Merge "Add app bounds to configuration." into oc-dev
diff --git a/api/current.txt b/api/current.txt
index d890cdb..392b60d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6595,6 +6595,7 @@
method public android.os.Bundle getExtras();
method public int getHeight();
method public java.lang.String getHint();
+ method public android.view.ViewStructure.HtmlInfo getHtmlInfo();
method public int getId();
method public java.lang.String getIdEntry();
method public java.lang.String getIdPackage();
@@ -7147,7 +7148,6 @@
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
- method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String);
@@ -7947,7 +7947,7 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean, int);
+ method public void enableAdvertising(boolean, int, int);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
@@ -8023,8 +8023,8 @@
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
- method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback);
- method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
@@ -8036,21 +8036,6 @@
method public void stopScan(android.bluetooth.le.ScanCallback);
}
- public abstract class PeriodicAdvertisingCallback {
- ctor public PeriodicAdvertisingCallback();
- method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport);
- method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int);
- method public void onSyncLost(int);
- field public static final int SYNC_NO_RESOURCES = 2; // 0x2
- field public static final int SYNC_NO_RESPONSE = 1; // 0x1
- }
-
- public final class PeriodicAdvertisingManager {
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback);
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler);
- method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
- }
-
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
method public int describeContents();
method public boolean getEnable();
@@ -8068,21 +8053,6 @@
method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
}
- public final class PeriodicAdvertisingReport implements android.os.Parcelable {
- ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
- method public int describeContents();
- method public android.bluetooth.le.ScanRecord getData();
- method public int getDataStatus();
- method public int getRssi();
- method public int getSyncHandle();
- method public long getTimestampNanos();
- method public int getTxPower();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR;
- field public static final int DATA_COMPLETE = 0; // 0x0
- field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2
- }
-
public abstract class ScanCallback {
ctor public ScanCallback();
method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>);
@@ -12540,6 +12510,7 @@
field public int inTargetDensity;
field public byte[] inTempStorage;
field public deprecated boolean mCancel;
+ field public android.graphics.ColorSpace outColorSpace;
field public android.graphics.Bitmap.Config outConfig;
field public int outHeight;
field public java.lang.String outMimeType;
@@ -46410,6 +46381,7 @@
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
method public abstract android.view.ViewStructure newChild(int);
+ method public abstract android.view.ViewStructure.HtmlInfo.Builder newHtmlInfoBuilder(java.lang.String);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
@@ -46432,8 +46404,8 @@
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
method public abstract void setHint(java.lang.CharSequence);
+ method public abstract void setHtmlInfo(android.view.ViewStructure.HtmlInfo);
method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
- method public abstract void setIdEntry(java.lang.String);
method public abstract void setInputType(int);
method public abstract void setLocaleList(android.os.LocaleList);
method public abstract void setLongClickable(boolean);
@@ -46448,6 +46420,18 @@
method public abstract void setVisibility(int);
}
+ public static abstract class ViewStructure.HtmlInfo {
+ ctor public ViewStructure.HtmlInfo();
+ method public abstract java.util.ArrayList<android.util.Pair<java.lang.String, java.lang.String>> getAttributes();
+ method public abstract java.lang.String getTag();
+ }
+
+ public static abstract class ViewStructure.HtmlInfo.Builder {
+ ctor public ViewStructure.HtmlInfo.Builder();
+ method public abstract android.view.ViewStructure.HtmlInfo.Builder addAttribute(java.lang.String, java.lang.String);
+ method public abstract android.view.ViewStructure.HtmlInfo build();
+ }
+
public final class ViewStub extends android.view.View {
ctor public ViewStub(android.content.Context);
ctor public ViewStub(android.content.Context, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 3e739d9..ac1597f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6832,6 +6832,7 @@
method public android.os.Bundle getExtras();
method public int getHeight();
method public java.lang.String getHint();
+ method public android.view.ViewStructure.HtmlInfo getHtmlInfo();
method public int getId();
method public java.lang.String getIdEntry();
method public java.lang.String getIdPackage();
@@ -7607,7 +7608,6 @@
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
- method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String);
@@ -8413,7 +8413,7 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean, int);
+ method public void enableAdvertising(boolean, int, int);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
@@ -8489,8 +8489,8 @@
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
- method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback);
- method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
@@ -8505,21 +8505,6 @@
method public void stopScan(android.bluetooth.le.ScanCallback);
}
- public abstract class PeriodicAdvertisingCallback {
- ctor public PeriodicAdvertisingCallback();
- method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport);
- method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int);
- method public void onSyncLost(int);
- field public static final int SYNC_NO_RESOURCES = 2; // 0x2
- field public static final int SYNC_NO_RESPONSE = 1; // 0x1
- }
-
- public final class PeriodicAdvertisingManager {
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback);
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler);
- method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
- }
-
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
method public int describeContents();
method public boolean getEnable();
@@ -8537,21 +8522,6 @@
method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
}
- public final class PeriodicAdvertisingReport implements android.os.Parcelable {
- ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
- method public int describeContents();
- method public android.bluetooth.le.ScanRecord getData();
- method public int getDataStatus();
- method public int getRssi();
- method public int getSyncHandle();
- method public long getTimestampNanos();
- method public int getTxPower();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR;
- field public static final int DATA_COMPLETE = 0; // 0x0
- field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2
- }
-
public final class ResultStorageDescriptor implements android.os.Parcelable {
ctor public ResultStorageDescriptor(int, int, int);
method public int describeContents();
@@ -13270,6 +13240,7 @@
field public int inTargetDensity;
field public byte[] inTempStorage;
field public deprecated boolean mCancel;
+ field public android.graphics.ColorSpace outColorSpace;
field public android.graphics.Bitmap.Config outConfig;
field public int outHeight;
field public java.lang.String outMimeType;
@@ -49867,6 +49838,7 @@
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
method public abstract android.view.ViewStructure newChild(int);
+ method public abstract android.view.ViewStructure.HtmlInfo.Builder newHtmlInfoBuilder(java.lang.String);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
@@ -49889,8 +49861,8 @@
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
method public abstract void setHint(java.lang.CharSequence);
+ method public abstract void setHtmlInfo(android.view.ViewStructure.HtmlInfo);
method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
- method public abstract void setIdEntry(java.lang.String);
method public abstract void setInputType(int);
method public abstract void setLocaleList(android.os.LocaleList);
method public abstract void setLongClickable(boolean);
@@ -49905,6 +49877,18 @@
method public abstract void setVisibility(int);
}
+ public static abstract class ViewStructure.HtmlInfo {
+ ctor public ViewStructure.HtmlInfo();
+ method public abstract java.util.ArrayList<android.util.Pair<java.lang.String, java.lang.String>> getAttributes();
+ method public abstract java.lang.String getTag();
+ }
+
+ public static abstract class ViewStructure.HtmlInfo.Builder {
+ ctor public ViewStructure.HtmlInfo.Builder();
+ method public abstract android.view.ViewStructure.HtmlInfo.Builder addAttribute(java.lang.String, java.lang.String);
+ method public abstract android.view.ViewStructure.HtmlInfo build();
+ }
+
public final class ViewStub extends android.view.View {
ctor public ViewStub(android.content.Context);
ctor public ViewStub(android.content.Context, int);
diff --git a/api/test-current.txt b/api/test-current.txt
index 6fba51a..fc3c9e7 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6624,6 +6624,7 @@
method public android.os.Bundle getExtras();
method public int getHeight();
method public java.lang.String getHint();
+ method public android.view.ViewStructure.HtmlInfo getHtmlInfo();
method public int getId();
method public java.lang.String getIdEntry();
method public java.lang.String getIdPackage();
@@ -7177,7 +7178,6 @@
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
- method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
method public boolean getProfileProxy(android.content.Context, android.bluetooth.BluetoothProfile.ServiceListener, int);
method public android.bluetooth.BluetoothDevice getRemoteDevice(java.lang.String);
@@ -7977,7 +7977,7 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean, int);
+ method public void enableAdvertising(boolean, int, int);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
@@ -8053,8 +8053,8 @@
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
- method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback);
- method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
@@ -8066,21 +8066,6 @@
method public void stopScan(android.bluetooth.le.ScanCallback);
}
- public abstract class PeriodicAdvertisingCallback {
- ctor public PeriodicAdvertisingCallback();
- method public void onPeriodicAdvertisingReport(android.bluetooth.le.PeriodicAdvertisingReport);
- method public void onSyncEstablished(int, android.bluetooth.BluetoothDevice, int, int, int, int);
- method public void onSyncLost(int);
- field public static final int SYNC_NO_RESOURCES = 2; // 0x2
- field public static final int SYNC_NO_RESPONSE = 1; // 0x1
- }
-
- public final class PeriodicAdvertisingManager {
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback);
- method public void registerSync(android.bluetooth.le.ScanResult, int, int, android.bluetooth.le.PeriodicAdvertisingCallback, android.os.Handler);
- method public void unregisterSync(android.bluetooth.le.PeriodicAdvertisingCallback);
- }
-
public final class PeriodicAdvertisingParameters implements android.os.Parcelable {
method public int describeContents();
method public boolean getEnable();
@@ -8098,21 +8083,6 @@
method public android.bluetooth.le.PeriodicAdvertisingParameters.Builder setInterval(int);
}
- public final class PeriodicAdvertisingReport implements android.os.Parcelable {
- ctor public PeriodicAdvertisingReport(int, int, int, int, android.bluetooth.le.ScanRecord);
- method public int describeContents();
- method public android.bluetooth.le.ScanRecord getData();
- method public int getDataStatus();
- method public int getRssi();
- method public int getSyncHandle();
- method public long getTimestampNanos();
- method public int getTxPower();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.bluetooth.le.PeriodicAdvertisingReport> CREATOR;
- field public static final int DATA_COMPLETE = 0; // 0x0
- field public static final int DATA_INCOMPLETE_TRUNCATED = 2; // 0x2
- }
-
public abstract class ScanCallback {
ctor public ScanCallback();
method public void onBatchScanResults(java.util.List<android.bluetooth.le.ScanResult>);
@@ -12590,6 +12560,7 @@
field public int inTargetDensity;
field public byte[] inTempStorage;
field public deprecated boolean mCancel;
+ field public android.graphics.ColorSpace outColorSpace;
field public android.graphics.Bitmap.Config outConfig;
field public int outHeight;
field public java.lang.String outMimeType;
@@ -46791,6 +46762,7 @@
method public abstract int getTextSelectionStart();
method public abstract boolean hasExtras();
method public abstract android.view.ViewStructure newChild(int);
+ method public abstract android.view.ViewStructure.HtmlInfo.Builder newHtmlInfoBuilder(java.lang.String);
method public abstract void setAccessibilityFocused(boolean);
method public abstract void setActivated(boolean);
method public abstract void setAlpha(float);
@@ -46813,8 +46785,8 @@
method public abstract void setFocusable(boolean);
method public abstract void setFocused(boolean);
method public abstract void setHint(java.lang.CharSequence);
+ method public abstract void setHtmlInfo(android.view.ViewStructure.HtmlInfo);
method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
- method public abstract void setIdEntry(java.lang.String);
method public abstract void setInputType(int);
method public abstract void setLocaleList(android.os.LocaleList);
method public abstract void setLongClickable(boolean);
@@ -46829,6 +46801,18 @@
method public abstract void setVisibility(int);
}
+ public static abstract class ViewStructure.HtmlInfo {
+ ctor public ViewStructure.HtmlInfo();
+ method public abstract java.util.ArrayList<android.util.Pair<java.lang.String, java.lang.String>> getAttributes();
+ method public abstract java.lang.String getTag();
+ }
+
+ public static abstract class ViewStructure.HtmlInfo.Builder {
+ ctor public ViewStructure.HtmlInfo.Builder();
+ method public abstract android.view.ViewStructure.HtmlInfo.Builder addAttribute(java.lang.String, java.lang.String);
+ method public abstract android.view.ViewStructure.HtmlInfo build();
+ }
+
public final class ViewStub extends android.view.View {
ctor public ViewStub(android.content.Context);
ctor public ViewStub(android.content.Context, int);
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 124267b..7d2db5c 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -19,9 +19,12 @@
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.ViewStructure;
+import android.view.ViewStructure.HtmlInfo;
+import android.view.ViewStructure.HtmlInfo.Builder;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.autofill.AutoFillId;
@@ -597,6 +600,7 @@
AutofillValue mAutofillValue;
String[] mAutofillOptions;
boolean mSanitized;
+ HtmlInfo mHtmlInfo;
int mX;
int mY;
@@ -641,7 +645,6 @@
static final int FLAGS_HAS_CHILDREN = 0x00100000;
static final int FLAGS_HAS_URL = 0x00080000;
static final int FLAGS_HAS_INPUT_TYPE = 0x00040000;
- static final int FLAGS_HAS_ENTRY_ID = 0x00020000;
static final int FLAGS_HAS_LOCALE_LIST = 0x00010000;
static final int FLAGS_ALL_CONTROL = 0xfff00000;
@@ -677,8 +680,6 @@
mIdPackage = preader.readString();
}
}
- } else if ((flags&FLAGS_HAS_ENTRY_ID) != 0) {
- mIdEntry = preader.readString();
}
if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0) {
@@ -688,6 +689,10 @@
mAutofillHints = in.readStringArray();
mAutofillValue = in.readParcelable(null);
mAutofillOptions = in.readStringArray();
+ final Parcelable p = in.readParcelable(null);
+ if (p instanceof HtmlInfo) {
+ mHtmlInfo = (HtmlInfo) p;
+ }
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
mX = in.readInt();
@@ -756,8 +761,6 @@
int flags = mFlags & ~FLAGS_ALL_CONTROL;
if (mId != View.NO_ID) {
flags |= FLAGS_HAS_ID;
- } else if (mIdEntry != null ){
- flags |= FLAGS_HAS_ENTRY_ID;
}
if (mAutofillId != null) {
flags |= FLAGS_HAS_AUTOFILL_DATA;
@@ -821,8 +824,6 @@
pwriter.writeString(mIdPackage);
}
}
- } else if ((flags&FLAGS_HAS_ENTRY_ID) != 0) {
- pwriter.writeString(mIdEntry);
}
if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0) {
@@ -834,6 +835,11 @@
final AutofillValue sanitizedValue = writeSensitive ? mAutofillValue : null;
out.writeParcelable(sanitizedValue, 0);
out.writeStringArray(mAutofillOptions);
+ if (mHtmlInfo instanceof Parcelable) {
+ out.writeParcelable((Parcelable) mHtmlInfo, 0);
+ } else {
+ out.writeParcelable(null, 0);
+ }
}
if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
out.writeInt(mX);
@@ -908,10 +914,6 @@
* If {@link #getId()} is a resource identifier, this is the entry name of that
* identifier. See {@link android.view.ViewStructure#setId ViewStructure.setId}
* for more information.
- *
- * <p>If the node represents a virtual view, it could also represent the entry id set by
- * {@link android.view.ViewStructure#setIdEntry ViewStructure.setIdEntry}
- *
*/
public String getIdEntry() {
return mIdEntry;
@@ -1233,12 +1235,8 @@
/**
* Returns the URL represented by this node.
*
- * <p>Typically used in 2 categories of nodes:
- *
- * <ol>
- * <li>Root node (containing the URL of the HTML page)
- * <li>Child nodes that represent hyperlinks (contains the hyperlink URL).
- * </ol>
+ * <p>Typically used when the view associated with the node is a container for an HTML
+ * document.
*
* <strong>WARNING:</strong> a {@link android.service.autofill.AutofillService} should only
* use this URL for autofill purposes when it trusts the app generating it (i.e., the app
@@ -1249,6 +1247,16 @@
}
/**
+ * Returns the HTML properties associated with this node.
+ *
+ * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
+ * for assist.
+ */
+ public HtmlInfo getHtmlInfo() {
+ return mHtmlInfo;
+ }
+
+ /**
* Returns the the list of locales associated with this node.
*/
public LocaleList getLocaleList() {
@@ -1393,11 +1401,6 @@
}
@Override
- public void setIdEntry(String entryName) {
- mNode.mIdEntry = entryName;
- }
-
- @Override
public void setDimens(int left, int top, int scrollX, int scrollY, int width, int height) {
mNode.mX = left;
mNode.mY = top;
@@ -1711,6 +1714,123 @@
public void setLocaleList(LocaleList localeList) {
mNode.mLocaleList = localeList;
}
+
+ @Override
+ public HtmlInfo.Builder newHtmlInfoBuilder(@NonNull String tagName) {
+ return new HtmlInfoNodeBuilder(tagName);
+ }
+
+ @Override
+ public void setHtmlInfo(@NonNull HtmlInfo htmlInfo) {
+ mNode.mHtmlInfo = htmlInfo;
+ }
+ }
+
+ private static final class HtmlInfoNode extends HtmlInfo implements Parcelable {
+ private final String mTag;
+ private final String[] mNames;
+ private final String[] mValues;
+
+ // Not parcelable
+ private ArrayList<Pair<String, String>> mAttributes;
+
+ private HtmlInfoNode(HtmlInfoNodeBuilder builder) {
+ mTag = builder.mTag;
+ if (builder.mNames == null) {
+ mNames = null;
+ mValues = null;
+ } else {
+ mNames = new String[builder.mNames.size()];
+ mValues = new String[builder.mValues.size()];
+ builder.mNames.toArray(mNames);
+ builder.mValues.toArray(mValues);
+ }
+ }
+
+ @Override
+ public String getTag() {
+ return mTag;
+ }
+
+ @Override
+ public ArrayList<Pair<String, String>> getAttributes() {
+ if (mAttributes == null && mNames != null) {
+ mAttributes = new ArrayList<>(mNames.length);
+ for (int i = 0; i < mNames.length; i++) {
+ final Pair<String, String> pair = new Pair<>(mNames[i], mValues[i]);
+ mAttributes.add(i, pair);
+ }
+ }
+ return mAttributes;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(mTag);
+ parcel.writeStringArray(mNames);
+ parcel.writeStringArray(mValues);
+ }
+
+ @SuppressWarnings("hiding")
+ public static final Creator<HtmlInfoNode> CREATOR = new Creator<HtmlInfoNode>() {
+ @Override
+ public HtmlInfoNode createFromParcel(Parcel parcel) {
+ // Always go through the builder to ensure the data ingested by
+ // the system obeys the contract of the builder to avoid attacks
+ // using specially crafted parcels.
+ final String tag = parcel.readString();
+ final HtmlInfoNodeBuilder builder = new HtmlInfoNodeBuilder(tag);
+ final String[] names = parcel.readStringArray();
+ final String[] values = parcel.readStringArray();
+ if (names != null && values != null) {
+ if (names.length != values.length) {
+ Log.w(TAG, "HtmlInfo attributes mismatch: names=" + names.length
+ + ", values=" + values.length);
+ } else {
+ for (int i = 0; i < names.length; i++) {
+ builder.addAttribute(names[i], values[i]);
+ }
+ }
+ }
+ return builder.build();
+ }
+
+ @Override
+ public HtmlInfoNode[] newArray(int size) {
+ return new HtmlInfoNode[size];
+ }
+ };
+ }
+
+ private static final class HtmlInfoNodeBuilder extends HtmlInfo.Builder {
+ private final String mTag;
+ private ArrayList<String> mNames;
+ private ArrayList<String> mValues;
+
+ HtmlInfoNodeBuilder(String tag) {
+ mTag = tag;
+ }
+
+ @Override
+ public Builder addAttribute(String name, String value) {
+ if (mNames == null) {
+ mNames = new ArrayList<>();
+ mValues = new ArrayList<>();
+ }
+ mNames.add(name);
+ mValues.add(value);
+ return this;
+ }
+
+ @Override
+ public HtmlInfoNode build() {
+ return new HtmlInfoNode(this);
+ }
}
/** @hide */
@@ -1813,6 +1933,12 @@
if (url != null) {
Log.i(TAG, prefix + " URL: " + url);
}
+ HtmlInfo htmlInfo = node.getHtmlInfo();
+ if (htmlInfo != null) {
+ Log.i(TAG, prefix + " HtmlInfo: tag=" + htmlInfo.getTag()
+ + ", attr="+ htmlInfo.getAttributes());
+ }
+
LocaleList localeList = node.getLocaleList();
if (localeList != null) {
Log.i(TAG, prefix + " LocaleList: " + localeList);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 4e1e42d..845a47d 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -638,6 +638,7 @@
* <p>
* Use {@link #isLePeriodicAdvertisingSupported()} to check whether LE Periodic Advertising is
* supported on this device before calling this method.
+ * @hide
*/
public PeriodicAdvertisingManager getPeriodicAdvertisingManager() {
if (!getLeAccess())
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index aa61ce2..5d1e8ec 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -778,7 +778,7 @@
/**
* Set the preferred connection PHY for this app. Please note that this is just a
- * recommendation, wether the PHY change will happen depends on other applications peferences,
+ * recommendation, whether the PHY change will happen depends on other applications peferences,
* local and remote controller capabilities. Controller can override these settings.
* <p>
* {@link BluetoothGattCallback#onPhyUpdate} will be triggered as a result of this call, even
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index b35a593..2df2ed8 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -550,7 +550,7 @@
/**
* Set the preferred connection PHY for this app. Please note that this is just a
- * recommendation, wether the PHY change will happen depends on other applications peferences,
+ * recommendation, whether the PHY change will happen depends on other applications peferences,
* local and remote controller capabilities. Controller can override these settings.
* <p>
* {@link BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even
diff --git a/core/java/android/bluetooth/BluetoothSocket.java b/core/java/android/bluetooth/BluetoothSocket.java
index 98a5341..6bf6aa0 100644
--- a/core/java/android/bluetooth/BluetoothSocket.java
+++ b/core/java/android/bluetooth/BluetoothSocket.java
@@ -416,6 +416,11 @@
if(mSocketState != SocketState.INIT) return EBADFD;
if(mPfd == null) return -1;
FileDescriptor fd = mPfd.getFileDescriptor();
+ if (fd == null) {
+ Log.e(TAG, "bindListen(), null file descriptor");
+ return -1;
+ }
+
if (DBG) Log.d(TAG, "bindListen(), Create LocalSocket");
mSocket = LocalSocket.createConnectedLocalSocket(fd);
if (DBG) Log.d(TAG, "bindListen(), new LocalSocket.getInputStream()");
@@ -556,8 +561,9 @@
@Override
public void close() throws IOException {
- if (DBG) Log.d(TAG, "close() in, this: " + this + ", channel: " + mPort + ", state: "
- + mSocketState);
+ Log.d(TAG, "close() this: " + this + ", channel: " + mPort +
+ ", mSocketIS: " + mSocketIS + ", mSocketOS: " + mSocketOS +
+ "mSocket: " + mSocket + ", mSocketState: " + mSocketState);
if(mSocketState == SocketState.CLOSED)
return;
else
@@ -567,9 +573,6 @@
if(mSocketState == SocketState.CLOSED)
return;
mSocketState = SocketState.CLOSED;
- if (DBG) Log.d(TAG, "close() this: " + this + ", channel: " + mPort +
- ", mSocketIS: " + mSocketIS + ", mSocketOS: " + mSocketOS +
- "mSocket: " + mSocket);
if(mSocket != null) {
if (DBG) Log.d(TAG, "Closing mSocket: " + mSocket);
mSocket.shutdownInput();
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 0825ee8..334e88b 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -52,10 +52,11 @@
void startAdvertisingSet(in AdvertisingSetParameters parameters, in AdvertiseData advertiseData,
in AdvertiseData scanResponse, in PeriodicAdvertisingParameters periodicParameters,
- in AdvertiseData periodicData, in int timeout, in IAdvertisingSetCallback callback);
+ in AdvertiseData periodicData, in int duration, in int maxExtAdvEvents,
+ in IAdvertisingSetCallback callback);
void stopAdvertisingSet(in IAdvertisingSetCallback callback);
- void enableAdvertisingSet(in int advertiserId, in boolean enable, in int timeout);
+ void enableAdvertisingSet(in int advertiserId, in boolean enable, in int duration, in int maxExtAdvEvents);
void setAdvertisingData(in int advertiserId, in AdvertiseData data);
void setScanResponseData(in int advertiserId, in AdvertiseData data);
void setAdvertisingParameters(in int advertiserId, in AdvertisingSetParameters parameters);
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
index 7355b0d..51571b2 100644
--- a/core/java/android/bluetooth/le/AdvertisingSet.java
+++ b/core/java/android/bluetooth/le/AdvertisingSet.java
@@ -16,6 +16,7 @@
package android.bluetooth.le;
+import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.le.IAdvertisingSetCallback;
@@ -57,15 +58,23 @@
/**
* Enables Advertising. This method returns immediately, the operation status is
- * delivered
- * through {@code callback.onAdvertisingEnabled()}.
+ * delivered through {@code callback.onAdvertisingEnabled()}.
* <p>
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
*
+ * @param enable whether the advertising should be enabled (true), or disabled (false)
+ * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
+ * 65535 (655,350 ms)
+ * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
+ * controller shall attempt to send prior to terminating the extended
+ * advertising, even if the duration has not expired. Valid range is
+ * from 1 to 255.
*/
- public void enableAdvertising(boolean enable, int timeout) {
+ public void enableAdvertising(boolean enable, int duration,
+ int maxExtendedAdvertisingEvents) {
try {
- gatt.enableAdvertisingSet(this.advertiserId, enable, timeout);
+ gatt.enableAdvertisingSet(this.advertiserId, enable, duration,
+ maxExtendedAdvertisingEvents);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -77,10 +86,16 @@
* delivered through {@code callback.onAdvertisingDataSet()}.
* <p>
* Advertising data must be empty if non-legacy scannable advertising is used.
+ *
+ * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
+ * advertisement is connectable, three bytes will be added for flags. If the
+ * update takes place when the advertising set is enabled, the data can be
+ * maximum 251 bytes long.
*/
- public void setAdvertisingData(AdvertiseData data) {
+ public void setAdvertisingData(AdvertiseData advertiseData) {
try {
- gatt.setAdvertisingData(this.advertiserId, data);
+ gatt.setAdvertisingData(this.advertiserId, advertiseData);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -90,10 +105,15 @@
* Set/update scan response data. Make sure that data doesn't exceed the size limit for
* specified AdvertisingSetParameters. This method returns immediately, the operation status
* is delivered through {@code callback.onScanResponseDataSet()}.
+ *
+ * @param scanResponse Scan response associated with the advertisement data. Size must not
+ * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
+ * update takes place when the advertising set is enabled, the data can be
+ * maximum 251 bytes long.
*/
- public void setScanResponseData(AdvertiseData data) {
+ public void setScanResponseData(AdvertiseData scanResponse) {
try {
- gatt.setScanResponseData(this.advertiserId, data);
+ gatt.setScanResponseData(this.advertiserId, scanResponse);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -103,6 +123,8 @@
* Update advertising parameters associated with this AdvertisingSet. Must be called when
* advertising is not active. This method returns immediately, the operation status is delivered
* through {@code callback.onAdvertisingParametersUpdated}.
+ *
+ * @param parameters advertising set parameters.
*/
public void setAdvertisingParameters(AdvertisingSetParameters parameters) {
try {
@@ -130,10 +152,15 @@
* or after advertising was started with periodic advertising data set. This method returns
* immediately, the operation status is delivered through
* {@code callback.onPeriodicAdvertisingDataSet()}.
+ *
+ * @param periodicData Periodic advertising data. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
+ * update takes place when the periodic advertising is enabled for this set,
+ * the data can be maximum 251 bytes long.
*/
- public void setPeriodicAdvertisingData(AdvertiseData data) {
+ public void setPeriodicAdvertisingData(AdvertiseData periodicData) {
try {
- gatt.setPeriodicAdvertisingData(this.advertiserId, data);
+ gatt.setPeriodicAdvertisingData(this.advertiserId, periodicData);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -142,6 +169,8 @@
/**
* Used to enable/disable periodic advertising. This method returns immediately, the operation
* status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
+ *
+ * @param enable whether the periodic advertising should be enabled (true), or disabled (false).
*/
public void setPeriodicAdvertisingEnable(boolean enable) {
try {
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index fe1f425..f5c1f08 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -16,6 +16,7 @@
package android.bluetooth.le;
+import android.bluetooth.BluetoothAdapter;
import android.os.Parcel;
import android.os.Parcelable;
@@ -279,7 +280,7 @@
* When set to true, advertising set will advertise 4.x Spec compliant
* advertisements.
*
- * @param isLegacy wether legacy advertising mode should be used.
+ * @param isLegacy whether legacy advertising mode should be used.
*/
public Builder setLegacyMode(boolean isLegacy) {
this.isLegacy = isLegacy;
@@ -287,12 +288,12 @@
}
/**
- * Set wether advertiser address should be ommited from all packets. If this
+ * Set whether advertiser address should be ommited from all packets. If this
* mode is used, periodic advertising can't be enabled for this set.
*
* This is used only if legacy mode is not used.
*
- * @param isAnonymous wether anonymous advertising should be used.
+ * @param isAnonymous whether anonymous advertising should be used.
*/
public Builder setAnonymous(boolean isAnonymous) {
this.isAnonymous = isAnonymous;
@@ -300,12 +301,12 @@
}
/**
- * Set wether TX power should be included in the extended header.
+ * Set whether TX power should be included in the extended header.
*
* This is used only if legacy mode is not used.
*
- * @param includeTxPower wether TX power should be included in extended
- * header
+ * @param includeTxPower whether TX power should be included in extended
+ * header
*/
public Builder setIncludeTxPower(boolean includeTxPower) {
this.includeTxPower = includeTxPower;
@@ -317,6 +318,8 @@
*
* This is used only if legacy mode is not used.
*
+ * Use {@link BluetoothAdapter#isLeCodedPhySupported} to determine if LE Coded PHY is
+ * supported on this device.
* @param primaryPhy Primary advertising physical channel, can only be
* {@link AdvertisingSetParameters#PHY_LE_1M} or
* {@link AdvertisingSetParameters#PHY_LE_CODED}.
@@ -335,6 +338,10 @@
*
* This is used only if legacy mode is not used.
*
+ * Use {@link BluetoothAdapter#isLeCodedPhySupported} and
+ * {@link BluetoothAdapter#isLe2MPhySupported} to determine if LE Coded PHY or 2M PHY is
+ * supported on this device.
+ *
* @param secondaryPhy Secondary advertising physical channel, can only be
* one of {@link AdvertisingSetParameters#PHY_LE_1M},
* {@link AdvertisingSetParameters#PHY_LE_2M} or
@@ -393,6 +400,32 @@
* Build the {@link AdvertisingSetParameters} object.
*/
public AdvertisingSetParameters build() {
+ if (isLegacy) {
+ if (isAnonymous) {
+ throw new IllegalArgumentException("Legacy advertising can't be anonymous");
+ }
+
+ if (connectable == true && scannable == false) {
+ throw new IllegalArgumentException(
+ "Legacy advertisement can't be connectable and non-scannable");
+ }
+
+ if (includeTxPower) {
+ throw new IllegalArgumentException(
+ "Legacy advertising can't include TX power level in header");
+ }
+ } else {
+ if (connectable && scannable) {
+ throw new IllegalArgumentException(
+ "Advertising can't be both connectable and scannable");
+ }
+
+ if (isAnonymous && connectable) {
+ throw new IllegalArgumentException(
+ "Advertising can't be both connectable and anonymous");
+ }
+ }
+
return new AdvertisingSetParameters(connectable, scannable, isLegacy, isAnonymous,
includeTxPower, primaryPhy,
secondaryPhy, interval, txPowerLevel);
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 242ee77..a9deb75 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -50,13 +50,13 @@
private static final String TAG = "BluetoothLeAdvertiser";
- private static final int MAX_ADVERTISING_DATA_BYTES = 31;
+ private static final int MAX_ADVERTISING_DATA_BYTES = 1650;
+ private static final int MAX_LEGACY_ADVERTISING_DATA_BYTES = 31;
// Each fields need one byte for field length and another byte for field type.
private static final int OVERHEAD_BYTES_PER_FIELD = 2;
// Flags field will be set by system.
private static final int FLAGS_FIELD_BYTES = 3;
private static final int MANUFACTURER_SPECIFIC_DATA_LENGTH = 2;
- private static final int SERVICE_DATA_UUID_LENGTH = 2;
private final IBluetoothManager mBluetoothManager;
private final Handler mHandler;
@@ -117,8 +117,8 @@
throw new IllegalArgumentException("callback cannot be null");
}
boolean isConnectable = settings.isConnectable();
- if (totalBytes(advertiseData, isConnectable) > MAX_ADVERTISING_DATA_BYTES ||
- totalBytes(scanResponse, false) > MAX_ADVERTISING_DATA_BYTES) {
+ if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES ||
+ totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
return;
}
@@ -149,10 +149,16 @@
parameters.setTxPowerLevel(1);
}
+ int duration = 0;
+ int timeoutMillis = settings.getTimeout();
+ if (timeoutMillis > 0) {
+ duration = (timeoutMillis < 10) ? 1 : timeoutMillis/10;
+ }
+
AdvertisingSetCallback wrapped = wrapOldCallback(callback, settings);
mLegacyAdvertisers.put(callback, wrapped);
startAdvertisingSet(parameters.build(), advertiseData, scanResponse, null, null,
- settings.getTimeout(), wrapped);
+ duration, 0, wrapped);
}
}
@@ -206,90 +212,202 @@
}
/**
- * Creates a new advertising set. If operation succeed, device will start advertising. This
- * method returns immediately, the operation status is delivered through
- * {@code callback.onAdvertisingSetStarted()}.
- * <p>
- * @param parameters advertising set parameters.
- * @param advertiseData Advertisement data to be broadcasted.
- * @param scanResponse Scan response associated with the advertisement data.
- * @param periodicData Periodic advertising data.
- * @param callback Callback for advertising set.
- */
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onAdvertisingSetStarted()}.
+ * <p>
+ * @param parameters advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
+ * advertisement is connectable, three bytes will be added for flags.
+ * @param scanResponse Scan response associated with the advertisement data. Size must not
+ * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+ * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
+ * not be started.
+ * @param periodicData Periodic advertising data. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+ * @param callback Callback for advertising set.
+ * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
+ * size, or unsupported advertising PHY is selected, or when attempt to use
+ * Periodic Advertising feature is made when it's not supported by the
+ * controller.
+ */
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback) {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, 0, callback, new Handler(Looper.getMainLooper()));
+ periodicData, 0, 0, callback, new Handler(Looper.getMainLooper()));
}
/**
- * Creates a new advertising set. If operation succeed, device will start advertising. This
- * method returns immediately, the operation status is delivered through
- * {@code callback.onAdvertisingSetStarted()}.
- * <p>
- * @param parameters advertising set parameters.
- * @param advertiseData Advertisement data to be broadcasted.
- * @param scanResponse Scan response associated with the advertisement data.
- * @param periodicData Periodic advertising data.
- * @param callback Callback for advertising set.
- * @param handler thread upon which the callbacks will be invoked.
- */
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onAdvertisingSetStarted()}.
+ * <p>
+ * @param parameters advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
+ * advertisement is connectable, three bytes will be added for flags.
+ * @param scanResponse Scan response associated with the advertisement data. Size must not
+ * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+ * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
+ * not be started.
+ * @param periodicData Periodic advertising data. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+ * @param callback Callback for advertising set.
+ * @param handler thread upon which the callbacks will be invoked.
+ * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
+ * size, or unsupported advertising PHY is selected, or when attempt to use
+ * Periodic Advertising feature is made when it's not supported by the
+ * controller.
+ */
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback,
Handler handler) {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, 0, callback, handler);
+ periodicData, 0, 0, callback, handler);
}
/**
- * Creates a new advertising set. If operation succeed, device will start advertising. This
- * method returns immediately, the operation status is delivered through
- * {@code callback.onAdvertisingSetStarted()}.
- * <p>
- * @param parameters advertising set parameters.
- * @param advertiseData Advertisement data to be broadcasted.
- * @param scanResponse Scan response associated with the advertisement data.
- * @param periodicData Periodic advertising data.
- * @param timeoutMillis Advertising time limit. May not exceed 180000
- * @param callback Callback for advertising set.
- */
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onAdvertisingSetStarted()}.
+ * <p>
+ * @param parameters advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
+ * advertisement is connectable, three bytes will be added for flags.
+ * @param scanResponse Scan response associated with the advertisement data. Size must not
+ * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+ * @param periodicParameters periodic advertisng parameters. If null, periodic advertising will
+ * not be started.
+ * @param periodicData Periodic advertising data. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}.
+ * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
+ * 65535 (655,350 ms). 0 means advertising should continue until stopped.
+ * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
+ * controller shall attempt to send prior to terminating the extended
+ * advertising, even if the duration has not expired. Valid range is
+ * from 1 to 255. 0 means no maximum.
+ * @param callback Callback for advertising set.
+ * @throws IllegalArgumentException when any of the data parameter exceed the maximum allowable
+ * size, or unsupported advertising PHY is selected, or when attempt to use
+ * Periodic Advertising feature is made when it's not supported by the
+ * controller.
+ */
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
- AdvertiseData periodicData, int timeoutMillis,
+ AdvertiseData periodicData, int duration,
+ int maxExtendedAdvertisingEvents,
AdvertisingSetCallback callback) {
startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, timeoutMillis, callback, new Handler(Looper.getMainLooper()));
+ periodicData, duration, maxExtendedAdvertisingEvents, callback,
+ new Handler(Looper.getMainLooper()));
}
/**
- * Creates a new advertising set. If operation succeed, device will start advertising. This
- * method returns immediately, the operation status is delivered through
- * {@code callback.onAdvertisingSetStarted()}.
- * <p>
- * @param parameters advertising set parameters.
- * @param advertiseData Advertisement data to be broadcasted.
- * @param scanResponse Scan response associated with the advertisement data.
- * @param periodicData Periodic advertising data.
- * @param timeoutMillis Advertising time limit. May not exceed 180000
- * @param callback Callback for advertising set.
- * @param handler thread upon which the callbacks will be invoked.
- */
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onAdvertisingSetStarted()}.
+ * <p>
+ * @param parameters Advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}. If the
+ * advertisement is connectable, three bytes will be added for flags.
+ * @param scanResponse Scan response associated with the advertisement data. Size must not
+ * exceed {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
+ * @param periodicParameters Periodic advertisng parameters. If null, periodic advertising will
+ * not be started.
+ * @param periodicData Periodic advertising data. Size must not exceed
+ * {@link BluetoothAdapter#getLeMaximumAdvertisingDataLength}
+ * @param duration advertising duration, in 10ms unit. Valid range is from 1 (10ms) to
+ * 65535 (655,350 ms). 0 means advertising should continue until stopped.
+ * @param maxExtendedAdvertisingEvents maximum number of extended advertising events the
+ * controller shall attempt to send prior to terminating the extended
+ * advertising, even if the duration has not expired. Valid range is
+ * from 1 to 255. 0 means no maximum.
+ * @param callback Callback for advertising set.
+ * @param handler Thread upon which the callbacks will be invoked.
+ * @throws IllegalArgumentException When any of the data parameter exceed the maximum allowable
+ * size, or unsupported advertising PHY is selected, or when attempt to use
+ * Periodic Advertising feature is made when it's not supported by the
+ * controller, or when maxExtendedAdvertisingEvents is used on a controller
+ * that doesn't support the LE Extended Advertising
+ */
public void startAdvertisingSet(AdvertisingSetParameters parameters,
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
- AdvertiseData periodicData, int timeoutMillis,
- AdvertisingSetCallback callback, Handler handler) {
+ AdvertiseData periodicData, int duration,
+ int maxExtendedAdvertisingEvents, AdvertisingSetCallback callback,
+ Handler handler) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
-
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
+ boolean isConnectable = parameters.isConnectable();
+ if (parameters.isLegacy()) {
+ if (totalBytes(advertiseData, isConnectable) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
+ throw new IllegalArgumentException("Legacy advertising data too big");
+ }
+
+ if (totalBytes(scanResponse, false) > MAX_LEGACY_ADVERTISING_DATA_BYTES) {
+ throw new IllegalArgumentException("Legacy scan response data too big");
+ }
+ } else {
+ boolean supportCodedPhy = mBluetoothAdapter.isLeCodedPhySupported();
+ boolean support2MPhy = mBluetoothAdapter.isLe2MPhySupported();
+ int pphy = parameters.getPrimaryPhy();
+ int sphy = parameters.getSecondaryPhy();
+ if (pphy == AdvertisingSetParameters.PHY_LE_CODED && !supportCodedPhy) {
+ throw new IllegalArgumentException("Unsupported primary PHY selected");
+ }
+
+ if ((sphy == AdvertisingSetParameters.PHY_LE_CODED && !supportCodedPhy)
+ || (sphy == AdvertisingSetParameters.PHY_LE_2M && !support2MPhy)) {
+ throw new IllegalArgumentException("Unsupported secondary PHY selected");
+ }
+
+ int maxData = mBluetoothAdapter.getLeMaximumAdvertisingDataLength();
+ if (totalBytes(advertiseData, isConnectable) > maxData) {
+ throw new IllegalArgumentException("Advertising data too big");
+ }
+
+ if (totalBytes(scanResponse, false) > maxData) {
+ throw new IllegalArgumentException("Scan response data too big");
+ }
+
+ if (totalBytes(periodicData, false) > maxData) {
+ throw new IllegalArgumentException("Periodic advertising data too big");
+ }
+
+ boolean supportPeriodic = mBluetoothAdapter.isLePeriodicAdvertisingSupported();
+ if (periodicParameters != null && periodicParameters.getEnable() && !supportPeriodic) {
+ throw new IllegalArgumentException(
+ "Controller does not support LE Periodic Advertising");
+ }
+ }
+
+ if (maxExtendedAdvertisingEvents < 0 || maxExtendedAdvertisingEvents > 255) {
+ throw new IllegalArgumentException(
+ "maxExtendedAdvertisingEvents out of range: " + maxExtendedAdvertisingEvents);
+ }
+
+ if (maxExtendedAdvertisingEvents != 0 &&
+ !mBluetoothAdapter.isLePeriodicAdvertisingSupported()) {
+ throw new IllegalArgumentException(
+ "Can't use maxExtendedAdvertisingEvents with controller that don't support " +
+ "LE Extended Advertising");
+ }
+
+ if (duration < 0 || duration > 65535) {
+ throw new IllegalArgumentException("duration out of range: " + duration);
+ }
+
IBluetoothGatt gatt;
try {
gatt = mBluetoothManager.getBluetoothGatt();
@@ -306,7 +424,7 @@
try {
gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, timeoutMillis, wrapped);
+ periodicData, duration, maxExtendedAdvertisingEvents, wrapped);
} catch (RemoteException e) {
Log.e(TAG, "Failed to start advertising set - ", e);
throw new IllegalStateException("Failed to start advertising set");
@@ -383,7 +501,8 @@
}
}
for (ParcelUuid uuid : data.getServiceData().keySet()) {
- size += OVERHEAD_BYTES_PER_FIELD + SERVICE_DATA_UUID_LENGTH
+ int uuidLen = BluetoothUuid.uuidToBytes(uuid).length;
+ size += OVERHEAD_BYTES_PER_FIELD + uuidLen
+ byteLength(data.getServiceData().get(uuid));
}
for (int i = 0; i < data.getManufacturerSpecificData().size(); ++i) {
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
index 6616231..364b575 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingCallback.java
@@ -23,6 +23,7 @@
* advertising operation status.
*
* @see PeriodicAdvertisingManager#createSync
+ * @hide
*/
public abstract class PeriodicAdvertisingCallback {
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
index 12c8a8c..d9c2d88 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingManager.java
@@ -37,6 +37,7 @@
* <p>
* <b>Note:</b> Most of the methods here require
* {@link android.Manifest.permission#BLUETOOTH_ADMIN} permission.
+ * @hide
*/
public final class PeriodicAdvertisingManager {
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
index ebc92bd..149540c 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingParameters.java
@@ -93,7 +93,7 @@
private int interval = INTERVAL_MAX;
/**
- * Set wether the Periodic Advertising should be enabled for this set.
+ * Set whether the Periodic Advertising should be enabled for this set.
*/
public Builder setEnable(boolean enable) {
this.enable = enable;
diff --git a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
index 3ff4ca5..51b93cb 100644
--- a/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
+++ b/core/java/android/bluetooth/le/PeriodicAdvertisingReport.java
@@ -24,6 +24,7 @@
/**
* PeriodicAdvertisingReport for Bluetooth LE synchronized advertising.
+ * @hide
*/
public final class PeriodicAdvertisingReport implements Parcelable {
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 13e9a15..d9e516c 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -61,15 +61,15 @@
*/
@Deprecated
public int getBlockSize() {
- return (int) mStat.f_bsize;
+ return (int) mStat.f_frsize;
}
/**
* The size, in bytes, of a block on the file system. This corresponds to
- * the Unix {@code statvfs.f_bsize} field.
+ * the Unix {@code statvfs.f_frsize} field.
*/
public long getBlockSizeLong() {
- return mStat.f_bsize;
+ return mStat.f_frsize;
}
/**
@@ -112,7 +112,7 @@
* will want to use {@link #getAvailableBytes()} instead.
*/
public long getFreeBytes() {
- return mStat.f_bfree * mStat.f_bsize;
+ return mStat.f_bfree * mStat.f_frsize;
}
/**
@@ -136,13 +136,13 @@
* applications.
*/
public long getAvailableBytes() {
- return mStat.f_bavail * mStat.f_bsize;
+ return mStat.f_bavail * mStat.f_frsize;
}
/**
* The total number of bytes supported by the file system.
*/
public long getTotalBytes() {
- return mStat.f_blocks * mStat.f_bsize;
+ return mStat.f_blocks * mStat.f_frsize;
}
}
diff --git a/core/java/android/provider/AlarmClock.java b/core/java/android/provider/AlarmClock.java
index 23134cd..d921ed4 100644
--- a/core/java/android/provider/AlarmClock.java
+++ b/core/java/android/provider/AlarmClock.java
@@ -29,6 +29,8 @@
* new alarm or timer should use
* {@link android.content.Context#startActivity Context.startActivity()} so that
* the user has the option of choosing which alarm clock application to use.
+ *
+ * Android TV devices may not support the alarm intents.
*/
public final class AlarmClock {
/**
diff --git a/core/java/android/text/BidiFormatter.java b/core/java/android/text/BidiFormatter.java
index d84502f..f65f397 100644
--- a/core/java/android/text/BidiFormatter.java
+++ b/core/java/android/text/BidiFormatter.java
@@ -592,10 +592,21 @@
static {
DIR_TYPE_CACHE = new byte[DIR_TYPE_CACHE_SIZE];
for (int i = 0; i < DIR_TYPE_CACHE_SIZE; i++) {
+ // Calling Character.getDirectionality() is OK here, since new emojis start after
+ // the end of our cache.
DIR_TYPE_CACHE[i] = Character.getDirectionality(i);
}
}
+ private static byte getDirectionality(int codePoint) {
+ if (Emoji.isNewEmoji(codePoint)) {
+ // TODO: Fix or remove once emoji-data.text 5.0 is in ICU or update to 6.0.
+ return Character.DIRECTIONALITY_OTHER_NEUTRALS;
+ } else {
+ return Character.getDirectionality(codePoint);
+ }
+ }
+
// Internal instance variables.
/**
@@ -809,7 +820,7 @@
* cache.
*/
private static byte getCachedDirectionality(char c) {
- return c < DIR_TYPE_CACHE_SIZE ? DIR_TYPE_CACHE[c] : Character.getDirectionality(c);
+ return c < DIR_TYPE_CACHE_SIZE ? DIR_TYPE_CACHE[c] : getDirectionality(c);
}
/**
@@ -826,7 +837,7 @@
if (Character.isHighSurrogate(lastChar)) {
int codePoint = Character.codePointAt(text, charIndex);
charIndex += Character.charCount(codePoint);
- return Character.getDirectionality(codePoint);
+ return getDirectionality(codePoint);
}
charIndex++;
byte dirType = getCachedDirectionality(lastChar);
@@ -856,7 +867,7 @@
if (Character.isLowSurrogate(lastChar)) {
int codePoint = Character.codePointBefore(text, charIndex);
charIndex -= Character.charCount(codePoint);
- return Character.getDirectionality(codePoint);
+ return getDirectionality(codePoint);
}
charIndex--;
byte dirType = getCachedDirectionality(lastChar);
diff --git a/core/java/android/text/Emoji.java b/core/java/android/text/Emoji.java
index ee016c1..d33aad9 100644
--- a/core/java/android/text/Emoji.java
+++ b/core/java/android/text/Emoji.java
@@ -65,22 +65,32 @@
return UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI_MODIFIER_BASE);
}
- // Returns true if the character has Emoji property.
- public static boolean isEmoji(int codePoint) {
+ /**
+ * Returns true if the character is a new emoji still not supported in our version of ICU.
+ */
+ public static boolean isNewEmoji(int codePoint) {
// Emoji characters new in Unicode emoji 5.0.
// From http://www.unicode.org/Public/emoji/5.0/emoji-data.txt
// TODO: Remove once emoji-data.text 5.0 is in ICU or update to 6.0.
- if ((0x1F6F7 <= codePoint && codePoint <= 0x1F6F8)
+ if (codePoint < 0x1F6F7 || codePoint > 0x1F9E6) {
+ // Optimization for characters outside the new emoji range.
+ return false;
+ }
+ return (0x1F6F7 <= codePoint && codePoint <= 0x1F6F8)
|| codePoint == 0x1F91F
|| (0x1F928 <= codePoint && codePoint <= 0x1F92F)
|| (0x1F931 <= codePoint && codePoint <= 0x1F932)
|| codePoint == 0x1F94C
|| (0x1F95F <= codePoint && codePoint <= 0x1F96B)
|| (0x1F992 <= codePoint && codePoint <= 0x1F997)
- || (0x1F9D0 <= codePoint && codePoint <= 0x1F9E6)) {
- return true;
- }
- return UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI);
+ || (0x1F9D0 <= codePoint && codePoint <= 0x1F9E6);
+ }
+
+ /**
+ * Returns true if the character has Emoji property.
+ */
+ public static boolean isEmoji(int codePoint) {
+ return isNewEmoji(codePoint) || UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI);
}
// Returns true if the character can be a base character of COMBINING ENCLOSING KEYCAP.
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 65f3c90..b157709 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -22,9 +22,12 @@
import android.graphics.Rect;
import android.os.Bundle;
import android.os.LocaleList;
+import android.util.Pair;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillValue;
+import java.util.ArrayList;
+
/**
* Container for storing additional per-view data generated by {@link View#onProvideStructure
* View.onProvideStructure} and {@link View#onProvideAutofillStructure
@@ -43,17 +46,6 @@
public abstract void setId(int id, String packageName, String typeName, String entryName);
/**
- * Sets the name of the identifier for this view.
- *
- * <p>Typically used when adding virtual children (through
- * {@link #asyncNewChild(int)}) that does not map to Android {@link View}
- * - otherwise, it's better to call {@link #setId(int, String, String, String)}.
- *
- * @param entryName The entry name of the view's identifier, or {@code null} if there is none.
- */
- public abstract void setIdEntry(String entryName);
-
- /**
* Set the basic dimensions of this view.
*
* @param left The view's left position, in pixels relative to its parent's left edge.
@@ -372,13 +364,7 @@
/**
* Sets the URL represented by this node.
*
- * <p>Typically used in the following situations:
- *
- * <ol>
- * <li>In a {@link android.app.assist.AssistStructure.WindowNode#getRootViewNode()}, to set up
- * the main URL of an HTML page.
- * <li>On child nodes represening hyperlinks.
- * </ol>
+ * <p>Typically used when the view is a container for an HTML document.
*/
public abstract void setUrl(String url);
@@ -386,4 +372,64 @@
* Sets the the list of locales associated with this node.
*/
public abstract void setLocaleList(LocaleList localeList);
+
+ /**
+ * Creates a new {@link HtmlInfo.Builder} for the given HTML tag.
+ *
+ * @param tagName name of the HTML tag.
+ * @return a new builder.
+ */
+ public abstract HtmlInfo.Builder newHtmlInfoBuilder(@NonNull String tagName);
+
+ /**
+ * Sets the HTML properties of this node when it represents an HTML element.
+ *
+ * <p>Should only be set when the node is used for autofill purposes - it will be ignored
+ * when used for assist.
+ *
+ * @param htmlInfo HTML properties.
+ */
+ public abstract void setHtmlInfo(@NonNull HtmlInfo htmlInfo);
+
+ /**
+ * Simplified representation of the HTML properties of a node that represents an HTML element.
+ */
+ public abstract static class HtmlInfo {
+
+ /**
+ * Gets the HTML tag.
+ */
+ @NonNull
+ public abstract String getTag();
+
+ /**
+ * Gets the list of HTML attributes.
+ *
+ * @return list of key/value pairs; could contain pairs with the same keys.
+ */
+ @Nullable
+ public abstract ArrayList<Pair<String, String>> getAttributes();
+
+ /**
+ * Builder for {@link HtmlInfo} objects.
+ */
+ public abstract static class Builder {
+
+ /**
+ * Adds an HTML attribute.
+ *
+ * @param name name of the attribute.
+ * @param value value of the attribute.
+ * @return same builder, for chaining.
+ */
+ public abstract Builder addAttribute(@NonNull String name, @NonNull String value);
+
+ /**
+ * Builds the {@link HtmlInfo} object.
+ *
+ * @return a new {@link HtmlInfo} instance.
+ */
+ public abstract HtmlInfo build();
+ }
+ }
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9582b72..3f72fde 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -42,7 +42,6 @@
import android.os.RemoteException;
import android.print.PrintDocumentAdapter;
import android.security.KeyChain;
-import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
@@ -2641,49 +2640,55 @@
* understood by the {@link android.service.autofill.AutofillService} implementations:
*
* <ol>
- * <li>{@link ViewStructure#setClassName(String)} should be use to describe the type of node:
- * <ol>
- * <li>If the Android SDK provides a similar View, the full-qualified class name of that
- * view should be used.
- * <li>Otherwise, the class name should be {@code HTML.iframe}.
- * </ol>
+ * <li>If the Android SDK provides a similar View, then should be set with the
+ * fully-qualified class name of such view.
* <li>The W3C autofill field ({@code autocomplete} tag attribute) maps to
* {@link ViewStructure#setAutofillHints(String[])}.
* <li>The {@code type} attribute of {@code INPUT} tags maps to
* {@link ViewStructure#setInputType(int)}.
- * <li>The {@code name} attribute maps to {@link ViewStructure#setIdEntry(String)}.
* <li>The {@code value} attribute maps to {@link ViewStructure#setText(CharSequence)}.
* <li>The {@code placeholder} attribute maps to {@link ViewStructure#setHint(CharSequence)}.
* <li>{@link ViewStructure#setDataIsSensitive(boolean)} whould only be called with
* {@code true} for form fields whose {@code value} attribute was not pre-loaded.
+ * <li>Other HTML attributes can be represented through
+ * {@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)}.
* </ol>
*
* <p>Example1: an HTML form with 2 fields for username and password.
*
* <pre class="prettyprint">
- * <input type="text" name="username" value="mr.sparkle" autocomplete="username" placeholder="Email or username">
- * <input type="password" name="password" autocomplete="current-password" placeholder="Password">
+ * <input type="text" name="username" id="user" value="mr.sparkle" autocomplete="username" placeholder="Email or username">
+ * <input type="password" name="password" id="pass" autocomplete="current-password" placeholder="Password">
* </pre>
*
* <p>Would map to:
*
* <pre class="prettyprint">
- * ViewStructure username = //structure.newChildForAutofill(...);
+ * int index = structure.addChildCount(2);
+ * ViewStructure username = structure.newChild(index);
+ * username.setAutofillId(structure, 1); // id 1 - first child
* username.setClassName("input");
* username.setInputType("android.widget.EditText");
* username.setAutofillHints("username");
- * username.setIdEntry("username");
+ * username.setHtmlInfo(child.newHtmlInfoBuilder("input")
+ * .addAttribute("name", "username")
+ * .addAttribute("id", "user")
+ * .build());
* username.setHint("Email or username");
* username.setAutofillType(View.AUTOFILL_TYPE_TEXT);
* username.setAutofillValue(AutofillValue.forText("mr.sparkle"));
* username.setText("mr.sparkle");
* username.setDataIsSensitive(true); // Contains real username, which is sensitive
*
- * ViewStructure password = //structure.newChildForAutofill(...);
+ * ViewStructure password = structure.newChild(index + 1);
+ * username.setAutofillId(structure, 2); // id 2 - second child
* password.setInputType("android.widget.EditText");
* password.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
* password.setAutofillHints("current-password");
- * password.setIdEntry("password");
+ * password.setHtmlInfo(child.newHtmlInfoBuilder("input")
+ * .addAttribute("name", "password")
+ * .addAttribute("id", "pass")
+ * .build());
* password.setHint("Password");
* password.setAutofillType(View.AUTOFILL_TYPE_TEXT);
* password.setDataIsSensitive(false); // Value is not set
@@ -2698,9 +2703,11 @@
* <p>Would map to:
*
* <pre class="prettyprint">
- * ViewStructure iframe = //structure.newChildForAutofill(...);
- * iframe.setClassName("HTML.iframe");
- * iframe.setUrl("http://example.com/login");
+ * int index = structure.addChildCount(1);
+ * ViewStructure iframe = structure.newChildFor(index);
+ * iframe.setHtmlInfo(child.newHtmlInfoBuilder("iframe")
+ * .addAttribute("url", "http://example.com/login")
+ * .build());
* </pre>
*/
@Override
diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java
index 8edd637..088e726 100644
--- a/core/java/com/android/internal/os/FuseAppLoop.java
+++ b/core/java/com/android/internal/os/FuseAppLoop.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.os.ProxyFileDescriptorCallback;
import android.os.Handler;
+import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.OsConstants;
@@ -28,10 +29,11 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ThreadFactory;
-public class FuseAppLoop {
+public class FuseAppLoop implements Handler.Callback {
private static final String TAG = "FuseAppLoop";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final int ROOT_INODE = 1;
@@ -43,13 +45,11 @@
}
};
private static final int FUSE_OK = 0;
+ private static final int ARGS_POOL_SIZE = 50;
private final Object mLock = new Object();
private final int mMountPointId;
private final Thread mThread;
- private final Handler mDefaultHandler;
-
- private static final int CMD_FSYNC = 1;
@GuardedBy("mLock")
private final SparseArray<CallbackEntry> mCallbackMap = new SparseArray<>();
@@ -57,6 +57,9 @@
@GuardedBy("mLock")
private final BytesMap mBytesMap = new BytesMap();
+ @GuardedBy("mLock")
+ private final LinkedList<Args> mArgsPool = new LinkedList<>();
+
/**
* Sequential number can be used as file name and inode in AppFuse.
* 0 is regarded as an error, 1 is mount point. So we start the number from 2.
@@ -83,7 +86,6 @@
}
});
mThread.start();
- mDefaultHandler = null;
}
public int registerCallback(@NonNull ProxyFileDescriptorCallback callback,
@@ -110,7 +112,8 @@
break;
}
}
- mCallbackMap.put(id, new CallbackEntry(callback, handler));
+ mCallbackMap.put(id, new CallbackEntry(
+ callback, new Handler(handler.getLooper(), this)));
return id;
}
}
@@ -137,78 +140,113 @@
// Defined in FuseBuffer.h
private static final int FUSE_MAX_WRITE = 256 * 1024;
+ @Override
+ public boolean handleMessage(Message msg) {
+ final Args args = (Args) msg.obj;
+ final CallbackEntry entry = args.entry;
+ final long inode = args.inode;
+ final long unique = args.unique;
+ final int size = args.size;
+ final long offset = args.offset;
+ final byte[] data = args.data;
+
+ try {
+ switch (msg.what) {
+ case FUSE_LOOKUP: {
+ final long fileSize = entry.callback.onGetSize();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyLookup(mInstance, unique, inode, fileSize);
+ }
+ recycleLocked(args);
+ }
+ break;
+ }
+ case FUSE_GETATTR: {
+ final long fileSize = entry.callback.onGetSize();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyGetAttr(mInstance, unique, inode, fileSize);
+ }
+ recycleLocked(args);
+ }
+ break;
+ }
+ case FUSE_READ:
+ final int readSize = entry.callback.onRead(
+ offset, size, data);
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyRead(mInstance, unique, readSize, data);
+ }
+ recycleLocked(args);
+ }
+ break;
+ case FUSE_WRITE:
+ final int writeSize = entry.callback.onWrite(offset, size, data);
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyWrite(mInstance, unique, writeSize);
+ }
+ recycleLocked(args);
+ }
+ break;
+ case FUSE_FSYNC:
+ entry.callback.onFsync();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replySimple(mInstance, unique, FUSE_OK);
+ }
+ recycleLocked(args);
+ }
+ break;
+ case FUSE_RELEASE:
+ entry.callback.onRelease();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replySimple(mInstance, unique, FUSE_OK);
+ }
+ mBytesMap.stopUsing(entry.getThreadId());
+ recycleLocked(args);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown FUSE command: " + msg.what);
+ }
+ } catch (Exception error) {
+ synchronized (mLock) {
+ Log.e(TAG, "", error);
+ replySimpleLocked(unique, getError(error));
+ recycleLocked(args);
+ }
+ }
+
+ return true;
+ }
+
// Called by JNI.
@SuppressWarnings("unused")
private void onCommand(int command, long unique, long inode, long offset, int size,
byte[] data) {
- synchronized(mLock) {
+ synchronized (mLock) {
try {
- final CallbackEntry entry = getCallbackEntryOrThrowLocked(inode);
- entry.postRunnable(() -> {
- try {
- switch (command) {
- case FUSE_LOOKUP: {
- final long fileSize = entry.callback.onGetSize();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyLookup(mInstance, unique, inode, fileSize);
- }
- }
- break;
- }
- case FUSE_GETATTR: {
- final long fileSize = entry.callback.onGetSize();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyGetAttr(mInstance, unique, inode, fileSize);
- }
- }
- break;
- }
- case FUSE_READ:
- final int readSize = entry.callback.onRead(offset, size, data);
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyRead(mInstance, unique, readSize, data);
- }
- }
- break;
- case FUSE_WRITE:
- final int writeSize = entry.callback.onWrite(offset, size, data);
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyWrite(mInstance, unique, writeSize);
- }
- }
- break;
- case FUSE_FSYNC:
- entry.callback.onFsync();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replySimple(mInstance, unique, FUSE_OK);
- }
- }
- break;
- case FUSE_RELEASE:
- entry.callback.onRelease();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replySimple(mInstance, unique, FUSE_OK);
- }
- mBytesMap.stopUsing(entry.getThreadId());
- }
- break;
- default:
- throw new IllegalArgumentException(
- "Unknown FUSE command: " + command);
- }
- } catch (Exception error) {
- Log.e(TAG, "", error);
- replySimple(unique, getError(error));
- }
- });
- } catch (ErrnoException error) {
- Log.e(TAG, "", error);
+ final Args args;
+ if (mArgsPool.size() == 0) {
+ args = new Args();
+ } else {
+ args = mArgsPool.pop();
+ }
+ args.unique = unique;
+ args.inode = inode;
+ args.offset = offset;
+ args.size = size;
+ args.data = data;
+ args.entry = getCallbackEntryOrThrowLocked(inode);
+ if (!args.entry.handler.sendMessage(
+ Message.obtain(args.entry.handler, command, 0, 0, args))) {
+ throw new ErrnoException("onCommand", OsConstants.EBADF);
+ }
+ } catch (Exception error) {
replySimpleLocked(unique, getError(error));
}
}
@@ -253,9 +291,9 @@
return entry;
}
- private void replySimple(long unique, int result) {
- synchronized (mLock) {
- replySimpleLocked(unique, result);
+ private void recycleLocked(Args args) {
+ if (mArgsPool.size() < ARGS_POOL_SIZE) {
+ mArgsPool.add(args);
}
}
@@ -296,13 +334,6 @@
long getThreadId() {
return handler.getLooper().getThread().getId();
}
-
- void postRunnable(Runnable runnable) throws ErrnoException {
- final boolean result = handler.post(runnable);
- if (!result) {
- throw new ErrnoException("postRunnable", OsConstants.EBADF);
- }
- }
}
/**
@@ -342,4 +373,13 @@
mEntries.clear();
}
}
+
+ private static class Args {
+ long unique;
+ long inode;
+ long offset;
+ int size;
+ byte[] data;
+ CallbackEntry entry;
+ }
}
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index 64e1d10..4659d3c 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -16,7 +16,12 @@
package com.android.internal.util;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
import android.os.Handler;
+import android.util.Slog;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -25,6 +30,9 @@
* Helper functions for dumping the state of system services.
*/
public final class DumpUtils {
+ private static final String TAG = "DumpUtils";
+ private static final boolean DEBUG = true;
+
private DumpUtils() {
}
@@ -55,4 +63,90 @@
public interface Dump {
void dump(PrintWriter pw, String prefix);
}
+
+ private static void logMessage(PrintWriter pw, String msg) {
+ if (DEBUG) Slog.v(TAG, msg);
+ pw.println(msg);
+ }
+
+ /**
+ * Verify that caller holds {@link android.Manifest.permission#DUMP}.
+ *
+ * @return true if access should be granted.
+ * @hide
+ */
+ public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
+ if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " due to missing android.permission.DUMP permission");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Verify that caller holds
+ * {@link android.Manifest.permission#PACKAGE_USAGE_STATS} and that they
+ * have {@link AppOpsManager#OP_GET_USAGE_STATS} access.
+ *
+ * @return true if access should be granted.
+ * @hide
+ */
+ public static boolean checkUsageStatsPermission(Context context, String tag, PrintWriter pw) {
+ // System internals always get access
+ final int uid = Binder.getCallingUid();
+ switch (uid) {
+ case android.os.Process.ROOT_UID:
+ case android.os.Process.SYSTEM_UID:
+ case android.os.Process.SHELL_UID:
+ return true;
+ }
+
+ // Caller always needs to hold permission
+ if (context.checkCallingOrSelfPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
+ != PackageManager.PERMISSION_GRANTED) {
+ logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " due to missing android.permission.PACKAGE_USAGE_STATS permission");
+ return false;
+ }
+
+ // And finally, caller needs to have appops access; this is totally
+ // hacky, but it's the easiest way to wire this up without retrofitting
+ // Binder.dump() to pass through package names.
+ final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+ final String[] pkgs = context.getPackageManager().getPackagesForUid(uid);
+ if (pkgs != null) {
+ for (String pkg : pkgs) {
+ if (appOps.checkOpNoThrow(AppOpsManager.OP_GET_USAGE_STATS, uid,
+ pkg) == AppOpsManager.MODE_ALLOWED) {
+ appOps.noteOp(AppOpsManager.OP_GET_USAGE_STATS, uid, pkg);
+ if (DEBUG) Slog.v(TAG, "Found package " + pkg + " with "
+ + "android:get_usage_stats access");
+ return true;
+ }
+ }
+ }
+
+ logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " due to android:get_usage_stats app-op not allowed");
+ return false;
+ }
+
+ /**
+ * Verify that caller holds both {@link android.Manifest.permission#DUMP}
+ * and {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, and that
+ * they have {@link AppOpsManager#OP_GET_USAGE_STATS} access.
+ *
+ * @return true if access should be granted.
+ * @hide
+ */
+ public static boolean checkDumpAndUsageStatsPermission(Context context, String tag,
+ PrintWriter pw) {
+ return checkDumpPermission(context, tag, pw) && checkUsageStatsPermission(context, tag, pw);
+ }
}
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index e64a574..3dc1be6 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -39,6 +39,7 @@
jfieldID gOptions_heightFieldID;
jfieldID gOptions_mimeFieldID;
jfieldID gOptions_outConfigFieldID;
+jfieldID gOptions_outColorSpaceFieldID;
jfieldID gOptions_mCancelID;
jfieldID gOptions_bitmapFieldID;
@@ -50,6 +51,20 @@
jclass gBitmapConfig_class;
jmethodID gBitmapConfig_nativeToConfigMethodID;
+jclass gColorSpace_class;
+jmethodID gColorSpace_getMethodID;
+jmethodID gColorSpace_matchMethodID;
+
+jclass gColorSpaceRGB_class;
+jmethodID gColorSpaceRGB_constructorMethodID;
+
+jclass gColorSpace_Named_class;
+jfieldID gColorSpace_Named_sRGBFieldID;
+jfieldID gColorSpace_Named_LinearExtendedSRGBFieldID;
+
+jclass gTransferParameters_class;
+jmethodID gTransferParameters_constructorMethodID;
+
using namespace android;
jstring encodedFormatToString(JNIEnv* env, SkEncodedImageFormat format) {
@@ -228,6 +243,70 @@
needsFineScale(fullSize.height(), decodedSize.height(), sampleSize);
}
+static jobject getColorSpace(JNIEnv* env,
+ sk_sp<SkColorSpace>& decodeColorSpace, SkColorType decodeColorType) {
+ jobject colorSpace = nullptr;
+
+ // No need to match, we know what the output color space will be
+ if (decodeColorType == kRGBA_F16_SkColorType) {
+ jobject linearExtendedSRGB = env->GetStaticObjectField(
+ gColorSpace_Named_class, gColorSpace_Named_LinearExtendedSRGBFieldID);
+ colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
+ gColorSpace_getMethodID, linearExtendedSRGB);
+ } else {
+ // Same here, no need to match
+ if (decodeColorSpace->isSRGB()) {
+ jobject sRGB = env->GetStaticObjectField(
+ gColorSpace_Named_class, gColorSpace_Named_sRGBFieldID);
+ colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
+ gColorSpace_getMethodID, sRGB);
+ } else if (decodeColorSpace.get() != nullptr) {
+ // Try to match against known RGB color spaces using the CIE XYZ D50
+ // conversion matrix and numerical transfer function parameters
+ SkMatrix44 xyzMatrix(SkMatrix44::kUninitialized_Constructor);
+ LOG_ALWAYS_FATAL_IF(!decodeColorSpace->toXYZD50(&xyzMatrix));
+
+ SkColorSpaceTransferFn transferParams;
+ // We can only handle numerical transfer functions at the moment
+ LOG_ALWAYS_FATAL_IF(!decodeColorSpace->isNumericalTransferFn(&transferParams));
+
+ jobject params = env->NewObject(gTransferParameters_class,
+ gTransferParameters_constructorMethodID,
+ transferParams.fA, transferParams.fB, transferParams.fC,
+ transferParams.fD, transferParams.fE, transferParams.fF,
+ transferParams.fG);
+
+ jfloatArray xyzArray = env->NewFloatArray(9);
+ jfloat xyz[9] = {
+ xyzMatrix.getFloat(0, 0),
+ xyzMatrix.getFloat(1, 0),
+ xyzMatrix.getFloat(2, 0),
+ xyzMatrix.getFloat(0, 1),
+ xyzMatrix.getFloat(1, 1),
+ xyzMatrix.getFloat(2, 1),
+ xyzMatrix.getFloat(0, 2),
+ xyzMatrix.getFloat(1, 2),
+ xyzMatrix.getFloat(2, 2)
+ };
+ env->SetFloatArrayRegion(xyzArray, 0, 9, xyz);
+
+ colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
+ gColorSpace_matchMethodID, xyzArray, params);
+
+ if (colorSpace == nullptr) {
+ // We couldn't find an exact match, let's create a new color space
+ // instance with the 3x3 conversion matrix and transfer function
+ colorSpace = env->NewObject(gColorSpaceRGB_class,
+ gColorSpaceRGB_constructorMethodID,
+ env->NewStringUTF("Unknown"), xyzArray, params);
+ }
+
+ env->DeleteLocalRef(xyzArray);
+ }
+ }
+ return colorSpace;
+}
+
static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding, jobject options) {
// This function takes ownership of the input stream. Since the SkAndroidCodec
// will take ownership of the stream, we don't necessarily need to take ownership
@@ -263,6 +342,7 @@
env->SetIntField(options, gOptions_heightFieldID, -1);
env->SetObjectField(options, gOptions_mimeFieldID, 0);
env->SetObjectField(options, gOptions_outConfigFieldID, 0);
+ env->SetObjectField(options, gOptions_outColorSpaceFieldID, 0);
jobject jconfig = env->GetObjectField(options, gOptions_configFieldID);
prefColorType = GraphicsJNI::getNativeBitmapColorType(env, jconfig);
@@ -319,6 +399,7 @@
// Set the decode colorType
SkColorType decodeColorType = codec->computeOutputColorType(prefColorType);
+ sk_sp<SkColorSpace> decodeColorSpace = codec->computeOutputColorSpace(decodeColorType);
// Set the options and return if the client only wants the size.
if (options != NULL) {
@@ -345,6 +426,9 @@
gBitmapConfig_nativeToConfigMethodID, configID);
env->SetObjectField(options, gOptions_outConfigFieldID, config);
+ env->SetObjectField(options, gOptions_outColorSpaceFieldID,
+ getColorSpace(env, decodeColorSpace, decodeColorType));
+
if (onlyDecodeSize) {
return nullptr;
}
@@ -412,7 +496,7 @@
SkAlphaType alphaType = codec->computeOutputAlphaType(requireUnpremultiplied);
const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(),
- decodeColorType, alphaType, codec->computeOutputColorSpace(decodeColorType));
+ decodeColorType, alphaType, decodeColorSpace);
// For wide gamut images, we will leave the color space on the SkBitmap. Otherwise,
// use the default.
@@ -725,6 +809,8 @@
gOptions_mimeFieldID = GetFieldIDOrDie(env, options_class, "outMimeType", "Ljava/lang/String;");
gOptions_outConfigFieldID = GetFieldIDOrDie(env, options_class, "outConfig",
"Landroid/graphics/Bitmap$Config;");
+ gOptions_outColorSpaceFieldID = GetFieldIDOrDie(env, options_class, "outColorSpace",
+ "Landroid/graphics/ColorSpace;");
gOptions_mCancelID = GetFieldIDOrDie(env, options_class, "mCancel", "Z");
jclass bitmap_class = FindClassOrDie(env, "android/graphics/Bitmap");
@@ -741,6 +827,29 @@
gBitmapConfig_nativeToConfigMethodID = GetStaticMethodIDOrDie(env, gBitmapConfig_class,
"nativeToConfig", "(I)Landroid/graphics/Bitmap$Config;");
+ gColorSpace_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/ColorSpace"));
+ gColorSpace_getMethodID = GetStaticMethodIDOrDie(env, gColorSpace_class,
+ "get", "(Landroid/graphics/ColorSpace$Named;)Landroid/graphics/ColorSpace;");
+ gColorSpace_matchMethodID = GetStaticMethodIDOrDie(env, gColorSpace_class, "match",
+ "([FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)Landroid/graphics/ColorSpace;");
+
+ gColorSpaceRGB_class = MakeGlobalRefOrDie(env,
+ FindClassOrDie(env, "android/graphics/ColorSpace$Rgb"));
+ gColorSpaceRGB_constructorMethodID = GetMethodIDOrDie(env, gColorSpaceRGB_class,
+ "<init>", "(Ljava/lang/String;[FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)V");
+
+ gColorSpace_Named_class = MakeGlobalRefOrDie(env,
+ FindClassOrDie(env, "android/graphics/ColorSpace$Named"));
+ gColorSpace_Named_sRGBFieldID = GetStaticFieldIDOrDie(env,
+ gColorSpace_Named_class, "SRGB", "Landroid/graphics/ColorSpace$Named;");
+ gColorSpace_Named_LinearExtendedSRGBFieldID = GetStaticFieldIDOrDie(env,
+ gColorSpace_Named_class, "LINEAR_EXTENDED_SRGB", "Landroid/graphics/ColorSpace$Named;");
+
+ gTransferParameters_class = MakeGlobalRefOrDie(env, FindClassOrDie(env,
+ "android/graphics/ColorSpace$Rgb$TransferParameters"));
+ gTransferParameters_constructorMethodID = GetMethodIDOrDie(env, gTransferParameters_class,
+ "<init>", "(DDDDDDD)V");
+
return android::RegisterMethodsOrDie(env, "android/graphics/BitmapFactory",
gMethods, NELEM(gMethods));
}
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index b926270..d606c2d 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -78,6 +78,9 @@
camera_frame_metadata_t *metadata);
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
virtual void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle);
+ virtual void postRecordingFrameHandleTimestampBatch(
+ const std::vector<nsecs_t>& timestamps,
+ const std::vector<native_handle_t*>& handles);
void postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata);
void addCallbackBuffer(JNIEnv *env, jbyteArray cbb, int msgType);
void setCallbackMode(JNIEnv *env, bool installed, bool manualMode);
@@ -362,6 +365,22 @@
}
}
+void JNICameraContext::postRecordingFrameHandleTimestampBatch(
+ const std::vector<nsecs_t>&,
+ const std::vector<native_handle_t*>& handles) {
+ // Video buffers are not needed at app layer so just return the video buffers here.
+ // This may be called when stagefright just releases camera but there are still outstanding
+ // video buffers.
+ if (mCamera != nullptr) {
+ mCamera->releaseRecordingFrameHandleBatch(handles);
+ } else {
+ for (auto& handle : handles) {
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ }
+ }
+}
+
void JNICameraContext::postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata)
{
jobjectArray obj = NULL;
diff --git a/core/jni/android_text_AndroidBidi.cpp b/core/jni/android_text_AndroidBidi.cpp
index 2a3f036..d744b7c 100644
--- a/core/jni/android_text_AndroidBidi.cpp
+++ b/core/jni/android_text_AndroidBidi.cpp
@@ -22,6 +22,7 @@
#include "utils/misc.h"
#include "utils/Log.h"
#include "unicode/ubidi.h"
+#include <minikin/Emoji.h>
namespace android {
@@ -38,6 +39,9 @@
if (info != NULL) {
UErrorCode status = U_ZERO_ERROR;
UBiDi* bidi = ubidi_openSized(n, 0, &status);
+ // Set callbacks to override bidi classes of new emoji
+ ubidi_setClassCallback(
+ bidi, minikin::emojiBidiOverride, nullptr, nullptr, nullptr, &status);
ubidi_setPara(bidi, chs, n, dir, NULL, &status);
if (U_SUCCESS(status)) {
for (int i = 0; i < n; ++i) {
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 5e3488c..344f3c8 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -181,10 +181,6 @@
<allow-in-power-save package="com.android.cellbroadcastreceiver" />
<allow-in-power-save package="com.android.shell" />
- <!-- Package in charge of provisioning that needs to freely run in the background -->
- <!-- STOPSHIP: Revert this once it is fixed properly -->
- <allow-in-power-save package="com.android.managedprovisioning" />
-
<!-- These are the packages that are white-listed to be able to run as system user -->
<system-user-whitelisted-app package="com.android.settings" />
diff --git a/docs/html/reference/images/graphics/composite_ADD.png b/docs/html/reference/images/graphics/composite_ADD.png
new file mode 100644
index 0000000..90932c5
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_ADD.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_CLEAR.png b/docs/html/reference/images/graphics/composite_CLEAR.png
new file mode 100644
index 0000000..7c0731d
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_CLEAR.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_DARKEN.png b/docs/html/reference/images/graphics/composite_DARKEN.png
new file mode 100644
index 0000000..a798b97
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_DARKEN.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_DST.png b/docs/html/reference/images/graphics/composite_DST.png
new file mode 100644
index 0000000..6dde48f
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_DST.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_DST_ATOP.png b/docs/html/reference/images/graphics/composite_DST_ATOP.png
new file mode 100644
index 0000000..c6767bd
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_DST_ATOP.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_DST_IN.png b/docs/html/reference/images/graphics/composite_DST_IN.png
new file mode 100644
index 0000000..cf50a7b
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_DST_IN.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_DST_OUT.png b/docs/html/reference/images/graphics/composite_DST_OUT.png
new file mode 100644
index 0000000..ee8a46e
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_DST_OUT.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_DST_OVER.png b/docs/html/reference/images/graphics/composite_DST_OVER.png
new file mode 100644
index 0000000..1838972
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_DST_OVER.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_LIGHTEN.png b/docs/html/reference/images/graphics/composite_LIGHTEN.png
new file mode 100644
index 0000000..8fc0a10
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_LIGHTEN.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_MULTIPLY.png b/docs/html/reference/images/graphics/composite_MULTIPLY.png
new file mode 100644
index 0000000..8816ab0
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_MULTIPLY.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_OVERLAY.png b/docs/html/reference/images/graphics/composite_OVERLAY.png
new file mode 100644
index 0000000..700a6b2
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_OVERLAY.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_SCREEN.png b/docs/html/reference/images/graphics/composite_SCREEN.png
new file mode 100644
index 0000000..b698819
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_SCREEN.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_SRC.png b/docs/html/reference/images/graphics/composite_SRC.png
new file mode 100644
index 0000000..2d70a54
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_SRC.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_SRC_ATOP.png b/docs/html/reference/images/graphics/composite_SRC_ATOP.png
new file mode 100644
index 0000000..111869e
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_SRC_ATOP.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_SRC_IN.png b/docs/html/reference/images/graphics/composite_SRC_IN.png
new file mode 100644
index 0000000..1d6145b
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_SRC_IN.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_SRC_OUT.png b/docs/html/reference/images/graphics/composite_SRC_OUT.png
new file mode 100644
index 0000000..39c0c17
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_SRC_OUT.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_SRC_OVER.png b/docs/html/reference/images/graphics/composite_SRC_OVER.png
new file mode 100644
index 0000000..1489487
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_SRC_OVER.png
Binary files differ
diff --git a/docs/html/reference/images/graphics/composite_XOR.png b/docs/html/reference/images/graphics/composite_XOR.png
new file mode 100644
index 0000000..6d0c5ba
--- /dev/null
+++ b/docs/html/reference/images/graphics/composite_XOR.png
Binary files differ
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index a3c6c6e..ceedc1f 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -361,6 +361,15 @@
public Bitmap.Config outConfig;
/**
+ * If known, the color space the decoded bitmap will have. Note that the
+ * output color space is not guaranteed to be the color space the bitmap
+ * is encoded with. If not known (when the config is
+ * {@link Bitmap.Config#ALPHA_8} for instance), or there is an error,
+ * it is set to null.
+ */
+ public ColorSpace outColorSpace;
+
+ /**
* Temp storage to use for decoding. Suggest 16K or so.
*/
public byte[] inTempStorage;
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 929ac22..e03dcf3 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -143,7 +143,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_renderer.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_renderer.png" />
* <figcaption style="text-align: center;">DCI-P3 vs ProPhoto RGB</figcaption>
* </p>
*
@@ -281,7 +281,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <figcaption style="text-align: center;">sRGB</figcaption>
* </p>
*/
@@ -308,7 +308,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <figcaption style="text-align: center;">sRGB</figcaption>
* </p>
*/
@@ -347,7 +347,7 @@
* <tr><td>Range</td><td colspan="4">\([-0.799..2.399[\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <figcaption style="text-align: center;">Extended sRGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -374,7 +374,7 @@
* <tr><td>Range</td><td colspan="4">\([-0.5..7.499[\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <figcaption style="text-align: center;">Extended sRGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -409,7 +409,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_bt709.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_bt709.png" />
* <figcaption style="text-align: center;">BT.709</figcaption>
* </p>
*/
@@ -444,7 +444,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_bt2020.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_bt2020.png" />
* <figcaption style="text-align: center;">BT.2020 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -471,7 +471,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_dci_p3.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_dci_p3.png" />
* <figcaption style="text-align: center;">DCI-P3 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -506,7 +506,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_display_p3.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_display_p3.png" />
* <figcaption style="text-align: center;">Display P3 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -541,7 +541,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_ntsc_1953.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_ntsc_1953.png" />
* <figcaption style="text-align: center;">NTSC 1953 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -576,7 +576,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_smpte_c.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_smpte_c.png" />
* <figcaption style="text-align: center;">SMPTE-C (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -603,7 +603,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_adobe_rgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_adobe_rgb.png" />
* <figcaption style="text-align: center;">Adobe RGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -638,7 +638,7 @@
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_pro_photo_rgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_pro_photo_rgb.png" />
* <figcaption style="text-align: center;">ProPhoto RGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -665,7 +665,7 @@
* <tr><td>Range</td><td colspan="4">\([-65504.0, 65504.0]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_aces.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_aces.png" />
* <figcaption style="text-align: center;">ACES (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -692,7 +692,7 @@
* <tr><td>Range</td><td colspan="4">\([-65504.0, 65504.0]\)</td></tr>
* </table>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_acescg.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_acescg.png" />
* <figcaption style="text-align: center;">ACEScg (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -1931,7 +1931,7 @@
* are internally converted to xyY.</p>
*
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <figcaption style="text-align: center;">sRGB primaries and white point</figcaption>
* </p>
*
@@ -1989,7 +1989,7 @@
* the range \([-65504, 65504]\).</p>
*
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <figcaption style="text-align: center;">Extended sRGB and its large range</figcaption>
* </p>
*
@@ -3703,7 +3703,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
* <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
* </p>
*
@@ -3746,7 +3746,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
* <figcaption style="text-align: center;">Clipping disabled</figcaption>
* </p>
*
@@ -3759,7 +3759,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
* <figcaption style="text-align: center;">Clipping enabled</figcaption>
* </p>
*
@@ -3789,7 +3789,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_ucs.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_ucs.png" />
* <figcaption style="text-align: center;">CIE 1976 UCS diagram</figcaption>
* </p>
*
@@ -3847,7 +3847,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
* <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
* </p>
*
@@ -3863,7 +3863,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
* <figcaption style="text-align: center;">sRGB, DCI-P3, ACES and scRGB</figcaption>
* </p>
*
@@ -3901,7 +3901,7 @@
* .render();
* </pre>
* <p>
- * <img src="{@docRoot}reference/android/images/graphics/colorspace_points.png" />
+ * <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_points.png" />
* <figcaption style="text-align: center;">
* Locating colors on the chromaticity diagram
* </figcaption>
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index f4bf079..c4f7dc3 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1067,19 +1067,23 @@
}
/**
- * Get the paint's xfermode object.
+ * Get the paint's transfer mode object.
*
- * @return the paint's xfermode (or null)
+ * @return the paint's transfer mode (or null)
*/
public Xfermode getXfermode() {
return mXfermode;
}
/**
- * Set or clear the xfermode object.
+ * Set or clear the transfer mode object. A transfer mode defines how
+ * source pixels (generate by a drawing command) are composited with
+ * the destination pixels (content of the render target).
* <p />
- * Pass null to clear any previous xfermode.
+ * Pass null to clear any previous transfer mode.
* As a convenience, the parameter passed is also returned.
+ * <p />
+ * {@link PorterDuffXfermode} is the most common transfer mode.
*
* @param xfermode May be null. The xfermode to be installed in the paint
* @return xfermode
diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index 2bbbff3..d7d3049 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -16,46 +16,345 @@
package android.graphics;
+/**
+ * <p>This class contains the list of alpha compositing and blending modes
+ * that can be passed to {@link PorterDuffXfermode}, a specialized implementation
+ * of {@link Paint}'s {@link Paint#setXfermode(Xfermode) transfer mode}.
+ * All the available modes can be found in the {@link Mode} enum.</p>
+ */
public class PorterDuff {
+ /**
+ * {@usesMathJax}
+ *
+ * <h3>Porter-Duff</h3>
+ *
+ * <p>The name of the parent class is an homage to the work of Thomas Porter and
+ * Tom Duff, presented in their seminal 1984 paper titled "Compositing Digital Images".
+ * In this paper, the authors describe 12 compositing operators that govern how to
+ * compute the color resulting of the composition of a source (the graphics object
+ * to render) with a destination (the content of the render target).</p>
+ *
+ * <p>"Compositing Digital Images" was published in <em>Computer Graphics</em>
+ * Volume 18, Number 3 dated July 1984.</p>
+ *
+ * <p>Because the work of Porter and Duff focuses solely on the effects of the alpha
+ * channel of the source and destination, the 12 operators described in the original
+ * paper are called alpha compositing modes here.</p>
+ *
+ * <p>For convenience, this class also provides several blending modes, which similarly
+ * define the result of compositing a source and a destination but without being
+ * constrained to the alpha channel. These blending modes are not defined by Porter
+ * and Duff but have been included in this class for convenience purposes.</p>
+ *
+ * <h3>Diagrams</h3>
+ *
+ * <p>All the example diagrams presented below use the same source and destination
+ * images:</p>
+ *
+ * <table summary="Source and Destination" style="background-color: transparent;">
+ * <tr>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC.png" />
+ * <figcaption>Source image</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST.png" />
+ * <figcaption>Destination image</figcaption>
+ * </td>
+ * </tr>
+ * </table>
+ *
+ * <p>The order of drawing operations used to generate each diagram is shown in the
+ * following code snippet:</p>
+ *
+ * <pre class="prettyprint">
+ * Paint paint = new Paint();
+ * canvas.drawBitmap(destinationImage, 0, 0, paint);
+ *
+ * PorterDuff.Mode mode = // choose a mode
+ * paint.setXfermode(new PorterDuffXfermode(mode));
+ *
+ * canvas.drawBitmap(sourceImage, 0, 0, paint);
+ * </pre>
- // these value must match their native equivalents. See SkXfermode.h
+ *
+ * <h3>Alpha compositing modes</h3>
+ *
+ * <table summary="Alpha compositing modes" style="background-color: transparent;">
+ * <tr>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC.png" />
+ * <figcaption>{@link #SRC Source}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_OVER.png" />
+ * <figcaption>{@link #SRC_OVER Source Over}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_IN.png" />
+ * <figcaption>{@link #SRC_IN Source In}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_ATOP.png" />
+ * <figcaption>{@link #SRC_ATOP Source Atop}</figcaption>
+ * </td>
+ * </tr>
+ * <tr>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST.png" />
+ * <figcaption>{@link #DST Destination}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_OVER.png" />
+ * <figcaption>{@link #DST_OVER Destination Over}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_IN.png" />
+ * <figcaption>{@link #DST_IN Destination In}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_ATOP.png" />
+ * <figcaption>{@link #DST_ATOP Destination Atop}</figcaption>
+ * </td>
+ * </tr>
+ * <tr>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_CLEAR.png" />
+ * <figcaption>{@link #CLEAR Clear}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_OUT.png" />
+ * <figcaption>{@link #SRC_OUT Source Out}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_OUT.png" />
+ * <figcaption>{@link #DST_OUT Destination Out}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_XOR.png" />
+ * <figcaption>{@link #XOR Exclusive Or}</figcaption>
+ * </td>
+ * </tr>
+ * </table>
+ *
+ * <h3>Blending modes</h3>
+ *
+ * <table summary="Blending modes" style="background-color: transparent;">
+ * <tr>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DARKEN.png" />
+ * <figcaption>{@link #DARKEN Darken}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_LIGHTEN.png" />
+ * <figcaption>{@link #LIGHTEN Lighten}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_MULTIPLY.png" />
+ * <figcaption>{@link #MULTIPLY Multiply}</figcaption>
+ * </td>
+ * </tr>
+ * <tr>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SCREEN.png" />
+ * <figcaption>{@link #SCREEN Screen}</figcaption>
+ * </td>
+ * <td style="border: none; text-align: center;">
+ * <img src="{@docRoot}reference/android/images/graphics/composite_OVERLAY.png" />
+ * <figcaption>{@link #OVERLAY Overlay}</figcaption>
+ * </td>
+ * </tr>
+ * </table>
+ *
+ * <h3>Compositing equations</h3>
+ *
+ * <p>The documentation of each individual alpha compositing or blending mode below
+ * provides the exact equation used to compute alpha and color value of the result
+ * of the composition of a source and destination.</p>
+ *
+ * <p>The result (or output) alpha value is noted \(\alpha_{out}\). The result (or output)
+ * color value is noted \(C_{out}\).</p>
+ */
public enum Mode {
- /** [0, 0] */
+ // these value must match their native equivalents. See SkXfermode.h
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_CLEAR.png" />
+ * <figcaption>Destination pixels covered by the source are cleared to 0.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = 0\)</p>
+ * <p>\(C_{out} = 0\)</p>
+ */
CLEAR (0),
- /** [Sa, Sc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC.png" />
+ * <figcaption>The source pixels replace the destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src}\)</p>
+ * <p>\(C_{out} = C_{src}\)</p>
+ */
SRC (1),
- /** [Da, Dc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST.png" />
+ * <figcaption>The source pixels are discarded, leaving the destination intact.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{dst}\)</p>
+ * <p>\(C_{out} = C_{dst}\)</p>
+ */
DST (2),
- /** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_OVER.png" />
+ * <figcaption>The source pixels are drawn over the destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} + (1 - \alpha_{src}) * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p>
+ */
SRC_OVER (3),
- /** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_OVER.png" />
+ * <figcaption>The source pixels are drawn behind the destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{dst} + (1 - \alpha_{dst}) * \alpha_{src}\)</p>
+ * <p>\(C_{out} = C_{dst} + (1 - \alpha_{dst}) * C_{src}\)</p>
+ */
DST_OVER (4),
- /** [Sa * Da, Sc * Da] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_IN.png" />
+ * <figcaption>Keeps the source pixels that cover the destination pixels,
+ * discards the remaining source and destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = C_{src} * \alpha_{dst}\)</p>
+ */
SRC_IN (5),
- /** [Sa * Da, Sa * Dc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_IN.png" />
+ * <figcaption>Keeps the destination pixels that cover source pixels,
+ * discards the remaining source and destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = C_{dst} * \alpha_{src}\)</p>
+ */
DST_IN (6),
- /** [Sa * (1 - Da), Sc * (1 - Da)] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_OUT.png" />
+ * <figcaption>Keeps the source pixels that do not cover destination pixels.
+ * Discards source pixels that cover destination pixels. Discards all
+ * destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = (1 - \alpha_{dst}) * \alpha_{src}\)</p>
+ * <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src}\)</p>
+ */
SRC_OUT (7),
- /** [Da * (1 - Sa), Dc * (1 - Sa)] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_OUT.png" />
+ * <figcaption>Keeps the destination pixels that are not covered by source pixels.
+ * Discards destination pixels that are covered by source pixels. Discards all
+ * source pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = (1 - \alpha_{src}) * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = (1 - \alpha_{src}) * C_{dst}\)</p>
+ */
DST_OUT (8),
- /** [Da, Sc * Da + (1 - Sa) * Dc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SRC_ATOP.png" />
+ * <figcaption>Discards the source pixels that do not cover destination pixels.
+ * Draws remaining source pixels over destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{dst}\)</p>
+ * <p>\(C_{out} = \alpha_{dst} * C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p>
+ */
SRC_ATOP (9),
- /** [Sa, Sa * Dc + Sc * (1 - Da)] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DST_ATOP.png" />
+ * <figcaption>Discards the destination pixels that are not covered by source pixels.
+ * Draws remaining destination pixels over source pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src}\)</p>
+ * <p>\(C_{out} = \alpha_{src} * C_{dst} + (1 - \alpha_{dst}) * C_{src}\)</p>
+ */
DST_ATOP (10),
- /** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_XOR.png" />
+ * <figcaption>Discards the source and destination pixels where source pixels
+ * cover destination pixels. Draws remaining source pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = (1 - \alpha_{dst}) * \alpha_{src} + (1 - \alpha_{src}) * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p>
+ */
XOR (11),
- /** [Sa + Da - Sa*Da,
- Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_DARKEN.png" />
+ * <figcaption>Retains the smallest component of the source and
+ * destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst} + min(C_{src}, C_{dst})\)</p>
+ */
DARKEN (16),
- /** [Sa + Da - Sa*Da,
- Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_LIGHTEN.png" />
+ * <figcaption>Retains the largest component of the source and
+ * destination pixel.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst} + max(C_{src}, C_{dst})\)</p>
+ */
LIGHTEN (17),
- /** [Sa * Da, Sc * Dc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_MULTIPLY.png" />
+ * <figcaption>Multiplies the source and destination pixels.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = C_{src} * C_{dst}\)</p>
+ */
MULTIPLY (13),
- /** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_SCREEN.png" />
+ * <figcaption>Adds the source and destination pixels, then subtracts the
+ * source pixels multiplied by the destination.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
+ * <p>\(C_{out} = C_{src} + C_{dst} - C_{src} * C_{dst}\)</p>
+ */
SCREEN (14),
- /** Saturate(S + D) */
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_ADD.png" />
+ * <figcaption>Adds the source pixels to the destination pixels and saturates
+ * the result.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = max(0, min(\alpha_{src} + \alpha_{dst}, 1))\)</p>
+ * <p>\(C_{out} = max(0, min(C_{src} + C_{dst}, 1))\)</p>
+ */
ADD (12),
+ /**
+ * <p>
+ * <img src="{@docRoot}reference/android/images/graphics/composite_OVERLAY.png" />
+ * <figcaption>Multiplies or screens the source and destination depending on the
+ * destination color.</figcaption>
+ * </p>
+ * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
+ * <p>\(\begin{equation}
+ * C_{out} = \begin{cases} 2 * C_{src} * C_{dst} & 2 * C_{dst} \lt \alpha_{dst} \\
+ * \alpha_{src} * \alpha_{dst} - 2 (\alpha_{dst} - C_{src}) (\alpha_{src} - C_{dst}) & otherwise \end{cases}
+ * \end{equation}\)</p>
+ */
OVERLAY (15);
Mode(int nativeInt) {
@@ -71,14 +370,14 @@
/**
* @hide
*/
- public static final int modeToInt(Mode mode) {
+ public static int modeToInt(Mode mode) {
return mode.nativeInt;
}
/**
* @hide
*/
- public static final Mode intToMode(int val) {
+ public static Mode intToMode(int val) {
switch (val) {
default:
case 0: return Mode.CLEAR;
diff --git a/graphics/java/android/graphics/PorterDuffXfermode.java b/graphics/java/android/graphics/PorterDuffXfermode.java
index 5104410..84d953d 100644
--- a/graphics/java/android/graphics/PorterDuffXfermode.java
+++ b/graphics/java/android/graphics/PorterDuffXfermode.java
@@ -16,6 +16,12 @@
package android.graphics;
+/**
+ * <p>Specialized implementation of {@link Paint}'s
+ * {@link Paint#setXfermode(Xfermode) transfer mode}. Refer to the
+ * documentation of the {@link PorterDuff.Mode} enum for more
+ * information on the available alpha compositing and blending modes.</p>
+ */
public class PorterDuffXfermode extends Xfermode {
/**
* Create an xfermode that uses the specified porter-duff mode.
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index c6c9271..643c0da 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -304,6 +304,9 @@
@Override
public void draw(Canvas canvas) {
+ if (mLayersBitmap == null) {
+ return;
+ }
if (mLayersShader == null) {
mCanvas.setBitmap(mLayersBitmap);
for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 9739319..06fc4bc 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1802,8 +1802,9 @@
* {@link #TYPE_OTHER},
* {@link #TYPE_PAL},
* {@link #TYPE_SECAM},
- * {@link #TYPE_S_DMB}, and
- * {@link #TYPE_T_DMB}.
+ * {@link #TYPE_S_DMB},
+ * {@link #TYPE_T_DMB}, and
+ * {@link #TYPE_PREVIEW}.
*
* <p>This value cannot be changed once it's set. Trying to modify it will make the update
* fail.
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index cc1e01a..37a68e0 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -220,14 +220,8 @@
public long[] getFileSystemStats(String path) {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- try {
- final StructStatVfs stat = Os.statvfs(path);
- final long totalSize = stat.f_blocks * stat.f_bsize;
- final long availSize = stat.f_bavail * stat.f_bsize;
- return new long[] { totalSize, availSize };
- } catch (ErrnoException e) {
- throw new IllegalStateException(e);
- }
+ final File file = new File(path);
+ return new long[] { file.getTotalSpace(), file.getUsableSpace() };
}
@Override
diff --git a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java b/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
index 18863ca..862f50b2 100644
--- a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
+++ b/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2017 The Android Open Source Project
*
@@ -123,10 +122,10 @@
StorageManager storageManager = getSystemService(StorageManager.class);
long freeBytes = 0;
if (uuid == StorageManager.UUID_PRIVATE_INTERNAL) { // regular equals because of null
- freeBytes = Environment.getDataDirectory().getFreeSpace();
+ freeBytes = Environment.getDataDirectory().getUsableSpace();
} else {
final VolumeInfo vol = storageManager.findVolumeByUuid(uuid);
- freeBytes = vol.getPath().getFreeSpace();
+ freeBytes = vol.getPath().getUsableSpace();
}
return Math.round(freeBytes * CACHE_RESERVE_RATIO);
}
diff --git a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
index cc1699a..df4738f 100644
--- a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
@@ -61,7 +61,7 @@
setContext(mContext);
when(mContext.getSystemService(Context.STORAGE_SERVICE)).thenReturn(mStorageManager);
- when(mFile.getFreeSpace()).thenReturn(10000L);
+ when(mFile.getUsableSpace()).thenReturn(10000L);
when(mVolume.getPath()).thenReturn(mFile);
when(mStorageManager.findVolumeByUuid(sTestVolUuid)).thenReturn(mVolume);
when(mStorageManager.findVolumeByUuid(sSecondTestVolUuid)).thenReturn(mVolume);
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index b60e2fe..b958c28 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -386,7 +386,7 @@
row.add(Root.COLUMN_TITLE, root.title);
row.add(Root.COLUMN_DOCUMENT_ID, root.docId);
row.add(Root.COLUMN_AVAILABLE_BYTES,
- root.reportAvailableBytes ? root.path.getFreeSpace() : -1);
+ root.reportAvailableBytes ? root.path.getUsableSpace() : -1);
}
}
return result;
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
index ca8edf5..40abb6c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
@@ -16,18 +16,15 @@
package com.android.settingslib.deviceinfo;
-import android.os.storage.StorageManager;
+import android.app.AppGlobals;
+import android.app.usage.StorageStatsManager;
+import android.content.Context;
import android.os.storage.VolumeInfo;
-import android.util.Log;
-
-import java.io.File;
-import java.util.Objects;
/**
* PrivateStorageInfo provides information about the total and free storage on the device.
*/
public class PrivateStorageInfo {
- private static final String TAG = "PrivateStorageInfo";
public final long freeBytes;
public final long totalBytes;
@@ -37,45 +34,23 @@
}
public static PrivateStorageInfo getPrivateStorageInfo(StorageVolumeProvider sm) {
- long totalInternalStorage = sm.getPrimaryStorageSize();
+ final Context context = AppGlobals.getInitialApplication();
+ final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
+
long privateFreeBytes = 0;
long privateTotalBytes = 0;
for (VolumeInfo info : sm.getVolumes()) {
- final File path = info.getPath();
- if (info.getType() != VolumeInfo.TYPE_PRIVATE || path == null) {
- continue;
+ if (info.getType() == VolumeInfo.TYPE_PRIVATE && info.isMountedReadable()) {
+ privateTotalBytes += stats.getTotalBytes(info.getFsUuid());
+ privateFreeBytes += stats.getFreeBytes(info.getFsUuid());
}
- privateTotalBytes += getTotalSize(info, totalInternalStorage);
- privateFreeBytes += path.getFreeSpace();
}
return new PrivateStorageInfo(privateFreeBytes, privateTotalBytes);
}
- /**
- * Returns the total size in bytes for a given volume info.
- * @param info Info of the volume to check.
- * @param totalInternalStorage Total number of bytes in the internal storage to use if the
- * volume is the internal disk.
- */
public static long getTotalSize(VolumeInfo info, long totalInternalStorage) {
- // Device could have more than one primary storage, which could be located in the
- // internal flash (UUID_PRIVATE_INTERNAL) or in an external disk.
- // If it's internal, try to get its total size from StorageManager first
- // (totalInternalStorage), because that size is more precise because it accounts for
- // the system partition.
- if (info.getType() == VolumeInfo.TYPE_PRIVATE
- && Objects.equals(info.getFsUuid(), StorageManager.UUID_PRIVATE_INTERNAL)
- && totalInternalStorage > 0) {
- return totalInternalStorage;
- } else {
- final File path = info.getPath();
- if (path == null) {
- // Should not happen, caller should have checked.
- Log.e(TAG, "info's path is null on getTotalSize(): " + info);
- return 0;
- }
- return path.getTotalSpace();
- }
+ final Context context = AppGlobals.getInitialApplication();
+ final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
+ return stats.getTotalBytes(info.getFsUuid());
}
-
}
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 635c96f..53c5b1b 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -34,6 +34,7 @@
android-support-v7-recyclerview \
android-support-v7-preference \
android-support-v7-appcompat \
+ android-support-v7-mediarouter \
android-support-v14-preference \
android-support-v17-leanback
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 22b6a63..2725a32 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -20,22 +20,29 @@
import android.content.Intent;
import android.provider.Settings;
import android.service.quicksettings.Tile;
+import android.support.v7.app.MediaRouteChooserDialog;
+import android.support.v7.app.MediaRouteControllerDialog;
+import android.support.v7.media.MediaControlIntent;
+import android.support.v7.media.MediaRouteSelector;
import android.util.Log;
+import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.widget.Button;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.R.style;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSDetailItems;
import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost;
-import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
@@ -109,7 +116,6 @@
if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
showDetail(true);
- mHost.openPanels();
});
return;
}
@@ -117,6 +123,29 @@
}
@Override
+ public void showDetail(boolean show) {
+ mUiHandler.post(() -> {
+ Context context = new ContextThemeWrapper(mContext,
+ R.style.Theme_AppCompat_Light_Dialog_Alert);
+ if (mState.value) {
+ MediaRouteControllerDialog dialog = new MediaRouteControllerDialog(context);
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+ dialog.show();
+ } else {
+ // Instead of showing detail, show standard media routing UI.
+ MediaRouteChooserDialog dialog = new MediaRouteChooserDialog(context);
+ MediaRouteSelector selector = new MediaRouteSelector.Builder()
+ .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
+ .build();
+ dialog.setRouteSelector(selector);
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+ dialog.show();
+ }
+ mHost.collapsePanels();
+ });
+ }
+
+ @Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_cast_title);
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
index 4eb1db6..9c69b98 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerActivity.java
@@ -110,10 +110,35 @@
}
public static class SubSettingsFragment extends PreferenceFragment {
+ private PreferenceScreen mParentScreen;
+
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
- setPreferenceScreen((PreferenceScreen) ((PreferenceFragment) getTargetFragment())
- .getPreferenceScreen().findPreference(rootKey));
+ mParentScreen =
+ (PreferenceScreen) ((PreferenceFragment) getTargetFragment())
+ .getPreferenceScreen().findPreference(rootKey);
+ PreferenceScreen screen =
+ getPreferenceManager().createPreferenceScreen(
+ getPreferenceManager().getContext());
+ setPreferenceScreen(screen);
+ // Copy all the preferences over to this screen so they go into the attached state.
+ while (mParentScreen.getPreferenceCount() > 0) {
+ Preference p = mParentScreen.getPreference(0);
+ mParentScreen.removePreference(p);
+ screen.addPreference(p);
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ // Copy all the preferences back so we don't lose them.
+ PreferenceScreen screen = getPreferenceScreen();
+ while (screen.getPreferenceCount() > 0) {
+ Preference p = screen.getPreference(0);
+ screen.removePreference(p);
+ mParentScreen.addPreference(p);
+ }
}
}
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index ddd8d7b..8eedf31 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -41,6 +41,7 @@
android-support-v7-recyclerview \
android-support-v7-preference \
android-support-v7-appcompat \
+ android-support-v7-mediarouter \
android-support-v14-preference \
android-support-v17-leanback
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 97099df..f6d91f4 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -153,10 +153,34 @@
// Package: android
NOTE_SSL_CERT_INFO = 33;
+ // Warn the user they are approaching their data limit.
+ // Package: android
+ NOTE_NET_WARNING = 34;
+
+ // Warn the user they have reached their data limit.
+ // Package: android
+ NOTE_NET_LIMIT = 35;
+
+ // Warn the user they have exceeded their data limit.
+ // Package: android
+ NOTE_NET_LIMIT_SNOOZED = 36;
+
// ADD_NEW_IDS_ABOVE_THIS_LINE
// Legacy IDs with arbitrary values appear below
// Legacy IDs existed as stable non-conflicting constants prior to the O release
+ // Network status notes, previously decleared in metrics_constants with these values
+ // Package: android
+ //
+ // A captive portal was detected during network validation
+ NOTE_NETWORK_SIGN_IN = 740;
+ // An unvalidated network without Internet was selected by the user
+ NOTE_NETWORK_NO_INTERNET = 741;
+ // A validated network failed revalidation and lost Internet access
+ NOTE_NETWORK_LOST_INTERNET = 742;
+ // The system default network switched to a different network
+ NOTE_NETWORK_SWITCH = 743;
+
// Notify the user that their work profile has been deleted
// Package: android
NOTE_PROFILE_WIPED = 1001;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index acaae7b..087c248 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -104,6 +104,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IntPair;
import com.android.server.LocalServices;
import com.android.server.policy.AccessibilityShortcutController;
@@ -2360,7 +2361,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (mLock) {
pw.println("ACCESSIBILITY MANAGER (dumpsys accessibility)");
pw.println();
@@ -3658,7 +3659,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (mLock) {
pw.append("Service[label=" + mAccessibilityServiceInfo.getResolveInfo()
.loadLabel(mContext.getPackageManager()));
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 8aa37ef..0482e73 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -97,6 +97,7 @@
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.widget.IRemoteViewsAdapterConnection;
import com.android.internal.widget.IRemoteViewsFactory;
@@ -714,10 +715,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
- "Permission Denial: can't dump from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
if (args.length > 0 && "--proto".equals(args[0])) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 72d37ad..be14440 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -60,6 +60,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -418,13 +419,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingPermission(
- Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump autofill from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.print("Disabled users: "); pw.println(mDisabledUsers);
final int size = mServicesCache.size();
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 57d3570..413746f 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -117,6 +117,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.backup.IObbBackupService;
+import com.android.internal.util.DumpUtils;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.SystemConfig;
@@ -11138,7 +11139,7 @@
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
long identityToken = Binder.clearCallingIdentity();
try {
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index c40f2ca..a109e631 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -35,6 +35,8 @@
import android.os.UserHandle;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -372,7 +374,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
BackupManagerService svc = mService;
if (svc != null) {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index c6af290..8b32c16 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -80,6 +80,7 @@
import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
import static android.app.AlarmManager.ELAPSED_REALTIME;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.LocalLog;
class AlarmManagerService extends SystemService {
@@ -1384,14 +1385,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump AlarmManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
dumpImpl(pw);
}
};
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index a5e357c..dcf6fd7 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -70,6 +70,7 @@
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
@@ -2028,13 +2029,7 @@
@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 ApOps service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
if (args != null) {
for (int i=0; i<args.length; i++) {
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index fd44794..83bd9eb 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -24,6 +24,7 @@
import android.os.ShellCallback;
import android.os.ShellCommand;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.util.DumpUtils;
import com.android.server.am.BatteryStatsService;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
@@ -945,14 +946,7 @@
private final class BinderService extends Binder {
@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 Battery service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
if (args.length > 0 && "--proto".equals(args[0])) {
dumpProto(fd);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 58e8631..6c4895c 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -60,6 +60,7 @@
import android.provider.Settings.SettingNotFoundException;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
import com.android.server.pm.PackageManagerService;
import java.io.FileDescriptor;
@@ -2084,7 +2085,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
String errorMsg = null;
boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
diff --git a/services/core/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java
index 60b366a..07c8679 100644
--- a/services/core/java/com/android/server/CommonTimeManagementService.java
+++ b/services/core/java/com/android/server/CommonTimeManagementService.java
@@ -37,6 +37,7 @@
import android.os.SystemProperties;
import android.util.Log;
+import com.android.internal.util.DumpUtils;
import com.android.server.net.BaseNetworkObserver;
/**
@@ -177,13 +178,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println(String.format(
- "Permission Denial: can't dump CommonTimeManagement service from from " +
- "pid=%d, uid=%d", Binder.getCallingPid(), Binder.getCallingUid()));
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
if (!mDetectedAtStartup) {
pw.println("Native Common Time service was not detected at startup. " +
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d02b726..0e752ff 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.internal.net.VpnInfo;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.WakeupMessage;
@@ -1927,14 +1928,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ConnectivityService " +
- "from from pid=" + Binder.getCallingPid() + ", uid=" +
- Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
if (argsContain(args, "--diag")) {
dumpNetworkDiagnostics(pw);
diff --git a/services/core/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java
index a478b2f..d8a2fe3 100644
--- a/services/core/java/com/android/server/CountryDetectorService.java
+++ b/services/core/java/com/android/server/CountryDetectorService.java
@@ -21,6 +21,7 @@
import java.util.HashMap;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.server.location.ComprehensiveCountryDetector;
import android.content.Context;
@@ -208,8 +209,7 @@
@SuppressWarnings("unused")
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
if (!DEBUG) return;
try {
final Printer p = new PrintWriterPrinter(fout);
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 26b15d8..8945952 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -81,6 +81,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.AtomicFile;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.server.am.BatteryStatsService;
@@ -2879,13 +2880,7 @@
}
void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump DeviceIdleController from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
if (args != null) {
int userId = UserHandle.USER_SYSTEM;
diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java
index 1bdff6b..800081e 100644
--- a/services/core/java/com/android/server/DiskStatsService.java
+++ b/services/core/java/com/android/server/DiskStatsService.java
@@ -30,6 +30,7 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.util.DumpUtils;
import com.android.server.storage.DiskStatsFileLogger;
import com.android.server.storage.DiskStatsLoggingService;
@@ -62,7 +63,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
// Run a quick-and-dirty performance test: write 512 bytes
byte[] junk = new byte[512];
diff --git a/services/core/java/com/android/server/DockObserver.java b/services/core/java/com/android/server/DockObserver.java
index 122074b..e5a7b4e 100644
--- a/services/core/java/com/android/server/DockObserver.java
+++ b/services/core/java/com/android/server/DockObserver.java
@@ -35,6 +35,8 @@
import android.util.Log;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
+
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileReader;
@@ -252,14 +254,7 @@
private final class BinderService extends Binder {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump dock observer service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index 040d22c..9d3d531 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -40,6 +40,7 @@
import libcore.io.IoUtils;
import com.android.internal.os.IDropBoxManagerService;
+import com.android.internal.util.DumpUtils;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -350,11 +351,7 @@
}
public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: Can't dump DropBoxManagerService");
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
try {
init();
diff --git a/services/core/java/com/android/server/GraphicsStatsService.java b/services/core/java/com/android/server/GraphicsStatsService.java
index 19bedfb..d3f77b6 100644
--- a/services/core/java/com/android/server/GraphicsStatsService.java
+++ b/services/core/java/com/android/server/GraphicsStatsService.java
@@ -37,6 +37,8 @@
import android.view.IGraphicsStats;
import android.view.IGraphicsStatsCallback;
+import com.android.internal.util.DumpUtils;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -345,7 +347,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, fout)) return;
boolean dumpProto = false;
for (String str : args) {
if ("--proto".equals(str)) {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index e619e8bf..39bfeda 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -33,6 +33,7 @@
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
import com.android.internal.os.TransferPipe;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethod;
@@ -4378,14 +4379,7 @@
@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 InputMethodManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
IInputMethod method;
ClientState client;
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 979096e..f0720f3 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -26,6 +26,7 @@
import com.android.internal.location.ProviderRequest;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.server.location.ActivityRecognitionProxy;
import com.android.server.location.FlpHardwareProvider;
import com.android.server.location.FusedProxy;
@@ -3026,13 +3027,7 @@
@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 LocationManagerService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("Current Location Manager state:");
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 6f3ff10..e26630b 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -79,6 +79,7 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.LockPatternUtils;
@@ -2178,14 +2179,7 @@
@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 LockSettingsService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (this) {
pw.println("Current lock settings service state:");
diff --git a/services/core/java/com/android/server/LockSettingsShellCommand.java b/services/core/java/com/android/server/LockSettingsShellCommand.java
index 91bd98e..9d671e39 100644
--- a/services/core/java/com/android/server/LockSettingsShellCommand.java
+++ b/services/core/java/com/android/server/LockSettingsShellCommand.java
@@ -35,6 +35,7 @@
private static final String COMMAND_SET_PASSWORD = "set-password";
private static final String COMMAND_CLEAR = "clear";
private static final String COMMAND_SP = "sp";
+ private static final String COMMAND_SET_DISABLED = "set-disabled";
private int mCurrentUserId;
private final LockPatternUtils mLockPatternUtils;
@@ -72,6 +73,9 @@
case COMMAND_SP:
runEnableSp();
break;
+ case COMMAND_SET_DISABLED:
+ runSetDisabled();
+ break;
default:
getErrPrintWriter().println("Unknown command: " + cmd);
break;
@@ -132,6 +136,12 @@
getOutPrintWriter().println("Lock credential cleared");
}
+ private void runSetDisabled() throws RemoteException {
+ final boolean disabled = Boolean.parseBoolean(mNew);
+ mLockPatternUtils.setLockScreenDisabled(disabled, mCurrentUserId);
+ getOutPrintWriter().println("Lock screen disabled set to " + disabled);
+ }
+
private boolean checkCredential() throws RemoteException, RequestThrottledException {
final boolean havePassword = mLockPatternUtils.isLockPasswordEnabled(mCurrentUserId);
final boolean havePattern = mLockPatternUtils.isLockPatternEnabled(mCurrentUserId);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 74328c0..ce4efd1 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -95,6 +95,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.net.NetworkStatsFactory;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.HexDump;
import com.android.internal.util.Preconditions;
import com.android.server.NativeDaemonConnector.Command;
@@ -2313,7 +2314,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("NetworkManagementService NativeDaemonConnector Log:");
mConnector.dump(fd, pw, args);
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 78c0fe6..a5debda 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -69,6 +69,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.TransferPipe;
+import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -925,7 +926,7 @@
@Override
protected void dump(final FileDescriptor fd, final PrintWriter writer, final String[] args) {
- mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final long token = Binder.clearCallingIdentity();
try {
NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer();
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index b64c65d..ebcda44 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -40,6 +40,7 @@
import android.util.TrustedTime;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -323,15 +324,7 @@
@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;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.print("PollingIntervalMs: ");
TimeUtils.formatDuration(mPollingIntervalMs, pw);
pw.print("\nPollingIntervalShorterMs: ");
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index a44b065..8ae95d5 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -41,6 +41,7 @@
import java.util.concurrent.CountDownLatch;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
@@ -811,13 +812,7 @@
@Override
public 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 ServiceDiscoverService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
for (ClientInfo client : mClients.values()) {
pw.println("Client Info");
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index fa5a52c..a94bf79 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -37,6 +37,7 @@
import com.android.internal.app.ResolverActivity;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import dalvik.system.DexFile;
import dalvik.system.VMRuntime;
@@ -333,7 +334,7 @@
private final class BinderService extends Binder {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("Pinned Files:");
synchronized(this) {
for (int i = 0; i < mPinnedFiles.size(); i++) {
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index cecd7e5..3b36c3c 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -18,14 +18,13 @@
import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.UserInfo;
import android.os.Build;
+import android.os.Environment;
import android.os.FileUtils;
import android.os.RecoverySystem;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.util.ExceptionUtils;
@@ -70,7 +69,7 @@
private static boolean isDisabled() {
// Check if we're explicitly enabled for testing
- if (SystemProperties.getBoolean(PROP_ENABLE_RESCUE, true)) {
+ if (SystemProperties.getBoolean(PROP_ENABLE_RESCUE, false)) {
return false;
}
@@ -203,7 +202,7 @@
} catch (Throwable t) {
res = new RuntimeException("Failed to reset global settings", t);
}
- for (int userId : getAllUserIds(context)) {
+ for (int userId : getAllUserIds()) {
try {
Settings.Secure.resetToDefaultsAsUser(resolver, null, mode, userId);
} catch (Throwable t) {
@@ -314,13 +313,16 @@
@Override public void setStart(long start) { this.start = start; }
}
- private static int[] getAllUserIds(Context context) {
+ private static int[] getAllUserIds() {
int[] userIds = { UserHandle.USER_SYSTEM };
try {
- final UserManager um = context.getSystemService(UserManager.class);
- for (UserInfo user : um.getUsers()) {
- if (user.id != UserHandle.USER_SYSTEM) {
- userIds = ArrayUtils.appendInt(userIds, user.id);
+ for (File file : FileUtils.listFilesOrEmpty(Environment.getDataSystemDeDirectory())) {
+ try {
+ final int userId = Integer.parseInt(file.getName());
+ if (userId != UserHandle.USER_SYSTEM) {
+ userIds = ArrayUtils.appendInt(userIds, userId);
+ }
+ } catch (NumberFormatException ignored) {
}
}
} catch (Throwable t) {
diff --git a/services/core/java/com/android/server/SamplingProfilerService.java b/services/core/java/com/android/server/SamplingProfilerService.java
index fbf1aa4..5f92695 100644
--- a/services/core/java/com/android/server/SamplingProfilerService.java
+++ b/services/core/java/com/android/server/SamplingProfilerService.java
@@ -27,6 +27,7 @@
import android.os.SystemProperties;
import android.provider.Settings;
import com.android.internal.os.SamplingProfilerIntegration;
+import com.android.internal.util.DumpUtils;
import java.io.File;
import java.io.FileDescriptor;
@@ -96,7 +97,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("SamplingProfilerService:");
pw.println("Watching directory: " + SNAPSHOT_DIR);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c68000a..d796098 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -102,6 +102,7 @@
import com.android.internal.os.SomeArgs;
import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
@@ -3911,7 +3912,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ", 160);
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 531df81..7c1a609 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -60,6 +60,7 @@
import com.android.internal.telephony.PhoneConstantConversions;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
import com.android.server.am.BatteryStatsService;
/**
@@ -1391,12 +1392,7 @@
@Override
public 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 telephony.registry from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mRecords) {
final int recordCount = mRecords.size();
pw.println("last known state:");
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index feda273..9068745 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -25,6 +25,7 @@
import com.android.internal.textservice.ISpellCheckerSessionListener;
import com.android.internal.textservice.ITextServicesManager;
import com.android.internal.textservice.ITextServicesSessionListener;
+import com.android.internal.util.DumpUtils;
import org.xmlpull.v1.XmlPullParserException;
@@ -757,14 +758,7 @@
@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 TextServicesManagerService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized(mSpellCheckerMap) {
pw.println("Current Text Services Manager state:");
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 227e2a2..04421cc 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -60,6 +60,7 @@
import com.android.internal.app.DisableCarModeActivity;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.DumpUtils;
import com.android.server.power.ShutdownThread;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
@@ -352,15 +353,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump uimode service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
dumpImpl(pw);
}
};
diff --git a/services/core/java/com/android/server/UpdateLockService.java b/services/core/java/com/android/server/UpdateLockService.java
index 7f33973..06f73e2 100644
--- a/services/core/java/com/android/server/UpdateLockService.java
+++ b/services/core/java/com/android/server/UpdateLockService.java
@@ -29,6 +29,8 @@
import android.os.UserHandle;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -112,14 +114,7 @@
@Override
public 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 update lock service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
mLocks.dump(pw);
}
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index c4676d1..678ae38 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -54,6 +54,7 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.util.DumpUtils;
import com.android.server.power.BatterySaverPolicy.ServiceType;
import java.io.FileDescriptor;
@@ -874,14 +875,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
- pw.println("Permission Denial: can't dump vibrator service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
pw.println("Previous vibrations:");
synchronized (mLock) {
for (VibrationInfo info : mPreviousVibrations) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ad2ed93..d996ee2 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -92,6 +92,7 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
@@ -4867,13 +4868,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- fout.println("Permission Denial: can't dump AccountsManager from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c");
final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " ");
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 81d0a7c..c27fa1b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -350,6 +350,7 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.MemInfoReader;
@@ -2656,14 +2657,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump meminfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "meminfo", pw)) return;
mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
}
}
@@ -2676,14 +2671,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump gfxinfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "gfxinfo", pw)) return;
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
}
}
@@ -2696,14 +2685,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump dbinfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "dbinfo", pw)) return;
mActivityManagerService.dumpDbInfo(fd, pw, args);
}
}
@@ -2716,14 +2699,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump cpuinfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "cpuinfo", pw)) return;
synchronized (mActivityManagerService.mProcessCpuTracker) {
pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
@@ -14758,15 +14735,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ActivityManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " without permission "
- + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
boolean dumpAll = false;
boolean dumpClient = false;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index a623df7..432988a 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -25,8 +25,20 @@
import static android.app.ActivityManager.StackId.HOME_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX;
+import static android.app.ActivityOptions.ANIM_CLIP_REVEAL;
+import static android.app.ActivityOptions.ANIM_CUSTOM;
+import static android.app.ActivityOptions.ANIM_SCALE_UP;
+import static android.app.ActivityOptions.ANIM_SCENE_TRANSITION;
+import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
+import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP;
+import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN;
+import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
+import static android.content.Intent.ACTION_MAIN;
+import static android.content.Intent.CATEGORY_HOME;
+import static android.content.Intent.CATEGORY_LAUNCHER;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
@@ -43,15 +55,19 @@
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
+import static android.content.pm.ActivityInfo.PERSIST_ACROSS_REBOOTS;
+import static android.content.pm.ActivityInfo.PERSIST_ROOT_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.res.Configuration.EMPTY;
+import static android.content.res.Configuration.UI_MODE_TYPE_MASK;
import static android.content.res.Configuration.UI_MODE_TYPE_VR_HEADSET;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Process.SYSTEM_UID;
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SCREENSHOTS;
@@ -68,8 +84,30 @@
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
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.IS_USER_BUILD;
import static com.android.server.am.ActivityManagerService.TAKE_FULLSCREEN_SCREENSHOTS;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
+import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
+import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
+import static com.android.server.am.ActivityStack.LAUNCH_TICK;
+import static com.android.server.am.ActivityStack.LAUNCH_TICK_MSG;
+import static com.android.server.am.ActivityStack.PAUSE_TIMEOUT_MSG;
+import static com.android.server.am.ActivityStack.STOP_TIMEOUT_MSG;
+import static com.android.server.am.EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME;
+import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
+import static com.android.server.am.EventLogTags.AM_RELAUNCH_ACTIVITY;
+import static com.android.server.am.EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY;
+import static com.android.server.am.TaskPersister.DEBUG;
+import static com.android.server.am.TaskPersister.IMAGE_EXTENSION;
import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
+import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
+import static org.xmlpull.v1.XmlPullParser.END_TAG;
+import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.annotation.NonNull;
import android.app.ActivityManager.TaskDescription;
@@ -109,6 +147,7 @@
import com.android.internal.content.ReferrerIntent;
import com.android.internal.util.XmlUtils;
import com.android.server.AttributeCache;
+import com.android.server.AttributeCache.Entry;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.am.ActivityStackSupervisor.ActivityContainer;
import com.android.server.wm.AppWindowContainerController;
@@ -199,6 +238,8 @@
long cpuTimeAtResume; // the cpu time of host process at the time of resuming activity
long pauseTime; // last time we started pausing the activity
long launchTickTime; // base time for launch tick messages
+ // TODO: Refactor mLastReportedConfiguration and mLastReportedOverrideConfiguration to use a
+ // MergedConfiguration object for clarity.
private Configuration mLastReportedConfiguration; // configuration activity was last running in
// Overridden configuration by the activity task
// WARNING: Reference points to {@link TaskRecord#getMergedOverrideConfig}, so its internal
@@ -299,6 +340,7 @@
*/
private final Configuration mTmpConfig1 = new Configuration();
private final Configuration mTmpConfig2 = new Configuration();
+ private final Configuration mTmpConfig3 = new Configuration();
private final Point mTmpPoint = new Point();
private final Rect mTmpBounds = new Rect();
@@ -684,7 +726,7 @@
resultTo = _resultTo;
resultWho = _resultWho;
requestCode = _reqCode;
- state = ActivityState.INITIALIZING;
+ state = INITIALIZING;
frontOfTask = false;
launchFailed = false;
stopped = false;
@@ -768,7 +810,7 @@
packageName = aInfo.applicationInfo.packageName;
launchMode = aInfo.launchMode;
- AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
+ Entry ent = AttributeCache.instance().get(packageName,
realTheme, com.android.internal.R.styleable.Window, userId);
final boolean translucent = ent != null && (ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowIsTranslucent, false)
@@ -860,16 +902,16 @@
}
private boolean isHomeIntent(Intent intent) {
- return Intent.ACTION_MAIN.equals(intent.getAction())
- && intent.hasCategory(Intent.CATEGORY_HOME)
+ return ACTION_MAIN.equals(intent.getAction())
+ && intent.hasCategory(CATEGORY_HOME)
&& intent.getCategories().size() == 1
&& intent.getData() == null
&& intent.getType() == null;
}
static boolean isMainIntent(Intent intent) {
- return Intent.ACTION_MAIN.equals(intent.getAction())
- && intent.hasCategory(Intent.CATEGORY_LAUNCHER)
+ return ACTION_MAIN.equals(intent.getAction())
+ && intent.hasCategory(CATEGORY_LAUNCHER)
&& intent.getCategories().size() == 1
&& intent.getData() == null
&& intent.getType() == null;
@@ -986,8 +1028,8 @@
}
boolean isPersistable() {
- return (info.persistableMode == ActivityInfo.PERSIST_ROOT_ONLY ||
- info.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS) &&
+ return (info.persistableMode == PERSIST_ROOT_ONLY ||
+ info.persistableMode == PERSIST_ACROSS_REBOOTS) &&
(intent == null ||
(intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0);
}
@@ -1203,13 +1245,13 @@
// - It is currently resumed or paused. i.e. it is currently visible to the user and we want
// the user to see the visual effects caused by the intent delivery now.
// - The device is sleeping and it is the top activity behind the lock screen (b/6700897).
- if ((state == ActivityState.RESUMED || state == ActivityState.PAUSED
+ if ((state == RESUMED || state == PAUSED
|| isTopActivityWhileSleeping) && app != null && app.thread != null) {
try {
ArrayList<ReferrerIntent> ar = new ArrayList<>(1);
ar.add(rintent);
app.thread.scheduleNewIntent(
- ar, appToken, state == ActivityState.PAUSED /* andPause */);
+ ar, appToken, state == PAUSED /* andPause */);
unsent = false;
} catch (RemoteException e) {
Slog.w(TAG, "Exception thrown sending new intent to " + this, e);
@@ -1233,17 +1275,17 @@
void applyOptionsLocked() {
if (pendingOptions != null
- && pendingOptions.getAnimationType() != ActivityOptions.ANIM_SCENE_TRANSITION) {
+ && pendingOptions.getAnimationType() != ANIM_SCENE_TRANSITION) {
final int animationType = pendingOptions.getAnimationType();
switch (animationType) {
- case ActivityOptions.ANIM_CUSTOM:
+ case ANIM_CUSTOM:
service.mWindowManager.overridePendingAppTransition(
pendingOptions.getPackageName(),
pendingOptions.getCustomEnterResId(),
pendingOptions.getCustomExitResId(),
pendingOptions.getOnAnimationStartListener());
break;
- case ActivityOptions.ANIM_CLIP_REVEAL:
+ case ANIM_CLIP_REVEAL:
service.mWindowManager.overridePendingAppTransitionClipReveal(
pendingOptions.getStartX(), pendingOptions.getStartY(),
pendingOptions.getWidth(), pendingOptions.getHeight());
@@ -1254,7 +1296,7 @@
pendingOptions.getStartY()+pendingOptions.getHeight()));
}
break;
- case ActivityOptions.ANIM_SCALE_UP:
+ case ANIM_SCALE_UP:
service.mWindowManager.overridePendingAppTransitionScaleUp(
pendingOptions.getStartX(), pendingOptions.getStartY(),
pendingOptions.getWidth(), pendingOptions.getHeight());
@@ -1265,9 +1307,9 @@
pendingOptions.getStartY()+pendingOptions.getHeight()));
}
break;
- case ActivityOptions.ANIM_THUMBNAIL_SCALE_UP:
- case ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN:
- boolean scaleUp = (animationType == ActivityOptions.ANIM_THUMBNAIL_SCALE_UP);
+ case ANIM_THUMBNAIL_SCALE_UP:
+ case ANIM_THUMBNAIL_SCALE_DOWN:
+ boolean scaleUp = (animationType == ANIM_THUMBNAIL_SCALE_UP);
service.mWindowManager.overridePendingAppTransitionThumb(
pendingOptions.getThumbnail(),
pendingOptions.getStartX(), pendingOptions.getStartY(),
@@ -1282,10 +1324,10 @@
+ pendingOptions.getThumbnail().getHeight()));
}
break;
- case ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP:
- case ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
+ case ANIM_THUMBNAIL_ASPECT_SCALE_UP:
+ case ANIM_THUMBNAIL_ASPECT_SCALE_DOWN:
final AppTransitionAnimationSpec[] specs = pendingOptions.getAnimSpecs();
- if (animationType == ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
+ if (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
&& specs != null) {
service.mWindowManager.overridePendingAppTransitionMultiThumb(
specs, pendingOptions.getOnAnimationStartListener(),
@@ -1296,7 +1338,7 @@
pendingOptions.getStartX(), pendingOptions.getStartY(),
pendingOptions.getWidth(), pendingOptions.getHeight(),
pendingOptions.getOnAnimationStartListener(),
- (animationType == ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP));
+ (animationType == ANIM_THUMBNAIL_ASPECT_SCALE_UP));
if (intent.getSourceBounds() == null) {
intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
pendingOptions.getStartY(),
@@ -1478,7 +1520,7 @@
void makeVisibleIfNeeded(ActivityRecord starting) {
// This activity is not currently visible, but is running. Tell it to become visible.
- if (state == ActivityState.RESUMED || this == starting) {
+ if (state == RESUMED || this == starting) {
if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY,
"Not making visible, r=" + this + " state=" + state + " starting=" + starting);
return;
@@ -1515,7 +1557,7 @@
}
} catch(RemoteException e) {
}
- return state == ActivityState.RESUMED;
+ return state == RESUMED;
}
static void activityResumedLocked(IBinder token) {
@@ -1586,9 +1628,9 @@
final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
CharSequence description) {
final ActivityStack stack = getStack();
- if (state != ActivityState.STOPPING) {
+ if (state != STOPPING) {
Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
- stack.mHandler.removeMessages(ActivityStack.STOP_TIMEOUT_MSG, this);
+ stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
return;
}
if (newPersistentState != null) {
@@ -1607,9 +1649,9 @@
}
if (!stopped) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
- stack.mHandler.removeMessages(ActivityStack.STOP_TIMEOUT_MSG, this);
+ stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
stopped = true;
- state = ActivityState.STOPPED;
+ state = STOPPED;
mWindowContainerController.notifyAppStopped();
@@ -1630,7 +1672,7 @@
}
void startLaunchTickingLocked() {
- if (ActivityManagerService.IS_USER_BUILD) {
+ if (IS_USER_BUILD) {
return;
}
if (launchTickTime == 0) {
@@ -1649,9 +1691,9 @@
return false;
}
- Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG, this);
- stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
- stack.mHandler.sendMessageDelayed(msg, ActivityStack.LAUNCH_TICK);
+ Message msg = stack.mHandler.obtainMessage(LAUNCH_TICK_MSG, this);
+ stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
+ stack.mHandler.sendMessageDelayed(msg, LAUNCH_TICK);
return true;
}
@@ -1659,7 +1701,7 @@
launchTickTime = 0;
final ActivityStack stack = getStack();
if (stack != null) {
- stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
+ stack.mHandler.removeMessages(LAUNCH_TICK_MSG);
}
}
@@ -1697,8 +1739,8 @@
final long totalTime = stack.mFullyDrawnStartTime != 0
? (curTime - stack.mFullyDrawnStartTime) : thisTime;
if (SHOW_ACTIVITY_START_TIME) {
- Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
- EventLog.writeEvent(EventLogTags.AM_ACTIVITY_FULLY_DRAWN_TIME,
+ Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
+ EventLog.writeEvent(AM_ACTIVITY_FULLY_DRAWN_TIME,
userId, System.identityHashCode(this), shortComponentName,
thisTime, totalTime);
StringBuilder sb = service.mStringBuilder;
@@ -1731,8 +1773,8 @@
final long totalTime = stack.mLaunchStartTime != 0
? (curTime - stack.mLaunchStartTime) : thisTime;
if (SHOW_ACTIVITY_START_TIME) {
- Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
- EventLog.writeEvent(EventLogTags.AM_ACTIVITY_LAUNCH_TIME,
+ Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
+ EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
userId, System.identityHashCode(this), shortComponentName,
thisTime, totalTime);
StringBuilder sb = service.mStringBuilder;
@@ -1869,8 +1911,8 @@
* currently pausing, or is resumed.
*/
public boolean isInterestingToUserLocked() {
- return visible || nowVisible || state == ActivityState.PAUSING ||
- state == ActivityState.RESUMED;
+ return visible || nowVisible || state == PAUSING ||
+ state == RESUMED;
}
void setSleeping(boolean _sleeping) {
@@ -1932,8 +1974,8 @@
}
final boolean isDestroyable() {
- if (finishing || app == null || state == ActivityState.DESTROYING
- || state == ActivityState.DESTROYED) {
+ if (finishing || app == null || state == DESTROYING
+ || state == DESTROYED) {
// This would be redundant.
return false;
}
@@ -1952,7 +1994,7 @@
private static String createImageFilename(long createTime, int taskId) {
return String.valueOf(taskId) + ACTIVITY_ICON_SUFFIX + createTime +
- TaskPersister.IMAGE_EXTENSION;
+ IMAGE_EXTENSION;
}
void setTaskDescription(TaskDescription _taskDescription) {
@@ -1994,7 +2036,7 @@
}
void removeOrphanedStartingWindow(boolean behindFullscreenActivity) {
- if (state == ActivityState.INITIALIZING
+ if (state == INITIALIZING
&& mStartingWindowState == STARTING_WINDOW_SHOWN
&& behindFullscreenActivity) {
if (DEBUG_VISIBILITY) Slog.w(TAG_VISIBILITY, "Found orphaned starting window " + this);
@@ -2181,6 +2223,9 @@
// to decide whether to relaunch an activity or just report a configuration change.
final int changes = getConfigurationChanges(mTmpConfig1);
+ // Preserve configuration used to generate this set of configuration changes.
+ mTmpConfig3.setTo(mTmpConfig1);
+
// Update last reported values.
final Configuration newGlobalConfig = service.getGlobalConfiguration();
final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
@@ -2224,8 +2269,7 @@
+ ", newGlobalConfig=" + newGlobalConfig
+ ", newMergedOverrideConfig=" + newMergedOverrideConfig);
- if (shouldRelaunchLocked(changes, newGlobalConfig, newMergedOverrideConfig)
- || forceNewConfig) {
+ if (shouldRelaunchLocked(changes, mTmpConfig3) || forceNewConfig) {
// Aha, the activity isn't handling the change, so DIE DIE DIE.
configChangeFlags |= changes;
startFreezingScreenLocked(app, globalChanges);
@@ -2235,7 +2279,7 @@
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is destroying non-running " + this);
stack.destroyActivityLocked(this, true, "config");
- } else if (state == ActivityState.PAUSING) {
+ } else if (state == PAUSING) {
// A little annoying: we are waiting for this activity to finish pausing. Let's not
// do anything now, but just flag that it needs to be restarted when done pausing.
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -2243,7 +2287,7 @@
deferRelaunchUntilPaused = true;
preserveWindowOnDeferredRelaunch = preserveWindow;
return true;
- } else if (state == ActivityState.RESUMED) {
+ } else if (state == RESUMED) {
// Try to optimize this case: the configuration is changing and we need to restart
// the top, resumed activity. Instead of doing the normal handshaking, just say
// "restart!".
@@ -2283,10 +2327,14 @@
/**
* When assessing a configuration change, decide if the changes flags and the new configurations
* should cause the Activity to relaunch.
+ *
+ * @param changes the changes due to the given configuration.
+ * @param changesConfig the configuration that was used to calculate the given changes via a
+ * call to getConfigurationChanges.
*/
- private boolean shouldRelaunchLocked(int changes, Configuration newGlobalConfig,
- Configuration newTaskMergedOverrideConfig) {
+ private boolean shouldRelaunchLocked(int changes, Configuration changesConfig) {
int configChanged = info.getRealConfigChanged();
+ boolean onlyVrUiModeChanged = onlyVrUiModeChanged(changes, changesConfig);
// Override for apps targeting pre-O sdks
// If a device is in VR mode, and we're transitioning into VR ui mode, add ignore ui mode
@@ -2294,13 +2342,23 @@
// For O and later, apps will be required to add configChanges="uimode" to their manifest.
if (appInfo.targetSdkVersion < O
&& requestedVrComponent != null
- && (isInVrUiMode(newGlobalConfig) || isInVrUiMode(newTaskMergedOverrideConfig))) {
+ && onlyVrUiModeChanged) {
configChanged |= CONFIG_UI_MODE;
}
return (changes&(~configChanged)) != 0;
}
+ /**
+ * Returns true if the configuration change is solely due to the UI mode switching into or out
+ * of UI_MODE_TYPE_VR_HEADSET.
+ */
+ private boolean onlyVrUiModeChanged(int changes, Configuration lastReportedConfig) {
+ final Configuration currentConfig = getConfiguration();
+ return changes == CONFIG_UI_MODE && (isInVrUiMode(currentConfig)
+ != isInVrUiMode(lastReportedConfig));
+ }
+
private int getConfigurationChanges(Configuration lastReportedConfig) {
// Determine what has changed. May be nothing, if this is a config that has come back from
// the app after going idle. In that case we just want to leave the official config object
@@ -2349,8 +2407,8 @@
"Relaunching: " + this + " with results=" + pendingResults
+ " newIntents=" + pendingNewIntents + " andResume=" + andResume
+ " preserveWindow=" + preserveWindow);
- EventLog.writeEvent(andResume ? EventLogTags.AM_RELAUNCH_RESUME_ACTIVITY
- : EventLogTags.AM_RELAUNCH_ACTIVITY, userId, System.identityHashCode(this),
+ EventLog.writeEvent(andResume ? AM_RELAUNCH_RESUME_ACTIVITY
+ : AM_RELAUNCH_ACTIVITY, userId, System.identityHashCode(this),
task.taskId, shortComponentName);
startFreezingScreenLocked(app, 0);
@@ -2383,8 +2441,8 @@
service.showUnsupportedZoomDialogIfNeededLocked(this);
service.showAskCompatModeDialogLocked(this);
} else {
- service.mHandler.removeMessages(ActivityStack.PAUSE_TIMEOUT_MSG, this);
- state = ActivityState.PAUSED;
+ service.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
+ state = PAUSED;
// if the app is relaunched when it's stopped, and we're not resuming,
// put it back into stopped state.
if (stopped) {
@@ -2448,7 +2506,7 @@
for (int attrNdx = in.getAttributeCount() - 1; attrNdx >= 0; --attrNdx) {
final String attrName = in.getAttributeName(attrNdx);
final String attrValue = in.getAttributeValue(attrNdx);
- if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
+ if (DEBUG) Slog.d(TaskPersister.TAG,
"ActivityRecord: attribute name=" + attrName + " value=" + attrValue);
if (ATTR_ID.equals(attrName)) {
createTime = Long.parseLong(attrValue);
@@ -2462,7 +2520,7 @@
componentSpecified = Boolean.parseBoolean(attrValue);
} else if (ATTR_USERID.equals(attrName)) {
userId = Integer.parseInt(attrValue);
- } else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
+ } else if (attrName.startsWith(ATTR_TASKDESCRIPTION_PREFIX)) {
taskDescription.restoreFromXml(attrName, attrValue);
} else {
Log.d(TAG, "Unknown ActivityRecord attribute=" + attrName);
@@ -2470,19 +2528,19 @@
}
int event;
- while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
- (event != XmlPullParser.END_TAG || in.getDepth() >= outerDepth)) {
- if (event == XmlPullParser.START_TAG) {
+ while (((event = in.next()) != END_DOCUMENT) &&
+ (event != END_TAG || in.getDepth() >= outerDepth)) {
+ if (event == START_TAG) {
final String name = in.getName();
- if (TaskPersister.DEBUG)
+ if (DEBUG)
Slog.d(TaskPersister.TAG, "ActivityRecord: START_TAG name=" + name);
if (TAG_INTENT.equals(name)) {
intent = Intent.restoreFromXml(in);
- if (TaskPersister.DEBUG)
+ if (DEBUG)
Slog.d(TaskPersister.TAG, "ActivityRecord: intent=" + intent);
} else if (TAG_PERSISTABLEBUNDLE.equals(name)) {
persistentState = PersistableBundle.restoreFromXml(in);
- if (TaskPersister.DEBUG) Slog.d(TaskPersister.TAG,
+ if (DEBUG) Slog.d(TaskPersister.TAG,
"ActivityRecord: persistentState=" + persistentState);
} else {
Slog.w(TAG, "restoreActivity: unexpected name=" + name);
@@ -2526,7 +2584,7 @@
}
private static boolean isInVrUiMode(Configuration config) {
- return (config.uiMode & Configuration.UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
+ return (config.uiMode & UI_MODE_TYPE_MASK) == UI_MODE_TYPE_VR_HEADSET;
}
int getUid() {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d3935d1..e5b2eca 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -59,6 +59,7 @@
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.PowerProfile;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.power.BatterySaverPolicy.ServiceType;
@@ -1188,13 +1189,7 @@
@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 BatteryStats from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
int flags = 0;
boolean useCheckinFormat = false;
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index d210ed7..deb3b28 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -616,13 +616,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mAm.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump procstats from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!com.android.internal.util.DumpUtils.checkDumpAndUsageStatsPermission(mAm.mContext,
+ TAG, pw)) return;
long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 49d1521..70e56b0 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -114,6 +114,7 @@
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityManager;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.XmlUtils;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -6116,7 +6117,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
mMediaFocusControl.dump(pw);
dumpStreamStates(pw);
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 83751a9..4315aaa 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -31,7 +31,7 @@
import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
@@ -40,11 +40,12 @@
public class NetworkNotificationManager {
+
public static enum NotificationType {
- LOST_INTERNET(MetricsEvent.NOTIFICATION_NETWORK_LOST_INTERNET),
- NETWORK_SWITCH(MetricsEvent.NOTIFICATION_NETWORK_SWITCH),
- NO_INTERNET(MetricsEvent.NOTIFICATION_NETWORK_NO_INTERNET),
- SIGN_IN(MetricsEvent.NOTIFICATION_NETWORK_SIGN_IN);
+ LOST_INTERNET(SystemMessage.NOTE_NETWORK_LOST_INTERNET),
+ NETWORK_SWITCH(SystemMessage.NOTE_NETWORK_SWITCH),
+ NO_INTERNET(SystemMessage.NOTE_NETWORK_NO_INTERNET),
+ SIGN_IN(SystemMessage.NOTE_NETWORK_SIGN_IN);
public final int eventId;
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 07ab067..0e593bd 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -70,6 +70,7 @@
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.Protocol;
@@ -1585,13 +1586,7 @@
// Binder.java closes the resource for us.
@SuppressWarnings("resource")
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ConnectivityService.Tether " +
- "from from pid=" + Binder.getCallingPid() + ", uid=" +
- Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("Tethering:");
pw.increaseIndent();
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index f47a9079..13054a6 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -60,6 +60,7 @@
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -162,9 +163,7 @@
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP,
- "caller doesn't have the DUMP permission");
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw_)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, " ");
// This makes it so that future permission checks will be in the context of this
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index fd89b97..a1a7437 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -23,6 +23,7 @@
import static android.hardware.display.DisplayManager
.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import android.Manifest;
@@ -1538,13 +1539,7 @@
@Override // Binder call
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext == null
- || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump DisplayManager from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long token = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 1991c00..313abab 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -479,14 +479,7 @@
private final class BinderService extends IDreamManager.Stub {
@Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump DreamManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
try {
dumpInternal(pw);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 7d97ce4..2b85570 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -56,6 +56,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.DumpUtils;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
@@ -1071,13 +1072,7 @@
@Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump Fingerprint from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 6864e1e..807b1b1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -68,6 +68,7 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
@@ -1677,7 +1678,7 @@
@Override
protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
- getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
pw.println("mHdmiControlEnabled: " + mHdmiControlEnabled);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 65a4604..aafc9a8 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -27,6 +27,7 @@
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.SomeArgs;
import com.android.internal.R;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.DisplayThread;
@@ -1747,13 +1748,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump InputManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("INPUT MANAGER (dumpsys input)\n");
String dumpStr = nativeDump(mPtr);
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 2de9aae..7c231ff 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -72,6 +72,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.server.DeviceIdleController;
import com.android.server.LocalServices;
import com.android.server.job.JobStore.JobStatusFunctor;
@@ -1790,7 +1791,7 @@
*/
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
long identityToken = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index 0a15db6..5e9f355 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -31,6 +31,8 @@
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.util.DumpUtils;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
@@ -242,11 +244,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump contexthub service");
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("Dumping ContextHub Service");
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index f91ea8c..7b0e51e 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -16,6 +16,7 @@
package com.android.server.media;
+import com.android.internal.util.DumpUtils;
import com.android.server.Watchdog;
import android.Manifest;
@@ -258,13 +259,7 @@
// Binder call
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump MediaRouterService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("MEDIA ROUTER SERVICE (dumpsys media_router)");
pw.println();
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 4bf9d8f..64ab848 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -71,6 +71,7 @@
import android.view.KeyEvent;
import android.view.ViewConfiguration;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.Watchdog;
@@ -1283,13 +1284,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump MediaSessionService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
pw.println("MEDIA SESSION SERVICE (dumpsys media_session)");
pw.println();
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 3ea4f2c..9d92cbc 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -39,6 +39,7 @@
import android.util.ArrayMap;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
import com.android.server.SystemService;
import java.io.FileDescriptor;
@@ -314,14 +315,7 @@
@Override // Binder call
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext == null
- || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump MediaProjectionManager from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long token = Binder.clearCallingIdentity();
try {
MediaProjectionManagerService.this.dump(pw);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index f180c50..4e1166b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -178,9 +178,11 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.DeviceIdleController;
@@ -212,6 +214,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Calendar;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -268,11 +271,11 @@
ActivityManager.isLowRamDeviceStatic() ? 50 : 200;
@VisibleForTesting
- public static final int TYPE_WARNING = 0x1;
+ public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
@VisibleForTesting
- public static final int TYPE_LIMIT = 0x2;
+ public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
@VisibleForTesting
- public static final int TYPE_LIMIT_SNOOZED = 0x3;
+ public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
private static final String TAG_POLICY_LIST = "policy-list";
private static final String TAG_NETWORK_POLICY = "network-policy";
@@ -419,7 +422,7 @@
/** Set of currently active {@link Notification} tags. */
@GuardedBy("mNetworkPoliciesSecondLock")
- private final ArraySet<String> mActiveNotifs = new ArraySet<String>();
+ private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
/** Foreground at UID granularity. */
@GuardedBy("mUidRulesFirstLock")
@@ -1054,7 +1057,7 @@
if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
// keep track of previously active notifications
- final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs);
+ final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
mActiveNotifs.clear();
// TODO: when switching to kernel notifications, compute next future
@@ -1091,9 +1094,9 @@
// cancel stale notifications that we didn't renew above
for (int i = beforeNotifs.size()-1; i >= 0; i--) {
- final String tag = beforeNotifs.valueAt(i);
- if (!mActiveNotifs.contains(tag)) {
- cancelNotification(tag);
+ final NotificationId notificationId = beforeNotifs.valueAt(i);
+ if (!mActiveNotifs.contains(notificationId)) {
+ cancelNotification(notificationId);
}
}
}
@@ -1141,19 +1144,11 @@
}
/**
- * Build unique tag that identifies an active {@link NetworkPolicy}
- * notification of a specific type, like {@link #TYPE_LIMIT}.
- */
- private String buildNotificationTag(NetworkPolicy policy, int type) {
- return TAG + ":" + policy.template.hashCode() + ":" + type;
- }
-
- /**
* Show notification for combined {@link NetworkPolicy} and specific type,
* like {@link #TYPE_LIMIT}. Okay to call multiple times.
*/
private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
- final String tag = buildNotificationTag(policy, type);
+ final NotificationId notificationId = new NotificationId(policy, type);
final Notification.Builder builder =
new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
builder.setOnlyAlertOnce(true);
@@ -1261,25 +1256,26 @@
try {
final String packageName = mContext.getPackageName();
final int[] idReceived = new int[1];
- if(!TextUtils.isEmpty(body)) {
+ if (!TextUtils.isEmpty(body)) {
builder.setStyle(new Notification.BigTextStyle()
.bigText(body));
}
mNotifManager.enqueueNotificationWithTag(
- packageName, packageName, tag, 0x0, builder.build(), idReceived,
- UserHandle.USER_ALL);
- mActiveNotifs.add(tag);
+ packageName, packageName, notificationId.getTag(), notificationId.getId(),
+ builder.build(), idReceived, UserHandle.USER_ALL);
+ mActiveNotifs.add(notificationId);
} catch (RemoteException e) {
// ignored; service lives in system_server
}
}
- private void cancelNotification(String tag) {
+ private void cancelNotification(NotificationId notificationId) {
// TODO: move to NotificationManager once we can mock it
try {
final String packageName = mContext.getPackageName();
mNotifManager.cancelNotificationWithTag(
- packageName, tag, 0x0, UserHandle.USER_ALL);
+ packageName, notificationId.getTag(), notificationId.getId(),
+ UserHandle.USER_ALL);
} catch (RemoteException e) {
// ignored; service lives in system_server
}
@@ -2585,7 +2581,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
@@ -4124,4 +4120,43 @@
return next;
}
}
+
+ private class NotificationId {
+ private final String mTag;
+ private final int mId;
+
+ NotificationId(NetworkPolicy policy, int type) {
+ mTag = buildNotificationTag(policy, type);
+ mId = type;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof NotificationId)) return false;
+ NotificationId that = (NotificationId) o;
+ return Objects.equals(mTag, that.mTag);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mTag);
+ }
+
+ /**
+ * Build unique tag that identifies an active {@link NetworkPolicy}
+ * notification of a specific type, like {@link #TYPE_LIMIT}.
+ */
+ private String buildNotificationTag(NetworkPolicy policy, int type) {
+ return TAG + ":" + policy.template.hashCode() + ":" + type;
+ }
+
+ public String getTag() {
+ return mTag;
+ }
+
+ public int getId() {
+ return mId;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 6d666e8..e746355 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -122,6 +122,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.EventLogTags;
@@ -1234,7 +1235,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
- mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
long duration = DateUtils.DAY_IN_MILLIS;
final HashSet<String> argSet = new HashSet<String>();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ede5a5e..44c715b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -144,6 +144,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.server.DeviceIdleController;
@@ -2451,14 +2452,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump NotificationManager from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
final DumpFilter filter = DumpFilter.parseFromArguments(args);
if (filter != null && filter.stats) {
dumpJson(pw, filter);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2115f31..0d9b052 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -254,6 +254,7 @@
import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
@@ -1181,7 +1182,6 @@
// Stores a list of users whose package restrictions file needs to be updated
private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
- static final long DEFAULT_CONTAINER_WHITELIST_DURATION = 10 * 60 * 1000;
final private DefaultContainerConnection mDefContainerConn =
new DefaultContainerConnection();
class DefaultContainerConnection implements ServiceConnection {
@@ -12915,9 +12915,6 @@
IActivityManager am = ActivityManager.getService();
if (am != null) {
try {
- getDeviceIdleController().addPowerSaveTempWhitelistApp(Process.SYSTEM_UID,
- DEFAULT_CONTAINER_PACKAGE, DEFAULT_CONTAINER_WHITELIST_DURATION,
- UserHandle.USER_SYSTEM, false, "cleaning packages");
am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
@@ -20230,15 +20227,7 @@
@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 ActivityManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " without permission "
- + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
DumpState dumpState = new DumpState();
boolean fullPreferred = false;
@@ -22238,7 +22227,7 @@
if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
+ stats.dataSize);
- final long startFreeBytes = measurePath.getFreeSpace();
+ final long startFreeBytes = measurePath.getUsableSpace();
final long sizeBytes;
if (moveCompleteApp) {
sizeBytes = stats.codeSize + stats.dataSize;
@@ -22302,7 +22291,7 @@
} catch (InterruptedException ignored) {
}
- final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
+ final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
final int progress = 10 + (int) MathUtils.constrain(
((deltaFreeBytes * 80) / sizeBytes), 0, 80);
mMoveCallbacks.notifyStatusChanged(moveId, progress);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 21fe5ba..6f7e0de 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -708,8 +708,6 @@
getPackageInfo().updateVersionInfo(pi);
- boolean changed = false;
-
// For existing shortcuts, update timestamps if they have any resources.
// Also check if shortcuts' activities are still main activities. Otherwise, disable them.
if (!isNewApp) {
@@ -733,7 +731,6 @@
}
// Still pinned, so fall-through and possibly update the resources.
}
- changed = true;
}
if (si.hasAnyResources()) {
@@ -750,29 +747,23 @@
// non-manifest at the moment, but icons can still be resources.)
si.lookupAndFillInResourceIds(publisherRes);
}
- changed = true;
si.setTimestamp(s.injectCurrentTimeMillis());
}
}
}
// (Re-)publish manifest shortcut.
- changed |= publishManifestShortcuts(newManifestShortcutList);
+ publishManifestShortcuts(newManifestShortcutList);
if (newManifestShortcutList != null) {
- changed |= pushOutExcessShortcuts();
+ pushOutExcessShortcuts();
}
s.verifyStates();
- if (changed) {
- // This will send a notification to the launcher, and also save .
- s.packageShortcutsChanged(getPackageName(), getPackageUserId());
- } else {
- // Still save the version code.
- s.scheduleSaveUser(getPackageUserId());
- }
- return changed;
+ // This will send a notification to the launcher, and also save .
+ s.packageShortcutsChanged(getPackageName(), getPackageUserId());
+ return true; // true means changed.
}
private boolean publishManifestShortcuts(List<ShortcutInfo> newManifestShortcutList) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index ef46bae..9bf6895 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -96,6 +96,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
@@ -1575,15 +1576,15 @@
* - Write to file
*/
void packageShortcutsChanged(@NonNull String packageName, @UserIdInt int userId) {
- if (DEBUG) {
- Slog.d(TAG, String.format(
- "Shortcut changes: package=%s, user=%d", packageName, userId));
- }
notifyListeners(packageName, userId);
scheduleSaveUser(userId);
}
private void notifyListeners(@NonNull String packageName, @UserIdInt int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, String.format(
+ "Shortcut changes: package=%s, user=%d", packageName, userId));
+ }
injectPostToHandler(() -> {
try {
final ArrayList<ShortcutChangeListener> copy;
@@ -2896,6 +2897,11 @@
}
private void handlePackageChanged(String packageName, int packageUserId) {
+ if (!isPackageInstalled(packageName, packageUserId)) {
+ // Probably disabled, which is the same thing as uninstalled.
+ handlePackageRemoved(packageName, packageUserId);
+ return;
+ }
if (DEBUG) {
Slog.d(TAG, String.format("handlePackageChanged: %s user=%d", packageName,
packageUserId));
@@ -3111,7 +3117,7 @@
}
private static boolean isInstalled(@Nullable ApplicationInfo ai) {
- return (ai != null) && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
+ return (ai != null) && ai.enabled && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
}
private static boolean isEphemeralApp(@Nullable ApplicationInfo ai) {
@@ -3442,8 +3448,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
- "can't dump by this caller");
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
boolean checkin = false;
boolean clear = false;
if (args != null) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8ecf6f7..63e2d4770 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -89,6 +89,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IAppOpsService;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
@@ -3358,15 +3359,7 @@
@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 UserManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " without permission "
- + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
long now = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 4f67e8c..9c4e700 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -75,6 +75,7 @@
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
import com.android.server.LockGuard;
import com.android.server.RescueParty;
@@ -4503,13 +4504,7 @@
@Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump PowerManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index edeb774..8c31731 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -47,6 +47,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -371,7 +372,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
synchronized (mSearchables) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 83ea075..212bd61 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -39,6 +39,7 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.notification.NotificationDelegate;
import com.android.server.power.ShutdownThread;
@@ -981,13 +982,7 @@
// ================================================================================
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 StatusBar from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println(" mDisabled1=0x" + Integer.toHexString(mDisabled1));
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index a847a3c..275b612 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -20,6 +20,7 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.server.pm.InstructionSets;
@@ -467,15 +468,7 @@
private final Binder mRemoteService = new Binder() {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump " + SERVICE + " from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
dumpImpl(fd, pw, args);
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 4570b0d..f4f7e24 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -59,6 +59,7 @@
import android.view.WindowManagerGlobal;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.SystemService;
import java.io.FileDescriptor;
@@ -849,8 +850,7 @@
@Override
protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
- mContext.enforceCallingPermission(Manifest.permission.DUMP,
- "dumping TrustManagerService");
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
if (isSafeMode()) {
fout.println("disabled because the system is in safe mode.");
return;
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 08eca73..6117da7 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -59,6 +59,7 @@
import android.view.KeyEvent;
import android.view.Surface;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
@@ -549,12 +550,7 @@
public void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump TvInputHardwareManager from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("TvInputHardwareManager Info:");
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 52763a1..be91f48 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -77,6 +77,7 @@
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
import com.android.server.SystemService;
@@ -1912,12 +1913,7 @@
@SuppressWarnings("resource")
protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump TvInputManager from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("User Ids (Current user: " + mCurrentUserId + "):");
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 324faff..cc08918 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -55,6 +55,7 @@
import android.util.SparseArray;
import com.android.internal.R;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
@@ -444,12 +445,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump VrManagerService from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+
pw.println("********* Dump of VrManagerService *********");
pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
pw.println("Persistent VR mode is currently: " +
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index c6b032b..6a18beb 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -87,6 +87,7 @@
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.server.EventLogTags;
@@ -2297,14 +2298,7 @@
@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 wallpaper service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("System wallpaper state:");
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 4a105e1..3b400b4 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -33,6 +33,7 @@
import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;
+import com.android.internal.util.DumpUtils;
import com.android.server.SystemService;
import java.io.FileDescriptor;
@@ -293,14 +294,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump webviewupdate service from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
WebViewUpdateService.this.mImpl.dumpState(pw);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6c7da50..95fbbb8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -204,6 +204,7 @@
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -6517,13 +6518,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump WindowManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
boolean dumpAll = false;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index db7c99e..6f49324 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -169,6 +169,7 @@
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BackgroundThread;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.Preconditions;
@@ -7269,14 +7270,7 @@
@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 DevicePolicyManagerService from from pid="
- + mInjector.binderGetCallingPid()
- + ", uid=" + mInjector.binderGetCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (this) {
pw.println("Current Device Policy Manager state:");
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 1c18c9b..100e459 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -45,6 +45,7 @@
import android.util.Log;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;
import com.android.server.SystemService;
@@ -1011,7 +1012,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
pw.println("MIDI Manager State:");
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index d7666d9..3ec8380 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -19,7 +19,6 @@
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
-import android.Manifest;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.ComponentName;
@@ -40,22 +39,23 @@
import android.print.IPrintDocumentAdapter;
import android.print.IPrintJobStateChangeListener;
import android.print.IPrintManager;
-import android.printservice.recommendation.IRecommendationsChangeListener;
import android.print.IPrintServicesChangeListener;
import android.print.IPrinterDiscoveryObserver;
import android.print.PrintAttributes;
import android.print.PrintJobId;
import android.print.PrintJobInfo;
import android.print.PrintManager;
-import android.printservice.recommendation.RecommendationInfo;
import android.print.PrinterId;
import android.printservice.PrintServiceInfo;
+import android.printservice.recommendation.IRecommendationsChangeListener;
+import android.printservice.recommendation.RecommendationInfo;
import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
@@ -628,13 +628,7 @@
fd = Preconditions.checkNotNull(fd);
pw = Preconditions.checkNotNull(pw);
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump PrintManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (mLock) {
final long identity = Binder.clearCallingIdentity();
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 7c37027..0f51c49 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -569,6 +569,7 @@
protected Map<String, PackageInfo> mInjectedPackages;
protected Set<PackageWithUser> mUninstalledPackages;
+ protected Set<PackageWithUser> mDisabledPackages;
protected Set<PackageWithUser> mEphemeralPackages;
protected Set<String> mSystemPackages;
@@ -740,6 +741,7 @@
pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
mUninstalledPackages = new HashSet<>();
+ mDisabledPackages = new HashSet<>();
mSystemPackages = new HashSet<>();
mEphemeralPackages = new HashSet<>();
@@ -1026,7 +1028,7 @@
protected void uninstallPackage(int userId, String packageName) {
if (ENABLE_DUMP) {
- Log.v(TAG, "Unnstall package " + packageName + " / " + userId);
+ Log.v(TAG, "Uninstall package " + packageName + " / " + userId);
}
mUninstalledPackages.add(PackageWithUser.of(userId, packageName));
}
@@ -1038,6 +1040,20 @@
mUninstalledPackages.remove(PackageWithUser.of(userId, packageName));
}
+ protected void disablePackage(int userId, String packageName) {
+ if (ENABLE_DUMP) {
+ Log.v(TAG, "Disable package " + packageName + " / " + userId);
+ }
+ mDisabledPackages.add(PackageWithUser.of(userId, packageName));
+ }
+
+ protected void enablePackage(int userId, String packageName) {
+ if (ENABLE_DUMP) {
+ Log.v(TAG, "Enable package " + packageName + " / " + userId);
+ }
+ mDisabledPackages.remove(PackageWithUser.of(userId, packageName));
+ }
+
PackageInfo getInjectedPackageInfo(String packageName, @UserIdInt int userId,
boolean getSignatures) {
final PackageInfo pi = mInjectedPackages.get(packageName);
@@ -1061,6 +1077,8 @@
if (mSystemPackages.contains(packageName)) {
ret.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
}
+ ret.applicationInfo.enabled =
+ !mDisabledPackages.contains(PackageWithUser.of(userId, packageName));
if (getSignatures) {
ret.signatures = pi.signatures;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 796cc16..dd0871a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -102,6 +102,8 @@
import java.io.IOException;
import java.util.List;
import java.util.Locale;
+import java.util.function.BiConsumer;
+import java.util.function.BiPredicate;
/**
* Tests for ShortcutService and ShortcutManager.
@@ -3967,6 +3969,22 @@
}
public void testHandlePackageDelete() {
+ checkHandlePackageDeleteInner((userId, packageName) -> {
+ uninstallPackage(userId, packageName);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageDeleteIntent(packageName, userId));
+ });
+ }
+
+ public void testHandlePackageDisable() {
+ checkHandlePackageDeleteInner((userId, packageName) -> {
+ disablePackage(userId, packageName);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageChangedIntent(packageName, userId));
+ });
+ }
+
+ private void checkHandlePackageDeleteInner(BiConsumer<Integer, String> remover) {
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
setCaller(CALLING_PACKAGE_1, USER_0);
@@ -4019,9 +4037,7 @@
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_2, USER_10));
assertTrue(bitmapDirectoryExists(CALLING_PACKAGE_3, USER_10));
- uninstallPackage(USER_0, CALLING_PACKAGE_1);
- mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageDeleteIntent(CALLING_PACKAGE_1, USER_0));
+ remover.accept(USER_0, CALLING_PACKAGE_1);
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
@@ -4039,9 +4055,7 @@
mRunningUsers.put(USER_10, true);
- uninstallPackage(USER_10, CALLING_PACKAGE_2);
- mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageDeleteIntent(CALLING_PACKAGE_2, USER_10));
+ remover.accept(USER_10, CALLING_PACKAGE_2);
assertNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "s1", USER_0));
assertNotNull(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, "s1", USER_0));
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 132ed98..c342933 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -26,6 +26,7 @@
import static org.mockito.Matchers.anyList;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
@@ -1096,7 +1097,7 @@
public ShortcutListAsserter assertCallbackCalledForPackageAndUser(
String publisherPackageName, UserHandle publisherUserHandle) {
final ArgumentCaptor<List> shortcuts = ArgumentCaptor.forClass(List.class);
- verify(mCallback, times(1)).onShortcutsChanged(
+ verify(mCallback, atLeastOnce()).onShortcutsChanged(
eq(publisherPackageName),
shortcuts.capture(),
eq(publisherUserHandle));
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 68c4c56..3f39e4f 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -398,7 +398,7 @@
super(looper);
// TODO: Handle all private volumes.
mStats = new StatFs(Environment.getDataDirectory().getAbsolutePath());
- mPreviousBytes = mStats.getFreeBytes();
+ mPreviousBytes = mStats.getAvailableBytes();
mMinimumThresholdBytes = mStats.getTotalBytes() * MINIMUM_CHANGE_DELTA;
}
@@ -413,9 +413,9 @@
switch (msg.what) {
case MSG_CHECK_STORAGE_DELTA: {
- long bytesDelta = Math.abs(mPreviousBytes - mStats.getFreeBytes());
+ long bytesDelta = Math.abs(mPreviousBytes - mStats.getAvailableBytes());
if (bytesDelta > mMinimumThresholdBytes) {
- mPreviousBytes = mStats.getFreeBytes();
+ mPreviousBytes = mStats.getAvailableBytes();
recalculateQuotas(getInitializedStrategy());
}
sendEmptyMessageDelayed(MSG_CHECK_STORAGE_DELTA, DELAY_IN_MILLIS);
@@ -434,7 +434,7 @@
// If errors occurred getting the quotas from disk, let's re-calc them.
if (mPreviousBytes < 0) {
- mPreviousBytes = mStats.getFreeBytes();
+ mPreviousBytes = mStats.getAvailableBytes();
recalculateQuotas(strategy);
}
sendEmptyMessageDelayed(MSG_CHECK_STORAGE_DELTA, DELAY_IN_MILLIS);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 7be2b0f..4ba457d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -78,6 +78,7 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
@@ -1465,13 +1466,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump UsageStats from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
UsageStatsService.this.dump(args, pw);
}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index a87ac9e..61e1e8f 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -40,6 +40,7 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
@@ -480,7 +481,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
final long ident = Binder.clearCallingIdentity();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 03a7db7..dc4b41c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -62,6 +62,7 @@
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiThread;
@@ -1117,13 +1118,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump voiceinteraction from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (this) {
pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)");
pw.println(" mEnableService: " + mEnableService);
diff --git a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
index e3bc34b..c20ee12 100644
--- a/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/content/res/Resources_Delegate.java
@@ -33,7 +33,6 @@
import com.android.layoutlib.bridge.util.NinePatchInputStream;
import com.android.ninepatch.NinePatch;
import com.android.resources.ResourceType;
-import com.android.resources.ResourceUrl;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
import com.android.util.Pair;
@@ -60,8 +59,6 @@
import java.io.InputStream;
import java.util.Iterator;
-import static com.android.SdkConstants.ANDROID_NS_NAME;
-
@SuppressWarnings("deprecation")
public class Resources_Delegate {
@@ -140,8 +137,8 @@
if (value == null) {
// Unable to resolve the attribute, just leave the unresolved value
- value = new ResourceValue(ResourceUrl.create(resourceInfo.getFirst(), attributeName,
- platformResFlag_out[0]), attributeName);
+ value = new ResourceValue(resourceInfo.getFirst(), attributeName, attributeName,
+ platformResFlag_out[0]);
}
return Pair.of(attributeName, value);
}
@@ -681,7 +678,7 @@
String packageName;
if (resourceInfo != null) {
if (platformOut[0]) {
- packageName = ANDROID_NS_NAME;
+ packageName = SdkConstants.ANDROID_NS_NAME;
} else {
packageName = resources.mContext.getPackageName();
packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
@@ -699,7 +696,7 @@
Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
if (resourceInfo != null) {
if (platformOut[0]) {
- return ANDROID_NS_NAME;
+ return SdkConstants.ANDROID_NS_NAME;
}
String packageName = resources.mContext.getPackageName();
return packageName == null ? SdkConstants.APP_PREFIX : packageName;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index cc5a0c3..328fc0a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -31,7 +31,6 @@
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.Stack;
import com.android.resources.ResourceType;
-import com.android.resources.ResourceUrl;
import com.android.util.Pair;
import com.android.util.PropertiesMap;
import com.android.util.PropertiesMap.Property;
@@ -87,6 +86,7 @@
import android.view.BridgeInflater;
import android.view.Display;
import android.view.DisplayAdjustments;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
@@ -107,7 +107,6 @@
import java.util.Map;
import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
-import static com.android.SdkConstants.ANDROID_NS_NAME;
import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
/**
@@ -122,23 +121,20 @@
static {
FRAMEWORK_PATCHED_VALUES.put("animateFirstView", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.BOOL, "animateFirstView"),
- "false"));
- FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.BOOL, "animateLayoutChanges"),
- "false"));
+ ResourceType.BOOL, "animateFirstView", "false", false));
+ FRAMEWORK_PATCHED_VALUES.put("animateLayoutChanges",
+ new ResourceValue(ResourceType.BOOL, "animateLayoutChanges", "false", false));
- FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.LAYOUT,
- "textEditSuggestionItemLayout"), "text_edit_suggestion_item"));
- FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.LAYOUT,
- "textEditSuggestionContainerLayout"), "text_edit_suggestion_container"));
- FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle", new ResourceValue(
- ResourceUrl.create(ANDROID_NS_NAME, ResourceType.STYLE,
- "textEditSuggestionHighlightStyle"),
- "TextAppearance.Holo.SuggestionHighlight"));
+ FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionItemLayout",
+ new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionItemLayout",
+ "text_edit_suggestion_item", true));
+ FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionContainerLayout",
+ new ResourceValue(ResourceType.LAYOUT, "textEditSuggestionContainerLayout",
+ "text_edit_suggestion_container", true));
+ FRAMEWORK_REPLACE_VALUES.put("textEditSuggestionHighlightStyle",
+ new ResourceValue(ResourceType.STYLE, "textEditSuggestionHighlightStyle",
+ "TextAppearance.Holo.SuggestionHighlight", true));
}
@@ -974,9 +970,7 @@
// there is a value in the XML, but we need to resolve it in case it's
// referencing another resource or a theme value.
ta.bridgeSetValue(index, attrName, frameworkAttr,
- mRenderResources.resolveResValue(new ResourceValue(
- ResourceUrl.create(ResourceType.STRING, attrName,
- isPlatformFile), value)));
+ mRenderResources.resolveValue(null, attrName, value, isPlatformFile));
}
}
}