Merge "Ensure that we stop app switches when finishing the recents animation" into qt-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index ee6fb51..1a912a1c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1917,6 +1917,10 @@
method public boolean hasSingleFileDescriptor();
}
+ public final class Parcel {
+ method public int readExceptionCode();
+ }
+
public class ParcelFileDescriptor implements java.io.Closeable android.os.Parcelable {
method public static java.io.File getFile(java.io.FileDescriptor) throws java.io.IOException;
}
@@ -1986,6 +1990,7 @@
public class SystemProperties {
method @NonNull public static String get(@NonNull String);
method @NonNull public static String get(@NonNull String, @Nullable String);
+ method public static boolean getBoolean(@NonNull String, boolean);
}
public final class UserHandle implements android.os.Parcelable {
@@ -2140,6 +2145,36 @@
}
+package android.os.image {
+
+ public class DynamicSystemClient {
+ ctor public DynamicSystemClient(@NonNull android.content.Context);
+ method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void bind();
+ method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+ method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+ method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long);
+ method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void start(@NonNull android.net.Uri, long, long);
+ method @RequiresPermission("android.permission.INSTALL_DYNAMIC_SYSTEM") public void unbind();
+ field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
+ field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
+ field public static final int CAUSE_ERROR_IO = 3; // 0x3
+ field public static final int CAUSE_ERROR_IPC = 5; // 0x5
+ field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2
+ field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1
+ field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0
+ field public static final int STATUS_IN_PROGRESS = 2; // 0x2
+ field public static final int STATUS_IN_USE = 4; // 0x4
+ field public static final int STATUS_NOT_STARTED = 1; // 0x1
+ field public static final int STATUS_READY = 3; // 0x3
+ field public static final int STATUS_UNKNOWN = 0; // 0x0
+ }
+
+ public static interface DynamicSystemClient.OnStatusChangedListener {
+ method public void onStatusChanged(int, int, long, @Nullable Throwable);
+ }
+
+}
+
package android.os.storage {
public class StorageManager {
@@ -2946,6 +2981,21 @@
method public E valueAtUnchecked(int);
}
+ public class FeatureFlagUtils {
+ ctor public FeatureFlagUtils();
+ method public static java.util.Map<java.lang.String,java.lang.String> getAllFeatureFlags();
+ method public static boolean isEnabled(android.content.Context, String);
+ method public static void setEnabled(android.content.Context, String, boolean);
+ field public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
+ field public static final String FFLAG_OVERRIDE_PREFIX = "sys.fflag.override.";
+ field public static final String FFLAG_PREFIX = "sys.fflag.";
+ field public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
+ field public static final String PERSIST_PREFIX = "persist.sys.fflag.override.";
+ field public static final String PIXEL_WALLPAPER_CATEGORY_SWITCH = "settings_pixel_wallpaper_category_switch";
+ field public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
+ field public static final String SEAMLESS_TRANSFER = "settings_seamless_transfer";
+ }
+
public class TimeUtils {
method public static String formatDuration(long);
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b09eada..cb939f0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -807,7 +807,7 @@
*
* @hide
*/
- public static final int INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS = 0x00000200;
+ public static final int INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS = 0x00400000;
/** {@hide} */
public static final int INSTALL_FORCE_VOLUME_UUID = 0x00000200;
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 41be38a..58aacc2 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -153,14 +153,21 @@
public static final int CLONE_REMOVE_RES_NAMES = 1 << 3;
/** @hide */
+ public static final int CLONE_REMOVE_PERSON = 1 << 4;
+
+ /** @hide */
public static final int CLONE_REMOVE_FOR_CREATOR = CLONE_REMOVE_ICON | CLONE_REMOVE_RES_NAMES;
/** @hide */
public static final int CLONE_REMOVE_FOR_LAUNCHER = CLONE_REMOVE_ICON | CLONE_REMOVE_INTENT
- | CLONE_REMOVE_RES_NAMES;
+ | CLONE_REMOVE_RES_NAMES | CLONE_REMOVE_PERSON;
/** @hide */
public static final int CLONE_REMOVE_FOR_LAUNCHER_APPROVAL = CLONE_REMOVE_INTENT
+ | CLONE_REMOVE_RES_NAMES | CLONE_REMOVE_PERSON;
+
+ /** @hide */
+ public static final int CLONE_REMOVE_FOR_APP_PREDICTION = CLONE_REMOVE_ICON
| CLONE_REMOVE_RES_NAMES;
/** @hide */
@@ -169,8 +176,11 @@
CLONE_REMOVE_INTENT,
CLONE_REMOVE_NON_KEY_INFO,
CLONE_REMOVE_RES_NAMES,
+ CLONE_REMOVE_PERSON,
CLONE_REMOVE_FOR_CREATOR,
- CLONE_REMOVE_FOR_LAUNCHER
+ CLONE_REMOVE_FOR_LAUNCHER,
+ CLONE_REMOVE_FOR_LAUNCHER_APPROVAL,
+ CLONE_REMOVE_FOR_APP_PREDICTION
})
@Retention(RetentionPolicy.SOURCE)
public @interface CloneFlags {}
@@ -548,7 +558,9 @@
mDisabledMessage = source.mDisabledMessage;
mDisabledMessageResId = source.mDisabledMessageResId;
mCategories = cloneCategories(source.mCategories);
- mPersons = clonePersons(source.mPersons);
+ if ((cloneFlags & CLONE_REMOVE_PERSON) == 0) {
+ mPersons = clonePersons(source.mPersons);
+ }
if ((cloneFlags & CLONE_REMOVE_INTENT) == 0) {
mIntents = cloneIntents(source.mIntents);
mIntentPersistableExtrases =
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index de963c9..fe2e948 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -2001,6 +2002,7 @@
* @hide
*/
@UnsupportedAppUsage
+ @TestApi
public final int readExceptionCode() {
int code = readInt();
if (code == EX_HAS_REPLY_HEADER) {
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index edfdda8bb..4538410 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -174,6 +174,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static boolean getBoolean(@NonNull String key, boolean def) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get_boolean(key, def);
diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java
index f1f24fb..921f0f2 100644
--- a/core/java/android/os/image/DynamicSystemClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -22,6 +22,7 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -67,6 +68,7 @@
* @hide
*/
@SystemApi
+@TestApi
public class DynamicSystemClient {
/** @hide */
@IntDef(prefix = { "STATUS_" }, value = {
@@ -283,6 +285,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public DynamicSystemClient(@NonNull Context context) {
mContext = context;
mConnection = new DynSystemServiceConnection();
@@ -314,8 +317,11 @@
* Bind to {@code DynamicSystem} installation service. Binding to the installation service
* allows it to send status updates to {@link #OnStatusChangedListener}. It is recommanded
* to bind before calling {@link #start} and get status updates.
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+ @SystemApi
+ @TestApi
public void bind() {
if (!featureFlagEnabled()) {
Slog.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; bind() aborted.");
@@ -334,8 +340,11 @@
/**
* Unbind from {@code DynamicSystem} installation service. Unbinding from the installation
* service stops it from sending following status updates.
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+ @SystemApi
+ @TestApi
public void unbind() {
if (!mBound) {
return;
@@ -367,8 +376,11 @@
*
* @param systemUrl a network Uri, a file Uri or a content Uri pointing to a system image file.
* @param systemSize size of system image.
+ * @hide
*/
@RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM)
+ @SystemApi
+ @TestApi
public void start(@NonNull Uri systemUrl, @BytesLong long systemSize) {
start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index c42dc81..324e02c 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -16,6 +16,7 @@
package android.util;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.SystemProperties;
import android.provider.Settings;
@@ -29,6 +30,7 @@
*
* @hide
*/
+@TestApi
public class FeatureFlagUtils {
public static final String FFLAG_PREFIX = "sys.fflag.";
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a88c51a..fca97fe 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -185,7 +185,7 @@
private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
- private static final int WATCHDOG_TIMEOUT_MILLIS = 3000;
+ private static final int WATCHDOG_TIMEOUT_MILLIS = 5000;
private static final int DEFAULT_SALT_EXPIRATION_DAYS = 7;
private int mMaxHashSaltDays = DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI,
@@ -252,6 +252,123 @@
// Sorted list of DisplayResolveInfos for the alphabetical app section.
private List<ResolverActivity.DisplayResolveInfo> mSortedList = new ArrayList<>();
+ private ContentPreviewCoordinator mPreviewCoord;
+
+ private class ContentPreviewCoordinator {
+ private static final int IMAGE_LOAD_TIMEOUT_MILLIS = 300;
+ private static final int IMAGE_FADE_IN_MILLIS = 150;
+ private static final int IMAGE_LOAD_TIMEOUT = 1;
+ private static final int IMAGE_LOAD_INTO_VIEW = 2;
+
+ private final View mParentView;
+ private boolean mHideParentOnFail;
+ private boolean mAtLeastOneLoaded = false;
+
+ class LoadUriTask {
+ public final Uri mUri;
+ public final int mImageResourceId;
+ public final int mExtraCount;
+ public final Bitmap mBmp;
+
+ LoadUriTask(int imageResourceId, Uri uri, int extraCount, Bitmap bmp) {
+ this.mImageResourceId = imageResourceId;
+ this.mUri = uri;
+ this.mExtraCount = extraCount;
+ this.mBmp = bmp;
+ }
+ }
+
+ // If at least one image loads within the timeout period, allow other
+ // loads to continue. Otherwise terminate and optionally hide
+ // the parent area
+ private final Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case IMAGE_LOAD_TIMEOUT:
+ maybeHideContentPreview();
+ break;
+
+ case IMAGE_LOAD_INTO_VIEW:
+ if (isFinishing()) break;
+
+ LoadUriTask task = (LoadUriTask) msg.obj;
+ RoundedRectImageView imageView = mParentView.findViewById(
+ task.mImageResourceId);
+ if (task.mBmp == null) {
+ imageView.setVisibility(View.GONE);
+ maybeHideContentPreview();
+ return;
+ }
+
+ mAtLeastOneLoaded = true;
+ imageView.setVisibility(View.VISIBLE);
+ imageView.setAlpha(0.0f);
+ imageView.setImageBitmap(task.mBmp);
+
+ ValueAnimator fadeAnim = ObjectAnimator.ofFloat(imageView, "alpha", 0.0f,
+ 1.0f);
+ fadeAnim.setInterpolator(new DecelerateInterpolator(1.0f));
+ fadeAnim.setDuration(IMAGE_FADE_IN_MILLIS);
+ fadeAnim.start();
+
+ if (task.mExtraCount > 0) {
+ imageView.setExtraImageCount(task.mExtraCount);
+ }
+ }
+ }
+ };
+
+ ContentPreviewCoordinator(View parentView, boolean hideParentOnFail) {
+ super();
+
+ this.mParentView = parentView;
+ this.mHideParentOnFail = hideParentOnFail;
+ }
+
+ private void loadUriIntoView(final int imageResourceId, final Uri uri,
+ final int extraImages) {
+ mHandler.sendEmptyMessageDelayed(IMAGE_LOAD_TIMEOUT, IMAGE_LOAD_TIMEOUT_MILLIS);
+
+ AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
+ final Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
+ final Message msg = Message.obtain();
+ msg.what = IMAGE_LOAD_INTO_VIEW;
+ msg.obj = new LoadUriTask(imageResourceId, uri, extraImages, bmp);
+ mHandler.sendMessage(msg);
+ });
+ }
+
+ private void cancelLoads() {
+ mHandler.removeMessages(IMAGE_LOAD_INTO_VIEW);
+ mHandler.removeMessages(IMAGE_LOAD_TIMEOUT);
+ }
+
+ private void maybeHideContentPreview() {
+ if (!mAtLeastOneLoaded && mHideParentOnFail) {
+ Log.i(TAG, "Hiding image preview area. Timed out waiting for preview to load"
+ + " within " + IMAGE_LOAD_TIMEOUT_MILLIS + "ms.");
+ collapseParentView();
+ if (mChooserRowAdapter != null) {
+ mChooserRowAdapter.hideContentPreview();
+ }
+ mHideParentOnFail = false;
+ }
+ }
+
+ private void collapseParentView() {
+ // This will effectively hide the content preview row by forcing the height
+ // to zero. It is faster than forcing a relayout of the listview
+ final View v = mParentView;
+ int widthSpec = MeasureSpec.makeMeasureSpec(v.getWidth(), MeasureSpec.EXACTLY);
+ int heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
+ v.measure(widthSpec, heightSpec);
+ v.getLayoutParams().height = 0;
+ v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getTop());
+ v.invalidate();
+ }
+ }
+
private final Handler mChooserHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -621,14 +738,15 @@
private ViewGroup displayContentPreview(@ContentPreviewType int previewType,
Intent targetIntent, LayoutInflater layoutInflater, ViewGroup convertView,
ViewGroup parent) {
+ if (convertView != null) return convertView;
+
switch (previewType) {
case CONTENT_PREVIEW_TEXT:
- return displayTextContentPreview(targetIntent, layoutInflater, convertView, parent);
+ return displayTextContentPreview(targetIntent, layoutInflater, parent);
case CONTENT_PREVIEW_IMAGE:
- return displayImageContentPreview(targetIntent, layoutInflater, convertView,
- parent);
+ return displayImageContentPreview(targetIntent, layoutInflater, parent);
case CONTENT_PREVIEW_FILE:
- return displayFileContentPreview(targetIntent, layoutInflater, convertView, parent);
+ return displayFileContentPreview(targetIntent, layoutInflater, parent);
default:
Log.e(TAG, "Unexpected content preview type: " + previewType);
}
@@ -637,10 +755,9 @@
}
private ViewGroup displayTextContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
- ViewGroup convertView, ViewGroup parent) {
- ViewGroup contentPreviewLayout =
- convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
- R.layout.chooser_grid_preview_text, parent, false);
+ ViewGroup parent) {
+ ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
+ R.layout.chooser_grid_preview_text, parent, false);
contentPreviewLayout.findViewById(R.id.copy_button).setOnClickListener(
this::onCopyButtonClicked);
@@ -677,12 +794,8 @@
if (previewThumbnail == null) {
previewThumbnailView.setVisibility(View.GONE);
} else {
- Bitmap bmp = loadThumbnail(previewThumbnail, new Size(100, 100));
- if (bmp == null) {
- previewThumbnailView.setVisibility(View.GONE);
- } else {
- previewThumbnailView.setImageBitmap(bmp);
- }
+ mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, false);
+ mPreviewCoord.loadUriIntoView(R.id.content_preview_thumbnail, previewThumbnail, 0);
}
}
@@ -690,15 +803,15 @@
}
private ViewGroup displayImageContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
- ViewGroup convertView, ViewGroup parent) {
- ViewGroup contentPreviewLayout =
- convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
- R.layout.chooser_grid_preview_image, parent, false);
+ ViewGroup parent) {
+ ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
+ R.layout.chooser_grid_preview_image, parent, false);
+ mPreviewCoord = new ContentPreviewCoordinator(contentPreviewLayout, true);
String action = targetIntent.getAction();
if (Intent.ACTION_SEND.equals(action)) {
Uri uri = targetIntent.getParcelableExtra(Intent.EXTRA_STREAM);
- loadUriIntoView(R.id.content_preview_image_1_large, uri, contentPreviewLayout);
+ mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, uri, 0);
} else {
ContentResolver resolver = getContentResolver();
@@ -717,21 +830,16 @@
return contentPreviewLayout;
}
- loadUriIntoView(R.id.content_preview_image_1_large, imageUris.get(0),
- contentPreviewLayout);
+ mPreviewCoord.loadUriIntoView(R.id.content_preview_image_1_large, imageUris.get(0), 0);
if (imageUris.size() == 2) {
- loadUriIntoView(R.id.content_preview_image_2_large, imageUris.get(1),
- contentPreviewLayout);
+ mPreviewCoord.loadUriIntoView(R.id.content_preview_image_2_large,
+ imageUris.get(1), 0);
} else if (imageUris.size() > 2) {
- loadUriIntoView(R.id.content_preview_image_2_small, imageUris.get(1),
- contentPreviewLayout);
- RoundedRectImageView imageView = loadUriIntoView(
- R.id.content_preview_image_3_small, imageUris.get(2), contentPreviewLayout);
-
- if (imageUris.size() > 3) {
- imageView.setExtraImageCount(imageUris.size() - 3);
- }
+ mPreviewCoord.loadUriIntoView(R.id.content_preview_image_2_small,
+ imageUris.get(1), 0);
+ mPreviewCoord.loadUriIntoView(R.id.content_preview_image_3_small,
+ imageUris.get(2), imageUris.size() - 3);
}
}
@@ -803,11 +911,10 @@
}
private ViewGroup displayFileContentPreview(Intent targetIntent, LayoutInflater layoutInflater,
- ViewGroup convertView, ViewGroup parent) {
+ ViewGroup parent) {
- ViewGroup contentPreviewLayout =
- convertView != null ? convertView : (ViewGroup) layoutInflater.inflate(
- R.layout.chooser_grid_preview_file, parent, false);
+ ViewGroup contentPreviewLayout = (ViewGroup) layoutInflater.inflate(
+ R.layout.chooser_grid_preview_file, parent, false);
// TODO(b/120417119): Disable file copy until after moving to sysui,
// due to permissions issues
@@ -839,6 +946,10 @@
R.id.content_preview_filename);
fileNameView.setText(fileName);
+ View thumbnailView = contentPreviewLayout.findViewById(
+ R.id.content_preview_file_thumbnail);
+ thumbnailView.setVisibility(View.GONE);
+
ImageView fileIconView = contentPreviewLayout.findViewById(
R.id.content_preview_file_icon);
fileIconView.setVisibility(View.VISIBLE);
@@ -849,32 +960,25 @@
return contentPreviewLayout;
}
- private void loadFileUriIntoView(Uri uri, View parent) {
+ private void loadFileUriIntoView(final Uri uri, final View parent) {
FileInfo fileInfo = extractFileInfo(uri, getContentResolver());
TextView fileNameView = parent.findViewById(R.id.content_preview_filename);
fileNameView.setText(fileInfo.name);
if (fileInfo.hasThumbnail) {
- loadUriIntoView(R.id.content_preview_file_thumbnail, uri, parent);
+ mPreviewCoord = new ContentPreviewCoordinator(parent, false);
+ mPreviewCoord.loadUriIntoView(R.id.content_preview_file_thumbnail, uri, 0);
} else {
+ View thumbnailView = parent.findViewById(R.id.content_preview_file_thumbnail);
+ thumbnailView.setVisibility(View.GONE);
+
ImageView fileIconView = parent.findViewById(R.id.content_preview_file_icon);
fileIconView.setVisibility(View.VISIBLE);
fileIconView.setImageResource(R.drawable.chooser_file_generic);
}
}
- private RoundedRectImageView loadUriIntoView(int imageResourceId, Uri uri, View parent) {
- RoundedRectImageView imageView = parent.findViewById(imageResourceId);
- Bitmap bmp = loadThumbnail(uri, new Size(200, 200));
- if (bmp != null) {
- imageView.setVisibility(View.VISIBLE);
- imageView.setImageBitmap(bmp);
- }
-
- return imageView;
- }
-
@VisibleForTesting
protected boolean isImageType(String mimeType) {
return mimeType != null && mimeType.startsWith("image/");
@@ -944,6 +1048,9 @@
mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT);
mChooserHandler.removeMessages(SHORTCUT_MANAGER_SHARE_TARGET_RESULT_COMPLETED);
+
+ if (mPreviewCoord != null) mPreviewCoord.cancelLoads();
+
if (mAppPredictor != null) {
mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback);
mAppPredictor.destroy();
@@ -2036,9 +2143,12 @@
}
int availableWidth = right - left - v.getPaddingLeft() - v.getPaddingRight();
- if (mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
+ if (mChooserRowAdapter.consumeLayoutRequest()
+ || mChooserRowAdapter.calculateChooserTargetWidth(availableWidth)
|| mAdapterView.getAdapter() == null) {
- mAdapterView.setAdapter(mChooserRowAdapter);
+ if (mAdapterView.getAdapter() == null) {
+ mAdapterView.setAdapter(mChooserRowAdapter);
+ }
getMainThreadHandler().post(() -> {
if (mResolverDrawerLayout == null || mChooserRowAdapter == null) {
@@ -2589,6 +2699,9 @@
private int mChooserTargetWidth = 0;
private boolean mShowAzLabelIfPoss;
+ private boolean mHideContentPreview = false;
+ private boolean mLayoutRequested = false;
+
private static final int VIEW_TYPE_DIRECT_SHARE = 0;
private static final int VIEW_TYPE_NORMAL = 1;
private static final int VIEW_TYPE_CONTENT_PREVIEW = 2;
@@ -2651,6 +2764,18 @@
return maxTargets;
}
+ public void hideContentPreview() {
+ mHideContentPreview = true;
+ mLayoutRequested = true;
+ notifyDataSetChanged();
+ }
+
+ public boolean consumeLayoutRequest() {
+ boolean oldValue = mLayoutRequested;
+ mLayoutRequested = false;
+ return oldValue;
+ }
+
@Override
public boolean areAllItemsEnabled() {
return false;
@@ -2684,7 +2809,8 @@
return 0;
}
- if (mChooserListAdapter == null || mChooserListAdapter.getCount() == 0) {
+ if (mHideContentPreview || mChooserListAdapter == null
+ || mChooserListAdapter.getCount() == 0) {
return 0;
}
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index f9f28da..daa6347 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -1301,18 +1301,6 @@
lpTrack->setParameters(param.toString());
}
-static void android_media_AudioTrack_set_eos(JNIEnv *env, jobject thiz) {
- sp<AudioTrack> lpTrack = getAudioTrack(env, thiz);
- if (lpTrack == NULL) {
- jniThrowException(env, "java/lang/IllegalStateException",
- "AudioTrack not initialized");
- return;
- }
- AudioParameter param = AudioParameter();
- param.addInt(String8("EOS"), 1);
- lpTrack->setParameters(param.toString());
-}
-
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
@@ -1389,7 +1377,6 @@
{"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
{"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
{"native_set_delay_padding", "(II)V", (void *)android_media_AudioTrack_set_delay_padding},
- {"native_set_eos", "()V", (void *)android_media_AudioTrack_set_eos},
};
diff --git a/core/res/res/layout/chooser_grid_preview_file.xml b/core/res/res/layout/chooser_grid_preview_file.xml
index 27c6041..f7d60c9 100644
--- a/core/res/res/layout/chooser_grid_preview_file.xml
+++ b/core/res/res/layout/chooser_grid_preview_file.xml
@@ -44,8 +44,7 @@
android:adjustViewBounds="true"
android:layout_gravity="center_vertical"
android:gravity="center"
- android:scaleType="centerCrop"
- android:visibility="gone"/>
+ android:scaleType="centerCrop"/>
<ImageView
android:id="@+id/content_preview_file_icon"
android:layout_width="36dp"
diff --git a/core/res/res/layout/chooser_grid_preview_image.xml b/core/res/res/layout/chooser_grid_preview_image.xml
index ad31e0d..79a0de4 100644
--- a/core/res/res/layout/chooser_grid_preview_image.xml
+++ b/core/res/res/layout/chooser_grid_preview_image.xml
@@ -33,7 +33,6 @@
<view class="com.android.internal.app.ChooserActivity$RoundedRectImageView"
android:id="@+id/content_preview_image_1_large"
- android:visibility="gone"
android:layout_width="120dp"
android:layout_height="140dp"
android:layout_alignParentTop="true"
diff --git a/packages/SystemUI/res/values-mcc310-mnc030/config.xml b/core/res/res/values-mcc310-mnc030/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc030/config.xml
rename to core/res/res/values-mcc310-mnc030/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc070/config.xml b/core/res/res/values-mcc310-mnc070/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc070/config.xml
rename to core/res/res/values-mcc310-mnc070/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc170/config.xml b/core/res/res/values-mcc310-mnc170/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc170/config.xml
rename to core/res/res/values-mcc310-mnc170/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc280/config.xml b/core/res/res/values-mcc310-mnc280/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc280/config.xml
rename to core/res/res/values-mcc310-mnc280/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc380/config.xml b/core/res/res/values-mcc310-mnc380/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc380/config.xml
rename to core/res/res/values-mcc310-mnc380/config.xml
diff --git a/core/res/res/values-mcc310-mnc410/config.xml b/core/res/res/values-mcc310-mnc410/config.xml
index 00ab712..3fb3f0f 100644
--- a/core/res/res/values-mcc310-mnc410/config.xml
+++ b/core/res/res/values-mcc310-mnc410/config.xml
@@ -48,4 +48,8 @@
<item>"#8"</item>
<item>"#9"</item>
</string-array>
+
+ <!-- Enable 5 bar signal strength icon -->
+ <bool name="config_inflateSignalStrength">true</bool>
+
</resources>
diff --git a/packages/SystemUI/res/values-mcc310-mnc560/config.xml b/core/res/res/values-mcc310-mnc560/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc560/config.xml
rename to core/res/res/values-mcc310-mnc560/config.xml
diff --git a/packages/SystemUI/res/values-mcc310-mnc950/config.xml b/core/res/res/values-mcc310-mnc950/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc310-mnc950/config.xml
rename to core/res/res/values-mcc310-mnc950/config.xml
diff --git a/packages/SystemUI/res/values-mcc311-mnc180/config.xml b/core/res/res/values-mcc311-mnc180/config.xml
similarity index 100%
rename from packages/SystemUI/res/values-mcc311-mnc180/config.xml
rename to core/res/res/values-mcc311-mnc180/config.xml
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index db2f8d0..336e30e 100755
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -40,4 +40,7 @@
<bool name="config_use_sim_language_file">true</bool>
+ <!-- Enable 5 bar signal strength icon -->
+ <bool name="config_inflateSignalStrength">true</bool>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2de5397..fb58569 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4121,4 +4121,9 @@
even after user setup is complete. The defined component should be used for supervision purposes
only. The component must be part of a system app. -->
<string name="config_defaultSupervisionProfileOwnerComponent" translatable="false"></string>
+
+ <!-- Whether to artificially interpret all signal strengths as
+ one bar higher than they actually are -->
+ <bool name="config_inflateSignalStrength">false</bool>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6cdb3d6..3d2d969 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3797,4 +3797,5 @@
<java-symbol type="style" name="Animation.DeviceDefault.Activity.Resolver" />
<java-symbol type="string" name="config_defaultSupervisionProfileOwnerComponent" />
+ <java-symbol type="bool" name="config_inflateSignalStrength" />
</resources>
diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
index dbb79bc..e030478 100644
--- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
+++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java
@@ -162,15 +162,15 @@
}
if ((opResult.output != null) && (opResult.output.length > 0)) {
- if (inputLength > 0) {
+ if (inputLength + mBufferedLength > 0) {
// More output might be produced in this loop -- buffer the current output
if (bufferedOutput == null) {
bufferedOutput = new ByteArrayOutputStream();
- try {
- bufferedOutput.write(opResult.output);
- } catch (IOException e) {
- throw new ProviderException("Failed to buffer output", e);
- }
+ }
+ try {
+ bufferedOutput.write(opResult.output);
+ } catch (IOException e) {
+ throw new ProviderException("Failed to buffer output", e);
}
} else {
// No more output will be produced in this loop
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index d9d614f..e29e569 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -101,6 +101,20 @@
public static final int PLAYSTATE_PAUSED = 2; // matches SL_PLAYSTATE_PAUSED
/** indicates AudioTrack state is playing */
public static final int PLAYSTATE_PLAYING = 3; // matches SL_PLAYSTATE_PLAYING
+ /**
+ * @hide
+ * indicates AudioTrack state is stopping waiting for NATIVE_EVENT_STREAM_END to
+ * transition to PLAYSTATE_STOPPED.
+ * Only valid for offload mode.
+ */
+ private static final int PLAYSTATE_STOPPING = 4;
+ /**
+ * @hide
+ * indicates AudioTrack state is paused from stopping state. Will transition to
+ * PLAYSTATE_STOPPING if play() is called.
+ * Only valid for offload mode.
+ */
+ private static final int PLAYSTATE_PAUSED_STOPPING = 5;
// keep these values in sync with android_media_AudioTrack.cpp
/**
@@ -303,6 +317,14 @@
* One of PLAYSTATE_STOPPED, PLAYSTATE_PAUSED, or PLAYSTATE_PLAYING.
*/
private int mPlayState = PLAYSTATE_STOPPED;
+
+ /**
+ * Indicates that we are expecting an end of stream callback following a call
+ * to setOffloadEndOfStream() in a gapless track transition context. The native track
+ * will be restarted automatically.
+ */
+ private boolean mOffloadEosPending = false;
+
/**
* Lock to ensure mPlayState updates reflect the actual state of the object.
*/
@@ -1073,6 +1095,10 @@
* Declares that the last write() operation on this track provided the last buffer of this
* stream.
* After the end of stream, previously set padding and delay values are ignored.
+ * Can only be called only if the AudioTrack is opened in offload mode
+ * {@see Builder#setOffloadedPlayback(boolean)}.
+ * Can only be called only if the AudioTrack is in state {@link #PLAYSTATE_PLAYING}
+ * {@see #getPlaystate()}.
* Use this method in the same thread as any write() operation.
*/
public void setOffloadEndOfStream() {
@@ -1082,7 +1108,20 @@
if (mState == STATE_UNINITIALIZED) {
throw new IllegalStateException("Uninitialized track");
}
- native_set_eos();
+ if (mPlayState != PLAYSTATE_PLAYING) {
+ throw new IllegalStateException("EOS not supported if not playing");
+ }
+ synchronized (mStreamEventCbLock) {
+ if (mStreamEventCbInfoList.size() == 0) {
+ throw new IllegalStateException("EOS not supported without StreamEventCallback");
+ }
+ }
+
+ synchronized (mPlayStateLock) {
+ native_stop();
+ mOffloadEosPending = true;
+ mPlayState = PLAYSTATE_STOPPING;
+ }
}
/**
@@ -1366,7 +1405,11 @@
}
baseRelease();
native_release();
- mState = STATE_UNINITIALIZED;
+ synchronized (mPlayStateLock) {
+ mState = STATE_UNINITIALIZED;
+ mPlayState = PLAYSTATE_STOPPED;
+ mPlayStateLock.notify();
+ }
}
@Override
@@ -1525,7 +1568,14 @@
*/
public int getPlayState() {
synchronized (mPlayStateLock) {
- return mPlayState;
+ switch (mPlayState) {
+ case PLAYSTATE_STOPPING:
+ return PLAYSTATE_PLAYING;
+ case PLAYSTATE_PAUSED_STOPPING:
+ return PLAYSTATE_PAUSED;
+ default:
+ return mPlayState;
+ }
}
}
@@ -2260,7 +2310,12 @@
synchronized(mPlayStateLock) {
baseStart();
native_start();
- mPlayState = PLAYSTATE_PLAYING;
+ if (mPlayState == PLAYSTATE_PAUSED_STOPPING) {
+ mPlayState = PLAYSTATE_STOPPING;
+ } else {
+ mPlayState = PLAYSTATE_PLAYING;
+ mOffloadEosPending = false;
+ }
}
}
@@ -2282,9 +2337,15 @@
synchronized(mPlayStateLock) {
native_stop();
baseStop();
- mPlayState = PLAYSTATE_STOPPED;
- mAvSyncHeader = null;
- mAvSyncBytesRemaining = 0;
+ if (mOffloaded && mPlayState != PLAYSTATE_PAUSED_STOPPING) {
+ mPlayState = PLAYSTATE_STOPPING;
+ } else {
+ mPlayState = PLAYSTATE_STOPPED;
+ mOffloadEosPending = false;
+ mAvSyncHeader = null;
+ mAvSyncBytesRemaining = 0;
+ mPlayStateLock.notify();
+ }
}
}
@@ -2305,7 +2366,11 @@
synchronized(mPlayStateLock) {
native_pause();
basePause();
- mPlayState = PLAYSTATE_PAUSED;
+ if (mPlayState == PLAYSTATE_STOPPING) {
+ mPlayState = PLAYSTATE_PAUSED_STOPPING;
+ } else {
+ mPlayState = PLAYSTATE_PAUSED;
+ }
}
}
@@ -2434,6 +2499,9 @@
return ERROR_BAD_VALUE;
}
+ if (!blockUntilOffloadDrain(writeMode)) {
+ return 0;
+ }
final int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
writeMode == WRITE_BLOCKING);
@@ -2544,6 +2612,10 @@
return ERROR_BAD_VALUE;
}
+ if (!blockUntilOffloadDrain(writeMode)) {
+ return 0;
+ }
+
final int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat,
writeMode == WRITE_BLOCKING);
@@ -2632,6 +2704,10 @@
return ERROR_BAD_VALUE;
}
+ if (!blockUntilOffloadDrain(writeMode)) {
+ return 0;
+ }
+
final int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat,
writeMode == WRITE_BLOCKING);
@@ -2706,6 +2782,10 @@
return ERROR_BAD_VALUE;
}
+ if (!blockUntilOffloadDrain(writeMode)) {
+ return 0;
+ }
+
int ret = 0;
if (audioData.isDirect()) {
ret = native_write_native_bytes(audioData,
@@ -2790,6 +2870,10 @@
return ERROR_BAD_VALUE;
}
+ if (!blockUntilOffloadDrain(writeMode)) {
+ return 0;
+ }
+
// create timestamp header if none exists
if (mAvSyncHeader == null) {
mAvSyncHeader = ByteBuffer.allocate(mOffset);
@@ -2859,6 +2943,25 @@
return native_reload_static();
}
+ /**
+ * When an AudioTrack in offload mode is in STOPPING play state, wait until event STREAM_END is
+ * received if blocking write or return with 0 frames written if non blocking mode.
+ */
+ private boolean blockUntilOffloadDrain(int writeMode) {
+ synchronized (mPlayStateLock) {
+ while (mPlayState == PLAYSTATE_STOPPING || mPlayState == PLAYSTATE_PAUSED_STOPPING) {
+ if (writeMode == WRITE_NON_BLOCKING) {
+ return false;
+ }
+ try {
+ mPlayStateLock.wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ return true;
+ }
+ }
+
//--------------------------------------------------------------------------
// Audio effects management
//--------------------
@@ -3293,6 +3396,22 @@
public void handleMessage(Message msg) {
final LinkedList<StreamEventCbInfo> cbInfoList;
synchronized (mStreamEventCbLock) {
+ if (msg.what == NATIVE_EVENT_STREAM_END) {
+ synchronized (mPlayStateLock) {
+ if (mPlayState == PLAYSTATE_STOPPING) {
+ if (mOffloadEosPending) {
+ native_start();
+ mPlayState = PLAYSTATE_PLAYING;
+ } else {
+ mAvSyncHeader = null;
+ mAvSyncBytesRemaining = 0;
+ mPlayState = PLAYSTATE_STOPPED;
+ }
+ mOffloadEosPending = false;
+ mPlayStateLock.notify();
+ }
+ }
+ }
if (mStreamEventCbInfoList.size() == 0) {
return;
}
@@ -3560,7 +3679,6 @@
private native int native_getPortId();
private native void native_set_delay_padding(int delayInFrames, int paddingInFrames);
- private native void native_set_eos();
//---------------------------------------------------------
// Utility methods
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 4c72f48..0e91839 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -578,6 +578,8 @@
<string name="wifi_display_certification">Wireless display certification</string>
<!-- Setting Checkbox title whether to enable WiFi Verbose Logging. [CHAR LIMIT=40] -->
<string name="wifi_verbose_logging">Enable Wi\u2011Fi Verbose Logging</string>
+ <!-- Setting Checkbox title whether to disable WiFi Scan Throttling. [CHAR LIMIT=40] -->
+ <string name="wifi_scan_throttling">Wi\u2011Fi scan throttling</string>
<!-- Setting Checkbox title whether to always keep mobile data active. [CHAR LIMIT=80] -->
<string name="mobile_data_always_on">Mobile data always active</string>
<!-- Setting Checkbox title whether to enable hardware acceleration for tethering. [CHAR LIMIT=80] -->
@@ -633,6 +635,8 @@
<string name="wifi_display_certification_summary">Show options for wireless display certification</string>
<!-- Setting Checkbox summary whether to enable Wifi verbose Logging [CHAR LIMIT=80] -->
<string name="wifi_verbose_logging_summary">Increase Wi\u2011Fi logging level, show per SSID RSSI in Wi\u2011Fi Picker</string>
+ <!-- Setting Checkbox summary whether to disable Wifi scan throttling [CHAR LIMIT=NONE] -->
+ <string name="wifi_scan_throttling_summary">Reduces battery drain & improves network performance</string>
<!-- Label indicating network has been manually marked as metered -->
<string name="wifi_metered_label">Metered</string>
<!-- Label indicating network has been manually marked as unmetered -->
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java b/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java
new file mode 100644
index 0000000..246f2ce
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/net/SignalStrengthUtil.java
@@ -0,0 +1,34 @@
+/*
+ * 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.settingslib.net;
+
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+
+/**
+ * Utilities for dealing with signal strength.
+ */
+public class SignalStrengthUtil {
+ /**
+ * @return whether we should artificially inflate the signal strength and number of levels by 1
+ * bar for the subscription with the given id
+ */
+ public static boolean shouldInflateSignalStrength(Context context, int subscriptionId) {
+ return SubscriptionManager.getResourcesForSubId(context, subscriptionId)
+ .getBoolean(com.android.internal.R.bool.config_inflateSignalStrength);
+ }
+}
diff --git a/packages/SystemUI/res/drawable/ic_volume_media.xml b/packages/SystemUI/res/drawable/ic_volume_media.xml
index c8fa3fb..99be7b6 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media.xml
@@ -22,6 +22,6 @@
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M12,3l0.01,10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17V7h4V3H12zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
+ android:pathData="M12 3l0.01 10.55c-0.59-0.34-1.27-0.55-2-0.55C7.79 13 6 14.79 6 17s1.79 4 4.01 4S14 19.21 14 17V7h4V3h-6z" />
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
index 45b5b87..3a495963 100644
--- a/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
+++ b/packages/SystemUI/res/drawable/ic_volume_media_mute.xml
@@ -22,9 +22,6 @@
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M21.19,21.19L14,14l-2,-2l-9.2,-9.2L1.39,4.22l8.79,8.79c-0.06,0 -0.12,-0.01 -0.18,-0.01C7.79,13 6,14.79 6,17c0,2.21 1.79,4 4.01,4S14,19.21 14,17v-0.17l5.78,5.78L21.19,21.19zM10.01,19c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C12.01,18.1 11.11,19 10.01,19z"/>
- <path
- android:fillColor="#FFffffff"
- android:pathData="M14,11.17l0,-4.17l4,0l0,-4l-6,0l0,6.17z"/>
+ android:pathData="M21.19 21.19L14 14l-2-2-9.2-9.2-1.41 1.42 8.79 8.79c-0.06 0-0.12-0.01-0.18-0.01-2.21 0-4 1.79-4 4s1.79 4 4.01 4S14 19.21 14 17v-0.17l5.78 5.78 1.41-1.42zM14 11.17V7h4V3h-6v6.17z" />
</vector>
diff --git a/packages/SystemUI/res/values-mcc310-mnc410/config.xml b/packages/SystemUI/res/values-mcc310-mnc410/config.xml
deleted file mode 100644
index 26b9192..0000000
--- a/packages/SystemUI/res/values-mcc310-mnc410/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 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.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-<resources>
- <!-- Enable 5 bar signal strength icon -->
- <bool name="config_inflateSignalStrength">true</bool>
-</resources>
-
diff --git a/packages/SystemUI/res/values-mcc311-mnc480/config.xml b/packages/SystemUI/res/values-mcc311-mnc480/config.xml
deleted file mode 100644
index 7dadae7..0000000
--- a/packages/SystemUI/res/values-mcc311-mnc480/config.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2017, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-
-<!-- These resources are around just to allow their values to be customized
- for different hardware and product builds. -->
-<resources>
- <!-- Enable 5 bar signal strength icon -->
- <bool name="config_inflateSignalStrength">true</bool>
-</resources>
-
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 27431f7..19e7b73 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -417,10 +417,6 @@
it has been expanded to reveal its children. -->
<bool name="config_showGroupNotificationBgWhenExpanded">false</bool>
- <!-- Whether to artificially interpret all signal strengths as
- one bar higher than they actually are -->
- <bool name="config_inflateSignalStrength">false</bool>
-
<!-- Should we vibrate on an icon animation of the shelf. This should only be active if the
vibrator is capable of subtle vibrations -->
<bool name="config_vibrateOnIconAnimation">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1987494..c04d28a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -38,7 +38,6 @@
<dimen name="navigation_handle_sample_horizontal_margin">10dp</dimen>
<dimen name="navigation_home_handle_width">72dp</dimen>
-
<!-- Size of the nav bar edge panels, should be greater to the
edge sensitivity + the drag threshold -->
<dimen name="navigation_edge_panel_width">70dp</dimen>
@@ -57,6 +56,9 @@
<!-- Luminance change threshold that allows applying new value if difference was exceeded -->
<item name="navigation_luminance_change_threshold" type="dimen" format="float">0.05</item>
+ <dimen name="floating_rotation_button_diameter">40dp</dimen>
+ <dimen name="floating_rotation_button_margin">4dp</dimen>
+
<!-- Height of notification icons in the status bar -->
<dimen name="status_bar_icon_size">@*android:dimen/status_bar_icon_size</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 4ec79a6..392183b 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.app.Notification.FLAG_BUBBLE;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
@@ -40,8 +41,6 @@
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
-import android.app.ActivityTaskManager;
-import android.app.IActivityTaskManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
@@ -53,6 +52,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import android.service.notification.ZenModeConfig;
import android.util.Log;
@@ -138,7 +138,6 @@
private final Context mContext;
private final NotificationEntryManager mNotificationEntryManager;
- private final IActivityTaskManager mActivityTaskManager;
private final BubbleTaskStackListener mTaskStackListener;
private BubbleStateChangeListener mStateChangeListener;
private BubbleExpandListener mExpandListener;
@@ -250,7 +249,6 @@
mStatusBarStateListener = new StatusBarStateListener();
Dependency.get(StatusBarStateController.class).addCallback(mStatusBarStateListener);
- mActivityTaskManager = ActivityTaskManager.getService();
mTaskStackListener = new BubbleTaskStackListener();
ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
@@ -509,6 +507,12 @@
updateBubble(entry);
}
}
+
+ @Override
+ public void onNotificationRankingUpdated(RankingMap rankingMap) {
+ // Forward to BubbleData to block any bubbles which should no longer be shown
+ mBubbleData.notificationRankingUpdated(rankingMap);
+ }
};
@SuppressWarnings("FieldCanBeLocal")
@@ -547,8 +551,11 @@
mNotificationEntryManager.performRemoveNotification(bubble.entry.notification,
UNDEFINED_DISMISS_REASON);
} else {
- // The notification is still in the shade but we've removed the bubble so
- // lets make sure NoMan knows it's not a bubble anymore
+ // Update the flag for SysUI
+ bubble.entry.notification.getNotification().flags &= ~FLAG_BUBBLE;
+
+ // Make sure NoMan knows it's not a bubble anymore so anyone querying it will
+ // get right result back
try {
mBarService.onNotificationBubbleChanged(bubble.getKey(),
false /* isBubble */);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
index 6ab973e..5575b35 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleData.java
@@ -22,6 +22,8 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.util.Log;
import android.util.Pair;
@@ -114,6 +116,8 @@
// State tracked during an operation -- keeps track of what listener events to dispatch.
private Update mStateChange;
+ private NotificationListenerService.Ranking mTmpRanking;
+
private TimeSource mTimeSource = System::currentTimeMillis;
@Nullable
@@ -193,6 +197,31 @@
dispatchPendingChanges();
}
+ /**
+ * Called when NotificationListener has received adjusted notification rank and reapplied
+ * filtering and sorting. This is used to dismiss any bubbles which should no longer be shown
+ * due to changes in permissions on the notification channel or the global setting.
+ *
+ * @param rankingMap the updated ranking map from NotificationListenerService
+ */
+ public void notificationRankingUpdated(RankingMap rankingMap) {
+ if (mTmpRanking == null) {
+ mTmpRanking = new NotificationListenerService.Ranking();
+ }
+
+ String[] orderedKeys = rankingMap.getOrderedKeys();
+ for (int i = 0; i < orderedKeys.length; i++) {
+ String key = orderedKeys[i];
+ if (hasBubbleWithKey(key)) {
+ rankingMap.getRanking(key, mTmpRanking);
+ if (!mTmpRanking.canBubble()) {
+ doRemove(key, BubbleController.DISMISS_BLOCKED);
+ }
+ }
+ }
+ dispatchPendingChanges();
+ }
+
private void doAdd(Bubble bubble) {
if (DEBUG) {
Log.d(TAG, "doAdd: " + bubble);
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 6de0fb5..c63389a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -732,7 +732,6 @@
}
}
-
/**
* Changes the currently selected bubble. If the stack is already expanded, the newly selected
* bubble will be shown immediately. This does not change the expanded state or change the
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 9d5871e..c375574 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -169,6 +169,5 @@
public interface NotificationSettingsListener {
default void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { }
-
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
index a5a6d87..1aa6bc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification;
import android.annotation.Nullable;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.StatusBarNotification;
import com.android.internal.statusbar.NotificationVisibility;
@@ -98,4 +100,14 @@
@Nullable NotificationVisibility visibility,
boolean removedByUser) {
}
+
+ /**
+ * Called whenever notification ranking changes, in response to
+ * {@link NotificationListenerService#onNotificationRankingUpdate}. This is called after
+ * NotificationData has processed the update and notifications have been re-sorted and filtered.
+ *
+ * @param rankingMap provides access to ranking information on currently active notifications
+ */
+ default void onNotificationRankingUpdated(RankingMap rankingMap) {
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 3ac5768..e8388ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -483,6 +483,10 @@
}
updateNotifications();
+
+ for (NotificationEntryListener listener : mNotificationEntryListeners) {
+ listener.onNotificationRankingUpdated(rankingMap);
+ }
}
private void updateRankingOfPendingNotifications(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index c65e90e..35cc960 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -65,7 +65,7 @@
private val mDozeParameters: DozeParameters;
var willWakeUp = false
set(value) {
- if (value && mDozeAmount != 0.0f) {
+ if (!value || mDozeAmount != 0.0f) {
field = value
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
index 215aa77..6286d4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
@@ -35,6 +36,8 @@
private final Context mContext;
private final WindowManager mWindowManager;
private final KeyButtonView mKeyButtonView;
+ private final int mDiameter;
+ private final int mMargin;
private KeyButtonDrawable mKeyButtonDrawable;
private boolean mIsShowing;
private boolean mCanShow = true;
@@ -46,6 +49,11 @@
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mKeyButtonView = (KeyButtonView) LayoutInflater.from(mContext).inflate(
R.layout.rotate_suggestion, null);
+ mKeyButtonView.setVisibility(View.VISIBLE);
+
+ Resources resources = mContext.getResources();
+ mDiameter = resources.getDimensionPixelSize(R.dimen.floating_rotation_button_diameter);
+ mMargin = resources.getDimensionPixelSize(R.dimen.floating_rotation_button_margin);
}
@Override
@@ -66,11 +74,8 @@
mIsShowing = true;
int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
- float density = mContext.getResources().getDisplayMetrics().density;
- int diameter = (int) density * 48;
- int margin = (int) density * 4;
- final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(diameter, diameter,
- margin, margin, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags,
+ final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(mDiameter, mDiameter,
+ mMargin, mMargin, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags,
PixelFormat.TRANSLUCENT);
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
lp.setTitle("FloatingRotationButton");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index c08390f..2afe485 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -38,6 +38,7 @@
import com.android.internal.telephony.cdma.EriInfo;
import com.android.settingslib.Utils;
import com.android.settingslib.graph.SignalDrawable;
+import com.android.settingslib.net.SignalStrengthUtil;
import com.android.systemui.R;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
@@ -248,9 +249,8 @@
}
private void updateInflateSignalStrength() {
- mInflateSignalStrengths = SubscriptionManager.getResourcesForSubId(mContext,
- mSubscriptionInfo.getSubscriptionId())
- .getBoolean(R.bool.config_inflateSignalStrength);
+ mInflateSignalStrengths = SignalStrengthUtil.shouldInflateSignalStrength(mContext,
+ mSubscriptionInfo.getSubscriptionId());
}
private int getNumLevels() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index b8a14ef..b2972fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -1140,7 +1140,8 @@
res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi);
config.hspaDataDistinguishable =
res.getBoolean(R.bool.config_hspa_data_distinguishable);
- config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
+ config.inflateSignalStrengths = res.getBoolean(
+ com.android.internal.R.bool.config_inflateSignalStrength);
CarrierConfigManager configMgr = (CarrierConfigManager)
context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 4d593c1..72f3a62 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -402,6 +402,7 @@
verify(mRow).setEntry(eq(mEntry));
assertEquals(1, mEntry.systemGeneratedSmartActions.size());
assertEquals("action", mEntry.systemGeneratedSmartActions.get(0).title);
+ verify(mEntryListener).onNotificationRankingUpdated(mRankingMap);
}
@Test
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index bdbff3d..4b48ef9 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -661,12 +661,6 @@
return mTestUserKeyFile == null ? getAdbFile(ADB_KEYS_FILE) : mTestUserKeyFile;
}
- private void createKeyFile(File keyFile) throws IOException {
- keyFile.createNewFile();
- FileUtils.setPermissions(keyFile.toString(),
- FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1);
- }
-
private void writeKey(String key) {
try {
File keyFile = getUserKeyFile();
@@ -675,14 +669,13 @@
return;
}
- if (!keyFile.exists()) {
- createKeyFile(keyFile);
- }
-
FileOutputStream fo = new FileOutputStream(keyFile, true);
fo.write(key.getBytes());
fo.write('\n');
fo.close();
+
+ FileUtils.setPermissions(keyFile.toString(),
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1);
} catch (IOException ex) {
Slog.e(TAG, "Error writing key:" + ex);
}
@@ -698,10 +691,6 @@
return;
}
- if (!keyFile.exists()) {
- createKeyFile(keyFile);
- }
-
atomicKeyFile = new AtomicFile(keyFile);
fo = atomicKeyFile.startWrite();
for (String key : keys) {
@@ -709,6 +698,9 @@
fo.write('\n');
}
atomicKeyFile.finishWrite(fo);
+
+ FileUtils.setPermissions(keyFile.toString(),
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1);
} catch (IOException ex) {
Slog.e(TAG, "Error writing keys: " + ex);
if (atomicKeyFile != null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1160e33..c4eb661 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1036,19 +1036,12 @@
final StatusBarNotification n = r.sbn;
final int callingUid = n.getUid();
final String pkg = n.getPackageName();
- final boolean wasBubble = r.getNotification().isBubbleNotification();
if (isBubble && isNotificationAppropriateToBubble(r, pkg, callingUid,
null /* oldEntry */)) {
r.getNotification().flags |= FLAG_BUBBLE;
} else {
r.getNotification().flags &= ~FLAG_BUBBLE;
}
- if (wasBubble != r.getNotification().isBubbleNotification()) {
- // Add the "alert only once" flag so that the notification won't HUN
- // unnecessarily just because the bubble flag was changed.
- r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
- mListeners.notifyPostedLocked(r, r);
- }
}
}
}
@@ -2643,18 +2636,25 @@
ParceledListSlice channelsList) {
List<NotificationChannel> channels = channelsList.getList();
final int channelsSize = channels.size();
+ boolean needsPolicyFileChange = false;
for (int i = 0; i < channelsSize; i++) {
final NotificationChannel channel = channels.get(i);
Preconditions.checkNotNull(channel, "channel in list is null");
- mPreferencesHelper.createNotificationChannel(pkg, uid, channel,
- true /* fromTargetApp */, mConditionProviders.isPackageOrComponentAllowed(
+ needsPolicyFileChange = mPreferencesHelper.createNotificationChannel(pkg, uid,
+ channel, true /* fromTargetApp */,
+ mConditionProviders.isPackageOrComponentAllowed(
pkg, UserHandle.getUserId(uid)));
- mListeners.notifyNotificationChannelChanged(pkg,
- UserHandle.getUserHandleForUid(uid),
- mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(), false),
- NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
+ if (needsPolicyFileChange) {
+ mListeners.notifyNotificationChannelChanged(pkg,
+ UserHandle.getUserHandleForUid(uid),
+ mPreferencesHelper.getNotificationChannel(pkg, uid, channel.getId(),
+ false),
+ NOTIFICATION_CHANNEL_OR_GROUP_ADDED);
+ }
}
- handleSavePolicyFile();
+ if (needsPolicyFileChange) {
+ handleSavePolicyFile();
+ }
}
@Override
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 5956c65..1c0ac16 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -615,12 +615,13 @@
}
@Override
- public void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
+ public boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
boolean fromTargetApp, boolean hasDndAccess) {
Preconditions.checkNotNull(pkg);
Preconditions.checkNotNull(channel);
Preconditions.checkNotNull(channel.getId());
Preconditions.checkArgument(!TextUtils.isEmpty(channel.getName()));
+ boolean needsPolicyFileChange = false;
synchronized (mPackagePreferences) {
PackagePreferences r = getOrCreatePackagePreferencesLocked(pkg, uid);
if (r == null) {
@@ -637,17 +638,28 @@
if (existing != null && fromTargetApp) {
if (existing.isDeleted()) {
existing.setDeleted(false);
+ needsPolicyFileChange = true;
// log a resurrected channel as if it's new again
MetricsLogger.action(getChannelLog(channel, pkg).setType(
com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN));
}
- existing.setName(channel.getName().toString());
- existing.setDescription(channel.getDescription());
- existing.setBlockableSystem(channel.isBlockableSystem());
- if (existing.getGroup() == null) {
+ if (!Objects.equals(channel.getName().toString(), existing.getName().toString())) {
+ existing.setName(channel.getName().toString());
+ needsPolicyFileChange = true;
+ }
+ if (!Objects.equals(channel.getDescription(), existing.getDescription())) {
+ existing.setDescription(channel.getDescription());
+ needsPolicyFileChange = true;
+ }
+ if (channel.isBlockableSystem() != existing.isBlockableSystem()) {
+ existing.setBlockableSystem(channel.isBlockableSystem());
+ needsPolicyFileChange = true;
+ }
+ if (channel.getGroup() != null && existing.getGroup() == null) {
existing.setGroup(channel.getGroup());
+ needsPolicyFileChange = true;
}
// Apps are allowed to downgrade channel importance if the user has not changed any
@@ -656,23 +668,30 @@
if (existing.getUserLockedFields() == 0 &&
channel.getImportance() < existing.getImportance()) {
existing.setImportance(channel.getImportance());
+ needsPolicyFileChange = true;
}
// system apps and dnd access apps can bypass dnd if the user hasn't changed any
// fields on the channel yet
if (existing.getUserLockedFields() == 0 && hasDndAccess) {
boolean bypassDnd = channel.canBypassDnd();
- existing.setBypassDnd(bypassDnd);
+ if (bypassDnd != existing.canBypassDnd()) {
+ existing.setBypassDnd(bypassDnd);
+ needsPolicyFileChange = true;
- if (bypassDnd != mAreChannelsBypassingDnd
- || previousExistingImportance != existing.getImportance()) {
- updateChannelsBypassingDnd(mContext.getUserId());
+ if (bypassDnd != mAreChannelsBypassingDnd
+ || previousExistingImportance != existing.getImportance()) {
+ updateChannelsBypassingDnd(mContext.getUserId());
+ }
}
}
updateConfig();
- return;
+ return needsPolicyFileChange;
}
+
+ needsPolicyFileChange = true;
+
if (channel.getImportance() < IMPORTANCE_NONE
|| channel.getImportance() > NotificationManager.IMPORTANCE_MAX) {
throw new IllegalArgumentException("Invalid importance level");
@@ -708,6 +727,8 @@
MetricsLogger.action(getChannelLog(channel, pkg).setType(
com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_OPEN));
}
+
+ return needsPolicyFileChange;
}
void clearLockedFieldsLocked(NotificationChannel channel) {
diff --git a/services/core/java/com/android/server/notification/RankingConfig.java b/services/core/java/com/android/server/notification/RankingConfig.java
index 72502acd..5de00e4 100644
--- a/services/core/java/com/android/server/notification/RankingConfig.java
+++ b/services/core/java/com/android/server/notification/RankingConfig.java
@@ -39,7 +39,7 @@
boolean fromTargetApp);
ParceledListSlice<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
int uid, boolean includeDeleted, boolean includeNonGrouped, boolean includeEmpty);
- void createNotificationChannel(String pkg, int uid, NotificationChannel channel,
+ boolean createNotificationChannel(String pkg, int uid, NotificationChannel channel,
boolean fromTargetApp, boolean hasDndAccess);
void updateNotificationChannel(String pkg, int uid, NotificationChannel channel, boolean fromUser);
NotificationChannel getNotificationChannel(String pkg, int uid, String channelId, boolean includeDeleted);
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index eec4b70..d6e87aa 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -674,9 +674,10 @@
return new ArrayList<>();
}
- // Get the list of all dynamic shortcuts in this package
+ // Get the list of all dynamic shortcuts in this package.
final ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- findAll(shortcuts, ShortcutInfo::isDynamicVisible, ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+ findAll(shortcuts, ShortcutInfo::isDynamicVisible,
+ ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
final List<ShortcutManager.ShareShortcutInfo> result = new ArrayList<>();
for (int i = 0; i < shortcuts.size(); i++) {
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index e65eae0..54369ca 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -16,21 +16,17 @@
package com.android.server.telecom;
+import android.app.role.RoleManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
-import android.provider.Settings;
import android.telecom.DefaultDialerManager;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
@@ -221,19 +217,10 @@
private void registerDefaultAppNotifier() {
final DefaultPermissionGrantPolicy permissionPolicy = getDefaultPermissionGrantPolicy();
// Notify the package manager on default app changes
- final Uri defaultDialerAppUri = Settings.Secure.getUriFor(
- Settings.Secure.DIALER_DEFAULT_APPLICATION);
- ContentObserver contentObserver = new ContentObserver(
- new Handler(Looper.getMainLooper())) {
- @Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
- if (defaultDialerAppUri.equals(uri)) {
- updateSimCallManagerPermissions(permissionPolicy, userId);
- }
- }
- };
- mContext.getContentResolver().registerContentObserver(defaultDialerAppUri,
- false, contentObserver, UserHandle.USER_ALL);
+ final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+ roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(),
+ (roleName, user) -> updateSimCallManagerPermissions(permissionPolicy,
+ user.getIdentifier()), UserHandle.ALL);
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 3a39053..a2eb40b 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -518,8 +518,11 @@
agentInfo = mActiveAgents.valueAt(index);
}
- boolean directUnlock = resolveInfo.serviceInfo.directBootAware
- && agentInfo.settings.canUnlockProfile;
+ boolean directUnlock = false;
+ if (agentInfo.settings != null) {
+ directUnlock = resolveInfo.serviceInfo.directBootAware
+ && agentInfo.settings.canUnlockProfile;
+ }
if (directUnlock) {
if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index fa1bcac..fd3678d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -423,9 +423,7 @@
assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
assertEquals(null, si.getIntent());
assertEquals(123, si.getRank());
- assertEquals("person", si.getPersons()[0].getName());
- assertEquals("personKey", si.getPersons()[0].getKey());
- assertEquals("personUri", si.getPersons()[0].getUri());
+ assertEquals(null, si.getPersons());
assertEquals(1, si.getExtras().getInt("k"));
assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
@@ -455,6 +453,30 @@
assertEquals(456, si.getIconResourceId());
assertEquals(null, si.getIconResName());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_APP_PREDICTION);
+
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(null, si.getIcon());
+ assertEquals("title", si.getTitle());
+ assertEquals("text", si.getText());
+ assertEquals("dismes", si.getDisabledMessage());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals("person", si.getPersons()[0].getName());
+ assertEquals("personKey", si.getPersons()[0].getKey());
+ assertEquals("personUri", si.getPersons()[0].getUri());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_LONG_LIVED, si.getFlags());
+ assertEquals(null, si.getBitmapPath());
+
+ assertEquals(456, si.getIconResourceId());
+ assertEquals(null, si.getIconResName());
}
public void testShortcutInfoClone_resId() {
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 87f221a..e75a30b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -22,7 +22,6 @@
import static android.app.Notification.CATEGORY_CALL;
import static android.app.Notification.FLAG_BUBBLE;
import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
-import static android.app.Notification.FLAG_ONLY_ALERT_ONCE;
import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
@@ -1660,11 +1659,14 @@
when(mPreferencesHelper.getNotificationChannel(eq(PKG), anyInt(),
eq(channel2.getId()), anyBoolean()))
.thenReturn(channel2);
+ when(mPreferencesHelper.createNotificationChannel(eq(PKG), anyInt(),
+ eq(channel2), anyBoolean(), anyBoolean()))
+ .thenReturn(true);
reset(mListeners);
mBinderService.createNotificationChannels(PKG,
new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
- verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
+ verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
@@ -4963,13 +4965,10 @@
mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), false);
waitForIdle();
- // Make sure we are not a bubble / reported as such to listeners
- ArgumentCaptor<NotificationRecord> captor =
- ArgumentCaptor.forClass(NotificationRecord.class);
- verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
-
- assertEquals((captor.getValue().getNotification().flags & FLAG_BUBBLE), 0);
- assertTrue((captor.getValue().getNotification().flags & FLAG_ONLY_ALERT_ONCE) != 0);
+ // Make sure we are not a bubble
+ StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+ assertEquals(1, notifsAfter.length);
+ assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
}
@Test
@@ -5000,13 +4999,10 @@
mService.mNotificationDelegate.onNotificationBubbleChanged(nr.getKey(), true);
waitForIdle();
- // Make sure we are a bubble / reported as such to listeners
- ArgumentCaptor<NotificationRecord> captor =
- ArgumentCaptor.forClass(NotificationRecord.class);
- verify(mListeners, times(1)).notifyPostedLocked(captor.capture(), any());
-
- assertTrue((captor.getValue().getNotification().flags & FLAG_BUBBLE) != 0);
- assertTrue((captor.getValue().getNotification().flags & FLAG_ONLY_ALERT_ONCE) != 0);
+ // Make sure we are a bubble
+ StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
+ assertEquals(1, notifsAfter.length);
+ assertTrue((notifsAfter[0].getNotification().flags & FLAG_BUBBLE) != 0);
}
@Test
@@ -5037,7 +5033,6 @@
StatusBarNotification[] notifsAfter = mBinderService.getActiveNotifications(PKG);
assertEquals(1, notifsAfter.length);
assertEquals((notifsAfter[0].getNotification().flags & FLAG_BUBBLE), 0);
- verify(mListeners, times(0)).notifyPostedLocked(any(), any());
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index a0660c4..8f8b746 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -262,13 +262,13 @@
int uid0 = 1001;
setUpPackageWithUid(package0, uid0);
NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(package0, uid0, channel0, true, false);
+ assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
String package10 = "test.package.user10";
int uid10 = 1001001;
setUpPackageWithUid(package10, uid10);
NotificationChannel channel10 = new NotificationChannel("id10", "name10", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(package10, uid10, channel10, true, false);
+ assertTrue(mHelper.createNotificationChannel(package10, uid10, channel10, true, false));
ByteArrayOutputStream baos = writeXmlAndPurge(package10, uid10, true, 10);
@@ -293,7 +293,7 @@
int uid0 = 1001;
setUpPackageWithUid(package0, uid0);
NotificationChannel channel0 = new NotificationChannel("id0", "name0", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(package0, uid0, channel0, true, false);
+ assertTrue(mHelper.createNotificationChannel(package0, uid0, channel0, true, false));
ByteArrayOutputStream baos = writeXmlAndPurge(package0, uid0, true, 0);
@@ -334,8 +334,8 @@
mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg, true);
mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, ncg2, true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false));
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, false, false));
mHelper.setShowBadge(PKG_N_MR1, UID_N_MR1, true);
mHelper.setAppImportanceLocked(PKG_N_MR1, UID_N_MR1);
@@ -716,8 +716,8 @@
public void testCreateChannel_blocked() throws Exception {
mHelper.setImportance(PKG_N_MR1, UID_N_MR1, IMPORTANCE_NONE);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_LOW), true, false));
}
@Test
@@ -746,10 +746,10 @@
} catch (IllegalArgumentException e) {
// yay
}
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
- new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_NONE), true, false));
+ assertFalse(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1,
+ new NotificationChannel("bananas", "bananas", IMPORTANCE_MAX), true, false));
}
@@ -763,7 +763,7 @@
channel.setBypassDnd(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, false, false));
// same id, try to update all fields
final NotificationChannel channel2 =
@@ -776,7 +776,8 @@
mHelper.updateNotificationChannel(PKG_N_MR1, UID_N_MR1, channel2, true);
// all fields should be changed
- assertEquals(channel2, mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
+ assertEquals(channel2,
+ mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false));
verify(mHandler, times(1)).requestSort();
}
@@ -894,7 +895,7 @@
}
channel.lockFields(lockMask);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
NotificationChannel savedChannel =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, channel.getId(), false);
@@ -1469,13 +1470,18 @@
new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
channel.setVibrationPattern(vibration);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel, true, false));
NotificationChannel newChannel = new NotificationChannel(
channel.getId(), channel.getName(), NotificationManager.IMPORTANCE_HIGH);
newChannel.setVibrationPattern(new long[]{100});
+ newChannel.setAllowBubbles(!channel.canBubble());
+ newChannel.setLightColor(Color.BLUE);
+ newChannel.setSound(Uri.EMPTY, null);
+ newChannel.setShowBadge(!channel.canShowBadge());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, newChannel, true, false);
+ assertFalse(mHelper.createNotificationChannel(
+ PKG_N_MR1, UID_N_MR1, newChannel, true, false));
// Old settings not overridden
compareChannels(channel,
@@ -1588,16 +1594,17 @@
new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
- UID_N_MR1});
+ assertTrue(mHelper.onPackagesChanged(true, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1},
+ new int[]{UID_N_MR1}));
- assertEquals(0, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, true).getList().size());
+ assertEquals(0, mHelper.getNotificationChannels(
+ PKG_N_MR1, UID_N_MR1, true).getList().size());
// Not deleted
mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, channel1, true, false);
- mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM, new String[]{PKG_N_MR1}, new int[]{
- UID_N_MR1});
+ assertFalse(mHelper.onPackagesChanged(false, UserHandle.USER_SYSTEM,
+ new String[]{PKG_N_MR1}, new int[]{UID_N_MR1}));
assertEquals(2, mHelper.getNotificationChannels(PKG_N_MR1, UID_N_MR1, false).getList().size());
}
@@ -1825,13 +1832,13 @@
@Test
public void testCreateChannel_updateName() {
NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
NotificationChannel actual =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertEquals("hello", actual.getName());
nc = new NotificationChannel("id", "goodbye", IMPORTANCE_HIGH);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertEquals("goodbye", actual.getName());
@@ -1845,14 +1852,14 @@
NotificationChannelGroup group = new NotificationChannelGroup("group", "");
mHelper.createNotificationChannelGroup(PKG_N_MR1, UID_N_MR1, group, true);
NotificationChannel nc = new NotificationChannel("id", "hello", IMPORTANCE_DEFAULT);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
NotificationChannel actual =
mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertNull(actual.getGroup());
nc = new NotificationChannel("id", "hello", IMPORTANCE_HIGH);
nc.setGroup(group.getId());
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, nc, true, false));
actual = mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "id", false);
assertNotNull(actual.getGroup());
@@ -2109,7 +2116,7 @@
NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
update.setBypassDnd(true);
- mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false);
+ assertFalse(mHelper.createNotificationChannel(SYSTEM_PKG, SYSTEM_UID, update, true, false));
assertFalse(mHelper.getNotificationChannel(SYSTEM_PKG, SYSTEM_UID, "A", false)
.canBypassDnd());
@@ -2122,7 +2129,7 @@
NotificationChannel update = new NotificationChannel("A", "a", IMPORTANCE_LOW);
update.setBypassDnd(true);
- mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true);
+ assertTrue(mHelper.createNotificationChannel(PKG_N_MR1, UID_N_MR1, update, true, true));
assertTrue(mHelper.getNotificationChannel(PKG_N_MR1, UID_N_MR1, "A", false).canBypassDnd());
}
diff --git a/services/usb/java/com/android/server/usb/UsbSerialReader.java b/services/usb/java/com/android/server/usb/UsbSerialReader.java
index 32fc796..8ca77f0 100644
--- a/services/usb/java/com/android/server/usb/UsbSerialReader.java
+++ b/services/usb/java/com/android/server/usb/UsbSerialReader.java
@@ -85,22 +85,22 @@
throw new RemoteException("package " + packageName + " cannot be found");
}
packageTargetSdkVersion = pkg.applicationInfo.targetSdkVersion;
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- if (packageTargetSdkVersion >= Build.VERSION_CODES.Q) {
- if (mContext.checkPermission(android.Manifest.permission.MANAGE_USB, pid, uid)
- == PackageManager.PERMISSION_DENIED) {
- UsbUserSettingsManager settings = mSettingsManager.getSettingsForUser(
- UserHandle.getUserId(uid));
+ if (packageTargetSdkVersion >= Build.VERSION_CODES.Q) {
+ if (mContext.checkPermission(android.Manifest.permission.MANAGE_USB, pid, uid)
+ == PackageManager.PERMISSION_DENIED) {
+ UsbUserSettingsManager settings = mSettingsManager.getSettingsForUser(
+ UserHandle.getUserId(uid));
- if (mDevice instanceof UsbDevice) {
- settings.checkPermission((UsbDevice) mDevice, packageName, uid);
- } else {
- settings.checkPermission((UsbAccessory) mDevice, uid);
+ if (mDevice instanceof UsbDevice) {
+ settings.checkPermission((UsbDevice) mDevice, packageName, uid);
+ } else {
+ settings.checkPermission((UsbAccessory) mDevice, uid);
+ }
}
}
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index 7b51457..511adf6 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -299,7 +299,7 @@
* Get the dialing number of the emergency number.
*
* The character in the number string is only the dial pad
- * character('0'-'9', '*', or '#'). For example: 911.
+ * character('0'-'9', '*', '+', or '#'). For example: 911.
*
* @return the dialing number.
*/