Merge "Remove tests already covered by CTS." into qt-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index 0de0d75..b1ffbad 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3171,6 +3171,7 @@
@UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
method public android.view.View getTooltipView();
+ method public boolean isAutofilled();
method public static boolean isDefaultFocusHighlightEnabled();
method public boolean isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
method protected void resetResolvedDrawables();
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 07ba2c6..038994f 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -590,6 +590,9 @@
public @NonNull Builder setServiceSolicitationUuid(
@Nullable ParcelUuid serviceSolicitationUuid) {
mServiceSolicitationUuid = serviceSolicitationUuid;
+ if (serviceSolicitationUuid == null) {
+ mServiceSolicitationUuidMask = null;
+ }
return this;
}
@@ -600,13 +603,16 @@
* indicate a match is needed for the bit in {@code serviceSolicitationUuid}, and 0 to
* ignore that bit.
*
+ * @param serviceSolicitationUuid can only be null if solicitationUuidMask is null.
+ * @param solicitationUuidMask can be null or a mask with no restriction.
+ *
* @throws IllegalArgumentException If {@code serviceSolicitationUuid} is {@code null} but
* {@code serviceSolicitationUuidMask} is not {@code null}.
*/
public @NonNull Builder setServiceSolicitationUuid(
@Nullable ParcelUuid serviceSolicitationUuid,
@Nullable ParcelUuid solicitationUuidMask) {
- if (mServiceSolicitationUuidMask != null && mServiceSolicitationUuid == null) {
+ if (solicitationUuidMask != null && serviceSolicitationUuid == null) {
throw new IllegalArgumentException(
"SolicitationUuid is null while SolicitationUuidMask is not null!");
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a69ca99..3bc40a7 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -3612,8 +3612,9 @@
* @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
* the callback must not be shared - it uniquely specifies this request.
* The callback is invoked on the default internal Handler.
- * @throws IllegalArgumentException if {@code request} specifies any mutable
- * {@code NetworkCapabilities}.
+ * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
+ * @throws SecurityException if missing the appropriate permissions.
+ * @throws RuntimeException if request limit per UID is exceeded.
*/
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull NetworkCallback networkCallback) {
@@ -3648,8 +3649,9 @@
* @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
* the callback must not be shared - it uniquely specifies this request.
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @throws IllegalArgumentException if {@code request} specifies any mutable
- * {@code NetworkCapabilities}.
+ * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
+ * @throws SecurityException if missing the appropriate permissions.
+ * @throws RuntimeException if request limit per UID is exceeded.
*/
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull NetworkCallback networkCallback, @NonNull Handler handler) {
@@ -3685,6 +3687,9 @@
* @param timeoutMs The time in milliseconds to attempt looking for a suitable network
* before {@link NetworkCallback#onUnavailable()} is called. The timeout must
* be a positive value (i.e. >0).
+ * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
+ * @throws SecurityException if missing the appropriate permissions.
+ * @throws RuntimeException if request limit per UID is exceeded.
*/
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull NetworkCallback networkCallback, int timeoutMs) {
@@ -3719,6 +3724,9 @@
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
* @param timeoutMs The time in milliseconds to attempt looking for a suitable network
* before {@link NetworkCallback#onUnavailable} is called.
+ * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
+ * @throws SecurityException if missing the appropriate permissions.
+ * @throws RuntimeException if request limit per UID is exceeded.
*/
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull NetworkCallback networkCallback, @NonNull Handler handler, int timeoutMs) {
@@ -3789,9 +3797,9 @@
* @param operation Action to perform when the network is available (corresponds
* to the {@link NetworkCallback#onAvailable} call. Typically
* comes from {@link PendingIntent#getBroadcast}. Cannot be null.
- * @throws IllegalArgumentException if {@code request} contains either
- * {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} or
- * {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
+ * @throws IllegalArgumentException if {@code request} contains invalid network capabilities.
+ * @throws SecurityException if missing the appropriate permissions.
+ * @throws RuntimeException if request limit per UID is exceeded.
*/
public void requestNetwork(@NonNull NetworkRequest request,
@NonNull PendingIntent operation) {
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index 87f8739..fe42111 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -58,15 +58,15 @@
@Nullable
public LinkAddress ipAddress;
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ @UnsupportedAppUsage
@Nullable
public InetAddress gateway;
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ @UnsupportedAppUsage
@NonNull
public final ArrayList<InetAddress> dnsServers;
/** @hide */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ @UnsupportedAppUsage
@Nullable
public String domains;
diff --git a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
index 87e369f..66c3e19 100644
--- a/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
+++ b/core/java/android/service/autofill/augmented/AugmentedAutofillService.java
@@ -228,7 +228,7 @@
} else {
// TODO(b/123099468): figure out if it's ok to reuse the proxy; add logging
if (sDebug) Log.d(TAG, "Reusing proxy for session " + sessionId);
- proxy.update(focusedId, focusedValue, callback);
+ proxy.update(focusedId, focusedValue, callback, cancellationSignal);
}
try {
@@ -252,6 +252,15 @@
Log.w(TAG, "No proxy for session " + sessionId);
return;
}
+ if (proxy.mCallback != null) {
+ try {
+ if (!proxy.mCallback.isCompleted()) {
+ proxy.mCallback.cancel();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "failed to check current pending request status", e);
+ }
+ }
proxy.destroy();
}
mAutofillProxies.clear();
@@ -442,7 +451,7 @@
}
private void update(@NonNull AutofillId focusedId, @NonNull AutofillValue focusedValue,
- @NonNull IFillCallback callback) {
+ @NonNull IFillCallback callback, @NonNull CancellationSignal cancellationSignal) {
synchronized (mLock) {
mFocusedId = focusedId;
mFocusedValue = focusedValue;
@@ -457,6 +466,7 @@
Log.d(TAG, "mCallback is updated.");
}
mCallback = callback;
+ mCancellationSignal = cancellationSignal;
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 779c75f..bf6191e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8852,6 +8852,7 @@
/**
* @hide
*/
+ @TestApi
public boolean isAutofilled() {
return (mPrivateFlags3 & PFLAG3_IS_AUTOFILLED) != 0;
}
@@ -21508,23 +21509,27 @@
}
saveCount = canvas.getSaveCount();
+ int topSaveCount = -1;
+ int bottomSaveCount = -1;
+ int leftSaveCount = -1;
+ int rightSaveCount = -1;
int solidColor = getSolidColor();
if (solidColor == 0) {
if (drawTop) {
- canvas.saveUnclippedLayer(left, top, right, top + length);
+ topSaveCount = canvas.saveUnclippedLayer(left, top, right, top + length);
}
if (drawBottom) {
- canvas.saveUnclippedLayer(left, bottom - length, right, bottom);
+ bottomSaveCount = canvas.saveUnclippedLayer(left, bottom - length, right, bottom);
}
if (drawLeft) {
- canvas.saveUnclippedLayer(left, top, left + length, bottom);
+ leftSaveCount = canvas.saveUnclippedLayer(left, top, left + length, bottom);
}
if (drawRight) {
- canvas.saveUnclippedLayer(right - length, top, right, bottom);
+ rightSaveCount = canvas.saveUnclippedLayer(right - length, top, right, bottom);
}
} else {
scrollabilityCache.setFadeColor(solidColor);
@@ -21541,21 +21546,19 @@
final Matrix matrix = scrollabilityCache.matrix;
final Shader fade = scrollabilityCache.shader;
- if (drawTop) {
- matrix.setScale(1, fadeHeight * topFadeStrength);
- matrix.postTranslate(left, top);
+ // must be restored in the reverse order that they were saved
+ if (drawRight) {
+ matrix.setScale(1, fadeHeight * rightFadeStrength);
+ matrix.postRotate(90);
+ matrix.postTranslate(right, top);
fade.setLocalMatrix(matrix);
p.setShader(fade);
- canvas.drawRect(left, top, right, top + length, p);
- }
+ if (solidColor == 0) {
+ canvas.restoreUnclippedLayer(rightSaveCount, p);
- if (drawBottom) {
- matrix.setScale(1, fadeHeight * bottomFadeStrength);
- matrix.postRotate(180);
- matrix.postTranslate(left, bottom);
- fade.setLocalMatrix(matrix);
- p.setShader(fade);
- canvas.drawRect(left, bottom - length, right, bottom, p);
+ } else {
+ canvas.drawRect(right - length, top, right, bottom, p);
+ }
}
if (drawLeft) {
@@ -21564,16 +21567,36 @@
matrix.postTranslate(left, top);
fade.setLocalMatrix(matrix);
p.setShader(fade);
- canvas.drawRect(left, top, left + length, bottom, p);
+ if (solidColor == 0) {
+ canvas.restoreUnclippedLayer(leftSaveCount, p);
+ } else {
+ canvas.drawRect(left, top, left + length, bottom, p);
+ }
}
- if (drawRight) {
- matrix.setScale(1, fadeHeight * rightFadeStrength);
- matrix.postRotate(90);
- matrix.postTranslate(right, top);
+ if (drawBottom) {
+ matrix.setScale(1, fadeHeight * bottomFadeStrength);
+ matrix.postRotate(180);
+ matrix.postTranslate(left, bottom);
fade.setLocalMatrix(matrix);
p.setShader(fade);
- canvas.drawRect(right - length, top, right, bottom, p);
+ if (solidColor == 0) {
+ canvas.restoreUnclippedLayer(bottomSaveCount, p);
+ } else {
+ canvas.drawRect(left, bottom - length, right, bottom, p);
+ }
+ }
+
+ if (drawTop) {
+ matrix.setScale(1, fadeHeight * topFadeStrength);
+ matrix.postTranslate(left, top);
+ fade.setLocalMatrix(matrix);
+ p.setShader(fade);
+ if (solidColor == 0) {
+ canvas.restoreUnclippedLayer(topSaveCount, p);
+ } else {
+ canvas.drawRect(left, top, right, top + length, p);
+ }
}
canvas.restoreToCount(saveCount);
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index c36b894..1f7ae0e 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1204,10 +1204,6 @@
AutofillValue value = null;
synchronized (mLock) {
- if (mForAugmentedAutofillOnly) {
- if (sVerbose) Log.v(TAG, "notifyValueChanged(): ignoring on augmented only mode");
- return;
- }
// If the session is gone some fields might still be highlighted, hence we have to
// remove the isAutofilled property even if no sessions are active.
if (mLastAutofilledData == null) {
@@ -1229,6 +1225,13 @@
}
}
+ if (mForAugmentedAutofillOnly) {
+ if (sVerbose) {
+ Log.v(TAG, "notifyValueChanged(): not notifying system server on "
+ + "augmented-only mode");
+ }
+ return;
+ }
if (!mEnabled || !isActiveLocked()) {
if (sVerbose) {
Log.v(TAG, "notifyValueChanged(" + view.getAutofillId()
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 4d5c9ad..a88c51a 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -237,7 +237,6 @@
private boolean mListViewDataChanged = false;
-
@Retention(SOURCE)
@IntDef({CONTENT_PREVIEW_FILE, CONTENT_PREVIEW_IMAGE, CONTENT_PREVIEW_TEXT})
private @interface ContentPreviewType {
@@ -2036,7 +2035,8 @@
return;
}
- if (mChooserRowAdapter.calculateChooserTargetWidth(right - left)
+ int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
+ if (mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
|| mAdapterView.getAdapter() == null) {
mAdapterView.setAdapter(mChooserRowAdapter);
@@ -2045,7 +2045,9 @@
return;
}
- int offset = 0;
+ final int bottomInset = mSystemWindowInsets != null
+ ? mSystemWindowInsets.bottom : 0;
+ int offset = bottomInset;
int rowsToShow = mChooserRowAdapter.getContentPreviewRowCount()
+ mChooserRowAdapter.getProfileRowCount()
+ mChooserRowAdapter.getServiceTargetRowCount()
@@ -2060,7 +2062,7 @@
// still zero? then use a default height and leave, which
// can happen when there are no targets to show
if (rowsToShow == 0) {
- offset = getResources().getDimensionPixelSize(
+ offset += getResources().getDimensionPixelSize(
R.dimen.chooser_max_collapsed_height);
mResolverDrawerLayout.setCollapsibleHeightReserved(offset);
return;
@@ -2085,8 +2087,9 @@
// make sure to leave room for direct share 4->8 expansion
int requiredExpansionHeight =
(int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
+ int topInset = mSystemWindowInsets != null ? mSystemWindowInsets.top : 0;
int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
- - requiredExpansionHeight;
+ - requiredExpansionHeight - topInset - bottomInset;
offset = Math.min(offset, minHeight);
}
@@ -2656,7 +2659,7 @@
@Override
public boolean isEnabled(int position) {
int viewType = getItemViewType(position);
- if (viewType == VIEW_TYPE_CONTENT_PREVIEW) {
+ if (viewType == VIEW_TYPE_CONTENT_PREVIEW || viewType == VIEW_TYPE_AZ_LABEL) {
return false;
}
return true;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 3ea746d..a5daa0a 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -46,6 +46,7 @@
import android.graphics.Bitmap;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Insets;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -67,12 +68,15 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.WindowInsets;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.Space;
import android.widget.TextView;
import android.widget.Toast;
@@ -136,6 +140,9 @@
private ColorMatrixColorFilter mSuspendedMatrixColorFilter;
+ protected Insets mSystemWindowInsets = null;
+ private Space mFooterSpacer = null;
+
/** See {@link #setRetainInOnStop}. */
private boolean mRetainInOnStop;
@@ -329,6 +336,11 @@
if (isVoiceInteraction()) {
rdl.setCollapsed(false);
}
+
+ rdl.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ rdl.setOnApplyWindowInsetsListener(this::onApplyWindowInsets);
+
mResolverDrawerLayout = rdl;
}
@@ -364,10 +376,38 @@
finish();
}
+ protected WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
+ mSystemWindowInsets = insets.getSystemWindowInsets();
+
+ mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top,
+ mSystemWindowInsets.right, 0);
+
+ View emptyView = findViewById(R.id.empty);
+ emptyView.setPadding(0, 0, 0, mSystemWindowInsets.bottom
+ + getResources().getDimensionPixelSize(
+ R.dimen.chooser_edge_margin_normal) * 2);
+
+ if (mFooterSpacer == null) {
+ mFooterSpacer = new Space(getApplicationContext());
+ } else {
+ ((ListView) mAdapterView).removeFooterView(mFooterSpacer);
+ }
+ mFooterSpacer.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT,
+ mSystemWindowInsets.bottom));
+ ((ListView) mAdapterView).addFooterView(mFooterSpacer);
+
+ return insets.consumeSystemWindowInsets();
+ }
+
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mAdapter.handlePackagesChanged();
+
+ if (mSystemWindowInsets != null) {
+ mResolverDrawerLayout.setPadding(mSystemWindowInsets.left, mSystemWindowInsets.top,
+ mSystemWindowInsets.right, 0);
+ }
}
private void initSuspendedColorMatrix() {
@@ -1277,6 +1317,10 @@
final ViewGroup buttonLayout = findViewById(R.id.button_bar);
if (buttonLayout != null) {
buttonLayout.setVisibility(View.VISIBLE);
+ int inset = mSystemWindowInsets != null ? mSystemWindowInsets.bottom : 0;
+ buttonLayout.setPadding(buttonLayout.getPaddingLeft(), buttonLayout.getPaddingTop(),
+ buttonLayout.getPaddingRight(), buttonLayout.getPaddingBottom() + inset);
+
mOnceButton = (Button) buttonLayout.findViewById(R.id.button_once);
mSettingsButton = (Button) buttonLayout.findViewById(R.id.button_app_settings);
mAlwaysButton = (Button) buttonLayout.findViewById(R.id.button_always);
diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
index 3adb36f..c73de8f 100644
--- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java
+++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java
@@ -854,12 +854,11 @@
final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
final int heightSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
- final int widthPadding = getPaddingLeft() + getPaddingRight();
// Currently we allot more height than is really needed so that the entirety of the
// sheet may be pulled up.
// TODO: Restrict the height here to be the right value.
- int heightUsed = getPaddingTop() + getPaddingBottom();
+ int heightUsed = 0;
// Measure always-show children first.
final int childCount = getChildCount();
@@ -869,11 +868,11 @@
if (lp.alwaysShow && child.getVisibility() != GONE) {
if (lp.maxHeight != -1) {
final int remainingHeight = heightSize - heightUsed;
- measureChildWithMargins(child, widthSpec, widthPadding,
+ measureChildWithMargins(child, widthSpec, 0,
MeasureSpec.makeMeasureSpec(lp.maxHeight, MeasureSpec.AT_MOST),
lp.maxHeight > remainingHeight ? lp.maxHeight - remainingHeight : 0);
} else {
- measureChildWithMargins(child, widthSpec, widthPadding, heightSpec, heightUsed);
+ measureChildWithMargins(child, widthSpec, 0, heightSpec, heightUsed);
}
heightUsed += child.getMeasuredHeight();
}
@@ -889,11 +888,11 @@
if (!lp.alwaysShow && child.getVisibility() != GONE) {
if (lp.maxHeight != -1) {
final int remainingHeight = heightSize - heightUsed;
- measureChildWithMargins(child, widthSpec, widthPadding,
+ measureChildWithMargins(child, widthSpec, 0,
MeasureSpec.makeMeasureSpec(lp.maxHeight, MeasureSpec.AT_MOST),
lp.maxHeight > remainingHeight ? lp.maxHeight - remainingHeight : 0);
} else {
- measureChildWithMargins(child, widthSpec, widthPadding, heightSpec, heightUsed);
+ measureChildWithMargins(child, widthSpec, 0, heightSpec, heightUsed);
}
heightUsed += child.getMeasuredHeight();
}
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 7a8c5c8..ebc6cd7 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -106,6 +106,11 @@
return reinterpret_cast<jint>(get_canvas(canvasHandle)->saveUnclippedLayer(l, t, r, b));
}
+static void restoreUnclippedLayer(jlong canvasHandle, jint saveCount, jlong paintHandle) {
+ Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+ get_canvas(canvasHandle)->restoreUnclippedLayer(saveCount, *paint);
+}
+
static bool restore(jlong canvasHandle) {
Canvas* canvas = get_canvas(canvasHandle);
if (canvas->getSaveCount() <= 1) {
@@ -668,6 +673,7 @@
{"nSaveLayer","(JFFFFJI)I", (void*) CanvasJNI::saveLayer},
{"nSaveLayerAlpha","(JFFFFII)I", (void*) CanvasJNI::saveLayerAlpha},
{"nSaveUnclippedLayer","(JIIII)I", (void*) CanvasJNI::saveUnclippedLayer},
+ {"nRestoreUnclippedLayer","(JIJ)V", (void*) CanvasJNI::restoreUnclippedLayer},
{"nGetSaveCount","(J)I", (void*) CanvasJNI::getSaveCount},
{"nRestore","(J)Z", (void*) CanvasJNI::restore},
{"nRestoreToCount","(JI)V", (void*) CanvasJNI::restoreToCount},
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index f595046..8ba2c60 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -88,5 +88,4 @@
<style name="Theme.DeviceDefault.Resolver" parent="Theme.DeviceDefault.ResolverCommon">
<item name="windowLightNavigationBar">false</item>
</style>
-
</resources>
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 6225896..7a8f411 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -50,9 +50,10 @@
<color name="list_divider_color_dark">#85ffffff</color>
<color name="list_divider_opacity_device_default_light">@android:color/white</color>
<color name="list_divider_opacity_device_default_dark">@android:color/white</color>
- <color name="loading_gradient_background_color_dark">#2D3033</color>
- <color name="loading_gradient_background_color_light">#DADCE0</color>
- <color name="loading_gradient_highlight_color_dark">#3C4043</color>
+
+ <color name="loading_gradient_background_color_dark">#44484C</color>
+ <color name="loading_gradient_background_color_light">#F8F9FA</color>
+ <color name="loading_gradient_highlight_color_dark">#4D5155</color>
<color name="loading_gradient_highlight_color_light">#F1F3F4</color>
<color name="edge_effect_device_default_light">@android:color/black</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0daebd7..2de5397 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3457,7 +3457,7 @@
<!-- Flag indicating whether the assist disclosure can be disabled using
ASSIST_DISCLOSURE_ENABLED. -->
- <bool name="config_allowDisablingAssistDisclosure">false</bool>
+ <bool name="config_allowDisablingAssistDisclosure">true</bool>
<!-- True if the device supports system navigation keys. -->
<bool name="config_supportSystemNavigationKeys">false</bool>
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index d6c0a10..3c65caf 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -78,6 +78,7 @@
<item>ar-YE</item> <!-- Arabic (Yemen) -->
<item>ar-YE-u-nu-latn</item> <!-- Arabic (Yemen, Western Digits) -->
<item>as-IN</item> <!-- Assamese (India) -->
+ <item>as-IN-u-nu-latn</item> <!-- Assamese (India, Western Digits) -->
<item>asa-TZ</item> <!-- Asu (Tanzania) -->
<item>ast-ES</item> <!-- Asturian (Spain) -->
<item>az-Cyrl-AZ</item> <!-- Azerbaijani (Cyrillic, Azerbaijan) -->
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index f4ebbad..6289262 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1678,8 +1678,11 @@
<item name="colorControlActivated">?attr/colorControlHighlight</item>
<item name="listPreferredItemPaddingStart">?attr/dialogPreferredPadding</item>
<item name="listPreferredItemPaddingEnd">?attr/dialogPreferredPadding</item>
- <item name="navigationBarColor">?attr/colorBackgroundFloating</item>
- <item name="navigationBarDividerColor">@color/chooser_row_divider</item>
+ <item name="navigationBarColor">@android:color/transparent</item>
+ </style>
+
+ <style name="Theme.DeviceDefault.Resolver" parent="Theme.DeviceDefault.ResolverCommon">
+ <item name="windowLightNavigationBar">true</item>
</style>
<style name="Animation.DeviceDefault.Activity.Resolver" parent="Animation.DeviceDefault.Activity">
@@ -1690,10 +1693,6 @@
<item name="taskOpenExitAnimation">@anim/resolver_close_anim</item>
</style>
- <style name="Theme.DeviceDefault.Resolver" parent="Theme.DeviceDefault.ResolverCommon">
- <item name="windowLightNavigationBar">true</item>
- </style>
-
<!-- @hide DeviceDefault themes for the autofill FillUi -->
<style name="Theme.DeviceDefault.Autofill" />
<style name="Theme.DeviceDefault.Light.Autofill" />
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index d4d5ae7..5648b85 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -559,6 +559,16 @@
}
/**
+ * @hide
+ * @param saveCount The save level to restore to.
+ * @param paint This is copied and is applied to the area within the unclipped layer's
+ * bounds (i.e. equivalent to a drawPaint()) before restore() is called.
+ */
+ public void restoreUnclippedLayer(int saveCount, Paint paint) {
+ nRestoreUnclippedLayer(mNativeCanvasWrapper, saveCount, paint.getNativeInstance());
+ }
+
+ /**
* Helper version of saveLayer() that takes 4 values rather than a RectF.
*
* As of API Level API level {@value Build.VERSION_CODES#P} the only valid
@@ -1398,6 +1408,9 @@
@CriticalNative
private static native int nSaveUnclippedLayer(long nativeCanvas, int l, int t, int r, int b);
@CriticalNative
+ private static native void nRestoreUnclippedLayer(long nativeCanvas, int saveCount,
+ long nativePaint);
+ @CriticalNative
private static native boolean nRestore(long canvasHandle);
@CriticalNative
private static native void nRestoreToCount(long canvasHandle, int saveCount);
diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in
index 14e3a32..2deb565 100644
--- a/libs/hwui/DisplayListOps.in
+++ b/libs/hwui/DisplayListOps.in
@@ -26,7 +26,8 @@
X(ClipRect)
X(ClipRRect)
X(ClipRegion)
-X(DrawPaint)
+X(DrawPaint)
+X(DrawBehind)
X(DrawPath)
X(DrawRect)
X(DrawRegion)
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 8594766..e58fbbe 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -20,6 +20,7 @@
#include "SkAndroidFrameworkUtils.h"
#include "SkCanvas.h"
+#include "SkCanvasPriv.h"
#include "SkData.h"
#include "SkDrawShadowInfo.h"
#include "SkImage.h"
@@ -187,6 +188,12 @@
SkPaint paint;
void draw(SkCanvas* c, const SkMatrix&) const { c->drawPaint(paint); }
};
+struct DrawBehind final : Op {
+ static const auto kType = Type::DrawBehind;
+ DrawBehind(const SkPaint& paint) : paint(paint) {}
+ SkPaint paint;
+ void draw(SkCanvas* c, const SkMatrix&) const { SkCanvasPriv::DrawBehind(c, paint); }
+};
struct DrawPath final : Op {
static const auto kType = Type::DrawPath;
DrawPath(const SkPath& path, const SkPaint& paint) : path(path), paint(paint) {}
@@ -565,6 +572,9 @@
void DisplayListData::drawPaint(const SkPaint& paint) {
this->push<DrawPaint>(0, paint);
}
+void DisplayListData::drawBehind(const SkPaint& paint) {
+ this->push<DrawBehind>(0, paint);
+}
void DisplayListData::drawPath(const SkPath& path, const SkPaint& paint) {
this->push<DrawPath>(0, path, paint);
}
@@ -834,6 +844,9 @@
void RecordingCanvas::onDrawPaint(const SkPaint& paint) {
fDL->drawPaint(paint);
}
+void RecordingCanvas::onDrawBehind(const SkPaint& paint) {
+ fDL->drawBehind(paint);
+}
void RecordingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
fDL->drawPath(path, paint);
}
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 3a76ca1..7269bca 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -89,6 +89,7 @@
void clipRegion(const SkRegion&, SkClipOp);
void drawPaint(const SkPaint&);
+ void drawBehind(const SkPaint&);
void drawPath(const SkPath&, const SkPaint&);
void drawRect(const SkRect&, const SkPaint&);
void drawRegion(const SkRegion&, const SkPaint&);
@@ -157,6 +158,7 @@
void onClipRegion(const SkRegion&, SkClipOp) override;
void onDrawPaint(const SkPaint&) override;
+ void onDrawBehind(const SkPaint&) override;
void onDrawPath(const SkPath&, const SkPaint&) override;
void onDrawRect(const SkRect&, const SkPaint&) override;
void onDrawRegion(const SkRegion&, const SkPaint&) override;
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index f328a53..bebda85 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -26,6 +26,7 @@
#include <SkAndroidFrameworkUtils.h>
#include <SkAnimatedImage.h>
+#include <SkCanvasPriv.h>
#include <SkCanvasStateUtils.h>
#include <SkColorFilter.h>
#include <SkDeque.h>
@@ -191,6 +192,18 @@
return SkAndroidFrameworkUtils::SaveBehind(mCanvas, &bounds);
}
+void SkiaCanvas::restoreUnclippedLayer(int restoreCount, const SkPaint& paint) {
+
+ while (mCanvas->getSaveCount() > restoreCount + 1) {
+ this->restore();
+ }
+
+ if (mCanvas->getSaveCount() == restoreCount + 1) {
+ SkCanvasPriv::DrawBehind(mCanvas, *filterPaint(paint));
+ this->restore();
+ }
+}
+
class SkiaCanvas::Clip {
public:
Clip(const SkRect& rect, SkClipOp op, const SkMatrix& m)
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 3fe2bce..bbe91eb 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -69,6 +69,7 @@
virtual int save(SaveFlags::Flags flags) override;
virtual void restore() override;
virtual void restoreToCount(int saveCount) override;
+ virtual void restoreUnclippedLayer(int saveCount, const SkPaint& paint) override;
virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
SaveFlags::Flags flags) override;
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 11e8579..ac8db21 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -191,6 +191,7 @@
virtual int save(SaveFlags::Flags flags) = 0;
virtual void restore() = 0;
virtual void restoreToCount(int saveCount) = 0;
+ virtual void restoreUnclippedLayer(int saveCount, const SkPaint& paint) = 0;
virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
SaveFlags::Flags flags) = 0;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index ccc1701..1f9ab5a 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -176,7 +176,7 @@
// position
Matrix4 windowTransform;
damageAccumulator.computeCurrentTransform(&windowTransform);
- node->getSkiaLayer()->inverseTransformInWindow = windowTransform;
+ node->getSkiaLayer()->inverseTransformInWindow.loadInverse(windowTransform);
} else {
String8 cachesOutput;
mRenderThread.cacheManager().dumpMemoryUsage(cachesOutput,
diff --git a/packages/CtsShim/apk/arm/CtsShim.apk b/packages/CtsShim/apk/arm/CtsShim.apk
index a911603..7d9f8e3 100644
--- a/packages/CtsShim/apk/arm/CtsShim.apk
+++ b/packages/CtsShim/apk/arm/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/arm/CtsShimPriv.apk b/packages/CtsShim/apk/arm/CtsShimPriv.apk
index 845d781..dcccada 100644
--- a/packages/CtsShim/apk/arm/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/arm/CtsShimPriv.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShim.apk b/packages/CtsShim/apk/x86/CtsShim.apk
index a911603..7d9f8e3 100644
--- a/packages/CtsShim/apk/x86/CtsShim.apk
+++ b/packages/CtsShim/apk/x86/CtsShim.apk
Binary files differ
diff --git a/packages/CtsShim/apk/x86/CtsShimPriv.apk b/packages/CtsShim/apk/x86/CtsShimPriv.apk
index 2fc9a94..3501fa4 100644
--- a/packages/CtsShim/apk/x86/CtsShimPriv.apk
+++ b/packages/CtsShim/apk/x86/CtsShimPriv.apk
Binary files differ
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index aefa882..c013b8c 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -42,8 +42,8 @@
static_libs: [
"androidx.annotation_annotation",
"ipmemorystore-client",
- "netd_aidl_interface-java",
- "networkstack-aidl-interfaces-java",
+ "netd_aidl_interface-V2-java",
+ "networkstack-aidl-interfaces-V3-java",
"datastallprotosnano",
"networkstackprotosnano",
"captiveportal-lib",
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
index c394d4c..2fae0c7 100644
--- a/packages/NetworkStack/src/com/android/server/NetworkStackService.java
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -49,6 +49,7 @@
import android.net.util.SharedLog;
import android.os.IBinder;
import android.os.RemoteException;
+import android.util.ArraySet;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;
@@ -62,7 +63,6 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* Android service used to start the network stack when bound to via an intent.
@@ -118,14 +118,12 @@
@GuardedBy("mValidationLogs")
private final ArrayDeque<SharedLog> mValidationLogs = new ArrayDeque<>(MAX_VALIDATION_LOGS);
- private static final int VERSION_UNKNOWN = 0;
private static final String DUMPSYS_ARG_VERSION = "version";
- /** Version of the AIDL interfaces observed on the system */
- private final AtomicInteger mSystemAidlVersion = new AtomicInteger(VERSION_UNKNOWN);
-
- /** Whether different versions have been observed on interfaces provided by the system */
- private volatile boolean mConflictingSystemAidlVersions = false;
+ /** Version of the framework AIDL interfaces observed. Should hold only one value. */
+ @GuardedBy("mFrameworkAidlVersions")
+ private final ArraySet<Integer> mFrameworkAidlVersions = new ArraySet<>(1);
+ private final int mNetdAidlVersion;
private SharedLog addValidationLogs(Network network, String name) {
final SharedLog log = new SharedLog(NUM_VALIDATION_LOG_LINES, network + " - " + name);
@@ -146,6 +144,15 @@
mCm = context.getSystemService(ConnectivityManager.class);
mIpMemoryStoreService = new IpMemoryStoreService(context);
+ int netdVersion;
+ try {
+ netdVersion = mNetd.getInterfaceVersion();
+ } catch (RemoteException e) {
+ mLog.e("Error obtaining INetd version", e);
+ netdVersion = -1;
+ }
+ mNetdAidlVersion = netdVersion;
+
try {
mObserverRegistry.register(mNetd);
} catch (RemoteException e) {
@@ -154,9 +161,8 @@
}
private void updateSystemAidlVersion(final int version) {
- final int previousVersion = mSystemAidlVersion.getAndSet(version);
- if (previousVersion != VERSION_UNKNOWN && previousVersion != version) {
- mConflictingSystemAidlVersions = true;
+ synchronized (mFrameworkAidlVersions) {
+ mFrameworkAidlVersions.add(version);
}
}
@@ -230,12 +236,16 @@
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
@Nullable String[] args) {
checkDumpPermission();
+
+ final IndentingPrintWriter pw = new IndentingPrintWriter(fout, " ");
+ pw.println("NetworkStack version:");
+ dumpVersion(pw);
+ pw.println();
+
if (args != null && args.length >= 1 && DUMPSYS_ARG_VERSION.equals(args[0])) {
- dumpVersion(fout);
return;
}
- final IndentingPrintWriter pw = new IndentingPrintWriter(fout, " ");
pw.println("NetworkStack logs:");
mLog.dump(fd, pw, args);
@@ -283,8 +293,10 @@
*/
private void dumpVersion(@NonNull PrintWriter fout) {
fout.println("NetworkStackConnector: " + this.VERSION);
- fout.println("SystemServer: " + mSystemAidlVersion);
- fout.println("SystemServerConflicts: " + mConflictingSystemAidlVersions);
+ synchronized (mFrameworkAidlVersions) {
+ fout.println("SystemServer: " + mFrameworkAidlVersions);
+ }
+ fout.println("Netd: " + mNetdAidlVersion);
}
@Override
diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/unit/Android.bp
similarity index 96%
rename from packages/NetworkStack/tests/Android.bp
rename to packages/NetworkStack/tests/unit/Android.bp
index 039f6bf..6cc8054 100644
--- a/packages/NetworkStack/tests/Android.bp
+++ b/packages/NetworkStack/tests/unit/Android.bp
@@ -72,7 +72,7 @@
"libutilscallstack",
"libziparchive",
"libz",
- "netd_aidl_interface-cpp",
+ "netd_aidl_interface-V2-cpp",
],
}
@@ -94,7 +94,7 @@
"liblog",
"libcutils",
"libnativehelper",
- "netd_aidl_interface-cpp",
+ "netd_aidl_interface-V2-cpp",
],
static_libs: [
"libapf",
diff --git a/packages/NetworkStack/tests/AndroidManifest.xml b/packages/NetworkStack/tests/unit/AndroidManifest.xml
similarity index 100%
rename from packages/NetworkStack/tests/AndroidManifest.xml
rename to packages/NetworkStack/tests/unit/AndroidManifest.xml
diff --git a/packages/NetworkStack/tests/AndroidTest.xml b/packages/NetworkStack/tests/unit/AndroidTest.xml
similarity index 100%
rename from packages/NetworkStack/tests/AndroidTest.xml
rename to packages/NetworkStack/tests/unit/AndroidTest.xml
diff --git a/packages/NetworkStack/tests/jni/apf_jni.cpp b/packages/NetworkStack/tests/unit/jni/apf_jni.cpp
similarity index 100%
rename from packages/NetworkStack/tests/jni/apf_jni.cpp
rename to packages/NetworkStack/tests/unit/jni/apf_jni.cpp
diff --git a/packages/NetworkStack/tests/res/raw/apf.pcap b/packages/NetworkStack/tests/unit/res/raw/apf.pcap
similarity index 100%
rename from packages/NetworkStack/tests/res/raw/apf.pcap
rename to packages/NetworkStack/tests/unit/res/raw/apf.pcap
Binary files differ
diff --git a/packages/NetworkStack/tests/res/raw/apfPcap.pcap b/packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
similarity index 100%
rename from packages/NetworkStack/tests/res/raw/apfPcap.pcap
rename to packages/NetworkStack/tests/unit/res/raw/apfPcap.pcap
Binary files differ
diff --git a/packages/NetworkStack/tests/src/android/net/apf/ApfTest.java b/packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/apf/ApfTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/apf/ApfTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/apf/Bpf2Apf.java b/packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/apf/Bpf2Apf.java
rename to packages/NetworkStack/tests/unit/src/android/net/apf/Bpf2Apf.java
diff --git a/packages/NetworkStack/tests/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java b/packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/captiveportal/CaptivePortalProbeSpecTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpLeaseRepositoryTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpLeaseRepositoryTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/dhcp/DhcpPacketTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpPacketTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/dhcp/DhcpServerTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServerTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/dhcp/DhcpServingParamsTest.java b/packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/dhcp/DhcpServingParamsTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/dhcp/DhcpServingParamsTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/ip/IpClientTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/ip/IpClientTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/ip/IpReachabilityMonitorTest.java b/packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/ip/IpReachabilityMonitorTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/ip/IpReachabilityMonitorTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/util/ConnectivityPacketSummaryTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/util/ConnectivityPacketSummaryTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/util/ConnectivityPacketSummaryTest.java
diff --git a/packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java b/packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/android/net/util/PacketReaderTest.java
rename to packages/NetworkStack/tests/unit/src/android/net/util/PacketReaderTest.java
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
similarity index 99%
rename from packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
rename to packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
index 2618675..832b712 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -297,6 +297,7 @@
setOtherFallbackUrls(TEST_OTHER_FALLBACK_URL);
setFallbackSpecs(null); // Test with no fallback spec by default
when(mRandom.nextInt()).thenReturn(0);
+
// DNS probe timeout should not be defined more than half of HANDLER_TIMEOUT_MS. Otherwise,
// it will fail the test because of timeout expired for querying AAAA and A sequentially.
when(mResources.getInteger(eq(R.integer.config_captive_portal_dns_probe_timeout)))
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
rename to packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/IpMemoryStoreServiceTest.java
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java b/packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
similarity index 100%
rename from packages/NetworkStack/tests/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
rename to packages/NetworkStack/tests/unit/src/com/android/server/connectivity/ipmemorystore/RelevanceUtilsTests.java
diff --git a/packages/NetworkStack/tests/src/com/android/server/util/SharedLogTest.java b/packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
similarity index 100%
rename from packages/NetworkStack/tests/src/com/android/server/util/SharedLogTest.java
rename to packages/NetworkStack/tests/unit/src/com/android/server/util/SharedLogTest.java
diff --git a/packages/SystemUI/res/drawable/corner_gesture_hint.xml b/packages/SystemUI/res/drawable/corner_gesture_hint.xml
new file mode 100644
index 0000000..3f4abb0
--- /dev/null
+++ b/packages/SystemUI/res/drawable/corner_gesture_hint.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="12dp"
+ android:width="12dp"
+ android:viewportWidth="12"
+ android:viewportHeight="12">
+
+ <path android:fillColor="#00000000"
+ android:pathData="M 1.18 10.65 C 1.18 5.58 5.41 1.18 10.65 1.18"
+ android:strokeColor="#000"
+ android:strokeLineCap="round"
+ android:strokeWidth="1.3" />
+</vector>
diff --git a/packages/SystemUI/res/layout/rounded_corners.xml b/packages/SystemUI/res/layout/rounded_corners.xml
index 26cf792..02651a2 100644
--- a/packages/SystemUI/res/layout/rounded_corners.xml
+++ b/packages/SystemUI/res/layout/rounded_corners.xml
@@ -32,4 +32,22 @@
android:tint="#ff000000"
android:layout_gravity="right|bottom"
android:src="@drawable/rounded" />
+ <ImageView
+ android:id="@+id/assist_hint_left"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:padding="6dp"
+ android:layout_gravity="left|top"
+ android:src="@drawable/corner_gesture_hint"
+ android:tint="#ffffffff"
+ android:visibility="gone" />
+ <ImageView
+ android:id="@+id/assist_hint_right"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:padding="6dp"
+ android:layout_gravity="right|bottom"
+ android:src="@drawable/corner_gesture_hint"
+ android:tint="#ffffffff"
+ android:visibility="gone" />
</com.android.systemui.RegionInterceptingFrameLayout>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 417cc68..6a4dbc8d 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1187,7 +1187,7 @@
throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
}
String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
- int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
+ int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index c0f03a6..69d3af8 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -105,6 +105,7 @@
private float mDensity;
private WindowManager mWindowManager;
private int mRotation;
+ private boolean mAssistHintVisible;
private DisplayCutoutView mCutoutTop;
private DisplayCutoutView mCutoutBottom;
private SecureSetting mColorInversionSetting;
@@ -133,6 +134,55 @@
mHandler = startHandlerThread();
mHandler.post(this::startOnScreenDecorationsThread);
setupStatusBarPaddingIfNeeded();
+ putComponent(ScreenDecorations.class, this);
+ }
+
+ private void fade(View view, boolean fadeIn) {
+ if (fadeIn) {
+ view.animate().cancel();
+ view.setAlpha(0f);
+ view.setVisibility(View.VISIBLE);
+ view.animate().alpha(1f);
+ } else {
+ view.animate().cancel();
+ view.animate().alpha(0f).withEndAction(() -> view.setVisibility(View.INVISIBLE));
+ }
+
+ }
+
+ /**
+ * Controls the visibility of the assist gesture handles.
+ *
+ * @param visible whether the handles should be shown
+ */
+ public void setAssistHintVisible(boolean visible) {
+ if (mAssistHintVisible != visible) {
+ mAssistHintVisible = visible;
+
+ View assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
+ View assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
+ View assistHintBottomLeft = mBottomOverlay.findViewById(R.id.assist_hint_left);
+ View assistHintBottomRight = mBottomOverlay.findViewById(R.id.assist_hint_right);
+
+ switch (mRotation) {
+ case RotationUtils.ROTATION_NONE:
+ fade(assistHintBottomLeft, mAssistHintVisible);
+ fade(assistHintBottomRight, mAssistHintVisible);
+ break;
+ case RotationUtils.ROTATION_LANDSCAPE:
+ fade(assistHintTopRight, mAssistHintVisible);
+ fade(assistHintBottomRight, mAssistHintVisible);
+ break;
+ case RotationUtils.ROTATION_SEASCAPE:
+ fade(assistHintTopLeft, mAssistHintVisible);
+ fade(assistHintBottomLeft, mAssistHintVisible);
+ break;
+ case RotationUtils.ROTATION_UPSIDE_DOWN:
+ fade(assistHintTopLeft, mAssistHintVisible);
+ fade(assistHintTopRight, mAssistHintVisible);
+ break;
+ }
+ }
}
@VisibleForTesting
@@ -375,12 +425,52 @@
updateView(bottomRight, Gravity.TOP | Gravity.LEFT, 0);
}
+ updateAssistantHandleViews();
mCutoutTop.setRotation(mRotation);
mCutoutBottom.setRotation(mRotation);
updateWindowVisibilities();
}
+ private void updateAssistantHandleViews() {
+ View assistHintTopLeft = mOverlay.findViewById(R.id.assist_hint_left);
+ View assistHintTopRight = mOverlay.findViewById(R.id.assist_hint_right);
+ View assistHintBottomLeft = mBottomOverlay.findViewById(R.id.assist_hint_left);
+ View assistHintBottomRight = mBottomOverlay.findViewById(R.id.assist_hint_right);
+
+ final int assistHintVisibility = mAssistHintVisible ? View.VISIBLE : View.INVISIBLE;
+
+ if (mRotation == RotationUtils.ROTATION_NONE) {
+ assistHintTopLeft.setVisibility(View.GONE);
+ assistHintTopRight.setVisibility(View.GONE);
+ assistHintBottomLeft.setVisibility(assistHintVisibility);
+ assistHintBottomRight.setVisibility(assistHintVisibility);
+ updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
+ updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
+ } else if (mRotation == RotationUtils.ROTATION_LANDSCAPE) {
+ assistHintTopLeft.setVisibility(View.GONE);
+ assistHintTopRight.setVisibility(assistHintVisibility);
+ assistHintBottomLeft.setVisibility(View.GONE);
+ assistHintBottomRight.setVisibility(assistHintVisibility);
+ updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.LEFT, 270);
+ updateView(assistHintBottomRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
+ } else if (mRotation == RotationUtils.ROTATION_UPSIDE_DOWN) {
+ assistHintTopLeft.setVisibility(assistHintVisibility);
+ assistHintTopRight.setVisibility(assistHintVisibility);
+ assistHintBottomLeft.setVisibility(View.GONE);
+ assistHintBottomRight.setVisibility(View.GONE);
+ updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
+ updateView(assistHintTopRight, Gravity.BOTTOM | Gravity.RIGHT, 180);
+ } else if (mRotation == RotationUtils.ROTATION_SEASCAPE) {
+ assistHintTopLeft.setVisibility(assistHintVisibility);
+ assistHintTopRight.setVisibility(View.GONE);
+ assistHintBottomLeft.setVisibility(assistHintVisibility);
+ assistHintBottomRight.setVisibility(View.GONE);
+ updateView(assistHintTopLeft, Gravity.BOTTOM | Gravity.RIGHT, 180);
+ updateView(assistHintBottomLeft, Gravity.BOTTOM | Gravity.LEFT, 270);
+ }
+ }
+
private void updateView(View v, int gravity, int rotation) {
((FrameLayout.LayoutParams)v.getLayoutParams()).gravity = gravity;
v.setRotation(rotation);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 51bd9f8..f0c38fb 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -169,7 +169,7 @@
}
protected boolean shouldShowOrb() {
- return true;
+ return false;
}
public void startAssist(Bundle args) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index dcc0419..7e016bb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -16,6 +16,7 @@
package com.android.systemui.bubbles;
+import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL;
import static android.service.notification.NotificationListenerService.REASON_APP_CANCEL_ALL;
import static android.service.notification.NotificationListenerService.REASON_CANCEL;
@@ -41,7 +42,9 @@
import android.app.IActivityTaskManager;
import android.app.Notification;
import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.pm.ParceledListSlice;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -112,7 +115,7 @@
public static final int MAX_BUBBLES = 5; // TODO: actually enforce this
// Enables some subset of notifs to automatically become bubbles
- private static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false;
+ public static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false;
/** Flag to enable or disable the entire feature */
private static final String ENABLE_BUBBLES = "experiment_enable_bubbles";
@@ -450,7 +453,8 @@
if (!areBubblesEnabled(mContext)) {
return;
}
- if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)) {
+ if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
+ && canLaunchInActivityView(mContext, entry)) {
updateShowInShadeForSuppressNotification(entry);
}
}
@@ -460,7 +464,8 @@
if (!areBubblesEnabled(mContext)) {
return;
}
- if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)) {
+ if (mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
+ && canLaunchInActivityView(mContext, entry)) {
updateBubble(entry);
}
}
@@ -470,7 +475,8 @@
if (!areBubblesEnabled(mContext)) {
return;
}
- boolean shouldBubble = mNotificationInterruptionStateProvider.shouldBubbleUp(entry);
+ boolean shouldBubble = mNotificationInterruptionStateProvider.shouldBubbleUp(entry)
+ && canLaunchInActivityView(mContext, entry);
if (!shouldBubble && mBubbleData.hasBubbleWithKey(entry.key)) {
// It was previously a bubble but no longer a bubble -- lets remove it
removeBubble(entry.key, DISMISS_NO_LONGER_BUBBLE);
@@ -657,12 +663,6 @@
|| autoBubbleAll;
}
- private boolean shouldAutoExpand(NotificationEntry entry) {
- Notification.BubbleMetadata metadata = entry.getBubbleMetadata();
- return metadata != null && metadata.getAutoExpandBubble()
- && isForegroundApp(mContext, entry.notification.getPackageName());
- }
-
private void updateShowInShadeForSuppressNotification(NotificationEntry entry) {
boolean suppressNotification = entry.getBubbleMetadata() != null
&& entry.getBubbleMetadata().isNotificationSuppressed()
@@ -771,6 +771,48 @@
(int) (defaultBounciness * 100)) / 100f;
}
+ /**
+ * Whether an intent is properly configured to display in an {@link android.app.ActivityView}.
+ *
+ * Keep checks in sync with NotificationManagerService#canLaunchInActivityView. Typically
+ * that should filter out any invalid bubbles, but should protect SysUI side just in case.
+ *
+ * @param context the context to use.
+ * @param entry the entry to bubble.
+ */
+ static boolean canLaunchInActivityView(Context context, NotificationEntry entry) {
+ PendingIntent intent = entry.getBubbleMetadata() != null
+ ? entry.getBubbleMetadata().getIntent()
+ : null;
+ if (intent == null) {
+ Log.w(TAG, "Unable to create bubble -- no intent");
+ return false;
+ }
+ ActivityInfo info =
+ intent.getIntent().resolveActivityInfo(context.getPackageManager(), 0);
+ if (info == null) {
+ Log.w(TAG, "Unable to send as bubble -- couldn't find activity info for intent: "
+ + intent);
+ return false;
+ }
+ if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
+ Log.w(TAG, "Unable to send as bubble -- activity is not resizable for intent: "
+ + intent);
+ return false;
+ }
+ if (info.documentLaunchMode != DOCUMENT_LAUNCH_ALWAYS) {
+ Log.w(TAG, "Unable to send as bubble -- activity is not documentLaunchMode=always "
+ + "for intent: " + intent);
+ return false;
+ }
+ if ((info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
+ Log.w(TAG, "Unable to send as bubble -- activity is not embeddable for intent: "
+ + intent);
+ return false;
+ }
+ return true;
+ }
+
/** PinnedStackListener that dispatches IME visibility updates to the stack. */
private class BubblesImeListener extends IPinnedStackListener.Stub {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index e7948b5..6add4a4 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -16,12 +16,10 @@
package com.android.systemui.bubbles;
-import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
-import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING;
-import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE;
-import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS;
import static android.view.Display.INVALID_DISPLAY;
+import static com.android.systemui.bubbles.BubbleController.DEBUG_ENABLE_AUTO_BUBBLE;
+
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.ActivityView;
@@ -30,7 +28,6 @@
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
@@ -337,11 +334,10 @@
mNotifRow = null;
}
mActivityView.setVisibility(VISIBLE);
- } else {
+ } else if (DEBUG_ENABLE_AUTO_BUBBLE) {
// Hide activity view if we had it previously
mActivityView.setVisibility(GONE);
mNotifRow = mEntry.getRow();
-
}
updateView();
}
@@ -532,59 +528,14 @@
@Nullable
private PendingIntent getBubbleIntent(NotificationEntry entry) {
Notification notif = entry.notification.getNotification();
- String packageName = entry.notification.getPackageName();
Notification.BubbleMetadata data = notif.getBubbleMetadata();
- if (data != null && canLaunchInActivityView(data.getIntent(), true /* enableLogging */,
- packageName)) {
+ if (BubbleController.canLaunchInActivityView(mContext, entry) && data != null) {
return data.getIntent();
- } else if (BubbleController.shouldUseContentIntent(mContext)
- && canLaunchInActivityView(notif.contentIntent, false /* enableLogging */,
- packageName)) {
- return notif.contentIntent;
}
return null;
}
/**
- * Whether an intent is properly configured to display in an {@link android.app.ActivityView}.
- *
- * @param intent the pending intent of the bubble.
- * @param enableLogging whether bubble developer error should be logged.
- * @param packageName the notification package name for this bubble.
- * @return
- */
- private boolean canLaunchInActivityView(PendingIntent intent, boolean enableLogging,
- String packageName) {
- if (intent == null) {
- return false;
- }
- ActivityInfo info =
- intent.getIntent().resolveActivityInfo(mContext.getPackageManager(), 0);
- if (info == null) {
- if (enableLogging) {
- StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
- BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING);
- }
- return false;
- }
- if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
- if (enableLogging) {
- StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
- BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE);
- }
- return false;
- }
- if (info.documentLaunchMode != DOCUMENT_LAUNCH_ALWAYS) {
- if (enableLogging) {
- StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
- BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS);
- }
- return false;
- }
- return (info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) != 0;
- }
-
- /**
* Listener that is notified when a bubble is blocked.
*/
public interface OnBubbleBlockedListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
index 812c9a7..689d161 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java
@@ -212,7 +212,7 @@
return;
}
mMobileDrawable.setTintList(
- ColorStateList.valueOf(mDualToneHandler.getFillColor(darkIntensity)));
+ ColorStateList.valueOf(mDualToneHandler.getSingleColor(darkIntensity)));
ColorStateList color = ColorStateList.valueOf(getTint(area, this, tint));
mIn.setImageTintList(color);
mOut.setImageTintList(color);
@@ -238,7 +238,7 @@
// We want the ability to change the theme from the one set by SignalDrawable in certain
// surfaces. In this way, we can pass a theme to the view.
mMobileDrawable.setTintList(
- ColorStateList.valueOf(mDualToneHandler.getFillColor(intensity)));
+ ColorStateList.valueOf(mDualToneHandler.getSingleColor(intensity)));
mIn.setImageTintList(list);
mOut.setImageTintList(list);
mMobileType.setImageTintList(list);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index ce8463e..4d4818d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -433,7 +433,8 @@
public void onBiometricError(int msgId, String errString,
BiometricSourceType biometricSourceType) {
mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
- .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType)));
+ .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType))
+ .addTaggedData(MetricsEvent.FIELD_BIOMETRIC_AUTH_ERROR, msgId));
cleanup();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
index aba64bdf..f221865 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/EdgeBackGestureHandler.java
@@ -121,8 +121,8 @@
private final int mEdgeWidth;
// The slop to distinguish between horizontal and vertical motion
private final float mTouchSlop;
- // Minimum distance to move so that is can be considerd as a back swipe
- private final float mSwipeThreshold;
+ // Duration after which we consider the event as longpress.
+ private final int mLongPressTimeout;
// The threshold where the touch needs to be at most, such that the arrow is displayed above the
// finger, otherwise it will be below
private final int mMinArrowPosition;
@@ -164,8 +164,9 @@
// TODO: Get this for the current user
mEdgeWidth = res.getDimensionPixelSize(
com.android.internal.R.dimen.config_backGestureInset);
+
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
- mSwipeThreshold = res.getDimension(R.dimen.navigation_edge_action_drag_threshold);
+ mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
mNavBarHeight = res.getDimensionPixelSize(R.dimen.navigation_bar_frame_height);
mMinArrowPosition = res.getDimensionPixelSize(
@@ -308,8 +309,18 @@
return !isInExcludedRegion;
}
+ private void cancelGesture(MotionEvent ev) {
+ // Send action cancel to reset all the touch events
+ mAllowGesture = false;
+ MotionEvent cancelEv = MotionEvent.obtain(ev);
+ cancelEv.setAction(MotionEvent.ACTION_CANCEL);
+ mEdgePanel.handleTouch(cancelEv);
+ cancelEv.recycle();
+ }
+
private void onMotionEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ int action = ev.getActionMasked();
+ if (action == MotionEvent.ACTION_DOWN) {
// Verify if this is in within the touch region and we aren't in immersive mode, and
// either the bouncer is showing or the notification panel is hidden
int stateFlags = mOverviewProxyService.getSystemUiStateFlags();
@@ -330,29 +341,35 @@
mThresholdCrossed = false;
}
} else if (mAllowGesture) {
- if (!mThresholdCrossed && ev.getAction() == MotionEvent.ACTION_MOVE) {
- float dx = Math.abs(ev.getX() - mDownPoint.x);
- float dy = Math.abs(ev.getY() - mDownPoint.y);
- if (dy > dx && dy > mTouchSlop) {
- // Send action cancel to reset all the touch events
- mAllowGesture = false;
- MotionEvent cancelEv = MotionEvent.obtain(ev);
- cancelEv.setAction(MotionEvent.ACTION_CANCEL);
- mEdgePanel.handleTouch(cancelEv);
- cancelEv.recycle();
+ if (!mThresholdCrossed) {
+ if (action == MotionEvent.ACTION_POINTER_DOWN) {
+ // We do not support multi touch for back gesture
+ cancelGesture(ev);
return;
+ } else if (action == MotionEvent.ACTION_MOVE) {
+ if ((ev.getEventTime() - ev.getDownTime()) > mLongPressTimeout) {
+ cancelGesture(ev);
+ return;
+ }
+ float dx = Math.abs(ev.getX() - mDownPoint.x);
+ float dy = Math.abs(ev.getY() - mDownPoint.y);
+ if (dy > dx && dy > mTouchSlop) {
+ cancelGesture(ev);
+ return;
- } else if (dx > dy && dx > mTouchSlop) {
- mThresholdCrossed = true;
- // Capture inputs
- mInputMonitor.pilferPointers();
+ } else if (dx > dy && dx > mTouchSlop) {
+ mThresholdCrossed = true;
+ // Capture inputs
+ mInputMonitor.pilferPointers();
+ }
}
+
}
// forward touch
mEdgePanel.handleTouch(ev);
- boolean isUp = ev.getAction() == MotionEvent.ACTION_UP;
+ boolean isUp = action == MotionEvent.ACTION_UP;
if (isUp) {
boolean performAction = mEdgePanel.shouldTriggerBack();
if (performAction) {
@@ -363,7 +380,7 @@
mOverviewProxyService.notifyBackAction(performAction, (int) mDownPoint.x,
(int) mDownPoint.y, false /* isButton */, !mIsOnLeftEdge);
}
- if (isUp || ev.getAction() == MotionEvent.ACTION_CANCEL) {
+ if (isUp || action == MotionEvent.ACTION_CANCEL) {
mRegionSamplingHelper.stop();
} else {
updateSamplingRect();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index b8887c4..61a3940 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -95,6 +95,7 @@
private boolean mWasPulsingOnThisFrame;
private boolean mWakeAndUnlockRunning;
private boolean mKeyguardShowing;
+ private boolean mShowingLaunchAffordance;
private final KeyguardMonitor.Callback mKeyguardMonitorCallback =
new KeyguardMonitor.Callback() {
@@ -299,7 +300,8 @@
}
boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked);
- boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning;
+ boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning
+ || mShowingLaunchAffordance;
setVisibility(invisible ? INVISIBLE : VISIBLE);
updateClickability();
}
@@ -485,6 +487,14 @@
}
/**
+ * When we're launching an affordance, like double pressing power to open camera.
+ */
+ public void onShowingLaunchAffordanceChanged(boolean showing) {
+ mShowingLaunchAffordance = showing;
+ update();
+ }
+
+ /**
* Called whenever the scrims become opaque, transparent or semi-transparent.
*/
public void onScrimVisibilityChanged(@ScrimVisibility int scrimsVisible) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index 6e56854..36050ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -17,12 +17,15 @@
package com.android.systemui.statusbar.phone;
import static android.content.Intent.ACTION_OVERLAY_CHANGED;
+import static android.content.Intent.ACTION_PREFERRED_ACTIVITY_CHANGED;
import static android.os.UserHandle.USER_CURRENT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -56,7 +59,7 @@
public class NavigationModeController implements Dumpable {
private static final String TAG = NavigationModeController.class.getSimpleName();
- private static final boolean DEBUG = true;
+ private static final boolean DEBUG = false;
public interface ModeChangedListener {
void onNavigationModeChanged(int mode);
@@ -76,11 +79,19 @@
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(ACTION_OVERLAY_CHANGED)) {
- if (DEBUG) {
- Log.d(TAG, "ACTION_OVERLAY_CHANGED");
- }
- updateCurrentInteractionMode(true /* notify */);
+ switch (intent.getAction()) {
+ case ACTION_OVERLAY_CHANGED:
+ if (DEBUG) {
+ Log.d(TAG, "ACTION_OVERLAY_CHANGED");
+ }
+ updateCurrentInteractionMode(true /* notify */);
+ break;
+ case ACTION_PREFERRED_ACTIVITY_CHANGED:
+ if (DEBUG) {
+ Log.d(TAG, "ACTION_PREFERRED_ACTIVITY_CHANGED");
+ }
+ switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
+ break;
}
}
};
@@ -116,6 +127,7 @@
// Update the nav mode for the current user
updateCurrentInteractionMode(true /* notify */);
+ switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
// When switching users, defer enabling the gestural nav overlay until the user
// is all set up
@@ -140,7 +152,12 @@
overlayFilter.addDataSchemeSpecificPart("android", PatternMatcher.PATTERN_LITERAL);
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, overlayFilter, null, null);
+ IntentFilter preferredActivityFilter = new IntentFilter(ACTION_PREFERRED_ACTIVITY_CHANGED);
+ mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, preferredActivityFilter, null,
+ null);
+
updateCurrentInteractionMode(false /* notify */);
+ switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
// Check if we need to defer enabling gestural nav
deferGesturalNavOverlayIfNecessary();
@@ -175,6 +192,10 @@
private int getCurrentInteractionMode(Context context) {
int mode = context.getResources().getInteger(
com.android.internal.R.integer.config_navBarInteractionMode);
+ if (DEBUG) {
+ Log.d(TAG, "getCurrentInteractionMode: mode=" + mMode
+ + " contextUser=" + context.getUserId());
+ }
return mode;
}
@@ -250,6 +271,10 @@
mUiOffloadThread.submit(() -> {
try {
mOverlayManager.setEnabledExclusiveInCategory(overlayPkg, userId);
+ if (DEBUG) {
+ Log.d(TAG, "setModeOverlay: overlayPackage=" + overlayPkg
+ + " userId=" + userId);
+ }
} catch (RemoteException e) {
Log.e(TAG, "Failed to enable overlay " + overlayPkg + " for user " + userId);
}
@@ -277,4 +302,27 @@
Log.d(TAG, " " + a.getAssetPath());
}
}
+
+ private void switchFromGestureNavModeIfNotSupportedByDefaultLauncher() {
+ if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL
+ && !isGestureNavSupportedByDefaultLauncher(mCurrentUserContext)) {
+ setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
+ }
+ }
+
+ private boolean isGestureNavSupportedByDefaultLauncher(Context context) {
+ final ComponentName cn = context.getPackageManager().getHomeActivities(new ArrayList<>());
+ if (cn == null) {
+ // There is no default home app set for the current user, don't make any changes yet.
+ return true;
+ }
+ if (DEBUG) {
+ Log.d(TAG, "isGestureNavSupportedByDefaultLauncher: launcher=" + cn.getPackageName()
+ + " contextUser=" + context.getUserId());
+ }
+
+ ComponentName recentsComponentName = ComponentName.unflattenFromString(context.getString(
+ com.android.internal.R.string.config_recentsComponentName));
+ return recentsComponentName.getPackageName().equals(cn.getPackageName());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 3fe7f36..9da75b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -151,7 +151,8 @@
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
private final PulseExpansionHandler mPulseExpansionHandler;
- private KeyguardAffordanceHelper mAffordanceHelper;
+ @VisibleForTesting
+ protected KeyguardAffordanceHelper mAffordanceHelper;
private KeyguardUserSwitcher mKeyguardUserSwitcher;
@VisibleForTesting
protected KeyguardStatusBarView mKeyguardStatusBar;
@@ -340,6 +341,7 @@
*/
private int mThemeResId;
private KeyguardIndicationController mKeyguardIndicationController;
+ private Consumer<Boolean> mAffordanceLaunchListener;
@Inject
public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
@@ -447,6 +449,14 @@
R.dimen.qs_notification_padding);
}
+ /**
+ * @see #launchCamera(boolean, int)
+ * @see #setLaunchingAffordance(boolean)
+ */
+ public void setLaunchAffordanceListener(Consumer<Boolean> listener) {
+ mAffordanceLaunchListener = listener;
+ }
+
public void updateResources() {
Resources res = getResources();
int qsWidth = res.getDimensionPixelSize(R.dimen.qs_panel_width);
@@ -2743,6 +2753,9 @@
private void setLaunchingAffordance(boolean launchingAffordance) {
getLeftIcon().setLaunchingAffordance(launchingAffordance);
getRightIcon().setLaunchingAffordance(launchingAffordance);
+ if (mAffordanceLaunchListener != null) {
+ mAffordanceLaunchListener.accept(launchingAffordance);
+ }
}
/**
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 72726b3..4e8f584 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -951,6 +951,9 @@
createUserSwitcher();
}
+ mNotificationPanel.setLaunchAffordanceListener(
+ mStatusBarWindow::onShowingLaunchAffordanceChanged);
+
// Set up the quick settings tile panel
View container = mStatusBarWindow.findViewById(R.id.qs_frame);
if (container != null) {
@@ -3636,6 +3639,7 @@
@Override
public void onStartedGoingToSleep() {
+ updateNotificationPanelTouchState();
notifyHeadsUpGoingToSleep();
dismissVolumeDialog();
}
@@ -3668,7 +3672,10 @@
* Keyguard.
*/
private void updateNotificationPanelTouchState() {
- mNotificationPanel.setTouchAndAnimationDisabled(!mDeviceInteractive && !mPulsing);
+ boolean goingToSleepWithoutAnimation = isGoingToSleep()
+ && !DozeParameters.getInstance(mContext).shouldControlScreenOff();
+ mNotificationPanel.setTouchAndAnimationDisabled((!mDeviceInteractive && !mPulsing)
+ || goingToSleepWithoutAnimation);
}
final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
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 049972e..7d5f23b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -510,6 +510,15 @@
}
}
+ /**
+ * When we're launching an affordance, like double pressing power to open camera.
+ */
+ public void onShowingLaunchAffordanceChanged(boolean showing) {
+ if (mLockIcon != null) {
+ mLockIcon.onShowingLaunchAffordanceChanged(showing);
+ }
+ }
+
public class LayoutParams extends FrameLayout.LayoutParams {
public boolean ignoreRightInset;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index 22006db..d061649 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -378,8 +378,18 @@
public int visibleState = STATE_ICON;
public boolean justAdded = true;
+ // How far we are from the end of the view actually is the most relevant for animation
+ float distanceToViewEnd = -1;
+
@Override
public void applyToView(View view) {
+ float parentWidth = 0;
+ if (view.getParent() instanceof View) {
+ parentWidth = ((View) view.getParent()).getWidth();
+ }
+
+ float currentDistanceToEnd = parentWidth - xTranslation;
+
if (!(view instanceof StatusIconDisplayable)) {
return;
}
@@ -403,7 +413,7 @@
// all other transitions (to/from dot, etc)
animationProperties = ANIMATE_ALL_PROPERTIES;
}
- } else if (visibleState != STATE_HIDDEN && xTranslation != view.getTranslationX()) {
+ } else if (visibleState != STATE_HIDDEN && distanceToViewEnd != currentDistanceToEnd) {
// Visibility isn't changing, just animate position
animationProperties = X_ANIMATION_PROPERTIES;
}
@@ -416,6 +426,8 @@
}
justAdded = false;
+ distanceToViewEnd = currentDistanceToEnd;
+
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
index a1c5707..74b15fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/ExpandedAnimationControllerTest.java
@@ -145,6 +145,7 @@
}
@Test
+ @Ignore("Flaky")
public void testMagnetToDismiss_dismiss() throws InterruptedException {
expand();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
index 9b894c3..9218a8b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/animation/StackAnimationControllerTest.java
@@ -234,6 +234,7 @@
}
@Test
+ @Ignore("Flaky")
public void testMagnetToDismiss_dismiss() throws InterruptedException {
final Runnable after = Mockito.mock(Runnable.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 2f9d892..1b7ca95 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -21,9 +21,11 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.StatusBarManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.MotionEvent;
@@ -36,6 +38,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.PulseExpansionHandler;
@@ -55,6 +58,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.function.Consumer;
+
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -90,6 +95,8 @@
private HeadsUpTouchHelper.Callback mHeadsUpCallback;
@Mock
private PanelBar mPanelBar;
+ @Mock
+ private KeyguardAffordanceHelper mAffordanceHelper;
private NotificationPanelView mNotificationPanelView;
@Before
@@ -112,6 +119,9 @@
mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler);
mNotificationPanelView.setHeadsUpManager(mHeadsUpManager);
mNotificationPanelView.setBar(mPanelBar);
+
+ when(mKeyguardBottomArea.getLeftView()).thenReturn(mock(KeyguardAffordanceView.class));
+ when(mKeyguardBottomArea.getRightView()).thenReturn(mock(KeyguardAffordanceView.class));
}
@Test
@@ -129,6 +139,19 @@
}
@Test
+ public void testAffordanceLaunchingListener() {
+ Consumer<Boolean> listener = spy((showing) -> { });
+ mNotificationPanelView.setExpandedFraction(1f);
+ mNotificationPanelView.setLaunchAffordanceListener(listener);
+ mNotificationPanelView.launchCamera(false /* animate */,
+ StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP);
+ verify(listener).accept(eq(true));
+
+ mNotificationPanelView.onAffordanceLaunchEnded();
+ verify(listener).accept(eq(false));
+ }
+
+ @Test
public void testOnTouchEvent_expansionCanBeBlocked() {
mNotificationPanelView.onTouchEvent(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, MotionEvent.ACTION_DOWN, 0f /* x */, 0f /* y */,
@@ -166,6 +189,7 @@
mKeyguardBottomArea = NotificationPanelViewTest.this.mKeyguardBottomArea;
mBigClockContainer = NotificationPanelViewTest.this.mBigClockContainer;
mQsFrame = NotificationPanelViewTest.this.mQsFrame;
+ mAffordanceHelper = NotificationPanelViewTest.this.mAffordanceHelper;
initDependencies(NotificationPanelViewTest.this.mStatusBar,
NotificationPanelViewTest.this.mGroupManager,
NotificationPanelViewTest.this.mNotificationShelf,
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 2616466..71d03a8 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7371,6 +7371,11 @@
// Note: Only shows up on first time toggle
DIALOG_DARK_UI_INFO = 1740;
+ // FIELD - Detailed reason in biometric authentication error.
+ // One of the constant value in BiometricConstants.java file.
+ // OS: Q
+ FIELD_BIOMETRIC_AUTH_ERROR = 1741;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index d2b71e5..d42943c 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -225,17 +225,7 @@
@Override
public void cancel() {
- synchronized (mLock) {
- final boolean cancelled = isCancelledLocked();
- final ICancellationSignal cancellation = mCancellation;
- if (!cancelled) {
- try {
- cancellation.cancel();
- } catch (RemoteException e) {
- Slog.e(mTag, "Error requesting a cancellation", e);
- }
- }
- }
+ PendingAutofillRequest.this.cancel();
}
};
}
@@ -304,7 +294,7 @@
try {
cancellation.cancel();
} catch (RemoteException e) {
- Slog.e(mTag, "Error cancelling a fill request", e);
+ Slog.e(mTag, "Error cancelling an augmented fill request", e);
}
}
return true;
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 9e1b3b8..9855e4e 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -51,8 +51,8 @@
"android.hardware.configstore-V1.0-java",
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
- "dnsresolver_aidl_interface-java",
- "netd_aidl_interface-java",
+ "dnsresolver_aidl_interface-V2-java",
+ "netd_aidl_interface-V2-java",
"netd_event_listener_interface-java",
],
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 0da39e7..104cadc 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -120,7 +120,7 @@
/**
* Default value for mFlagBackgroundActivityStartsEnabled if not explicitly set in
* Settings.Global. This allows it to be set experimentally unless it has been
- * enabled/disabled in developer options. Defaults to true.
+ * enabled/disabled in developer options. Defaults to false.
*/
private static final String KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED =
"default_background_activity_starts_enabled";
@@ -497,7 +497,7 @@
boolean enabledInDeviceConfig = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_DEFAULT_BACKGROUND_ACTIVITY_STARTS_ENABLED,
- /*defaultValue*/ true);
+ /*defaultValue*/ false);
mFlagBackgroundActivityStartsEnabled = enabledInDeviceConfig;
if (!enabledInDeviceConfig) {
whitelistedPackageNames = DeviceConfig.getProperty(
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index d8b7c2e..fa8c48b 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -1170,7 +1170,7 @@
}
private void removeSyncsForAuthority(EndPoint info, String why) {
- mLogger.log("removeSyncsForAuthority: ", info);
+ mLogger.log("removeSyncsForAuthority: ", info, why);
verifyJobScheduler();
List<SyncOperation> ops = getAllPendingSyncs();
for (SyncOperation op: ops) {
diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java
index c7a3f4b..e09c661 100644
--- a/services/core/java/com/android/server/content/SyncStorageEngine.java
+++ b/services/core/java/com/android/server/content/SyncStorageEngine.java
@@ -1027,7 +1027,7 @@
* Called when the set of account has changed, given the new array of
* active accounts.
*/
- public void removeStaleAccounts(@Nullable Account[] accounts, int userId) {
+ public void removeStaleAccounts(@Nullable Account[] currentAccounts, int userId) {
synchronized (mAuthorities) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Slog.v(TAG, "Updating for new accounts...");
@@ -1036,9 +1036,11 @@
Iterator<AccountInfo> accIt = mAccounts.values().iterator();
while (accIt.hasNext()) {
AccountInfo acc = accIt.next();
- if ((accounts == null) || (
- (acc.accountAndUser.userId == userId)
- && !ArrayUtils.contains(accounts, acc.accountAndUser.account))) {
+ if (acc.accountAndUser.userId != userId) {
+ continue; // Irrelevant user.
+ }
+ if ((currentAccounts == null)
+ || !ArrayUtils.contains(currentAccounts, acc.accountAndUser.account)) {
// This account no longer exists...
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Slog.v(TAG, "Account removed: " + acc.accountAndUser);
diff --git a/services/core/java/com/android/server/location/GnssVisibilityControl.java b/services/core/java/com/android/server/location/GnssVisibilityControl.java
index b7e0a0f..8d4ad7f 100644
--- a/services/core/java/com/android/server/location/GnssVisibilityControl.java
+++ b/services/core/java/com/android/server/location/GnssVisibilityControl.java
@@ -16,6 +16,7 @@
package com.android.server.location;
+import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.AppOpsManager;
import android.app.Notification;
@@ -27,6 +28,7 @@
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.location.LocationManager;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
@@ -62,6 +64,9 @@
// Max wait time for synchronous method onGpsEnabledChanged() to run.
private static final long ON_GPS_ENABLED_CHANGED_TIMEOUT_MILLIS = 3 * 1000;
+ // How long to display location icon for each non-framework non-emergency location request.
+ private static final long LOCATION_ICON_DISPLAY_DURATION_MILLIS = 5 * 1000;
+
// Wakelocks
private static final String WAKELOCK_KEY = TAG;
private static final long WAKELOCK_TIMEOUT_MILLIS = 60 * 1000;
@@ -77,10 +82,19 @@
private boolean mIsGpsEnabled;
+ private static final class ProxyAppState {
+ private boolean mHasLocationPermission;
+ private boolean mIsLocationIconOn;
+
+ private ProxyAppState(boolean hasLocationPermission) {
+ mHasLocationPermission = hasLocationPermission;
+ }
+ }
+
// Number of non-framework location access proxy apps is expected to be small (< 5).
- private static final int ARRAY_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS = 7;
- private ArrayMap<String, Boolean> mProxyAppToLocationPermissions = new ArrayMap<>(
- ARRAY_MAP_INITIAL_CAPACITY_PROXY_APP_TO_LOCATION_PERMISSIONS);
+ private static final int ARRAY_MAP_INITIAL_CAPACITY_PROXY_APPS_STATE = 5;
+ private ArrayMap<String, ProxyAppState> mProxyAppsState = new ArrayMap<>(
+ ARRAY_MAP_INITIAL_CAPACITY_PROXY_APPS_STATE);
private PackageManager.OnPermissionsChangedListener mOnPermissionsChangedListener =
uid -> runOnHandler(() -> handlePermissionsChanged(uid));
@@ -173,18 +187,18 @@
}
private void handleProxyAppPackageUpdate(String pkgName, String action) {
- final Boolean locationPermission = mProxyAppToLocationPermissions.get(pkgName);
- if (locationPermission == null) {
+ final ProxyAppState proxyAppState = mProxyAppsState.get(pkgName);
+ if (proxyAppState == null) {
return; // ignore, pkgName is not one of the proxy apps in our list.
}
if (DEBUG) Log.d(TAG, "Proxy app " + pkgName + " package changed: " + action);
final boolean updatedLocationPermission = shouldEnableLocationPermissionInGnssHal(pkgName);
- if (locationPermission != updatedLocationPermission) {
+ if (proxyAppState.mHasLocationPermission != updatedLocationPermission) {
// Permission changed. So, update the GNSS HAL with the updated list.
Log.i(TAG, "Proxy app " + pkgName + " location permission changed."
+ " IsLocationPermissionEnabled: " + updatedLocationPermission);
- mProxyAppToLocationPermissions.put(pkgName, updatedLocationPermission);
+ proxyAppState.mHasLocationPermission = updatedLocationPermission;
updateNfwLocationAccessProxyAppsInGnssHal();
}
}
@@ -196,35 +210,53 @@
if (nfwLocationAccessProxyApps.isEmpty()) {
// Stop listening for app permission changes. Clear the app list in GNSS HAL.
- if (!mProxyAppToLocationPermissions.isEmpty()) {
+ if (!mProxyAppsState.isEmpty()) {
mPackageManager.removeOnPermissionsChangeListener(mOnPermissionsChangedListener);
- mProxyAppToLocationPermissions.clear();
+ resetProxyAppsState();
updateNfwLocationAccessProxyAppsInGnssHal();
}
return;
}
- if (mProxyAppToLocationPermissions.isEmpty()) {
+ if (mProxyAppsState.isEmpty()) {
mPackageManager.addOnPermissionsChangeListener(mOnPermissionsChangedListener);
} else {
- mProxyAppToLocationPermissions.clear();
+ resetProxyAppsState();
}
for (String proxyAppPkgName : nfwLocationAccessProxyApps) {
- mProxyAppToLocationPermissions.put(proxyAppPkgName,
- shouldEnableLocationPermissionInGnssHal(proxyAppPkgName));
+ ProxyAppState proxyAppState = new ProxyAppState(shouldEnableLocationPermissionInGnssHal(
+ proxyAppPkgName));
+ mProxyAppsState.put(proxyAppPkgName, proxyAppState);
}
updateNfwLocationAccessProxyAppsInGnssHal();
}
+ private void resetProxyAppsState() {
+ // Clear location icons displayed.
+ for (Map.Entry<String, ProxyAppState> entry : mProxyAppsState.entrySet()) {
+ ProxyAppState proxyAppState = entry.getValue();
+ if (!proxyAppState.mIsLocationIconOn) {
+ continue;
+ }
+
+ mHandler.removeCallbacksAndMessages(proxyAppState);
+ final ApplicationInfo proxyAppInfo = getProxyAppInfo(entry.getKey());
+ if (proxyAppInfo != null) {
+ clearLocationIcon(proxyAppState, proxyAppInfo.uid, entry.getKey());
+ }
+ }
+ mProxyAppsState.clear();
+ }
+
private boolean isProxyAppListUpdated(List<String> nfwLocationAccessProxyApps) {
- if (nfwLocationAccessProxyApps.size() != mProxyAppToLocationPermissions.size()) {
+ if (nfwLocationAccessProxyApps.size() != mProxyAppsState.size()) {
return true;
}
for (String nfwLocationAccessProxyApp : nfwLocationAccessProxyApps) {
- if (!mProxyAppToLocationPermissions.containsKey(nfwLocationAccessProxyApp)) {
+ if (!mProxyAppsState.containsKey(nfwLocationAccessProxyApp)) {
return true;
}
}
@@ -326,11 +358,11 @@
}
private void handlePermissionsChanged(int uid) {
- if (mProxyAppToLocationPermissions.isEmpty()) {
+ if (mProxyAppsState.isEmpty()) {
return;
}
- for (Map.Entry<String, Boolean> entry : mProxyAppToLocationPermissions.entrySet()) {
+ for (Map.Entry<String, ProxyAppState> entry : mProxyAppsState.entrySet()) {
final String proxyAppPkgName = entry.getKey();
final ApplicationInfo proxyAppInfo = getProxyAppInfo(proxyAppPkgName);
if (proxyAppInfo == null || proxyAppInfo.uid != uid) {
@@ -339,10 +371,11 @@
final boolean isLocationPermissionEnabled = shouldEnableLocationPermissionInGnssHal(
proxyAppPkgName);
- if (isLocationPermissionEnabled != entry.getValue()) {
+ ProxyAppState proxyAppState = entry.getValue();
+ if (isLocationPermissionEnabled != proxyAppState.mHasLocationPermission) {
Log.i(TAG, "Proxy app " + proxyAppPkgName + " location permission changed."
+ " IsLocationPermissionEnabled: " + isLocationPermissionEnabled);
- entry.setValue(isLocationPermissionEnabled);
+ proxyAppState.mHasLocationPermission = isLocationPermissionEnabled;
updateNfwLocationAccessProxyAppsInGnssHal();
}
return;
@@ -394,8 +427,8 @@
private String[] getLocationPermissionEnabledProxyApps() {
// Get a count of proxy apps with location permission enabled for array creation size.
int countLocationPermissionEnabledProxyApps = 0;
- for (Boolean hasLocationPermissionEnabled : mProxyAppToLocationPermissions.values()) {
- if (hasLocationPermissionEnabled) {
+ for (ProxyAppState proxyAppState : mProxyAppsState.values()) {
+ if (proxyAppState.mHasLocationPermission) {
++countLocationPermissionEnabledProxyApps;
}
}
@@ -403,10 +436,9 @@
int i = 0;
String[] locationPermissionEnabledProxyApps =
new String[countLocationPermissionEnabledProxyApps];
- for (Map.Entry<String, Boolean> entry : mProxyAppToLocationPermissions.entrySet()) {
+ for (Map.Entry<String, ProxyAppState> entry : mProxyAppsState.entrySet()) {
final String proxyApp = entry.getKey();
- final boolean hasLocationPermissionEnabled = entry.getValue();
- if (hasLocationPermissionEnabled) {
+ if (entry.getValue().mHasLocationPermission) {
locationPermissionEnabledProxyApps[i++] = proxyApp;
}
}
@@ -422,12 +454,11 @@
}
final String proxyAppPkgName = nfwNotification.mProxyAppPackageName;
- final Boolean isLocationPermissionEnabled = mProxyAppToLocationPermissions.get(
- proxyAppPkgName);
+ final ProxyAppState proxyAppState = mProxyAppsState.get(proxyAppPkgName);
final boolean isLocationRequestAccepted = nfwNotification.isRequestAccepted();
final boolean isPermissionMismatched =
- (isLocationPermissionEnabled == null) ? isLocationRequestAccepted
- : (isLocationPermissionEnabled != isLocationRequestAccepted);
+ (proxyAppState == null) ? isLocationRequestAccepted
+ : (proxyAppState.mHasLocationPermission != isLocationRequestAccepted);
logEvent(nfwNotification, isPermissionMismatched);
if (!nfwNotification.isRequestAttributedToProxyApp()) {
@@ -442,7 +473,7 @@
if (DEBUG) {
Log.d(TAG, "Non-framework location request rejected. ProxyAppPackageName field"
+ " is not set in the notification: " + nfwNotification + ". Number of"
- + " configured proxy apps: " + mProxyAppToLocationPermissions.size());
+ + " configured proxy apps: " + mProxyAppsState.size());
}
return;
}
@@ -452,7 +483,7 @@
return;
}
- if (isLocationPermissionEnabled == null) {
+ if (proxyAppState == null) {
Log.w(TAG, "Could not find proxy app " + proxyAppPkgName + " in the value specified for"
+ " config parameter: " + GnssConfiguration.CONFIG_NFW_PROXY_APPS
+ ". AppOps service not notified for notification: " + nfwNotification);
@@ -467,18 +498,99 @@
return;
}
- mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, proxyAppInfo.uid, proxyAppPkgName);
+ if (nfwNotification.isLocationProvided()) {
+ showLocationIcon(proxyAppState, nfwNotification, proxyAppInfo.uid, proxyAppPkgName);
+ mAppOps.noteOpNoThrow(AppOpsManager.OP_FINE_LOCATION, proxyAppInfo.uid,
+ proxyAppPkgName);
+ }
// Log proxy app permission mismatch between framework and GNSS HAL.
if (isPermissionMismatched) {
Log.w(TAG, "Permission mismatch. Framework proxy app " + proxyAppPkgName
- + " location permission is set to " + isLocationPermissionEnabled
+ + " location permission is set to " + proxyAppState.mHasLocationPermission
+ " but GNSS non-framework location access response type is "
+ nfwNotification.getResponseTypeAsString() + " for notification: "
+ nfwNotification);
}
}
+ private void showLocationIcon(ProxyAppState proxyAppState, NfwNotification nfwNotification,
+ int uid, String proxyAppPkgName) {
+ // If we receive a new NfwNotification before the location icon is turned off for the
+ // previous notification, update the timer to extend the location icon display duration.
+ final boolean isLocationIconOn = proxyAppState.mIsLocationIconOn;
+ if (!isLocationIconOn) {
+ if (!updateLocationIcon(/* displayLocationIcon = */ true, uid, proxyAppPkgName)) {
+ Log.w(TAG, "Failed to show Location icon for notification: " + nfwNotification);
+ return;
+ }
+ proxyAppState.mIsLocationIconOn = true;
+ } else {
+ // Extend timer by canceling the current one and starting a new one.
+ mHandler.removeCallbacksAndMessages(proxyAppState);
+ }
+
+ // Start timer to turn off location icon. proxyAppState is used as a token to cancel timer.
+ if (DEBUG) {
+ Log.d(TAG, "Location icon on. " + (isLocationIconOn ? "Extending" : "Setting")
+ + " icon display timer. Uid: " + uid + ", proxyAppPkgName: " + proxyAppPkgName);
+ }
+ if (!mHandler.postDelayed(() -> handleLocationIconTimeout(proxyAppPkgName),
+ /* token = */ proxyAppState, LOCATION_ICON_DISPLAY_DURATION_MILLIS)) {
+ clearLocationIcon(proxyAppState, uid, proxyAppPkgName);
+ Log.w(TAG, "Failed to show location icon for the full duration for notification: "
+ + nfwNotification);
+ }
+ }
+
+ private void handleLocationIconTimeout(String proxyAppPkgName) {
+ // Get uid again instead of using the one provided in startOp() call as the app could have
+ // been uninstalled and reinstalled during the timeout duration (unlikely in real world).
+ final ApplicationInfo proxyAppInfo = getProxyAppInfo(proxyAppPkgName);
+ if (proxyAppInfo != null) {
+ clearLocationIcon(mProxyAppsState.get(proxyAppPkgName), proxyAppInfo.uid,
+ proxyAppPkgName);
+ }
+ }
+
+ private void clearLocationIcon(@Nullable ProxyAppState proxyAppState, int uid,
+ String proxyAppPkgName) {
+ updateLocationIcon(/* displayLocationIcon = */ false, uid, proxyAppPkgName);
+ if (proxyAppState != null) proxyAppState.mIsLocationIconOn = false;
+ if (DEBUG) {
+ Log.d(TAG, "Location icon off. Uid: " + uid + ", proxyAppPkgName: " + proxyAppPkgName);
+ }
+ }
+
+ private boolean updateLocationIcon(boolean displayLocationIcon, int uid,
+ String proxyAppPkgName) {
+ if (displayLocationIcon) {
+ // Need two calls to startOp() here with different op code so that the proxy app shows
+ // up in the recent location requests page and also the location icon gets displayed.
+ if (mAppOps.startOpNoThrow(AppOpsManager.OP_MONITOR_LOCATION, uid,
+ proxyAppPkgName) != AppOpsManager.MODE_ALLOWED) {
+ return false;
+ }
+ if (mAppOps.startOpNoThrow(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, uid,
+ proxyAppPkgName) != AppOpsManager.MODE_ALLOWED) {
+ mAppOps.finishOp(AppOpsManager.OP_MONITOR_LOCATION, uid, proxyAppPkgName);
+ return false;
+ }
+ } else {
+ mAppOps.finishOp(AppOpsManager.OP_MONITOR_LOCATION, uid, proxyAppPkgName);
+ mAppOps.finishOp(AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, uid, proxyAppPkgName);
+ }
+ sendHighPowerMonitoringBroadcast();
+ return true;
+ }
+
+ private void sendHighPowerMonitoringBroadcast() {
+ // Send an intent to notify that a high power request has been added/removed so that
+ // the SystemUi checks the state of AppOps and updates the location icon accordingly.
+ Intent intent = new Intent(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION);
+ mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ }
+
private void handleEmergencyNfwNotification(NfwNotification nfwNotification) {
boolean isPermissionMismatched = false;
if (!nfwNotification.isRequestAccepted()) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 46d6886..8c58247 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -46,6 +46,7 @@
import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
+import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.MATCH_ALL;
@@ -82,6 +83,9 @@
import static android.service.notification.NotificationListenerService.REASON_USER_STOPPED;
import static android.service.notification.NotificationListenerService.TRIM_FULL;
import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
+import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING;
+import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE;
+import static android.util.StatsLogInternal.BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
@@ -131,6 +135,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -197,6 +202,7 @@
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.StatsLog;
import android.util.Xml;
import android.util.proto.ProtoOutputStream;
import android.view.accessibility.AccessibilityEvent;
@@ -4821,9 +4827,12 @@
private boolean isNotificationAppropriateToBubble(NotificationRecord r, String pkg, int userId,
NotificationRecord oldRecord) {
Notification notification = r.getNotification();
+ Notification.BubbleMetadata metadata = notification.getBubbleMetadata();
+ boolean intentCanBubble = metadata != null
+ && canLaunchInActivityView(getContext(), metadata.getIntent(), pkg);
// Does the app want to bubble & is able to bubble
- boolean canBubble = notification.getBubbleMetadata() != null
+ boolean canBubble = intentCanBubble
&& mPreferencesHelper.areBubblesAllowed(pkg, userId)
&& mPreferencesHelper.bubblesEnabled(r.sbn.getUser())
&& r.getChannel().canBubble()
@@ -4869,6 +4878,63 @@
return false;
}
+ /**
+ * Whether an intent is properly configured to display in an {@link android.app.ActivityView}.
+ *
+ * @param context the context to use.
+ * @param pendingIntent the pending intent of the bubble.
+ * @param packageName the notification package name for this bubble.
+ */
+ // Keep checks in sync with BubbleController#canLaunchInActivityView.
+ @VisibleForTesting
+ protected boolean canLaunchInActivityView(Context context, PendingIntent pendingIntent,
+ String packageName) {
+ if (pendingIntent == null) {
+ Log.w(TAG, "Unable to create bubble -- no intent");
+ return false;
+ }
+
+ // Need escalated privileges to get the intent.
+ final long token = Binder.clearCallingIdentity();
+ Intent intent;
+ try {
+ intent = pendingIntent.getIntent();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+
+ ActivityInfo info = intent != null
+ ? intent.resolveActivityInfo(context.getPackageManager(), 0)
+ : null;
+ if (info == null) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_MISSING);
+ Log.w(TAG, "Unable to send as bubble -- couldn't find activity info for intent: "
+ + intent);
+ return false;
+ }
+ if (!ActivityInfo.isResizeableMode(info.resizeMode)) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__ACTIVITY_INFO_NOT_RESIZABLE);
+ Log.w(TAG, "Unable to send as bubble -- activity is not resizable for intent: "
+ + intent);
+ return false;
+ }
+ if (info.documentLaunchMode != DOCUMENT_LAUNCH_ALWAYS) {
+ StatsLog.write(StatsLog.BUBBLE_DEVELOPER_ERROR_REPORTED, packageName,
+ BUBBLE_DEVELOPER_ERROR_REPORTED__ERROR__DOCUMENT_LAUNCH_NOT_ALWAYS);
+ Log.w(TAG, "Unable to send as bubble -- activity is not documentLaunchMode=always "
+ + "for intent: " + intent);
+ return false;
+ }
+ if ((info.flags & ActivityInfo.FLAG_ALLOW_EMBEDDED) == 0) {
+ Log.w(TAG, "Unable to send as bubble -- activity is not embeddable for intent: "
+ + intent);
+ return false;
+ }
+ return true;
+ }
+
private void doChannelWarningToast(CharSequence toastText) {
Binder.withCleanCallingIdentity(() -> {
final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0;
diff --git a/services/core/java/com/android/server/pm/ModuleInfoProvider.java b/services/core/java/com/android/server/pm/ModuleInfoProvider.java
index 6499530..69510d9 100644
--- a/services/core/java/com/android/server/pm/ModuleInfoProvider.java
+++ b/services/core/java/com/android/server/pm/ModuleInfoProvider.java
@@ -64,6 +64,7 @@
// TODO: Move this to an earlier boot phase if anybody requires it then.
private volatile boolean mMetadataLoaded;
+ private volatile String mPackageName;
ModuleInfoProvider(Context context, IPackageManager packageManager) {
mContext = context;
@@ -81,9 +82,9 @@
/** Called by the {@code PackageManager} when it has completed its boot sequence */
public void systemReady() {
- final String packageName = mContext.getResources().getString(
+ mPackageName = mContext.getResources().getString(
R.string.config_defaultModuleMetadataProvider);
- if (TextUtils.isEmpty(packageName)) {
+ if (TextUtils.isEmpty(mPackageName)) {
Slog.w(TAG, "No configured module metadata provider.");
return;
}
@@ -91,13 +92,13 @@
final Resources packageResources;
final PackageInfo pi;
try {
- pi = mPackageManager.getPackageInfo(packageName,
+ pi = mPackageManager.getPackageInfo(mPackageName,
PackageManager.GET_META_DATA, UserHandle.USER_SYSTEM);
- Context packageContext = mContext.createPackageContext(packageName, 0);
+ Context packageContext = mContext.createPackageContext(mPackageName, 0);
packageResources = packageContext.getResources();
} catch (RemoteException | NameNotFoundException e) {
- Slog.w(TAG, "Unable to discover metadata package: " + packageName, e);
+ Slog.w(TAG, "Unable to discover metadata package: " + mPackageName, e);
return;
}
@@ -201,4 +202,11 @@
return mModuleInfo.get(packageName);
}
+
+ String getPackageName() {
+ if (!mMetadataLoaded) {
+ throw new IllegalStateException("Call to getVersion before metadata loaded");
+ }
+ return mPackageName;
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e07a132..e86f56f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5646,9 +5646,11 @@
private int checkUidPermissionImpl(String permName, int uid) {
synchronized (mPackages) {
final String[] packageNames = getPackagesForUid(uid);
- final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0)
- ? mPackages.get(packageNames[0])
- : null;
+ PackageParser.Package pkg = null;
+ final int N = packageNames == null ? 0 : packageNames.length;
+ for (int i = 0; pkg == null && i < N; i++) {
+ pkg = mPackages.get(packageNames[i]);
+ }
// Additional logs for b/111075456; ignore system UIDs
if (pkg == null && UserHandle.getAppId(uid) >= Process.FIRST_APPLICATION_UID) {
if (packageNames == null || packageNames.length < 2) {
@@ -6385,6 +6387,16 @@
}
}
+ /**
+ * <em>IMPORTANT:</em> Not all packages returned by this method may be known
+ * to the system. There are two conditions in which this may occur:
+ * <ol>
+ * <li>The package is on adoptable storage and the device has been removed</li>
+ * <li>The package is being removed and the internal structures are partially updated</li>
+ * </ol>
+ * The second is an artifact of the current data structures and should be fixed. See
+ * b/111075456 for one such instance.
+ */
@Override
public String[] getPackagesForUid(int uid) {
return getPackagesForUid_debug(uid, false);
@@ -24074,6 +24086,11 @@
| (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
| (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
}
+
+ @Override
+ public String getModuleMetadataPackageName() throws RemoteException {
+ return PackageManagerService.this.mModuleInfoProvider.getPackageName();
+ }
}
private class PackageManagerInternalImpl extends PackageManagerInternal {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 2b7691b8..2a1aee8 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1347,6 +1347,7 @@
updatedUserIds);
updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
permissionsState, pkg, newImplicitPermissions, updatedUserIds);
+ updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
}
// Persist the runtime permissions state for users with changes. If permissions
@@ -1473,6 +1474,28 @@
}
/**
+ * When the app has requested legacy storage we might need to update
+ * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
+ * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
+ *
+ * @param pkg The package for which the permissions are updated
+ * @param replace If the app is being replaced
+ * @param updatedUserIds The ids of the users that already changed.
+ *
+ * @return The ids of the users that are changed
+ */
+ private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
+ @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) {
+ if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && (
+ pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE)
+ || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) {
+ return UserManagerService.getInstance().getUserIds();
+ }
+
+ return updatedUserIds;
+ }
+
+ /**
* Set the state of a implicit permission that is seen for the first time.
*
* @param origPs The permission state of the package before the split
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyInternal.java b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
index ea8616c..7760c1e 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyInternal.java
@@ -17,6 +17,7 @@
package com.android.server.policy;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Intent;
/**
@@ -34,5 +35,5 @@
* @return whether the activity should be started
*/
public abstract boolean checkStartActivity(@NonNull Intent intent, int callingUid,
- @NonNull String callingPackage);
+ @Nullable String callingPackage);
}
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 570a153..02911e2 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -229,6 +229,15 @@
*
* @see #syncRestrictedOps
*/
+ private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllowIfDefault = new ArrayList<>();
+
+ /**
+ * All ops that need to be flipped to allow.
+ *
+ * Currently, only used by the restricted permissions logic.
+ *
+ * @see #syncRestrictedOps
+ */
private final @NonNull ArrayList<OpToUnrestrict> mOpsToAllow = new ArrayList<>();
/**
@@ -238,7 +247,7 @@
*
* @see #syncRestrictedOps
*/
- private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnore = new ArrayList<>();
+ private final @NonNull ArrayList<OpToUnrestrict> mOpsToIgnoreIfDefault = new ArrayList<>();
/**
* All foreground permissions
@@ -262,11 +271,16 @@
final int allowCount = mOpsToAllow.size();
for (int i = 0; i < allowCount; i++) {
final OpToUnrestrict op = mOpsToAllow.get(i);
+ setUidModeAllowed(op.code, op.uid);
+ }
+ final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
+ for (int i = 0; i < allowIfDefaultCount; i++) {
+ final OpToUnrestrict op = mOpsToAllowIfDefault.get(i);
setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
}
- final int ignoreCount = mOpsToIgnore.size();
- for (int i = 0; i < ignoreCount; i++) {
- final OpToUnrestrict op = mOpsToIgnore.get(i);
+ final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
+ for (int i = 0; i < ignoreIfDefaultCount; i++) {
+ final OpToUnrestrict op = mOpsToIgnoreIfDefault.get(i);
setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
}
final int defaultCount = mOpsToDefault.size();
@@ -341,7 +355,7 @@
if (applyRestriction) {
mOpsToDefault.add(new OpToRestrict(uid, opCode));
} else {
- mOpsToAllow.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
+ mOpsToAllowIfDefault.add(new OpToUnrestrict(uid, pkg.packageName, opCode));
}
} else if (permissionInfo.isSoftRestricted()) {
// Storage uses a special app op to decide the mount state and
@@ -356,7 +370,7 @@
mOpsToAllow.add(new OpToUnrestrict(uid, pkg.packageName,
AppOpsManager.OP_LEGACY_STORAGE));
} else {
- mOpsToIgnore.add(new OpToUnrestrict(uid, pkg.packageName,
+ mOpsToIgnoreIfDefault.add(new OpToUnrestrict(uid, pkg.packageName,
AppOpsManager.OP_LEGACY_STORAGE));
}
}
@@ -421,6 +435,10 @@
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_ALLOWED, packageName);
}
+ private void setUidModeAllowed(int opCode, int uid) {
+ mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
+ }
+
private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
}
@@ -480,8 +498,9 @@
@Override
public boolean checkStartActivity(@NonNull Intent intent, int callingUid,
- @NonNull String callingPackage) {
- if (isActionRemovedForCallingPackage(intent.getAction(), callingPackage)) {
+ @Nullable String callingPackage) {
+ if (callingPackage != null && isActionRemovedForCallingPackage(intent.getAction(),
+ callingPackage)) {
Slog.w(LOG_TAG, "Action Removed: starting " + intent.toString() + " from "
+ callingPackage + " (uid=" + callingUid + ")");
return false;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f60a672..c3a769b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2637,17 +2637,25 @@
final WindowState imeWin = mInputMethodWindow;
final boolean imeVisible = imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw()
&& !mDividerControllerLocked.isImeHideRequested();
- final boolean dockVisible = isStackVisible(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ final TaskStack dockedStack = getSplitScreenPrimaryStack();
+ final boolean dockVisible = dockedStack != null;
+ final Task topDockedTask = dockVisible ? dockedStack.getTopChild() : null;
final TaskStack imeTargetStack = mWmService.getImeFocusStackLocked();
final int imeDockSide = (dockVisible && imeTargetStack != null) ?
imeTargetStack.getDockSide() : DOCKED_INVALID;
final boolean imeOnTop = (imeDockSide == DOCKED_TOP);
final boolean imeOnBottom = (imeDockSide == DOCKED_BOTTOM);
- final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock();
final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight();
final boolean imeHeightChanged = imeVisible &&
imeHeight != mDividerControllerLocked.getImeHeightAdjustedFor();
+ // This includes a case where the docked stack is unminimizing and IME is visible for the
+ // bottom side stack. The condition prevents adjusting the override task bounds for IME to
+ // the minimized docked stack bounds.
+ final boolean dockMinimized = mDividerControllerLocked.isMinimizedDock()
+ || (topDockedTask != null && imeOnBottom && !dockedStack.isAdjustedForIme()
+ && dockedStack.getBounds().height() < topDockedTask.getBounds().height());
+
// The divider could be adjusted for IME position, or be thinner than usual,
// or both. There are three possible cases:
// - If IME is visible, and focus is on top, divider is not moved for IME but thinner.
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 4b0a27b..fb548f9 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -65,10 +65,10 @@
name: "services.net",
srcs: ["java/**/*.java"],
static_libs: [
- "dnsresolver_aidl_interface-java",
+ "dnsresolver_aidl_interface-V2-java",
"ipmemorystore-client",
- "netd_aidl_interface-java",
- "networkstack-aidl-interfaces-java",
+ "netd_aidl_interface-V2-java",
+ "networkstack-aidl-interfaces-V3-java",
],
}
@@ -81,7 +81,7 @@
"java/android/net/ipmemorystore/**/*.java",
],
static_libs: [
- "ipmemorystore-aidl-interfaces-java",
+ "ipmemorystore-aidl-interfaces-V3-java",
],
}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 1522a60..869913d 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -73,7 +73,7 @@
"libui",
"libunwindstack",
"libutils",
- "netd_aidl_interface-cpp",
+ "netd_aidl_interface-V2-cpp",
],
dxflags: ["--multi-dex"],
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 92198fa..4a9cef1 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -55,6 +55,6 @@
"libui",
"libunwindstack",
"libutils",
- "netd_aidl_interface-cpp",
+ "netd_aidl_interface-V2-cpp",
],
}
diff --git a/services/tests/uiservicestests/AndroidManifest.xml b/services/tests/uiservicestests/AndroidManifest.xml
index 3ff85c8..7453c48 100644
--- a/services/tests/uiservicestests/AndroidManifest.xml
+++ b/services/tests/uiservicestests/AndroidManifest.xml
@@ -30,12 +30,14 @@
<uses-permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.OBSERVE_ROLE_HOLDERS" />
+ <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT"/>
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
<provider android:name=".DummyProvider"
android:authorities="com.android.services.uitests" />
+
</application>
<instrumentation
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 9db8753..87f221a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -304,6 +304,12 @@
void onGranted(ComponentName assistant, int userId, boolean granted);
}
+ @Override
+ protected boolean canLaunchInActivityView(Context context, PendingIntent pendingIntent,
+ String packageName) {
+ // Tests for this not being true are in CTS NotificationManagerTest
+ return true;
+ }
}
private class TestableToastCallback extends ITransientNotification.Stub {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 55159c3..d77ea6e 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -51,8 +51,6 @@
import android.os.RemoteCallback;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -106,7 +104,6 @@
final ArraySet<Integer> mLoadedKeyphraseIds = new ArraySet<>();
ShortcutServiceInternal mShortcutServiceInternal;
SoundTriggerInternal mSoundTriggerInternal;
- private boolean mAllowInstantService;
private final RemoteCallbackList<IVoiceInteractionSessionListener>
mVoiceInteractionSessionListeners = new RemoteCallbackList<>();
@@ -173,14 +170,6 @@
mServiceStub.switchUser(userHandle);
}
- // Called by Shell cmd
- void setAllowInstantService(boolean allowed) {
- Log.i(TAG, "setAllowInstantService(): " + allowed);
- mContext.enforceCallingPermission(Manifest.permission.MANAGE_BIND_INSTANT_SERVICE,
- "setAllowInstantService");
- mAllowInstantService = allowed;
- }
-
class LocalService extends VoiceInteractionManagerInternal {
@Override
public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) {
@@ -234,7 +223,6 @@
new IVoiceInteractionSessionShowCallback.Stub() {
@Override
public void onFailed() {
- Slog.w(TAG, "startLocalVoiceInteraction() failed");
}
@Override
@@ -283,10 +271,7 @@
}
public void initForUser(int userHandle) {
- if (DEBUG) {
- Slog.d(TAG, "**************** initForUser user=" + userHandle
- + ", allowInstantService=" + mAllowInstantService);
- }
+ if (DEBUG) Slog.d(TAG, "**************** initForUser user=" + userHandle);
String curInteractorStr = Settings.Secure.getStringForUser(
mContext.getContentResolver(),
Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle);
@@ -445,7 +430,6 @@
if (!mSafeMode) {
String curService = Settings.Secure.getStringForUser(
mResolver, Settings.Secure.VOICE_INTERACTION_SERVICE, mCurUser);
- if (DEBUG) Log.d(TAG, "Service for user " + mCurUser + ": " + curService);
ComponentName serviceComponent = null;
ServiceInfo serviceInfo = null;
if (curService != null && !curService.isEmpty()) {
@@ -482,8 +466,7 @@
}
if (hasComponent) {
setImplLocked(new VoiceInteractionManagerServiceImpl(mContext,
- UiThread.getHandler(), this, mCurUser, serviceComponent,
- mAllowInstantService));
+ UiThread.getHandler(), this, mCurUser, serviceComponent));
mImpl.startLocked();
} else {
setImplLocked(null);
@@ -1244,26 +1227,16 @@
synchronized (this) {
pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)");
pw.println(" mEnableService: " + mEnableService);
- pw.println(" mAllowInstantService: " + mAllowInstantService);
if (mImpl == null) {
pw.println(" (No active implementation)");
return;
}
mImpl.dumpLocked(fd, pw, args);
}
-
mSoundTriggerInternal.dump(fd, pw, args);
}
@Override
- public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
- String[] args, ShellCallback callback, ResultReceiver resultReceiver)
- throws RemoteException {
- new VoiceInteractionManagerServiceShellCommand(VoiceInteractionManagerService.this)
- .exec(this, in, out, err, args, callback, resultReceiver);
- }
-
- @Override
public void setUiHints(IVoiceInteractionService service, Bundle hints) {
synchronized (this) {
enforceIsCurrentVoiceInteractionService(service);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 4881ade..a1210cf 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -80,7 +80,6 @@
final VoiceInteractionServiceInfo mInfo;
final ComponentName mSessionComponentName;
final IWindowManager mIWindowManager;
- final boolean mAllowInstant;
boolean mBound = false;
IVoiceInteractionService mService;
@@ -126,7 +125,7 @@
VoiceInteractionManagerServiceImpl(Context context, Handler handler,
VoiceInteractionManagerService.VoiceInteractionManagerServiceStub stub,
- int userHandle, ComponentName service, boolean allowInstant) {
+ int userHandle, ComponentName service) {
mContext = context;
mHandler = handler;
mServiceStub = stub;
@@ -134,7 +133,6 @@
mComponent = service;
mAm = ActivityManager.getService();
mAtm = ActivityTaskManager.getService();
- mAllowInstant = allowInstant;
VoiceInteractionServiceInfo info;
try {
info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
@@ -169,7 +167,7 @@
if (mActiveSession == null) {
mActiveSession = new VoiceInteractionSessionConnection(mServiceStub,
mSessionComponentName, mUser, mContext, this,
- mInfo.getServiceInfo().applicationInfo.uid, mHandler, mAllowInstant);
+ mInfo.getServiceInfo().applicationInfo.uid, mHandler);
}
List<IBinder> activityTokens = null;
if (activityToken != null) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
deleted file mode 100644
index de1191f..0000000
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceShellCommand.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 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.voiceinteraction;
-
-import android.annotation.NonNull;
-import android.os.ShellCommand;
-
-import java.io.PrintWriter;
-
-final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
-
- private final VoiceInteractionManagerService mService;
-
- VoiceInteractionManagerServiceShellCommand(@NonNull VoiceInteractionManagerService service) {
- this.mService = service;
- }
-
- @Override
- public int onCommand(String cmd) {
- if (cmd == null) {
- return handleDefaultCommands(cmd);
- }
- final PrintWriter pw = getOutPrintWriter();
- switch (cmd) {
- case "set bind-instant-service-allowed":
- case "set":
- return requestSet(pw);
- default:
- return handleDefaultCommands(cmd);
- }
- }
-
- @Override
- public void onHelp() {
- try (PrintWriter pw = getOutPrintWriter();) {
- pw.println("VoiceInteraction Service (voiceinteraction) commands:");
- pw.println(" help");
- pw.println(" Prints this help text.");
- pw.println("");
- pw.println(" set bind-instant-service-allowed [true | false]");
- pw.println(" Sets whether binding to services provided by instant apps is allowed");
- pw.println("");
- }
- }
-
- private int requestSet(@NonNull PrintWriter pw) {
- final String what = getNextArgRequired();
-
- switch(what) {
- case "bind-instant-service-allowed":
- return setBindInstantService(pw);
- default:
- pw.println("Invalid set: " + what);
- return -1;
- }
- }
-
- private int setBindInstantService(@NonNull PrintWriter pw) {
- final String mode = getNextArgRequired();
- switch (mode.toLowerCase()) {
- case "true":
- mService.setAllowInstantService(true);
- return 0;
- case "false":
- mService.setAllowInstantService(false);
- return 0;
- default:
- pw.println("Invalid mode: " + mode);
- return -1;
- }
- }
-}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 3c47044..f16dec6 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -138,8 +138,7 @@
};
public VoiceInteractionSessionConnection(Object lock, ComponentName component, int user,
- Context context, Callback callback, int callingUid, Handler handler,
- boolean allowInstant) {
+ Context context, Callback callback, int callingUid, Handler handler) {
mLock = lock;
mSessionComponentName = component;
mUser = user;
@@ -160,13 +159,10 @@
mPermissionOwner = permOwner;
mBindIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
mBindIntent.setComponent(mSessionComponentName);
- int flags = Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY
- | Context.BIND_ALLOW_OOM_MANAGEMENT
- | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS;
- if (allowInstant) {
- flags |= Context.BIND_ALLOW_INSTANT;
- }
- mBound = mContext.bindServiceAsUser(mBindIntent, this, flags, new UserHandle(mUser));
+ mBound = mContext.bindServiceAsUser(mBindIntent, this,
+ Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY
+ | Context.BIND_ALLOW_OOM_MANAGEMENT
+ | Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS, new UserHandle(mUser));
if (mBound) {
try {
mIWindowManager.addWindowToken(mToken, TYPE_VOICE_INTERACTION, DEFAULT_DISPLAY);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index dab1e6f..4a58d94 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2246,7 +2246,7 @@
@UnsupportedAppUsage
public String getNetworkOperatorForPhone(int phoneId) {
return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, "");
- }
+ }
/**
@@ -2446,21 +2446,7 @@
* @return the NETWORK_TYPE_xxxx for current data connection.
*/
public @NetworkType int getNetworkType() {
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null) {
- return telephony.getNetworkType();
- } else {
- // This can happen when the ITelephony interface is not up yet.
- return NETWORK_TYPE_UNKNOWN;
- }
- } catch(RemoteException ex) {
- // This shouldn't happen in the normal case
- return NETWORK_TYPE_UNKNOWN;
- } catch (NullPointerException ex) {
- // This could happen before phone restarts due to crashing
- return NETWORK_TYPE_UNKNOWN;
- }
+ return getNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
}
/**
@@ -2491,7 +2477,7 @@
* @hide
*/
@RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public int getNetworkType(int subId) {
try {
ITelephony telephony = getITelephony();
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 68fd9ac..63aded1 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -460,13 +460,6 @@
void sendDialerSpecialCode(String callingPackageName, String inputCode);
/**
- * Returns the network type for data transmission
- * Legacy call, permission-free
- */
- @UnsupportedAppUsage
- int getNetworkType();
-
- /**
* Returns the network type of a subId.
* @param subId user preferred subId.
* @param callingPackage package making the call.
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 2552f04..e8e2a3d 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -102,6 +102,16 @@
callingPackage, message);
}
+ /** Identical to checkCallingOrSelfReadPhoneState but never throws SecurityException */
+ public static boolean checkCallingOrSelfReadPhoneStateNoThrow(
+ Context context, int subId, String callingPackage, String message) {
+ try {
+ return checkCallingOrSelfReadPhoneState(context, subId, callingPackage, message);
+ } catch (SecurityException se) {
+ return false;
+ }
+ }
+
/**
* Check whether the app with the given pid/uid can read phone state.
*
diff --git a/tests/net/Android.bp b/tests/net/Android.bp
index 1fbb658..306cc51 100644
--- a/tests/net/Android.bp
+++ b/tests/net/Android.bp
@@ -56,7 +56,7 @@
"libutilscallstack",
"libziparchive",
"libz",
- "netd_aidl_interface-cpp",
+ "netd_aidl_interface-V2-cpp",
"libnetworkstatsfactorytestjni",
],
}