Merge "Modify constructor of NetworkRegistrationState"
diff --git a/Android.bp b/Android.bp
index 41d5f28..cc9cfe9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -290,7 +290,6 @@
"core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl",
"core/java/android/service/gatekeeper/IGateKeeperService.aidl",
"core/java/android/service/intelligence/IIntelligenceService.aidl",
-
"core/java/android/service/notification/INotificationListener.aidl",
"core/java/android/service/notification/IStatusBarNotificationHolder.aidl",
"core/java/android/service/notification/IConditionListener.aidl",
@@ -573,6 +572,7 @@
"telephony/java/com/android/internal/telephony/IApnSourceService.aidl",
"telephony/java/com/android/internal/telephony/ICarrierConfigLoader.aidl",
"telephony/java/com/android/internal/telephony/IMms.aidl",
+ "telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl",
"telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl",
"telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl",
"telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
@@ -782,9 +782,11 @@
java_library_host {
name: "inspector-annotation",
srcs: [
- "core/java/android/view/inspector/InspectableChildren.java",
"core/java/android/view/inspector/InspectableNodeName.java",
"core/java/android/view/inspector/InspectableProperty.java",
+ // Needed for the ResourceId.ID_NULL constant
+ "core/java/android/content/res/ResourceId.java",
+ "core/java/android/annotation/AnyRes.java",
],
}
diff --git a/api/current.txt b/api/current.txt
index 079539e..83827ea 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13728,6 +13728,7 @@
public abstract class ColorSpace {
method public static android.graphics.ColorSpace adapt(android.graphics.ColorSpace, float[]);
method public static android.graphics.ColorSpace adapt(android.graphics.ColorSpace, float[], android.graphics.ColorSpace.Adaptation);
+ method public static float[] cctToIlluminantdXyz(int);
method public static float[] chromaticAdaptation(android.graphics.ColorSpace.Adaptation, float[], float[]);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace);
method public static android.graphics.ColorSpace.Connector connect(android.graphics.ColorSpace, android.graphics.ColorSpace, android.graphics.ColorSpace.RenderIntent);
@@ -29062,7 +29063,7 @@
method public static int compareSignalLevel(int, int);
method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String);
method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String);
- method public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String);
+ method public deprecated android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String);
method public deprecated boolean disableNetwork(int);
method public deprecated boolean disconnect();
method public deprecated boolean enableNetwork(int, boolean);
@@ -29124,9 +29125,10 @@
field public static final int STATUS_NETWORK_SUGGESTIONS_SUCCESS = 0; // 0x0
field public static final deprecated java.lang.String SUPPLICANT_CONNECTION_CHANGE_ACTION = "android.net.wifi.supplicant.CONNECTION_CHANGE";
field public static final deprecated java.lang.String SUPPLICANT_STATE_CHANGED_ACTION = "android.net.wifi.supplicant.STATE_CHANGE";
- field public static final int WIFI_MODE_FULL = 1; // 0x1
+ field public static final deprecated int WIFI_MODE_FULL = 1; // 0x1
field public static final int WIFI_MODE_FULL_HIGH_PERF = 3; // 0x3
- field public static final int WIFI_MODE_SCAN_ONLY = 2; // 0x2
+ field public static final int WIFI_MODE_FULL_LOW_LATENCY = 4; // 0x4
+ field public static final deprecated int WIFI_MODE_SCAN_ONLY = 2; // 0x2
field public static final java.lang.String WIFI_STATE_CHANGED_ACTION = "android.net.wifi.WIFI_STATE_CHANGED";
field public static final int WIFI_STATE_DISABLED = 1; // 0x1
field public static final int WIFI_STATE_DISABLING = 0; // 0x0
@@ -33537,6 +33539,7 @@
method public static boolean isExternalStorageRemovable();
method public static boolean isExternalStorageRemovable(java.io.File);
field public static java.lang.String DIRECTORY_ALARMS;
+ field public static java.lang.String DIRECTORY_AUDIOBOOKS;
field public static java.lang.String DIRECTORY_DCIM;
field public static java.lang.String DIRECTORY_DOCUMENTS;
field public static java.lang.String DIRECTORY_DOWNLOADS;
@@ -37296,6 +37299,7 @@
method public static java.lang.String getVolumeName(android.net.Uri);
method public static android.provider.MediaStore.PendingSession openPending(android.content.Context, android.net.Uri);
method public static android.net.Uri setIncludePending(android.net.Uri);
+ method public static android.net.Uri setRequireOriginal(android.net.Uri);
field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
field public static final java.lang.String ACTION_REVIEW = "android.provider.action.REVIEW";
@@ -37393,6 +37397,7 @@
field public static final java.lang.String COMPOSER = "composer";
field public static final java.lang.String DURATION = "duration";
field public static final java.lang.String IS_ALARM = "is_alarm";
+ field public static final java.lang.String IS_AUDIOBOOK = "is_audiobook";
field public static final java.lang.String IS_MUSIC = "is_music";
field public static final java.lang.String IS_NOTIFICATION = "is_notification";
field public static final java.lang.String IS_PODCAST = "is_podcast";
@@ -42898,6 +42903,19 @@
field public static final int BAND_9 = 9; // 0x9
}
+ public final class AvailableNetworkInfo implements android.os.Parcelable {
+ ctor public AvailableNetworkInfo(int, int, java.util.ArrayList<java.lang.String>);
+ method public int describeContents();
+ method public java.util.List<java.lang.String> getMccMncs();
+ method public int getPriority();
+ method public int getSubId();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.AvailableNetworkInfo> CREATOR;
+ field public static final int PRIORITY_HIGH = 1; // 0x1
+ field public static final int PRIORITY_LOW = 3; // 0x3
+ field public static final int PRIORITY_MED = 2; // 0x2
+ }
+
public class CarrierConfigManager {
method public android.os.PersistableBundle getConfig();
method public android.os.PersistableBundle getConfigForSubId(int);
@@ -43876,6 +43894,7 @@
method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
method public deprecated void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
method public deprecated void setVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle, boolean);
+ method public boolean updateAvailableNetworks(java.util.List<android.telephony.AvailableNetworkInfo>);
field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL";
field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -45847,6 +45866,7 @@
method public deprecated java.lang.String getLocale();
method public java.util.Locale getLocaleObject();
method public int getSpanTypeId();
+ method public int getUnderlineColor();
method public java.lang.String[] getSuggestions();
method public void setFlags(int);
method public void updateDrawState(android.text.TextPaint);
@@ -51963,10 +51983,90 @@
}
+package android.view.inspector {
+
+ public abstract interface InspectionCompanion<T> {
+ method public default java.lang.String getNodeName();
+ method public abstract void mapProperties(android.view.inspector.PropertyMapper);
+ method public abstract void readProperties(T, android.view.inspector.PropertyReader);
+ }
+
+ public static class InspectionCompanion.UninitializedPropertyMapException extends java.lang.RuntimeException {
+ ctor public InspectionCompanion.UninitializedPropertyMapException();
+ }
+
+ public final class IntEnumMapping {
+ method public java.lang.String nameOf(int);
+ }
+
+ public static final class IntEnumMapping.Builder {
+ ctor public IntEnumMapping.Builder();
+ method public android.view.inspector.IntEnumMapping.Builder addValue(java.lang.String, int);
+ method public android.view.inspector.IntEnumMapping build();
+ method public void clear();
+ }
+
+ public final class IntFlagMapping {
+ method public java.lang.String[] namesOf(int);
+ }
+
+ public static final class IntFlagMapping.Builder {
+ ctor public IntFlagMapping.Builder();
+ method public android.view.inspector.IntFlagMapping.Builder addFlag(java.lang.String, int);
+ method public android.view.inspector.IntFlagMapping.Builder addFlag(java.lang.String, int, int);
+ method public android.view.inspector.IntFlagMapping build();
+ method public void clear();
+ }
+
+ public abstract interface PropertyMapper {
+ method public abstract int mapBoolean(java.lang.String, int);
+ method public abstract int mapByte(java.lang.String, int);
+ method public abstract int mapChar(java.lang.String, int);
+ method public abstract int mapColor(java.lang.String, int);
+ method public abstract int mapDouble(java.lang.String, int);
+ method public abstract int mapFloat(java.lang.String, int);
+ method public abstract int mapGravity(java.lang.String, int);
+ method public abstract int mapInt(java.lang.String, int);
+ method public abstract int mapIntEnum(java.lang.String, int, android.view.inspector.IntEnumMapping);
+ method public abstract int mapIntFlag(java.lang.String, int, android.view.inspector.IntFlagMapping);
+ method public abstract int mapLong(java.lang.String, int);
+ method public abstract int mapObject(java.lang.String, int);
+ method public abstract int mapShort(java.lang.String, int);
+ }
+
+ public static class PropertyMapper.PropertyConflictException extends java.lang.RuntimeException {
+ ctor public PropertyMapper.PropertyConflictException(java.lang.String, java.lang.String, java.lang.String);
+ }
+
+ public abstract interface PropertyReader {
+ method public abstract void readBoolean(int, boolean);
+ method public abstract void readByte(int, byte);
+ method public abstract void readChar(int, char);
+ method public abstract void readColor(int, int);
+ method public abstract void readColor(int, long);
+ method public abstract void readColor(int, android.graphics.Color);
+ method public abstract void readDouble(int, double);
+ method public abstract void readFloat(int, float);
+ method public abstract void readGravity(int, int);
+ method public abstract void readInt(int, int);
+ method public abstract void readIntEnum(int, int);
+ method public abstract void readIntFlag(int, int);
+ method public abstract void readLong(int, long);
+ method public abstract void readObject(int, java.lang.Object);
+ method public abstract void readShort(int, short);
+ }
+
+ public static class PropertyReader.PropertyTypeMismatchException extends java.lang.RuntimeException {
+ ctor public PropertyReader.PropertyTypeMismatchException(int, java.lang.String, java.lang.String, java.lang.String);
+ ctor public PropertyReader.PropertyTypeMismatchException(int, java.lang.String, java.lang.String);
+ }
+
+}
+
package android.view.intelligence {
- public final class IntelligenceManager {
- method public android.content.ComponentName getIntelligenceServiceComponentName();
+ public final class ContentCaptureManager {
+ method public android.content.ComponentName getServiceComponentName();
method public boolean isContentCaptureEnabled();
method public android.view.ViewStructure newVirtualViewStructure(android.view.autofill.AutofillId, int);
method public void notifyViewAppeared(android.view.ViewStructure);
diff --git a/api/system-current.txt b/api/system-current.txt
index 62d446f..6ee7afa 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25,7 +25,6 @@
field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
field public static final java.lang.String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
- field public static final java.lang.String BIND_INTELLIGENCE_SERVICE = "android.permission.BIND_INTELLIGENCE_SERVICE";
field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
@@ -34,6 +33,7 @@
field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
field public static final java.lang.String BIND_SETTINGS_SUGGESTIONS_SERVICE = "android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE";
+ field public static final java.lang.String BIND_SMART_SUGGESTIONS_SERVICE = "android.permission.BIND_SMART_SUGGESTIONS_SERVICE";
field public static final java.lang.String BIND_SOUND_TRIGGER_DETECTION_SERVICE = "android.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE";
field public static final java.lang.String BIND_TELEPHONY_DATA_SERVICE = "android.permission.BIND_TELEPHONY_DATA_SERVICE";
field public static final java.lang.String BIND_TELEPHONY_NETWORK_SERVICE = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
@@ -4980,6 +4980,13 @@
package android.service.intelligence {
+ public final class ContentCaptureEventsRequest implements android.os.Parcelable {
+ method public int describeContents();
+ method public java.util.List<android.view.intelligence.ContentCaptureEvent> getEvents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.intelligence.ContentCaptureEventsRequest> CREATOR;
+ }
+
public final class FillCallback {
method public void onSuccess(android.service.intelligence.FillResponse);
}
@@ -5014,16 +5021,6 @@
field public static final long FLAG_METADATA_ADDRESS = 1L; // 0x1L
}
- public abstract class IntelligenceService extends android.app.Service {
- ctor public IntelligenceService();
- method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData);
- method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>);
- method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId);
- method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId);
- method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback);
- field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.IntelligenceService";
- }
-
public final class InteractionContext implements android.os.Parcelable {
method public int describeContents();
method public android.content.ComponentName getActivityComponent();
@@ -5059,6 +5056,21 @@
method public android.service.intelligence.PresentationParams.Area getSubArea(android.graphics.Rect);
}
+ public abstract class SmartSuggestionsService extends android.app.Service {
+ ctor public SmartSuggestionsService();
+ method public final java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities();
+ method public final java.util.Set<java.lang.String> getContentCaptureDisabledPackages();
+ method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData);
+ method public abstract void onContentCaptureEventsRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.ContentCaptureEventsRequest);
+ method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId);
+ method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId);
+ method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback);
+ method public final void setActivityContentCaptureEnabled(android.content.ComponentName, boolean);
+ method public final void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>);
+ method public final void setPackageContentCaptureEnabled(java.lang.String, boolean);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.SmartSuggestionsService";
+ }
+
public final class SnapshotData implements android.os.Parcelable {
method public int describeContents();
method public android.app.assist.AssistContent getAssistContent();
@@ -5699,6 +5711,26 @@
field public static final int RESULT_SUCCESS = 0; // 0x0
}
+ public abstract interface NumberVerificationCallback {
+ method public default void onCallReceived(java.lang.String);
+ method public default void onVerificationFailed(int);
+ field public static final int REASON_CONCURRENT_REQUESTS = 4; // 0x4
+ field public static final int REASON_IN_ECBM = 5; // 0x5
+ field public static final int REASON_IN_EMERGENCY_CALL = 6; // 0x6
+ field public static final int REASON_NETWORK_NOT_AVAILABLE = 2; // 0x2
+ field public static final int REASON_TIMED_OUT = 1; // 0x1
+ field public static final int REASON_TOO_MANY_CALLS = 3; // 0x3
+ field public static final int REASON_UNSPECIFIED = 0; // 0x0
+ }
+
+ public final class PhoneNumberRange implements android.os.Parcelable {
+ ctor public PhoneNumberRange(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+ method public int describeContents();
+ method public boolean matches(java.lang.String);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.PhoneNumberRange> CREATOR;
+ }
+
public class PhoneStateListener {
method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int);
@@ -5863,6 +5895,7 @@
method public boolean needsOtaServiceProvisioning();
method public boolean rebootRadio();
method public void requestCellInfoUpdate(android.os.WorkSource, java.util.concurrent.Executor, android.telephony.TelephonyManager.CellInfoCallback);
+ method public void requestNumberVerification(android.telephony.PhoneNumberRange, long, java.util.concurrent.Executor, android.telephony.NumberVerificationCallback);
method public boolean resetRadioConfig();
method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
method public void setCarrierDataEnabled(boolean);
@@ -5892,6 +5925,7 @@
field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+ field public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000L; // 0xea60L
field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4
field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5
field public static final int NETWORK_MODE_EVDO_NO_CDMA = 6; // 0x6
@@ -7243,14 +7277,6 @@
field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7
}
- public final class IntelligenceManager {
- method public java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities();
- method public java.util.Set<java.lang.String> getContentCaptureDisabledPackages();
- method public void setActivityContentCaptureEnabled(android.content.ComponentName, boolean);
- method public void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>);
- method public void setPackageContentCaptureEnabled(java.lang.String, boolean);
- }
-
public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
method public android.view.autofill.AutofillId getParentAutofillId();
}
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 1597c8c..52a2ab4 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -77,7 +77,7 @@
+ " <BINDING> binds a typed value to a column and is formatted:\n"
+ " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
+ " <TYPE> specifies data type such as:\n"
- + " b - boolean, s - string, i - integer, l - long, f - float, d - double\n"
+ + " b - boolean, s - string, i - integer, l - long, f - float, d - double, n - null\n"
+ " Note: Omit the value for passing an empty string, e.g column:s:\n"
+ " Example:\n"
+ " # Add \"new_setting\" secure setting with value \"new_value\".\n"
@@ -153,6 +153,7 @@
private static final String TYPE_LONG = "l";
private static final String TYPE_FLOAT = "f";
private static final String TYPE_DOUBLE = "d";
+ private static final String TYPE_NULL = "n";
private static final String COLON = ":";
private static final String ARGUMENT_PREFIX = "--";
@@ -410,6 +411,8 @@
values.put(column, Long.parseLong(value));
} else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) {
values.put(column, Double.parseDouble(value));
+ } else if (TYPE_NULL.equalsIgnoreCase(type)) {
+ values.putNull(column);
} else {
throw new IllegalArgumentException("Unsupported type: " + type);
}
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 05bb9a1..f3f065a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -122,7 +122,7 @@
import android.view.autofill.AutofillPopupWindow;
import android.view.autofill.IAutofillWindowPresenter;
import android.view.intelligence.ContentCaptureEvent;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -824,8 +824,8 @@
/** The autofill manager. Always access via {@link #getAutofillManager()}. */
@Nullable private AutofillManager mAutofillManager;
- /** The screen observation manager. Always access via {@link #getIntelligenceManager()}. */
- @Nullable private IntelligenceManager mIntelligenceManager;
+ /** The content capture manager. Always access via {@link #getContentCaptureManager()}. */
+ @Nullable private ContentCaptureManager mContentCaptureManager;
private final ArrayList<Application.ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<Application.ActivityLifecycleCallbacks>();
@@ -1016,39 +1016,39 @@
}
/**
- * (Creates, sets, and ) returns the intelligence manager
+ * (Creates, sets, and ) returns the content capture manager
*
- * @return The intelligence manager
+ * @return The content capture manager
*/
- @NonNull private IntelligenceManager getIntelligenceManager() {
- if (mIntelligenceManager == null) {
- mIntelligenceManager = getSystemService(IntelligenceManager.class);
+ @NonNull private ContentCaptureManager getContentCaptureManager() {
+ if (mContentCaptureManager == null) {
+ mContentCaptureManager = getSystemService(ContentCaptureManager.class);
}
- return mIntelligenceManager;
+ return mContentCaptureManager;
}
- private void notifyIntelligenceManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
- final IntelligenceManager im = getIntelligenceManager();
- if (im == null || !im.isContentCaptureEnabled()) {
+ private void notifyContentCaptureManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
+ final ContentCaptureManager cm = getContentCaptureManager();
+ if (cm == null || !cm.isContentCaptureEnabled()) {
return;
}
switch (event) {
case ContentCaptureEvent.TYPE_ACTIVITY_CREATED:
//TODO(b/111276913): decide whether the InteractionSessionId should be
// saved / restored in the activity bundle.
- im.onActivityCreated(mToken, getComponentName());
+ cm.onActivityCreated(mToken, getComponentName());
break;
case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED:
- im.onActivityDestroyed();
+ cm.onActivityDestroyed();
break;
case ContentCaptureEvent.TYPE_ACTIVITY_STARTED:
case ContentCaptureEvent.TYPE_ACTIVITY_RESUMED:
case ContentCaptureEvent.TYPE_ACTIVITY_PAUSED:
case ContentCaptureEvent.TYPE_ACTIVITY_STOPPED:
- im.onActivityLifecycleEvent(event);
+ cm.onActivityLifecycleEvent(event);
break;
default:
- Log.w(TAG, "notifyIntelligenceManagerIfNeeded(): invalid type " + event);
+ Log.w(TAG, "notifyContentCaptureManagerIfNeeded(): invalid type " + event);
}
}
@@ -1057,6 +1057,7 @@
super.attachBaseContext(newBase);
if (newBase != null) {
newBase.setAutofillClient(this);
+ newBase.setContentCaptureSupported(true);
}
}
@@ -1066,6 +1067,12 @@
return this;
}
+ /** @hide */
+ @Override
+ public boolean isContentCaptureSupported() {
+ return true;
+ }
+
/**
* Register an {@link Application.ActivityLifecycleCallbacks} instance that receives
* lifecycle callbacks for only this Activity.
@@ -1410,7 +1417,7 @@
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
- notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
+ notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
}
/**
@@ -1644,7 +1651,7 @@
if (mAutoFillResetNeeded) {
getAutofillManager().onVisibleForAutofill();
}
- notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
+ notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
}
/**
@@ -1735,7 +1742,7 @@
}
}
}
- notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
+ notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
mCalled = true;
}
@@ -2129,7 +2136,7 @@
mAutoFillIgnoreFirstResumePause = false;
}
}
- notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
+ notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
mCalled = true;
}
@@ -2318,7 +2325,7 @@
getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL,
mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
}
- notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
+ notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
}
}
@@ -2390,7 +2397,7 @@
dispatchActivityDestroyed();
- notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);
+ notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);
}
@@ -6806,7 +6813,7 @@
}
void dumpIntelligenceManager(String prefix, PrintWriter writer) {
- final IntelligenceManager im = getIntelligenceManager();
+ final ContentCaptureManager im = getContentCaptureManager();
if (im != null) {
im.dump(prefix, writer);
} else {
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 446d98e..2c435a2 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -31,7 +31,6 @@
import android.util.Log;
import android.view.IWindowManager;
import android.view.InputDevice;
-import android.view.InputEvent;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -291,9 +290,14 @@
return super.onGenericMotionEvent(event);
}
- private boolean injectInputEvent(InputEvent event) {
+ private boolean injectInputEvent(MotionEvent event) {
if (mInputForwarder != null) {
try {
+ // The touch event that the ActivityView gets is in View space, but the event needs
+ // to get forwarded in screen space. This offsets the touch event by the location
+ // the ActivityView is on screen and sends it to the input forwarder.
+ getLocationOnScreen(mLocationOnScreen);
+ event.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
return mInputForwarder.forwardEvent(event);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 28ecb27..6f0b6c8 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -217,6 +217,8 @@
private AutofillClient mAutofillClient = null;
private boolean mIsAutofillCompatEnabled;
+ private boolean mIsContentCaptureSupported = false;
+
private final Object mSync = new Object();
@GuardedBy("mSync")
@@ -2376,6 +2378,18 @@
mIsAutofillCompatEnabled = autofillCompatEnabled;
}
+ /** @hide */
+ @Override
+ public boolean isContentCaptureSupported() {
+ return mIsContentCaptureSupported;
+ }
+
+ /** @hide */
+ @Override
+ public void setContentCaptureSupported(boolean supported) {
+ mIsContentCaptureSupported = supported;
+ }
+
@UnsupportedAppUsage
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index e83bcd0..88fb025 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -96,6 +96,7 @@
String callingPackage);
void unregisterUidObserver(in IUidObserver observer);
boolean isUidActive(int uid, String callingPackage);
+ int getUidProcessState(int uid, in String callingPackage);
// =============== End of transactions used on native side as well ============================
// Special low-level communication with activity manager.
@@ -379,8 +380,6 @@
void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
int getPackageProcessState(in String packageName, in String callingPackage);
void updateDeviceOwner(in String packageName);
- int getUidProcessState(int uid, in String callingPackage);
-
// Start of N transactions
// Start Binder transaction tracking for all applications.
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index ce88809..e116d98 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -43,8 +43,6 @@
*/
void onUidIdle(int uid, boolean disabled);
- // =============== End of transactions used on native side as well ============================
-
/**
* General report of a state change of an uid.
*
@@ -55,6 +53,8 @@
*/
void onUidStateChanged(int uid, int procState, long procStateSeq);
+ // =============== End of transactions used on native side as well ============================
+
/**
* Report when the cached state of a uid has changed.
* If true, a uid has become cached -- that is, it has some active processes that are
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 89ec19b..25fa897 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1424,7 +1424,62 @@
return other.priorityCategories == priorityCategories
&& other.priorityCallSenders == priorityCallSenders
&& other.priorityMessageSenders == priorityMessageSenders
- && other.suppressedVisualEffects == suppressedVisualEffects;
+ && suppressedVisualEffectsEqual(suppressedVisualEffects,
+ other.suppressedVisualEffects);
+ }
+
+
+ private boolean suppressedVisualEffectsEqual(int suppressedEffects,
+ int otherSuppressedVisualEffects) {
+ if (suppressedEffects == otherSuppressedVisualEffects) {
+ return true;
+ }
+
+ if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
+ suppressedEffects |= SUPPRESSED_EFFECT_PEEK;
+ }
+ if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
+ suppressedEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+ suppressedEffects |= SUPPRESSED_EFFECT_LIGHTS;
+ suppressedEffects |= SUPPRESSED_EFFECT_AMBIENT;
+ }
+
+ if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0) {
+ otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_PEEK;
+ }
+ if ((otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0) {
+ otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+ otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_LIGHTS;
+ otherSuppressedVisualEffects |= SUPPRESSED_EFFECT_AMBIENT;
+ }
+
+ if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON)
+ != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_ON)) {
+ int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_ON) != 0
+ ? otherSuppressedVisualEffects : suppressedEffects;
+ if ((currSuppressedEffects & SUPPRESSED_EFFECT_PEEK) == 0) {
+ return false;
+ }
+ }
+
+ if ((suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF)
+ != (otherSuppressedVisualEffects & SUPPRESSED_EFFECT_SCREEN_OFF)) {
+ int currSuppressedEffects = (suppressedEffects & SUPPRESSED_EFFECT_SCREEN_OFF) != 0
+ ? otherSuppressedVisualEffects : suppressedEffects;
+ if ((currSuppressedEffects & SUPPRESSED_EFFECT_FULL_SCREEN_INTENT) == 0
+ || (currSuppressedEffects & SUPPRESSED_EFFECT_LIGHTS) == 0
+ || (currSuppressedEffects & SUPPRESSED_EFFECT_AMBIENT) == 0) {
+ return false;
+ }
+ }
+
+ int thisWithoutOldEffects = suppressedEffects
+ & ~SUPPRESSED_EFFECT_SCREEN_ON
+ & ~SUPPRESSED_EFFECT_SCREEN_OFF;
+ int otherWithoutOldEffects = otherSuppressedVisualEffects
+ & ~SUPPRESSED_EFFECT_SCREEN_ON
+ & ~SUPPRESSED_EFFECT_SCREEN_OFF;
+ return thisWithoutOldEffects == otherWithoutOldEffects;
}
@Override
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 0123551..dfe371c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -165,8 +165,8 @@
import android.view.autofill.AutofillManager;
import android.view.autofill.IAutoFillManager;
import android.view.inputmethod.InputMethodManager;
+import android.view.intelligence.ContentCaptureManager;
import android.view.intelligence.IIntelligenceManager;
-import android.view.intelligence.IntelligenceManager;
import android.view.textclassifier.TextClassificationManager;
import android.view.textservice.TextServicesManager;
@@ -199,6 +199,7 @@
private SystemServiceRegistry() { }
static {
+ //CHECKSTYLE:OFF IndentationCheck
registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
new CachedServiceFetcher<AccessibilityManager>() {
@Override
@@ -1050,15 +1051,20 @@
return new AutofillManager(ctx.getOuterContext(), service);
}});
- registerService(Context.INTELLIGENCE_MANAGER_SERVICE, IntelligenceManager.class,
- new CachedServiceFetcher<IntelligenceManager>() {
+ registerService(Context.CONTENT_CAPTURE_MANAGER_SERVICE, ContentCaptureManager.class,
+ new CachedServiceFetcher<ContentCaptureManager>() {
@Override
- public IntelligenceManager createService(ContextImpl ctx)
+ public ContentCaptureManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
// Get the services without throwing as this is an optional feature
- IBinder b = ServiceManager.getService(Context.INTELLIGENCE_MANAGER_SERVICE);
- IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b);
- return new IntelligenceManager(ctx.getOuterContext(), service);
+ Context outerContext = ctx.getOuterContext();
+ if (outerContext.isContentCaptureSupported()) {
+ IBinder b = ServiceManager
+ .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+ IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b);
+ return new ContentCaptureManager(outerContext, service);
+ }
+ return null;
}});
registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
@@ -1138,6 +1144,7 @@
throws ServiceNotFoundException {
return new RoleManager(ctx.getOuterContext());
}});
+ //CHECKSTYLE:ON IndentationCheck
}
/**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index ff57b03..68aac64 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3933,12 +3933,13 @@
public static final String AUTOFILL_MANAGER_SERVICE = "autofill";
/**
- * Official published name of the intelligence service.
+ * Official published name of the smart suggestions service.
*
* @hide
* @see #getSystemService(String)
*/
- public static final String INTELLIGENCE_MANAGER_SERVICE = "intelligence";
+ // TODO(b/111276913): rename string (will require SELinux change first)
+ public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "intelligence";
/**
* Use with {@link #getSystemService(String)} to access the
@@ -5223,6 +5224,25 @@
}
/**
+ * Checks whether this context supports content capture.
+ *
+ * @hide
+ */
+ // NOTE: for now we just need to check if it's supported so we can optimize calls that can be
+ // skipped when it isn't. Eventually, we might need a full
+ // ContentCaptureManager.ContentCaptureClient interface (as it's done with AutofillClient).
+ //
+ public boolean isContentCaptureSupported() {
+ return false;
+ }
+
+ /**
+ * @hide
+ */
+ public void setContentCaptureSupported(@SuppressWarnings("unused") boolean supported) {
+ }
+
+ /**
* Throws an exception if the Context is using system resources,
* which are non-runtime-overlay-themable and may show inconsistent UI.
* @hide
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 2db44b4..26ed3b7 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -1049,4 +1049,20 @@
mBase.setAutofillCompatibilityEnabled(autofillCompatEnabled);
}
}
+
+ /**
+ * @hide
+ */
+ @Override
+ public boolean isContentCaptureSupported() {
+ return mBase.isContentCaptureSupported();
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public void setContentCaptureSupported(boolean supported) {
+ mBase.setContentCaptureSupported(supported);
+ }
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 7c3b5e4..98a135f 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1770,7 +1770,7 @@
* is on the package whitelist.
*
* @param policy configured policy for this app, or {@link #HIDDEN_API_ENFORCEMENT_DEFAULT}
- * if nothing configured.
+ * if nothing configured.
* @hide
*/
public void maybeUpdateHiddenApiEnforcementPolicy(@HiddenApiEnforcementPolicy int policy) {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0c1aae8..8904ee6 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -657,6 +657,12 @@
public static String DIRECTORY_SCREENSHOTS = "Screenshots";
/**
+ * Standard directory in which to place any audio files which are
+ * audiobooks.
+ */
+ public static String DIRECTORY_AUDIOBOOKS = "Audiobooks";
+
+ /**
* List of standard storage directories.
* <p>
* Each of its values have its own constant:
@@ -671,6 +677,7 @@
* <li>{@link #DIRECTORY_DOWNLOADS}
* <li>{@link #DIRECTORY_DCIM}
* <li>{@link #DIRECTORY_DOCUMENTS}
+ * <li>{@link #DIRECTORY_AUDIOBOOKS}
* </ul>
* @hide
*/
@@ -684,7 +691,8 @@
DIRECTORY_MOVIES,
DIRECTORY_DOWNLOADS,
DIRECTORY_DCIM,
- DIRECTORY_DOCUMENTS
+ DIRECTORY_DOCUMENTS,
+ DIRECTORY_AUDIOBOOKS,
};
/**
@@ -709,6 +717,7 @@
/** {@hide} */ public static final int HAS_DOWNLOADS = 1 << 7;
/** {@hide} */ public static final int HAS_DCIM = 1 << 8;
/** {@hide} */ public static final int HAS_DOCUMENTS = 1 << 9;
+ /** {@hide} */ public static final int HAS_AUDIOBOOKS = 1 << 10;
/** {@hide} */ public static final int HAS_ANDROID = 1 << 16;
/** {@hide} */ public static final int HAS_OTHER = 1 << 17;
@@ -738,6 +747,7 @@
else if (DIRECTORY_DOWNLOADS.equals(name)) res |= HAS_DOWNLOADS;
else if (DIRECTORY_DCIM.equals(name)) res |= HAS_DCIM;
else if (DIRECTORY_DOCUMENTS.equals(name)) res |= HAS_DOCUMENTS;
+ else if (DIRECTORY_AUDIOBOOKS.equals(name)) res |= HAS_AUDIOBOOKS;
else if (DIRECTORY_ANDROID.equals(name)) res |= HAS_ANDROID;
else res |= HAS_OTHER;
}
diff --git a/core/java/android/os/IThermalService.aidl b/core/java/android/os/IThermalService.aidl
index 8160338..9280cb9 100644
--- a/core/java/android/os/IThermalService.aidl
+++ b/core/java/android/os/IThermalService.aidl
@@ -67,7 +67,7 @@
/**
* Register a listener for thermal status change.
- * @param listener the IThermalStatusListener to be notified.
+ * @param listener the {@link android.os.IThermalStatusListener} to be notified.
* @return true if registered successfully.
* {@hide}
*/
@@ -75,7 +75,7 @@
/**
* Unregister a previously-registered listener for thermal status.
- * @param listener the IThermalStatusListener to no longer be notified.
+ * @param listener the {@link android.os.IThermalStatusListener} to no longer be notified.
* @return true if unregistered successfully.
* {@hide}
*/
@@ -86,5 +86,5 @@
* @return status defined in {@link android.os.Temperature}.
* {@hide}
*/
- int getCurrentStatus();
+ int getCurrentThermalStatus();
}
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 44b9e311..6de1ff4 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -17,12 +17,6 @@
package android.os;
import static android.system.OsConstants.AF_UNIX;
-import static android.system.OsConstants.O_APPEND;
-import static android.system.OsConstants.O_CREAT;
-import static android.system.OsConstants.O_RDONLY;
-import static android.system.OsConstants.O_RDWR;
-import static android.system.OsConstants.O_TRUNC;
-import static android.system.OsConstants.O_WRONLY;
import static android.system.OsConstants.SEEK_SET;
import static android.system.OsConstants.SOCK_SEQPACKET;
import static android.system.OsConstants.SOCK_STREAM;
@@ -254,8 +248,16 @@
}
/** {@hide} */
- public static ParcelFileDescriptor fromFd(
- FileDescriptor fd, Handler handler, final OnCloseListener listener) throws IOException {
+ public static ParcelFileDescriptor fromPfd(ParcelFileDescriptor pfd, Handler handler,
+ final OnCloseListener listener) throws IOException {
+ final FileDescriptor original = new FileDescriptor();
+ original.setInt$(pfd.detachFd());
+ return fromFd(original, handler, listener);
+ }
+
+ /** {@hide} */
+ public static ParcelFileDescriptor fromFd(FileDescriptor fd, Handler handler,
+ final OnCloseListener listener) throws IOException {
if (handler == null) {
throw new IllegalArgumentException("Handler must not be null");
}
diff --git a/core/java/android/os/RedactingFileDescriptor.java b/core/java/android/os/RedactingFileDescriptor.java
index 60eb5c3..4e5eaac 100644
--- a/core/java/android/os/RedactingFileDescriptor.java
+++ b/core/java/android/os/RedactingFileDescriptor.java
@@ -20,15 +20,18 @@
import android.os.storage.StorageManager;
import android.system.ErrnoException;
import android.system.Os;
-import android.system.OsConstants;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+
import libcore.io.IoUtils;
+import libcore.util.EmptyArray;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InterruptedIOException;
+import java.util.Arrays;
/**
* Variant of {@link FileDescriptor} that allows its creator to specify regions
@@ -40,20 +43,21 @@
private static final String TAG = "RedactingFileDescriptor";
private static final boolean DEBUG = true;
- private final long[] mRedactRanges;
+ private volatile long[] mRedactRanges;
private FileDescriptor mInner = null;
private ParcelFileDescriptor mOuter = null;
- private RedactingFileDescriptor(Context context, File file, long[] redactRanges)
+ private RedactingFileDescriptor(Context context, File file, int mode, long[] redactRanges)
throws IOException {
mRedactRanges = checkRangesArgument(redactRanges);
try {
try {
- mInner = Os.open(file.getAbsolutePath(), OsConstants.O_RDONLY, 0);
+ mInner = Os.open(file.getAbsolutePath(),
+ FileUtils.translateModePfdToPosix(mode), 0);
mOuter = context.getSystemService(StorageManager.class)
- .openProxyFileDescriptor(ParcelFileDescriptor.MODE_READ_ONLY, mCallback);
+ .openProxyFileDescriptor(mode, mCallback);
} catch (ErrnoException e) {
throw e.rethrowAsIOException();
}
@@ -78,16 +82,61 @@
/**
* Open the given {@link File} and returns a {@link ParcelFileDescriptor}
- * that offers a redacted, read-only view of the underlying data.
+ * that offers a redacted view of the underlying data. If a redacted region
+ * is written to, the newly written data can be read back correctly instead
+ * of continuing to be redacted.
*
* @param file The underlying file to open.
+ * @param mode The {@link ParcelFileDescriptor} mode to open with.
* @param redactRanges List of file offsets that should be redacted, stored
* as {@code [start1, end1, start2, end2, ...]}. Start values are
* inclusive and end values are exclusive.
*/
- public static ParcelFileDescriptor open(Context context, File file, long[] redactRanges)
- throws IOException {
- return new RedactingFileDescriptor(context, file, redactRanges).mOuter;
+ public static ParcelFileDescriptor open(Context context, File file, int mode,
+ long[] redactRanges) throws IOException {
+ return new RedactingFileDescriptor(context, file, mode, redactRanges).mOuter;
+ }
+
+ /**
+ * Update the given ranges argument to remove any references to the given
+ * offset and length. This is typically used when a caller has written over
+ * a previously redacted region.
+ */
+ @VisibleForTesting
+ public static long[] removeRange(long[] ranges, long start, long end) {
+ if (start == end) {
+ return ranges;
+ } else if (start > end) {
+ throw new IllegalArgumentException();
+ }
+
+ long[] res = EmptyArray.LONG;
+ for (int i = 0; i < ranges.length; i += 2) {
+ if (start <= ranges[i] && end >= ranges[i + 1]) {
+ // Range entirely covered; remove it
+ } else if (start >= ranges[i] && end <= ranges[i + 1]) {
+ // Range partially covered; punch a hole
+ res = Arrays.copyOf(res, res.length + 4);
+ res[res.length - 4] = ranges[i];
+ res[res.length - 3] = start;
+ res[res.length - 2] = end;
+ res[res.length - 1] = ranges[i + 1];
+ } else {
+ // Range might covered; adjust edges if needed
+ res = Arrays.copyOf(res, res.length + 2);
+ if (end >= ranges[i] && end <= ranges[i + 1]) {
+ res[res.length - 2] = Math.max(ranges[i], end);
+ } else {
+ res[res.length - 2] = ranges[i];
+ }
+ if (start >= ranges[i] && start <= ranges[i + 1]) {
+ res[res.length - 1] = Math.min(ranges[i + 1], start);
+ } else {
+ res[res.length - 1] = ranges[i + 1];
+ }
+ }
+ }
+ return res;
}
private final ProxyFileDescriptorCallback mCallback = new ProxyFileDescriptorCallback() {
@@ -126,7 +175,24 @@
@Override
public int onWrite(long offset, int size, byte[] data) throws ErrnoException {
- throw new ErrnoException(TAG, OsConstants.EBADF);
+ int n = 0;
+ while (n < size) {
+ try {
+ final int res = Os.pwrite(mInner, data, n, size - n, offset + n);
+ if (res == 0) {
+ break;
+ } else {
+ n += res;
+ }
+ } catch (InterruptedIOException e) {
+ n += e.bytesTransferred;
+ }
+ }
+
+ // Clear any relevant redaction ranges before returning, since the
+ // writer should have access to see the data they just overwrote
+ mRedactRanges = removeRange(mRedactRanges, offset, offset + n);
+ return n;
}
@Override
diff --git a/core/java/android/os/Temperature.java b/core/java/android/os/Temperature.java
index bf85fbd..21aba59 100644
--- a/core/java/android/os/Temperature.java
+++ b/core/java/android/os/Temperature.java
@@ -28,7 +28,7 @@
*
* @hide
*/
-public class Temperature implements Parcelable {
+public final class Temperature implements Parcelable {
/** Temperature value */
private float mValue;
/** A temperature type from ThermalHAL */
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index 76607e9..8e37559 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -660,7 +660,22 @@
if (familyBuilder == null) {
return null;
}
- return new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
+
+ final FontFamily family = familyBuilder.build();
+
+ final FontStyle normal = new FontStyle(FontStyle.FONT_WEIGHT_NORMAL,
+ FontStyle.FONT_SLANT_UPRIGHT);
+ Font bestFont = family.getFont(0);
+ int bestScore = normal.getMatchScore(bestFont.getStyle());
+ for (int i = 1; i < family.getSize(); ++i) {
+ final Font candidate = family.getFont(i);
+ final int score = normal.getMatchScore(candidate.getStyle());
+ if (score < bestScore) {
+ bestFont = candidate;
+ bestScore = score;
+ }
+ }
+ return new Typeface.CustomFallbackBuilder(family).setStyle(bestFont.getStyle()).build();
}
/**
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index e0e4fe2..9e26a36 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -121,6 +121,8 @@
public static final String PARAM_INCLUDE_PENDING = "includePending";
/** {@hide} */
public static final String PARAM_PROGRESS = "progress";
+ /** {@hide} */
+ public static final String PARAM_REQUIRE_ORIGINAL = "requireOriginal";
/**
* Activity Action: Launch a music player.
@@ -478,6 +480,24 @@
}
/**
+ * Update the given {@link Uri} to indicate that the caller requires the
+ * original file contents when calling
+ * {@link ContentResolver#openFileDescriptor(Uri, String)}.
+ * <p>
+ * This can be useful when the caller wants to ensure they're backing up the
+ * exact bytes of the underlying media, without any Exif redaction being
+ * performed.
+ * <p>
+ * If the original file contents cannot be provided, a
+ * {@link UnsupportedOperationException} will be thrown when the returned
+ * {@link Uri} is used, such as when the caller doesn't hold
+ * {@link android.Manifest.permission#ACCESS_MEDIA_LOCATION}.
+ */
+ public static @NonNull Uri setRequireOriginal(@NonNull Uri uri) {
+ return uri.buildUpon().appendQueryParameter(PARAM_REQUIRE_ORIGINAL, "1").build();
+ }
+
+ /**
* Create a new pending media item using the given parameters. Pending items
* are expected to have a short lifetime, and owners should either
* {@link PendingSession#publish()} or {@link PendingSession#abandon()} a
@@ -1673,6 +1693,12 @@
public static final String IS_NOTIFICATION = "is_notification";
/**
+ * Non-zero if the audio file is an audiobook
+ * <P>Type: INTEGER (boolean)</P>
+ */
+ public static final String IS_AUDIOBOOK = "is_audiobook";
+
+ /**
* The genre of the audio file, if any
* <P>Type: TEXT</P>
* Does not exist in the database - only used by the media scanner for inserts.
diff --git a/core/java/android/provider/TEST_MAPPING b/core/java/android/provider/TEST_MAPPING
deleted file mode 100644
index 8e67ce7..0000000
--- a/core/java/android/provider/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "presubmit": [
- {
- "name": "FrameworksCoreTests",
- "options": [
- {
- "include-filter": "android.provider.SettingsBackupTest"
- }
- ]
- }
- ]
-}
diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl
new file mode 100644
index 0000000..23d607d
--- /dev/null
+++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.intelligence;
+
+parcelable ContentCaptureEventsRequest;
diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.java b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java
new file mode 100644
index 0000000..bc5b92b
--- /dev/null
+++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.service.intelligence;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.intelligence.ContentCaptureEvent;
+
+import java.util.List;
+
+/**
+ * Batch of content capture events.
+ *
+ * @hide
+ */
+@SystemApi
+public final class ContentCaptureEventsRequest implements Parcelable {
+
+ private final List<ContentCaptureEvent> mEvents;
+
+ /** @hide */
+ public ContentCaptureEventsRequest(@NonNull List<ContentCaptureEvent> events) {
+ mEvents = events;
+ }
+
+ /**
+ * Gets the events.
+ */
+ @NonNull
+ public List<ContentCaptureEvent> getEvents() {
+ return mEvents;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeTypedList(mEvents, flags);
+ }
+
+ public static final Parcelable.Creator<ContentCaptureEventsRequest> CREATOR =
+ new Parcelable.Creator<ContentCaptureEventsRequest>() {
+
+ @Override
+ public ContentCaptureEventsRequest createFromParcel(Parcel parcel) {
+ return new ContentCaptureEventsRequest(parcel
+ .createTypedArrayList(ContentCaptureEvent.CREATOR));
+ }
+
+ @Override
+ public ContentCaptureEventsRequest[] newArray(int size) {
+ return new ContentCaptureEventsRequest[size];
+ }
+ };
+}
diff --git a/core/java/android/service/intelligence/FillController.java b/core/java/android/service/intelligence/FillController.java
index c5e1242..4a9c85d 100644
--- a/core/java/android/service/intelligence/FillController.java
+++ b/core/java/android/service/intelligence/FillController.java
@@ -15,12 +15,12 @@
*/
package android.service.intelligence;
-import static android.service.intelligence.IntelligenceService.DEBUG;
+import static android.service.intelligence.SmartSuggestionsService.DEBUG;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.RemoteException;
-import android.service.intelligence.IntelligenceService.AutofillProxy;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
import android.util.Log;
import android.util.Pair;
import android.view.autofill.AutofillId;
diff --git a/core/java/android/service/intelligence/FillRequest.java b/core/java/android/service/intelligence/FillRequest.java
index 95e9224..f68db9d 100644
--- a/core/java/android/service/intelligence/FillRequest.java
+++ b/core/java/android/service/intelligence/FillRequest.java
@@ -18,7 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.service.intelligence.IntelligenceService.AutofillProxy;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
import android.view.autofill.AutofillId;
/**
diff --git a/core/java/android/service/intelligence/FillWindow.java b/core/java/android/service/intelligence/FillWindow.java
index 4ea07bf..309f6a1 100644
--- a/core/java/android/service/intelligence/FillWindow.java
+++ b/core/java/android/service/intelligence/FillWindow.java
@@ -15,7 +15,7 @@
*/
package android.service.intelligence;
-import static android.service.intelligence.IntelligenceService.DEBUG;
+import static android.service.intelligence.SmartSuggestionsService.DEBUG;
import android.annotation.LongDef;
import android.annotation.NonNull;
diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl
index e2260d7..d6b3107 100644
--- a/core/java/android/service/intelligence/IIntelligenceService.aidl
+++ b/core/java/android/service/intelligence/IIntelligenceService.aidl
@@ -17,6 +17,7 @@
package android.service.intelligence;
import android.os.IBinder;
+import android.service.intelligence.ContentCaptureEventsRequest;
import android.service.intelligence.InteractionSessionId;
import android.service.intelligence.InteractionContext;
import android.service.intelligence.SnapshotData;
@@ -26,19 +27,19 @@
import java.util.List;
-
/**
* Interface from the system to an intelligence service.
*
* @hide
*/
+ // TODO(b/111276913): rename / update javadoc (once the final name is defined)
oneway interface IIntelligenceService {
// Called when session is created (context not null) or destroyed (context null)
void onSessionLifecycle(in InteractionContext context, in InteractionSessionId sessionId);
- void onContentCaptureEvents(in InteractionSessionId sessionId,
- in List<ContentCaptureEvent> events);
+ void onContentCaptureEventsRequest(in InteractionSessionId sessionId,
+ in ContentCaptureEventsRequest request);
void onActivitySnapshot(in InteractionSessionId sessionId,
in SnapshotData snapshotData);
diff --git a/core/java/android/service/intelligence/InteractionContext.java b/core/java/android/service/intelligence/InteractionContext.java
index 0cc377b..7f4283d 100644
--- a/core/java/android/service/intelligence/InteractionContext.java
+++ b/core/java/android/service/intelligence/InteractionContext.java
@@ -37,7 +37,7 @@
/**
* Flag used to indicate that the app explicitly disabled content capture for the activity
* (using
- * {@link android.view.intelligence.IntelligenceManager#setContentCaptureEnabled()}),
+ * {@link android.view.intelligence.ContentCaptureManager#setContentCaptureEnabled()}),
* in which case the service will just receive activity-level events.
*/
public static final int FLAG_DISABLED_BY_APP = 0x1;
diff --git a/core/java/android/service/intelligence/PresentationParams.java b/core/java/android/service/intelligence/PresentationParams.java
index c59069b..9530309 100644
--- a/core/java/android/service/intelligence/PresentationParams.java
+++ b/core/java/android/service/intelligence/PresentationParams.java
@@ -20,7 +20,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.graphics.Rect;
-import android.service.intelligence.IntelligenceService.AutofillProxy;
+import android.service.intelligence.SmartSuggestionsService.AutofillProxy;
import android.util.DebugUtils;
import android.view.View;
diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/SmartSuggestionsService.java
similarity index 71%
rename from core/java/android/service/intelligence/IntelligenceService.java
rename to core/java/android/service/intelligence/SmartSuggestionsService.java
index 040e25e..0e29e70 100644
--- a/core/java/android/service/intelligence/IntelligenceService.java
+++ b/core/java/android/service/intelligence/SmartSuggestionsService.java
@@ -19,8 +19,10 @@
import android.annotation.CallSuper;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
+import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Rect;
import android.os.CancellationSignal;
@@ -43,31 +45,31 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
/**
- * A service used to capture the content of the screen.
- *
- * <p>The data collected by this service can be analyzed and combined with other sources to provide
- * contextual data in other areas of the system such as Autofill.
+ * A service used to capture the content of the screen to provide contextual data in other areas of
+ * the system such as Autofill.
*
* @hide
*/
@SystemApi
-public abstract class IntelligenceService extends Service {
+public abstract class SmartSuggestionsService extends Service {
- private static final String TAG = "IntelligenceService";
+ private static final String TAG = "SmartSuggestionsService";
// TODO(b/111330312): STOPSHIP use dynamic value, or change to false
static final boolean DEBUG = true;
+ static final boolean VERBOSE = false;
/**
* The {@link Intent} that must be declared as handled by the service.
* To be supported, the service must also require the
- * {@link android.Manifest.permission#BIND_INTELLIGENCE_SERVICE} permission so
+ * {@link android.Manifest.permission#BIND_SMART_SUGGESTIONS_SERVICE} permission so
* that other applications can not abuse it.
*/
public static final String SERVICE_INTERFACE =
- "android.service.intelligence.IntelligenceService";
+ "android.service.intelligence.SmartSuggestionsService";
private Handler mHandler;
@@ -80,21 +82,21 @@
throws RemoteException {
if (context != null) {
mHandler.sendMessage(
- obtainMessage(IntelligenceService::onCreateInteractionSession,
- IntelligenceService.this, context, sessionId));
+ obtainMessage(SmartSuggestionsService::onCreateInteractionSession,
+ SmartSuggestionsService.this, context, sessionId));
} else {
mHandler.sendMessage(
- obtainMessage(IntelligenceService::onDestroyInteractionSession,
- IntelligenceService.this, sessionId));
+ obtainMessage(SmartSuggestionsService::onDestroyInteractionSession,
+ SmartSuggestionsService.this, sessionId));
}
}
@Override
- public void onContentCaptureEvents(InteractionSessionId sessionId,
- List<ContentCaptureEvent> events) {
+ public void onContentCaptureEventsRequest(InteractionSessionId sessionId,
+ ContentCaptureEventsRequest request) {
mHandler.sendMessage(
- obtainMessage(IntelligenceService::onContentCaptureEvent,
- IntelligenceService.this, sessionId, events));
+ obtainMessage(SmartSuggestionsService::onContentCaptureEventsRequest,
+ SmartSuggestionsService.this, sessionId, request));
}
@@ -102,22 +104,22 @@
public void onActivitySnapshot(InteractionSessionId sessionId,
SnapshotData snapshotData) {
mHandler.sendMessage(
- obtainMessage(IntelligenceService::onActivitySnapshot,
- IntelligenceService.this, sessionId, snapshotData));
+ obtainMessage(SmartSuggestionsService::onActivitySnapshot,
+ SmartSuggestionsService.this, sessionId, snapshotData));
}
@Override
public void onAutofillRequest(InteractionSessionId sessionId, IBinder client,
int autofilSessionId, AutofillId focusedId) {
- mHandler.sendMessage(obtainMessage(IntelligenceService::handleOnAutofillRequest,
- IntelligenceService.this, sessionId, client, autofilSessionId, focusedId));
+ mHandler.sendMessage(obtainMessage(SmartSuggestionsService::handleOnAutofillRequest,
+ SmartSuggestionsService.this, sessionId, client, autofilSessionId, focusedId));
}
@Override
public void onDestroyAutofillWindowsRequest(InteractionSessionId sessionId) {
mHandler.sendMessage(
- obtainMessage(IntelligenceService::handleOnDestroyAutofillWindowsRequest,
- IntelligenceService.this, sessionId));
+ obtainMessage(SmartSuggestionsService::handleOnDestroyAutofillWindowsRequest,
+ SmartSuggestionsService.this, sessionId));
}
};
@@ -139,25 +141,92 @@
}
/**
+ * Explicitly limits content capture to the given packages and activities.
+ *
+ * <p>When the whitelist is set, it overrides the values passed to
+ * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}
+ * and {@link #setPackageContentCaptureEnabled(String, boolean)}.
+ *
+ * <p>To reset the whitelist, call it passing {@code null} to both arguments.
+ *
+ * <p>Useful when the service wants to restrict content capture to a category of apps, like
+ * chat apps. For example, if the service wants to support view captures on all activities of
+ * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2},
+ * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"),
+ * Arrays.asList(new ComponentName("ChatApp2", "act1"),
+ * new ComponentName("ChatApp2", "act2")));}
+ */
+ public final void setContentCaptureWhitelist(@Nullable List<String> packages,
+ @Nullable List<ComponentName> activities) {
+ //TODO(b/111276913): implement
+ }
+
+ /**
+ * Defines whether content capture should be enabled for activities with such
+ * {@link android.content.ComponentName}.
+ *
+ * <p>Useful to blacklist a particular activity.
+ */
+ public final void setActivityContentCaptureEnabled(@NonNull ComponentName activity,
+ boolean enabled) {
+ //TODO(b/111276913): implement
+ }
+
+ /**
+ * Defines whether content capture should be enabled for activities of the app with such
+ * {@code packageName}.
+ *
+ * <p>Useful to blacklist any activity from a particular app.
+ */
+ public final void setPackageContentCaptureEnabled(@NonNull String packageName,
+ boolean enabled) {
+ //TODO(b/111276913): implement
+ }
+
+ /**
+ * Gets the activities where content capture was disabled by
+ * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}.
+ */
+ @NonNull
+ public final Set<ComponentName> getContentCaptureDisabledActivities() {
+ //TODO(b/111276913): implement
+ return null;
+ }
+
+ /**
+ * Gets the apps where content capture was disabled by
+ * {@link #setPackageContentCaptureEnabled(String, boolean)}.
+ */
+ @NonNull
+ public final Set<String> getContentCaptureDisabledPackages() {
+ //TODO(b/111276913): implement
+ return null;
+ }
+
+ /**
* Creates a new interaction session.
*
* @param context interaction context
* @param sessionId the session's Id
*/
public void onCreateInteractionSession(@NonNull InteractionContext context,
- @NonNull InteractionSessionId sessionId) {}
+ @NonNull InteractionSessionId sessionId) {
+ if (VERBOSE) {
+ Log.v(TAG, "onCreateInteractionSession(id=" + sessionId + ", ctx=" + context + ")");
+ }
+ }
/**
* Notifies the service of {@link ContentCaptureEvent events} associated with a content capture
* session.
*
* @param sessionId the session's Id
- * @param events the events
+ * @param request the events
*/
// TODO(b/111276913): rename to onContentCaptureEvents or something like that; also, pass a
// Request object so it can be extended
- public abstract void onContentCaptureEvent(@NonNull InteractionSessionId sessionId,
- @NonNull List<ContentCaptureEvent> events);
+ public abstract void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId,
+ @NonNull ContentCaptureEventsRequest request);
private void handleOnAutofillRequest(@NonNull InteractionSessionId sessionId,
@NonNull IBinder client, int autofillSessionId, @NonNull AutofillId focusedId) {
@@ -242,8 +311,7 @@
}
/**
- * Notifies the service of {@link IntelligenceSnapshotData snapshot data} associated with a
- * session.
+ * Notifies the service of {@link SnapshotData snapshot data} associated with a session.
*
* @param sessionId the session's Id
* @param snapshotData the data
@@ -256,7 +324,11 @@
*
* @param sessionId the id of the session to destroy
*/
- public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {}
+ public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {
+ if (VERBOSE) {
+ Log.v(TAG, "onDestroyInteractionSession(id=" + sessionId + ")");
+ }
+ }
/** @hide */
static final class AutofillProxy {
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 8371c31b..0e2ae83 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -806,7 +806,7 @@
if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_CALLS,
isPriorityCategoryEnabled(Policy.PRIORITY_CATEGORY_CALLS, defaultPolicy))) {
priorityCategories |= Policy.PRIORITY_CATEGORY_CALLS;
- messageSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders());
+ callSenders = getNotificationPolicySenders(zenPolicy.getPriorityCallSenders());
}
if (zenPolicy.isCategoryAllowed(ZenPolicy.PRIORITY_CATEGORY_REPEAT_CALLERS,
diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java
index 43ab8dc..194147c 100644
--- a/core/java/android/service/notification/ZenPolicy.java
+++ b/core/java/android/service/notification/ZenPolicy.java
@@ -859,6 +859,27 @@
/**
* @hide
*/
+ public boolean areValuesSet() {
+ return getPriorityCategoryReminders() != STATE_UNSET
+ || getPriorityCategoryEvents() != STATE_UNSET
+ || getPriorityCategoryMessages() != STATE_UNSET
+ || getPriorityCategoryCalls() != STATE_UNSET
+ || getPriorityCategoryRepeatCallers() != STATE_UNSET
+ || getPriorityCategoryAlarms() != STATE_UNSET
+ || getPriorityCategoryMedia() != STATE_UNSET
+ || getPriorityCategorySystem() != STATE_UNSET
+ || getVisualEffectFullScreenIntent() != STATE_UNSET
+ || getVisualEffectLights() != STATE_UNSET
+ || getVisualEffectPeek() != STATE_UNSET
+ || getVisualEffectStatusBar() != STATE_UNSET
+ || getVisualEffectBadge() != STATE_UNSET
+ || getVisualEffectAmbient() != STATE_UNSET
+ || getVisualEffectNotificationList() != STATE_UNSET;
+ }
+
+ /**
+ * @hide
+ */
public void writeToProto(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java
index be47320..433483f7 100644
--- a/core/java/android/text/style/SuggestionSpan.java
+++ b/core/java/android/text/style/SuggestionSpan.java
@@ -369,10 +369,7 @@
/**
* @return The color of the underline for that span, or 0 if there is no underline
- *
- * @hide
*/
- @UnsupportedAppUsage
public int getUnderlineColor() {
// The order here should match what is used in updateDrawState
final boolean misspelled = (mFlags & FLAG_MISSPELLED) != 0;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 5f348c4..dee6d90 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -45,7 +45,6 @@
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
DEFAULT_FLAGS.put("settings_dynamic_homepage", "true");
DEFAULT_FLAGS.put("settings_mobile_network_v2", "true");
- DEFAULT_FLAGS.put("settings_data_usage_v2", "true");
DEFAULT_FLAGS.put("settings_seamless_transfer", "false");
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
DEFAULT_FLAGS.put("settings_network_and_internet_v2", "false");
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index af41b69..5e6d3d1 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -25,6 +25,7 @@
import android.view.MotionEvent;
import android.view.DisplayCutout;
import android.view.InsetsState;
+import android.view.InsetsSourceControl;
import com.android.internal.os.IResultReceiver;
import android.util.MergedConfiguration;
@@ -60,6 +61,11 @@
*/
void insetsChanged(in InsetsState insetsState);
+ /**
+ * Called when this window retrieved control over a specified set of inset sources.
+ */
+ void insetsControlChanged(in InsetsState insetsState, in InsetsSourceControl[] activeControls);
+
void moved(int newX, int newY);
void dispatchAppVisibility(boolean visible);
void dispatchGetNewSurface();
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 7841d04..ba5340c 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -16,17 +16,30 @@
package android.view;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Rect;
+import android.util.ArraySet;
+import android.util.SparseArray;
+import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets.Type.InsetType;
+import android.view.InsetsState.InternalInsetType;
+
+import com.android.internal.annotations.VisibleForTesting;
import java.io.PrintWriter;
/**
* Implements {@link WindowInsetsController} on the client.
+ * @hide
*/
-class InsetsController {
+public class InsetsController implements WindowInsetsController {
private final InsetsState mState = new InsetsState();
private final Rect mFrame = new Rect();
+ private final SparseArray<InsetsSourceConsumer> mSourceConsumers = new SparseArray<>();
+
+ private final SparseArray<InsetsSourceControl> mTmpControlArray = new SparseArray<>();
void onFrameChanged(Rect frame) {
mFrame.set(frame);
@@ -48,6 +61,61 @@
return mState.calculateInsets(mFrame, isScreenRound, alwaysConsumeNavBar, cutout);
}
+ /**
+ * Called when the server has dispatched us a new set of inset controls.
+ */
+ public void onControlsChanged(InsetsSourceControl[] activeControls) {
+ if (activeControls != null) {
+ for (InsetsSourceControl activeControl : activeControls) {
+ mTmpControlArray.put(activeControl.getType(), activeControl);
+ }
+ }
+
+ // Ensure to update all existing source consumers
+ for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
+ final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
+ final InsetsSourceControl control = mTmpControlArray.get(consumer.getType());
+
+ // control may be null, but we still need to update the control to null if it got
+ // revoked.
+ consumer.setControl(control);
+ }
+
+ // Ensure to create source consumers if not available yet.
+ for (int i = mTmpControlArray.size() - 1; i >= 0; i--) {
+ final InsetsSourceControl control = mTmpControlArray.valueAt(i);
+ getSourceConsumer(control.getType()).setControl(control);
+ }
+ mTmpControlArray.clear();
+ }
+
+ @Override
+ public void show(@InsetType int types) {
+ final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
+ for (int i = internalTypes.size() - 1; i >= 0; i--) {
+ getSourceConsumer(internalTypes.valueAt(i)).show();
+ }
+ }
+
+ @Override
+ public void hide(@InsetType int types) {
+ final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
+ for (int i = internalTypes.size() - 1; i >= 0; i--) {
+ getSourceConsumer(internalTypes.valueAt(i)).hide();
+ }
+ }
+
+ @VisibleForTesting
+ public @NonNull InsetsSourceConsumer getSourceConsumer(@InternalInsetType int type) {
+ InsetsSourceConsumer controller = mSourceConsumers.get(type);
+ if (controller != null) {
+ return controller;
+ }
+ controller = new InsetsSourceConsumer(type, mState, Transaction::new);
+ mSourceConsumers.put(type, controller);
+ return controller;
+ }
+
void dump(String prefix, PrintWriter pw) {
pw.println(prefix); pw.println("InsetsController:");
mState.dump(prefix + " ", pw);
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
new file mode 100644
index 0000000..e74aa8d
--- /dev/null
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.view;
+
+import android.annotation.Nullable;
+import android.view.SurfaceControl.Transaction;
+import android.view.InsetsState.InternalInsetType;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.function.Supplier;
+
+/**
+ * Controls the visibility and animations of a single window insets source.
+ * @hide
+ */
+public class InsetsSourceConsumer {
+
+ private final Supplier<Transaction> mTransactionSupplier;
+ private final @InternalInsetType int mType;
+ private final InsetsState mState;
+ private @Nullable InsetsSourceControl mControl;
+ private boolean mHidden;
+
+ public InsetsSourceConsumer(@InternalInsetType int type, InsetsState state,
+ Supplier<Transaction> transactionSupplier) {
+ mType = type;
+ mState = state;
+ mTransactionSupplier = transactionSupplier;
+ }
+
+ public void setControl(@Nullable InsetsSourceControl control) {
+ if (mControl == control) {
+ return;
+ }
+ mControl = control;
+ applyHiddenToControl();
+ }
+
+ @VisibleForTesting
+ public InsetsSourceControl getControl() {
+ return mControl;
+ }
+
+ int getType() {
+ return mType;
+ }
+
+ @VisibleForTesting
+ public void show() {
+ setHidden(false);
+ }
+
+ @VisibleForTesting
+ public void hide() {
+ setHidden(true);
+ }
+
+ private void setHidden(boolean hidden) {
+ if (mHidden == hidden) {
+ return;
+ }
+ mHidden = hidden;
+ applyHiddenToControl();
+ }
+
+ private void applyHiddenToControl() {
+ if (mControl == null) {
+ return;
+ }
+
+ // TODO: Animation
+ final Transaction t = mTransactionSupplier.get();
+ if (mHidden) {
+ t.hide(mControl.getLeash());
+ } else {
+ t.show(mControl.getLeash());
+ }
+ t.apply();
+ }
+}
diff --git a/core/java/android/view/InsetsSourceControl.aidl b/core/java/android/view/InsetsSourceControl.aidl
new file mode 100644
index 0000000..755bf45
--- /dev/null
+++ b/core/java/android/view/InsetsSourceControl.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+parcelable InsetsSourceControl;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
new file mode 100644
index 0000000..9383e6c
--- /dev/null
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.graphics.Point;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.InsetsState.InternalInsetType;
+
+/**
+ * Represents a parcelable object to allow controlling a single {@link InsetsSource}.
+ * @hide
+ */
+public class InsetsSourceControl implements Parcelable {
+
+ private final @InternalInsetType int mType;
+ private final SurfaceControl mLeash;
+
+ public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash) {
+ mType = type;
+ mLeash = leash;
+ }
+
+ public int getType() {
+ return mType;
+ }
+
+ public SurfaceControl getLeash() {
+ return mLeash;
+ }
+
+ public InsetsSourceControl(Parcel in) {
+ mType = in.readInt();
+ mLeash = in.readParcelable(null /* loader */);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mType);
+ dest.writeParcelable(mLeash, 0 /* flags*/);
+ }
+
+ public static final Creator<InsetsSourceControl> CREATOR
+ = new Creator<InsetsSourceControl>() {
+ public InsetsSourceControl createFromParcel(Parcel in) {
+ return new InsetsSourceControl(in);
+ }
+
+ public InsetsSourceControl[] newArray(int size) {
+ return new InsetsSourceControl[size];
+ }
+ };
+}
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index 9895adc..689b14f 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -22,6 +22,9 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.view.WindowInsets.Type;
+import android.view.WindowInsets.Type.InsetType;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
@@ -148,6 +151,22 @@
}
}
+ public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) {
+ final ArraySet<Integer> result = new ArraySet<>();
+ if ((insetTypes & Type.TOP_BAR) != 0) {
+ result.add(TYPE_TOP_BAR);
+ }
+ if ((insetTypes & Type.SIDE_BARS) != 0) {
+ result.add(TYPE_SIDE_BAR_1);
+ result.add(TYPE_SIDE_BAR_2);
+ result.add(TYPE_SIDE_BAR_3);
+ }
+ if ((insetTypes & Type.IME) != 0) {
+ result.add(TYPE_IME);
+ }
+ return result;
+ }
+
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "InsetsState");
for (int i = mSources.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index c5d0374..4b9cbff 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -112,7 +112,7 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
import android.widget.Checkable;
import android.widget.FrameLayout;
import android.widget.ScrollBarDrawable;
@@ -8138,7 +8138,7 @@
* is visible.
*
* <p>The populated structure is then passed to the service through
- * {@link IntelligenceManager#notifyViewAppeared(ViewStructure)}.
+ * {@link ContentCaptureManager#notifyViewAppeared(ViewStructure)}.
*
* <p><b>Note: </b>the following methods of the {@code structure} will be ignored:
* <ul>
@@ -8915,7 +8915,7 @@
}
/**
- * Helper used to notify the {@link IntelligenceManager} when the view is removed or
+ * Helper used to notify the {@link ContentCaptureManager} when the view is removed or
* added, based on whether it's laid out and visible, and without knowing if the parent removed
* it from the view hierarchy.
*
@@ -8931,11 +8931,15 @@
* </ol>
*/
private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) {
+ // First check if context has client, so it saves a service lookup when it doesn't
+ if (!mContext.isContentCaptureSupported()) return;
- final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class);
- if (im == null || !im.isContentCaptureEnabled()) return;
+ // Then check if it's enabled in the context...
+ final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
+ if (cm == null || !cm.isContentCaptureEnabled()) return;
- // NOTE: isImportantForContentCapture() is more expensive than im.isContentCaptureEnabled()
+ // ... and finally at the view level
+ // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled()
if (!isImportantForContentCapture()) return;
if (appeared) {
@@ -8950,9 +8954,9 @@
return;
}
// All good: notify the manager...
- final ViewStructure structure = im.newViewStructure(this);
+ final ViewStructure structure = cm.newViewStructure(this);
onProvideContentCaptureStructure(structure, /* flags= */ 0);
- im.notifyViewAppeared(structure);
+ cm.notifyViewAppeared(structure);
// ...and set the flags
mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
@@ -8969,7 +8973,7 @@
return;
}
// All good: notify the manager...
- im.notifyViewDisappeared(getAutofillId());
+ cm.notifyViewDisappeared(getAutofillId());
// ...and set the flags
mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
@@ -10337,6 +10341,20 @@
}
/**
+ * Retrieves the single {@link WindowInsetsController} of the window this view is attached to.
+ *
+ * @return The {@link WindowInsetsController} or {@code null} if the view isn't attached to a
+ * a window.
+ * @hide pending unhide
+ */
+ public @Nullable WindowInsetsController getWindowInsetsController() {
+ if (mAttachInfo != null) {
+ return mAttachInfo.mViewRootImpl.getInsetsController();
+ }
+ return null;
+ }
+
+ /**
* @hide Compute the insets that should be consumed by this view and the ones
* that should propagate to those under it.
*
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 937e238..cb47886 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -170,7 +170,12 @@
* fully migrated over.
*/
private static final String USE_NEW_INSETS_PROPERTY = "persist.wm.new_insets";
- private static final boolean USE_NEW_INSETS =
+
+ /**
+ * @see #USE_NEW_INSETS_PROPERTY
+ * @hide
+ */
+ public static final boolean USE_NEW_INSETS =
SystemProperties.getBoolean(USE_NEW_INSETS_PROPERTY, false);
/**
@@ -1847,6 +1852,10 @@
host.dispatchApplyWindowInsets(insets);
}
+ InsetsController getInsetsController() {
+ return mInsetsController;
+ }
+
private static boolean shouldUseDisplaySize(final WindowManager.LayoutParams lp) {
return lp.type == TYPE_STATUS_BAR_PANEL
|| lp.type == TYPE_INPUT_METHOD
@@ -1935,7 +1944,6 @@
// PixelFormat.hasAlpha(lp.format) || lp.format == PixelFormat.RGBX_8888
// However, windows are now always 32 bits by default, so choose 32 bits
mAttachInfo.mUse32BitDrawingCache = true;
- mAttachInfo.mHasWindowFocus = false;
mAttachInfo.mWindowVisibility = viewVisibility;
mAttachInfo.mRecomputeGlobalAttributes = false;
mLastConfigurationFromResources.setTo(config);
@@ -4208,6 +4216,7 @@
private final static int MSG_POINTER_CAPTURE_CHANGED = 28;
private final static int MSG_DRAW_FINISHED = 29;
private final static int MSG_INSETS_CHANGED = 30;
+ private final static int MSG_INSETS_CONTROL_CHANGED = 31;
final class ViewRootHandler extends Handler {
@Override
@@ -4371,11 +4380,22 @@
case MSG_INSETS_CHANGED:
mPendingInsets = (InsetsState) msg.obj;
- // TODO: Full traversal not needed here
+ // TODO: Full traversal not needed here.
if (USE_NEW_INSETS) {
requestLayout();
}
break;
+ case MSG_INSETS_CONTROL_CHANGED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ mPendingInsets = (InsetsState) args.arg1;
+ mInsetsController.onControlsChanged((InsetsSourceControl[]) args.arg2);
+
+ // TODO: Full traversal not necessarily needed here.
+ if (USE_NEW_INSETS) {
+ requestLayout();
+ }
+ break;
+ }
case MSG_WINDOW_MOVED:
if (mAdded) {
final int w = mWinFrame.width();
@@ -7116,6 +7136,14 @@
mHandler.obtainMessage(MSG_INSETS_CHANGED, insetsState).sendToTarget();
}
+ private void dispatchInsetsControlChanged(InsetsState insetsState,
+ InsetsSourceControl[] activeControls) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = insetsState;
+ args.arg2 = activeControls;
+ mHandler.obtainMessage(MSG_INSETS_CONTROL_CHANGED, args).sendToTarget();
+ }
+
public void dispatchMoved(int newX, int newY) {
if (DEBUG_LAYOUT) Log.v(mTag, "Window moved " + this + ": newX=" + newX + " newY=" + newY);
if (mTranslator != null) {
@@ -8187,6 +8215,15 @@
}
@Override
+ public void insetsControlChanged(InsetsState insetsState,
+ InsetsSourceControl[] activeControls) {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
+ if (viewAncestor != null) {
+ viewAncestor.dispatchInsetsControlChanged(insetsState, activeControls);
+ }
+ }
+
+ @Override
public void moved(int newX, int newY) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index c1e94d8..58ab817 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -2410,4 +2410,11 @@
public boolean isCloseOnSwipeEnabled() {
return mCloseOnSwipeEnabled;
}
+
+ /**
+ * @return The {@link WindowInsetsController} associated with this window
+ * @see View#getWindowInsetsController()
+ * @hide pending unhide
+ */
+ public abstract @NonNull WindowInsetsController getInsetsController();
}
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index a8debbd..572d331 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -18,13 +18,17 @@
package android.view;
import android.annotation.NonNull;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.graphics.Insets;
import android.graphics.Rect;
+import android.view.inputmethod.InputMethod;
import com.android.internal.util.Preconditions;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -807,4 +811,69 @@
mIsRound, mAlwaysConsumeNavBar, mDisplayCutout);
}
}
+
+ /**
+ * Class that defines different types of sources causing window insets.
+ * @hide pending unhide
+ */
+ public static final class Type {
+
+ static final int TOP_BAR = 0x1;
+ static final int IME = 0x2;
+ static final int SIDE_BARS = 0x4;
+ static final int WINDOW_DECOR = 0x8;
+
+ private Type() {
+ }
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = true, value = { TOP_BAR, IME, SIDE_BARS, WINDOW_DECOR })
+ public @interface InsetType {
+ }
+
+ /**
+ * @return An inset type representing the top bar of a window, which can be the status
+ * bar on handheld-like devices as well as a caption bar.
+ */
+ public static @InsetType int topBar() {
+ return TOP_BAR;
+ }
+
+ /**
+ * @return An inset type representing the window of an {@link InputMethod}.
+ */
+ public static @InsetType int ime() {
+ return IME;
+ }
+
+ /**
+ * @return An inset type representing any system bars that are not {@link #topBar()}.
+ */
+ public static @InsetType int sideBars() {
+ return SIDE_BARS;
+ }
+
+ /**
+ * @return An inset type representing decor that is being app-controlled.
+ */
+ public static @InsetType int windowDecor() {
+ return WINDOW_DECOR;
+ }
+
+ /**
+ * @return All system bars. Includes {@link #topBar()} as well as {@link #sideBars()}, but
+ * not {@link #ime()}.
+ */
+ public static @InsetType int systemBars() {
+ return TOP_BAR | SIDE_BARS;
+ }
+
+ /**
+ * @return All inset types combined.
+ */
+ public static @InsetType int all() {
+ return 0xFFFFFFFF;
+ }
+ }
}
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
new file mode 100644
index 0000000..7be5f2e
--- /dev/null
+++ b/core/java/android/view/WindowInsetsController.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.view.WindowInsets.Type.InsetType;
+
+/**
+ * Interface to control windows that generate insets.
+ *
+ * TODO Needs more information and examples once the API is more baked.
+ * @hide pending unhide
+ */
+public interface WindowInsetsController {
+
+ /**
+ * Makes a set of windows that cause insets appear on screen.
+ * <p>
+ * Note that if the window currently doesn't have control over a certain type, it will apply the
+ * change as soon as the window gains control. The app can listen to the event by observing
+ * {@link View#onApplyWindowInsets} and checking visibility with "TODO at method" in
+ * {@link WindowInsets}.
+ *
+ * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+ * would like to make appear on screen.
+ */
+ void show(@InsetType int types);
+
+ /**
+ * Makes a set of windows causing insets disappear.
+ * <p>
+ * Note that if the window currently doesn't have control over a certain type, it will apply the
+ * change as soon as the window gains control. The app can listen to the event by observing
+ * {@link View#onApplyWindowInsets} and checking visibility with "TODO at method" in
+ * {@link WindowInsets}.
+ *
+ * @param types A bitmask of {@link WindowInsets.Type.InsetType} specifying what windows the app
+ * would like to make disappear.
+ */
+ void hide(@InsetType int types);
+}
diff --git a/core/java/android/view/inspector/ChildTraverser.java b/core/java/android/view/inspector/ChildTraverser.java
deleted file mode 100644
index b775de5..0000000
--- a/core/java/android/view/inspector/ChildTraverser.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inspector;
-
-import android.annotation.NonNull;
-
-/**
- * Interface for visiting all the child nodes of an inspectable object.
- *
- * Inspectable objects may return a collection of children as an array, an {@link Iterable} or an
- * {@link java.util.Iterator}. This provides a unified API for traversing across all the children
- * of an inspectable node.
- *
- * This interface is consumed by {@link InspectionHelper#traverseChildren(Object, ChildTraverser)}
- * and may be implemented as a lambda.
- *
- * @see InspectionHelper#traverseChildren(Object, ChildTraverser)
- * @hide
- */
-@FunctionalInterface
-public interface ChildTraverser {
- /**
- * Visit one child object of a parent inspectable object.
- *
- * The iteration interface will filter null values out before passing them to this method, but
- * some child objects may not be inspectable. It is up to the implementor to determine their
- * inspectablity and what to do with them.
- *
- * @param child A child object, guaranteed not to be null.
- */
- void traverseChild(@NonNull Object child);
-}
diff --git a/core/java/android/view/inspector/InspectableChildren.java b/core/java/android/view/inspector/InspectableChildren.java
deleted file mode 100644
index de8fa29..0000000
--- a/core/java/android/view/inspector/InspectableChildren.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inspector;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Marks a getter for an inspectable node's inspectable children.
- *
- * This annotation can be applied to any getter that returns a collection of objects, either an
- * array, an {@link Iterable} or a {@link java.util.Iterator}. The getter may return null, which
- * will be treated as an empty collection. Additionally, the inspector will discard any null
- * entries in the collection.
- *
- * By default, this annotation is inherited. At runtime, the inspector introspects on the class
- * hierachy and uses the annotated getter from the bottommost class, if different from any
- * annoated getters of the parent class. If a class inherits from a parent class with an annotated
- * getter, but does not include this annotation, the child class will be traversed using the
- * getter annotated on the parent. This holds true even if the child class overrides the getter.
- *
- * @see InspectionHelper#traverseChildren(Object, ChildTraverser)
- * @see InspectionHelper#hasChildTraversal()
- * @hide
- */
-@Target({METHOD})
-@Retention(SOURCE)
-public @interface InspectableChildren {
-}
diff --git a/core/java/android/view/inspector/InspectableNodeName.java b/core/java/android/view/inspector/InspectableNodeName.java
index 716409c..ea94ad4 100644
--- a/core/java/android/view/inspector/InspectableNodeName.java
+++ b/core/java/android/view/inspector/InspectableNodeName.java
@@ -34,7 +34,7 @@
* This annotation does not inherit. If a class extends an annotated parent class, but does not
* annotate itself, its node name will be inferred from its Java name.
*
- * @see InspectionHelper#getNodeName()
+ * @see InspectionCompanion#getNodeName()
* @hide
*/
@Target({TYPE})
diff --git a/core/java/android/view/inspector/InspectableProperty.java b/core/java/android/view/inspector/InspectableProperty.java
index b0fd503..5b957156 100644
--- a/core/java/android/view/inspector/InspectableProperty.java
+++ b/core/java/android/view/inspector/InspectableProperty.java
@@ -17,8 +17,11 @@
package android.view.inspector;
import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;
+import android.content.res.ResourceId;
+
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -31,8 +34,8 @@
* but on a different getter, the inspector will use the child's getter when inspecting instances
* of the child, and the parent's otherwise.
*
- * @see InspectionHelper#mapProperties(PropertyMapper)
- * @see InspectionHelper#readProperties(Object, PropertyReader)
+ * @see InspectionCompanion#mapProperties(PropertyMapper)
+ * @see InspectionCompanion#readProperties(Object, PropertyReader)
* @hide
*/
@Target({METHOD})
@@ -46,5 +49,171 @@
*
* @return The name of the property.
*/
- String value() default "";
+ String name() default "";
+
+ /**
+ * If the property is inflated from XML, the resource ID of its XML attribute.
+ *
+ * If left as {ID_NULL}, and {@link #hasAttributeId()} is true, the attribute ID will be
+ * inferred from {@link #name()}.
+ *
+ * @return The attribute ID of the property or {@link ResourceId#ID_NULL}
+ */
+ int attributeId() default ResourceId.ID_NULL;
+
+ /**
+ * If this property has an attribute ID.
+ *
+ * Set to false if the annotated property does not have an attribute ID, that is, it is not
+ * inflated from an XML attribute. This will prevent the automatic inference of the attribute
+ * ID if {@link #attributeId()} is set to {@link ResourceId#ID_NULL}.
+ *
+ * @return Whether to infer an attribute ID if not supplied
+ */
+ boolean hasAttributeId() default true;
+
+ /**
+ * Specify how to interpret a value type packed into a primitive integer.
+ *
+ * @return A {@link ValueType}
+ */
+ ValueType valueType() default ValueType.INFERRED;
+
+ /**
+ * For enumerations packed into primitive {int} properties, map the values to string names.
+ *
+ * Note that {@link #enumMapping()} cannot be used simultaneously with {@link #flagMapping()}.
+ *
+ * @return An array of {@link EnumMap}, empty if not applicable
+ * @see android.annotation.IntDef
+ * @see IntEnumMapping
+ */
+ EnumMap[] enumMapping() default {};
+
+ /**
+ * For flags packed into primitive {int} properties, model the string names of the flags.
+ *
+ * Note that {@link #flagMapping()} cannot be used simultaneously with {@link #enumMapping()}.
+ *
+ * @return An array of {@link FlagMap}, empty if not applicable
+ * @see android.annotation.IntDef
+ * @see IntFlagMapping
+ */
+ FlagMap[] flagMapping() default {};
+
+
+ /**
+ * One entry in an enumeration packed into a primitive {int}.
+ *
+ * @see IntEnumMapping
+ * @hide
+ */
+ @Target({TYPE})
+ @Retention(SOURCE)
+ @interface EnumMap {
+ /**
+ * The string name of this enumeration value.
+ *
+ * @return A string name
+ */
+ String name();
+
+ /**
+ * The integer value of this enumeration value.
+ *
+ * @return An integer value
+ */
+ int value();
+ }
+
+ /**
+ * One flag value of many that may be packed into a primitive {int}.
+ *
+ * @see IntFlagMapping
+ * @hide
+ */
+ @Target({TYPE})
+ @Retention(SOURCE)
+ @interface FlagMap {
+ /**
+ * The string name of this flag.
+ *
+ * @return A string name
+ */
+ String name();
+
+ /**
+ * A target value that the property's value must equal after masking.
+ *
+ * If a mask is not supplied (i.e., {@link #mask()} is 0), the target will be reused as the
+ * mask. This handles the common case where no flags mutually exclude each other.
+ *
+ * @return The target value to compare against
+ */
+ int target();
+
+ /**
+ * A mask that the property will be bitwise anded with before comparing to the target.
+ *
+ * If set to 0 (the default), the value of {@link #target()} will be used as a mask. Zero
+ * was chosen as the default since bitwise and with zero is always zero.
+ *
+ * @return A mask, or 0 to use the target as a mask
+ */
+ int mask() default 0;
+ }
+
+ /**
+ * The type of value packed into a primitive {int}.
+ *
+ * @hide
+ */
+ enum ValueType {
+ /**
+ * No special handling, property is considered to be a numeric value.
+ */
+ NONE,
+
+ /**
+ * The default the annotation processor infers the value type from context.
+ */
+ INFERRED,
+
+ /**
+ * Value packs an enumeration.
+ *
+ * This is inferred if {@link #enumMapping()} is specified.
+ *
+ * @see EnumMap
+ */
+ INT_ENUM,
+
+ /**
+ * Value packs flags, of which many may be enabled at once.
+ *
+ * This is inferred if {@link #flagMapping()} is specified.
+ *
+ * @see FlagMap
+ */
+ INT_FLAG,
+
+ /**
+ * Value packs color information.
+ *
+ * This is inferred from {@link android.annotation.ColorInt}, or
+ * {@link android.annotation.ColorLong} on the getter method.
+ *
+ * @see android.graphics.Color
+ */
+ COLOR,
+
+ /**
+ * Value packs gravity information.
+ *
+ * This type is not inferred, and is non-trivial to represent using {@link FlagMap}.
+ *
+ * @see android.view.Gravity
+ */
+ GRAVITY
+ }
}
diff --git a/core/java/android/view/inspector/InspectionCompanion.java b/core/java/android/view/inspector/InspectionCompanion.java
new file mode 100644
index 0000000..ce0aee8
--- /dev/null
+++ b/core/java/android/view/inspector/InspectionCompanion.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * An interface for companion objects used to inspect views.
+ *
+ * Inspection companions only need to handle the properties and node name of the specific class
+ * they are defined for, not anything from a parent class. At runtime, the inspector instantiates
+ * one instance of each inspection companion, and handles visiting them in the correct inheritance
+ * order for each type it inspects.
+ *
+ * Properties are read from the top of the type tree to the bottom, so that classes that override
+ * a property in their parent class can overwrite it in the reader. In general, properties will
+ * cleanly inherit through their getters, and the inspector runtime will read the properties of a
+ * parent class via the parent's inspection companion, and the child companion will only read
+ * properties added or changed since the parent was defined.
+ *
+ * Only one child traversal is considered for each class. If a descendant class defines a
+ * different child traversal than its parent, only the bottom traversal is used. If a class does
+ * not define its own child traversal, but one of its ancestors does, the bottom-most ancestor's
+ * traversal will be used.
+ *
+ * @param <T> The type of inspectable this is the companion to
+ */
+public interface InspectionCompanion<T> {
+ /**
+ * Map the string names of the properties this companion knows about to integer IDs.
+ *
+ * Each companion is responsible for storing the integer IDs of all its properties. This is the
+ * only method that is allowed to modify the stored IDs.
+ *
+ * Calling {@link #readProperties(T, PropertyReader)} before calling this results in
+ * undefined behavior.
+ *
+ * @param propertyMapper A {@link PropertyMapper} maps string names to IDs.
+ */
+ void mapProperties(@NonNull PropertyMapper propertyMapper);
+
+ /**
+ * Read the values of an instance of this companion's type into a {@link PropertyReader}.
+ *
+ * This method needs to return the property IDs stored by
+ * {@link #mapProperties(PropertyMapper)}. Implementations should track if their properties
+ * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
+ * called before {mapProperties}.
+ *
+ * @param inspectable A object of type {@link T} to read the properties of.
+ * @param propertyReader An object which receives the property IDs and values.
+ */
+ void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
+
+ /**
+ * Get an optional name to display to developers for inspection nodes of this companion's type.
+ *
+ * The default implementation returns null, which will cause the runtime to use the class's
+ * simple name as defined by {@link Class#getSimpleName()} as the node name.
+ *
+ * If the type of this companion is inflated from XML, this method should be overridden to
+ * return the string used as the tag name for this type in XML.
+ *
+ * @return A string to use as the node name, or null to use the simple class name fallback.
+ */
+ @Nullable
+ default String getNodeName() {
+ return null;
+ }
+
+ /**
+ * Thrown by {@link #readProperties(Object, PropertyReader)} if called before
+ * {@link #mapProperties(PropertyMapper)}.
+ */
+ class UninitializedPropertyMapException extends RuntimeException {
+ public UninitializedPropertyMapException() {
+ super("Unable to read properties of an inspectable before mapping their IDs.");
+ }
+ }
+}
diff --git a/core/java/android/view/inspector/InspectionHelper.java b/core/java/android/view/inspector/InspectionHelper.java
deleted file mode 100644
index 27a9704..0000000
--- a/core/java/android/view/inspector/InspectionHelper.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view.inspector;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-/**
- * An interface for companion objects used to inspect views.
- *
- * Inspection helpers only need to handle the properties, name and traversal of the specific class
- * they are defined for, not anything from a parent class. At runtime, the inspector instantiates
- * one instance of each inspection helper, and handles visiting them in the correct inheritance
- * order for each type it inspects.
- *
- * Properties are read from the top of the type tree to the bottom, so that classes that override
- * a property in their parent class can overwrite it in the reader. In general, properties will
- * cleanly inherit through their getters, and the inspector runtime will read the properties of a
- * parent class via the parent's inspection helper, and the child helper will only read properties
- * added or changed since the parent was defined.
- *
- * Only one child traversal is considered for each class. If a descendant class defines a
- * different child traversal than its parent, only the bottom traversal is used. If a class does
- * not define its own child traversal, but one of its ancestors does, the bottom-most ancestor's
- * traversal will be used.
- *
- * @param <T> The type of inspectable this helper operates on
- * @hide
- */
-public interface InspectionHelper<T> {
- /**
- * Map the string names of the properties this helper knows about to integer IDs.
- *
- * Each helper is responsible for storing the integer IDs of all its properties. This is the
- * only method that is allowed to modify the stored IDs.
- *
- * Calling {@link #readProperties(T, PropertyReader)} before calling this results in
- * undefined behavior.
- *
- * @param propertyMapper A {@link PropertyMapper} or lambda which maps string names to IDs.
- */
- void mapProperties(@NonNull PropertyMapper propertyMapper);
-
- /**
- * Read the values of an instance of this helper's type into a {@link PropertyReader}.
- *
- * This method needs to return the property IDs stored by
- * {@link #mapProperties(PropertyMapper)}. Implementations should track if their properties
- * have been mapped and throw a {@link UninitializedPropertyMapException} if this method is
- * called before {mapProperties}.
- *
- * @param inspectable A object of type {@link T} to read the properties of.
- * @param propertyReader An object which receives the property IDs and values.
- */
- void readProperties(@NonNull T inspectable, @NonNull PropertyReader propertyReader);
-
- /**
- * Query if this inspectable type can potentially have child nodes.
- *
- * E.g.: any descendant of {@link android.view.ViewGroup} can have child nodes, but a leaf
- * view like {@link android.widget.ImageView} may not.
- *
- * The default implementation always returns false. If an implementing class overrides this, it
- * should also define {@link #traverseChildren(T, ChildTraverser)}.
- *
- * @return True if this inspectable type can potentially have child nodes, false otherwise.
- */
- default boolean hasChildTraversal() {
- return false;
- }
-
- /**
- * Traverse the child nodes of an instance of this helper's type into a {@link ChildTraverser}.
- *
- * This provides the ability to traverse over a variety of collection APIs (e.g.: arrays,
- * {@link Iterable}, or {@link java.util.Iterator}) in a uniform fashion. The traversal must be
- * in the order defined by this helper's type. If the getter returns null, the helper must
- * treat it as an empty collection.
- *
- * The default implementation throws a {@link NoChildTraversalException}. If
- * {@link #hasChildTraversal()} returns is overriden to return true, it is expected that the
- * implementing class will also override this method and provide a traversal.
- *
- * @param inspectable An object of type {@link T} to traverse the child nodes of.
- * @param childTraverser A {@link ChildTraverser} or lamba to receive the children in order.
- * @throws NoChildTraversalException If there is no defined child traversal
- */
- default void traverseChildren(
- @NonNull T inspectable,
- @SuppressWarnings("unused") @NonNull ChildTraverser childTraverser) {
- throw new NoChildTraversalException(inspectable.getClass());
- }
-
- /**
- * Get an optional name to display to developers for inspection nodes of this helper's type.
- *
- * The default implementation returns null, which will cause the runtime to use the class's
- * simple name as defined by {@link Class#getSimpleName()} as the node name.
- *
- * If the type of this helper is inflated from XML, this method should be overridden to return
- * the string used as the tag name for this type in XML.
- *
- * @return A string to use as the node name, or null to use the simple class name fallback.
- */
- @Nullable
- default String getNodeName() {
- return null;
- }
-
- /**
- * Thrown by {@link #readProperties(Object, PropertyReader)} if called before
- * {@link #mapProperties(PropertyMapper)}.
- */
- class UninitializedPropertyMapException extends RuntimeException {
- public UninitializedPropertyMapException() {
- super("Unable to read properties of an inspectable before mapping their IDs.");
- }
- }
-
- /**
- * Thrown by {@link #traverseChildren(Object, ChildTraverser)} if no child traversal exists.
- */
- class NoChildTraversalException extends RuntimeException {
- public NoChildTraversalException(Class cls) {
- super(String.format(
- "Class %s does not have a defined child traversal. Cannot traverse children.",
- cls.getCanonicalName()
- ));
- }
- }
-}
diff --git a/core/java/android/view/inspector/IntEnumMapping.java b/core/java/android/view/inspector/IntEnumMapping.java
new file mode 100644
index 0000000..69f6dce
--- /dev/null
+++ b/core/java/android/view/inspector/IntEnumMapping.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inspector;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * Maps the values of an {int} property to string names for properties that encode enumerations.
+ *
+ * An {@link InspectionCompanion} may provide an instance of this class to a {@link PropertyMapper}
+ * for enumerations packed into primitive {int} properties.
+ *
+ * This class is immutable, and must be constructed by a {@link Builder}.
+ *
+ * @see PropertyMapper#mapIntEnum(String, int, IntEnumMapping)
+ */
+public final class IntEnumMapping {
+ private final Value[] mValues;
+
+ /**
+ * Map from a property value to a string name.
+ *
+ * @param value The value of a property
+ * @return The name of the enumeration value, null if the value is not mapped
+ */
+ @Nullable
+ public String nameOf(int value) {
+ for (Value valueTuple : mValues) {
+ if (valueTuple.mValue == value) {
+ return valueTuple.mName;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Create a new instance from a builder.
+ *
+ * This constructor is private, use {@link Builder#build()} instead.
+ *
+ * @param builder A builder to create from
+ */
+ private IntEnumMapping(Builder builder) {
+ mValues = builder.mValues.toArray(new Value[builder.mValues.size()]);
+ }
+
+ /**
+ * A builder for {@link IntEnumMapping}
+ */
+ public static final class Builder {
+ private final ArrayList<Value> mValues;
+
+ public Builder() {
+ mValues = new ArrayList<>();
+ }
+
+ /**
+ * Add a new entry to this mapping.
+ *
+ * @param name Name of the enumeration value
+ * @param value Int value of the enumeration value
+ * @return This builder
+ */
+ @NonNull
+ public Builder addValue(@NonNull String name, int value) {
+ mValues.add(new Value(name, value));
+ return this;
+ }
+
+ /**
+ * Clear the builder, allowing for recycling.
+ */
+ public void clear() {
+ mValues.clear();
+ }
+
+ /**
+ * Build a new {@link IntEnumMapping} from this builder
+ *
+ * @return A new mapping
+ */
+ @NonNull
+ public IntEnumMapping build() {
+ return new IntEnumMapping(this);
+ }
+ }
+
+ /**
+ * Inner class that holds the name and value of an enumeration value.
+ */
+ private static final class Value {
+ @NonNull private final String mName;
+ private final int mValue;
+
+ private Value(@NonNull String name, int value) {
+ mName = name;
+ mValue = value;
+ }
+ }
+}
diff --git a/core/java/android/view/inspector/IntFlagMapping.java b/core/java/android/view/inspector/IntFlagMapping.java
new file mode 100644
index 0000000..dcb87e1
--- /dev/null
+++ b/core/java/android/view/inspector/IntFlagMapping.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inspector;
+
+import android.annotation.NonNull;
+
+import java.util.ArrayList;
+
+/**
+ * Maps the values of an {int} property to arrays of string for properties that encode flags.
+ *
+ * An {@link InspectionCompanion} may provide an instance of this class to a {@link PropertyMapper}
+ * for flag values packed into primitive {int} properties.
+ *
+ * Each flag has a
+ *
+ * This class is immutable, and must be constructed by a {@link Builder}.
+ *
+ * @see PropertyMapper#mapIntFlag(String, int, IntFlagMapping)
+ */
+public final class IntFlagMapping {
+ private final Flag[] mFlags;
+
+ /**
+ * Get an array of the names of enabled flags for a given property value.
+ *
+ * @param value The value of the property
+ * @return The names of the enabled flags
+ */
+ @NonNull
+ public String[] namesOf(int value) {
+ ArrayList<String> enabledFlagNames = new ArrayList<>(mFlags.length);
+
+ for (Flag flag : mFlags) {
+ if (flag.isEnabledFor(value)) {
+ enabledFlagNames.add(flag.mName);
+ }
+ }
+
+ return enabledFlagNames.toArray(new String[enabledFlagNames.size()]);
+ }
+
+ /**
+ * Create a new instance from a builder.
+ *
+ * This constructor is private, use {@link Builder#build()} instead.
+ *
+ * @param builder A builder to create from
+ */
+ private IntFlagMapping(Builder builder) {
+ mFlags = builder.mFlags.toArray(new Flag[builder.mFlags.size()]);
+ }
+
+ /**
+ * A builder for {@link IntFlagMapping}.
+ */
+ public static final class Builder {
+ private ArrayList<Flag> mFlags;
+
+ public Builder() {
+ mFlags = new ArrayList<>();
+ }
+
+ /**
+ * Add a new flag without a mask.
+ *
+ * The target value will be used as a mask, to handle the common case where flag values
+ * are not mutually exclusive. The flag will be considered enabled for a property value if
+ * the result of bitwise anding the target and the value equals the target, that is:
+ * {(value & target) == target}.
+ *
+ * @param name The name of the flag
+ * @param target The value to compare against
+ * @return This builder
+ */
+ @NonNull
+ public Builder addFlag(@NonNull String name, int target) {
+ mFlags.add(new Flag(name, target, target));
+ return this;
+ }
+
+ /**
+ * Add a new flag with a mask.
+ *
+ * The flag will be considered enabled for a property value if the result of bitwise anding
+ * the value and the mask equals the target, that is: {(value & mask) == target}.
+ *
+ * @param name The name of the flag
+ * @param target The value to compare against
+ * @param mask A bit mask
+ * @return This builder
+ */
+ @NonNull
+ public Builder addFlag(@NonNull String name, int target, int mask) {
+ mFlags.add(new Flag(name, target, mask));
+ return this;
+ }
+
+ /**
+ * Clear the builder, allowing for recycling.
+ */
+ public void clear() {
+ mFlags.clear();
+ }
+
+ /**
+ * Build a new {@link IntFlagMapping} from this builder.
+ *
+ * @return A new mapping
+ */
+ @NonNull
+ public IntFlagMapping build() {
+ return new IntFlagMapping(this);
+ }
+ }
+
+ /**
+ * Inner class that holds the name, mask, and target value of a flag
+ */
+ private static final class Flag {
+ @NonNull private final String mName;
+ private final int mTarget;
+ private final int mMask;
+
+ private Flag(@NonNull String name, int target, int mask) {
+ mName = name;
+ mTarget = target;
+ mMask = mask;
+ }
+
+ /**
+ * Compare the supplied property value against the mask and taget.
+ *
+ * @param value The value to check
+ * @return True if this flag is enabled
+ */
+ private boolean isEnabledFor(int value) {
+ return (value & mMask) == mTarget;
+ }
+ }
+}
diff --git a/core/java/android/view/inspector/PropertyMapper.java b/core/java/android/view/inspector/PropertyMapper.java
index 35550bd..5fb291b 100644
--- a/core/java/android/view/inspector/PropertyMapper.java
+++ b/core/java/android/view/inspector/PropertyMapper.java
@@ -16,102 +16,160 @@
package android.view.inspector;
+import android.annotation.AttrRes;
import android.annotation.NonNull;
/**
* An interface for mapping the string names of inspectable properties to integer identifiers.
*
- * This interface is consumed by {@link InspectionHelper#mapProperties(PropertyMapper)}.
+ * This interface is consumed by {@link InspectionCompanion#mapProperties(PropertyMapper)}.
*
* Mapping properties to IDs enables quick comparisons against shadow copies of inspectable
* objects without performing a large number of string comparisons.
*
- * @see InspectionHelper#mapProperties(PropertyMapper)
- * @hide
+ * @see InspectionCompanion#mapProperties(PropertyMapper)
*/
public interface PropertyMapper {
/**
* Map a string name to an integer ID for a primitive boolean property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapBoolean(@NonNull String name);
+ int mapBoolean(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for a primitive byte property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapByte(@NonNull String name);
+ int mapByte(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for a primitive char property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapChar(@NonNull String name);
+ int mapChar(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for a primitive double property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapDouble(@NonNull String name);
+ int mapDouble(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for a primitive float property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapFloat(@NonNull String name);
+ int mapFloat(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for a primitive int property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapInt(@NonNull String name);
+ int mapInt(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for a primitive long property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapLong(@NonNull String name);
+ int mapLong(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for a primitive short property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapShort(@NonNull String name);
+ int mapShort(@NonNull String name, @AttrRes int attributeId);
/**
* Map a string name to an integer ID for an object property.
*
* @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
* @return An integer ID for the property
* @throws PropertyConflictException If the property name is already mapped as another type.
*/
- int mapObject(@NonNull String name);
+ int mapObject(@NonNull String name, @AttrRes int attributeId);
/**
+ * Map a string name to an integer ID for a color property.
+ *
+ * @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
+ * @return An integer ID for the property
+ * @throws PropertyConflictException If the property name is already mapped as another type.
+ * @see android.graphics.Color
+ */
+ int mapColor(@NonNull String name, @AttrRes int attributeId);
+
+ /**
+ * Map a string name to an integer ID for a gravity property.
+ *
+ * @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
+ * @return An integer ID for the property
+ * @throws PropertyConflictException If the property name is already mapped as another type.
+ * @see android.view.Gravity
+ */
+ int mapGravity(@NonNull String name, @AttrRes int attributeId);
+
+ /**
+ * Map a string name to an integer ID for an enumeration packed into an int property.
+ *
+ * @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
+ * @param mapping A mapping from int to String
+ * @return An integer ID for the property
+ * @throws PropertyConflictException If the property name is already mapped as another type.
+ */
+ int mapIntEnum(
+ @NonNull String name,
+ @AttrRes int attributeId,
+ @NonNull IntEnumMapping mapping);
+
+ /**
+ * Map a string name to an integer ID for a flag set packed into an int property.
+ *
+ * @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
+ * @param mapping A mapping from int to an array of strings
+ * @return An integer ID for the property
+ * @throws PropertyConflictException If the property name is already mapped as another type.
+ */
+ int mapIntFlag(
+ @NonNull String name,
+ @AttrRes int attributeId,
+ @NonNull IntFlagMapping mapping);
+ /**
* Thrown from a map method if a property name is already mapped as different type.
*/
class PropertyConflictException extends RuntimeException {
diff --git a/core/java/android/view/inspector/PropertyReader.java b/core/java/android/view/inspector/PropertyReader.java
index df81c10..fd83e8d 100644
--- a/core/java/android/view/inspector/PropertyReader.java
+++ b/core/java/android/view/inspector/PropertyReader.java
@@ -16,19 +16,21 @@
package android.view.inspector;
+import android.annotation.ColorInt;
+import android.annotation.ColorLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Color;
/**
* An interface for reading the properties of an inspectable object.
*
- * Used as the parameter for {@link InspectionHelper#readProperties(Object, PropertyReader)}.
+ * Used as the parameter for {@link InspectionCompanion#readProperties(Object, PropertyReader)}.
* It has separate methods for all primitive types to avoid autoboxing overhead if a concrete
* implementation is able to work with primitives. Implementations should be prepared to accept
* {null} as the value of {@link PropertyReader#readObject(int, Object)}.
*
- * @see InspectionHelper#readProperties(Object, PropertyReader)
- * @hide
+ * @see InspectionCompanion#readProperties(Object, PropertyReader)
*/
public interface PropertyReader {
/**
@@ -115,6 +117,60 @@
void readObject(int id, @Nullable Object value);
/**
+ * Read a color packed into a {@link ColorInt} as a property.
+ *
+ * @param id Identifier of the property from a {@link PropertyMapper}
+ * @param value Value of the property
+ * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+ */
+ void readColor(int id, @ColorInt int value);
+
+ /**
+ * Read a color packed into a {@link ColorLong} as a property.
+ *
+ * @param id Identifier of the property from a {@link PropertyMapper}
+ * @param value Value of the property
+ * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+ */
+ void readColor(int id, @ColorLong long value);
+
+ /**
+ * Read a {@link Color} object as a property.
+ *
+ * @param id Identifier of the property from a {@link PropertyMapper}
+ * @param value Value of the property
+ * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
+ */
+ void readColor(int id, @Nullable Color value);
+
+ /**
+ * Read {@link android.view.Gravity} packed into an primitive {int}.
+ *
+ * @param id Identifier of the property from a {@link PropertyMapper}
+ * @param value Value of the property
+ * @throws PropertyTypeMismatchException If the property ID is not mapped as a gravity property
+ */
+ void readGravity(int id, int value);
+
+ /**
+ * Read an enumeration packed into a primitive {int}.
+ *
+ * @param id Identifier of the property from a {@link PropertyMapper}
+ * @param value Value of the property
+ * @throws PropertyTypeMismatchException If the property ID is not mapped as an object
+ */
+ void readIntEnum(int id, int value);
+
+ /**
+ * Read a flag packed into a primitive {int}.
+ *
+ * @param id Identifier of the property from a {@link PropertyMapper}
+ * @param value Value of the property
+ * @throws PropertyTypeMismatchException If the property ID is not mapped as an object
+ */
+ void readIntFlag(int id, int value);
+
+ /**
* Thrown if a client calls a typed read method for a property of a different type.
*/
class PropertyTypeMismatchException extends RuntimeException {
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java
index befcb55..f636281 100644
--- a/core/java/android/view/intelligence/ContentCaptureEvent.java
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.java
@@ -163,7 +163,7 @@
* Gets optional flags associated with the event.
*
* @return either {@code 0} or
- * {@link android.view.intelligence.IntelligenceManager#FLAG_USER_INPUT}.
+ * {@link android.view.intelligence.ContentCaptureManager#FLAG_USER_INPUT}.
*/
public int getFlags() {
return mFlags;
diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/ContentCaptureManager.java
similarity index 77%
rename from core/java/android/view/intelligence/IntelligenceManager.java
rename to core/java/android/view/intelligence/ContentCaptureManager.java
index 2f3b4ef..45518d5 100644
--- a/core/java/android/view/intelligence/IntelligenceManager.java
+++ b/core/java/android/view/intelligence/ContentCaptureManager.java
@@ -23,7 +23,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.content.ComponentName;
import android.content.Context;
@@ -44,13 +43,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
-/**
- * TODO(b/111276913): add javadocs / implement
- */
/*
* NOTE: all methods in this class should return right away, or do the real work in a handler
* thread.
@@ -58,10 +52,13 @@
* Hence, the only field that must be thread-safe is mEnabled, which is called at the beginning
* of every method.
*/
-@SystemService(Context.INTELLIGENCE_MANAGER_SERVICE)
-public final class IntelligenceManager {
+/**
+ * TODO(b/111276913): add javadocs / implement
+ */
+@SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE)
+public final class ContentCaptureManager {
- private static final String TAG = "IntelligenceManager";
+ private static final String TAG = "ContentCaptureManager";
// TODO(b/111276913): define a way to dynamically set them(for example, using settings?)
private static final boolean VERBOSE = false;
@@ -140,7 +137,7 @@
private final Handler mHandler;
/** @hide */
- public IntelligenceManager(@NonNull Context context, @Nullable IIntelligenceManager service) {
+ public ContentCaptureManager(@NonNull Context context, @Nullable IIntelligenceManager service) {
mContext = Preconditions.checkNotNull(context, "context cannot be null");
if (VERBOSE) {
Log.v(TAG, "Constructor for " + context.getPackageName());
@@ -156,7 +153,7 @@
public void onActivityCreated(@NonNull IBinder token, @NonNull ComponentName componentName) {
if (!isContentCaptureEnabled()) return;
- mHandler.sendMessage(obtainMessage(IntelligenceManager::handleStartSession, this,
+ mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleStartSession, this,
token, componentName));
}
@@ -192,7 +189,7 @@
}
}
- private void handleSessionStarted(int resultCode) {
+ private void handleSessionStarted(int resultCode) {
mState = resultCode;
mDisabled.set(mState == STATE_DISABLED);
if (VERBOSE) {
@@ -264,7 +261,7 @@
Log.v(TAG, "onActivityLifecycleEvent() for " + getActivityDebugName()
+ ": " + ContentCaptureEvent.getTypeAsString(type));
}
- mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+ mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
new ContentCaptureEvent(type), /* forceFlush= */ true));
}
@@ -279,7 +276,7 @@
+ ", mId=" + mId);
}
- mHandler.sendMessage(obtainMessage(IntelligenceManager::handleFinishSession, this));
+ mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleFinishSession, this));
}
private void handleFinishSession() {
@@ -328,7 +325,7 @@
throw new IllegalArgumentException("Invalid node class: " + node.getClass());
}
- mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+ mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
new ContentCaptureEvent(TYPE_VIEW_APPEARED)
.setViewNode(((ViewNode.ViewStructureImpl) node).mNode),
/* forceFlush= */ false));
@@ -346,7 +343,7 @@
Preconditions.checkNotNull(id);
if (!isContentCaptureEnabled()) return;
- mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+ mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
new ContentCaptureEvent(TYPE_VIEW_DISAPPEARED).setAutofillId(id),
/* forceFlush= */ false));
}
@@ -365,7 +362,7 @@
if (!isContentCaptureEnabled()) return;
- mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this,
+ mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this,
new ContentCaptureEvent(TYPE_VIEW_TEXT_CHANGED, flags).setAutofillId(id)
.setText(text), /* forceFlush= */ false));
}
@@ -396,11 +393,11 @@
}
/**
- * Returns the component name of the {@code android.service.intelligence.IntelligenceService}
- * that is enabled for the current user.
+ * Returns the component name of the system service that is consuming the captured events for
+ * the current user.
*/
@Nullable
- public ComponentName getIntelligenceServiceComponentName() {
+ public ComponentName getServiceComponentName() {
//TODO(b/111276913): implement
return null;
}
@@ -422,106 +419,6 @@
//TODO(b/111276913): implement
}
- /**
- * Called by the the service {@link android.service.intelligence.IntelligenceService}
- * to define whether content capture should be enabled for activities with such
- * {@link android.content.ComponentName}.
- *
- * <p>Useful to blacklist a particular activity.
- *
- * @throws UnsupportedOperationException if not called by the UID that owns the
- * {@link android.service.intelligence.IntelligenceService} associated with the
- * current user.
- *
- * @hide
- */
- @SystemApi
- public void setActivityContentCaptureEnabled(@NonNull ComponentName activity,
- boolean enabled) {
- //TODO(b/111276913): implement
- }
-
- /**
- * Called by the the service {@link android.service.intelligence.IntelligenceService}
- * to explicitly limit content capture to the given packages and activities.
- *
- * <p>When the whitelist is set, it overrides the values passed to
- * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}
- * and {@link #setPackageContentCaptureEnabled(String, boolean)}.
- *
- * <p>To reset the whitelist, call it passing {@code null} to both arguments.
- *
- * <p>Useful when the service wants to restrict content capture to a category of apps, like
- * chat apps. For example, if the service wants to support view captures on all activities of
- * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2},
- * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"),
- * Arrays.asList(new ComponentName("ChatApp2", "act1"),
- * new ComponentName("ChatApp2", "act2")));}
- *
- * @throws UnsupportedOperationException if not called by the UID that owns the
- * {@link android.service.intelligence.IntelligenceService} associated with the
- * current user.
- *
- * @hide
- */
- @SystemApi
- public void setContentCaptureWhitelist(@Nullable List<String> packages,
- @Nullable List<ComponentName> activities) {
- //TODO(b/111276913): implement
- }
-
- /**
- * Called by the the service {@link android.service.intelligence.IntelligenceService}
- * to define whether content capture should be enabled for activities of the app with such
- * {@code packageName}.
- *
- * <p>Useful to blacklist any activity from a particular app.
- *
- * @throws UnsupportedOperationException if not called by the UID that owns the
- * {@link android.service.intelligence.IntelligenceService} associated with the
- * current user.
- *
- * @hide
- */
- @SystemApi
- public void setPackageContentCaptureEnabled(@NonNull String packageName, boolean enabled) {
- //TODO(b/111276913): implement
- }
-
- /**
- * Gets the activities where content capture was disabled by
- * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}.
- *
- * @throws UnsupportedOperationException if not called by the UID that owns the
- * {@link android.service.intelligence.IntelligenceService} associated with the
- * current user.
- *
- * @hide
- */
- @SystemApi
- @NonNull
- public Set<ComponentName> getContentCaptureDisabledActivities() {
- //TODO(b/111276913): implement
- return null;
- }
-
- /**
- * Gets the apps where content capture was disabled by
- * {@link #setPackageContentCaptureEnabled(String, boolean)}.
- *
- * @throws UnsupportedOperationException if not called by the UID that owns the
- * {@link android.service.intelligence.IntelligenceService} associated with the
- * current user.
- *
- * @hide
- */
- @SystemApi
- @NonNull
- public Set<String> getContentCaptureDisabledPackages() {
- //TODO(b/111276913): implement
- return null;
- }
-
/** @hide */
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix); pw.println("IntelligenceManager");
@@ -547,7 +444,7 @@
}
if (mEvents != null) {
final int numberEvents = mEvents.size();
- pw.print(prefix2); pw.print("batched events: "); pw.print(numberEvents);
+ pw.print(prefix2); pw.print("buffered events: "); pw.print(numberEvents);
pw.print('/'); pw.println(MAX_BUFFER_SIZE);
if (VERBOSE && numberEvents > 0) {
final String prefix3 = prefix2 + " ";
diff --git a/core/java/android/view/intelligence/IIntelligenceManager.aidl b/core/java/android/view/intelligence/IIntelligenceManager.aidl
index 7518ff5..882fb26 100644
--- a/core/java/android/view/intelligence/IIntelligenceManager.aidl
+++ b/core/java/android/view/intelligence/IIntelligenceManager.aidl
@@ -28,6 +28,7 @@
/**
* {@hide}
*/
+// TODO(b/111276913): rename once the final name is defined
oneway interface IIntelligenceManager {
/**
* Starts a session, sending the "remote" sessionId to the receiver.
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1deee8a..085f8f1 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -166,7 +166,7 @@
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationContext;
import android.view.textclassifier.TextClassificationManager;
@@ -10135,7 +10135,7 @@
}
/**
- * Notify managers (such as {@link AutofillManager} and {@link IntelligenceManager}) that are
+ * Notify managers (such as {@link AutofillManager} and {@link ContentCaptureManager}) that are
* interested on text changes.
*/
private void notifyListeningManagersAfterTextChanged() {
@@ -10155,10 +10155,10 @@
// ContentCapture
if (isImportantForContentCapture() && isTextEditable()) {
- final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class);
- if (im != null && im.isContentCaptureEnabled()) {
+ final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
+ if (cm != null && cm.isContentCaptureEnabled()) {
// TODO(b/111276913): pass flags when edited by user / add CTS test
- im.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0);
+ cm.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0);
}
}
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 488b991..d8ee643 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -91,6 +91,7 @@
import android.view.ViewRootImpl;
import android.view.ViewRootImpl.ActivityConfigCallback;
import android.view.Window;
+import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -3877,4 +3878,9 @@
mDecor.updateLogTag(params);
}
}
+
+ @Override
+ public WindowInsetsController getInsetsController() {
+ return mDecor.getWindowInsetsController();
+ }
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index 36fe4fc..c8834a8 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -27,6 +27,7 @@
import android.view.IWindow;
import android.view.IWindowSession;
import android.view.PointerIcon;
+import android.view.InsetsSourceControl;
import android.view.InsetsState;
import com.android.internal.os.IResultReceiver;
@@ -58,6 +59,11 @@
}
@Override
+ public void insetsControlChanged(InsetsState insetsState,
+ InsetsSourceControl[] activeControls) throws RemoteException {
+ }
+
+ @Override
public void moved(int newX, int newY) {
}
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index bdd5f83..31bb1d5 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -34,7 +34,6 @@
],
cppflags: ["-Wno-conversion-null"],
- cpp_std: "c++17",
srcs: [
"AndroidRuntime.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index bc1d5cc..f9879cc 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -1056,12 +1056,18 @@
if (rootDir == NULL) {
rootDir = "/system";
if (!hasDir("/system")) {
- LOG_FATAL("No root directory specified, and /android does not exist.");
+ LOG_FATAL("No root directory specified, and /system does not exist.");
return;
}
setenv("ANDROID_ROOT", rootDir, 1);
}
+ const char* runtimeRootDir = getenv("ANDROID_RUNTIME_ROOT");
+ if (runtimeRootDir == NULL) {
+ LOG_FATAL("No runtime directory specified with ANDROID_RUNTIME_ROOT environment variable.");
+ return;
+ }
+
//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 1ea4ed1..12a8343b4 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -842,6 +842,18 @@
}
// ----------------------------------------------------------------------------
+static jint android_media_AudioRecord_get_port_id(JNIEnv *env, jobject thiz) {
+ sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
+ if (lpRecorder == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Unable to retrieve AudioRecord pointer for getId()");
+ return (jint)AUDIO_PORT_HANDLE_NONE;
+ }
+ return (jint)lpRecorder->getPortId();
+}
+
+
+// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
// name, signature, funcPtr
@@ -883,6 +895,7 @@
(void *)android_media_AudioRecord_get_timestamp},
{"native_get_active_microphones", "(Ljava/util/ArrayList;)I",
(void *)android_media_AudioRecord_get_active_microphones},
+ {"native_getPortId", "()I", (void *)android_media_AudioRecord_get_port_id},
};
// field names found in android/media/AudioRecord.java
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 04f0a53..d927972 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1284,6 +1284,17 @@
}
// ----------------------------------------------------------------------------
+static jint android_media_AudioTrack_get_port_id(JNIEnv *env, jobject thiz) {
+ sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
+ if (lpTrack == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "AudioTrack not initialized");
+ return (jint)AUDIO_PORT_HANDLE_NONE;
+ }
+ return (jint)lpTrack->getPortId();
+}
+
+// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
// name, signature, funcPtr
@@ -1354,6 +1365,7 @@
"(I)Landroid/media/VolumeShaper$State;",
(void *)android_media_AudioTrack_get_volume_shaper_state},
{"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
+ {"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
};
@@ -1379,7 +1391,6 @@
}
}
-
// ----------------------------------------------------------------------------
int register_android_media_AudioTrack(JNIEnv *env)
{
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index b465fb4..0e052fe 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -234,10 +234,14 @@
}
optional Location location = 31;
+ // How frequently will the user be reminded about location permission grants
message LocationAccessCheck {
option (android.msg_privacy).dest = DEST_EXPLICIT;
+ // Time in between periodic checks
optional SettingProto interval_millis = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ // Time in between the user granting a location permission and a check
optional SettingProto delay_millis = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional LocationAccessCheck location_access_check = 73;
diff --git a/core/proto/android/service/runtime.proto b/core/proto/android/service/runtime.proto
new file mode 100644
index 0000000..ecbccef
--- /dev/null
+++ b/core/proto/android/service/runtime.proto
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+package android.service.runtime;
+
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "RuntimeServiceProto";
+
+// Represents dumpsys info from RuntimeService.
+message RuntimeServiceInfoProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Generic debug information to include.
+ repeated DebugEntryProto debug_entry = 1;
+}
+
+// A piece of key / value debug information.
+message DebugEntryProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ optional string key = 1;
+
+ optional string string_value = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b4d5f67..83f3057 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3047,12 +3047,12 @@
<permission android:name="android.permission.BIND_TEXTCLASSIFIER_SERVICE"
android:protectionLevel="signature" />
- <!-- Must be required by a android.service.intelligence.IntelligenceService,
+ <!-- Must be required by a android.service.intelligence.SmartSuggestionsService,
to ensure that only the system can bind to it.
@SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
<p>Protection level: signature
-->
- <permission android:name="android.permission.BIND_INTELLIGENCE_SERVICE"
+ <permission android:name="android.permission.BIND_SMART_SUGGESTIONS_SERVICE"
android:protectionLevel="signature" />
<!-- Must be required by hotword enrollment application,
@@ -4611,6 +4611,13 @@
</intent-filter>
</receiver>
+ <receiver android:name="com.android.server.WallpaperUpdateReceiver"
+ android:permission="android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY">
+ <intent-filter>
+ <action android:name="android.intent.action.DEVICE_CUSTOMIZATION_READY"/>
+ </intent-filter>
+ </receiver>
+
<service android:name="android.hardware.location.GeofenceHardwareService"
android:permission="android.permission.LOCATION_HARDWARE"
android:exported="false" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2447289..f55e48e 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1915,6 +1915,9 @@
<enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
<enum name="KEYCODE_ALL_APPS" value="284" />
<enum name="KEYCODE_REFRESH" value="285" />
+ <enum name="KEYCODE_THUMBS_UP" value="286" />
+ <enum name="KEYCODE_THUMBS_DOWN" value="287" />
+ <enum name="KEYCODE_PROFILE_SWITCH" value="288" />
</attr>
<!-- ***************************************************************** -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 1d80961..0cd6bc5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2125,6 +2125,9 @@
during initialization when the setting is still null. -->
<bool name="config_dozeAlwaysOnEnabled">true</bool>
+ <!-- If AOD can show an ambient version of the wallpaper -->
+ <bool name="config_dozeSupportsAodWallpaper">true</bool>
+
<!-- Whether the display blanks itself when transitioning from a doze to a non-doze state -->
<bool name="config_displayBlanksAfterDoze">false</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 783f1f3..01422c8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3310,6 +3310,7 @@
<java-symbol type="integer" name="config_autoGroupAtCount" />
<java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
<java-symbol type="bool" name="config_dozeAlwaysOnEnabled" />
+ <java-symbol type="bool" name="config_dozeSupportsAodWallpaper" />
<java-symbol type="bool" name="config_displayBlanksAfterDoze" />
<java-symbol type="bool" name="config_displayBrightnessBucketsInDoze" />
<java-symbol type="integer" name="config_storageManagerDaystoRetainDefault" />
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 3b650e5..46d4a47 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -91,6 +91,8 @@
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<uses-permission android:name="android.permission.KILL_UID" />
+ <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+
<!-- location test permissions -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
index c8bc35c..9e15231 100644
--- a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
+++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
@@ -16,6 +16,10 @@
package android.os;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
+import static android.os.RedactingFileDescriptor.removeRange;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -58,8 +62,8 @@
@Test
public void testSingleByte() throws Exception {
- final FileDescriptor fd = RedactingFileDescriptor
- .open(mContext, mFile, new long[] { 10, 11 }).getFileDescriptor();
+ final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
+ new long[] { 10, 11 }).getFileDescriptor();
final byte[] buf = new byte[1_000];
assertEquals(buf.length, Os.read(fd, buf, 0, buf.length));
@@ -74,8 +78,8 @@
@Test
public void testRanges() throws Exception {
- final FileDescriptor fd = RedactingFileDescriptor
- .open(mContext, mFile, new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+ final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
+ new long[] { 100, 200, 300, 400 }).getFileDescriptor();
final byte[] buf = new byte[10];
assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 90));
@@ -96,8 +100,8 @@
@Test
public void testEntireFile() throws Exception {
- final FileDescriptor fd = RedactingFileDescriptor
- .open(mContext, mFile, new long[] { 0, 5_000_000 }).getFileDescriptor();
+ final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
+ new long[] { 0, 5_000_000 }).getFileDescriptor();
try (FileInputStream in = new FileInputStream(fd)) {
int val;
@@ -106,4 +110,61 @@
}
}
}
+
+ @Test
+ public void testReadWrite() throws Exception {
+ final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
+ new long[] { 100, 200, 300, 400 }).getFileDescriptor();
+
+ // Redacted at first
+ final byte[] buf = new byte[10];
+ assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 95));
+ assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 0, 0, 0, 0, 0 }, buf);
+
+ // But we can see data that we've written
+ Os.pwrite(fd, new byte[] { 32, 32 }, 0, 2, 102);
+ assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 95));
+ assertArrayEquals(new byte[] { 64, 64, 64, 64, 64, 0, 0, 32, 32, 0 }, buf);
+ }
+
+ @Test
+ public void testRemoveRange() throws Exception {
+ // Removing outside ranges should have no changes
+ assertArrayEquals(new long[] { 100, 200, 300, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 0, 100));
+ assertArrayEquals(new long[] { 100, 200, 300, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 200, 300));
+ assertArrayEquals(new long[] { 100, 200, 300, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 400, 500));
+
+ // Removing full regions
+ assertArrayEquals(new long[] { 100, 200 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 300, 400));
+ assertArrayEquals(new long[] { 100, 200 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 250, 450));
+ assertArrayEquals(new long[] { 300, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 50, 250));
+ assertArrayEquals(new long[] { },
+ removeRange(new long[] { 100, 200, 300, 400 }, 0, 5_000_000));
+ }
+
+ @Test
+ public void testRemoveRange_Partial() throws Exception {
+ assertArrayEquals(new long[] { 150, 200, 300, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 50, 150));
+ assertArrayEquals(new long[] { 100, 150, 300, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 150, 250));
+ assertArrayEquals(new long[] { 100, 150, 350, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 150, 350));
+ assertArrayEquals(new long[] { 100, 150 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 150, 500));
+ }
+
+ @Test
+ public void testRemoveRange_Hole() throws Exception {
+ assertArrayEquals(new long[] { 100, 125, 175, 200, 300, 400 },
+ removeRange(new long[] { 100, 200, 300, 400 }, 125, 175));
+ assertArrayEquals(new long[] { 100, 200 },
+ removeRange(new long[] { 100, 200 }, 150, 150));
+ }
}
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
new file mode 100644
index 0000000..ed80cd7
--- /dev/null
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.view;
+
+import static android.view.InsetsState.TYPE_TOP_BAR;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNull;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+@RunWith(AndroidJUnit4.class)
+public class InsetsControllerTest {
+
+ private InsetsController mController = new InsetsController();
+
+ private SurfaceSession mSession = new SurfaceSession();
+ private SurfaceControl mLeash;
+
+ @Before
+ public void setup() {
+ mLeash = new SurfaceControl.Builder(mSession)
+ .setName("testSurface")
+ .build();
+ }
+
+ @Test
+ public void testControlsChanged() {
+ InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+ mController.onControlsChanged(new InsetsSourceControl[] { control });
+ assertEquals(mLeash,
+ mController.getSourceConsumer(TYPE_TOP_BAR).getControl().getLeash());
+ }
+
+ @Test
+ public void testControlsRevoked() {
+ InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+ mController.onControlsChanged(new InsetsSourceControl[] { control });
+ mController.onControlsChanged(new InsetsSourceControl[0]);
+ assertNull(mController.getSourceConsumer(TYPE_TOP_BAR).getControl());
+ }
+}
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
new file mode 100644
index 0000000..5a20ba2
--- /dev/null
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.view;
+
+import static android.view.InsetsState.TYPE_TOP_BAR;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.FlakyTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl.Transaction;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@Presubmit
+@FlakyTest(detail = "Promote once confirmed non-flaky")
+@RunWith(AndroidJUnit4.class)
+public class InsetsSourceConsumerTest {
+
+ private InsetsSourceConsumer mConsumer;
+
+ private SurfaceSession mSession = new SurfaceSession();
+ private SurfaceControl mLeash;
+ @Mock Transaction mMockTransaction;
+ @Mock InsetsController mMockController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mLeash = new SurfaceControl.Builder(mSession)
+ .setName("testSurface")
+ .build();
+ mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(),
+ () -> mMockTransaction);
+ mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+ }
+
+ @Test
+ public void testHide() {
+ mConsumer.hide();
+ verify(mMockTransaction).hide(eq(mLeash));
+ }
+
+ @Test
+ public void testShow() {
+ mConsumer.hide();
+ mConsumer.show();
+ verify(mMockTransaction, atLeastOnce()).show(eq(mLeash));
+ }
+
+ @Test
+ public void testRestore() {
+ mConsumer.setControl(null);
+ reset(mMockTransaction);
+ mConsumer.hide();
+ verifyZeroInteractions(mMockTransaction);
+ mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+ verify(mMockTransaction).hide(eq(mLeash));
+ }
+}
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index bf114b9..2227cf5 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -1779,6 +1779,36 @@
}
/**
+ * <p>Computes the chromaticity coordinates of a CIE series D illuminant
+ * from the specified correlated color temperature (CCT). The specified CCT
+ * must be greater than 0. A meaningful CCT range is [4000, 25000].</p>
+ *
+ * <p>The transform is computed using the methods referred to in Kang et
+ * al., <i>Design of Advanced Color - Temperature Control System for HDTV
+ * Applications</i>, Journal of Korean Physical Society 41, 865-871
+ * (2002).</p>
+ *
+ * @param cct The correlated color temperature, in Kelvin
+ * @return Corresponding XYZ values
+ * @throws IllegalArgumentException If cct is invalid
+ */
+ @NonNull
+ @Size(3)
+ public static float[] cctToIlluminantdXyz(@IntRange(from = 1) int cct) {
+ if (cct < 1) {
+ throw new IllegalArgumentException("Temperature must be greater than 0");
+ }
+
+ final float icct = 1.0f / cct;
+ final float icct2 = icct * icct;
+ final float x = cct <= 7000.0f ?
+ 0.244063f + 0.09911e3f * icct + 2.9678e6f * icct2 - 4.6070e9f * icct2 * icct :
+ 0.237040f + 0.24748e3f * icct + 1.9018e6f * icct2 - 2.0064e9f * icct2 * icct;
+ final float y = -3.0f * x * x + 2.87f * x - 0.275f;
+ return xyYToXyz(new float[] {x, y});
+ }
+
+ /**
* <p>Computes the chromatic adaptation transform from the specified
* source white point to the specified destination white point.</p>
*
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index dbe6e8f..9b86b77 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -249,7 +249,22 @@
if (familyBuilder == null) {
return Typeface.DEFAULT;
}
- typeface = new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
+ final FontFamily family = familyBuilder.build();
+ final FontStyle normal = new FontStyle(FontStyle.FONT_WEIGHT_NORMAL,
+ FontStyle.FONT_SLANT_UPRIGHT);
+ Font bestFont = family.getFont(0);
+ int bestScore = normal.getMatchScore(bestFont.getStyle());
+ for (int i = 1; i < family.getSize(); ++i) {
+ final Font candidate = family.getFont(i);
+ final int score = normal.getMatchScore(candidate.getStyle());
+ if (score < bestScore) {
+ bestFont = candidate;
+ bestScore = score;
+ }
+ }
+ typeface = new Typeface.CustomFallbackBuilder(family)
+ .setStyle(bestFont.getStyle())
+ .build();
} catch (IOException e) {
typeface = Typeface.DEFAULT;
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 8740234..991847a 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1571,15 +1571,32 @@
st.mGradient = a.getInt(
R.styleable.GradientDrawableGradient_type, st.mGradient);
- // TODO: Update these to be themeable.
+ final boolean hasGradientColors = st.mGradientColors != null;
+ final boolean hasGradientCenter = st.hasCenterColor();
+ final int prevStart = hasGradientColors ? st.mGradientColors[0] : 0;
+ final int prevCenter = hasGradientCenter ? st.mGradientColors[1] : 0;
+ final int prevEnd;
+
+ if (st.hasCenterColor()) {
+ // if there is a center color, the end color is the last of the 3 values
+ prevEnd = st.mGradientColors[2];
+ } else if (hasGradientColors) {
+ // if there is not a center color but there are already colors configured, then
+ // the end color is the 2nd value in the array
+ prevEnd = st.mGradientColors[1];
+ } else {
+ // otherwise, there isn't a previously configured end color
+ prevEnd = 0;
+ }
+
final int startColor = a.getColor(
- R.styleable.GradientDrawableGradient_startColor, 0);
+ R.styleable.GradientDrawableGradient_startColor, prevStart);
final boolean hasCenterColor = a.hasValue(
- R.styleable.GradientDrawableGradient_centerColor);
+ R.styleable.GradientDrawableGradient_centerColor) || hasGradientCenter;
final int centerColor = a.getColor(
- R.styleable.GradientDrawableGradient_centerColor, 0);
+ R.styleable.GradientDrawableGradient_centerColor, prevCenter);
final int endColor = a.getColor(
- R.styleable.GradientDrawableGradient_endColor, 0);
+ R.styleable.GradientDrawableGradient_endColor, prevEnd);
if (hasCenterColor) {
st.mGradientColors = new int[3];
@@ -1943,6 +1960,10 @@
}
}
+ public boolean hasCenterColor() {
+ return mGradientColors != null && mGradientColors.length == 3;
+ }
+
private void applyDensityScaling(int sourceDensity, int targetDensity) {
if (mInnerRadius > 0) {
mInnerRadius = Drawable.scaleFromDensity(
diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java
index 82fc7ac..af517d6 100644
--- a/graphics/java/android/graphics/fonts/FontStyle.java
+++ b/graphics/java/android/graphics/fonts/FontStyle.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.internal.util.Preconditions;
@@ -232,6 +233,16 @@
return mSlant;
}
+ /**
+ * Compute the matching score for another style.
+ *
+ * The smaller is better.
+ * @hide
+ */
+ public int getMatchScore(@NonNull FontStyle o) {
+ return Math.abs((getWeight() - o.getWeight())) / 100 + (getSlant() == o.getSlant() ? 0 : 2);
+ }
+
@Override
public boolean equals(@Nullable Object o) {
if (o == this) {
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 7ab12b1..ad9ec02 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -217,10 +217,19 @@
ATRACE_NAME("AssetManager::GetResourceConfigurations");
std::set<ResTable_config> configurations;
for (const PackageGroup& package_group : package_groups_) {
+ bool found_system_package = false;
for (const ConfiguredPackage& package : package_group.packages_) {
if (exclude_system && package.loaded_package_->IsSystem()) {
+ found_system_package = true;
continue;
}
+
+ if (exclude_system && package.loaded_package_->IsOverlay() && found_system_package) {
+ // Overlays must appear after the target package to take effect. Any overlay found in the
+ // same package as a system package is able to overlay system resources.
+ continue;
+ }
+
package.loaded_package_->CollectConfigurations(exclude_mipmap, &configurations);
}
}
@@ -232,10 +241,19 @@
ATRACE_NAME("AssetManager::GetResourceLocales");
std::set<std::string> locales;
for (const PackageGroup& package_group : package_groups_) {
+ bool found_system_package = false;
for (const ConfiguredPackage& package : package_group.packages_) {
if (exclude_system && package.loaded_package_->IsSystem()) {
+ found_system_package = true;
continue;
}
+
+ if (exclude_system && package.loaded_package_->IsOverlay() && found_system_package) {
+ // Overlays must appear after the target package to take effect. Any overlay found in the
+ // same package as a system package is able to overlay system resources.
+ continue;
+ }
+
package.loaded_package_->CollectLocales(merge_equivalent_languages, &locales);
}
}
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 4a5b61a..da77b99 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -9,8 +9,6 @@
"hwui_lto",
],
- cpp_std: "c++17",
-
cflags: [
"-DEGL_EGLEXT_PROTOTYPES",
"-DGL_GLEXT_PROTOTYPES",
diff --git a/libs/hwui/CanvasTransform.cpp b/libs/hwui/CanvasTransform.cpp
index 06e937a..0cfaa8c 100644
--- a/libs/hwui/CanvasTransform.cpp
+++ b/libs/hwui/CanvasTransform.cpp
@@ -146,4 +146,4 @@
return shouldInvert;
}
-}; // namespace android::uirenderer
\ No newline at end of file
+} // namespace android::uirenderer
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index a952cc2..dc63e5d 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -31,5 +31,5 @@
*/
using DisplayList = skiapipeline::SkiaDisplayList;
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/FrameMetricsObserver.h b/libs/hwui/FrameMetricsObserver.h
index ba72e93..237fc62 100644
--- a/libs/hwui/FrameMetricsObserver.h
+++ b/libs/hwui/FrameMetricsObserver.h
@@ -26,5 +26,5 @@
virtual void notify(const int64_t* buffer);
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/FrameMetricsReporter.h b/libs/hwui/FrameMetricsReporter.h
index d920a99..75b8038 100644
--- a/libs/hwui/FrameMetricsReporter.h
+++ b/libs/hwui/FrameMetricsReporter.h
@@ -56,5 +56,5 @@
std::vector<sp<FrameMetricsObserver> > mObservers;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/GlFunctorLifecycleListener.h b/libs/hwui/GlFunctorLifecycleListener.h
index 5d07b46..5adc469 100644
--- a/libs/hwui/GlFunctorLifecycleListener.h
+++ b/libs/hwui/GlFunctorLifecycleListener.h
@@ -28,5 +28,5 @@
virtual void onGlFunctorReleased(Functor* functor) = 0;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index 165fc48..a97c12c 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -256,4 +256,4 @@
return sk_sp<Bitmap>(new Bitmap(buffer.get(), bitmap.info(), Bitmap::computePalette(bitmap)));
}
-}; // namespace android::uirenderer
+} // namespace android::uirenderer
diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h
index c0113d8..6298013 100644
--- a/libs/hwui/HardwareBitmapUploader.h
+++ b/libs/hwui/HardwareBitmapUploader.h
@@ -25,4 +25,4 @@
static sk_sp<Bitmap> allocateHardwareBitmap(const SkBitmap& sourceBitmap);
};
-}; // namespace android::uirenderer
+} // namespace android::uirenderer
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index d0df200..a15ff22 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -54,5 +54,5 @@
}
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 98600db..ea3bfc9 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -144,5 +144,5 @@
}; // struct Layer
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/LayerUpdateQueue.h b/libs/hwui/LayerUpdateQueue.h
index 6857999..2c63af6 100644
--- a/libs/hwui/LayerUpdateQueue.h
+++ b/libs/hwui/LayerUpdateQueue.h
@@ -50,7 +50,7 @@
std::vector<Entry> mEntries;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_LAYER_UPDATE_QUEUE_H
diff --git a/libs/hwui/Lighting.h b/libs/hwui/Lighting.h
index d972c21..ccfbb93 100644
--- a/libs/hwui/Lighting.h
+++ b/libs/hwui/Lighting.h
@@ -34,5 +34,5 @@
uint8_t spotShadowAlpha;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index d84ed32..d0dbff03 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -526,5 +526,5 @@
ALOGD("]");
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index 1b5cb60..b33cfe2 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -245,5 +245,5 @@
typedef Matrix4 mat4;
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/NinePatchUtils.h b/libs/hwui/NinePatchUtils.h
index 082e95f..86d3cb9 100644
--- a/libs/hwui/NinePatchUtils.h
+++ b/libs/hwui/NinePatchUtils.h
@@ -103,5 +103,5 @@
}
}
-}; // namespace NinePatchUtils
-}; // namespace android
+} // namespace NinePatchUtils
+} // namespace android
diff --git a/libs/hwui/PathParser.cpp b/libs/hwui/PathParser.cpp
index ad599e9..808921d 100644
--- a/libs/hwui/PathParser.cpp
+++ b/libs/hwui/PathParser.cpp
@@ -304,5 +304,5 @@
return;
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/PathParser.h b/libs/hwui/PathParser.h
index 474eb97..f5bebce 100644
--- a/libs/hwui/PathParser.h
+++ b/libs/hwui/PathParser.h
@@ -46,6 +46,6 @@
static void validateVerbAndPoints(char verb, size_t points, ParseResult* result);
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_PATHPARSER_H
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 3f2c616..4a3e10c 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -223,5 +223,5 @@
sRenderPipelineType = type;
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 542bc71..da53f66 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -289,7 +289,7 @@
static RenderPipelineType sRenderPipelineType;
}; // class Caches
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_PROPERTIES_H
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index f928de9..c63e449 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -1028,5 +1028,5 @@
fDL->drawVectorDrawable(tree);
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 099e0be..08cfc62 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -216,5 +216,5 @@
DisplayListData* fDL;
};
-}; // namespace uirenderer
-}; // namespace android
\ No newline at end of file
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 0715187..d6362ef 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -262,5 +262,5 @@
}
}; // class Rect
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/UvMapper.h b/libs/hwui/UvMapper.h
index b495e33..833ca4a 100644
--- a/libs/hwui/UvMapper.h
+++ b/libs/hwui/UvMapper.h
@@ -124,7 +124,7 @@
float mMaxV;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_UV_MAPPER_H
diff --git a/libs/hwui/Vector.h b/libs/hwui/Vector.h
index d2c15ad..e6eea1c 100644
--- a/libs/hwui/Vector.h
+++ b/libs/hwui/Vector.h
@@ -113,7 +113,7 @@
}
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_VECTOR_H
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 6cf04bf..dd62bbb 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -691,7 +691,7 @@
return BitmapPalette::Unknown;
}
-}; // namespace VectorDrawable
+} // namespace VectorDrawable
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index f091277..28cabb9 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -73,7 +73,7 @@
REQUIRE_COMPATIBLE_LAYOUT(TextureVertex);
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_VERTEX_H
diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h
index 613cf4a..6543a22 100644
--- a/libs/hwui/VertexBuffer.h
+++ b/libs/hwui/VertexBuffer.h
@@ -174,7 +174,7 @@
void (*mCleanupIndexMethod)(void*);
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_VERTEX_BUFFER_H
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index e99742b..a5f21d8 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -76,8 +76,8 @@
namespace uirenderer {
namespace VectorDrawable {
class Tree;
-};
-};
+}
+}
typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
typedef std::function<void(uint16_t* text, float* positions)> ReadGlyphFunc;
@@ -318,4 +318,4 @@
friend class DrawTextOnPathFunctor;
};
-}; // namespace android
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h
index efef6de..bf19655 100644
--- a/libs/hwui/pipeline/skia/AnimatedDrawables.h
+++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h
@@ -79,6 +79,6 @@
sp<uirenderer::CanvasPropertyPaint> mPaint;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
index e4ba13d..2062194 100644
--- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h
+++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
@@ -172,6 +172,6 @@
std::string mIdent;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/FunctorDrawable.h b/libs/hwui/pipeline/skia/FunctorDrawable.h
index 162d137..af3a056 100644
--- a/libs/hwui/pipeline/skia/FunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/FunctorDrawable.h
@@ -48,6 +48,6 @@
const SkRect mBounds;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
index 90d5e71..4a87e75 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.cpp
@@ -216,6 +216,6 @@
}
}
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/GLFunctorDrawable.h b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
index b06f7f0..215979c 100644
--- a/libs/hwui/pipeline/skia/GLFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/GLFunctorDrawable.h
@@ -41,6 +41,6 @@
void onDraw(SkCanvas* canvas) override;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 9b408fb..f08ac17 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -145,6 +145,6 @@
return layerImage != nullptr;
}
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.h b/libs/hwui/pipeline/skia/LayerDrawable.h
index 5c12590..95dc6d0 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.h
+++ b/libs/hwui/pipeline/skia/LayerDrawable.h
@@ -45,6 +45,6 @@
sp<DeferredLayerUpdater> mLayerUpdater;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index d80cb6d..4494cb0 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -332,6 +332,6 @@
}
}
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
index d746978..6ba8e59 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -150,6 +150,6 @@
SkiaDisplayList* mProjectedDisplayList = nullptr;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index dba97fe..0a3c8f4 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -211,6 +211,6 @@
casterAlpha < 1.0f ? SkShadowFlags::kTransparentOccluder_ShadowFlag : 0);
}
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
index 26cfa90..cfc0f9b 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
@@ -74,6 +74,6 @@
StartReorderBarrierDrawable* mStartBarrier;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index 3890513..ac6f6a3 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -141,6 +141,6 @@
mDisplayList.draw(&canvas);
}
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index ac7bb7b..d7879e7 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -36,7 +36,7 @@
namespace VectorDrawable {
class Tree;
-};
+}
typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
namespace skiapipeline {
@@ -179,6 +179,6 @@
SkMatrix mParentMatrix;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index f5de1c8..b682ab0 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -259,6 +259,6 @@
return 0;
}
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 988728d..d6107a9 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -92,6 +92,6 @@
PaintCoW&& filterBitmap(PaintCoW&& paint, sk_sp<SkColorFilter> colorSpaceFilter);
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index a494e49..3607b23 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -122,8 +122,9 @@
mVkSurface = nullptr;
}
+ mSurfaceColorSpace = SkColorSpace::MakeSRGB();
if (surface) {
- mVkSurface = mVkManager.createSurface(surface, colorMode);
+ mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace);
}
if (colorMode == ColorMode::SRGB) {
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
index a594206..004a558 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.cpp
@@ -219,6 +219,6 @@
});
}
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
index 3269cfb..8fe52c5 100644
--- a/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/VkInteropFunctorDrawable.h
@@ -51,6 +51,6 @@
SkImageInfo mFBInfo;
};
-}; // namespace skiapipeline
-}; // namespace uirenderer
-}; // namespace android
+} // namespace skiapipeline
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/private/hwui/DrawGlInfo.h b/libs/hwui/private/hwui/DrawGlInfo.h
index efa9da2..9e1bb8e 100644
--- a/libs/hwui/private/hwui/DrawGlInfo.h
+++ b/libs/hwui/private/hwui/DrawGlInfo.h
@@ -83,7 +83,7 @@
};
}; // struct DrawGlInfo
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_DRAW_GL_INFO_H
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f1a522e..6869972 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -323,25 +323,6 @@
// the deadline for RT animations
info.out.canDrawThisFrame = false;
}
- /* This logic exists to try and recover from a display latch miss, which essentially
- * results in the bufferqueue being double-buffered instead of triple-buffered.
- * SurfaceFlinger itself now tries to handle & recover from this situation, so this
- * logic should no longer be necessary. As it's occasionally triggering when
- * undesired disable it.
- * TODO: Remove this entirely if the results are solid.
- else if (vsyncDelta >= mRenderThread.timeLord().frameIntervalNanos() * 3 ||
- (latestVsync - mLastDropVsync) < 500_ms) {
- // It's been several frame intervals, assume the buffer queue is fine
- // or the last drop was too recent
- info.out.canDrawThisFrame = true;
- } else {
- info.out.canDrawThisFrame = !isSwapChainStuffed();
- if (!info.out.canDrawThisFrame) {
- // dropping frame
- mLastDropVsync = mRenderThread.timeLord().latestVsync();
- }
- }
- */
} else {
info.out.canDrawThisFrame = true;
}
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 6668c58..d9b789f 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -49,7 +49,7 @@
Reset = 1 << 1,
JankStats = 1 << 2,
};
-};
+}
/*
* RenderProxy is strictly single threaded. All methods must be invoked on the owning
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 9a6df75..e1f8307 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -472,8 +472,9 @@
window->query(window, NATIVE_WINDOW_HEIGHT, &windowHeight);
if (windowWidth != surface->mWindowWidth || windowHeight != surface->mWindowHeight) {
ColorMode colorMode = surface->mColorMode;
+ sk_sp<SkColorSpace> colorSpace = surface->mColorSpace;
destroySurface(surface);
- *surfaceOut = createSurface(window, colorMode);
+ *surfaceOut = createSurface(window, colorMode, colorSpace);
surface = *surfaceOut;
}
@@ -647,7 +648,7 @@
imageInfo.mSurface = SkSurface::MakeFromBackendRenderTarget(
mRenderThread.getGrContext(), backendRT, kTopLeft_GrSurfaceOrigin,
surface->mColorMode == ColorMode::WideColorGamut ? kRGBA_F16_SkColorType
- : kRGBA_8888_SkColorType, nullptr, &props);
+ : kRGBA_8888_SkColorType, surface->mColorSpace, &props);
}
SkASSERT(mCommandPool != VK_NULL_HANDLE);
@@ -833,14 +834,15 @@
return true;
}
-VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode) {
+VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode,
+ sk_sp<SkColorSpace> surfaceColorSpace) {
initialize();
if (!window) {
return nullptr;
}
- VulkanSurface* surface = new VulkanSurface(colorMode, window);
+ VulkanSurface* surface = new VulkanSurface(colorMode, window, surfaceColorSpace);
VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo;
memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR));
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 8594a1b..d67d2c8 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -38,8 +38,8 @@
class VulkanSurface {
public:
- VulkanSurface(ColorMode colorMode, ANativeWindow* window)
- : mColorMode(colorMode), mNativeWindow(window) {}
+ VulkanSurface(ColorMode colorMode, ANativeWindow* window, sk_sp<SkColorSpace> colorSpace)
+ : mColorMode(colorMode), mNativeWindow(window), mColorSpace(colorSpace) {}
sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; }
@@ -79,6 +79,7 @@
ANativeWindow* mNativeWindow;
int mWindowWidth = 0;
int mWindowHeight = 0;
+ sk_sp<SkColorSpace> mColorSpace;
};
// This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue,
@@ -96,7 +97,8 @@
// Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new
// VulkanSurface object which is returned.
- VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode);
+ VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode,
+ sk_sp<SkColorSpace> surfaceColorSpace);
// Destroy the VulkanSurface and all associated vulkan objects.
void destroySurface(VulkanSurface* surface);
diff --git a/libs/hwui/surfacetexture/EGLConsumer.cpp b/libs/hwui/surfacetexture/EGLConsumer.cpp
index c8220c6..85b3917 100644
--- a/libs/hwui/surfacetexture/EGLConsumer.cpp
+++ b/libs/hwui/surfacetexture/EGLConsumer.cpp
@@ -672,4 +672,4 @@
return image;
}
-}; // namespace android
+} // namespace android
diff --git a/libs/hwui/surfacetexture/EGLConsumer.h b/libs/hwui/surfacetexture/EGLConsumer.h
index eccb082..7dac3ef 100644
--- a/libs/hwui/surfacetexture/EGLConsumer.h
+++ b/libs/hwui/surfacetexture/EGLConsumer.h
@@ -308,4 +308,4 @@
sp<EglImage> mReleasedTexImage;
};
-}; // namespace android
+} // namespace android
diff --git a/libs/hwui/surfacetexture/ImageConsumer.h b/libs/hwui/surfacetexture/ImageConsumer.h
index 5bab0ef5..f0e55bb 100644
--- a/libs/hwui/surfacetexture/ImageConsumer.h
+++ b/libs/hwui/surfacetexture/ImageConsumer.h
@@ -97,4 +97,4 @@
ImageSlot mImageSlots[BufferQueueDefs::NUM_BUFFER_SLOTS];
};
-}; /* namespace android */
+} /* namespace android */
diff --git a/libs/hwui/surfacetexture/SurfaceTexture.cpp b/libs/hwui/surfacetexture/SurfaceTexture.cpp
index 90f8912..da09444 100644
--- a/libs/hwui/surfacetexture/SurfaceTexture.cpp
+++ b/libs/hwui/surfacetexture/SurfaceTexture.cpp
@@ -491,4 +491,4 @@
return image;
}
-}; // namespace android
+} // namespace android
diff --git a/libs/hwui/surfacetexture/SurfaceTexture.h b/libs/hwui/surfacetexture/SurfaceTexture.h
index 96afd82..b5d136f 100644
--- a/libs/hwui/surfacetexture/SurfaceTexture.h
+++ b/libs/hwui/surfacetexture/SurfaceTexture.h
@@ -449,4 +449,4 @@
};
// ----------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
diff --git a/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
index 217d63f..41714eb 100644
--- a/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
+++ b/libs/hwui/tests/unit/LayerUpdateQueueTests.cpp
@@ -81,5 +81,5 @@
EXPECT_TRUE(queue.entries().empty());
}
-};
-};
+}
+}
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 02f740c..ee6beba 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -406,5 +406,5 @@
EXPECT_TRUE(shader->unique());
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/thread/Barrier.h b/libs/hwui/thread/Barrier.h
index 8faeee6..bb750ca 100644
--- a/libs/hwui/thread/Barrier.h
+++ b/libs/hwui/thread/Barrier.h
@@ -48,7 +48,7 @@
mutable Condition mCondition;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_BARRIER_H
diff --git a/libs/hwui/thread/Future.h b/libs/hwui/thread/Future.h
index 45f3102..df53348e 100644
--- a/libs/hwui/thread/Future.h
+++ b/libs/hwui/thread/Future.h
@@ -53,7 +53,7 @@
T mResult;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_FUTURE_H
diff --git a/libs/hwui/thread/Signal.h b/libs/hwui/thread/Signal.h
index ffcd4b6..6d33ac4 100644
--- a/libs/hwui/thread/Signal.h
+++ b/libs/hwui/thread/Signal.h
@@ -53,7 +53,7 @@
mutable Condition mCondition;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_SIGNAL_H
diff --git a/libs/hwui/thread/Task.h b/libs/hwui/thread/Task.h
index 276a22f..228ce19 100644
--- a/libs/hwui/thread/Task.h
+++ b/libs/hwui/thread/Task.h
@@ -48,7 +48,7 @@
sp<Future<T> > mFuture;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_TASK_H
diff --git a/libs/hwui/thread/TaskManager.cpp b/libs/hwui/thread/TaskManager.cpp
index 54b55e4..26ff6eb 100644
--- a/libs/hwui/thread/TaskManager.cpp
+++ b/libs/hwui/thread/TaskManager.cpp
@@ -129,5 +129,5 @@
mSignal.signal();
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h
index 29b4fcd..c4c1291 100644
--- a/libs/hwui/thread/TaskManager.h
+++ b/libs/hwui/thread/TaskManager.h
@@ -101,7 +101,7 @@
std::vector<sp<WorkerThread> > mThreads;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_TASK_MANAGER_H
diff --git a/libs/hwui/utils/Blur.cpp b/libs/hwui/utils/Blur.cpp
index 1bc5646..763d1aa 100644
--- a/libs/hwui/utils/Blur.cpp
+++ b/libs/hwui/utils/Blur.cpp
@@ -178,5 +178,5 @@
}
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/utils/Blur.h b/libs/hwui/utils/Blur.h
index bec3837..d6b41b8 100644
--- a/libs/hwui/utils/Blur.h
+++ b/libs/hwui/utils/Blur.h
@@ -41,7 +41,7 @@
int32_t width, int32_t height);
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_HWUI_BLUR_H
diff --git a/libs/hwui/utils/Color.cpp b/libs/hwui/utils/Color.cpp
index 3fb6a31..dc347f6 100644
--- a/libs/hwui/utils/Color.cpp
+++ b/libs/hwui/utils/Color.cpp
@@ -221,5 +221,5 @@
static_cast<uint8_t>(rgb.b * 255));
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/utils/FatVector.h b/libs/hwui/utils/FatVector.h
index eafe2f1..8cc4d10 100644
--- a/libs/hwui/utils/FatVector.h
+++ b/libs/hwui/utils/FatVector.h
@@ -99,7 +99,7 @@
typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_FAT_VECTOR_H
diff --git a/libs/hwui/utils/GLUtils.cpp b/libs/hwui/utils/GLUtils.cpp
index fcd036c..c694e93 100644
--- a/libs/hwui/utils/GLUtils.cpp
+++ b/libs/hwui/utils/GLUtils.cpp
@@ -76,5 +76,5 @@
}
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp
index 3e5021c..8baa4b77 100644
--- a/libs/hwui/utils/LinearAllocator.cpp
+++ b/libs/hwui/utils/LinearAllocator.cpp
@@ -249,5 +249,5 @@
ALOGD("%sPages %zu (dedicated %zu)", prefix, mPageCount, mDedicatedPageCount);
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/utils/LinearAllocator.h b/libs/hwui/utils/LinearAllocator.h
index 03f685e..b401fcf 100644
--- a/libs/hwui/utils/LinearAllocator.h
+++ b/libs/hwui/utils/LinearAllocator.h
@@ -201,7 +201,7 @@
: std::vector<T, LinearStdAllocator<T>>(allocator) {}
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif // ANDROID_LINEARALLOCATOR_H
diff --git a/libs/hwui/utils/Pair.h b/libs/hwui/utils/Pair.h
index 4bcd576..76f93cb 100644
--- a/libs/hwui/utils/Pair.h
+++ b/libs/hwui/utils/Pair.h
@@ -36,7 +36,7 @@
inline const S& getSecond() const { return second; }
};
-}; // namespace uirenderer
+} // namespace uirenderer
template <typename F, typename S>
struct trait_trivial_ctor<uirenderer::Pair<F, S> > {
@@ -55,6 +55,6 @@
enum { value = aggregate_traits<F, S>::has_trivial_move };
};
-}; // namespace android
+} // namespace android
#endif // ANDROID_HWUI_PAIR_H
diff --git a/libs/hwui/utils/Result.h b/libs/hwui/utils/Result.h
index 7f33f2e..bd20ba6 100644
--- a/libs/hwui/utils/Result.h
+++ b/libs/hwui/utils/Result.h
@@ -51,4 +51,4 @@
std::variant<R, Error<E>> result;
};
-}; // namespace android::uirenderer
+} // namespace android::uirenderer
diff --git a/libs/hwui/utils/RingBuffer.h b/libs/hwui/utils/RingBuffer.h
index b3e8931..081386a 100644
--- a/libs/hwui/utils/RingBuffer.h
+++ b/libs/hwui/utils/RingBuffer.h
@@ -61,7 +61,7 @@
size_t mCount = 0;
};
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
#endif /* RINGBUFFER_H_ */
diff --git a/libs/hwui/utils/StringUtils.cpp b/libs/hwui/utils/StringUtils.cpp
index 5304b76..304982e 100644
--- a/libs/hwui/utils/StringUtils.cpp
+++ b/libs/hwui/utils/StringUtils.cpp
@@ -34,5 +34,5 @@
return set;
}
-}; // namespace uirenderer
-}; // namespace android
+} // namespace uirenderer
+} // namespace android
diff --git a/libs/hwui/utils/TypeLogic.h b/libs/hwui/utils/TypeLogic.h
index dbdad33..1689cce 100644
--- a/libs/hwui/utils/TypeLogic.h
+++ b/libs/hwui/utils/TypeLogic.h
@@ -37,4 +37,4 @@
template <typename D, typename S> using same_cv = copy_cv<std::remove_cv_t<D>, S>;
template <typename D, typename S> using same_cv_t = typename same_cv<D, S>::type;
-}; // namespace android::uirenderer
\ No newline at end of file
+} // namespace android::uirenderer
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 2a575b6..4b2353c 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -16,16 +16,6 @@
package android.media;
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.List;
-
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
@@ -39,13 +29,21 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.GuardedBy;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
/**
* The AudioRecord class manages the audio resources for Java applications
* to record audio from the audio input hardware of the platform. This is
@@ -1807,6 +1805,8 @@
private native final int native_get_active_microphones(
ArrayList<MicrophoneInfo> activeMicrophones);
+ private native int native_getPortId();
+
//---------------------------------------------------------
// Utility methods
//------------------
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index c226d49..2c4ec3a 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -2620,7 +2620,8 @@
* to the audio sink.
* <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
* queuing as much audio data for playback as possible without blocking.
- * @param timestamp The timestamp of the first decodable audio frame in the provided audioData.
+ * @param timestamp The timestamp, in nanoseconds, of the first decodable audio frame in the
+ * provided audioData.
* @return zero or the positive number of bytes that were written, or one of the following
* error codes.
* <ul>
@@ -3422,6 +3423,8 @@
private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id);
private native final int native_setPresentation(int presentationId, int programId);
+ private native int native_getPortId();
+
//---------------------------------------------------------
// Utility methods
//------------------
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 01a0cb6..32c4643 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -2635,13 +2635,18 @@
if (size == 0) {
return 0;
}
- // We don't allow read positions after the available bytes,
- // the input stream won't be able to seek back then.
- if (position < 0 || position >= in.available()) {
+ if (position < 0) {
return -1;
}
try {
if (mPosition != position) {
+ // We don't allow seek to positions after the available bytes,
+ // the input stream won't be able to seek back then.
+ // However, if we hit an exception before (mPosition set to -1),
+ // let it try the seek in hope it might recover.
+ if (mPosition >= 0 && position >= mPosition + in.available()) {
+ return -1;
+ }
in.seek(position);
mPosition = position;
}
@@ -2649,8 +2654,8 @@
// If the read will cause us to go over the available bytes,
// reduce the size so that we stay in the available range.
// Otherwise the input stream may not be able to seek back.
- if (mPosition + size > in.available()) {
- size = in.available() - (int)mPosition;
+ if (size > in.available()) {
+ size = in.available();
}
int bytesRead = in.read(buffer, offset, size);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 3a64f43..0950a24 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -156,7 +156,8 @@
private static final String NOTIFICATIONS_DIR = "/notifications/";
private static final String ALARMS_DIR = "/alarms/";
private static final String MUSIC_DIR = "/music/";
- private static final String PODCAST_DIR = "/podcasts/";
+ private static final String PODCASTS_DIR = "/podcasts/";
+ private static final String AUDIOBOOKS_DIR = "/audiobooks/";
public static final String SCANNED_BUILD_PREFS_NAME = "MediaScanBuild";
public static final String LAST_INTERNAL_SCAN_FINGERPRINT = "lastScanFingerprint";
@@ -654,7 +655,7 @@
// rescan for metadata if file was modified since last scan
if (entry != null && (entry.mLastModifiedChanged || scanAlways)) {
if (noMedia) {
- result = endFile(entry, false, false, false, false, false);
+ result = endFile(entry, false, false, false, false, false, false);
} else {
boolean isaudio = MediaFile.isAudioMimeType(mMimeType);
boolean isvideo = MediaFile.isVideoMimeType(mMimeType);
@@ -679,11 +680,13 @@
boolean notifications = mScanSuccess &&
(lowpath.indexOf(NOTIFICATIONS_DIR) > 0);
boolean alarms = mScanSuccess && (lowpath.indexOf(ALARMS_DIR) > 0);
- boolean podcasts = mScanSuccess && (lowpath.indexOf(PODCAST_DIR) > 0);
+ boolean podcasts = mScanSuccess && (lowpath.indexOf(PODCASTS_DIR) > 0);
+ boolean audiobooks = mScanSuccess && (lowpath.indexOf(AUDIOBOOKS_DIR) > 0);
boolean music = mScanSuccess && ((lowpath.indexOf(MUSIC_DIR) > 0) ||
- (!ringtones && !notifications && !alarms && !podcasts));
+ (!ringtones && !notifications && !alarms && !podcasts && !audiobooks));
- result = endFile(entry, ringtones, notifications, alarms, music, podcasts);
+ result = endFile(entry, ringtones, notifications, alarms, podcasts,
+ audiobooks, music);
}
}
} catch (RemoteException e) {
@@ -957,7 +960,7 @@
@UnsupportedAppUsage
private Uri endFile(FileEntry entry, boolean ringtones, boolean notifications,
- boolean alarms, boolean music, boolean podcasts)
+ boolean alarms, boolean podcasts, boolean audiobooks, boolean music)
throws RemoteException {
// update database
@@ -1003,6 +1006,7 @@
values.put(Audio.Media.IS_ALARM, alarms);
values.put(Audio.Media.IS_MUSIC, music);
values.put(Audio.Media.IS_PODCAST, podcasts);
+ values.put(Audio.Media.IS_AUDIOBOOK, audiobooks);
} else if (MediaFile.isExifMimeType(mMimeType) && !mNoMedia) {
ExifInterface exif = null;
try {
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index a7bdf4f..89a509f 100644
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -18,11 +18,12 @@
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
-import android.util.Log;
-import java.lang.ref.WeakReference;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
/**
* The Visualizer class enables application to retrieve part of the currently playing audio for
@@ -455,7 +456,7 @@
* <li> Rfk, Ifk are respectively the real and imaginary parts of the kth frequency
* component</li>
* <li> If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is:
- * (k*Fs)/(n/2) </li>
+ * k * Fs / n </li>
* </ul>
* <table border="0" cellspacing="0" cellpadding="0">
* <tr><td>Index </p></td>
@@ -476,9 +477,23 @@
* <td>Rf2 </p></td>
* <td>If2 </p></td>
* <td>... </p></td>
- * <td>Rf(n-1)/2 </p></td>
- * <td>If(n-1)/2 </p></td></tr>
+ * <td>Rf(n/2-1) </p></td>
+ * <td>If(n/2-1) </p></td></tr>
* </table>
+ * <p>In order to obtain magnitude and phase values the following code can
+ * be used:
+ * <pre class="prettyprint">
+ * int n = fft.size();
+ * float[] magnitudes = new float[n / 2 + 1];
+ * float[] phases = new float[n / 2 + 1];
+ * magnitudes[0] = (float)Math.abs(fft[0]); // DC
+ * magnitudes[n / 2] = (float)Math.abs(fft[1]); // Nyquist
+ * phases[0] = phases[n / 2] = 0;
+ * for (int k = 1; k < n / 2; k++) {
+ * int i = k * 2;
+ * magnitudes[k] = (float)Math.hypot(fft[i], fft[i + 1]);
+ * phases[k] = (float)Math.atan2(fft[i + 1], fft[i]);
+ * }</pre>
* @param fft array of bytes where the FFT should be returned
* @return {@link #SUCCESS} in case of success,
* {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
@@ -561,25 +576,11 @@
* <p>Data in the fft buffer is valid only within the scope of the callback.
* Applications which need access to the fft data after returning from the callback
* should make a copy of the data instead of holding a reference.
+ * <p>For the explanation of the fft data array layout, and the example
+ * code for processing it, please see the documentation for {@link #getFft(byte[])} method.
*
- * <p>In order to obtain magnitude and phase values the following formulas can
- * be used:
- * <pre class="prettyprint">
- * for (int i = 0; i < fft.size(); i += 2) {
- * float magnitude = (float)Math.hypot(fft[i], fft[i + 1]);
- * float phase = (float)Math.atan2(fft[i + 1], fft[i]);
- * }</pre>
* @param visualizer Visualizer object on which the listener is registered.
* @param fft array of bytes containing the frequency representation.
- * The fft array only contains the first half of the actual
- * FFT spectrum (frequencies up to Nyquist frequency), exploiting
- * the symmetry of the spectrum. For each frequencies bin <code>i</code>:
- * <ul>
- * <li>the element at index <code>2*i</code> in the array contains
- * the real part of a complex number,</li>
- * <li>the element at index <code>2*i+1</code> contains the imaginary
- * part of the complex number.</li>
- * </ul>
* @param samplingRate sampling rate of the visualized audio.
*/
void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate);
diff --git a/packages/CarSystemUI/res/xml/car_volume_items.xml b/packages/CarSystemUI/res/xml/car_volume_items.xml
index 8715946..922b1a7 100644
--- a/packages/CarSystemUI/res/xml/car_volume_items.xml
+++ b/packages/CarSystemUI/res/xml/car_volume_items.xml
@@ -23,8 +23,8 @@
car:icon="@drawable/car_ic_music"/>
<item car:usage="media"
car:icon="@drawable/car_ic_music"/>
- <item car:usage="voice_communication"
- car:icon="@*android:drawable/ic_audio_ring_notif"/>
+ <item car:usage="assistance_navigation_guidance"
+ car:icon="@drawable/car_ic_navigation"/>
<item car:usage="voice_communication_signalling"
car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="alarm"
@@ -43,8 +43,8 @@
car:icon="@drawable/car_ic_notification"/>
<item car:usage="assistance_accessibility"
car:icon="@drawable/car_ic_notification"/>
- <item car:usage="assistance_navigation_guidance"
- car:icon="@drawable/car_ic_navigation"/>
+ <item car:usage="voice_communication"
+ car:icon="@*android:drawable/ic_audio_ring_notif"/>
<item car:usage="assistance_sonification"
car:icon="@drawable/car_ic_notification"/>
<item car:usage="game"
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index b2fc417..892267b 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -48,7 +48,7 @@
| Notification.FLAG_NO_CLEAR;
private static final int MAX_ACTION_EXTRACTION_TEXT_LENGTH = 400;
private static final int MAX_ACTIONS_PER_LINK = 1;
- private static final int MAX_SMART_ACTIONS = Notification.MAX_ACTION_BUTTONS;
+ private static final int MAX_SMART_ACTIONS = 3;
private static final int MAX_SUGGESTED_REPLIES = 3;
private static final ConversationActions.TypeConfig TYPE_CONFIG =
@@ -81,12 +81,9 @@
if (tcm == null) {
return EMPTY_ACTION_LIST;
}
- Notification.Action[] actions = entry.getNotification().actions;
- int numOfExistingActions = actions == null ? 0: actions.length;
- int maxSmartActions = MAX_SMART_ACTIONS - numOfExistingActions;
return suggestActionsFromText(
tcm,
- getMostSalientActionText(entry.getNotification()), maxSmartActions);
+ getMostSalientActionText(entry.getNotification()), MAX_SMART_ACTIONS);
}
ArrayList<CharSequence> suggestReplies(
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 91e23dd..03eafc4 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -34,15 +34,23 @@
<uses-permission android:name="com.android.printspooler.permission.ACCESS_ALL_PRINT_JOBS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY"/>
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PRINT_SERVICES" />
<uses-permission android:name="android.permission.READ_PRINT_SERVICE_RECOMMENDATIONS" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
+ android:dataSentOffDevice="no"
+ android:dataSharedWithThirdParty="no"
+ android:dataUsedForMonetization="no"
+ android:dataRetentionTime="unlimited"/>
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
+ android:dataSentOffDevice="no"
+ android:dataSharedWithThirdParty="no"
+ android:dataUsedForMonetization="no"
+ android:dataRetentionTime="unlimited"/>
+
<application
android:allowClearUserData="true"
android:label="@string/app_label"
- android:allowBackup= "false"
android:supportsRtl="true">
<service
diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml
index 0ccf13e..9e16f5e 100644
--- a/packages/PrintSpooler/res/layout/print_activity.xml
+++ b/packages/PrintSpooler/res/layout/print_activity.xml
@@ -107,7 +107,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="16dip"
android:elevation="@dimen/preview_controls_elevation"
- android:tint="?android:attr/textColorPrimaryInverse"
+ android:tint="@android:color/white"
android:background="@drawable/print_button">
</ImageButton>
diff --git a/packages/SettingsLib/res/layout/preference_checkable_two_target.xml b/packages/SettingsLib/res/layout/preference_checkable_two_target.xml
new file mode 100644
index 0000000..1a47afc
--- /dev/null
+++ b/packages/SettingsLib/res/layout/preference_checkable_two_target.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<!-- Based off preference_material_settings.xml except that ripple on only on the left side. -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeightSmall"
+ android:gravity="center_vertical"
+ android:background="@android:color/transparent"
+ android:clipToPadding="false">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:gravity="start|center_vertical"
+ android:clipToPadding="false"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd">
+
+ <LinearLayout
+ android:id="@+id/checkbox_container"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="start|center_vertical"
+ android:minWidth="56dp"
+ android:orientation="horizontal"
+ android:clipToPadding="false"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp">
+ <include layout="@layout/preference_widget_checkbox" />
+ </LinearLayout>
+
+ <RelativeLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp">
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:ellipsize="marquee" />
+
+ <TextView
+ android:id="@android:id/summary"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@android:id/title"
+ android:layout_alignStart="@android:id/title"
+ android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+ android:textColor="?android:attr/textColorSecondary"
+ android:maxLines="10" />
+
+ </RelativeLayout>
+
+ </LinearLayout>
+
+ <include layout="@layout/preference_two_target_divider" />
+
+ <!-- Preference should place its actual preference widget here. -->
+ <LinearLayout
+ android:id="@android:id/widget_frame"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:minWidth="64dp"
+ android:gravity="center"
+ android:orientation="vertical" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 92fd868..12b8efb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -53,6 +53,8 @@
"com.android.settings.category.ia.night_display";
public static final String CATEGORY_PRIVACY =
"com.android.settings.category.ia.privacy";
+ public static final String CATEGORY_ENTERPRISE_PRIVACY =
+ "com.android.settings.category.ia.enterprise_privacy";
public static final Map<String, String> KEY_COMPAT_MAP;
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
deleted file mode 100644
index e9c5238..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/ChartDataLoaderCompat.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.net;
-
-import static android.net.NetworkStats.SET_DEFAULT;
-import static android.net.NetworkStats.SET_FOREGROUND;
-import static android.net.NetworkStats.TAG_NONE;
-import static android.net.NetworkStatsHistory.FIELD_RX_BYTES;
-import static android.net.NetworkStatsHistory.FIELD_TX_BYTES;
-import static android.text.format.DateUtils.HOUR_IN_MILLIS;
-
-import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStatsHistory;
-import android.net.NetworkTemplate;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-import com.android.settingslib.AppItem;
-
-/**
- * Loader for historical chart data for both network and UID details.
- *
- * Deprecated in favor of {@link NetworkCycleChartDataLoader} and
- * {@link NetworkCycleDataForUidLoader}
- *
- * @deprecated
- */
-@Deprecated
-public class ChartDataLoaderCompat extends AsyncTaskLoader<ChartData> {
- private static final String KEY_TEMPLATE = "template";
- private static final String KEY_APP = "app";
- private static final String KEY_FIELDS = "fields";
-
- private final INetworkStatsSession mSession;
- private final Bundle mArgs;
-
- public static Bundle buildArgs(NetworkTemplate template, AppItem app) {
- return buildArgs(template, app, FIELD_RX_BYTES | FIELD_TX_BYTES);
- }
-
- public static Bundle buildArgs(NetworkTemplate template, AppItem app, int fields) {
- final Bundle args = new Bundle();
- args.putParcelable(KEY_TEMPLATE, template);
- args.putParcelable(KEY_APP, app);
- args.putInt(KEY_FIELDS, fields);
- return args;
- }
-
- public ChartDataLoaderCompat(Context context, INetworkStatsSession session, Bundle args) {
- super(context);
- mSession = session;
- mArgs = args;
- }
-
- @Override
- protected void onStartLoading() {
- super.onStartLoading();
- forceLoad();
- }
-
- @Override
- public ChartData loadInBackground() {
- final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
- final AppItem app = mArgs.getParcelable(KEY_APP);
- final int fields = mArgs.getInt(KEY_FIELDS);
-
- try {
- return loadInBackground(template, app, fields);
- } catch (RemoteException e) {
- // since we can't do much without history, and we don't want to
- // leave with half-baked UI, we bail hard.
- throw new RuntimeException("problem reading network stats", e);
- }
- }
-
- private ChartData loadInBackground(NetworkTemplate template, AppItem app, int fields)
- throws RemoteException {
- final ChartData data = new ChartData();
- data.network = mSession.getHistoryForNetwork(template, fields);
-
- if (app != null) {
- // load stats for current uid and template
- final int size = app.uids.size();
- for (int i = 0; i < size; i++) {
- final int uid = app.uids.keyAt(i);
- data.detailDefault = collectHistoryForUid(
- template, uid, SET_DEFAULT, data.detailDefault);
- data.detailForeground = collectHistoryForUid(
- template, uid, SET_FOREGROUND, data.detailForeground);
- }
-
- if (size > 0) {
- data.detail = new NetworkStatsHistory(data.detailForeground.getBucketDuration());
- data.detail.recordEntireHistory(data.detailDefault);
- data.detail.recordEntireHistory(data.detailForeground);
- } else {
- data.detailDefault = new NetworkStatsHistory(HOUR_IN_MILLIS);
- data.detailForeground = new NetworkStatsHistory(HOUR_IN_MILLIS);
- data.detail = new NetworkStatsHistory(HOUR_IN_MILLIS);
- }
- }
-
- return data;
- }
-
- @Override
- protected void onStopLoading() {
- super.onStopLoading();
- cancelLoad();
- }
-
- @Override
- protected void onReset() {
- super.onReset();
- cancelLoad();
- }
-
- /**
- * Collect {@link NetworkStatsHistory} for the requested UID, combining with
- * an existing {@link NetworkStatsHistory} if provided.
- */
- private NetworkStatsHistory collectHistoryForUid(
- NetworkTemplate template, int uid, int set, NetworkStatsHistory existing)
- throws RemoteException {
- final NetworkStatsHistory history = mSession.getHistoryForUid(
- template, uid, set, TAG_NONE, FIELD_RX_BYTES | FIELD_TX_BYTES);
-
- if (existing != null) {
- existing.recordEntireHistory(history);
- return existing;
- } else {
- return history;
- }
- }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index 183d485..180b77e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -32,30 +32,24 @@
import android.net.INetworkStatsSession;
import android.net.NetworkPolicy;
import android.net.NetworkPolicyManager;
-import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
-import android.util.FeatureFlagUtils;
import android.util.Log;
import android.util.Range;
import com.android.internal.R;
-import com.android.internal.annotations.VisibleForTesting;
import java.time.ZonedDateTime;
-import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
public class DataUsageController {
private static final String TAG = "DataUsageController";
- @VisibleForTesting
- static final String DATA_USAGE_V2 = "settings_data_usage_v2";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES;
private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
@@ -95,21 +89,6 @@
* mContext.getResources().getInteger(R.integer.default_data_warning_level_mb);
}
- @VisibleForTesting
- @Deprecated
- INetworkStatsSession getSession() {
- if (mSession == null) {
- try {
- mSession = mStatsService.openSession();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to open stats session", e);
- } catch (RuntimeException e) {
- Log.w(TAG, "Failed to open stats session", e);
- }
- }
- return mSession;
- }
-
public void setCallback(Callback callback) {
mCallback = callback;
}
@@ -149,13 +128,7 @@
end = now;
start = now - DateUtils.WEEK_IN_MILLIS * 4;
}
- final long totalBytes;
- final long callStart = System.currentTimeMillis();
- if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
- totalBytes = getUsageLevel(template, start, end);
- } else {
- totalBytes = getUsageLevel(template, start, end, now);
- }
+ final long totalBytes = getUsageLevel(template, start, end);
if (totalBytes < 0L) {
return warn("no entry data");
}
@@ -185,32 +158,7 @@
* retrieving the data.
*/
public long getHistoricalUsageLevel(NetworkTemplate template) {
- if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
- return getUsageLevel(template, 0L /* start */, System.currentTimeMillis() /* end */);
- } else {
- final long now = System.currentTimeMillis();
- return getUsageLevel(template, 0L /* start */, now /* end */, now);
- }
- }
-
- @Deprecated
- private long getUsageLevel(NetworkTemplate template, long start, long end, long now) {
- final INetworkStatsSession session = getSession();
- if (session != null) {
- try {
- final NetworkStatsHistory history =
- session.getHistoryForNetwork(template, FIELDS);
- final NetworkStatsHistory.Entry entry = history.getValues(
- start, end, System.currentTimeMillis() /* now */, null /* recycle */);
- if (entry != null) {
- return entry.rxBytes + entry.txBytes;
- }
- Log.w(TAG, "Failed to get data usage, no entry data");
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to get data usage, remote call failed");
- }
- }
- return -1L;
+ return getUsageLevel(template, 0L /* start */, System.currentTimeMillis() /* end */);
}
private long getUsageLevel(NetworkTemplate template, long start, long end) {
@@ -241,20 +189,6 @@
return null;
}
- @Deprecated
- private static String historyEntryToString(NetworkStatsHistory.Entry entry) {
- return entry == null ? null : new StringBuilder("Entry[")
- .append("bucketDuration=").append(entry.bucketDuration)
- .append(",bucketStart=").append(entry.bucketStart)
- .append(",activeTime=").append(entry.activeTime)
- .append(",rxBytes=").append(entry.rxBytes)
- .append(",rxPackets=").append(entry.rxPackets)
- .append(",txBytes=").append(entry.txBytes)
- .append(",txPackets=").append(entry.txPackets)
- .append(",operations=").append(entry.operations)
- .append(']').toString();
- }
-
private static String statsBucketToString(Bucket bucket) {
return bucket == null ? null : new StringBuilder("Entry[")
.append("bucketDuration=").append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java b/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java
deleted file mode 100644
index 82bb011..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/net/SummaryForAllUidLoaderCompat.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settingslib.net;
-
-import android.content.Context;
-import android.net.INetworkStatsSession;
-import android.net.NetworkStats;
-import android.net.NetworkTemplate;
-import android.os.Bundle;
-import android.os.RemoteException;
-
-import androidx.loader.content.AsyncTaskLoader;
-
-/**
- * Deprecated in favor of {@link NetworkStatsDetailLoader}
- *
- * @deprecated
- */
-@Deprecated
-public class SummaryForAllUidLoaderCompat extends AsyncTaskLoader<NetworkStats> {
- private static final String KEY_TEMPLATE = "template";
- private static final String KEY_START = "start";
- private static final String KEY_END = "end";
-
- private final INetworkStatsSession mSession;
- private final Bundle mArgs;
-
- public static Bundle buildArgs(NetworkTemplate template, long start, long end) {
- final Bundle args = new Bundle();
- args.putParcelable(KEY_TEMPLATE, template);
- args.putLong(KEY_START, start);
- args.putLong(KEY_END, end);
- return args;
- }
-
- public SummaryForAllUidLoaderCompat(Context context, INetworkStatsSession session,
- Bundle args) {
- super(context);
- mSession = session;
- mArgs = args;
- }
-
- @Override
- protected void onStartLoading() {
- super.onStartLoading();
- forceLoad();
- }
-
- @Override
- public NetworkStats loadInBackground() {
- final NetworkTemplate template = mArgs.getParcelable(KEY_TEMPLATE);
- final long start = mArgs.getLong(KEY_START);
- final long end = mArgs.getLong(KEY_END);
-
- try {
- return mSession.getSummaryForAllUid(template, start, end, false);
- } catch (RemoteException e) {
- return null;
- }
- }
-
- @Override
- protected void onStopLoading() {
- super.onStopLoading();
- cancelLoad();
- }
-
- @Override
- protected void onReset() {
- super.onReset();
- cancelLoad();
- }
-}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index 72ed5e1..acf99a2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -18,7 +18,6 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyLong;
@@ -35,12 +34,10 @@
import android.net.ConnectivityManager;
import android.net.INetworkStatsSession;
import android.net.NetworkStatsHistory;
-import android.net.NetworkStatsHistory.Entry;
import android.net.NetworkTemplate;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.text.format.DateUtils;
-import android.util.FeatureFlagUtils;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +45,6 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class DataUsageControllerTest {
@@ -61,16 +57,18 @@
private TelephonyManager mTelephonyManager;
@Mock
private NetworkStatsManager mNetworkStatsManager;
-
+ @Mock
private Context mContext;
+
private DataUsageController mController;
private NetworkStatsHistory mNetworkStatsHistory;
@Before
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- mController = spy(new DataUsageController(mContext));
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+ when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+ mController = new DataUsageController(mContext);
mNetworkStatsHistory = spy(
new NetworkStatsHistory(DateUtils.DAY_IN_MILLIS /* bucketDuration */));
doReturn(mNetworkStatsHistory)
@@ -79,75 +77,25 @@
}
@Test
- public void getHistoricalUsageLevel_v1_noNetworkSession_shouldReturnNegative1() {
- FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
- doReturn(null).when(mController).getSession();
+ public void getHistoricalUsageLevel_shouldQuerySummaryForDevice() throws Exception {
- assertThat(mController.getHistoricalUsageLevel(null /* template */)).isEqualTo(-1L);
- }
-
- @Test
- public void getHistoriclUsageLevel_v1_noUsageData_shouldReturn0() {
- FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
- doReturn(mSession).when(mController).getSession();
-
- assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
- .isEqualTo(0L);
- }
-
- @Test
- public void getHistoricalUsageLevel_v1_hasUsageData_shouldReturnTotalUsage() {
- FeatureFlagUtils.setEnabled(mContext, DataUsageController.DATA_USAGE_V2, false);
- doReturn(mSession).when(mController).getSession();
- final long receivedBytes = 743823454L;
- final long transmittedBytes = 16574289L;
- final Entry entry = new Entry();
- entry.bucketStart = 1521583200000L;
- entry.rxBytes = receivedBytes;
- entry.txBytes = transmittedBytes;
- when(mNetworkStatsHistory.getValues(eq(0L), anyLong(), anyLong(), nullable(Entry.class)))
- .thenReturn(entry);
-
- assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
- .isEqualTo(receivedBytes + transmittedBytes);
- }
-
- @Test
- public void getHistoricalUsageLevel_v2_shouldQuerySummaryForDevice() throws Exception {
- final Context context = mock(Context.class);
- FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
- when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
- when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
- final DataUsageController controller = new DataUsageController(context);
-
- controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
+ mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
verify(mNetworkStatsManager).querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */);
}
@Test
- public void getHistoricalUsageLevel_v2NoUsageData_shouldReturn0() throws Exception {
- final Context context = mock(Context.class);
- FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
- when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
- when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+ public void getHistoricalUsageLevel_noUsageData_shouldReturn0() throws Exception {
when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */))
.thenReturn(mock(NetworkStats.Bucket.class));
- final DataUsageController controller = new DataUsageController(context);
-
- assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+ assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
.isEqualTo(0L);
}
@Test
- public void getHistoricalUsageLevel_v2HasUsageData_shouldReturnTotalUsage()
- throws Exception {
- final Context context = mock(Context.class);
- FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
- when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
- when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+ public void getHistoricalUsageLevel_hasUsageData_shouldReturnTotalUsage() throws Exception {
final long receivedBytes = 743823454L;
final long transmittedBytes = 16574289L;
final NetworkStats.Bucket bucket = mock(NetworkStats.Bucket.class);
@@ -155,9 +103,8 @@
when(bucket.getTxBytes()).thenReturn(transmittedBytes);
when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */)).thenReturn(bucket);
- final DataUsageController controller = new DataUsageController(context);
- assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+ assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
.isEqualTo(receivedBytes + transmittedBytes);
}
}
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
deleted file mode 100644
index 3cc98d8..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_1.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="500"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M 0,0 c 31.33333,0 156.66667,0 188,0 "
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
deleted file mode 100644
index eda843d..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="33"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M -12,18 L -12,18" />
- <objectAnimator
- android:duration="500"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M -12,18 c 31.33333,0 156.66667,0 188,0 "
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
deleted file mode 100644
index cab3d5c..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_3.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="67"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M -24,36 L -24,36" />
- <objectAnimator
- android:duration="500"
- android:propertyXName="translateX"
- android:propertyYName="translateY"
- android:pathData="M -24,36 c 31.33333,0 156.66667,0 188,0 "
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
deleted file mode 100644
index e435d9a..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="150"
- android:propertyName="fillAlpha"
- android:valueFrom="1"
- android:valueTo="1"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="100"
- android:propertyName="fillAlpha"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
deleted file mode 100644
index e31a7db..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_1.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="183"
- android:propertyName="fillAlpha"
- android:valueFrom="1"
- android:valueTo="1"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="100"
- android:propertyName="fillAlpha"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml b/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
deleted file mode 100644
index 2409612..0000000
--- a/packages/SystemUI/res/anim/dismiss_all_shape_animation_rectangle_path_1_2.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<!-- Copyright (C) 2014 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="217"
- android:propertyName="fillAlpha"
- android:valueFrom="1"
- android:valueTo="1"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="100"
- android:propertyName="fillAlpha"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/fab_elevation.xml b/packages/SystemUI/res/anim/fab_elevation.xml
deleted file mode 100644
index 2c76a86..0000000
--- a/packages/SystemUI/res/anim/fab_elevation.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="true" android:state_pressed="true">
- <set>
- <objectAnimator
- android:duration="@android:integer/config_shortAnimTime"
- android:propertyName="translationZ"
- android:valueTo="@dimen/fab_press_translation_z"
- android:valueType="floatType" />
- </set>
- </item>
- <item>
- <set>
- <objectAnimator
- android:duration="@android:integer/config_shortAnimTime"
- android:propertyName="translationZ"
- android:valueTo="0"
- android:valueType="floatType" />
- </set>
- </item>
-</selector>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
deleted file mode 100644
index 8fdad80..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="616"
- android:propertyName="rotation"
- android:valueFrom="-90.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
deleted file mode 100644
index 3c3c131..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="50"
- android:propertyName="fillAlpha"
- android:valueFrom="0.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="83"
- android:propertyName="fillAlpha"
- android:valueFrom="0.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml b/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
deleted file mode 100644
index 57132e1..0000000
--- a/packages/SystemUI/res/anim/ic_landscape_to_rotate_landscape_animation.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="466"
- android:propertyName="scaleX"
- android:valueFrom="1.0"
- android:valueTo="0.909"
- android:valueType="floatType"
- android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
- <objectAnimator
- android:duration="466"
- android:propertyName="scaleY"
- android:valueFrom="1.0"
- android:valueTo="0.909"
- android:valueType="floatType"
- android:interpolator="@interpolator/ic_landscape_to_rotate_animation_interpolator_0" />
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="50"
- android:propertyName="rotation"
- android:valueFrom="0.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="400"
- android:propertyName="rotation"
- android:valueFrom="0.0"
- android:valueTo="45.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
deleted file mode 100644
index ad2a5fa..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_0_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="116"
- android:propertyName="scaleX"
- android:valueFrom="1.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="333"
- android:propertyName="scaleX"
- android:valueFrom="1.0"
- android:valueTo="0.9"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="116"
- android:propertyName="scaleY"
- android:valueFrom="1.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="333"
- android:propertyName="scaleY"
- android:valueFrom="1.0"
- android:valueTo="0.9"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
deleted file mode 100644
index cdb7890..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="616"
- android:propertyName="rotation"
- android:valueFrom="0.0"
- android:valueTo="-221.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
deleted file mode 100644
index 46100b4..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="400"
- android:propertyName="fillAlpha"
- android:valueFrom="1.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="83"
- android:propertyName="fillAlpha"
- android:valueFrom="1.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
deleted file mode 100644
index 8f6d24d..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_0_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="400"
- android:propertyName="rotation"
- android:valueFrom="0.0"
- android:valueTo="-135.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
deleted file mode 100644
index 300ed53..0000000
--- a/packages/SystemUI/res/anim/ic_portrait_to_rotate_device_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="66"
- android:propertyName="pathData"
- android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
- android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
- android:valueType="pathType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="216"
- android:propertyName="pathData"
- android:valueFrom="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
- android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
- android:valueType="pathType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
deleted file mode 100644
index ad2a5fa..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_0_animation.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="116"
- android:propertyName="scaleX"
- android:valueFrom="1.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="333"
- android:propertyName="scaleX"
- android:valueFrom="1.0"
- android:valueTo="0.9"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="116"
- android:propertyName="scaleY"
- android:valueFrom="1.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="333"
- android:propertyName="scaleY"
- android:valueFrom="1.0"
- android:valueTo="0.9"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
deleted file mode 100644
index c152152..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="616"
- android:propertyName="rotation"
- android:valueFrom="0.0"
- android:valueTo="-180.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
deleted file mode 100644
index b2c1eb8..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="200"
- android:propertyName="fillAlpha"
- android:valueFrom="1.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="83"
- android:propertyName="fillAlpha"
- android:valueFrom="1.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
deleted file mode 100644
index 2a9bbe3..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_landscape_landscape_animation.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="116"
- android:propertyName="scaleX"
- android:valueFrom="0.909"
- android:valueTo="0.909"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="166"
- android:propertyName="scaleX"
- android:valueFrom="0.909"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
- </set>
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="116"
- android:propertyName="scaleY"
- android:valueFrom="0.909"
- android:valueTo="0.909"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="166"
- android:propertyName="scaleY"
- android:valueFrom="0.909"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@interpolator/ic_rotate_to_landscape_animation_interpolator_0" />
- </set>
- <objectAnimator
- android:duration="616"
- android:propertyName="rotation"
- android:valueFrom="45.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
deleted file mode 100644
index ce26770..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_0_animation.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="466"
- android:propertyName="scaleX"
- android:valueFrom="0.9"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
- <objectAnimator
- android:duration="466"
- android:propertyName="scaleY"
- android:valueFrom="0.9"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@interpolator/ic_rotate_to_portrait_animation_interpolator_0" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
deleted file mode 100644
index 6e8941d..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_arrows_animation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <objectAnimator
- android:duration="616"
- android:propertyName="rotation"
- android:valueFrom="-221.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
deleted file mode 100644
index 3c3c131..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_bottom_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="50"
- android:propertyName="fillAlpha"
- android:valueFrom="0.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="83"
- android:propertyName="fillAlpha"
- android:valueFrom="0.0"
- android:valueTo="1.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
deleted file mode 100644
index fd8e4f8..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_0_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="50"
- android:propertyName="rotation"
- android:valueFrom="-135.0"
- android:valueTo="-135.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="400"
- android:propertyName="rotation"
- android:valueFrom="-135.0"
- android:valueTo="0.0"
- android:valueType="floatType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml b/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
deleted file mode 100644
index a77a536..0000000
--- a/packages/SystemUI/res/anim/ic_rotate_to_portrait_device_merged_animation.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<set
- xmlns:android="http://schemas.android.com/apk/res/android" >
- <set
- android:ordering="sequentially" >
- <objectAnimator
- android:duration="50"
- android:propertyName="pathData"
- android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
- android:valueTo="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
- android:valueType="pathType"
- android:interpolator="@android:interpolator/linear" />
- <objectAnimator
- android:duration="500"
- android:propertyName="pathData"
- android:valueFrom="M -3.34053039551,-22.9980926514 c -1.3207244873,-1.3207244873 -3.46876525879,-1.26383972168 -4.74829101563,0.125762939453 c 0.0,0.0 -14.8512420654,14.7411804199 -14.8512420654,14.7411804199 c -1.39259338379,1.392578125 -1.44947814941,3.54061889648 -0.125762939453,4.74827575684 c 0.0,0.0 26.4143981934,26.4144134521 26.4143981934,26.4144134521 c 1.3207244873,1.3207244873 3.46876525879,1.26382446289 4.74829101562,-0.125762939453 c 0.0,0.0 14.7381896973,-14.7381896973 14.7381896973,-14.7381896973 c 1.392578125,-1.39259338379 1.44947814941,-3.54061889648 0.125762939453,-4.74829101562 c 0.0,0.0 -26.3013458252,-26.417388916 -26.3013458252,-26.417388916 Z M 2.87156677246,16.9857940674 c 0.0,0.0 -19.7573547363,-19.7573699951 -19.7573547363,-19.7573699951 c 0.0,0.0 14.0142059326,-14.2142181396 14.0142059326,-14.2142181396 c 0.0,0.0 19.7573699951,19.7573699951 19.7573699951,19.7573699951 c 0.0,0.0 -14.0142211914,14.2142181396 -14.0142211914,14.2142181396 Z"
- android:valueTo="M -3.5,-20.5 c -1.19999694824,-1.19999694824 -3.10000610352,-1.19999694824 -4.19999694824,0.0 c 0.0,0.0 -12.8000030518,12.6999969482 -12.8000030518,12.6999969482 c -1.19999694824,1.19999694824 -1.19999694824,3.10000610352 0.0,4.19999694824 c 0.0,0.0 24.0,24.0000152588 24.0,24.0000152588 c 1.19999694824,1.19999694824 3.10000610352,1.19999694824 4.19999694824,0.0 c 0.0,0.0 12.6999969482,-12.700012207 12.6999969482,-12.700012207 c 1.20001220703,-1.19999694824 1.20001220703,-3.09999084473 0.0,-4.19999694824 c 0.0,0.0 -23.8999938965,-24.0 -23.8999938965,-24.0 Z M 2.84999084473,15.5500183105 c 0.0,0.0 -18.6000061035,-18.5000457764 -18.6000061035,-18.5000457764 c 0.0,0.0 12.5999908447,-12.8000030518 12.5999908447,-12.8000030518 c 0.0,0.0 18.6000213623,18.5000457764 18.6000213623,18.5000457764 c 0.0,0.0 -12.6000061035,12.8000030518 -12.6000061035,12.8000030518 Z"
- android:valueType="pathType"
- android:interpolator="@android:interpolator/fast_out_slow_in" />
- </set>
-</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_1.xml b/packages/SystemUI/res/anim/ic_signal_blink_1.xml
deleted file mode 100644
index 64580d1..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_1.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/linear_interpolator"
- android:duration="@integer/carrier_network_change_anim_time"
- android:repeatCount="-1">
-
- <propertyValuesHolder
- android:propertyName="fillColor"
- android:valueType="colorType">
- <keyframe
- android:fraction="0.0"
- android:value="?attr/fillColor"/>
- <keyframe
- android:fraction="0.32"
- android:value="?attr/fillColor"/>
- <keyframe
- android:fraction="0.33"
- android:value="?attr/backgroundColor"/>
- <keyframe
- android:fraction="1.0"
- android:value="?attr/backgroundColor"/>
- </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_2.xml b/packages/SystemUI/res/anim/ic_signal_blink_2.xml
deleted file mode 100644
index f055cd07..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_2.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/linear_interpolator"
- android:duration="@integer/carrier_network_change_anim_time"
- android:repeatCount="-1">
-
- <propertyValuesHolder
- android:propertyName="fillColor"
- android:valueType="colorType">
- <keyframe
- android:fraction="0.0"
- android:value="?attr/backgroundColor"/>
- <keyframe
- android:fraction="0.32"
- android:value="?attr/backgroundColor"/>
- <keyframe
- android:fraction="0.33"
- android:value="?attr/fillColor"/>
- <keyframe
- android:fraction="0.66"
- android:value="?attr/fillColor"/>
- <keyframe
- android:fraction="0.67"
- android:value="?attr/backgroundColor"/>
- <keyframe
- android:fraction="1.0"
- android:value="?attr/backgroundColor"/>
- </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/ic_signal_blink_3.xml b/packages/SystemUI/res/anim/ic_signal_blink_3.xml
deleted file mode 100644
index abcd774..0000000
--- a/packages/SystemUI/res/anim/ic_signal_blink_3.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--
- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/linear_interpolator"
- android:duration="@integer/carrier_network_change_anim_time"
- android:repeatCount="-1">
-
- <propertyValuesHolder
- android:propertyName="fillColor"
- android:valueType="colorType">
- <keyframe
- android:fraction="0.0"
- android:value="?attr/backgroundColor"/>
- <keyframe
- android:fraction="0.66"
- android:value="?attr/backgroundColor"/>
- <keyframe
- android:fraction="0.67"
- android:value="?attr/fillColor"/>
- <keyframe
- android:fraction="1.0"
- android:value="?attr/fillColor"/>
- </propertyValuesHolder>
-
-</objectAnimator>
diff --git a/packages/SystemUI/res/anim/system_in.xml b/packages/SystemUI/res/anim/system_in.xml
deleted file mode 100644
index 630fd72..0000000
--- a/packages/SystemUI/res/anim/system_in.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
- android:duration="@android:integer/config_longAnimTime"
- />
-</set>
diff --git a/packages/SystemUI/res/anim/system_out.xml b/packages/SystemUI/res/anim/system_out.xml
deleted file mode 100644
index 4717e47..0000000
--- a/packages/SystemUI/res/anim/system_out.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<set xmlns:android="http://schemas.android.com/apk/res/android"
- >
- <alpha android:toAlpha="0.0" android:fromAlpha="1.0"
- android:duration="@android:integer/config_longAnimTime"
- />
-</set>
diff --git a/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml b/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
deleted file mode 100644
index 9e71cbe..0000000
--- a/packages/SystemUI/res/drawable/dismiss_all_shape_animation.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:drawable="@drawable/dismiss_all_shape" >
- <target
- android:name="3"
- android:animation="@anim/dismiss_all_shape_animation_3" />
- <target
- android:name="rectangle_path_1_2"
- android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1_2" />
- <target
- android:name="2"
- android:animation="@anim/dismiss_all_shape_animation_2" />
- <target
- android:name="rectangle_path_1_1"
- android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1_1" />
- <target
- android:name="1"
- android:animation="@anim/dismiss_all_shape_animation_1" />
- <target
- android:name="rectangle_path_1"
- android:animation="@anim/dismiss_all_shape_animation_rectangle_path_1" />
-</animated-vector>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
index a5e7f04..8821679 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
@@ -33,7 +33,7 @@
* dozing and/or in AOD. The pulse uses the notification's ambient view and pops in briefly
* before automatically dismissing the alert.
*/
-public final class AmbientPulseManager extends AlertingNotificationManager {
+public class AmbientPulseManager extends AlertingNotificationManager {
protected final ArraySet<OnAmbientChangedListener> mListeners = new ArraySet<>();
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index e7b4904..ac4abfc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -225,7 +225,7 @@
}
viewState.hasItemsInStableShelf = lastViewState.inShelf;
viewState.hidden = !mAmbientState.isShadeExpanded()
- || mAmbientState.isQsCustomizerShowing();
+ || mAmbientState.isQsCustomizerShowing() || mAmbientState.isFullyDark();
viewState.maxShelfEnd = maxShelfEnd;
} else {
viewState.hidden = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 1616b6d..70d144e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -952,10 +952,12 @@
// Has a copy of the current UI adjustments.
ArrayMap<String, NotificationUiAdjustment> oldAdjustments = new ArrayMap<>();
+ ArrayMap<String, Integer> oldImportances = new ArrayMap<>();
for (NotificationData.Entry entry : entries) {
NotificationUiAdjustment adjustment =
NotificationUiAdjustment.extractFromNotificationEntry(entry);
oldAdjustments.put(entry.key, adjustment);
+ oldImportances.put(entry.key, entry.importance);
}
// Populate notification entries from the new rankings.
@@ -978,6 +980,11 @@
// Once the RowInflaterTask is done, it will pick up the updated entry, so
// no-op here.
}
+ } else if (oldImportances.containsKey(entry.key)
+ && entry.importance != oldImportances.get(entry.key)) {
+ if (entry.rowExists()) {
+ entry.getRow().onNotificationRankingUpdated();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d4d45ea..63fe04a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -588,6 +588,13 @@
updateRippleAllowed();
}
+ /** Called when the notification's ranking was changed (but nothing else changed). */
+ public void onNotificationRankingUpdated() {
+ if (mMenuRow != null) {
+ mMenuRow.onNotificationUpdated(mStatusBarNotification);
+ }
+ }
+
@VisibleForTesting
void updateShelfIconColor() {
StatusBarIconView expandedIcon = mEntry.expandedIcon;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 948d2a5..50564e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -267,7 +267,9 @@
} else {
mRightMenuItems.add(mInfoItem);
mRightMenuItems.add(mAppOpsItem);
- mRightMenuItems.add(mSnoozeItem);
+ if (!isForeground) {
+ mRightMenuItems.add(mSnoozeItem);
+ }
}
populateMenuViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 626e688..5d640e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -18,6 +18,8 @@
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator
.ExpandAnimationParameters;
+import static com.android.systemui.statusbar.notification.stack.StackStateAnimator
+ .ANIMATION_DURATION_SWIPE;
import static com.android.systemui.statusbar.phone.NotificationIconAreaController.LOW_PRIORITY;
import android.animation.Animator;
@@ -5093,7 +5095,7 @@
if (i == 0) {
endRunnable = animationFinishAction;
}
- dismissViewAnimated(view, endRunnable, totalDelay, 260);
+ dismissViewAnimated(view, endRunnable, totalDelay, ANIMATION_DURATION_SWIPE);
currentDelay = Math.max(50, currentDelay - rowDelayDecrement);
totalDelay += currentDelay;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index fef28cf..d690547 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -44,6 +44,7 @@
public static final int ANIMATION_DURATION_WAKEUP = 500;
public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448;
public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
+ public static final int ANIMATION_DURATION_SWIPE = 260;
public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;
public static final int ANIMATION_DURATION_CLOSE_REMOTE_INPUT = 150;
public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 550;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
index 83067f6..a8d00c4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java
@@ -127,6 +127,15 @@
}
/**
+ * Decide if the controller should not send the current motion event to launcher via
+ * {@link OverviewProxyService}
+ * @return if controller should not proxy
+ */
+ public boolean disableProxyEvents() {
+ return false;
+ }
+
+ /**
* Tell if action is enabled. Compared to {@link #canPerformAction()} this is based on settings
* if the action is disabled for a particular gesture. For example a back action can be enabled
* however if there is nothing to back to then {@link #canPerformAction()} should return false.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
index 74744f1..2b202eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java
@@ -212,6 +212,11 @@
}
@Override
+ public boolean disableProxyEvents() {
+ return true;
+ }
+
+ @Override
protected void onGestureStart(MotionEvent event) {
updateHighlight();
ObjectAnimator trackAnimator = ObjectAnimator.ofPropertyValuesHolder(this,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 43e86d6..2cbf27c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -275,25 +275,21 @@
if (mDragVPositive ? (posV < touchDownV) : (posV > touchDownV)) {
// Swiping up gesture
tryToStartGesture(mGestureActions[ACTION_SWIPE_UP_INDEX],
- false /* alignedWithNavBar */, false /* positiveDirection */,
- event);
+ false /* alignedWithNavBar */, event);
} else {
// Swiping down gesture
tryToStartGesture(mGestureActions[ACTION_SWIPE_DOWN_INDEX],
- false /* alignedWithNavBar */, true /* positiveDirection */,
- event);
+ false /* alignedWithNavBar */, event);
}
} else if (exceededSwipeHorizontalTouchSlop) {
if (mDragHPositive ? (posH < touchDownH) : (posH > touchDownH)) {
// Swiping left (ltr) gesture
tryToStartGesture(mGestureActions[ACTION_SWIPE_LEFT_INDEX],
- true /* alignedWithNavBar */, false /* positiveDirection */,
- event);
+ true /* alignedWithNavBar */, event);
} else {
// Swiping right (ltr) gesture
tryToStartGesture(mGestureActions[ACTION_SWIPE_RIGHT_INDEX],
- true /* alignedWithNavBar */, true /* positiveDirection */,
- event);
+ true /* alignedWithNavBar */, event);
}
}
}
@@ -306,7 +302,6 @@
case MotionEvent.ACTION_UP:
if (mCurrentAction != null) {
mCurrentAction.endGesture();
- mCurrentAction = null;
}
// Return the hit target back to its original position
@@ -329,6 +324,11 @@
if (shouldProxyEvents(action)) {
proxyMotionEvents(event);
}
+
+ // Clear action when gesture and event proxy finishes
+ if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+ mCurrentAction = null;
+ }
return mCurrentAction != null || deadZoneConsumed;
}
@@ -354,8 +354,7 @@
private boolean shouldProxyEvents(int action) {
final boolean actionValid = (mCurrentAction == null
- || (mGestureActions[ACTION_SWIPE_UP_INDEX] != null
- && mGestureActions[ACTION_SWIPE_UP_INDEX].isActive()));
+ || !mCurrentAction.disableProxyEvents());
if (actionValid && !mIsInScreenPinning) {
// Allow down, cancel and up events, move and other events are passed if notifications
// are not showing and disabled gestures (such as long press) are not executed
@@ -455,7 +454,7 @@
}
private void tryToStartGesture(NavigationGestureAction action, boolean alignedWithNavBar,
- boolean positiveDirection, MotionEvent event) {
+ MotionEvent event) {
if (action == null) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index cfd53be..5723948 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -474,8 +474,10 @@
return;
}
WallpaperInfo info = wallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
- final boolean supportsAmbientMode = info != null &&
- info.supportsAmbientMode();
+ final boolean deviceSupportsAodWallpaper = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_dozeSupportsAodWallpaper);
+ final boolean supportsAmbientMode = deviceSupportsAodWallpaper
+ && info != null && info.supportsAmbientMode();
mStatusBarWindowController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 978a72d..53e461d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -49,6 +49,7 @@
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
+import android.view.WindowInsetsController;
import android.widget.FrameLayout;
import com.android.internal.annotations.VisibleForTesting;
@@ -785,6 +786,11 @@
@Override
public void reportActivityRelaunched() {
}
+
+ @Override
+ public WindowInsetsController getInsetsController() {
+ return null;
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 8517d90..c2af95e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -165,7 +165,7 @@
mClockVisibleByUser = bundle.getBoolean(VISIBLE_BY_USER, true);
mShowSeconds = bundle.getBoolean(SHOW_SECONDS, false);
if (bundle.containsKey(VISIBILITY)) {
- setVisibility(bundle.getInt(VISIBILITY));
+ super.setVisibility(bundle.getInt(VISIBILITY));
}
}
@@ -203,6 +203,7 @@
// Make sure we update to the current time
updateClock();
+ updateClockVisibility();
updateShowSeconds();
}
@@ -247,6 +248,15 @@
}
};
+ @Override
+ public void setVisibility(int visibility) {
+ if (visibility == View.VISIBLE && !shouldBeVisible()) {
+ return;
+ }
+
+ super.setVisibility(visibility);
+ }
+
public void setClockVisibleByUser(boolean visible) {
mClockVisibleByUser = visible;
updateClockVisibility();
@@ -257,11 +267,15 @@
updateClockVisibility();
}
+ private boolean shouldBeVisible() {
+ return mClockVisibleByPolicy && mClockVisibleByUser;
+ }
+
private void updateClockVisibility() {
- boolean visible = mClockVisibleByPolicy && mClockVisibleByUser;
+ boolean visible = shouldBeVisible();
Dependency.get(IconLogger.class).onIconVisibility("clock", visible);
int visibility = visible ? View.VISIBLE : View.GONE;
- setVisibility(visibility);
+ super.setVisibility(visibility);
}
final void updateClock() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
index 4177cd1..8fc15b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java
@@ -38,12 +38,12 @@
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import android.content.Context;
import com.android.systemui.R;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.SysuiTestCase;
+import android.content.Context;
import android.content.res.Resources;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -395,6 +395,7 @@
verify(mProxy, times(1)).onQuickScrubStart();
verify(mProxyService, times(1)).notifyQuickScrubStarted();
verify(mNavigationBarView, times(1)).updateSlippery();
+ verify(mProxy, never()).onMotionEvent(moveEvent1);
// Move again for scrub
MotionEvent moveEvent2 = event(MotionEvent.ACTION_MOVE, 200, y);
@@ -402,6 +403,7 @@
assertEquals(action, mController.getCurrentAction());
verify(action, times(1)).onGestureMove(200, y);
verify(mProxy, times(1)).onQuickScrubProgress(1f / 2);
+ verify(mProxy, never()).onMotionEvent(moveEvent2);
// Action up
MotionEvent upEvent = event(MotionEvent.ACTION_UP, 1, y);
@@ -409,6 +411,7 @@
assertNull(mController.getCurrentAction());
verify(action, times(1)).onGestureEnd();
verify(mProxy, times(1)).onQuickScrubEnd();
+ verify(mProxy, never()).onMotionEvent(upEvent);
}
@Test
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index 9aa9d7c..af65759 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -40,9 +40,9 @@
import android.text.format.DateUtils;
import android.util.Slog;
-import com.android.server.AbstractRemoteService;
+import com.android.server.AbstractSinglePendingRequestRemoteService;
-final class RemoteFillService extends AbstractRemoteService {
+final class RemoteFillService extends AbstractSinglePendingRequestRemoteService<RemoteFillService> {
private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
@@ -69,8 +69,8 @@
mCallbacks = callbacks;
}
- @Override
- protected void onConnectedStateChanged(boolean state) {
+ @Override // from AbstractRemoteService
+ protected void handleOnConnectedStateChanged(boolean state) {
if (mAutoFillService == null) {
Slog.w(mTag, "onConnectedStateChanged(): null service");
return;
@@ -82,18 +82,18 @@
}
}
- @Override
+ @Override // from AbstractRemoteService
protected IInterface getServiceInterface(IBinder service) {
mAutoFillService = IAutoFillService.Stub.asInterface(service);
return mAutoFillService;
}
- @Override
+ @Override // from AbstractRemoteService
protected long getTimeoutIdleBindMillis() {
return TIMEOUT_IDLE_BIND_MILLIS;
}
- @Override
+ @Override // from AbstractRemoteService
protected long getRemoteRequestMillis() {
return TIMEOUT_REMOTE_REQUEST_MILLIS;
}
@@ -136,6 +136,19 @@
scheduleRequest(new PendingSaveRequest(request, this));
}
+ private boolean handleResponseCallbackCommon(
+ @NonNull PendingRequest<RemoteFillService> pendingRequest) {
+ if (isDestroyed()) return false;
+
+ if (mPendingRequest == pendingRequest) {
+ mPendingRequest = null;
+ }
+ if (mPendingRequest == null) {
+ scheduleUnbind();
+ }
+ return true;
+ }
+
private void dispatchOnFillRequestSuccess(@NonNull PendingFillRequest pendingRequest,
@Nullable FillResponse response, int requestFlags) {
mHandler.post(() -> {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 8676f7f..4c64507 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -902,7 +902,7 @@
// VultureCallback
@Override
- public void onServiceDied(AbstractRemoteService service) {
+ public void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service) {
Slog.w(TAG, "removing session because service died");
forceRemoveSelfLocked();
}
diff --git a/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java b/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java
new file mode 100644
index 0000000..f532b22
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractMultiplePendingRequestsRemoteService.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Base class representing a remote service that can queue multiple pending requests while not
+ * bound.
+ *
+ * @param <S> the concrete remote service class
+ *
+ * @hide
+ */
+public abstract class AbstractMultiplePendingRequestsRemoteService<
+ S extends AbstractMultiplePendingRequestsRemoteService<S>>
+ extends AbstractRemoteService<S> {
+
+ private final int mInitialCapacity;
+
+ protected ArrayList<PendingRequest<S>> mPendingRequests;
+
+ public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
+ @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
+ @NonNull VultureCallback callback, boolean bindInstantServiceAllowed, boolean verbose,
+ int initialCapacity) {
+ super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
+ verbose);
+ mInitialCapacity = initialCapacity;
+ }
+
+ @Override // from AbstractRemoteService
+ void handlePendingRequests() {
+ if (mPendingRequests != null) {
+ final int size = mPendingRequests.size();
+ if (mVerbose) Slog.v(mTag, "Sending " + size + " pending requests");
+ for (int i = 0; i < size; i++) {
+ mPendingRequests.get(i).run();
+ }
+ mPendingRequests = null;
+ }
+ }
+
+ @Override // from AbstractRemoteService
+ protected void handleOnDestroy() {
+ if (mPendingRequests != null) {
+ final int size = mPendingRequests.size();
+ if (mVerbose) Slog.v(mTag, "Canceling " + size + " pending requests");
+ for (int i = 0; i < size; i++) {
+ mPendingRequests.get(i).cancel();
+ }
+ mPendingRequests = null;
+ }
+ }
+
+ @Override // from AbstractRemoteService
+ public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+ super.dump(prefix, pw);
+
+ pw.append(prefix).append("initialCapacity=").append(String.valueOf(mInitialCapacity))
+ .println();
+ final int size = mPendingRequests == null ? 0 : mPendingRequests.size();
+ pw.append(prefix).append("pendingRequests=").append(String.valueOf(size)).println();
+ }
+
+ @Override // from AbstractRemoteService
+ void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+ if (mPendingRequests == null) {
+ mPendingRequests = new ArrayList<>(mInitialCapacity);
+ }
+ mPendingRequests.add(pendingRequest);
+ if (mVerbose) {
+ Slog.v(mTag, "queued " + mPendingRequests.size() + " requests; last=" + pendingRequest);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/AbstractPerUserSystemService.java b/services/core/java/com/android/server/AbstractPerUserSystemService.java
index 71d261c..001d85f 100644
--- a/services/core/java/com/android/server/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/AbstractPerUserSystemService.java
@@ -108,7 +108,8 @@
* <p>Typically called when the service {@link Settings} property or {@link UserManager}
* restriction changed, which includes the initial creation of the service.
*
- * <p>Subclasses can extend this method to provide extra initialization.
+ * <p>Subclasses can extend this method to provide extra initialization, like clearing up
+ * previous state.
*
* @param disabled whether the service is disabled (due to {@link UserManager} restrictions).
*
diff --git a/services/core/java/com/android/server/AbstractRemoteService.java b/services/core/java/com/android/server/AbstractRemoteService.java
index 0d4cf6b..f636487 100644
--- a/services/core/java/com/android/server/AbstractRemoteService.java
+++ b/services/core/java/com/android/server/AbstractRemoteService.java
@@ -45,13 +45,20 @@
*
* <p>All state of this class is modified on a handler thread.
*
+ * <p><b>NOTE: </b>this class should not be extended directly, you should extend either
+ * {@link AbstractSinglePendingRequestRemoteService} or
+ * {@link AbstractMultiplePendingRequestsRemoteService}.
+ *
* <p>See {@code com.android.server.autofill.RemoteFillService} for a concrete
* (no pun intended) example of how to use it.
*
+ * @param <S> the concrete remote service class
+ *
* @hide
*/
//TODO(b/117779333): improve javadoc above instead of using Autofill as an example
-public abstract class AbstractRemoteService implements DeathRecipient {
+public abstract class AbstractRemoteService<S extends AbstractRemoteService<S>>
+ implements DeathRecipient {
private static final int MSG_UNBIND = 1;
@@ -64,8 +71,6 @@
protected final Handler mHandler;
protected final ComponentName mComponentName;
- protected PendingRequest<? extends AbstractRemoteService> mPendingRequest;
-
private final Context mContext;
private final Intent mIntent;
private final VultureCallback mVultureCallback;
@@ -88,10 +93,11 @@
*
* @param service service that died!
*/
- void onServiceDied(AbstractRemoteService service);
+ void onServiceDied(AbstractRemoteService<? extends AbstractRemoteService<?>> service);
}
- public AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
+ // NOTE: must be package-protected so this class is not extend outside
+ AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
@NonNull ComponentName componentName, int userId, @NonNull VultureCallback callback,
boolean bindInstantServiceAllowed, boolean verbose) {
mContext = context;
@@ -118,12 +124,25 @@
return mDestroyed;
}
+ private void handleOnConnectedStateChangedInternal(boolean connected) {
+ if (connected) {
+ handlePendingRequests();
+ }
+ handleOnConnectedStateChanged(connected);
+ }
+
/**
- * Callback called when the system connected / disconnected to the service.
+ * Handles the pending requests when the connection it bounds to the remote service.
+ */
+ abstract void handlePendingRequests();
+
+ /**
+ * Callback called when the system connected / disconnected to the service and the pending
+ * requests have been handled.
*
* @param state {@code true} when connected, {@code false} when disconnected.
*/
- protected void onConnectedStateChanged(boolean state) {
+ protected void handleOnConnectedStateChanged(boolean state) {
}
/**
@@ -144,14 +163,18 @@
private void handleDestroy() {
if (checkIfDestroyed()) return;
- if (mPendingRequest != null) {
- mPendingRequest.cancel();
- mPendingRequest = null;
- }
- ensureUnbound();
+ handleOnDestroy();
+ handleEnsureUnbound();
mDestroyed = true;
}
+ /**
+ * Clears the state when this object is destroyed.
+ *
+ * <p>Typically used to cancel the pending requests.
+ */
+ protected abstract void handleOnDestroy();
+
@Override // from DeathRecipient
public void binderDied() {
mHandler.sendMessage(obtainMessage(AbstractRemoteService::handleBinderDied, this));
@@ -183,9 +206,7 @@
pw.append(prefix).append(tab).append("destroyed=")
.append(String.valueOf(mDestroyed)).println();
pw.append(prefix).append(tab).append("bound=")
- .append(String.valueOf(isBound())).println();
- pw.append(prefix).append(tab).append("hasPendingRequest=")
- .append(String.valueOf(mPendingRequest != null)).println();
+ .append(String.valueOf(handleIsBound())).println();
pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
pw.append(prefix).append("idleTimeout=")
.append(Long.toString(getTimeoutIdleBindMillis() / 1000)).append("s").println();
@@ -194,7 +215,7 @@
pw.println();
}
- protected void scheduleRequest(PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+ protected void scheduleRequest(@NonNull PendingRequest<S> pendingRequest) {
mHandler.sendMessage(obtainMessage(
AbstractRemoteService::handlePendingRequest, this, pendingRequest));
}
@@ -215,19 +236,20 @@
private void handleUnbind() {
if (checkIfDestroyed()) return;
- ensureUnbound();
+ handleEnsureUnbound();
}
- private void handlePendingRequest(
- PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+ /**
+ * Handles a request, either processing it right now when bound, or saving it to be handled when
+ * bound.
+ */
+ protected final void handlePendingRequest(@NonNull PendingRequest<S> pendingRequest) {
if (checkIfDestroyed() || mCompleted) return;
- if (!isBound()) {
- if (mPendingRequest != null) {
- mPendingRequest.cancel();
- }
- mPendingRequest = pendingRequest;
- ensureBound();
+ if (!handleIsBound()) {
+ if (mVerbose) Slog.v(mTag, "handlePendingRequest(): queuing" + pendingRequest);
+ handlePendingRequestWhileUnBound(pendingRequest);
+ handleEnsureBound();
} else {
if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);
pendingRequest.run();
@@ -237,12 +259,17 @@
}
}
- private boolean isBound() {
+ /**
+ * Defines what to do with a request that arrives while not bound to the service.
+ */
+ abstract void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest);
+
+ private boolean handleIsBound() {
return mServiceInterface != null;
}
- private void ensureBound() {
- if (isBound() || mBinding) return;
+ private void handleEnsureBound() {
+ if (handleIsBound() || mBinding) return;
if (mVerbose) Slog.v(mTag, "ensureBound()");
mBinding = true;
@@ -265,13 +292,13 @@
}
}
- private void ensureUnbound() {
- if (!isBound() && !mBinding) return;
+ private void handleEnsureUnbound() {
+ if (!handleIsBound() && !mBinding) return;
if (mVerbose) Slog.v(mTag, "ensureUnbound()");
mBinding = false;
- if (isBound()) {
- onConnectedStateChanged(false);
+ if (handleIsBound()) {
+ handleOnConnectedStateChangedInternal(false);
if (mServiceInterface != null) {
mServiceInterface.asBinder().unlinkToDeath(this, 0);
mServiceInterface = null;
@@ -283,6 +310,7 @@
private class RemoteServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
+ if (mVerbose) Slog.v(mTag, "onServiceConnected()");
if (mDestroyed || !mBinding) {
// This is abnormal. Unbinding the connection has been requested already.
Slog.wtf(mTag, "onServiceConnected() was dispatched after unbindService.");
@@ -296,15 +324,7 @@
handleBinderDied();
return;
}
- onConnectedStateChanged(true);
-
- if (mPendingRequest != null) {
- final PendingRequest<? extends AbstractRemoteService> pendingRequest =
- mPendingRequest;
- mPendingRequest = null;
- handlePendingRequest(pendingRequest);
- }
-
+ handleOnConnectedStateChangedInternal(true);
mServiceDied = false;
}
@@ -325,25 +345,12 @@
return mDestroyed;
}
- protected boolean handleResponseCallbackCommon(
- PendingRequest<? extends AbstractRemoteService> pendingRequest) {
- if (isDestroyed()) return false;
-
- if (mPendingRequest == pendingRequest) {
- mPendingRequest = null;
- }
- if (mPendingRequest == null) {
- scheduleUnbind();
- }
- return true;
- }
-
/**
* Base class for the requests serviced by the remote service.
*
* @param <S> the remote service class
*/
- public abstract static class PendingRequest<S extends AbstractRemoteService>
+ public abstract static class PendingRequest<S extends AbstractRemoteService<S>>
implements Runnable {
protected final String mTag = getClass().getSimpleName();
protected final Object mLock = new Object();
diff --git a/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java b/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java
new file mode 100644
index 0000000..8e1f540
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractSinglePendingRequestRemoteService.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+
+/**
+ * Base class representing a remote service that can have only one pending requests while not bound.
+ *
+ * <p>If another request is received while not bound, the previous one will be canceled.
+ *
+ * @param <S> the concrete remote service class
+ *
+ * @hide
+ */
+public abstract class AbstractSinglePendingRequestRemoteService<
+ S extends AbstractSinglePendingRequestRemoteService<S>> extends AbstractRemoteService<S> {
+
+ protected PendingRequest<S> mPendingRequest;
+
+ public AbstractSinglePendingRequestRemoteService(@NonNull Context context,
+ @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
+ @NonNull VultureCallback callback, boolean bindInstantServiceAllowed,
+ boolean verbose) {
+ super(context, serviceInterface, componentName, userId, callback, bindInstantServiceAllowed,
+ verbose);
+ }
+
+ @Override // from AbstractRemoteService
+ void handlePendingRequests() {
+ if (mPendingRequest != null) {
+ final PendingRequest<S> pendingRequest = mPendingRequest;
+ mPendingRequest = null;
+ handlePendingRequest(pendingRequest);
+ }
+ }
+
+ @Override // from AbstractRemoteService
+ protected void handleOnDestroy() {
+ if (mPendingRequest != null) {
+ mPendingRequest.cancel();
+ mPendingRequest = null;
+ }
+ }
+
+ @Override // from AbstractRemoteService
+ public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+ super.dump(prefix, pw);
+ pw.append(prefix).append("hasPendingRequest=")
+ .append(String.valueOf(mPendingRequest != null)).println();
+ }
+
+ @Override // from AbstractRemoteService
+ void handlePendingRequestWhileUnBound(@NonNull PendingRequest<S> pendingRequest) {
+ if (mPendingRequest != null) {
+ if (mVerbose) {
+ Slog.v(mTag, "handlePendingRequestWhileUnBound(): cancelling " + mPendingRequest);
+ }
+ mPendingRequest.cancel();
+ }
+ mPendingRequest = pendingRequest;
+ }
+}
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index 9820321..01716a0 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -98,7 +98,7 @@
mBinderCallsStats.setSamplingInterval(mParser.getInt(
SETTINGS_SAMPLING_INTERVAL_KEY,
BinderCallsStats.PERIODIC_SAMPLING_INTERVAL_DEFAULT));
- mBinderCallsStats.setSamplingInterval(mParser.getInt(
+ mBinderCallsStats.setMaxBinderCallStats(mParser.getInt(
SETTINGS_MAX_CALL_STATS_KEY,
BinderCallsStats.MAX_BINDER_CALL_STATS_COUNT_DEFAULT));
diff --git a/services/core/java/com/android/server/RuntimeService.java b/services/core/java/com/android/server/RuntimeService.java
new file mode 100644
index 0000000..ccfac80
--- /dev/null
+++ b/services/core/java/com/android/server/RuntimeService.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.os.Binder;
+import android.service.runtime.DebugEntryProto;
+import android.service.runtime.RuntimeServiceInfoProto;
+import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
+
+import libcore.timezone.TimeZoneDataFiles;
+import libcore.util.CoreLibraryDebug;
+import libcore.util.DebugInfo;
+
+import com.android.internal.util.DumpUtils;
+import com.android.timezone.distro.DistroException;
+import com.android.timezone.distro.DistroVersion;
+import com.android.timezone.distro.FileUtils;
+import com.android.timezone.distro.TimeZoneDistro;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * This service exists only as a "dumpsys" target which reports information about the status of the
+ * runtime and related libraries.
+ */
+public class RuntimeService extends Binder {
+
+ private static final String TAG = "RuntimeService";
+
+ private final Context mContext;
+
+ public RuntimeService(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) {
+ return;
+ }
+
+ boolean protoFormat = hasOption(args, "--proto");
+ ProtoOutputStream proto = null;
+
+ DebugInfo coreLibraryDebugInfo = CoreLibraryDebug.getDebugInfo();
+ addTimeZoneApkDebugInfo(coreLibraryDebugInfo);
+
+ if (protoFormat) {
+ proto = new ProtoOutputStream(fd);
+ reportTimeZoneInfoProto(coreLibraryDebugInfo, proto);
+ } else {
+ reportTimeZoneInfo(coreLibraryDebugInfo, pw);
+ }
+
+ if (protoFormat) {
+ proto.flush();
+ }
+ }
+
+ /** Returns {@code true} if {@code args} contains {@code arg}. */
+ private static boolean hasOption(String[] args, String arg) {
+ for (String opt : args) {
+ if (arg.equals(opt)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add information to {@link DebugInfo} about the time zone data supplied by the
+ * "Time zone updates via APK" feature.
+ */
+ private static void addTimeZoneApkDebugInfo(DebugInfo coreLibraryDebugInfo) {
+ // Add /data tz data set using the DistroVersion class (which libcore cannot use).
+ // This update mechanism will be removed after the time zone APEX is launched so this
+ // untidiness will disappear with it.
+ String debugKeyPrefix = "core_library.timezone.data_";
+ String versionFileName = TimeZoneDataFiles.getDataTimeZoneFile(
+ TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+ addDistroVersionDebugInfo(versionFileName, debugKeyPrefix, coreLibraryDebugInfo);
+ }
+
+ /**
+ * Prints {@code coreLibraryDebugInfo} to {@code pw}.
+ *
+ * <p>If you change this method, make sure to modify
+ * {@link #reportTimeZoneInfoProto(DebugInfo, ProtoOutputStream)} as well.
+ */
+ private static void reportTimeZoneInfo(DebugInfo coreLibraryDebugInfo,
+ PrintWriter pw) {
+ pw.println("Core Library Debug Info: ");
+ for (DebugInfo.DebugEntry debugEntry : coreLibraryDebugInfo.getDebugEntries()) {
+ pw.print(debugEntry.getKey());
+ pw.print(": \"");
+ pw.print(debugEntry.getStringValue());
+ pw.println("\"");
+ }
+ }
+
+ /**
+ * Adds {@code coreLibraryDebugInfo} to {@code protoStream}.
+ *
+ * <p>If you change this method, make sure to modify
+ * {@link #reportTimeZoneInfo(DebugInfo, PrintWriter)}.
+ */
+ private static void reportTimeZoneInfoProto(
+ DebugInfo coreLibraryDebugInfo, ProtoOutputStream protoStream) {
+ for (DebugInfo.DebugEntry debugEntry : coreLibraryDebugInfo.getDebugEntries()) {
+ long entryToken = protoStream.start(RuntimeServiceInfoProto.DEBUG_ENTRY);
+ protoStream.write(DebugEntryProto.KEY, debugEntry.getKey());
+ protoStream.write(DebugEntryProto.STRING_VALUE, debugEntry.getStringValue());
+ protoStream.end(entryToken);
+ }
+ }
+
+ /**
+ * Adds version information to {@code debugInfo} from the distro_version file that may exist
+ * at {@code distroVersionFileName}. If the file does not exist or cannot be read this is
+ * reported as debug information too.
+ */
+ private static void addDistroVersionDebugInfo(String distroVersionFileName,
+ String debugKeyPrefix, DebugInfo debugInfo) {
+ File file = new File(distroVersionFileName);
+ String statusKey = debugKeyPrefix + "status";
+ if (file.exists()) {
+ try {
+ byte[] versionBytes =
+ FileUtils.readBytes(file, DistroVersion.DISTRO_VERSION_FILE_LENGTH);
+ DistroVersion distroVersion = DistroVersion.fromBytes(versionBytes);
+ String formatVersionString = distroVersion.formatMajorVersion + "."
+ + distroVersion.formatMinorVersion;
+ debugInfo.addStringEntry(statusKey, "OK")
+ .addStringEntry(debugKeyPrefix + "formatVersion", formatVersionString)
+ .addStringEntry(debugKeyPrefix + "rulesVersion",
+ distroVersion.rulesVersion)
+ .addStringEntry(debugKeyPrefix + "revision",
+ distroVersion.revision);
+ } catch (IOException | DistroException e) {
+ debugInfo.addStringEntry(statusKey, "ERROR");
+ debugInfo.addStringEntry(debugKeyPrefix + "exception_class",
+ e.getClass().getName());
+ debugInfo.addStringEntry(debugKeyPrefix + "exception_msg", e.getMessage());
+ logMessage("Error reading " + file, e);
+ }
+ } else {
+ debugInfo.addStringEntry(statusKey, "NOT_FOUND");
+ }
+ }
+
+ private static void logMessage(String msg, Throwable t) {
+ Slog.v(TAG, msg, t);
+ }
+}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index f0b472b..a2cbfaa 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -47,6 +47,7 @@
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.emergency.EmergencyNumber;
import android.util.LocalLog;
import android.util.StatsLog;
@@ -1664,6 +1665,14 @@
}
@Override
+ public void notifyEmergencyNumberList(List<EmergencyNumber> emergencyNumberList) {
+ // TODO checkPermission, modify Listener constent documentation
+ // TODO implement multisim emergency number list update in listener
+ // TODO implement PhoneStateListenerTest
+ }
+
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
diff --git a/services/core/java/com/android/server/WallpaperUpdateReceiver.java b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
new file mode 100644
index 0000000..629e882
--- /dev/null
+++ b/services/core/java/com/android/server/WallpaperUpdateReceiver.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.app.ActivityThread;
+import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.AsyncTask;
+import android.util.Slog;
+
+/**
+ * Receiver responsible for updating the wallpaper when the device
+ * configuration has changed.
+ *
+ * @hide
+ */
+public class WallpaperUpdateReceiver extends BroadcastReceiver {
+
+ private static final String TAG = "WallpaperUpdateReceiver";
+ private static final boolean DEBUG = false;
+
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ if (DEBUG) Slog.d(TAG, "onReceive: " + intent);
+
+ if (intent != null && Intent.ACTION_DEVICE_CUSTOMIZATION_READY.equals(intent.getAction())) {
+ AsyncTask.execute(this::updateWallpaper);
+ }
+ }
+
+ private void updateWallpaper() {
+ try {
+ ActivityThread currentActivityThread = ActivityThread.currentActivityThread();
+ Context uiContext = currentActivityThread.getSystemUiContext();
+ WallpaperManager wallpaperManager = WallpaperManager.getInstance(uiContext);
+ if (DEBUG) Slog.d(TAG, "Set customized default_wallpaper.");
+ Bitmap blank = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+ // set a blank wallpaper to force a redraw of default_wallpaper
+ wallpaperManager.setBitmap(blank);
+ wallpaperManager.setResource(com.android.internal.R.drawable.default_wallpaper);
+ } catch (Exception e) {
+ Slog.w(TAG, "Failed to customize system wallpaper." + e);
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 0e354d5..562e80d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -666,16 +666,50 @@
final class PidMap {
private final SparseArray<ProcessRecord> mPidMap = new SparseArray<>();
+ /**
+ * Puts the process record in the map.
+ * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+ * method.
+ */
void put(int key, ProcessRecord value) {
- mPidMap.put(key, value);
+ synchronized (this) {
+ mPidMap.put(key, value);
+ }
mAtmInternal.onProcessMapped(key, value.getWindowProcessController());
}
+ /**
+ * Removes the process record from the map.
+ * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+ * method.
+ */
void remove(int pid) {
- mPidMap.remove(pid);
+ synchronized (this) {
+ mPidMap.remove(pid);
+ }
mAtmInternal.onProcessUnMapped(pid);
}
+ /**
+ * Removes the process record from the map if it has a thread.
+ * <p>NOTE: Callers should avoid acquiring the mPidsSelfLocked lock before calling this
+ * method.
+ */
+ boolean removeIfNoThread(int pid) {
+ boolean removed = false;
+ synchronized (this) {
+ final ProcessRecord app = get(pid);
+ if (app != null && app.thread == null) {
+ mPidMap.remove(pid);
+ removed = true;
+ }
+ }
+ if (removed) {
+ mAtmInternal.onProcessUnMapped(pid);
+ }
+ return removed;
+ }
+
ProcessRecord get(int pid) {
return mPidMap.get(pid);
}
@@ -1889,9 +1923,7 @@
app.getWindowProcessController().setPid(MY_PID);
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
- synchronized (mPidsSelfLocked) {
- mPidsSelfLocked.put(app.pid, app);
- }
+ mPidsSelfLocked.put(app.pid, app);
mProcessList.updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
@@ -4254,14 +4286,7 @@
private final void processStartTimedOutLocked(ProcessRecord app) {
final int pid = app.pid;
- boolean gone = false;
- synchronized (mPidsSelfLocked) {
- ProcessRecord knownApp = mPidsSelfLocked.get(pid);
- if (knownApp != null && knownApp.thread == null) {
- mPidsSelfLocked.remove(pid);
- gone = true;
- }
- }
+ boolean gone = mPidsSelfLocked.removeIfNoThread(pid);
if (gone) {
Slog.w(TAG, "Process " + app + " failed to attach");
@@ -13113,11 +13138,8 @@
return true;
} else if (app.pid > 0 && app.pid != MY_PID) {
// Goodbye!
- boolean removed;
- synchronized (mPidsSelfLocked) {
- mPidsSelfLocked.remove(app.pid);
- mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
- }
+ mPidsSelfLocked.remove(app.pid);
+ mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
diff --git a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
index 2541352..24543b7 100644
--- a/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
+++ b/services/core/java/com/android/server/am/BatteryExternalStatsWorker.java
@@ -25,10 +25,12 @@
import android.net.wifi.WifiActivityEnergyInfo;
import android.os.BatteryStats;
import android.os.Parcelable;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SynchronousResultReceiver;
import android.os.SystemClock;
+import android.os.ThreadLocalWorkSource;
import android.telephony.ModemActivityInfo;
import android.telephony.TelephonyManager;
import android.util.IntArray;
@@ -43,11 +45,9 @@
import libcore.util.EmptyArray;
import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -74,7 +74,12 @@
private final ScheduledExecutorService mExecutorService =
Executors.newSingleThreadScheduledExecutor(
(ThreadFactory) r -> {
- Thread t = new Thread(r, "batterystats-worker");
+ Thread t = new Thread(
+ () -> {
+ ThreadLocalWorkSource.setUid(Process.myUid());
+ r.run();
+ },
+ "batterystats-worker");
t.setPriority(Thread.NORM_PRIORITY);
return t;
});
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 7991783..62f1009 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -1246,10 +1246,8 @@
long startTime = SystemClock.elapsedRealtime();
if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
checkSlow(startTime, "startProcess: removing from pids map");
- synchronized (mService.mPidsSelfLocked) {
- mService.mPidsSelfLocked.remove(app.pid);
- mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
- }
+ mService.mPidsSelfLocked.remove(app.pid);
+ mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
checkSlow(startTime, "startProcess: done removing from pids map");
app.setPid(0);
}
@@ -1767,8 +1765,8 @@
mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
true /*replacingPid*/);
}
+ mService.mPidsSelfLocked.put(pid, app);
synchronized (mService.mPidsSelfLocked) {
- mService.mPidsSelfLocked.put(pid, app);
if (!procAttached) {
Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
@@ -1928,10 +1926,8 @@
.pendingStart)) {
int pid = app.pid;
if (pid > 0) {
- synchronized (mService.mPidsSelfLocked) {
- mService.mPidsSelfLocked.remove(pid);
- mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
- }
+ mService.mPidsSelfLocked.remove(pid);
+ mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index c2f4406..bf95210 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -313,6 +313,7 @@
private final State mCaptivePortalState = new CaptivePortalState();
private final State mEvaluatingPrivateDnsState = new EvaluatingPrivateDnsState();
private final State mProbingState = new ProbingState();
+ private final State mWaitingForNextProbeState = new WaitingForNextProbeState();
private CustomIntentReceiver mLaunchCaptivePortalAppBroadcastReceiver = null;
@@ -368,6 +369,7 @@
addState(mMaybeNotifyState, mDefaultState);
addState(mEvaluatingState, mMaybeNotifyState);
addState(mProbingState, mEvaluatingState);
+ addState(mWaitingForNextProbeState, mEvaluatingState);
addState(mCaptivePortalState, mMaybeNotifyState);
addState(mEvaluatingPrivateDnsState, mDefaultState);
addState(mValidatedState, mDefaultState);
@@ -877,6 +879,11 @@
@Override
public void enter() {
+ if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) {
+ //Don't continue to blame UID forever.
+ TrafficStats.clearThreadStatsUid();
+ }
+
final int token = ++mProbeToken;
mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0,
isCaptivePortal())));
@@ -904,29 +911,16 @@
mLastPortalProbeResult = probeResult;
transitionTo(mCaptivePortalState);
} else {
- final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
- sendMessageDelayed(msg, mReevaluateDelayMs);
logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
notifyNetworkTestResultInvalid(probeResult.redirectUrl);
- if (mEvaluateAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) {
- // Don't continue to blame UID forever.
- TrafficStats.clearThreadStatsUid();
- }
- mReevaluateDelayMs *= 2;
- if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) {
- mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS;
- }
+ transitionTo(mWaitingForNextProbeState);
}
return HANDLED;
- case CMD_REEVALUATE:
- // Leave the event to EvaluatingState. Defer this message will result in reset
- // of mReevaluateDelayMs and mEvaluateAttempts.
- case CMD_NETWORK_DISCONNECTED:
case EVENT_DNS_NOTIFICATION:
+ // Leave the event to DefaultState to record correct dns timestamp.
return NOT_HANDLED;
default:
- // TODO: Some events may able to handle in this state, instead of deferring to
- // next state.
+ // Wait for probe result and defer events to next state by default.
deferMessage(message);
return HANDLED;
}
@@ -941,6 +935,29 @@
}
}
+ // Being in the WaitingForNextProbeState indicates that evaluating probes failed and state is
+ // transited from ProbingState. This ensures that the state machine is only in ProbingState
+ // while a probe is in progress, not while waiting to perform the next probe. That allows
+ // ProbingState to defer most messages until the probe is complete, which keeps the code simple
+ // and matches the pre-Q behaviour where probes were a blocking operation performed on the state
+ // machine thread.
+ private class WaitingForNextProbeState extends State {
+ @Override
+ public void enter() {
+ final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
+ sendMessageDelayed(msg, mReevaluateDelayMs);
+ mReevaluateDelayMs *= 2;
+ if (mReevaluateDelayMs > MAX_REEVALUATE_DELAY_MS) {
+ mReevaluateDelayMs = MAX_REEVALUATE_DELAY_MS;
+ }
+ }
+
+ @Override
+ public boolean processMessage(Message message) {
+ return NOT_HANDLED;
+ }
+ }
+
// Limits the list of IP addresses returned by getAllByName or tried by openConnection to at
// most one per address family. This ensures we only wait up to 20 seconds for TCP connections
// to complete, regardless of how many IP addresses a host has.
diff --git a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
index 6fe6324..d5be26a 100644
--- a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
+++ b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java
@@ -27,12 +27,13 @@
*
* @hide Only for use within the system server.
*/
+//TODO(b/111276913): rename once the final name is defined
public abstract class IntelligenceManagerInternal {
/**
* Checks whether the given {@code uid} owns the
- * {@link android.service.intelligence.IntelligenceService} implementation associated with the
- * given {@code userId}.
+ * {@link android.service.intelligence.SmartSuggestionsService} implementation associated with
+ * the given {@code userId}.
*/
public abstract boolean isIntelligenceServiceForUser(int uid, @UserIdInt int userId);
diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java
index 79e2688..07bebad 100644
--- a/services/core/java/com/android/server/power/ThermalManagerService.java
+++ b/services/core/java/com/android/server/power/ThermalManagerService.java
@@ -29,8 +29,12 @@
import android.os.IThermalService;
import android.os.IThermalStatusListener;
import android.os.PowerManager;
+import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
import android.os.Temperature;
import android.util.ArrayMap;
import android.util.Slog;
@@ -77,6 +81,10 @@
@GuardedBy("mLock")
private int mStatus;
+ /** If override status takes effect*/
+ @GuardedBy("mLock")
+ private boolean mIsStatusOverride;
+
/** Current thermal map, key as name */
@GuardedBy("mLock")
private ArrayMap<String, Temperature> mTemperatureMap = new ArrayMap<>();
@@ -184,13 +192,19 @@
newStatus = t.getStatus();
}
}
+ // Do not update if override from shell
+ if (!mIsStatusOverride) {
+ setStatusLocked(newStatus);
+ }
+ }
+
+ private void setStatusLocked(int newStatus) {
if (newStatus != mStatus) {
mStatus = newStatus;
notifyStatusListenersLocked();
}
}
-
private void postEventListenerCurrentTemperatures(IThermalEventListener listener,
@Nullable Integer type) {
synchronized (mLock) {
@@ -241,12 +255,7 @@
// Thermal Shutdown for Skin temperature
if (temperature.getStatus() == Temperature.THROTTLING_SHUTDOWN
&& temperature.getType() == Temperature.TYPE_SKIN) {
- final long token = Binder.clearCallingIdentity();
- try {
- mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
+ mPowerManager.shutdown(false, PowerManager.SHUTDOWN_THERMAL_STATE, false);
}
Temperature old = mTemperatureMap.put(temperature.getName(), temperature);
@@ -263,8 +272,14 @@
}
}
+ /* HwBinder callback **/
private void onTemperatureChangedCallback(Temperature temperature) {
- onTemperatureChanged(temperature, true);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ onTemperatureChanged(temperature, true);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
private void dumpTemperaturesLocked(PrintWriter pw, String prefix,
@@ -393,7 +408,7 @@
}
@Override
- public int getCurrentStatus() {
+ public int getCurrentThermalStatus() {
synchronized (mLock) {
final long token = Binder.clearCallingIdentity();
try {
@@ -434,8 +449,93 @@
Binder.restoreCallingIdentity(token);
}
}
+
+ private boolean isCallerShell() {
+ final int callingUid = Binder.getCallingUid();
+ return callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID;
+ }
+
+ @Override
+ public void onShellCommand(FileDescriptor in, FileDescriptor out,
+ FileDescriptor err, String[] args, ShellCallback callback,
+ ResultReceiver resultReceiver) {
+ if (!isCallerShell()) {
+ Slog.w(TAG, "Only shell is allowed to call thermalservice shell commands");
+ return;
+ }
+ (new ThermalShellCommand()).exec(
+ this, in, out, err, args, callback, resultReceiver);
+ }
+
};
+ class ThermalShellCommand extends ShellCommand {
+ @Override
+ public int onCommand(String cmd) {
+ switch(cmd != null ? cmd : "") {
+ case "override-status":
+ return runOverrideStatus();
+ case "reset":
+ return runReset();
+ default:
+ return handleDefaultCommands(cmd);
+ }
+ }
+
+ private int runReset() {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ mIsStatusOverride = false;
+ onTemperatureMapChangedLocked();
+ return 0;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private int runOverrideStatus() {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final PrintWriter pw = getOutPrintWriter();
+ int status;
+ try {
+ status = Integer.parseInt(getNextArgRequired());
+ } catch (RuntimeException ex) {
+ pw.println("Error: " + ex.toString());
+ return -1;
+ }
+ if (!Temperature.isValidStatus(status)) {
+ pw.println("Invalid status: " + Integer.toString(status));
+ return -1;
+ }
+ synchronized (mLock) {
+ mIsStatusOverride = true;
+ setStatusLocked(status);
+ }
+ return 0;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
+ public void onHelp() {
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println("Thermal service (thermalservice) commands:");
+ pw.println(" help");
+ pw.println(" Print this help text.");
+ pw.println("");
+ pw.println(" override-status STATUS");
+ pw.println(" sets and locks the thermal status of the device to STATUS.");
+ pw.println(" status code is defined in android.os.Temperature.");
+ pw.println(" reset");
+ pw.println(" unlocks the thermal status of the device.");
+ pw.println();
+ }
+ }
+
abstract static class ThermalHalWrapper {
protected static final String TAG = ThermalHalWrapper.class.getSimpleName();
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index b065470..b5ad235 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -55,6 +55,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@@ -106,7 +107,7 @@
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
getContext().registerReceiverAsUser(new BroadcastReceiver() {
@Override
- public void onReceive(Context context, Intent intent) {
+ public void onReceive(@NonNull Context context, @NonNull Intent intent) {
if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) {
int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
onRemoveUser(userId);
@@ -129,10 +130,11 @@
userState = getUserStateLocked(userId);
}
String packagesHash = computeComponentStateHash(userId);
- boolean needGrant;
+ String lastGrantPackagesHash;
synchronized (mLock) {
- needGrant = !packagesHash.equals(userState.getLastGrantPackagesHashLocked());
+ lastGrantPackagesHash = userState.getLastGrantPackagesHashLocked();
}
+ boolean needGrant = !Objects.equals(packagesHash, lastGrantPackagesHash);
if (needGrant) {
// Some vital packages state has changed since last role grant
// Run grants again
@@ -144,7 +146,6 @@
public void onSuccess() {
result.complete(null);
}
-
@Override
public void onFailure() {
result.completeExceptionally(new RuntimeException());
@@ -163,7 +164,8 @@
}
}
- private String computeComponentStateHash(int userId) {
+ @Nullable
+ private String computeComponentStateHash(@UserIdInt int userId) {
PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -198,8 +200,7 @@
private RoleUserState getUserStateLocked(@UserIdInt int userId) {
RoleUserState userState = mUserStates.get(userId);
if (userState == null) {
- userState = new RoleUserState(userId);
- userState.readSyncLocked();
+ userState = RoleUserState.newInstanceLocked(userId);
mUserStates.put(userId, userState);
}
return userState;
@@ -386,11 +387,11 @@
}
@Override
- public void onShellCommand(FileDescriptor in, FileDescriptor out,
- FileDescriptor err, String[] args, ShellCallback callback,
- ResultReceiver resultReceiver) {
- (new RoleManagerShellCommand(this)).exec(
- this, in, out, err, args, callback, resultReceiver);
+ public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err, @NonNull String[] args,
+ @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
+ new RoleManagerShellCommand(this).exec(this, in, out, err, args, callback,
+ resultReceiver);
}
}
}
diff --git a/services/core/java/com/android/server/role/RoleManagerShellCommand.java b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
index e1977ef..336b311 100644
--- a/services/core/java/com/android/server/role/RoleManagerShellCommand.java
+++ b/services/core/java/com/android/server/role/RoleManagerShellCommand.java
@@ -16,6 +16,8 @@
package com.android.server.role;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.role.IRoleManager;
import android.app.role.IRoleManagerCallback;
import android.os.RemoteException;
@@ -27,13 +29,17 @@
import java.util.concurrent.TimeUnit;
class RoleManagerShellCommand extends ShellCommand {
+
+ @NonNull
private final IRoleManager mRoleManager;
- RoleManagerShellCommand(IRoleManager roleManager) {
+ RoleManagerShellCommand(@NonNull IRoleManager roleManager) {
mRoleManager = roleManager;
}
private class Callback extends IRoleManagerCallback.Stub {
+
+ @NonNull
private final CompletableFuture<Void> mResult = new CompletableFuture<>();
public int waitForResult() {
@@ -58,7 +64,7 @@
}
@Override
- public int onCommand(String cmd) {
+ public int onCommand(@Nullable String cmd) {
if (cmd == null) {
return handleDefaultCommands(cmd);
}
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index f218d3a..3e3e156 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -47,6 +47,7 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.Objects;
/**
* Stores the state of roles for a user.
@@ -70,25 +71,41 @@
private final int mUserId;
@GuardedBy("RoleManagerService.mLock")
- private int mVersion;
+ private int mVersion = VERSION_UNDEFINED;
@GuardedBy("RoleManagerService.mLock")
- private String mLastGrantPackagesHash = null;
+ @Nullable
+ private String mLastGrantPackagesHash;
/**
* Maps role names to its holders' package names. The values should never be null.
*/
@GuardedBy("RoleManagerService.mLock")
- @Nullable
- private ArrayMap<String, ArraySet<String>> mRoles = null;
+ @NonNull
+ private ArrayMap<String, ArraySet<String>> mRoles = new ArrayMap<>();
@GuardedBy("RoleManagerService.mLock")
private boolean mDestroyed;
+ @NonNull
private final Handler mWriteHandler = new Handler(BackgroundThread.getHandler().getLooper());
- public RoleUserState(@UserIdInt int userId) {
+ private RoleUserState(@UserIdInt int userId) {
mUserId = userId;
+
+ readSyncLocked();
+ }
+
+ /**
+ * Create a new instance of user state, and read its state from disk if previously persisted.
+ *
+ * @param userId the user id for the new user state
+ *
+ * @return the new user state
+ */
+ @GuardedBy("RoleManagerService.mLock")
+ public static RoleUserState newInstanceLocked(@UserIdInt int userId) {
+ return new RoleUserState(userId);
}
/**
@@ -116,7 +133,9 @@
}
/**
- * Get the hash representing the state of packages during the last time initial grants was run
+ * Get the hash representing the state of packages during the last time initial grants was run.
+ *
+ * @return the hash representing the state of packages
*/
@GuardedBy("RoleManagerService.mLock")
public String getLastGrantPackagesHashLocked() {
@@ -124,10 +143,16 @@
}
/**
- * Set the hash representing the state of packages during the last time initial grants was run
+ * Set the hash representing the state of packages during the last time initial grants was run.
+ *
+ * @param lastGrantPackagesHash the hash representing the state of packages
*/
@GuardedBy("RoleManagerService.mLock")
- public void setLastGrantPackagesHashLocked(String lastGrantPackagesHash) {
+ public void setLastGrantPackagesHashLocked(@Nullable String lastGrantPackagesHash) {
+ throwIfDestroyedLocked();
+ if (Objects.equals(mLastGrantPackagesHash, lastGrantPackagesHash)) {
+ return;
+ }
mLastGrantPackagesHash = lastGrantPackagesHash;
writeAsyncLocked();
}
@@ -250,9 +275,9 @@
* Schedule writing the state to file.
*/
@GuardedBy("RoleManagerService.mLock")
- void writeAsyncLocked() {
+ private void writeAsyncLocked() {
throwIfDestroyedLocked();
- int version = mVersion;
+
ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
String roleName = mRoles.keyAt(i);
@@ -260,15 +285,16 @@
roleHolders = new ArraySet<>(roleHolders);
roles.put(roleName, roleHolders);
}
+
mWriteHandler.removeCallbacksAndMessages(null);
// TODO: Throttle writes.
- mWriteHandler.sendMessage(PooledLambda.obtainMessage(
- RoleUserState::writeSync, this, version, roles, mLastGrantPackagesHash));
+ mWriteHandler.sendMessage(PooledLambda.obtainMessage(RoleUserState::writeSync, this,
+ mVersion, mLastGrantPackagesHash, roles));
}
@WorkerThread
- private void writeSync(int version, @NonNull ArrayMap<String, ArraySet<String>> roles,
- String packagesHash) {
+ private void writeSync(int version, @Nullable String packagesHash,
+ @NonNull ArrayMap<String, ArraySet<String>> roles) {
AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
FileOutputStream out = null;
try {
@@ -280,7 +306,7 @@
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startDocument(null, true);
- serializeRoles(serializer, version, roles, packagesHash);
+ serializeRoles(serializer, version, packagesHash, roles);
serializer.endDocument();
atomicFile.finishWrite(out);
@@ -296,19 +322,26 @@
@WorkerThread
private void serializeRoles(@NonNull XmlSerializer serializer, int version,
- @NonNull ArrayMap<String, ArraySet<String>> roles, String packagesHash)
+ @Nullable String packagesHash, @NonNull ArrayMap<String, ArraySet<String>> roles)
throws IOException {
serializer.startTag(null, TAG_ROLES);
+
serializer.attribute(null, ATTRIBUTE_VERSION, Integer.toString(version));
- serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+
+ if (packagesHash != null) {
+ serializer.attribute(null, ATTRIBUTE_PACKAGES_HASH, packagesHash);
+ }
+
for (int i = 0, size = roles.size(); i < size; ++i) {
String roleName = roles.keyAt(i);
ArraySet<String> roleHolders = roles.valueAt(i);
+
serializer.startTag(null, TAG_ROLE);
serializer.attribute(null, ATTRIBUTE_NAME, roleName);
serializeRoleHolders(serializer, roleHolders);
serializer.endTag(null, TAG_ROLE);
}
+
serializer.endTag(null, TAG_ROLES);
}
@@ -317,6 +350,7 @@
@NonNull ArraySet<String> roleHolders) throws IOException {
for (int i = 0, size = roleHolders.size(); i < size; ++i) {
String roleHolder = roleHolders.valueAt(i);
+
serializer.startTag(null, TAG_HOLDER);
serializer.attribute(null, ATTRIBUTE_NAME, roleHolder);
serializer.endTag(null, TAG_HOLDER);
@@ -327,11 +361,7 @@
* Read the state from file.
*/
@GuardedBy("RoleManagerService.mLock")
- public void readSyncLocked() {
- if (mRoles != null) {
- throw new IllegalStateException("This RoleUserState has already read the roles.xml");
- }
-
+ private void readSyncLocked() {
File file = getFile(mUserId);
try (FileInputStream in = new AtomicFile(file).openRead()) {
XmlPullParser parser = Xml.newPullParser();
@@ -339,8 +369,6 @@
parseXmlLocked(parser);
} catch (FileNotFoundException e) {
Slog.i(LOG_TAG, "roles.xml not found");
- mRoles = new ArrayMap<>();
- mVersion = VERSION_UNDEFINED;
} catch (XmlPullParserException | IOException e) {
throw new IllegalStateException("Failed to parse roles.xml: " + file, e);
}
@@ -362,13 +390,14 @@
return;
}
}
+ Slog.w(LOG_TAG, "Missing <" + TAG_ROLES + "> in roles.xml");
}
private void parseRolesLocked(@NonNull XmlPullParser parser) throws IOException,
XmlPullParserException {
mVersion = Integer.parseInt(parser.getAttributeValue(null, ATTRIBUTE_VERSION));
mLastGrantPackagesHash = parser.getAttributeValue(null, ATTRIBUTE_PACKAGES_HASH);
- mRoles = new ArrayMap<>();
+ mRoles.clear();
int type;
int depth;
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index f1d77b9..581cec9 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2834,6 +2834,9 @@
return 0;
}
+ mDisplayContent.getInsetsStateController().onBarControllingWindowChanged(
+ mTopFullscreenOpaqueWindowState);
+
int tmpVisibility = PolicyControl.getSystemUiVisibility(win, null)
& ~mResettingSystemUiFlags
& ~mForceClearedSystemUiFlags;
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index e96f0b1..282838f 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -18,11 +18,18 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Point;
import android.graphics.Rect;
+import android.util.proto.ProtoOutputStream;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
import android.view.InsetsSource;
+import android.view.InsetsSourceControl;
import com.android.internal.util.function.TriConsumer;
-import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+
+import java.io.PrintWriter;
/**
* Controller for a specific inset source on the server. It's called provider as it provides the
@@ -32,11 +39,19 @@
private final Rect mTmpRect = new Rect();
private final @NonNull InsetsSource mSource;
+ private final DisplayContent mDisplayContent;
+ private final InsetsStateController mStateController;
+ private @Nullable InsetsSourceControl mControl;
+ private @Nullable WindowState mControllingWin;
+ private @Nullable ControlAdapter mAdapter;
private WindowState mWin;
private TriConsumer<DisplayFrames, WindowState, Rect> mFrameProvider;
- InsetsSourceProvider(InsetsSource source) {
+ InsetsSourceProvider(InsetsSource source, InsetsStateController stateController,
+ DisplayContent displayContent) {
mSource = source;
+ mDisplayContent = displayContent;
+ mStateController = stateController;
}
InsetsSource getSource() {
@@ -84,4 +99,81 @@
mSource.setVisible(mWin.isVisible() && !mWin.mGivenInsetsPending);
}
+
+ void updateControlForTarget(@Nullable WindowState target) {
+ if (target == mControllingWin) {
+ return;
+ }
+ if (target == null) {
+ revokeControl();
+ return;
+ }
+ mAdapter = new ControlAdapter();
+ mWin.startAnimation(mDisplayContent.getPendingTransaction(), mAdapter,
+ false /* TODO hidden */);
+ mControllingWin = target;
+ mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash);
+ }
+
+ InsetsSourceControl getControl() {
+ return mControl;
+ }
+
+ void revokeControl() {
+ if (mControllingWin != null) {
+
+ // Cancelling the animation will invoke onAnimationCancelled, resetting all the fields.
+ mWin.cancelAnimation();
+ }
+ }
+
+ private class ControlAdapter implements AnimationAdapter {
+
+ private SurfaceControl mCapturedLeash;
+
+ @Override
+ public boolean getShowWallpaper() {
+ return false;
+ }
+
+ @Override
+ public int getBackgroundColor() {
+ return 0;
+ }
+
+ @Override
+ public void startAnimation(SurfaceControl animationLeash, Transaction t,
+ OnAnimationFinishedCallback finishCallback) {
+ mCapturedLeash = animationLeash;
+ t.setPosition(mCapturedLeash, mSource.getFrame().left, mSource.getFrame().top);
+ }
+
+ @Override
+ public void onAnimationCancelled(SurfaceControl animationLeash) {
+ if (mAdapter == this) {
+ mStateController.notifyControlRevoked(mControllingWin, InsetsSourceProvider.this);
+ mControl = null;
+ mControllingWin = null;
+ mAdapter = null;
+ }
+ }
+
+ @Override
+ public long getDurationHint() {
+ return 0;
+ }
+
+ @Override
+ public long getStatusBarTransitionsStartTime() {
+ return 0;
+ }
+
+ @Override
+ public void dump(PrintWriter pw, String prefix) {
+ }
+
+ @Override
+ public void writeToProto(ProtoOutputStream proto) {
+ }
+ };
}
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 1189ee6..592b7fb 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -20,10 +20,17 @@
import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
import static android.view.InsetsState.TYPE_TOP_BAR;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.SparseArray;
+import android.view.InsetsSourceControl;
import android.view.InsetsState;
+import android.view.ViewRootImpl;
import java.io.PrintWriter;
+import java.util.ArrayList;
import java.util.function.Consumer;
/**
@@ -34,7 +41,11 @@
private final InsetsState mLastState = new InsetsState();
private final InsetsState mState = new InsetsState();
private final DisplayContent mDisplayContent;
- private ArrayMap<Integer, InsetsSourceProvider> mControllers = new ArrayMap<>();
+
+ private final ArrayMap<Integer, InsetsSourceProvider> mControllers = new ArrayMap<>();
+ private final ArrayMap<WindowState, ArrayList<Integer>> mWinControlTypeMap = new ArrayMap<>();
+ private final SparseArray<WindowState> mTypeWinControlMap = new SparseArray<>();
+ private final ArraySet<WindowState> mPendingControlChanged = new ArraySet<>();
private final Consumer<WindowState> mDispatchInsetsChanged = w -> {
if (w.isVisible()) {
@@ -72,12 +83,25 @@
return state;
}
+ @Nullable InsetsSourceControl[] getControlsForDispatch(WindowState target) {
+ ArrayList<Integer> controlled = mWinControlTypeMap.get(target);
+ if (controlled == null) {
+ return null;
+ }
+ final int size = controlled.size();
+ final InsetsSourceControl[] result = new InsetsSourceControl[size];
+ for (int i = 0; i < size; i++) {
+ result[i] = mControllers.get(controlled.get(i)).getControl();
+ }
+ return result;
+ }
+
/**
* @return The provider of a specific type.
*/
InsetsSourceProvider getSourceProvider(int type) {
return mControllers.computeIfAbsent(type,
- key -> new InsetsSourceProvider(mState.getSource(key)));
+ key -> new InsetsSourceProvider(mState.getSource(key), this, mDisplayContent));
}
/**
@@ -93,6 +117,84 @@
}
}
+ void onImeTargetChanged(@Nullable WindowState imeTarget) {
+ onControlChanged(TYPE_IME, imeTarget);
+ notifyPendingInsetsControlChanged();
+ }
+
+ /**
+ * Called when the top opaque fullscreen window that is able to control the system bars changes.
+ *
+ * @param controllingWindow The window that is now able to control the system bars appearance
+ * and visibility.
+ */
+ void onBarControllingWindowChanged(@Nullable WindowState controllingWindow) {
+ // TODO: Apply policy that determines whether controllingWindow is able to control system
+ // bars
+
+ // TODO: Depending on the form factor, mapping is different
+ onControlChanged(TYPE_TOP_BAR, controllingWindow);
+ onControlChanged(TYPE_NAVIGATION_BAR, controllingWindow);
+ notifyPendingInsetsControlChanged();
+ }
+
+ void notifyControlRevoked(@NonNull WindowState previousControllingWin,
+ InsetsSourceProvider provider) {
+ removeFromControlMaps(previousControllingWin, provider.getSource().getType());
+ }
+
+ private void onControlChanged(int type, @Nullable WindowState win) {
+ if (!ViewRootImpl.USE_NEW_INSETS) {
+ return;
+ }
+ final WindowState previous = mTypeWinControlMap.get(type);
+ if (win == previous) {
+ return;
+ }
+ final InsetsSourceProvider controller = mControllers.get(type);
+ if (controller == null) {
+ return;
+ }
+ controller.updateControlForTarget(win);
+ if (previous != null) {
+ removeFromControlMaps(previous, type);
+ mPendingControlChanged.add(previous);
+ }
+ if (win != null) {
+ addToControlMaps(win, type);
+ mPendingControlChanged.add(win);
+ }
+ }
+
+ private void removeFromControlMaps(@NonNull WindowState win, int type) {
+ final ArrayList<Integer> array = mWinControlTypeMap.get(win);
+ if (array == null) {
+ return;
+ }
+ array.remove((Integer) type);
+ if (array.isEmpty()) {
+ mWinControlTypeMap.remove(win);
+ }
+ mTypeWinControlMap.remove(type);
+ }
+
+ private void addToControlMaps(@NonNull WindowState win, int type) {
+ final ArrayList<Integer> array = mWinControlTypeMap.computeIfAbsent(win,
+ key -> new ArrayList<>());
+ array.add(type);
+ mTypeWinControlMap.put(type, win);
+ }
+
+ private void notifyPendingInsetsControlChanged() {
+ mDisplayContent.mWmService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
+ for (int i = mPendingControlChanged.size() - 1; i >= 0; i--) {
+ final WindowState controllingWin = mPendingControlChanged.valueAt(i);
+ controllingWin.notifyInsetsControlChanged();
+ }
+ mPendingControlChanged.clear();
+ });
+ }
+
private void notifyInsetsChanged() {
mDisplayContent.forAllWindows(mDispatchInsetsChanged, true /* traverseTopToBottom */);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index cdf9118..ef22bb8 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2972,6 +2972,17 @@
}
}
+ void notifyInsetsControlChanged() {
+ final InsetsStateController stateController =
+ getDisplayContent().getInsetsStateController();
+ try {
+ mClient.insetsControlChanged(stateController.getInsetsForDispatch(this),
+ stateController.getControlsForDispatch(this));
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to deliver inset state change", e);
+ }
+ }
+
Rect getBackdropFrame(Rect frame) {
// When the task is docked, we send fullscreen sized backDropFrame as soon as resizing
// start even if we haven't received the relayout window, so that the client requests
diff --git a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
index 08fbf55..108f91c 100644
--- a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
+++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java
@@ -19,9 +19,9 @@
import android.content.ComponentName;
import android.content.Context;
import android.os.IBinder;
-import android.service.intelligence.IntelligenceService;
import android.service.intelligence.InteractionContext;
import android.service.intelligence.InteractionSessionId;
+import android.service.intelligence.SmartSuggestionsService;
import android.service.intelligence.SnapshotData;
import android.util.Slog;
import android.view.autofill.AutofillId;
@@ -59,7 +59,7 @@
mService = service;
mId = Preconditions.checkNotNull(sessionId);
mRemoteService = new RemoteIntelligenceService(context,
- IntelligenceService.SERVICE_INTERFACE, serviceComponentName, userId, this,
+ SmartSuggestionsService.SERVICE_INTERFACE, serviceComponentName, userId, this,
bindInstantServiceAllowed, verbose);
mInterationContext = new InteractionContext(appComponentName, taskId, displayId, flags);
}
@@ -72,7 +72,7 @@
}
/**
- * Notifies the {@link IntelligenceService} that the service started.
+ * Notifies the {@link SmartSuggestionsService} that the service started.
*/
@GuardedBy("mLock")
public void notifySessionStartedLocked() {
@@ -80,14 +80,14 @@
}
/**
- * Notifies the {@link IntelligenceService} of a batch of events.
+ * Notifies the {@link SmartSuggestionsService} of a batch of events.
*/
public void sendEventsLocked(@NonNull List<ContentCaptureEvent> events) {
mRemoteService.onContentCaptureEventsRequest(mId, events);
}
/**
- * Notifies the {@link IntelligenceService} of a snapshot of an activity.
+ * Notifies the {@link SmartSuggestionsService} of a snapshot of an activity.
*/
@GuardedBy("mLock")
public void sendActivitySnapshotLocked(@NonNull SnapshotData snapshotData) {
@@ -110,7 +110,7 @@
* Cleans up the session and removes it from the service.
*
* @param notifyRemoteService whether it should trigger a {@link
- * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
+ * SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)}
* request.
*/
@GuardedBy("mLock")
@@ -126,7 +126,7 @@
* Cleans up the session, but not removes it from the service.
*
* @param notifyRemoteService whether it should trigger a {@link
- * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
+ * SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)}
* request.
*/
@GuardedBy("mLock")
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
index 9fd797d..e0d47d2 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java
@@ -16,7 +16,7 @@
package com.android.server.intelligence;
-import static android.content.Context.INTELLIGENCE_MANAGER_SERVICE;
+import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -50,6 +50,7 @@
* <p>The data collected by this service can be analyzed and combined with other sources to provide
* contextual data in other areas of the system such as Autofill.
*/
+//TODO(b/111276913): rename once the final name is defined
public final class IntelligenceManagerService extends
AbstractMasterSystemService<IntelligenceManagerService, IntelligencePerUserService> {
@@ -67,7 +68,7 @@
@Override // from AbstractMasterSystemService
protected String getServiceSettingsProperty() {
// TODO(b/111276913): STOPSHIP temporary settings, until it's set by resourcs + cmd
- return "intel_service";
+ return "smart_suggestions_service";
}
@Override // from AbstractMasterSystemService
@@ -78,7 +79,7 @@
@Override // from SystemService
public void onStart() {
- publishBinderService(INTELLIGENCE_MANAGER_SERVICE,
+ publishBinderService(CONTENT_CAPTURE_MANAGER_SERVICE,
new IntelligenceManagerServiceStub());
publishLocalService(IntelligenceManagerInternal.class, mLocalService);
}
diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
index 9ab7e58..e3b09c6 100644
--- a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
+++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java
@@ -41,7 +41,7 @@
import android.view.autofill.AutofillId;
import android.view.autofill.IAutoFillManagerClient;
import android.view.intelligence.ContentCaptureEvent;
-import android.view.intelligence.IntelligenceManager;
+import android.view.intelligence.ContentCaptureManager;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
@@ -54,6 +54,7 @@
/**
* Per-user instance of {@link IntelligenceManagerService}.
*/
+//TODO(b/111276913): rename once the final name is defined
final class IntelligencePerUserService
extends AbstractPerUserSystemService<IntelligencePerUserService,
IntelligenceManagerService> {
@@ -86,16 +87,23 @@
Slog.w(TAG, "Could not get service for " + serviceComponent + ": " + e);
return null;
}
- if (!Manifest.permission.BIND_INTELLIGENCE_SERVICE.equals(si.permission)) {
- Slog.w(TAG, "IntelligenceService from '" + si.packageName
+ if (!Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE.equals(si.permission)) {
+ Slog.w(TAG, "SmartSuggestionsService from '" + si.packageName
+ "' does not require permission "
- + Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+ + Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE);
throw new SecurityException("Service does not require permission "
- + Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+ + Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE);
}
return si;
}
+ @Override // from PerUserSystemService
+ @GuardedBy("mLock")
+ protected boolean updateLocked(boolean disabled) {
+ destroyLocked();
+ return super.updateLocked(disabled);
+ }
+
// TODO(b/111276913): log metrics
@GuardedBy("mLock")
public void startSessionLocked(@NonNull IBinder activityToken,
@@ -103,7 +111,7 @@
@NonNull InteractionSessionId sessionId, int flags,
@NonNull IResultReceiver resultReceiver) {
if (!isEnabledLocked()) {
- sendToClient(resultReceiver, IntelligenceManager.STATE_DISABLED);
+ sendToClient(resultReceiver, ContentCaptureManager.STATE_DISABLED);
return;
}
final ComponentName serviceComponentName = getServiceComponentName();
@@ -126,7 +134,7 @@
// TODO(b/111276913): check if local ids match and decide what to do if they don't
// TODO(b/111276913): should we call session.notifySessionStartedLocked() again??
// if not, move notifySessionStartedLocked() into session constructor
- sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
+ sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE);
return;
}
@@ -142,7 +150,7 @@
}
mSessions.put(sessionId, session);
session.notifySessionStartedLocked();
- sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
+ sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE);
}
// TODO(b/111276913): log metrics
@@ -192,7 +200,7 @@
return;
}
if (mMaster.verbose) {
- Slog.v(TAG, "sendEvents(): id=" + sessionId + "; events =" + events.size());
+ Slog.v(TAG, "sendEvents(): id=" + sessionId + ", events=" + events.size());
}
session.sendEventsLocked(events);
}
diff --git a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
index 00c5b6a..d9f4f20 100644
--- a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
+++ b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java
@@ -23,6 +23,7 @@
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
+import android.service.intelligence.ContentCaptureEventsRequest;
import android.service.intelligence.IIntelligenceService;
import android.service.intelligence.InteractionContext;
import android.service.intelligence.InteractionSessionId;
@@ -35,11 +36,13 @@
import android.view.intelligence.ContentCaptureEvent;
import com.android.internal.os.IResultReceiver;
-import com.android.server.AbstractRemoteService;
+import com.android.server.AbstractMultiplePendingRequestsRemoteService;
import java.util.List;
-final class RemoteIntelligenceService extends AbstractRemoteService {
+//TODO(b/111276913): rename once the final name is defined
+final class RemoteIntelligenceService
+ extends AbstractMultiplePendingRequestsRemoteService<RemoteIntelligenceService> {
private static final String TAG = "RemoteIntelligenceService";
@@ -54,7 +57,7 @@
RemoteIntelligenceServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
boolean verbose) {
super(context, serviceInterface, componentName, userId, callbacks,
- bindInstantServiceAllowed, verbose);
+ bindInstantServiceAllowed, verbose, /* initialCapacity= */ 2);
mCallbacks = callbacks;
}
@@ -194,7 +197,8 @@
@Override // from MyPendingRequest
public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException {
- remoteService.mService.onContentCaptureEvents(mSessionId, mEvents);
+ remoteService.mService.onContentCaptureEventsRequest(mSessionId,
+ new ContentCaptureEventsRequest(mEvents));
}
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 56f7cff..f3704d8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1503,6 +1503,14 @@
}
traceEnd();
+ traceBeginAndSlog("RuntimeService");
+ try {
+ ServiceManager.addService("runtime", new RuntimeService(context));
+ } catch (Throwable e) {
+ reportWtf("starting RuntimeService", e);
+ }
+ traceEnd();
+
// timezone.RulesManagerService will prevent a device starting up if the chain of trust
// required for safe time zone updates might be broken. RuleManagerService cannot do
// this check when mOnlyCore == true, so we don't enable the service in this case.
diff --git a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
index 7cf7df13..5077f92 100644
--- a/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/ThermalManagerServiceTest.java
@@ -271,7 +271,7 @@
int status = Temperature.THROTTLING_WARNING;
Temperature newSkin = new Temperature(100, Temperature.TYPE_SKIN, "skin1", status);
mFakeHal.mCallback.onValues(newSkin);
- assertEquals(status, mService.mService.getCurrentStatus());
+ assertEquals(status, mService.mService.getCurrentThermalStatus());
}
@Test
@@ -294,6 +294,6 @@
assertEquals(0, mService.mService.getCurrentTemperatures().size());
assertEquals(0,
mService.mService.getCurrentTemperaturesWithType(Temperature.TYPE_SKIN).size());
- assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentStatus());
+ assertEquals(Temperature.THROTTLING_NONE, mService.mService.getCurrentThermalStatus());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
index b94f472..845a09f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java
@@ -95,52 +95,6 @@
}
@Test
- public void layoutWindowLw_appDrawsBars() {
- mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- addWindow(mWindow);
-
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
- }
-
- @Test
- public void layoutWindowLw_appWontDrawBars() {
- mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- addWindow(mWindow);
-
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
- }
-
- @Test
- public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
- mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
- mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
- addWindow(mWindow);
-
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
-
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
- }
-
- @Test
public void addingWindow_doesNotTamperWithSysuiFlags() {
mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
addWindow(mWindow);
@@ -150,253 +104,331 @@
}
@Test
+ public void layoutWindowLw_appDrawsBars() {
+ synchronized (mWm.mGlobalLock) {
+ mWindow.mAttrs.flags |= FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ addWindow(mWindow);
+
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+ }
+ }
+
+ @Test
+ public void layoutWindowLw_appWontDrawBars() {
+ synchronized (mWm.mGlobalLock) {
+ mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ addWindow(mWindow);
+
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+ }
+ }
+
+ @Test
+ public void layoutWindowLw_appWontDrawBars_forceStatus() throws Exception {
+ synchronized (mWm.mGlobalLock) {
+ mWindow.mAttrs.flags &= ~FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
+ mWindow.mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
+ addWindow(mWindow);
+
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, NAV_BAR_HEIGHT);
+ }
+ }
+
+ @Test
public void layoutWindowLw_withDisplayCutout() {
- addDisplayCutout();
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
- addWindow(mWindow);
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_never() {
- addDisplayCutout();
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
- mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
- addWindow(mWindow);
+ mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_layoutFullscreen() {
- addDisplayCutout();
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, 0, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreen() {
- addDisplayCutout();
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreenInCutout() {
- addDisplayCutout();
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
- mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_FULLSCREEN;
+ mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getStableFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getContentFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), 0, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_landscape() {
- addDisplayCutout();
- setRotation(ROTATION_90);
- addWindow(mWindow);
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
+ setRotation(ROTATION_90);
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_seascape() {
- addDisplayCutout();
- setRotation(ROTATION_270);
- addWindow(mWindow);
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
+ setRotation(ROTATION_270);
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+ assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getDisplayFrameLw(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreen_landscape() {
- addDisplayCutout();
- setRotation(ROTATION_90);
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
+ setRotation(ROTATION_90);
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_floatingInScreen() {
- addDisplayCutout();
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
- mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
- mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
- mWindow.mAttrs.width = DISPLAY_WIDTH;
- mWindow.mAttrs.height = DISPLAY_HEIGHT;
- addWindow(mWindow);
+ mWindow.mAttrs.flags = FLAG_LAYOUT_IN_SCREEN;
+ mWindow.mAttrs.type = TYPE_APPLICATION_OVERLAY;
+ mWindow.mAttrs.width = DISPLAY_WIDTH;
+ mWindow.mAttrs.height = DISPLAY_HEIGHT;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
- assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mWindow.getDisplayFrameLw(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ }
}
@Test
public void layoutWindowLw_withDisplayCutout_fullscreenInCutout_landscape() {
- addDisplayCutout();
- setRotation(ROTATION_90);
+ synchronized (mWm.mGlobalLock) {
+ addDisplayCutout();
+ setRotation(ROTATION_90);
- mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
- mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
- addWindow(mWindow);
+ mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
+ mWindow.mAttrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+ addWindow(mWindow);
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);
- assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
- assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getContentFrameLw(),
- DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
- assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0);
+ assertInsetBy(mWindow.getStableFrameLw(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getContentFrameLw(),
+ DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
+ assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);
+ }
}
@Test
public void layoutHint_appWindow() {
- // Initialize DisplayFrames
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ synchronized (mWm.mGlobalLock) {
+ // Initialize DisplayFrames
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- final Rect outFrame = new Rect();
- final Rect outContentInsets = new Rect();
- final Rect outStableInsets = new Rect();
- final Rect outOutsets = new Rect();
- final DisplayCutout.ParcelableWrapper outDisplayCutout =
- new DisplayCutout.ParcelableWrapper();
+ final Rect outFrame = new Rect();
+ final Rect outContentInsets = new Rect();
+ final Rect outStableInsets = new Rect();
+ final Rect outOutsets = new Rect();
+ final DisplayCutout.ParcelableWrapper outDisplayCutout =
+ new DisplayCutout.ParcelableWrapper();
- mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
- false /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
- outDisplayCutout);
+ mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, null, mFrames,
+ false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+ outOutsets, outDisplayCutout);
- assertThat(outFrame, is(mFrames.mUnrestricted));
- assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
- assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
- assertThat(outOutsets, is(new Rect()));
- assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+ assertThat(outFrame, is(mFrames.mUnrestricted));
+ assertThat(outContentInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+ assertThat(outStableInsets, is(new Rect(0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT)));
+ assertThat(outOutsets, is(new Rect()));
+ assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+ }
}
@Test
public void layoutHint_appWindowInTask() {
- // Initialize DisplayFrames
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ synchronized (mWm.mGlobalLock) {
+ // Initialize DisplayFrames
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- final Rect taskBounds = new Rect(100, 100, 200, 200);
+ final Rect taskBounds = new Rect(100, 100, 200, 200);
- final Rect outFrame = new Rect();
- final Rect outContentInsets = new Rect();
- final Rect outStableInsets = new Rect();
- final Rect outOutsets = new Rect();
- final DisplayCutout.ParcelableWrapper outDisplayCutout =
- new DisplayCutout.ParcelableWrapper();
+ final Rect outFrame = new Rect();
+ final Rect outContentInsets = new Rect();
+ final Rect outStableInsets = new Rect();
+ final Rect outOutsets = new Rect();
+ final DisplayCutout.ParcelableWrapper outDisplayCutout =
+ new DisplayCutout.ParcelableWrapper();
- mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
- false /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
- outDisplayCutout);
+ mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+ false /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+ outOutsets, outDisplayCutout);
- assertThat(outFrame, is(taskBounds));
- assertThat(outContentInsets, is(new Rect()));
- assertThat(outStableInsets, is(new Rect()));
- assertThat(outOutsets, is(new Rect()));
- assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+ assertThat(outFrame, is(taskBounds));
+ assertThat(outContentInsets, is(new Rect()));
+ assertThat(outStableInsets, is(new Rect()));
+ assertThat(outOutsets, is(new Rect()));
+ assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+ }
}
@Test
public void layoutHint_appWindowInTask_outsideContentFrame() {
- // Initialize DisplayFrames
- mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
+ synchronized (mWm.mGlobalLock) {
+ // Initialize DisplayFrames
+ mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);
- // Task is in the nav bar area (usually does not happen, but this is similar enough to the
- // possible overlap with the IME)
- final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
- 200, mFrames.mContent.bottom + 10);
+ // Task is in the nav bar area (usually does not happen, but this is similar enough to
+ // the possible overlap with the IME)
+ final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1,
+ 200, mFrames.mContent.bottom + 10);
- final Rect outFrame = new Rect();
- final Rect outContentInsets = new Rect();
- final Rect outStableInsets = new Rect();
- final Rect outOutsets = new Rect();
- final DisplayCutout.ParcelableWrapper outDisplayCutout =
- new DisplayCutout.ParcelableWrapper();
+ final Rect outFrame = new Rect();
+ final Rect outContentInsets = new Rect();
+ final Rect outStableInsets = new Rect();
+ final Rect outOutsets = new Rect();
+ final DisplayCutout.ParcelableWrapper outDisplayCutout =
+ new DisplayCutout.ParcelableWrapper();
- mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
- true /* floatingStack */, outFrame, outContentInsets, outStableInsets, outOutsets,
- outDisplayCutout);
+ mDisplayPolicy.getLayoutHintLw(mWindow.mAttrs, taskBounds, mFrames,
+ true /* floatingStack */, outFrame, outContentInsets, outStableInsets,
+ outOutsets, outDisplayCutout);
- assertThat(outFrame, is(taskBounds));
- assertThat(outContentInsets, is(new Rect()));
- assertThat(outStableInsets, is(new Rect()));
- assertThat(outOutsets, is(new Rect()));
- assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+ assertThat(outFrame, is(taskBounds));
+ assertThat(outContentInsets, is(new Rect()));
+ assertThat(outStableInsets, is(new Rect()));
+ assertThat(outOutsets, is(new Rect()));
+ assertThat(outDisplayCutout, is(new DisplayCutout.ParcelableWrapper()));
+ }
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
index c11e606..88215449 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsSourceProviderTest.java
@@ -29,6 +29,7 @@
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
+import org.junit.Before;
import org.junit.Test;
@SmallTest
@@ -36,8 +37,15 @@
@Presubmit
public class InsetsSourceProviderTest extends WindowTestsBase {
- private InsetsSourceProvider mProvider = new InsetsSourceProvider(
- new InsetsSource(TYPE_TOP_BAR));
+ private InsetsSource mSource = new InsetsSource(TYPE_TOP_BAR);
+ private InsetsSourceProvider mProvider;
+
+ @Before
+ public void setUp() throws Exception {
+ mSource.setVisible(true);
+ mProvider = new InsetsSourceProvider(mSource,
+ mDisplayContent.getInsetsStateController(), mDisplayContent);
+ }
@Test
public void testPostLayout() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index 331622c..11526a8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -23,8 +23,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import android.platform.test.annotations.Presubmit;
+import android.view.InsetsSourceControl;
import android.view.InsetsState;
import androidx.test.filters.FlakyTest;
@@ -41,12 +43,9 @@
public void testStripForDispatch_notOwn() {
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
- mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
- .setWindow(topBar, null);
- topBar.setInsetProvider(
- mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR));
- assertNotNull(mDisplayContent.getInsetsStateController().getInsetsForDispatch(app)
- .getSource(TYPE_TOP_BAR));
+ getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+ topBar.setInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
+ assertNotNull(getController().getInsetsForDispatch(app).getSource(TYPE_TOP_BAR));
}
@Test
@@ -54,10 +53,8 @@
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
.setWindow(topBar, null);
- topBar.setInsetProvider(
- mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR));
- assertEquals(new InsetsState(),
- mDisplayContent.getInsetsStateController().getInsetsForDispatch(topBar));
+ topBar.setInsetProvider(getController().getSourceProvider(TYPE_TOP_BAR));
+ assertEquals(new InsetsState(), getController().getInsetsForDispatch(topBar));
}
@Test
@@ -65,13 +62,47 @@
final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState ime = createWindow(null, TYPE_APPLICATION, "parentWindow");
- mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_TOP_BAR)
- .setWindow(topBar, null);
- mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_NAVIGATION_BAR)
- .setWindow(navBar, null);
- mDisplayContent.getInsetsStateController().getSourceProvider(TYPE_IME)
- .setWindow(ime, null);
- assertEquals(new InsetsState(),
- mDisplayContent.getInsetsStateController().getInsetsForDispatch(navBar));
+ getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+ getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
+ getController().getSourceProvider(TYPE_IME).setWindow(ime, null);
+ assertEquals(new InsetsState(), getController().getInsetsForDispatch(navBar));
+ }
+
+ @Test
+ public void testBarControllingWinChanged() {
+ final WindowState navBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+ final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+ getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+ getController().getSourceProvider(TYPE_NAVIGATION_BAR).setWindow(navBar, null);
+ getController().onBarControllingWindowChanged(app);
+ InsetsSourceControl[] controls = getController().getControlsForDispatch(app);
+ assertEquals(2, controls.length);
+ }
+
+ @Test
+ public void testControlRevoked() {
+ final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+ getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+ getController().onBarControllingWindowChanged(app);
+ assertNotNull(getController().getControlsForDispatch(app));
+ getController().onBarControllingWindowChanged(null);
+ assertNull(getController().getControlsForDispatch(app));
+ }
+
+ @Test
+ public void testControlRevoked_animation() {
+ final WindowState topBar = createWindow(null, TYPE_APPLICATION, "parentWindow");
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "parentWindow");
+ getController().getSourceProvider(TYPE_TOP_BAR).setWindow(topBar, null);
+ getController().onBarControllingWindowChanged(app);
+ assertNotNull(getController().getControlsForDispatch(app));
+ topBar.cancelAnimation();
+ assertNull(getController().getControlsForDispatch(app));
+ }
+
+ private InsetsStateController getController() {
+ return mDisplayContent.getInsetsStateController();
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index 432af0d..29738ff 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -24,6 +24,7 @@
import android.view.DisplayCutout;
import android.view.DragEvent;
import android.view.IWindow;
+import android.view.InsetsSourceControl;
import android.view.InsetsState;
import com.android.internal.os.IResultReceiver;
@@ -40,11 +41,17 @@
Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId,
DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException {
}
+
@Override
public void insetsChanged(InsetsState insetsState) throws RemoteException {
}
@Override
+ public void insetsControlChanged(InsetsState insetsState, InsetsSourceControl[] activeControls)
+ throws RemoteException {
+ }
+
+ @Override
public void moved(int newX, int newY) throws RemoteException {
}
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index 0c40a6b..de40e0d 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -24,7 +24,6 @@
"libdexfile",
"slicer",
],
- cppflags: ["-std=c++17"],
}
cc_library_host_static {
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.aidl b/telephony/java/android/telephony/AvailableNetworkInfo.aidl
new file mode 100644
index 0000000..1d4378c
--- /dev/null
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable AvailableNetworkInfo;
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
new file mode 100644
index 0000000..fe07370
--- /dev/null
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Defines available network information which includes corresponding subscription id,
+ * network plmns and corresponding priority to be used for network selection by Alternative Network
+ * Service.
+ */
+public final class AvailableNetworkInfo implements Parcelable {
+
+ /*
+ * Defines number of priority level high.
+ */
+ public static final int PRIORITY_HIGH = 1;
+
+ /*
+ * Defines number of priority level medium.
+ */
+ public static final int PRIORITY_MED = 2;
+
+ /*
+ * Defines number of priority level low.
+ */
+ public static final int PRIORITY_LOW = 3;
+
+ /**
+ * subscription Id of the available network. This value must be one of the entry retrieved from
+ * {@link SubscriptionManager#getOpportunisticSubscriptions}
+ */
+ private int mSubId;
+
+ /**
+ * Priority for the subscription id.
+ * Priorities are in the range of 1 to 3 where 1
+ * has the highest priority.
+ */
+ private int mPriority;
+
+ /**
+ * Describes the List of PLMN ids (MCC-MNC) associated with mSubId.
+ * If this entry is left empty, then the platform software will not scan the network
+ * to revalidate the input.
+ */
+ private ArrayList<String> mMccMncs;
+
+ /**
+ * Return subscription Id of the available network.
+ * This value must be one of the entry retrieved from
+ * {@link SubscriptionManager#getOpportunisticSubscriptions}
+ * @return subscription id
+ */
+ public int getSubId() {
+ return mSubId;
+ }
+
+ /**
+ * Return priority for the subscription id. Valid value will be within
+ * [{@link AvailableNetworkInfo#PRIORITY_HIGH}, {@link AvailableNetworkInfo#PRIORITY_LOW}]
+ * @return priority level
+ */
+ public int getPriority() {
+ return mPriority;
+ }
+
+ /**
+ * Return List of PLMN ids (MCC-MNC) associated with the sub ID.
+ * If this entry is left empty, then the platform software will not scan the network
+ * to revalidate the input.
+ * @return list of PLMN ids
+ */
+ public List<String> getMccMncs() {
+ return (List<String>) mMccMncs.clone();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mSubId);
+ dest.writeInt(mPriority);
+ dest.writeStringList(mMccMncs);
+ }
+
+ private AvailableNetworkInfo(Parcel in) {
+ mSubId = in.readInt();
+ mPriority = in.readInt();
+ in.readStringList(mMccMncs);
+ }
+
+ public AvailableNetworkInfo(int subId, int priority, ArrayList<String> mccMncs) {
+ mSubId = subId;
+ mPriority = priority;
+ mMccMncs = new ArrayList<String>(mccMncs);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ AvailableNetworkInfo ani;
+
+ try {
+ ani = (AvailableNetworkInfo) o;
+ } catch (ClassCastException ex) {
+ return false;
+ }
+
+ if (o == null) {
+ return false;
+ }
+
+ return (mSubId == ani.mSubId
+ && mPriority == ani.mPriority
+ && (((mMccMncs != null)
+ && mMccMncs.equals(ani.mMccMncs))));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mSubId, mPriority, mMccMncs);
+ }
+
+ public static final Parcelable.Creator<AvailableNetworkInfo> CREATOR =
+ new Creator<AvailableNetworkInfo>() {
+ @Override
+ public AvailableNetworkInfo createFromParcel(Parcel in) {
+ return new AvailableNetworkInfo(in);
+ }
+
+ @Override
+ public AvailableNetworkInfo[] newArray(int size) {
+ return new AvailableNetworkInfo[size];
+ }
+ };
+
+ @Override
+ public String toString() {
+ return ("AvailableNetworkInfo:"
+ + " mSubId: " + mSubId
+ + " mPriority: " + mPriority
+ + " mMccMncs: " + Arrays.toString(mMccMncs.toArray()));
+ }
+}
+
diff --git a/telephony/java/android/telephony/NumberVerificationCallback.java b/telephony/java/android/telephony/NumberVerificationCallback.java
new file mode 100644
index 0000000..b00c573
--- /dev/null
+++ b/telephony/java/android/telephony/NumberVerificationCallback.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * A callback for number verification. After a request for number verification is received,
+ * the system will call {@link #onCallReceived(String)} if a phone call was received from a number
+ * matching the provided {@link PhoneNumberRange} or it will call {@link #onVerificationFailed(int)}
+ * if an error occurs.
+ * @hide
+ */
+@SystemApi
+public interface NumberVerificationCallback {
+ /** @hide */
+ @IntDef(value = {REASON_UNSPECIFIED, REASON_TIMED_OUT, REASON_NETWORK_NOT_AVAILABLE,
+ REASON_TOO_MANY_CALLS, REASON_CONCURRENT_REQUESTS, REASON_IN_ECBM,
+ REASON_IN_EMERGENCY_CALL},
+ prefix = {"REASON_"})
+ @interface NumberVerificationFailureReason {}
+
+ /**
+ * Verification failed for an unspecified reason.
+ */
+ int REASON_UNSPECIFIED = 0;
+
+ /**
+ * Verification failed because no phone call was received from a matching number within the
+ * provided timeout.
+ */
+ int REASON_TIMED_OUT = 1;
+
+ /**
+ * Verification failed because no cellular voice network is available.
+ */
+ int REASON_NETWORK_NOT_AVAILABLE = 2;
+
+ /**
+ * Verification failed because there are currently too many ongoing phone calls for a new
+ * incoming phone call to be received.
+ */
+ int REASON_TOO_MANY_CALLS = 3;
+
+ /**
+ * Verification failed because a previous request for verification has not yet completed.
+ */
+ int REASON_CONCURRENT_REQUESTS = 4;
+
+ /**
+ * Verification failed because the phone is in emergency callback mode.
+ */
+ int REASON_IN_ECBM = 5;
+
+ /**
+ * Verification failed because the phone is currently in an emergency call.
+ */
+ int REASON_IN_EMERGENCY_CALL = 6;
+
+ /**
+ * Called when the device receives a phone call from the provided {@link PhoneNumberRange}.
+ * @param phoneNumber The phone number within the range that called. May or may not contain the
+ * country code, but will be entirely numeric.
+ */
+ default void onCallReceived(@NonNull String phoneNumber) { }
+
+ /**
+ * Called when verification fails for some reason.
+ * @param reason The reason for failure.
+ */
+ default void onVerificationFailed(@NumberVerificationFailureReason int reason) { }
+}
diff --git a/telephony/java/android/telephony/PhoneNumberRange.aidl b/telephony/java/android/telephony/PhoneNumberRange.aidl
new file mode 100644
index 0000000..b0727be
--- /dev/null
+++ b/telephony/java/android/telephony/PhoneNumberRange.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable PhoneNumberRange;
diff --git a/telephony/java/android/telephony/PhoneNumberRange.java b/telephony/java/android/telephony/PhoneNumberRange.java
new file mode 100644
index 0000000..d65156f
--- /dev/null
+++ b/telephony/java/android/telephony/PhoneNumberRange.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.util.Objects;
+import java.util.regex.Pattern;
+
+/**
+ * This class is used to represent a range of phone numbers. Each range corresponds to a contiguous
+ * block of phone numbers.
+ *
+ * Example:
+ * {@code
+ * {
+ * mCountryCode = "1"
+ * mPrefix = "650555"
+ * mLowerBound = "0055"
+ * mUpperBound = "0899"
+ * }
+ * }
+ * would match 16505550089 and 6505550472, but not 63827593759 or 16505550900
+ * @hide
+ */
+@SystemApi
+public final class PhoneNumberRange implements Parcelable {
+ public static final Creator<PhoneNumberRange> CREATOR = new Creator<PhoneNumberRange>() {
+ @Override
+ public PhoneNumberRange createFromParcel(Parcel in) {
+ return new PhoneNumberRange(in);
+ }
+
+ @Override
+ public PhoneNumberRange[] newArray(int size) {
+ return new PhoneNumberRange[size];
+ }
+ };
+
+ private final String mCountryCode;
+ private final String mPrefix;
+ private final String mLowerBound;
+ private final String mUpperBound;
+
+ /**
+ * @param countryCode The country code, omitting the leading "+"
+ * @param prefix A prefix that all numbers matching the range must have.
+ * @param lowerBound When concatenated with the prefix, represents the lower bound of phone
+ * numbers that match this range.
+ * @param upperBound When concatenated with the prefix, represents the upper bound of phone
+ * numbers that match this range.
+ */
+ public PhoneNumberRange(@NonNull String countryCode, @NonNull String prefix,
+ @NonNull String lowerBound, @NonNull String upperBound) {
+ validateLowerAndUpperBounds(lowerBound, upperBound);
+ if (!Pattern.matches("[0-9]+", countryCode)) {
+ throw new IllegalArgumentException("Country code must be all numeric");
+ }
+ if (!Pattern.matches("[0-9]+", prefix)) {
+ throw new IllegalArgumentException("Prefix must be all numeric");
+ }
+ mCountryCode = countryCode;
+ mPrefix = prefix;
+ mLowerBound = lowerBound;
+ mUpperBound = upperBound;
+ }
+
+ private PhoneNumberRange(Parcel in) {
+ mCountryCode = in.readStringNoHelper();
+ mPrefix = in.readStringNoHelper();
+ mLowerBound = in.readStringNoHelper();
+ mUpperBound = in.readStringNoHelper();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeStringNoHelper(mCountryCode);
+ dest.writeStringNoHelper(mPrefix);
+ dest.writeStringNoHelper(mLowerBound);
+ dest.writeStringNoHelper(mUpperBound);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PhoneNumberRange that = (PhoneNumberRange) o;
+ return Objects.equals(mCountryCode, that.mCountryCode)
+ && Objects.equals(mPrefix, that.mPrefix)
+ && Objects.equals(mLowerBound, that.mLowerBound)
+ && Objects.equals(mUpperBound, that.mUpperBound);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mCountryCode, mPrefix, mLowerBound, mUpperBound);
+ }
+
+ @Override
+ public String toString() {
+ return "PhoneNumberRange{"
+ + "mCountryCode='" + mCountryCode + '\''
+ + ", mPrefix='" + mPrefix + '\''
+ + ", mLowerBound='" + mLowerBound + '\''
+ + ", mUpperBound='" + mUpperBound + '\''
+ + '}';
+ }
+
+ private void validateLowerAndUpperBounds(String lowerBound, String upperBound) {
+ if (lowerBound.length() != upperBound.length()) {
+ throw new IllegalArgumentException("Lower and upper bounds must have the same length");
+ }
+ if (!Pattern.matches("[0-9]+", lowerBound)) {
+ throw new IllegalArgumentException("Lower bound must be all numeric");
+ }
+ if (!Pattern.matches("[0-9]+", upperBound)) {
+ throw new IllegalArgumentException("Upper bound must be all numeric");
+ }
+ if (Integer.parseInt(lowerBound) > Integer.parseInt(upperBound)) {
+ throw new IllegalArgumentException("Lower bound must be lower than upper bound");
+ }
+ }
+
+ /**
+ * Checks to see if the provided phone number matches this range.
+ * @param number A phone number, with or without separators or a country code.
+ * @return {@code true} if the number matches, {@code false} otherwise.
+ */
+ public boolean matches(String number) {
+ // Check the prefix, make sure it matches either with or without the country code.
+ String normalizedNumber = number.replaceAll("[^0-9]", "");
+ String prefixWithCountryCode = mCountryCode + mPrefix;
+ String numberPostfix;
+ if (normalizedNumber.startsWith(prefixWithCountryCode)) {
+ numberPostfix = normalizedNumber.substring(prefixWithCountryCode.length());
+ } else if (normalizedNumber.startsWith(mPrefix)) {
+ numberPostfix = normalizedNumber.substring(mPrefix.length());
+ } else {
+ return false;
+ }
+
+ // Next check the postfix to make sure it lies within the bounds.
+ try {
+ int lower = Integer.parseInt(mLowerBound);
+ int upper = Integer.parseInt(mUpperBound);
+ int numberToCheck = Integer.parseInt(numberPostfix);
+ return numberToCheck <= upper && numberToCheck >= lower;
+ } catch (NumberFormatException e) {
+ Log.e(PhoneNumberRange.class.getSimpleName(), "Invalid bounds or number.", e);
+ return false;
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index b41e14e..bacfe61a 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -150,6 +150,11 @@
private String mGroupUUID;
/**
+ * A property in opportunistic subscription to indicate whether it is metered or not.
+ */
+ private boolean mIsMetered;
+
+ /**
* @hide
*/
public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
@@ -158,7 +163,7 @@
@Nullable UiccAccessRule[] accessRules, String cardId) {
this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardId,
- false, null);
+ false, null, true);
}
/**
@@ -168,7 +173,7 @@
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
@Nullable UiccAccessRule[] accessRules, String cardId, boolean isOpportunistic,
- @Nullable String groupUUID) {
+ @Nullable String groupUUID, boolean isMetered) {
this.mId = id;
this.mIccId = iccId;
this.mSimSlotIndex = simSlotIndex;
@@ -187,8 +192,10 @@
this.mCardId = cardId;
this.mIsOpportunistic = isOpportunistic;
this.mGroupUUID = groupUUID;
+ this.mIsMetered = isMetered;
}
+
/**
* @return the subscription ID.
*/
@@ -403,6 +410,18 @@
}
/**
+ * Used in opportunistic subscription ({@link #isOpportunistic()}) to indicate whether it's
+ * metered or not.This is one of the factors when deciding to switch to the subscription.
+ * (a non-metered subscription, for example, would likely be preferred over a metered one).
+ *
+ * @return whether subscription is metered.
+ * @hide
+ */
+ public boolean isMetered() {
+ return mIsMetered;
+ }
+
+ /**
* Checks whether the app with the given context is authorized to manage this subscription
* according to its metadata. Only supported for embedded subscriptions (if {@link #isEmbedded}
* returns true).
@@ -496,10 +515,11 @@
String cardId = source.readString();
boolean isOpportunistic = source.readBoolean();
String groupUUID = source.readString();
+ boolean isMetered = source.readBoolean();
return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
- isEmbedded, accessRules, cardId, isOpportunistic, groupUUID);
+ isEmbedded, accessRules, cardId, isOpportunistic, groupUUID, isMetered);
}
@Override
@@ -528,6 +548,7 @@
dest.writeString(mCardId);
dest.writeBoolean(mIsOpportunistic);
dest.writeString(mGroupUUID);
+ dest.writeBoolean(mIsMetered);
}
@Override
@@ -561,14 +582,14 @@
+ " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
+ " accessRules " + Arrays.toString(mAccessRules)
+ " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic
- + " mGroupUUID=" + mGroupUUID + "}";
+ + " mGroupUUID=" + mGroupUUID + " isMetered=" + mIsMetered + "}";
}
@Override
public int hashCode() {
return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
- mIsOpportunistic, mGroupUUID, mIccId, mNumber, mMcc, mMnc, mCountryIso,
- mCardId, mDisplayName, mCarrierName, mAccessRules);
+ mIsOpportunistic, mGroupUUID, mIsMetered, mIccId, mNumber, mMcc, mMnc,
+ mCountryIso, mCardId, mDisplayName, mCarrierName, mAccessRules);
}
@Override
@@ -591,6 +612,7 @@
&& mIsEmbedded == toCompare.mIsEmbedded
&& mIsOpportunistic == toCompare.mIsOpportunistic
&& Objects.equals(mGroupUUID, toCompare.mGroupUUID)
+ && mIsMetered == toCompare.mIsMetered
&& Objects.equals(mIccId, toCompare.mIccId)
&& Objects.equals(mNumber, toCompare.mNumber)
&& Objects.equals(mMcc, toCompare.mMcc)
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 45cfe1e..4b24646 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -576,7 +576,12 @@
* @hide
*/
public static final String GROUP_UUID = "group_uuid";
-
+ /**
+ * TelephonyProvider column name for whether a subscription is metered or not, that is, whether
+ * the network it connects to charges for subscription or not. For example, paid CBRS or unpaid.
+ * @hide
+ */
+ public static final String IS_METERED = "is_metered";
/**
* Broadcast Action: The user has changed one of the default subs related to
* data, phone calls, or sms</p>
@@ -2403,6 +2408,21 @@
return groupUUID;
}
+ /**
+ * Set metered by simInfo index
+ *
+ * @param isMetered whether it’s a metered subscription.
+ * @param subId the unique SubscriptionInfo index in database
+ * @return the number of records updated
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public int setMetered(boolean isMetered, int subId) {
+ if (VDBG) logd("[setIsMetered]+ isMetered:" + isMetered + " subId:" + subId);
+ return setSubscriptionPropertyHelper(subId, "setIsMetered",
+ (iSub)-> iSub.setMetered(isMetered, subId));
+ }
+
private interface CallISubMethodHelper {
int callMethod(ISub iSub) throws RemoteException;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d54da09..45d914e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -77,6 +77,7 @@
import com.android.internal.telecom.ITelecomService;
import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.IAns;
+import com.android.internal.telephony.INumberVerificationCallback;
import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephonyRegistry;
@@ -1341,6 +1342,13 @@
*/
public static final String EXTRA_RECOVERY_ACTION = "recoveryAction";
+ /**
+ * The max value for the timeout passed in {@link #requestNumberVerification}.
+ * @hide
+ */
+ @SystemApi
+ public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000;
+
//
//
// Device Info
@@ -5372,7 +5380,7 @@
/**
* Rollback modem configurations to factory default except some config which are in whitelist.
- * Used for device configuration by some CDMA operators.
+ * Used for device configuration by some carriers.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -5399,7 +5407,7 @@
}
/**
- * Generate a radio modem reset. Used for device configuration by some CDMA operators.
+ * Generate a radio modem reset. Used for device configuration by some carriers.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -5503,6 +5511,52 @@
}
/**
+ * Request that the next incoming call from a number matching {@code range} be intercepted.
+ *
+ * This API is intended for OEMs to provide a service for apps to verify the device's phone
+ * number. When called, the Telephony stack will store the provided {@link PhoneNumberRange} and
+ * intercept the next incoming call from a number that lies within the range, within a timeout
+ * specified by {@code timeoutMillis}.
+ *
+ * If such a phone call is received, the caller will be notified via
+ * {@link NumberVerificationCallback#onCallReceived(String)} on the provided {@link Executor}.
+ * If verification fails for any reason, the caller will be notified via
+ * {@link NumberVerificationCallback#onVerificationFailed(int)}
+ * on the provided {@link Executor}.
+ *
+ * In addition to the {@link Manifest.permission#MODIFY_PHONE_STATE} permission, callers of this
+ * API must also be listed in the device configuration as an authorized app in
+ * {@code packages/services/Telephony/res/values/config.xml} under the
+ * {@code config_number_verification_package_name} key.
+ *
+ * @hide
+ * @param range The range of phone numbers the caller expects a phone call from.
+ * @param timeoutMillis The amount of time to wait for such a call, or
+ * {@link #MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS}, whichever is lesser.
+ * @param executor The {@link Executor} that callbacks should be executed on.
+ * @param callback The callback to use for delivering results.
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+ public void requestNumberVerification(@NonNull PhoneNumberRange range, long timeoutMillis,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull NumberVerificationCallback callback) {
+ INumberVerificationCallback internalCallback = new INumberVerificationCallback.Stub() {
+ @Override
+ public void onCallReceived(String phoneNumber) throws RemoteException {
+ Binder.withCleanCallingIdentity(() -> callback.onCallReceived(phoneNumber));
+ }
+
+ @Override
+ public void onVerificationFailed(int reason) throws RemoteException {
+ Binder.withCleanCallingIdentity(() -> callback.onVerificationFailed(reason));
+ }
+ };
+
+ // TODO -- call the aidl method
+ }
+
+ /**
* Sets a per-phone telephony property with the value specified.
*
* @hide
@@ -9533,4 +9587,34 @@
}
return subId;
}
+
+ /**
+ * Update availability of a list of networks in the current location.
+ *
+ * This api should be called to inform AlternativeNetwork Service about the availability
+ * of a network at the current location. This information will be used by AlternativeNetwork
+ * service to decide to attach to the network opportunistically. If an empty list is passed,
+ * it is assumed that no network is available.
+ * Requires that the calling app has carrier privileges on both primary and
+ * secondary subscriptions (see {@link #hasCarrierPrivileges}), or has permission
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+ * @param availableNetworks is a list of available network information.
+ * @return true if request is accepted
+ *
+ */
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+ public boolean updateAvailableNetworks(List<AvailableNetworkInfo> availableNetworks) {
+ String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+ boolean ret = false;
+ try {
+ IAns iAlternativeNetworkService = getIAns();
+ if (iAlternativeNetworkService != null) {
+ ret = iAlternativeNetworkService.updateAvailableNetworks(availableNetworks,
+ pkgForDebug);
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "updateAvailableNetworks RemoteException", ex);
+ }
+ return ret;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/IAns.aidl b/telephony/java/com/android/internal/telephony/IAns.aidl
index e9a4649..98bcd41 100755
--- a/telephony/java/com/android/internal/telephony/IAns.aidl
+++ b/telephony/java/com/android/internal/telephony/IAns.aidl
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
+import android.telephony.AvailableNetworkInfo;
interface IAns {
@@ -78,4 +79,23 @@
*
*/
int getPreferredData(String callingPackage);
+
+ /**
+ * Update availability of a list of networks in the current location.
+ *
+ * This api should be called if the caller is aware of the availability of a network
+ * at the current location. This information will be used by AlternativeNetwork service
+ * to decide to attach to the network. If an empty list is passed,
+ * it is assumed that no network is available.
+ * Requires that the calling app has carrier privileges on both primary and
+ * secondary subscriptions (see
+ * {@link #hasCarrierPrivileges}), or has permission
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+ * @param availableNetworks is a list of available network information.
+ * @param callingPackage caller's package name
+ * @return true if request is accepted
+ *
+ */
+ boolean updateAvailableNetworks(in List<AvailableNetworkInfo> availableNetworks,
+ String callingPackage);
}
diff --git a/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl b/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl
new file mode 100644
index 0000000..76918af
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/INumberVerificationCallback.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+oneway interface INumberVerificationCallback {
+ void onCallReceived(String phoneNumber);
+ void onVerificationFailed(int reason);
+}
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index bc44519..f9db4b0 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -184,6 +184,15 @@
String setSubscriptionGroup(in int[] subIdList, String callingPackage);
/**
+ * Set whether a subscription is metered
+ *
+ * @param isMetered whether it’s a metered subscription.
+ * @param subId the unique SubscriptionInfo index in database
+ * @return the number of records updated
+ */
+ int setMetered(boolean isMetered, int subId);
+
+ /**
* Set which subscription is preferred for cellular data. It's
* designed to overwrite default data subscription temporarily.
*
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 923ab06..76e7509 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -25,6 +25,7 @@
import android.telephony.PhysicalChannelConfig;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
+import android.telephony.emergency.EmergencyNumber;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.telephony.IOnSubscriptionsChangedListener;
@@ -80,4 +81,5 @@
void notifyPhoneCapabilityChanged(in PhoneCapability capability);
void notifyPreferredDataSubIdChanged(int preferredSubId);
void notifyRadioPowerStateChanged(in int state);
+ void notifyEmergencyNumberList(in List<EmergencyNumber> emergencyNumberList);
}
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index d1a70a7..31d205e 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -298,19 +298,20 @@
"<colgroup align=\"left\" />\n"
"<tr><th>Attribute</th><th>Description</th></tr>\n";
- // Build the table of attributes with their links and names.
- for (const StyleableAttr& entry : sorted_attributes) {
- if (SkipSymbol(entry.symbol)) {
- continue;
- }
-
+ // Removed and hidden attributes are public but hidden from the documentation, so don't emit
+ // them as part of the class documentation.
+ std::vector<StyleableAttr> documentation_attrs = sorted_attributes;
+ auto documentation_remove_iter = std::remove_if(documentation_attrs.begin(),
+ documentation_attrs.end(),
+ [&](StyleableAttr entry) -> bool {
StringPiece attr_comment_line = entry.symbol.value().attribute->GetComment();
- if (attr_comment_line.contains("@removed")) {
- // Removed attributes are public but hidden from the documentation, so
- // don't emit them as part of the class documentation.
- continue;
- }
+ return SkipSymbol(entry.symbol) || attr_comment_line.contains("@removed")
+ || attr_comment_line.contains("@hide");
+ });
+ documentation_attrs.erase(documentation_remove_iter, documentation_attrs.end());
+ // Build the table of attributes with their links and names.
+ for (const StyleableAttr& entry : documentation_attrs) {
const ResourceName& attr_name = entry.attr_ref->name.value();
styleable_comment << "<tr><td><code>{@link #" << entry.field_name << " "
<< (!attr_name.package.empty() ? attr_name.package
@@ -320,16 +321,14 @@
// Only use the comment up until the first '.'. This is to stay compatible with
// the way old AAPT did it (presumably to keep it short and to avoid including
// annotations like @hide which would affect this Styleable).
+ StringPiece attr_comment_line = entry.symbol.value().attribute->GetComment();
styleable_comment << "<td>" << AnnotationProcessor::ExtractFirstSentence(attr_comment_line)
<< "</td></tr>\n";
}
styleable_comment << "</table>\n";
// Generate the @see lines for each attribute.
- for (const StyleableAttr& entry : sorted_attributes) {
- if (SkipSymbol(entry.symbol)) {
- continue;
- }
+ for (const StyleableAttr& entry : documentation_attrs) {
styleable_comment << "@see #" << entry.field_name << "\n";
}
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index fa208be..4f51fc4 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -366,6 +366,46 @@
ASSERT_TRUE(generator.Generate("android", &out));
out.Flush();
+ EXPECT_THAT(output, HasSubstr("#Container_one android:one"));
+ EXPECT_THAT(output, HasSubstr("@see #Container_one"));
+ EXPECT_THAT(output, HasSubstr("attr name android:one"));
+ EXPECT_THAT(output, HasSubstr("attr description"));
+ EXPECT_THAT(output, HasSubstr(attr.GetComment()));
+ EXPECT_THAT(output, HasSubstr(styleable.GetComment()));
+}
+
+TEST(JavaClassGeneratorTest, CommentsForStyleableHiddenAttributesAreNotPresent) {
+ Attribute attr;
+ attr.SetComment(StringPiece("This is an attribute @hide"));
+
+ Styleable styleable;
+ styleable.entries.push_back(Reference(test::ParseNameOrDie("android:attr/one")));
+ styleable.SetComment(StringPiece("This is a styleable"));
+
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .SetPackageId("android", 0x01)
+ .AddValue("android:attr/one", util::make_unique<Attribute>(attr))
+ .AddValue("android:styleable/Container",
+ std::unique_ptr<Styleable>(styleable.Clone(nullptr)))
+ .Build();
+
+ std::unique_ptr<IAaptContext> context =
+ test::ContextBuilder()
+ .AddSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get()))
+ .SetNameManglerPolicy(NameManglerPolicy{"android"})
+ .Build();
+ JavaClassGeneratorOptions options;
+ options.use_final = false;
+ JavaClassGenerator generator(context.get(), table.get(), options);
+
+ std::string output;
+ StringOutputStream out(&output);
+ ASSERT_TRUE(generator.Generate("android", &out));
+ out.Flush();
+
+ EXPECT_THAT(output, Not(HasSubstr("#Container_one android:one")));
+ EXPECT_THAT(output, Not(HasSubstr("@see #Container_one")));
EXPECT_THAT(output, HasSubstr("attr name android:one"));
EXPECT_THAT(output, HasSubstr("attr description"));
EXPECT_THAT(output, HasSubstr(attr.GetComment()));
diff --git a/tools/aosp/aosp_sha.sh b/tools/aosp/aosp_sha.sh
index e50c70d..f25fcdc 100755
--- a/tools/aosp/aosp_sha.sh
+++ b/tools/aosp/aosp_sha.sh
@@ -19,6 +19,6 @@
echo "If your change contains no confidential details (such as security fixes), please"
echo "upload and merge this change at https://android-review.googlesource.com/."
echo
- exit 77
+ exit 1
fi
fi
diff --git a/tools/hiddenapi/generate_hiddenapi_lists.py b/tools/hiddenapi/generate_hiddenapi_lists.py
index 2f1e53c..01728fa1 100755
--- a/tools/hiddenapi/generate_hiddenapi_lists.py
+++ b/tools/hiddenapi/generate_hiddenapi_lists.py
@@ -26,6 +26,7 @@
FLAG_GREYLIST = "greylist"
FLAG_BLACKLIST = "blacklist"
FLAG_GREYLIST_MAX_O = "greylist-max-o"
+FLAG_GREYLIST_MAX_P = "greylist-max-p"
# List of all known flags.
FLAGS = [
@@ -33,6 +34,7 @@
FLAG_GREYLIST,
FLAG_BLACKLIST,
FLAG_GREYLIST_MAX_O,
+ FLAG_GREYLIST_MAX_P,
]
FLAGS_SET = set(FLAGS)
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 9789319..8e0d4ac 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -953,8 +953,12 @@
* establish a connection to a remembered access point that is
* within range, and will do periodic scans if there are remembered
* access points but none are in range.
+ *
+ * @deprecated This API is non-functional and will have no impact.
*/
+ @Deprecated
public static final int WIFI_MODE_FULL = 1;
+
/**
* In this Wi-Fi lock mode, Wi-Fi will be kept active,
* but the only operation that will be supported is initiation of
@@ -963,28 +967,62 @@
* nor will periodic scans be automatically performed looking for
* remembered access points. Scans must be explicitly requested by
* an application in this mode.
+ *
+ * @deprecated This API is non-functional and will have no impact.
*/
+ @Deprecated
public static final int WIFI_MODE_SCAN_ONLY = 2;
+
/**
- * In this Wi-Fi lock mode, Wi-Fi will be kept active as in mode
- * {@link #WIFI_MODE_FULL} but it operates at high performance
- * with minimum packet loss and low packet latency even when
- * the device screen is off. This mode will consume more power
- * and hence should be used only when there is a need for such
- * an active connection.
+ * In this Wi-Fi lock mode, Wi-Fi will not go to power save.
+ * This results in operating with low packet latency.
+ * The lock is active even when the device screen is off or
+ * the acquiring application is running in the background.
+ * This mode will consume more power and hence should be used only
+ * when there is a need for this tradeoff.
* <p>
* An example use case is when a voice connection needs to be
- * kept active even after the device screen goes off. Holding the
- * regular {@link #WIFI_MODE_FULL} lock will keep the wifi
- * connection active, but the connection can be lossy.
+ * kept active even after the device screen goes off.
* Holding a {@link #WIFI_MODE_FULL_HIGH_PERF} lock for the
- * duration of the voice call will improve the call quality.
+ * duration of the voice call may improve the call quality.
* <p>
- * When there is no support from the hardware, this lock mode
- * will have the same behavior as {@link #WIFI_MODE_FULL}
+ * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_HIGH_PERF}
+ * lock will have no impact.
*/
public static final int WIFI_MODE_FULL_HIGH_PERF = 3;
+ /**
+ * In this Wi-Fi lock mode, Wi-Fi will operate with a priority to achieve low latency.
+ * {@link #WIFI_MODE_FULL_LOW_LATENCY} lock has the following limitations:
+ * <ol>
+ * <li>The lock is only active when the screen is on.</li>
+ * <li>The lock is only active when the acquiring app is running in the foreground.</li>
+ * </ol>
+ * Low latency mode optimizes for reduced packet latency,
+ * and as a result other performance measures may suffer when there are trade-offs to make:
+ * <ol>
+ * <li>Battery life may be reduced.</li>
+ * <li>Throughput may be reduced.</li>
+ * <li>Frequency of Wi-Fi scanning may be reduced. This may result in: </li>
+ * <ul>
+ * <li>The device may not roam or switch to the AP with highest signal quality.</li>
+ * <li>Location accuracy may be reduced.</li>
+ * </ul>
+ * </ol>
+ * <p>
+ * Example use cases are real time gaming or virtual reality applications where
+ * low latency is a key factor for user experience.
+ * <p>
+ * When there is no support from the hardware, the {@link #WIFI_MODE_FULL_LOW_LATENCY}
+ * lock will cause the device not to go power save.
+ * <p>
+ * Note: For an app which acquires both {@link #WIFI_MODE_FULL_LOW_LATENCY} and
+ * {@link #WIFI_MODE_FULL_HIGH_PERF} locks, {@link #WIFI_MODE_FULL_LOW_LATENCY}
+ * lock will be effective when app is running in foreground and screen is on,
+ * while the {@link #WIFI_MODE_FULL_HIGH_PERF} lock will take effect otherwise.
+ */
+ public static final int WIFI_MODE_FULL_LOW_LATENCY = 4;
+
/** Anything worse than or equal to this will show 0 bars. */
@UnsupportedAppUsage
private static final int MIN_RSSI = -100;
@@ -3830,9 +3868,8 @@
/**
* Creates a new WifiLock.
*
- * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL},
- * {@link #WIFI_MODE_FULL_HIGH_PERF} and {@link #WIFI_MODE_SCAN_ONLY} for
- * descriptions of the types of Wi-Fi locks.
+ * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL_HIGH_PERF}
+ * and {@link #WIFI_MODE_FULL_LOW_LATENCY} for descriptions of the types of Wi-Fi locks.
* @param tag a tag for the WifiLock to identify it in debugging messages. This string is
* never shown to the user under normal conditions, but should be descriptive
* enough to identify your application and the specific WifiLock within it, if it
@@ -3857,12 +3894,14 @@
* @return a new, unacquired WifiLock with the given tag.
*
* @see WifiLock
+ *
+ * @deprecated This API is non-functional.
*/
+ @Deprecated
public WifiLock createWifiLock(String tag) {
return new WifiLock(WIFI_MODE_FULL, tag);
}
-
/**
* Create a new MulticastLock
*