Merge "Fix vertical nav button direction issue" into nyc-mr2-dev
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 0ba937a..d4f80a0 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -60,6 +60,11 @@
*/
public static final int APP_TRANSITION_TIMEOUT = 3;
+ /**
+ * Verify that calling app has access to the given provider.
+ */
+ public abstract String checkContentProviderAccess(String authority, int userId);
+
// Called by the power manager.
public abstract void onWakefulnessChanged(int wakefulness);
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 6e2c464..f29e576 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -200,6 +200,7 @@
@Nullable Message cancelCallback) {
this(context);
mCancelable = cancelable;
+ updateWindowForCancelable();
mCancelMessage = cancelCallback;
}
@@ -207,6 +208,7 @@
@Nullable OnCancelListener cancelListener) {
this(context);
mCancelable = cancelable;
+ updateWindowForCancelable();
setOnCancelListener(cancelListener);
}
@@ -1187,6 +1189,7 @@
*/
public void setCancelable(boolean flag) {
mCancelable = flag;
+ updateWindowForCancelable();
}
/**
@@ -1200,6 +1203,7 @@
public void setCanceledOnTouchOutside(boolean cancel) {
if (cancel && !mCancelable) {
mCancelable = true;
+ updateWindowForCancelable();
}
mWindow.setCloseOnTouchOutside(cancel);
@@ -1351,4 +1355,8 @@
}
}
}
+
+ private void updateWindowForCancelable() {
+ mWindow.setCloseOnSwipeEnabled(mCancelable);
+ }
}
diff --git a/core/java/android/bluetooth/OobData.java b/core/java/android/bluetooth/OobData.java
index 8e659e0..9e87230 100644
--- a/core/java/android/bluetooth/OobData.java
+++ b/core/java/android/bluetooth/OobData.java
@@ -30,7 +30,23 @@
* @hide
*/
public class OobData implements Parcelable {
+ private byte[] leBluetoothDeviceAddress;
private byte[] securityManagerTk;
+ private byte[] leSecureConnectionsConfirmation;
+ private byte[] leSecureConnectionsRandom;
+
+ public byte[] getLeBluetoothDeviceAddress() {
+ return leBluetoothDeviceAddress;
+ }
+
+ /**
+ * Sets the LE Bluetooth Device Address value to be used during LE pairing.
+ * The value shall be 7 bytes. Please see Bluetooth CSSv6, Part A 1.16 for
+ * a detailed description.
+ */
+ public void setLeBluetoothDeviceAddress(byte[] leBluetoothDeviceAddress) {
+ this.leBluetoothDeviceAddress = leBluetoothDeviceAddress;
+ }
public byte[] getSecurityManagerTk() {
return securityManagerTk;
@@ -45,10 +61,29 @@
this.securityManagerTk = securityManagerTk;
}
+ public byte[] getLeSecureConnectionsConfirmation() {
+ return leSecureConnectionsConfirmation;
+ }
+
+ public void setLeSecureConnectionsConfirmation(byte[] leSecureConnectionsConfirmation) {
+ this.leSecureConnectionsConfirmation = leSecureConnectionsConfirmation;
+ }
+
+ public byte[] getLeSecureConnectionsRandom() {
+ return leSecureConnectionsRandom;
+ }
+
+ public void setLeSecureConnectionsRandom(byte[] leSecureConnectionsRandom) {
+ this.leSecureConnectionsRandom = leSecureConnectionsRandom;
+ }
+
public OobData() { }
private OobData(Parcel in) {
+ leBluetoothDeviceAddress = in.createByteArray();
securityManagerTk = in.createByteArray();
+ leSecureConnectionsConfirmation = in.createByteArray();
+ leSecureConnectionsRandom = in.createByteArray();
}
public int describeContents() {
@@ -57,7 +92,10 @@
@Override
public void writeToParcel(Parcel out, int flags) {
+ out.writeByteArray(leBluetoothDeviceAddress);
out.writeByteArray(securityManagerTk);
+ out.writeByteArray(leSecureConnectionsConfirmation);
+ out.writeByteArray(leSecureConnectionsRandom);
}
public static final Parcelable.Creator<OobData> CREATOR
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index 4fc6b7a..6176b2c 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -21,7 +21,7 @@
import android.os.Parcelable;
/**
- * An event recorded by DnsEventListenerService.
+ * A DNS event recorded by NetdEventListenerService.
* {@hide}
*/
@SystemApi
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index b826584..a280e59 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -41,6 +41,8 @@
public static final class Impl implements BaseColumns {
private Impl() {}
+ public static final String AUTHORITY = "downloads";
+
/**
* The permission to access the download manager
*/
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 85c16b8..1cca074 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -302,6 +302,7 @@
private boolean mDestroyed;
private boolean mOverlayWithDecorCaptionEnabled = false;
+ private boolean mCloseOnSwipeEnabled = false;
// The current window attributes.
private final WindowManager.LayoutParams mWindowAttributes =
@@ -2208,4 +2209,21 @@
* @hide
*/
public abstract void reportActivityRelaunched();
+
+ /**
+ * Called to set flag to check if the close on swipe is enabled. This will only function if
+ * FEATURE_SWIPE_TO_DISMISS has been set.
+ * @hide
+ */
+ public void setCloseOnSwipeEnabled(boolean closeOnSwipeEnabled) {
+ mCloseOnSwipeEnabled = closeOnSwipeEnabled;
+ }
+
+ /**
+ * @return {@code true} if the close on swipe is enabled.
+ * @hide
+ */
+ public boolean isCloseOnSwipeEnabled() {
+ return mCloseOnSwipeEnabled;
+ }
}
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 878f3a6..713190d 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2495,6 +2495,7 @@
// System.out.println("Features: 0x" + Integer.toHexString(features));
if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
layoutResource = R.layout.screen_swipe_dismiss;
+ setCloseOnSwipeEnabled(true);
} else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
if (mIsFloating) {
TypedValue res = new TypedValue();
@@ -2566,7 +2567,7 @@
}
if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
- registerSwipeCallbacks();
+ registerSwipeCallbacks(contentParent);
}
// Remaining setup -- of background and title -- that only applies
@@ -2980,9 +2981,12 @@
return (mRightIconView = (ImageView)findViewById(R.id.right_icon));
}
- private void registerSwipeCallbacks() {
- SwipeDismissLayout swipeDismiss =
- (SwipeDismissLayout) findViewById(R.id.content);
+ private void registerSwipeCallbacks(ViewGroup contentParent) {
+ if (!(contentParent instanceof SwipeDismissLayout)) {
+ Log.w(TAG, "contentParent is not a SwipeDismissLayout: " + contentParent);
+ return;
+ }
+ SwipeDismissLayout swipeDismiss = (SwipeDismissLayout) contentParent;
swipeDismiss.setOnDismissedListener(new SwipeDismissLayout.OnDismissedListener() {
@Override
public void onDismissed(SwipeDismissLayout layout) {
@@ -3021,6 +3025,16 @@
});
}
+ /** @hide */
+ @Override
+ public void setCloseOnSwipeEnabled(boolean closeOnSwipeEnabled) {
+ if (hasFeature(Window.FEATURE_SWIPE_TO_DISMISS) // swipe-to-dismiss feature is requested
+ && mContentParent instanceof SwipeDismissLayout) { // check casting mContentParent
+ ((SwipeDismissLayout) mContentParent).setDismissable(closeOnSwipeEnabled);
+ }
+ super.setCloseOnSwipeEnabled(closeOnSwipeEnabled);
+ }
+
/**
* Helper method for calling the {@link Callback#onPanelClosed(int, Menu)}
* callback. This method will grab whatever extra state is needed for the
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index d88f479..31e67bd 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -110,6 +110,8 @@
private float mLastX;
+ private boolean mDismissable = true;
+
public SwipeDismissLayout(Context context) {
super(context);
init(context);
@@ -166,6 +168,10 @@
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
+ if (!mDismissable) {
+ return super.onInterceptTouchEvent(ev);
+ }
+
// offset because the view is translated during swipe
ev.offsetLocation(mTranslationX, 0);
@@ -225,7 +231,7 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
- if (mVelocityTracker == null) {
+ if (mVelocityTracker == null || !mDismissable) {
return super.onTouchEvent(ev);
}
// offset because the view is translated during swipe
@@ -363,4 +369,13 @@
return checkV && v.canScrollHorizontally((int) -dx);
}
+
+ public void setDismissable(boolean dismissable) {
+ if (!dismissable && mDismissable) {
+ cancel();
+ resetMembers();
+ }
+
+ mDismissable = dismissable;
+ }
}
diff --git a/core/res/res/layout/date_picker_material.xml b/core/res/res/layout/date_picker_material.xml
index 763f2a4..dd8a45d2 100644
--- a/core/res/res/layout/date_picker_material.xml
+++ b/core/res/res/layout/date_picker_material.xml
@@ -25,10 +25,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- <include
- layout="@layout/date_picker_view_animator_material"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
+ <ScrollView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fadeScrollbars="false"
+ android:scrollIndicators="top|bottom">
+ <include
+ layout="@layout/date_picker_view_animator_material"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+ </ScrollView>
</LinearLayout>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 90c19fb..a5e3fab 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -419,6 +419,9 @@
<!-- Boolean indicating whether Hotspot 2.0/Passpoint and ANQP queries is enabled -->
<bool translatable="false" name="config_wifi_hotspot2_enabled">false</bool>
+ <!-- Boolean indicating whether 802.11r Fast BSS Transition is enabled on this platform -->
+ <bool translatable="false" name="config_wifi_fast_bss_transition_enabled">false</bool>
+
<!-- Device type information conforming to Annex B format in WiFi Direct specification.
The default represents a dual-mode smartphone -->
<string translatable="false" name="config_wifi_p2p_device_type">10-0050F204-5</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index bbfee14..647d53a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1699,6 +1699,7 @@
<java-symbol type="bool" name="config_wifi_background_scan_support" />
<java-symbol type="bool" name="config_wifi_dual_band_support" />
<java-symbol type="bool" name="config_wifi_hotspot2_enabled" />
+ <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
<java-symbol type="bool" name="config_wimaxEnabled" />
<java-symbol type="bool" name="show_ongoing_ime_switcher" />
<java-symbol type="color" name="config_defaultNotificationColor" />
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index c24d313..659725e 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -15,14 +15,14 @@
package android.graphics.drawable;
import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
-import android.animation.Animator.AnimatorListener;
+import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
-import android.animation.ObjectAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
@@ -55,8 +55,8 @@
import android.view.View;
import com.android.internal.R;
-
import com.android.internal.util.VirtualRefBasePtr;
+
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -88,9 +88,77 @@
* <a name="VDExample"></a>
* <li><h4>XML for the VectorDrawable containing properties to be animated</h4>
* <p>
- * Animations can be performed on both group and path attributes, which requires groups and paths to
- * have unique names in the same VectorDrawable. Groups and paths without animations do not need to
- * be named.
+ * Animations can be performed on the animatable attributes in
+ * {@link android.graphics.drawable.VectorDrawable}. These attributes will be animated by
+ * {@link android.animation.ObjectAnimator}. The ObjectAnimator's target can be the root element,
+ * a group element or a path element. The targeted elements need to be named uniquely within
+ * the same VectorDrawable. Elements without animation do not need to be named.
+ * </p>
+ * <p>
+ * Here are all the animatable attributes in {@link android.graphics.drawable.VectorDrawable}:
+ * <table border="2" align="center" cellpadding="5">
+ * <thead>
+ * <tr>
+ * <th>Element Name</th>
+ * <th>Animatable attribute name</th>
+ * </tr>
+ * </thead>
+ * <tr>
+ * <td><vector></td>
+ * <td>alpha</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="7"><group></td>
+ * <td>rotation</td>
+ * </tr>
+ * <tr>
+ * <td>pivotX</td>
+ * </tr>
+ * <tr>
+ * <td>pivotY</td>
+ * </tr>
+ * <tr>
+ * <td>scaleX</td>
+ * </tr>
+ * <tr>
+ * <td>scaleY</td>
+ * </tr>
+ * <tr>
+ * <td>translateX</td>
+ * </tr>
+ * <tr>
+ * <td>translateY</td>
+ * </tr>
+ * <tr>
+ * <td rowspan="8"><path></td>
+ * <td>pathData</td>
+ * </tr>
+ * <tr>
+ * <td>fillColor</td>
+ * </tr>
+ * <tr>
+ * <td>strokeColor</td>
+ * </tr>
+ * <tr>
+ * <td>strokeWidth</td>
+ * </tr>
+ * <tr>
+ * <td>strokeAlpha</td>
+ * </tr>
+ * <tr>
+ * <td>fillAlpha</td>
+ * </tr>
+ * <tr>
+ * <td>trimPathStart</td>
+ * </tr>
+ * <tr>
+ * <td>trimPathOffset</td>
+ * </tr>
+ * <tr>
+ * <td><clip-path></td>
+ * <td>pathData</td>
+ * </tr>
+ * </table>
* </p>
* Below is an example of a VectorDrawable defined in vectordrawable.xml. This VectorDrawable is
* referred to by its file name (not including file suffix) in the
@@ -118,9 +186,8 @@
* <li><h4>XML for AnimatedVectorDrawable</h4>
* <p>
* An AnimatedVectorDrawable element has a VectorDrawable attribute, and one or more target
- * element(s). The target elements can be the path or group to be animated. Each target element
- * contains a name attribute that references a property (of a path or a group) to animate, and an
- * animation attribute that points to an ObjectAnimator or an AnimatorSet.
+ * element(s). The target element can specify its target by android:name attribute, and link the
+ * target with the proper ObjectAnimator or AnimatorSet by android:animation attribute.
* </p>
* The following code sample defines an AnimatedVectorDrawable. Note that the names refer to the
* groups and paths in the <a href="#VDExample">VectorDrawable XML above</a>.
@@ -173,7 +240,8 @@
* merge the XML files from the previous examples into one XML file:
* </p>
* <pre>
- * <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ * <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ * xmlns:aapt="http://schemas.android.com/aapt" >
* <aapt:attr name="android:drawable">
* <vector
* android:height="64dp"
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 1ca1552..d644bee 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -76,36 +76,27 @@
* <dl>
* <dt><code>android:name</code></dt>
* <dd>Defines the name of this vector drawable.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:width</code></dt>
* <dd>Used to define the intrinsic width of the drawable.
* This support all the dimension units, normally specified with dp.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:height</code></dt>
* <dd>Used to define the intrinsic height the drawable.
* This support all the dimension units, normally specified with dp.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:viewportWidth</code></dt>
* <dd>Used to define the width of the viewport space. Viewport is basically
* the virtual canvas where the paths are drawn on.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:viewportHeight</code></dt>
* <dd>Used to define the height of the viewport space. Viewport is basically
* the virtual canvas where the paths are drawn on.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:tint</code></dt>
* <dd>The color to apply to the drawable as a tint. By default, no tint is applied.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:tintMode</code></dt>
- * <dd>The Porter-Duff blending mode for the tint color. The default value is src_in.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>The Porter-Duff blending mode for the tint color. Default is src_in.</dd>
* <dt><code>android:autoMirrored</code></dt>
* <dd>Indicates if the drawable needs to be mirrored when its layout direction is
- * RTL (right-to-left).</dd>
- * <dd>Animatable : No.</dd>
+ * RTL (right-to-left). Default is false.</dd>
* <dt><code>android:alpha</code></dt>
- * <dd>The opacity of this drawable.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity of this drawable. Default is 1.0.</dd>
* </dl></dd>
* </dl>
*
@@ -117,32 +108,24 @@
* <dl>
* <dt><code>android:name</code></dt>
* <dd>Defines the name of the group.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:rotation</code></dt>
- * <dd>The degrees of rotation of the group.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The degrees of rotation of the group. Default is 0.</dd>
* <dt><code>android:pivotX</code></dt>
* <dd>The X coordinate of the pivot for the scale and rotation of the group.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
* <dt><code>android:pivotY</code></dt>
* <dd>The Y coordinate of the pivot for the scale and rotation of the group.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
* <dt><code>android:scaleX</code></dt>
- * <dd>The amount of scale on the X Coordinate.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The amount of scale on the X Coordinate. Default is 1.</dd>
* <dt><code>android:scaleY</code></dt>
- * <dd>The amount of scale on the Y coordinate.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The amount of scale on the Y coordinate. Default is 1.</dd>
* <dt><code>android:translateX</code></dt>
* <dd>The amount of translation on the X coordinate.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
* <dt><code>android:translateY</code></dt>
* <dd>The amount of translation on the Y coordinate.
- * This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
+ * This is defined in the viewport space. Default is 0.</dd>
* </dl></dd>
* </dl>
*
@@ -152,58 +135,44 @@
* <dl>
* <dt><code>android:name</code></dt>
* <dd>Defines the name of the path.</dd>
- * <dd>Animatable : No.</dd>
* <dt><code>android:pathData</code></dt>
* <dd>Defines path data using exactly same format as "d" attribute
* in the SVG's path data. This is defined in the viewport space.</dd>
- * <dd>Animatable : Yes.</dd>
* <dt><code>android:fillColor</code></dt>
* <dd>Specifies the color used to fill the path. May be a color or, for SDK 24+, a color state list
* or a gradient color (See {@link android.R.styleable#GradientColor}
* and {@link android.R.styleable#GradientColorItem}).
* If this property is animated, any value set by the animation will override the original value.
* No path fill is drawn if this property is not specified.</dd>
- * <dd>Animatable : Yes.</dd>
* <dt><code>android:strokeColor</code></dt>
* <dd>Specifies the color used to draw the path outline. May be a color or, for SDK 24+, a color
* state list or a gradient color (See {@link android.R.styleable#GradientColor}
* and {@link android.R.styleable#GradientColorItem}).
* If this property is animated, any value set by the animation will override the original value.
* No path outline is drawn if this property is not specified.</dd>
- * <dd>Animatable : Yes.</dd>
* <dt><code>android:strokeWidth</code></dt>
- * <dd>The width a path stroke.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The width a path stroke. Default is 0.</dd>
* <dt><code>android:strokeAlpha</code></dt>
- * <dd>The opacity of a path stroke.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity of a path stroke. Default is 1.</dd>
* <dt><code>android:fillAlpha</code></dt>
- * <dd>The opacity to fill the path with.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The opacity to fill the path with. Default is 1.</dd>
* <dt><code>android:trimPathStart</code></dt>
- * <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The fraction of the path to trim from the start, in the range from 0 to 1. Default is 0.</dd>
* <dt><code>android:trimPathEnd</code></dt>
- * <dd>The fraction of the path to trim from the end, in the range from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * <dd>The fraction of the path to trim from the end, in the range from 0 to 1. Default is 1.</dd>
* <dt><code>android:trimPathOffset</code></dt>
* <dd>Shift trim region (allows showed region to include the start and end), in the range
- * from 0 to 1.</dd>
- * <dd>Animatable : Yes.</dd>
+ * from 0 to 1. Default is 0.</dd>
* <dt><code>android:strokeLineCap</code></dt>
- * <dd>Sets the linecap for a stroked path: butt, round, square.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the linecap for a stroked path: butt, round, square. Default is butt.</dd>
* <dt><code>android:strokeLineJoin</code></dt>
- * <dd>Sets the lineJoin for a stroked path: miter,round,bevel.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the lineJoin for a stroked path: miter,round,bevel. Default is miter.</dd>
* <dt><code>android:strokeMiterLimit</code></dt>
- * <dd>Sets the Miter limit for a stroked path.</dd>
- * <dd>Animatable : No.</dd>
+ * <dd>Sets the Miter limit for a stroked path. Default is 4.</dd>
* <dt><code>android:fillType</code></dt>
- * <dd>Sets the fillType for a path. The types can be either "evenOdd" or "nonZero". They behave the
- * same as SVG's "fill-rule" properties. For more details, see
+ * <dd>For SDK 24+, sets the fillType for a path. The types can be either "evenOdd" or "nonZero". They behave the
+ * same as SVG's "fill-rule" properties. Default is nonZero. For more details, see
* <a href="https://www.w3.org/TR/SVG/painting.html#FillRuleProperty">FillRuleProperty</a></dd>
- * <dd>Animatable : No.</dd>
* </dl></dd>
*
* </dl>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 4bcbea7..a332332 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -268,16 +268,16 @@
if (cachedDevice == null) {
Log.w(TAG, "CachedBluetoothDevice for device " + device +
" not found, calling readPairedDevices().");
- if (!readPairedDevices()) {
- Log.e(TAG, "Got bonding state changed for " + device +
- ", but we have no record of that device.");
- return;
+ if (readPairedDevices()) {
+ cachedDevice = mDeviceManager.findDevice(device);
}
- cachedDevice = mDeviceManager.findDevice(device);
+
if (cachedDevice == null) {
- Log.e(TAG, "Got bonding state changed for " + device +
- ", but device not added in cache.");
- return;
+ Log.w(TAG, "Got bonding state changed for " + device +
+ ", but we have no record of that device.");
+
+ cachedDevice = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, device);
+ dispatchDeviceAdded(cachedDevice);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6103355..54cd77b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -63,6 +63,8 @@
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.policy.IKeyguardDrawnCallback;
import com.android.internal.policy.IKeyguardExitCallback;
import com.android.internal.policy.IKeyguardStateCallback;
@@ -335,6 +337,7 @@
private boolean mWakeAndUnlocking;
private IKeyguardDrawnCallback mDrawnCallback;
+ private boolean mLockWhenSimRemoved;
private boolean mIsPerUserLock;
@@ -429,7 +432,7 @@
case ABSENT:
// only force lock screen in case of missing sim if user hasn't
// gone through setup wizard
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (shouldWaitForProvisioning()) {
if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG, "ICC_ABSENT isn't showing,"
@@ -440,11 +443,12 @@
resetStateLocked();
}
}
+ onSimNotReadyLocked();
}
break;
case PIN_REQUIRED:
case PUK_REQUIRED:
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG,
"INTENT_VALUE_ICC_LOCKED and keygaurd isn't "
@@ -456,7 +460,7 @@
}
break;
case PERM_DISABLED:
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (!mShowing) {
if (DEBUG_SIM_STATES) Log.d(TAG, "PERM_DISABLED and "
+ "keygaurd isn't showing.");
@@ -466,21 +470,40 @@
+ "show permanently disabled message in lockscreen.");
resetStateLocked();
}
+ onSimNotReadyLocked();
}
break;
case READY:
- synchronized (this) {
+ synchronized (KeyguardViewMediator.this) {
if (mShowing) {
resetStateLocked();
}
+ mLockWhenSimRemoved = true;
}
break;
default:
- if (DEBUG_SIM_STATES) Log.v(TAG, "Ignoring state: " + simState);
+ if (DEBUG_SIM_STATES) Log.v(TAG, "Unspecific state: " + simState);
+ synchronized (KeyguardViewMediator.this) {
+ onSimNotReadyLocked();
+ }
break;
}
}
+ private void onSimNotReadyLocked() {
+ if (isSecure() && mLockWhenSimRemoved) {
+ mLockWhenSimRemoved = false;
+ MetricsLogger.action(mContext,
+ MetricsEvent.ACTION_LOCK_BECAUSE_SIM_REMOVED, mShowing);
+ if (!mShowing) {
+ if (DEBUG_SIM_STATES) Log.d(TAG, "SIM removed, showing keyguard");
+ doKeyguardLocked(null);
+ } else {
+ resetStateLocked();
+ }
+ }
+ }
+
@Override
public void onFingerprintAuthFailed() {
final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 8a0dfe5..81d645e 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2213,6 +2213,14 @@
// ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
+ // ACTION: The lockscreen gets shown because the SIM card was removed
+ // SUBTYPE: false: device was previously unlocked, true: device was previously locked
+ // CATEGORY: GLOBAL_SYSTEM_UI
+ // OS: N-MR2
+ ACTION_LOCK_BECAUSE_SIM_REMOVED = 497;
+
+ // ---- End N-MR2 Constants, all N-MR2 constants go above this line ----
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 3210542..58f2074 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -12,7 +12,7 @@
java/com/android/server/EventLogTags.logtags \
java/com/android/server/am/EventLogTags.logtags \
../../../../system/netd/server/binder/android/net/INetd.aidl \
- ../../../../system/netd/server/binder/android/net/metrics/IDnsEventListener.aidl \
+ ../../../../system/netd/server/binder/android/net/metrics/INetdEventListener.aidl \
LOCAL_AIDL_INCLUDES += \
system/netd/server/binder
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index eccfb6d..91d9ac7 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -190,6 +190,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
+import android.provider.Downloads;
import android.os.storage.IMountService;
import android.os.storage.MountServiceInternal;
import android.os.storage.StorageManager;
@@ -8550,6 +8551,12 @@
// Only inspect grants matching package
if (packageName == null || perm.sourcePkg.equals(packageName)
|| perm.targetPkg.equals(packageName)) {
+ // Hacky solution as part of fixing a security bug; ignore
+ // grants associated with DownloadManager so we don't have
+ // to immediately launch it to regrant the permissions
+ if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
+ && !persistable) continue;
+
persistChanged |= perm.revokeModes(persistable
? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
@@ -10394,6 +10401,46 @@
}
/**
+ * Check if the calling UID has a possible chance at accessing the provider
+ * at the given authority and user.
+ */
+ public String checkContentProviderAccess(String authority, int userId) {
+ if (userId == UserHandle.USER_ALL) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+ userId = UserHandle.getCallingUserId();
+ }
+
+ ProviderInfo cpi = null;
+ try {
+ cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
+ STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+ userId);
+ } catch (RemoteException ignored) {
+ }
+ if (cpi == null) {
+ // TODO: make this an outright failure in a future platform release;
+ // until then anonymous content notifications are unprotected
+ //return "Failed to find provider " + authority + " for user " + userId;
+ return null;
+ }
+
+ ProcessRecord r = null;
+ synchronized (mPidsSelfLocked) {
+ r = mPidsSelfLocked.get(Binder.getCallingPid());
+ }
+ if (r == null) {
+ return "Failed to find PID " + Binder.getCallingPid();
+ }
+
+ synchronized (this) {
+ return checkContentProviderPermissionLocked(cpi, r, userId, true);
+ }
+ }
+
+ /**
* Check if {@link ProcessRecord} has a possible chance at accessing the
* given {@link ProviderInfo}. Final permission checking is always done
* in {@link ContentProvider}.
@@ -21849,6 +21896,11 @@
private final class LocalService extends ActivityManagerInternal {
@Override
+ public String checkContentProviderAccess(String authority, int userId) {
+ return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
+ }
+
+ @Override
public void onWakefulnessChanged(int wakefulness) {
ActivityManagerService.this.onWakefulnessChanged(wakefulness);
}
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index bcbcf54..28e724c 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -54,7 +54,7 @@
@VisibleForTesting
public final Impl impl = new Impl();
- private DnsEventListenerService mDnsListener;
+ private NetdEventListenerService mNetdListener;
@GuardedBy("mLock")
private ArrayList<ConnectivityMetricsEvent> mBuffer;
@@ -77,10 +77,10 @@
public void onBootPhase(int phase) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
if (DBG) Log.d(TAG, "onBootPhase");
- mDnsListener = new DnsEventListenerService(getContext());
+ mNetdListener = new NetdEventListenerService(getContext());
publishBinderService(SERVICE_NAME, impl);
- publishBinderService(mDnsListener.SERVICE_NAME, mDnsListener);
+ publishBinderService(mNetdListener.SERVICE_NAME, mNetdListener);
}
}
@@ -169,8 +169,8 @@
pw.println("Buffer capacity: " + mCapacity);
pw.println("Dropped events: " + mDropped);
}
- if (mDnsListener != null) {
- mDnsListener.dump(pw);
+ if (mNetdListener != null) {
+ mNetdListener.dump(pw);
}
}
diff --git a/services/core/java/com/android/server/connectivity/DnsEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
similarity index 91%
rename from services/core/java/com/android/server/connectivity/DnsEventListenerService.java
rename to services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 8d206ef..21e5d3c 100644
--- a/services/core/java/com/android/server/connectivity/DnsEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -22,7 +22,7 @@
import android.net.Network;
import android.net.NetworkRequest;
import android.net.metrics.DnsEvent;
-import android.net.metrics.IDnsEventListener;
+import android.net.metrics.INetdEventListener;
import android.net.metrics.IpConnectivityLog;
import android.util.Log;
@@ -37,13 +37,13 @@
/**
- * Implementation of the IDnsEventListener interface.
+ * Implementation of the INetdEventListener interface.
*/
-public class DnsEventListenerService extends IDnsEventListener.Stub {
+public class NetdEventListenerService extends INetdEventListener.Stub {
- public static final String SERVICE_NAME = "dns_listener";
+ public static final String SERVICE_NAME = "netd_listener";
- private static final String TAG = DnsEventListenerService.class.getSimpleName();
+ private static final String TAG = NetdEventListenerService.class.getSimpleName();
private static final boolean DBG = true;
private static final boolean VDBG = false;
@@ -110,7 +110,7 @@
private final NetworkCallback mNetworkCallback = new NetworkCallback() {
@Override
public void onLost(Network network) {
- synchronized (DnsEventListenerService.this) {
+ synchronized (NetdEventListenerService.this) {
DnsEventBatch batch = mEventBatches.remove(network.netId);
if (batch != null) {
batch.logAndClear();
@@ -119,12 +119,12 @@
}
};
- public DnsEventListenerService(Context context) {
+ public NetdEventListenerService(Context context) {
this(context.getSystemService(ConnectivityManager.class), new IpConnectivityLog());
}
@VisibleForTesting
- public DnsEventListenerService(ConnectivityManager cm, IpConnectivityLog log) {
+ public NetdEventListenerService(ConnectivityManager cm, IpConnectivityLog log) {
// We are started when boot is complete, so ConnectivityService should already be running.
mCm = cm;
mMetricsLog = log;
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 0727629..2434390 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -20,12 +20,12 @@
import android.accounts.Account;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.app.ActivityManagerNative;
import android.app.AppOpsManager;
import android.app.job.JobInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentService;
@@ -66,7 +66,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -296,24 +295,15 @@
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
- final int callingUserHandle = UserHandle.getCallingUserId();
- // Registering an observer for any user other than the calling user requires uri grant or
- // cross user permission
- if (callingUserHandle != userHandle) {
- if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle)
- != PackageManager.PERMISSION_GRANTED) {
- enforceCrossUserPermission(userHandle,
- "no permission to observe other users' provider view");
- }
- }
- if (userHandle < 0) {
- if (userHandle == UserHandle.USER_CURRENT) {
- userHandle = ActivityManager.getCurrentUser();
- } else if (userHandle != UserHandle.USER_ALL) {
- throw new InvalidParameterException("Bad user handle for registerContentObserver: "
- + userHandle);
- }
+ userHandle = handleIncomingUser(uri, pid, uid,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle);
+
+ final String msg = LocalServices.getService(ActivityManagerInternal.class)
+ .checkContentProviderAccess(uri.getAuthority(), userHandle);
+ if (msg != null) {
+ Log.w(TAG, "Ignoring content changes for " + uri + " from " + uid + ": " + msg);
+ return;
}
synchronized (mRootNode) {
@@ -363,22 +353,15 @@
final int uid = Binder.getCallingUid();
final int pid = Binder.getCallingPid();
final int callingUserHandle = UserHandle.getCallingUserId();
- // Notify for any user other than the caller requires uri grant or cross user permission
- if (callingUserHandle != userHandle) {
- if (checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
- userHandle) != PackageManager.PERMISSION_GRANTED) {
- enforceCrossUserPermission(userHandle, "no permission to notify other users");
- }
- }
- // We passed the permission check; resolve pseudouser targets as appropriate
- if (userHandle < 0) {
- if (userHandle == UserHandle.USER_CURRENT) {
- userHandle = ActivityManager.getCurrentUser();
- } else if (userHandle != UserHandle.USER_ALL) {
- throw new InvalidParameterException("Bad user handle for notifyChange: "
- + userHandle);
- }
+ userHandle = handleIncomingUser(uri, pid, uid,
+ Intent.FLAG_GRANT_WRITE_URI_PERMISSION, userHandle);
+
+ final String msg = LocalServices.getService(ActivityManagerInternal.class)
+ .checkContentProviderAccess(uri.getAuthority(), userHandle);
+ if (msg != null) {
+ Log.w(TAG, "Ignoring notify for " + uri + " from " + uid + ": " + msg);
+ return;
}
// This makes it so that future permission checks will be in the context of this
@@ -1143,6 +1126,27 @@
}
}
+ private int handleIncomingUser(Uri uri, int pid, int uid, int modeFlags, int userId) {
+ if (userId == UserHandle.USER_CURRENT) {
+ userId = ActivityManager.getCurrentUser();
+ }
+
+ if (userId == UserHandle.USER_ALL) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+ } else if (userId < 0) {
+ throw new IllegalArgumentException("Invalid user: " + userId);
+ } else if (userId != UserHandle.getCallingUserId()) {
+ if (checkUriPermission(uri, pid, uid, modeFlags,
+ userId) != PackageManager.PERMISSION_GRANTED) {
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+ }
+ }
+
+ return userId;
+ }
+
/**
* Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS_FULL
* permission, if the userHandle is not for the caller.
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index bdd041a..8bfa7d7 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -208,7 +208,7 @@
mDozeScaleFactor = dozeScaleFactor;
mNormalLightSensorRate = lightSensorRate;
mInitialLightSensorRate = initialLightSensorRate;
- mCurrentLightSensorRate = mNormalLightSensorRate;
+ mCurrentLightSensorRate = -1;
mBrighteningLightDebounceConfig = brighteningLightDebounceConfig;
mDarkeningLightDebounceConfig = darkeningLightDebounceConfig;
mResetAmbientLuxAfterWarmUpConfig = resetAmbientLuxAfterWarmUpConfig;
@@ -320,6 +320,7 @@
mInitialHorizonAmbientLightRingBuffer.clear();
mAmbientLuxValid = !mResetAmbientLuxAfterWarmUpConfig;
mLightSensorEnableTime = SystemClock.uptimeMillis();
+ mCurrentLightSensorRate = mInitialLightSensorRate;
mSensorManager.registerListener(mLightSensorListener, mLightSensor,
mCurrentLightSensorRate * 1000, mHandler);
return true;
@@ -328,9 +329,7 @@
if (mLightSensorEnabled) {
mLightSensorEnabled = false;
mRecentLightSamples = 0;
- if (mInitialLightSensorRate > 0) {
- mCurrentLightSensorRate = mInitialLightSensorRate;
- }
+ mCurrentLightSensorRate = -1;
mHandler.removeMessages(MSG_UPDATE_AMBIENT_LUX);
mSensorManager.unregisterListener(mLightSensorListener);
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 3207a86..de5bffd 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -315,6 +315,13 @@
com.android.internal.R.integer.config_autoBrightnessLightSensorRate);
int initialLightSensorRate = resources.getInteger(
com.android.internal.R.integer.config_autoBrightnessInitialLightSensorRate);
+ if (initialLightSensorRate == -1) {
+ initialLightSensorRate = lightSensorRate;
+ } else if (initialLightSensorRate > lightSensorRate) {
+ Slog.w(TAG, "Expected config_autoBrightnessInitialLightSensorRate ("
+ + initialLightSensorRate + ") to be less than or equal to "
+ + "config_autoBrightnessLightSensorRate (" + lightSensorRate + ").");
+ }
long brighteningLightDebounce = resources.getInteger(
com.android.internal.R.integer.config_autoBrightnessBrighteningLightDebounce);
long darkeningLightDebounce = resources.getInteger(
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index 1f195a7..e59d69f 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -106,27 +106,31 @@
}
return; // Not installed, no need to restore yet.
}
+ boolean blockRestore = false;
if (!mPackageInfo.hasSignatures()) {
s.wtf("Attempted to restore package " + mPackageName + ", user=" + mPackageUserId
+ " but signatures not found in the restore data.");
+ blockRestore = true;
+ }
+ if (!blockRestore) {
+ final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
+ if (!mPackageInfo.canRestoreTo(s, pi)) {
+ // Package is now installed, but can't restore. Let the subclass do the cleanup.
+ blockRestore = true;
+ }
+ }
+ if (blockRestore) {
onRestoreBlocked();
- return;
+ } else {
+ if (ShortcutService.DEBUG) {
+ Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName,
+ mPackageUserId, getOwnerUserId()));
+ }
+
+ onRestored();
}
- final PackageInfo pi = s.getPackageInfoWithSignatures(mPackageName, mPackageUserId);
- if (!mPackageInfo.canRestoreTo(s, pi)) {
- // Package is now installed, but can't restore. Let the subclass do the cleanup.
- onRestoreBlocked();
- return;
- }
- if (ShortcutService.DEBUG) {
- Slog.d(TAG, String.format("Restored package: %s/%d on user %d", mPackageName,
- mPackageUserId, getOwnerUserId()));
- }
-
- onRestored();
-
- // Now the package is not shadow.
+ // Either way, it's no longer a shadow.
mPackageInfo.setShadow(false);
s.scheduleSaveUser(mPackageUserId);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 500af0c..6e8799e 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -3739,6 +3739,16 @@
}
}
+ @VisibleForTesting
+ ShortcutLauncher getLauncherShortcutForTest(String packageName, int userId) {
+ synchronized (mLock) {
+ final ShortcutUser user = mUsers.get(userId);
+ if (user == null) return null;
+
+ return user.getAllLaunchersForTest().get(PackageWithUser.of(userId, packageName));
+ }
+ }
+
/**
* Control whether {@link #verifyStates} should be performed. We always perform it during unit
* tests.
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/DnsEventListenerServiceTest.java b/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
similarity index 91%
rename from services/tests/servicestests/src/com/android/server/connectivity/DnsEventListenerServiceTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
index 033b2c9..63d5d9fb 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/DnsEventListenerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
@@ -20,7 +20,7 @@
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.metrics.DnsEvent;
-import android.net.metrics.IDnsEventListener;
+import android.net.metrics.INetdEventListener;
import android.net.metrics.IpConnectivityLog;
import junit.framework.TestCase;
@@ -47,12 +47,12 @@
import java.util.OptionalInt;
import java.util.stream.IntStream;
-public class DnsEventListenerServiceTest extends TestCase {
+public class NetdEventListenerServiceTest extends TestCase {
- // TODO: read from DnsEventListenerService after this constant is read from system property
+ // TODO: read from NetdEventListenerService after this constant is read from system property
static final int BATCH_SIZE = 100;
- static final int EVENT_TYPE = IDnsEventListener.EVENT_GETADDRINFO;
- // TODO: read from IDnsEventListener
+ static final int EVENT_TYPE = INetdEventListener.EVENT_GETADDRINFO;
+ // TODO: read from INetdEventListener
static final int RETURN_CODE = 1;
static final byte[] EVENT_TYPES = new byte[BATCH_SIZE];
@@ -66,7 +66,7 @@
}
}
- DnsEventListenerService mDnsService;
+ NetdEventListenerService mNetdEventListenerService;
@Mock ConnectivityManager mCm;
@Mock IpConnectivityLog mLog;
@@ -77,7 +77,7 @@
MockitoAnnotations.initMocks(this);
mCallbackCaptor = ArgumentCaptor.forClass(NetworkCallback.class);
mEvCaptor = ArgumentCaptor.forClass(DnsEvent.class);
- mDnsService = new DnsEventListenerService(mCm, mLog);
+ mNetdEventListenerService = new NetdEventListenerService(mCm, mLog);
verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture());
}
@@ -131,7 +131,7 @@
new Thread() {
public void run() {
while (System.currentTimeMillis() < stop) {
- mDnsService.dump(pw);
+ mNetdEventListenerService.dump(pw);
}
}
}.start();
@@ -158,7 +158,7 @@
void log(int netId, int[] latencies) {
for (int l : latencies) {
- mDnsService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l);
+ mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 3cfdc32..cd48f36 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -4938,6 +4938,9 @@
assertEquals(0, mManager.getDynamicShortcuts().size());
assertEquals(0, mManager.getPinnedShortcuts().size());
});
+ assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_1, USER_0)
+ .getPackageInfo().isShadow());
+
installPackage(USER_0, CALLING_PACKAGE_2);
runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
@@ -4946,6 +4949,8 @@
mManager.getPinnedShortcuts()),
"s1", "s2", "s3");
});
+ assertFalse(mService.getPackageShortcutForTest(CALLING_PACKAGE_2, USER_0)
+ .getPackageInfo().isShadow());
installPackage(USER_0, LAUNCHER_1);
runWithCaller(LAUNCHER_1, USER_0, () -> {
@@ -5069,6 +5074,8 @@
mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
/* empty */);
});
+ assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_1, USER_0)
+ .getPackageInfo().isShadow());
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
@@ -5091,6 +5098,8 @@
mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_3), HANDLE_USER_0))
/* empty */);
});
+ assertFalse(mService.getLauncherShortcutForTest(LAUNCHER_2, USER_0)
+ .getPackageInfo().isShadow());
installPackage(USER_0, CALLING_PACKAGE_3);
runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 62625bd..58c5002 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -324,6 +324,7 @@
private final PhoneAccountHandle mAccountHandle;
private final int mCallCapabilities;
private final int mCallProperties;
+ private final int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
private final DisconnectCause mDisconnectCause;
private final long mConnectTimeMillis;
private final GatewayInfo mGatewayInfo;
@@ -536,6 +537,15 @@
}
/**
+ * @return a bitmask of the audio routes available for the call.
+ *
+ * @hide
+ */
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
+ /**
* @return For a {@link #STATE_DISCONNECTED} {@code Call}, the disconnect cause expressed
* by {@link android.telecom.DisconnectCause}.
*/
diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java
index 2b16722..f601d8b 100644
--- a/telecomm/java/android/telecom/CallAudioState.java
+++ b/telecomm/java/android/telecom/CallAudioState.java
@@ -44,8 +44,12 @@
*/
public static final int ROUTE_WIRED_OR_EARPIECE = ROUTE_EARPIECE | ROUTE_WIRED_HEADSET;
- /** Bit mask of all possible audio routes. */
- private static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
+ /**
+ * Bit mask of all possible audio routes.
+ *
+ * @hide
+ **/
+ public static final int ROUTE_ALL = ROUTE_EARPIECE | ROUTE_BLUETOOTH | ROUTE_WIRED_HEADSET |
ROUTE_SPEAKER;
private final boolean isMuted;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 8f9c758..6cf9828 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -722,6 +722,7 @@
public void onDestroyed(Connection c) {}
public void onConnectionCapabilitiesChanged(Connection c, int capabilities) {}
public void onConnectionPropertiesChanged(Connection c, int properties) {}
+ public void onSupportedAudioRoutesChanged(Connection c, int supportedAudioRoutes) {}
public void onVideoProviderChanged(
Connection c, VideoProvider videoProvider) {}
public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {}
@@ -1428,6 +1429,7 @@
private boolean mRingbackRequested = false;
private int mConnectionCapabilities;
private int mConnectionProperties;
+ private int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
private VideoProvider mVideoProvider;
private boolean mAudioModeIsVoip;
private long mConnectTimeMillis = Conference.CONNECT_TIME_NOT_SPECIFIED;
@@ -1708,6 +1710,15 @@
}
/**
+ * Returns the connection's supported audio routes.
+ *
+ * @hide
+ */
+ public final int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
+ /**
* Sets the value of the {@link #getAddress()} property.
*
* @param address The new address.
@@ -1929,6 +1940,28 @@
}
/**
+ * Sets the supported audio routes.
+ *
+ * @param supportedAudioRoutes the supported audio routes as a bitmask.
+ * See {@link CallAudioState}
+ * @hide
+ */
+ public final void setSupportedAudioRoutes(int supportedAudioRoutes) {
+ if ((supportedAudioRoutes
+ & (CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER)) == 0) {
+ throw new IllegalArgumentException(
+ "supported audio routes must include either speaker or earpiece");
+ }
+
+ if (mSupportedAudioRoutes != supportedAudioRoutes) {
+ mSupportedAudioRoutes = supportedAudioRoutes;
+ for (Listener l : mListeners) {
+ l.onSupportedAudioRoutesChanged(this, mSupportedAudioRoutes);
+ }
+ }
+ }
+
+ /**
* Tears down the Connection object.
*/
public final void destroy() {
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index dd55ca9..f782232 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -776,6 +776,7 @@
connection.getState(),
connection.getConnectionCapabilities(),
connection.getConnectionProperties(),
+ connection.getSupportedAudioRoutes(),
connection.getAddress(),
connection.getAddressPresentation(),
connection.getCallerDisplayName(),
@@ -1175,6 +1176,7 @@
connection.getState(),
connection.getConnectionCapabilities(),
connection.getConnectionProperties(),
+ connection.getSupportedAudioRoutes(),
connection.getAddress(),
connection.getAddressPresentation(),
connection.getCallerDisplayName(),
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 4a6fd7c..f7a6595 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -39,6 +39,7 @@
private final List<String> mCannedSmsResponses;
private final int mCapabilities;
private final int mProperties;
+ private final int mSupportedAudioRoutes;
private final long mConnectTimeMillis;
private final Uri mHandle;
private final int mHandlePresentation;
@@ -64,6 +65,7 @@
List<String> cannedSmsResponses,
int capabilities,
int properties,
+ int supportedAudioRoutes,
long connectTimeMillis,
Uri handle,
int handlePresentation,
@@ -86,6 +88,7 @@
mCannedSmsResponses = cannedSmsResponses;
mCapabilities = capabilities;
mProperties = properties;
+ mSupportedAudioRoutes = supportedAudioRoutes;
mConnectTimeMillis = connectTimeMillis;
mHandle = handle;
mHandlePresentation = handlePresentation;
@@ -137,6 +140,11 @@
/** Bitmask of properties of the call. */
public int getProperties() { return mProperties; }
+ /** Bitmask of supported routes of the call */
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
/** The time that the call switched to the active state. */
public long getConnectTimeMillis() {
return mConnectTimeMillis;
@@ -292,6 +300,7 @@
source.readList(conferenceableCallIds, classLoader);
Bundle intentExtras = source.readBundle(classLoader);
Bundle extras = source.readBundle(classLoader);
+ int supportedAudioRoutes = source.readInt();
return new ParcelableCall(
id,
state,
@@ -299,6 +308,7 @@
cannedSmsResponses,
capabilities,
properties,
+ supportedAudioRoutes,
connectTimeMillis,
handle,
handlePresentation,
@@ -355,6 +365,7 @@
destination.writeList(mConferenceableCallIds);
destination.writeBundle(mIntentExtras);
destination.writeBundle(mExtras);
+ destination.writeInt(mSupportedAudioRoutes);
}
@Override
diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java
index 540f388..e9dba68 100644
--- a/telecomm/java/android/telecom/ParcelableConnection.java
+++ b/telecomm/java/android/telecom/ParcelableConnection.java
@@ -37,6 +37,7 @@
private final int mState;
private final int mConnectionCapabilities;
private final int mConnectionProperties;
+ private final int mSupportedAudioRoutes;
private final Uri mAddress;
private final int mAddressPresentation;
private final String mCallerDisplayName;
@@ -57,6 +58,7 @@
int state,
int capabilities,
int properties,
+ int supportedAudioRoutes,
Uri address,
int addressPresentation,
String callerDisplayName,
@@ -74,6 +76,7 @@
mState = state;
mConnectionCapabilities = capabilities;
mConnectionProperties = properties;
+ mSupportedAudioRoutes = supportedAudioRoutes;
mAddress = address;
mAddressPresentation = addressPresentation;
mCallerDisplayName = callerDisplayName;
@@ -117,6 +120,10 @@
return mConnectionProperties;
}
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
public Uri getHandle() {
return mAddress;
}
@@ -210,12 +217,14 @@
source.readStringList(conferenceableConnectionIds);
Bundle extras = Bundle.setDefusable(source.readBundle(classLoader), true);
int properties = source.readInt();
+ int supportedAudioRoutes = source.readInt();
return new ParcelableConnection(
phoneAccount,
state,
capabilities,
properties,
+ supportedAudioRoutes,
address,
addressPresentation,
callerDisplayName,
@@ -264,5 +273,6 @@
destination.writeStringList(mConferenceableConnectionIds);
destination.writeBundle(mExtras);
destination.writeInt(mConnectionProperties);
+ destination.writeInt(mSupportedAudioRoutes);
}
}
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index 473e394..692dfb73 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -17,15 +17,6 @@
package android.telecom;
import android.annotation.SystemApi;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
@@ -37,7 +28,6 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.MissingResourceException;
/**
* Represents a distinct method to place or receive a phone call. Apps which can place calls and
@@ -217,6 +207,7 @@
private final CharSequence mLabel;
private final CharSequence mShortDescription;
private final List<String> mSupportedUriSchemes;
+ private final int mSupportedAudioRoutes;
private final Icon mIcon;
private final Bundle mExtras;
private boolean mIsEnabled;
@@ -226,10 +217,12 @@
* Helper class for creating a {@link PhoneAccount}.
*/
public static class Builder {
+
private PhoneAccountHandle mAccountHandle;
private Uri mAddress;
private Uri mSubscriptionAddress;
private int mCapabilities;
+ private int mSupportedAudioRoutes = CallAudioState.ROUTE_ALL;
private int mHighlightColor = NO_HIGHLIGHT_COLOR;
private CharSequence mLabel;
private CharSequence mShortDescription;
@@ -266,6 +259,7 @@
mIsEnabled = phoneAccount.isEnabled();
mExtras = phoneAccount.getExtras();
mGroupId = phoneAccount.getGroupId();
+ mSupportedAudioRoutes = phoneAccount.getSupportedAudioRoutes();
}
/**
@@ -411,6 +405,18 @@
}
/**
+ * Sets the audio routes supported by this {@link PhoneAccount}.
+ *
+ * @param routes bit mask of available routes.
+ * @return The builder.
+ * @hide
+ */
+ public Builder setSupportedAudioRoutes(int routes) {
+ mSupportedAudioRoutes = routes;
+ return this;
+ }
+
+ /**
* Creates an instance of a {@link PhoneAccount} based on the current builder settings.
*
* @return The {@link PhoneAccount}.
@@ -432,6 +438,7 @@
mShortDescription,
mSupportedUriSchemes,
mExtras,
+ mSupportedAudioRoutes,
mIsEnabled,
mGroupId);
}
@@ -448,6 +455,7 @@
CharSequence shortDescription,
List<String> supportedUriSchemes,
Bundle extras,
+ int supportedAudioRoutes,
boolean isEnabled,
String groupId) {
mAccountHandle = account;
@@ -460,6 +468,7 @@
mShortDescription = shortDescription;
mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
mExtras = extras;
+ mSupportedAudioRoutes = supportedAudioRoutes;
mIsEnabled = isEnabled;
mGroupId = groupId;
}
@@ -533,6 +542,17 @@
}
/**
+ * Determines if this {@code PhoneAccount} has routes specified by the passed in bit mask.
+ *
+ * @param route The routes to check.
+ * @return {@code true} if the phone account has the routes.
+ * @hide
+ */
+ public boolean hasAudioRoutes(int routes) {
+ return (mSupportedAudioRoutes & routes) == routes;
+ }
+
+ /**
* A short label describing a {@code PhoneAccount}.
*
* @return A label for this {@code PhoneAccount}.
@@ -572,6 +592,15 @@
}
/**
+ * The audio routes supported by this {@code PhoneAccount}.
+ *
+ * @hide
+ */
+ public int getSupportedAudioRoutes() {
+ return mSupportedAudioRoutes;
+ }
+
+ /**
* The icon to represent this {@code PhoneAccount}.
*
* @return The icon.
@@ -687,6 +716,7 @@
out.writeByte((byte) (mIsEnabled ? 1 : 0));
out.writeBundle(mExtras);
out.writeString(mGroupId);
+ out.writeInt(mSupportedAudioRoutes);
}
public static final Creator<PhoneAccount> CREATOR
@@ -731,6 +761,7 @@
mIsEnabled = in.readByte() == 1;
mExtras = in.readBundle();
mGroupId = in.readString();
+ mSupportedAudioRoutes = in.readInt();
}
@Override
@@ -740,7 +771,9 @@
.append("] PhoneAccount: ")
.append(mAccountHandle)
.append(" Capabilities: ")
- .append(capabilitiesToString(mCapabilities))
+ .append(capabilitiesToString())
+ .append(" Audio Routes: ")
+ .append(audioRoutesToString())
.append(" Schemes: ");
for (String scheme : mSupportedUriSchemes) {
sb.append(scheme)
@@ -760,7 +793,7 @@
* @param capabilities The capabilities bitmask.
* @return String representation of the capabilities bitmask.
*/
- private String capabilitiesToString(int capabilities) {
+ private String capabilitiesToString() {
StringBuilder sb = new StringBuilder();
if (hasCapabilities(CAPABILITY_VIDEO_CALLING)) {
sb.append("Video ");
@@ -794,4 +827,23 @@
}
return sb.toString();
}
+
+ private String audioRoutesToString() {
+ StringBuilder sb = new StringBuilder();
+
+ if (hasAudioRoutes(CallAudioState.ROUTE_BLUETOOTH)) {
+ sb.append("B");
+ }
+ if (hasAudioRoutes(CallAudioState.ROUTE_EARPIECE)) {
+ sb.append("E");
+ }
+ if (hasAudioRoutes(CallAudioState.ROUTE_SPEAKER)) {
+ sb.append("S");
+ }
+ if (hasAudioRoutes(CallAudioState.ROUTE_WIRED_HEADSET)) {
+ sb.append("W");
+ }
+
+ return sb.toString();
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index d3d5ea0..f123980 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -98,10 +98,22 @@
*/
public static final int OSEN = 5;
+ /**
+ * IEEE 802.11r Fast BSS Transition with PSK authentication.
+ * @hide
+ */
+ public static final int FT_PSK = 6;
+
+ /**
+ * IEEE 802.11r Fast BSS Transition with EAP authentication.
+ * @hide
+ */
+ public static final int FT_EAP = 7;
+
public static final String varName = "key_mgmt";
public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP", "IEEE8021X",
- "WPA2_PSK", "OSEN" };
+ "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP" };
}
/**