Merge "Fix build breakage"
diff --git a/api/current.txt b/api/current.txt
index 76a2289..1228db8 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -33513,6 +33513,7 @@
field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
field public static final java.lang.String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
+ field public static final java.lang.String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
@@ -33565,8 +33566,10 @@
field public static final java.lang.String AUTHORITY = "settings";
field public static final java.lang.String EXTRA_ACCOUNT_TYPES = "account_types";
field public static final java.lang.String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled";
+ field public static final java.lang.String EXTRA_APP_PACKAGE = "android.provider.extra.APP_PACKAGE";
field public static final java.lang.String EXTRA_AUTHORITIES = "authorities";
field public static final java.lang.String EXTRA_BATTERY_SAVER_MODE_ENABLED = "android.settings.extra.battery_saver_mode_enabled";
+ field public static final java.lang.String EXTRA_CHANNEL_ID = "android.provider.extra.CHANNEL_ID";
field public static final java.lang.String EXTRA_DO_NOT_DISTURB_MODE_ENABLED = "android.settings.extra.do_not_disturb_mode_enabled";
field public static final java.lang.String EXTRA_DO_NOT_DISTURB_MODE_MINUTES = "android.settings.extra.do_not_disturb_mode_minutes";
field public static final java.lang.String EXTRA_INPUT_METHOD_ID = "input_method_id";
@@ -46207,6 +46210,13 @@
field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillId> CREATOR;
}
+ public final class AutoFillManager {
+ method public void updateAutoFillInput(android.view.View, int);
+ method public void updateAutoFillInput(android.view.View, int, android.graphics.Rect, int);
+ field public static final int FLAG_UPDATE_UI_HIDE = 2; // 0x2
+ field public static final int FLAG_UPDATE_UI_SHOW = 1; // 0x1
+ }
+
public final class AutoFillType implements android.os.Parcelable {
method public int describeContents();
method public static android.view.autofill.AutoFillType forList();
@@ -46266,7 +46276,7 @@
public static abstract class VirtualViewDelegate.Callback {
ctor public VirtualViewDelegate.Callback();
- method public void onFocusChanged(int, boolean);
+ method public void onAutoFillInputUpdated(int, android.graphics.Rect, int);
method public void onNodeRemoved(int...);
method public void onValueChanged(int);
}
diff --git a/api/system-current.txt b/api/system-current.txt
index bda634f..4698a68 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -36504,6 +36504,7 @@
field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
field public static final java.lang.String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
+ field public static final java.lang.String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
field public static final java.lang.String ACTION_CONFIGURE_WIFI_SETTINGS = "android.settings.CONFIGURE_WIFI_SETTINGS";
field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
@@ -36559,8 +36560,10 @@
field public static final java.lang.String AUTHORITY = "settings";
field public static final java.lang.String EXTRA_ACCOUNT_TYPES = "account_types";
field public static final java.lang.String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled";
+ field public static final java.lang.String EXTRA_APP_PACKAGE = "android.provider.extra.APP_PACKAGE";
field public static final java.lang.String EXTRA_AUTHORITIES = "authorities";
field public static final java.lang.String EXTRA_BATTERY_SAVER_MODE_ENABLED = "android.settings.extra.battery_saver_mode_enabled";
+ field public static final java.lang.String EXTRA_CHANNEL_ID = "android.provider.extra.CHANNEL_ID";
field public static final java.lang.String EXTRA_DO_NOT_DISTURB_MODE_ENABLED = "android.settings.extra.do_not_disturb_mode_enabled";
field public static final java.lang.String EXTRA_DO_NOT_DISTURB_MODE_MINUTES = "android.settings.extra.do_not_disturb_mode_minutes";
field public static final java.lang.String EXTRA_INPUT_METHOD_ID = "input_method_id";
@@ -49592,6 +49595,13 @@
field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillId> CREATOR;
}
+ public final class AutoFillManager {
+ method public void updateAutoFillInput(android.view.View, int);
+ method public void updateAutoFillInput(android.view.View, int, android.graphics.Rect, int);
+ field public static final int FLAG_UPDATE_UI_HIDE = 2; // 0x2
+ field public static final int FLAG_UPDATE_UI_SHOW = 1; // 0x1
+ }
+
public final class AutoFillType implements android.os.Parcelable {
method public int describeContents();
method public static android.view.autofill.AutoFillType forList();
@@ -49651,7 +49661,7 @@
public static abstract class VirtualViewDelegate.Callback {
ctor public VirtualViewDelegate.Callback();
- method public void onFocusChanged(int, boolean);
+ method public void onAutoFillInputUpdated(int, android.graphics.Rect, int);
method public void onNodeRemoved(int...);
method public void onValueChanged(int);
}
diff --git a/api/test-current.txt b/api/test-current.txt
index c6de2e4..15844cd 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -33629,6 +33629,7 @@
field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
field public static final java.lang.String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
+ field public static final java.lang.String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
field public static final java.lang.String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
field public static final java.lang.String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
field public static final java.lang.String ACTION_DEVICE_INFO_SETTINGS = "android.settings.DEVICE_INFO_SETTINGS";
@@ -33682,8 +33683,10 @@
field public static final java.lang.String AUTHORITY = "settings";
field public static final java.lang.String EXTRA_ACCOUNT_TYPES = "account_types";
field public static final java.lang.String EXTRA_AIRPLANE_MODE_ENABLED = "airplane_mode_enabled";
+ field public static final java.lang.String EXTRA_APP_PACKAGE = "android.provider.extra.APP_PACKAGE";
field public static final java.lang.String EXTRA_AUTHORITIES = "authorities";
field public static final java.lang.String EXTRA_BATTERY_SAVER_MODE_ENABLED = "android.settings.extra.battery_saver_mode_enabled";
+ field public static final java.lang.String EXTRA_CHANNEL_ID = "android.provider.extra.CHANNEL_ID";
field public static final java.lang.String EXTRA_DO_NOT_DISTURB_MODE_ENABLED = "android.settings.extra.do_not_disturb_mode_enabled";
field public static final java.lang.String EXTRA_DO_NOT_DISTURB_MODE_MINUTES = "android.settings.extra.do_not_disturb_mode_minutes";
field public static final java.lang.String EXTRA_INPUT_METHOD_ID = "input_method_id";
@@ -46517,6 +46520,13 @@
field public static final android.os.Parcelable.Creator<android.view.autofill.AutoFillId> CREATOR;
}
+ public final class AutoFillManager {
+ method public void updateAutoFillInput(android.view.View, int);
+ method public void updateAutoFillInput(android.view.View, int, android.graphics.Rect, int);
+ field public static final int FLAG_UPDATE_UI_HIDE = 2; // 0x2
+ field public static final int FLAG_UPDATE_UI_SHOW = 1; // 0x1
+ }
+
public final class AutoFillType implements android.os.Parcelable {
method public int describeContents();
method public static android.view.autofill.AutoFillType forList();
@@ -46576,7 +46586,7 @@
public static abstract class VirtualViewDelegate.Callback {
ctor public VirtualViewDelegate.Callback();
- method public void onFocusChanged(int, boolean);
+ method public void onAutoFillInputUpdated(int, android.graphics.Rect, int);
method public void onNodeRemoved(int...);
method public void onValueChanged(int);
}
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 3cb920a..3902bd6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -698,6 +698,13 @@
}
/**
+ * Returns true if the input stack is affected by drag resizing.
+ */
+ public static boolean isStackAffectedByDragResizing(int stackId) {
+ return isStaticStack(stackId) && stackId != PINNED_STACK_ID;
+ }
+
+ /**
* Returns true if the windows of tasks being moved to the target stack from the source
* stack should be replaced, meaning that window manager will keep the old window around
* until the new is ready.
diff --git a/core/java/android/app/IUiModeManager.aidl b/core/java/android/app/IUiModeManager.aidl
index 848464c..7f0b6fb 100644
--- a/core/java/android/app/IUiModeManager.aidl
+++ b/core/java/android/app/IUiModeManager.aidl
@@ -58,11 +58,16 @@
void setTheme(String theme);
/**
- * Gets whith theme overlays to use within /vendor/overlay.
+ * Gets which theme overlays to use within /vendor/overlay.
*/
String getTheme();
/**
+ * Gets the themes available in /vendor/overlay.
+ */
+ String[] getAvailableThemes();
+
+ /**
* Tells if UI mode is locked or not.
*/
boolean isUiModeLocked();
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3270349..b4fe6b8 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -46,6 +46,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.BidiFormatter;
import android.text.SpannableStringBuilder;
@@ -2427,6 +2428,9 @@
private static final int MAX_ACTION_BUTTONS = 3;
+ private static final boolean USE_ONLY_TITLE_IN_LOW_PRIORITY_SUMMARY =
+ SystemProperties.getBoolean("notifications.only_title", true);
+
private Context mContext;
private Notification mN;
private Bundle mUserExtras = new Bundle();
@@ -3760,7 +3764,7 @@
} else if (mActions.size() != 0) {
result = applyStandardTemplateWithActions(getBigBaseLayoutResource());
}
- adaptNotificationHeaderForBigContentView(result);
+ makeHeaderExpanded(result);
return result;
}
@@ -3795,7 +3799,12 @@
}
}
- private void adaptNotificationHeaderForBigContentView(RemoteViews result) {
+ /**
+ * Adapt the Notification header if this view is used as an expanded view.
+ *
+ * @hide
+ */
+ public static void makeHeaderExpanded(RemoteViews result) {
if (result != null) {
result.setBoolean(R.id.notification_header, "setExpanded", true);
}
@@ -3855,7 +3864,57 @@
return publicView;
}
+ /**
+ * Construct a content view for the display when low - priority
+ *
+ * @param useRegularSubtext uses the normal subtext set if there is one available. Otherwise
+ * a new subtext is created consisting of the content of the
+ * notification.
+ * @hide
+ */
+ public RemoteViews makeLowPriorityContentView(boolean useRegularSubtext) {
+ int color = mN.color;
+ mN.color = COLOR_DEFAULT;
+ CharSequence summary = mN.extras.getCharSequence(EXTRA_SUB_TEXT);
+ if (!useRegularSubtext || TextUtils.isEmpty(summary)) {
+ CharSequence newSummary = createSummaryText();
+ if (!TextUtils.isEmpty(newSummary)) {
+ mN.extras.putCharSequence(EXTRA_SUB_TEXT, newSummary);
+ }
+ }
+ RemoteViews header = makeNotificationHeader();
+ if (summary != null) {
+ mN.extras.putCharSequence(EXTRA_SUB_TEXT, summary);
+ } else {
+ mN.extras.remove(EXTRA_SUB_TEXT);
+ }
+ mN.color = color;
+ return header;
+ }
+ private CharSequence createSummaryText() {
+ CharSequence titleText = mN.extras.getCharSequence(Notification.EXTRA_TITLE);
+ if (USE_ONLY_TITLE_IN_LOW_PRIORITY_SUMMARY) {
+ return titleText;
+ }
+ SpannableStringBuilder summary = new SpannableStringBuilder();
+ if (titleText == null) {
+ titleText = mN.extras.getCharSequence(Notification.EXTRA_TITLE_BIG);
+ }
+ BidiFormatter bidi = BidiFormatter.getInstance();
+ if (titleText != null) {
+ summary.append(bidi.unicodeWrap(titleText));
+ }
+ CharSequence contentText = mN.extras.getCharSequence(Notification.EXTRA_TEXT);
+ if (titleText != null && contentText != null) {
+ summary.append(bidi.unicodeWrap(mContext.getText(
+ R.string.notification_header_divider_symbol_with_spaces)));
+ }
+ if (contentText != null) {
+ summary.append(bidi.unicodeWrap(contentText));
+ }
+ return summary;
+ }
private RemoteViews generateActionButton(Action action, boolean emphazisedMode,
boolean oddAction, boolean ambient) {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 5d8909c..5a75a67 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -112,6 +112,7 @@
import android.os.storage.StorageManager;
import android.print.IPrintManager;
import android.print.PrintManager;
+import android.service.autofill.IAutoFillManagerService;
import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
import android.telecom.TelecomManager;
@@ -126,6 +127,7 @@
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.CaptioningManager;
+import android.view.autofill.AutoFillManager;
import android.view.inputmethod.InputMethodManager;
import android.view.textclassifier.TextClassificationManager;
import android.view.textservice.TextServicesManager;
@@ -804,6 +806,14 @@
IBinder b = ServiceManager.getServiceOrThrow(Context.FONT_SERVICE);
return new FontManager(IFontManager.Stub.asInterface(b));
}});
+ registerService(Context.AUTO_FILL_MANAGER_SERVICE, AutoFillManager.class,
+ new CachedServiceFetcher<AutoFillManager>() {
+ @Override
+ public AutoFillManager createService(ContextImpl ctx) throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(Context.AUTO_FILL_MANAGER_SERVICE);
+ IAutoFillManagerService service = IAutoFillManagerService.Stub.asInterface(b);
+ return new AutoFillManager(ctx, service);
+ }});
}
/**
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
index 2572a20..af41a7d 100644
--- a/core/java/android/app/UiModeManager.java
+++ b/core/java/android/app/UiModeManager.java
@@ -271,6 +271,21 @@
}
/**
+ * Gets the valid inputs to {@link #setTheme(String)}.
+ * @hide
+ */
+ public String[] getAvailableThemes() {
+ if (mService != null) {
+ try {
+ return mService.getAvailableThemes();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns the currently configured night mode.
* <p>
* May be one of:
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 9e2d4a7..b92d293 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -30,6 +30,7 @@
import android.app.ActivityThread;
import android.app.AppOpsManager;
import android.app.Application;
+import android.app.NotificationChannel;
import android.app.SearchManager;
import android.app.WallpaperManager;
import android.content.ComponentName;
@@ -1274,6 +1275,7 @@
/**
* Activity Action: Show notification settings for a single app.
*
+ * Input: Optionally, {@link #EXTRA_CHANNEL_ID}, to highlight that channel.
* @hide
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@@ -1281,6 +1283,35 @@
= "android.settings.APP_NOTIFICATION_SETTINGS";
/**
+ * Activity Action: Show notification settings for a single {@link NotificationChannel}.
+ * <p>
+ * Must be called from an activity.
+ * <p>
+ * Input: {@link #EXTRA_APP_PACKAGE}, the package containing the channel to display.
+ * Input: {@link #EXTRA_CHANNEL_ID}, the id of the channel to display.
+ * <p>
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_CHANNEL_NOTIFICATION_SETTINGS
+ = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
+
+ /**
+ * Activity Extra: The package owner of the notification channel settings to display.
+ * <p>
+ * This must be passed as an extra field to the {@link #ACTION_CHANNEL_NOTIFICATION_SETTINGS}.
+ */
+ public static final String EXTRA_APP_PACKAGE = "android.provider.extra.APP_PACKAGE";
+
+ /**
+ * Activity Extra: The {@link NotificationChannel#getId()} of the notification channel settings
+ * to display.
+ * <p>
+ * This must be passed as an extra field to the {@link #ACTION_CHANNEL_NOTIFICATION_SETTINGS}.
+ */
+ public static final String EXTRA_CHANNEL_ID = "android.provider.extra.CHANNEL_ID";
+
+ /**
* Activity Action: Show notification redaction settings.
*
* @hide
@@ -1290,7 +1321,6 @@
= "android.settings.ACTION_APP_NOTIFICATION_REDACTION";
/** @hide */ public static final String EXTRA_APP_UID = "app_uid";
- /** @hide */ public static final String EXTRA_APP_PACKAGE = "app_package";
/**
* Activity Action: Show a dialog with disabled by policy message.
diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/service/autofill/AutoFillService.java
index 805d8e5..c7c8321 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/service/autofill/AutoFillService.java
@@ -15,8 +15,6 @@
*/
package android.service.autofill;
-import static android.service.voice.VoiceInteractionSession.KEY_FLAGS;
-import static android.service.voice.VoiceInteractionSession.KEY_STRUCTURE;
import static android.view.View.AUTO_FILL_FLAG_TYPE_FILL;
import static android.view.View.AUTO_FILL_FLAG_TYPE_SAVE;
@@ -30,13 +28,11 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
-import android.os.RemoteException;
import android.util.Log;
import android.view.autofill.AutoFillId;
import android.view.autofill.FillResponse;
import com.android.internal.os.HandlerCaller;
-import com.android.internal.os.IResultReceiver;
import com.android.internal.os.SomeArgs;
// TODO(b/33197203): improve javadoc (of both class and methods); in particular, make sure the
@@ -49,8 +45,8 @@
*/
public abstract class AutoFillService extends Service {
- static final String TAG = "AutoFillService";
- static final boolean DEBUG = true; // TODO: set to false once stable
+ private static final String TAG = "AutoFillService";
+ static final boolean DEBUG = true; // TODO(b/33197203): set to false once stable
/**
* The {@link Intent} that must be declared as handled by the service.
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 5a9a9f6..925da8b 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -21,7 +21,6 @@
import android.annotation.Nullable;
import android.app.Activity;
import android.os.Bundle;
-import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.autofill.FillResponse;
diff --git a/core/java/android/service/autofill/IAutoFillManagerService.aidl b/core/java/android/service/autofill/IAutoFillManagerService.aidl
index f8ae57b..ce42107 100644
--- a/core/java/android/service/autofill/IAutoFillManagerService.aidl
+++ b/core/java/android/service/autofill/IAutoFillManagerService.aidl
@@ -16,7 +16,9 @@
package android.service.autofill;
+import android.graphics.Rect;
import android.os.Bundle;
+import android.view.autofill.AutoFillId;
/**
* Mediator between apps being auto-filled and auto-fill service implementations.
@@ -24,5 +26,9 @@
* {@hide}
*/
oneway interface IAutoFillManagerService {
+
+ void showAutoFillInput(in AutoFillId id, in Rect boundaries);
+
+ // TODO(b/33197203): remove it and refactor onShellCommand
void requestAutoFill(IBinder activityToken, int userId, in Bundle extras, int flags);
}
diff --git a/core/java/android/service/autofill/SaveCallback.java b/core/java/android/service/autofill/SaveCallback.java
index 627d74c..04f8c9f 100644
--- a/core/java/android/service/autofill/SaveCallback.java
+++ b/core/java/android/service/autofill/SaveCallback.java
@@ -21,7 +21,6 @@
import android.app.Activity;
import android.app.assist.AssistStructure.ViewNode;
import android.os.Bundle;
-import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.autofill.AutoFillId;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 547f7d8..15b62a2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1765,6 +1765,12 @@
*/
int mAccessibilityViewId = NO_ID;
+ /**
+ * The stable ID of this view for auto-fill purposes.
+ */
+ private int mAutoFillId = NO_ID;
+
+
private int mAccessibilityCursorPosition = ACCESSIBILITY_CURSOR_POSITION_UNDEFINED;
SendViewStateChangedAccessibilityEvent mSendViewStateChangedAccessibilityEvent;
@@ -6932,8 +6938,8 @@
if (forAutoFill) {
// The auto-fill id needs to be unique, but its value doesn't matter, so it's better to
// reuse the accessibility id to save space.
- structure.setAutoFillId(getAccessibilityViewId());
-
+ mAutoFillId = getAccessibilityViewId();
+ structure.setAutoFillId(mAutoFillId);
structure.setAutoFillType(getAutoFillType());
}
@@ -7063,7 +7069,7 @@
}
/**
- * Describes the auto-fill type that should be used on callas to
+ * Describes the auto-fill type that should be used on calls to
* {@link #autoFill(AutoFillValue)} and
* {@link VirtualViewDelegate#autoFill(int, AutoFillValue)}.
*
@@ -7560,6 +7566,20 @@
}
/**
+ * Gets the unique identifier of this view for auto-fill purposes.
+ *
+ * <p>It's only set after {@link #onProvideAutoFillStructure(ViewStructure, int)} is called.
+ *
+ * @return The view autofill id or {@link #NO_ID} if
+ * {@link #onProvideAutoFillStructure(ViewStructure, int)} was not called yet.
+ *
+ * @hide
+ */
+ public int getAutoFillViewId() {
+ return mAutoFillId;
+ }
+
+ /**
* Gets the unique identifier of the window in which this View reseides.
*
* @return The window accessibility id.
diff --git a/core/java/android/view/autofill/AutoFillId.java b/core/java/android/view/autofill/AutoFillId.java
index b7b694d..e9c1c3b 100644
--- a/core/java/android/view/autofill/AutoFillId.java
+++ b/core/java/android/view/autofill/AutoFillId.java
@@ -43,6 +43,13 @@
}
/** @hide */
+ public AutoFillId(int parentId, int virtualChildId) {
+ mVirtual = true;
+ mViewId = parentId;
+ mVirtualId = virtualChildId;
+ }
+
+ /** @hide */
public int getViewId() {
return mViewId;
}
diff --git a/core/java/android/view/autofill/AutoFillManager.java b/core/java/android/view/autofill/AutoFillManager.java
new file mode 100644
index 0000000..cd9842f
--- /dev/null
+++ b/core/java/android/view/autofill/AutoFillManager.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.autofill;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.service.autofill.IAutoFillManagerService;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * App entry point to the AutoFill Framework.
+ */
+// TODO(b/33197203): improve this javadoc
+public final class AutoFillManager {
+
+ private static final String TAG = "AutoFillManager";
+ private static final boolean DEBUG = true; // TODO(b/33197203): change to false once stable
+
+ /**
+ * Flag used to show the auto-fill UI affordance for a view.
+ */
+ public static final int FLAG_UPDATE_UI_SHOW = 1 << 0;
+
+ /**
+ * Flag used to hide the auto-fill UI affordance for a view.
+ */
+ public static final int FLAG_UPDATE_UI_HIDE = 1 << 1;
+
+ private final IAutoFillManagerService mService;
+
+ /**
+ * @hide
+ */
+ public AutoFillManager(@SuppressWarnings("unused") Context context,
+ IAutoFillManagerService service) {
+ mService = service;
+ }
+
+ /**
+ * Updates the auto-fill bar for a given {@link View}.
+ *
+ * <b>Typically called twice, with different flags ({@link #FLAG_UPDATE_UI_SHOW} and
+ * {@link #FLAG_UPDATE_UI_HIDE} respectively), as the user "entered" and "exited" a view.
+ *
+ * @param view view to be updated.
+ * @param flags either {@link #FLAG_UPDATE_UI_SHOW} or
+ * {@link #FLAG_UPDATE_UI_HIDE}.
+ */
+ public void updateAutoFillInput(View view, int flags) {
+ if (DEBUG) {
+ Log.v(TAG, "updateAutoFillInput(" + view.getAutoFillViewId() + "): flags=" + flags);
+ }
+
+ updateAutoFillInput(view, false, View.NO_ID, null, flags);
+ }
+
+ /**
+ * Updates the auto-fill bar for a virtual child of a given {@link View}.
+ *
+ * <b>Typically called twice, with different flags ({@link #FLAG_UPDATE_UI_SHOW} and
+ * {@link #FLAG_UPDATE_UI_HIDE} respectively), as the user "entered" and "exited" a view.
+ *
+ * @param parent parent view.
+ * @param childId id identifying the virtual child inside the parent view.
+ * @param boundaries boundaries of the child (inside the parent; could be {@code null} when
+ * flag is {@link #FLAG_UPDATE_UI_HIDE}.
+ * @param flags either {@link #FLAG_UPDATE_UI_SHOW} or
+ * {@link #FLAG_UPDATE_UI_HIDE}.
+ */
+ public void updateAutoFillInput(View parent, int childId, @Nullable Rect boundaries,
+ int flags) {
+ if (DEBUG) {
+ Log.v(TAG, "updateAutoFillInput(" + parent.getAutoFillViewId() + ", " + childId
+ + "): boundaries=" + boundaries + ", flags=" + flags);
+ }
+ updateAutoFillInput(parent, true, childId, boundaries, flags);
+ }
+
+ private void updateAutoFillInput(View view, boolean virtual, int childId, Rect boundaries,
+ int flags) {
+ if ((flags & FLAG_UPDATE_UI_SHOW) != 0) {
+ final int viewId = view.getAutoFillViewId();
+ final AutoFillId id = virtual
+ ? new AutoFillId(viewId, childId)
+ : new AutoFillId(viewId);
+ showAutoFillInput(id, boundaries);
+ return;
+ }
+ // TODO(b/33197203): handle FLAG_UPDATE_UI_HIDE
+ }
+
+ private void showAutoFillInput(AutoFillId id, Rect boundaries) {
+ final int autoFillViewId = id.getViewId();
+ /*
+ * TODO(b/33197203): currently SHOW_AUTO_FILL_BAR is only set once per activity (i.e, when
+ * the view does not have an auto-fill id), but it should be called again for views that
+ * were not part of the initial auto-fill dataset returned by the service. For example:
+ *
+ * 1.Activity has 4 fields, `first_name`, `last_name`, and `address`.
+ * 2.User taps `first_name`.
+ * 3.Service returns a dataset with ids for `first_name` and `last_name`.
+ * 4.When user taps `first_name` (again) or `last_name`, flag should not have
+ * SHOW_AUTO_FILL_BAR set, but when user taps `address`, it should (since that field was
+ * not part of the initial dataset).
+ *
+ * Similarly, once the activity is auto-filled, the flag logic should be reset (so if the
+ * user taps the view again, a new auto-fill request is made)
+ */
+ if (autoFillViewId != View.NO_ID) {
+ return;
+ }
+
+ try {
+ mService.showAutoFillInput(id, boundaries);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+}
diff --git a/core/java/android/view/autofill/VirtualViewDelegate.java b/core/java/android/view/autofill/VirtualViewDelegate.java
index a19b4e5..278bf4f 100644
--- a/core/java/android/view/autofill/VirtualViewDelegate.java
+++ b/core/java/android/view/autofill/VirtualViewDelegate.java
@@ -15,6 +15,8 @@
*/
package android.view.autofill;
+import android.annotation.Nullable;
+import android.graphics.Rect;
import android.util.Log;
import android.view.View;
import android.view.ViewStructure;
@@ -71,20 +73,18 @@
public abstract static class Callback {
/**
- * Sent when the focus inside the hierarchy changed.
+ * Sent when the auto-fill bar for a child must be updated.
*
- * <p>Typically callled twice - for the nodes that lost and gained focus.
- *
- * <p>This method should only be called when the change was not caused by the AutoFill
- * Framework itselft (i.e, through {@link VirtualViewDelegate#autoFill(int, AutoFillValue)},
- * but by external causes (for example, when the user changed the value through the view's
- * UI).
- *
- * @param virtualId id of the node whose focus changed.
- * @param hasFocus {@code true} when focus was gained, {@code false} when it was lost.
+ * See {@link AutoFillManager#updateAutoFillInput(View, int, android.graphics.Rect, int)}
+ * for more details.
*/
- public void onFocusChanged(int virtualId, boolean hasFocus) {
- if (DEBUG) Log.d(TAG, "onFocusChanged() for " + virtualId + ": " + hasFocus);
+ // TODO(b/33197203): do we really need it, or should the parent view just call
+ // AutoFillManager.updateAutoFillInput() directly?
+ public void onAutoFillInputUpdated(int virtualId, @Nullable Rect boundaries, int flags) {
+ if (DEBUG) {
+ Log.v(TAG, "onAutoFillInputUpdated(): virtualId=" + virtualId + ", boundaries="
+ + boundaries + ", flags=" + flags);
+ }
}
/**
diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java
index faf0379..6706790 100644
--- a/core/java/android/widget/EditText.java
+++ b/core/java/android/widget/EditText.java
@@ -169,8 +169,6 @@
Log.w(VIEW_LOG_TAG, "EditText.autoFill(): no text on AutoFillValue");
return;
}
- // TODO(b/33197203): once auto-fill is triggered by the IME, we'll need a new setText()
- // or setAutoFillText() method on TextView to avoid re-triggering it.
setText(text);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a11ece6..072fe4a 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -136,6 +136,7 @@
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
+import android.view.autofill.AutoFillManager;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
@@ -264,6 +265,7 @@
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
static final String LOG_TAG = "TextView";
static final boolean DEBUG_EXTRACT = false;
+ static final boolean DEBUG_AUTOFILL = false;
// Enum for the "typeface" XML parameter.
// TODO: How can we get this from the XML instead of hardcoding it here?
@@ -9024,6 +9026,15 @@
Spannable sp = (Spannable) mText;
MetaKeyKeyListener.resetMetaState(sp);
}
+ } else {
+ final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+ if (afm != null) {
+ if (DEBUG_AUTOFILL) {
+ Log.v(LOG_TAG, "onFocusChanged(): id=" + getAutoFillViewId() + ", focused= "
+ + focused);
+ }
+ afm.updateAutoFillInput(this, AutoFillManager.FLAG_UPDATE_UI_HIDE);
+ }
}
startStopMarquee(focused);
@@ -10602,6 +10613,14 @@
* @hide
*/
protected void viewClicked(InputMethodManager imm) {
+ final AutoFillManager afm = mContext.getSystemService(AutoFillManager.class);
+ if (afm != null) {
+ if (DEBUG_AUTOFILL) Log.v(LOG_TAG, "viewClicked(): id=" + getAutoFillViewId());
+
+ // TODO(b/33197203): integrate with onFocus and/or move to view?
+ afm.updateAutoFillInput(this, AutoFillManager.FLAG_UPDATE_UI_SHOW);
+ }
+
if (imm != null) {
imm.viewClicked(this);
}
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 1f71a18..0dfeb62 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -20,10 +20,11 @@
android:id="@+id/notification_header"
android:orientation="horizontal"
android:layout_width="wrap_content"
- android:layout_height="53dp"
+ android:layout_height="48dp"
android:clipChildren="false"
android:paddingTop="10dp"
- android:paddingBottom="16dp"
+ android:paddingBottom="11dp"
+ android:layout_marginBottom="5dp"
android:paddingStart="@dimen/notification_content_margin_start"
android:paddingEnd="16dp">
<com.android.internal.widget.CachingIconView
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index eece9fc..ac8c896 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -578,6 +578,9 @@
<!-- The divider symbol between different parts of the notification header. not translatable [CHAR LIMIT=1] -->
<string name="notification_header_divider_symbol" translatable="false">•</string>
+ <!-- The divider symbol between different parts of the notification header including spaces. not translatable [CHAR LIMIT=3] -->
+ <string name="notification_header_divider_symbol_with_spaces" translatable="false">" • "</string>
+
<!-- Text shown in place of notification contents when the notification is hidden on a secure lockscreen -->
<string name="notification_hidden_text">Contents hidden</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 58c925f..78f6b49 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2788,6 +2788,7 @@
<java-symbol type="drawable" name="lockscreen_notselected" />
<java-symbol type="drawable" name="lockscreen_selected" />
+ <java-symbol type="string" name="notification_header_divider_symbol_with_spaces" />
<java-symbol type="string" name="config_defaultCellBroadcastReceiverComponent" />
<java-symbol type="string" name="app_category_game" />
diff --git a/packages/SystemUI/res/xml/other_settings.xml b/packages/SystemUI/res/xml/other_settings.xml
index 18cb930..7719d5e 100644
--- a/packages/SystemUI/res/xml/other_settings.xml
+++ b/packages/SystemUI/res/xml/other_settings.xml
@@ -23,10 +23,5 @@
android:key="power_notification_controls"
android:title="@string/tuner_full_importance_settings"
android:fragment="com.android.systemui.tuner.PowerNotificationControlsFragment"/>
-e
- <com.android.systemui.tuner.ThemePreference
- android:key="theme"
- android:title="@string/theme"
- android:summary="%s" />
</PreferenceScreen>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 0bf3f15..1835afd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -60,7 +60,7 @@
private AlertDialog mDialog;
private QSTileHost mHost;
- protected Handler mHandler;
+ protected H mHandler;
private boolean mIsVisible;
private boolean mIsIconVisible;
@@ -83,7 +83,7 @@
mMainHandler = new Handler(Looper.getMainLooper());
mActivityStarter = Dependency.get(ActivityStarter.class);
mSecurityController = Dependency.get(SecurityController.class);
- mHandler = new Handler((Looper) Dependency.get(Dependency.BG_LOOPER));
+ mHandler = new H(Dependency.get(Dependency.BG_LOOPER));
}
public void setHostEnvironment(QSTileHost host) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index d9298ed..926f610 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1524,8 +1524,9 @@
entry.notification.getUser().getIdentifier());
final StatusBarNotification sbn = entry.notification;
+ boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
try {
- entry.cacheContentViews(mContext, null);
+ entry.cacheContentViews(mContext, null, isLowPriority);
} catch (RuntimeException e) {
Log.e(TAG, "Unable to get notification remote views", e);
return false;
@@ -1597,6 +1598,7 @@
workAroundBadLayerDrawableOpacity(row);
bindDismissRunnable(row);
+ row.setIsLowPriority(isLowPriority);
// NB: the large icon is now handled entirely by the template
@@ -2283,7 +2285,8 @@
boolean applyInPlace;
try {
- applyInPlace = entry.cacheContentViews(mContext, notification.getNotification());
+ applyInPlace = entry.cacheContentViews(mContext, notification.getNotification(),
+ mNotificationData.isAmbient(key));
} catch (RuntimeException e) {
Log.e(TAG, "Unable to get notification remote views", e);
applyInPlace = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 93c48f8..013554c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -22,6 +22,7 @@
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.ColorDrawable;
@@ -51,6 +52,7 @@
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.statusbar.notification.HybridNotificationView;
+import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -201,6 +203,7 @@
private boolean mShowAmbient;
private boolean mIsLastChild;
private Runnable mOnDismissRunnable;
+ private boolean mIsLowPriority;
public boolean isGroupExpansionChanging() {
if (isChildInGroup()) {
@@ -309,6 +312,18 @@
mPublicLayout.updateExpandButtons(true);
updateLimits();
updateIconVisibilities();
+ updateShelfIconColor();
+ }
+
+ private void updateShelfIconColor() {
+ StatusBarIconView expandedIcon = mEntry.expandedIcon;
+ boolean isPreL = Boolean.TRUE.equals(expandedIcon.getTag(R.id.icon_is_pre_L));
+ boolean colorize = !isPreL || NotificationUtils.isGrayscale(expandedIcon,
+ NotificationColorUtil.getInstance(mContext));
+ if (colorize) {
+ int color = mEntry.getContrastedColor(mContext, mIsLowPriority && !isExpanded());
+ expandedIcon.setImageTintList(ColorStateList.valueOf(color));
+ }
}
private void updateLimits() {
@@ -943,6 +958,14 @@
return mPrivateLayout.getTranslationY();
}
+ public void setIsLowPriority(boolean isLowPriority) {
+ mIsLowPriority = isLowPriority;
+ mPrivateLayout.setIsLowPriority(isLowPriority);
+ if (mChildrenContainer != null) {
+ mChildrenContainer.setIsLowPriority(isLowPriority);
+ }
+ }
+
public interface ExpansionLogger {
public void logNotificationExpansion(String key, boolean userAction, boolean expanded);
}
@@ -1043,6 +1066,7 @@
@Override
public void onInflate(ViewStub stub, View inflated) {
mChildrenContainer = (NotificationChildrenContainer) inflated;
+ mChildrenContainer.setIsLowPriority(mIsLowPriority);
mChildrenContainer.setNotificationParent(ExpandableNotificationRow.this);
mChildrenContainer.onNotificationUpdated();
mTranslateableViews.add(mChildrenContainer);
@@ -1242,6 +1266,7 @@
*/
public void setUserExpanded(boolean userExpanded) {
setUserExpanded(userExpanded, false /* allowChildExpansion */);
+ updateShelfIconColor();
}
/**
@@ -1301,6 +1326,7 @@
if (expand != mIsSystemExpanded) {
final boolean wasExpanded = isExpanded();
mIsSystemExpanded = expand;
+ updateShelfIconColor();
notifyHeightChanged(false /* needsAnimation */);
logExpansionEvent(false, wasExpanded);
if (mIsSummaryWithChildren) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index b45cde8..4d0ce12 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -129,6 +129,7 @@
private boolean mHeadsUpAnimatingAway;
private boolean mIconsVisible;
private int mClipBottomAmount;
+ private boolean mIsLowPriority;
public NotificationContentView(Context context, AttributeSet attrs) {
@@ -163,20 +164,31 @@
if (mExpandedChild != null) {
int size = Math.min(maxSize, mNotificationMaxHeight);
ViewGroup.LayoutParams layoutParams = mExpandedChild.getLayoutParams();
+ boolean useExactly = false;
if (layoutParams.height >= 0) {
// An actual height is set
size = Math.min(maxSize, layoutParams.height);
+ useExactly = true;
}
int spec = size == Integer.MAX_VALUE
? MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
- : MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+ : MeasureSpec.makeMeasureSpec(size, useExactly
+ ? MeasureSpec.EXACTLY
+ : MeasureSpec.AT_MOST);
mExpandedChild.measure(widthMeasureSpec, spec);
maxChildHeight = Math.max(maxChildHeight, mExpandedChild.getMeasuredHeight());
}
if (mContractedChild != null) {
int heightSpec;
int size = Math.min(maxSize, mSmallHeight);
- if (shouldContractedBeFixedSize()) {
+ ViewGroup.LayoutParams layoutParams = mContractedChild.getLayoutParams();
+ boolean useExactly = false;
+ if (layoutParams.height >= 0) {
+ // An actual height is set
+ size = Math.min(size, layoutParams.height);
+ useExactly = true;
+ }
+ if (shouldContractedBeFixedSize() || useExactly) {
heightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
} else {
heightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
@@ -202,12 +214,15 @@
if (mHeadsUpChild != null) {
int size = Math.min(maxSize, mHeadsUpHeight);
ViewGroup.LayoutParams layoutParams = mHeadsUpChild.getLayoutParams();
+ boolean useExactly = false;
if (layoutParams.height >= 0) {
// An actual height is set
size = Math.min(size, layoutParams.height);
+ useExactly = true;
}
mHeadsUpChild.measure(widthMeasureSpec,
- MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST));
+ MeasureSpec.makeMeasureSpec(size, useExactly ? MeasureSpec.EXACTLY
+ : MeasureSpec.AT_MOST));
maxChildHeight = Math.max(maxChildHeight, mHeadsUpChild.getMeasuredHeight());
}
if (mSingleLineView != null) {
@@ -225,12 +240,15 @@
if (mAmbientChild != null) {
int size = Math.min(maxSize, mNotificationAmbientHeight);
ViewGroup.LayoutParams layoutParams = mAmbientChild.getLayoutParams();
+ boolean useExactly = false;
if (layoutParams.height >= 0) {
// An actual height is set
size = Math.min(size, layoutParams.height);
+ useExactly = true;
}
mAmbientChild.measure(widthMeasureSpec,
- MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST));
+ MeasureSpec.makeMeasureSpec(size, useExactly ? MeasureSpec.EXACTLY
+ : MeasureSpec.AT_MOST));
maxChildHeight = Math.max(maxChildHeight, mAmbientChild.getMeasuredHeight());
}
int ownHeight = Math.min(maxChildHeight, maxSize);
@@ -606,7 +624,7 @@
}
public int getMinHeight(boolean likeGroupExpanded) {
- if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
+ if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded() || mIsLowPriority) {
return mContractedChild.getHeight();
} else {
return mSingleLineView.getHeight();
@@ -868,7 +886,7 @@
height = mContentHeight;
}
int expandedVisualType = getVisualTypeForHeight(height);
- int collapsedVisualType = mIsChildInGroup && !isGroupExpanded()
+ int collapsedVisualType = mIsChildInGroup && !isGroupExpanded() && !mIsLowPriority
? VISIBLE_TYPE_SINGLELINE
: getVisualTypeForHeight(mContainingNotification.getCollapsedHeight());
return mTransformationStartVisibleType == collapsedVisualType
@@ -889,7 +907,7 @@
if (!noExpandedChild && viewHeight == mExpandedChild.getHeight()) {
return VISIBLE_TYPE_EXPANDED;
}
- if (!mUserExpanding && mIsChildInGroup && !isGroupExpanded()) {
+ if (!mUserExpanding && mIsChildInGroup && !isGroupExpanded() && !mIsLowPriority) {
return VISIBLE_TYPE_SINGLELINE;
}
@@ -976,16 +994,16 @@
updateSingleLineView();
applyRemoteInput(entry);
if (mContractedChild != null) {
- mContractedWrapper.notifyContentUpdated(entry.notification);
+ mContractedWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
}
if (mExpandedChild != null) {
- mExpandedWrapper.notifyContentUpdated(entry.notification);
+ mExpandedWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
}
if (mHeadsUpChild != null) {
- mHeadsUpWrapper.notifyContentUpdated(entry.notification);
+ mHeadsUpWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
}
if (mAmbientChild != null) {
- mAmbientWrapper.notifyContentUpdated(entry.notification);
+ mAmbientWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
}
updateShowingLegacyBackground();
mForceSelectNextLayout = true;
@@ -1282,4 +1300,8 @@
}
}
}
+
+ public void setIsLowPriority(boolean isLowPriority) {
+ mIsLowPriority = isLowPriority;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 3a89186..8c04a1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -117,14 +117,16 @@
return row.getPublicLayout().getContractedChild();
}
- public boolean cacheContentViews(Context ctx, Notification updatedNotification) {
+ public boolean cacheContentViews(Context ctx, Notification updatedNotification,
+ boolean isLowPriority) {
boolean applyInPlace = false;
if (updatedNotification != null) {
final Notification.Builder updatedNotificationBuilder
= Notification.Builder.recoverBuilder(ctx, updatedNotification);
- final RemoteViews newContentView = updatedNotificationBuilder.createContentView();
- final RemoteViews newBigContentView =
- updatedNotificationBuilder.createBigContentView();
+ final RemoteViews newContentView = createContentView(updatedNotificationBuilder,
+ isLowPriority);
+ final RemoteViews newBigContentView = createBigContentView(
+ updatedNotificationBuilder, isLowPriority);
final RemoteViews newHeadsUpContentView =
updatedNotificationBuilder.createHeadsUpContentView();
final RemoteViews newPublicNotification
@@ -152,8 +154,8 @@
final Notification.Builder builder
= Notification.Builder.recoverBuilder(ctx, notification.getNotification());
- cachedContentView = builder.createContentView();
- cachedBigContentView = builder.createBigContentView();
+ cachedContentView = createContentView(builder, isLowPriority);
+ cachedBigContentView = createBigContentView(builder, isLowPriority);
cachedHeadsUpContentView = builder.createHeadsUpContentView();
cachedPublicContentView = builder.makePublicContentView();
cachedAmbientContentView = builder.makeAmbientNotification();
@@ -163,6 +165,28 @@
return applyInPlace;
}
+ private RemoteViews createBigContentView(Notification.Builder builder,
+ boolean isLowPriority) {
+ RemoteViews bigContentView = builder.createBigContentView();
+ if (bigContentView != null) {
+ return bigContentView;
+ }
+ if (isLowPriority) {
+ RemoteViews contentView = builder.createContentView();
+ Notification.Builder.makeHeaderExpanded(contentView);
+ return contentView;
+ }
+ return null;
+ }
+
+ private RemoteViews createContentView(Notification.Builder builder,
+ boolean isAmbient) {
+ if (isAmbient) {
+ return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
+ }
+ return builder.createContentView();
+ }
+
// Returns true if the RemoteViews are the same.
private boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
return (a == null && b == null) ||
@@ -256,8 +280,9 @@
}
}
- public int getContrastedColor(Context context) {
- int rawColor = notification.getNotification().color;
+ public int getContrastedColor(Context context, boolean ambient) {
+ int rawColor = ambient ? Notification.COLOR_DEFAULT :
+ notification.getNotification().color;
if (mCachedContrastColorIsFor == rawColor && mCachedContrastColor != COLOR_INVALID) {
return mCachedContrastColor;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TransformableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/TransformableView.java
index dd7c4c7..063252f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/TransformableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/TransformableView.java
@@ -22,7 +22,7 @@
* A view that can be transformed to and from.
*/
public interface TransformableView {
- int TRANSFORMING_VIEW_HEADER = 0;
+ int TRANSFORMING_VIEW_ICON = 0;
int TRANSFORMING_VIEW_TITLE = 1;
int TRANSFORMING_VIEW_TEXT = 2;
int TRANSFORMING_VIEW_IMAGE = 3;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeaderTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeaderTransformState.java
deleted file mode 100644
index 9501f90..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/HeaderTransformState.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.statusbar.notification;
-
-import android.util.Pools;
-import android.view.NotificationHeaderView;
-import android.view.View;
-
-import com.android.systemui.statusbar.CrossFadeHelper;
-
-/**
- * A transform state of a text view.
-*/
-public class HeaderTransformState extends TransformState {
-
- private static Pools.SimplePool<HeaderTransformState> sInstancePool
- = new Pools.SimplePool<>(40);
- private View mExpandButton;
- private View mWorkProfileIcon;
- private TransformState mWorkProfileState;
-
- @Override
- public void initFrom(View view) {
- super.initFrom(view);
- if (view instanceof NotificationHeaderView) {
- NotificationHeaderView header = (NotificationHeaderView) view;
- mExpandButton = header.getExpandButton();
- mWorkProfileState = TransformState.obtain();
- mWorkProfileIcon = header.getWorkProfileIcon();
- mWorkProfileState.initFrom(mWorkProfileIcon);
- }
- }
-
- @Override
- public boolean transformViewTo(TransformState otherState, float transformationAmount) {
- // if the transforming notification has a header, we have ensured that it looks the same
- // but the expand button, so lets fade just that one and transform the work profile icon.
- if (!(mTransformedView instanceof NotificationHeaderView)) {
- return false;
- }
- NotificationHeaderView header = (NotificationHeaderView) mTransformedView;
- int childCount = header.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View headerChild = header.getChildAt(i);
- if (headerChild.getVisibility() == View.GONE) {
- continue;
- }
- if (headerChild != mExpandButton) {
- headerChild.setVisibility(View.INVISIBLE);
- } else {
- CrossFadeHelper.fadeOut(mExpandButton, transformationAmount);
- }
- }
- return true;
- }
-
- @Override
- public void transformViewFrom(TransformState otherState, float transformationAmount) {
- // if the transforming notification has a header, we have ensured that it looks the same
- // but the expand button, so lets fade just that one and transform the work profile icon.
- if (!(mTransformedView instanceof NotificationHeaderView)) {
- return;
- }
- NotificationHeaderView header = (NotificationHeaderView) mTransformedView;
- header.setVisibility(View.VISIBLE);
- header.setAlpha(1.0f);
- int childCount = header.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View headerChild = header.getChildAt(i);
- if (headerChild.getVisibility() == View.GONE) {
- continue;
- }
- if (headerChild == mExpandButton) {
- CrossFadeHelper.fadeIn(mExpandButton, transformationAmount);
- } else {
- headerChild.setVisibility(View.VISIBLE);
- if (headerChild == mWorkProfileIcon) {
- mWorkProfileState.transformViewFullyFrom(
- ((HeaderTransformState) otherState).mWorkProfileState,
- transformationAmount);
- }
- }
- }
- return;
- }
-
- public static HeaderTransformState obtain() {
- HeaderTransformState instance = sInstancePool.acquire();
- if (instance != null) {
- return instance;
- }
- return new HeaderTransformState();
- }
-
- @Override
- public void recycle() {
- super.recycle();
- sInstancePool.release(this);
- }
-
- @Override
- protected void reset() {
- super.reset();
- mExpandButton = null;
- mWorkProfileState = null;
- if (mWorkProfileState != null) {
- mWorkProfileState.recycle();
- mWorkProfileState = null;
- }
- }
-
- @Override
- public void setVisible(boolean visible, boolean force) {
- super.setVisible(visible, force);
- if (!(mTransformedView instanceof NotificationHeaderView)) {
- return;
- }
- NotificationHeaderView header = (NotificationHeaderView) mTransformedView;
- int childCount = header.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View headerChild = header.getChildAt(i);
- if (!force && headerChild.getVisibility() == View.GONE) {
- continue;
- }
- headerChild.animate().cancel();
- if (headerChild.getVisibility() != View.GONE) {
- headerChild.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
- }
- if (headerChild == mExpandButton) {
- headerChild.setAlpha(visible ? 1.0f : 0.0f);
- }
- if (headerChild == mWorkProfileIcon) {
- headerChild.setTranslationX(0);
- headerChild.setTranslationY(0);
- }
- }
- }
-
- @Override
- public void prepareFadeIn() {
- super.prepareFadeIn();
- if (!(mTransformedView instanceof NotificationHeaderView)) {
- return;
- }
- NotificationHeaderView header = (NotificationHeaderView) mTransformedView;
- int childCount = header.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View headerChild = header.getChildAt(i);
- if (headerChild.getVisibility() == View.GONE) {
- continue;
- }
- headerChild.animate().cancel();
- headerChild.setVisibility(View.VISIBLE);
- headerChild.setAlpha(1.0f);
- if (headerChild == mWorkProfileIcon) {
- headerChild.setTranslationX(0);
- headerChild.setTranslationY(0);
- }
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
index 6084770..78b967a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
@@ -36,8 +36,8 @@
}
@Override
- public void notifyContentUpdated(StatusBarNotification notification) {
- super.notifyContentUpdated(notification);
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+ super.notifyContentUpdated(notification, isLowPriority);
updateImageTag(notification);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
index 3f49125..39db243 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
@@ -41,11 +41,11 @@
}
@Override
- public void notifyContentUpdated(StatusBarNotification notification) {
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveViews(notification);
- super.notifyContentUpdated(notification);
+ super.notifyContentUpdated(notification, isLowPriority);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index 85e87dd..d564741 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -106,8 +106,8 @@
}
@Override
- public void notifyContentUpdated(StatusBarNotification notification) {
- super.notifyContentUpdated(notification);
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+ super.notifyContentUpdated(notification, isLowPriority);
Drawable background = mView.getBackground();
mBackgroundColor = 0;
if (background instanceof ColorDrawable) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 3e4c758..e1f553c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -32,6 +32,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
+import android.widget.TextView;
import com.android.systemui.R;
import com.android.systemui.ViewInvertHelper;
@@ -60,6 +61,9 @@
private ImageView mExpandButton;
private NotificationHeaderView mNotificationHeader;
+ private TextView mHeaderText;
+ private ImageView mWorkProfileImage;
+ private boolean mIsLowPriority;
protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
super(view, row);
@@ -72,7 +76,9 @@
protected void resolveHeaderViews() {
mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon);
+ mHeaderText = (TextView) mView.findViewById(com.android.internal.R.id.header_text);
mExpandButton = (ImageView) mView.findViewById(com.android.internal.R.id.expand_button);
+ mWorkProfileImage = (ImageView) mView.findViewById(com.android.internal.R.id.profile_badge);
mColor = resolveColor(mExpandButton);
mNotificationHeader = (NotificationHeaderView) mView.findViewById(
com.android.internal.R.id.notification_header);
@@ -89,9 +95,9 @@
}
@Override
- public void notifyContentUpdated(StatusBarNotification notification) {
- super.notifyContentUpdated(notification);
-
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+ super.notifyContentUpdated(notification, isLowPriority);
+ mIsLowPriority = isLowPriority;
ArraySet<View> previousViews = mTransformationHelper.getAllTransformingViews();
// Reinspect the notification.
@@ -100,6 +106,11 @@
updateTransformedTypes();
addRemainingTransformTypes();
updateCropToPaddingForImageViews();
+ mIcon.setTag(ImageTransformState.ICON_TAG, notification.getNotification().getSmallIcon());
+ // The work profile image is always the same lets just set the icon tag for it not to
+ // animate
+ mWorkProfileImage.setTag(ImageTransformState.ICON_TAG,
+ notification.getNotification().getSmallIcon());
// We need to reset all views that are no longer transforming in case a view was previously
// transformed, but now we decided to transform its container instead.
@@ -154,8 +165,11 @@
protected void updateTransformedTypes() {
mTransformationHelper.reset();
- mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_HEADER,
- mNotificationHeader);
+ mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_ICON, mIcon);
+ if (mIsLowPriority) {
+ mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
+ mHeaderText);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
index 4ce330c..04ee6aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
@@ -40,11 +40,11 @@
}
@Override
- public void notifyContentUpdated(StatusBarNotification notification) {
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveViews(notification);
- super.notifyContentUpdated(notification);
+ super.notifyContentUpdated(notification, isLowPriority);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
index 58f01c8..61457df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
@@ -59,11 +59,11 @@
}
@Override
- public void notifyContentUpdated(StatusBarNotification notification) {
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveViews();
- super.notifyContentUpdated(notification);
+ super.notifyContentUpdated(notification, isLowPriority);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index b984c0b..e9956ff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -133,11 +133,11 @@
}
@Override
- public void notifyContentUpdated(StatusBarNotification notification) {
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
// Reinspect the notification. Before the super call, because the super call also updates
// the transformation types and we need to have our values set by then.
resolveTemplateViews(notification);
- super.notifyContentUpdated(notification);
+ super.notifyContentUpdated(notification, isLowPriority);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 16348dfe..8106223 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -80,9 +80,10 @@
/**
* Notifies this wrapper that the content of the view might have changed.
- * @param notification
+ * @param notification the notification this is wrapped around
+ * @param isLowPriority is this notification low priority
*/
- public void notifyContentUpdated(StatusBarNotification notification) {
+ public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
mDarkInitialized = false;
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
index 770ec95..6b3d25d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TransformState.java
@@ -402,11 +402,6 @@
result.initFrom(view);
return result;
}
- if (view instanceof NotificationHeaderView) {
- HeaderTransformState result = HeaderTransformState.obtain();
- result.initFrom(view);
- return result;
- }
if (view instanceof ImageView) {
ImageTransformState result = ImageTransformState.obtain();
result.initFrom(view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 345dcbd..32b9969 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -154,18 +154,6 @@
NotificationShelf.SHOW_AMBIENT_ICONS);
applyNotificationIconsTint();
- ArrayList<NotificationData.Entry> activeNotifications
- = notificationData.getActiveNotifications();
- for (int i = 0; i < activeNotifications.size(); i++) {
- NotificationData.Entry entry = activeNotifications.get(i);
- boolean isPreL = Boolean.TRUE.equals(entry.expandedIcon.getTag(R.id.icon_is_pre_L));
- boolean colorize = !isPreL
- || NotificationUtils.isGrayscale(entry.expandedIcon, mNotificationColorUtil);
- if (colorize) {
- int color = entry.getContrastedColor(mContext);
- entry.expandedIcon.setImageTintList(ColorStateList.valueOf(color));
- }
- }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index a706408..5536209 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -162,6 +162,10 @@
BatteryMeterView battery = (BatteryMeterView) findViewById(R.id.battery);
int colorSecondary = Utils.getColorAttr(getContext(), android.R.attr.textColorSecondary);
battery.setRawColors(colorForeground, colorSecondary);
+
+ mNextAlarmController = Dependency.get(NextAlarmController.class);
+ mUserInfoController = Dependency.get(UserInfoController.class);
+ mActivityStarter = Dependency.get(ActivityStarter.class);
}
@Override
@@ -260,14 +264,6 @@
}
@Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mNextAlarmController = Dependency.get(NextAlarmController.class);
- mUserInfoController = Dependency.get(UserInfoController.class);
- mActivityStarter = Dependency.get(ActivityStarter.class);
- }
-
- @Override
@VisibleForTesting
public void onDetachedFromWindow() {
setListening(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index 1a2d778..e6a3add 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -78,6 +78,7 @@
private NotificationHeaderUtil mHeaderUtil;
private ViewState mHeaderViewState;
private int mClipBottomAmount;
+ private boolean mIsLowPriority;
public NotificationChildrenContainer(Context context) {
this(context, null);
@@ -246,10 +247,13 @@
return mChildren.size();
}
- public void recreateNotificationHeader(OnClickListener listener, StatusBarNotification notification) {
+ public void recreateNotificationHeader(OnClickListener listener,
+ StatusBarNotification notification) {
final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
mNotificationParent.getStatusBarNotification().getNotification());
- final RemoteViews header = builder.makeNotificationHeader();
+ final RemoteViews header = mIsLowPriority
+ ? builder.makeLowPriorityContentView(true /* useRegularSubtext */)
+ : builder.makeNotificationHeader();
if (mNotificationHeader == null) {
mNotificationHeader = (NotificationHeaderView) header.apply(getContext(), this);
final View expandButton = mNotificationHeader.findViewById(
@@ -262,7 +266,7 @@
invalidate();
} else {
header.reapply(getContext(), mNotificationHeader);
- mNotificationHeaderWrapper.notifyContentUpdated(notification);
+ mNotificationHeaderWrapper.notifyContentUpdated(notification, mIsLowPriority);
}
updateChildrenHeaderAppearance();
}
@@ -367,6 +371,9 @@
* @return the intrinsic size of this children container, i.e the natural fully expanded state
*/
public int getIntrinsicHeight() {
+ if (mIsLowPriority && !mChildrenExpanded) {
+ return mNotificationHeader.getHeight();
+ }
int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren();
return getIntrinsicHeight(maxAllowedVisibleChildren);
}
@@ -480,7 +487,7 @@
childState.clipTopAmount = 0;
childState.alpha = 0;
if (i < firstOverflowIndex) {
- childState.alpha = 1;
+ childState.alpha = mIsLowPriority && !mChildrenExpanded ? expandFactor : 1.0f;
} else if (expandFactor == 1.0f && i <= lastVisibleIndex) {
childState.alpha = (mActualHeight - childState.yTranslation) / childState.height;
childState.alpha = Math.max(0.0f, Math.min(1.0f, childState.alpha));
@@ -828,6 +835,9 @@
}
private int getMinHeight(int maxAllowedVisibleChildren) {
+ if (mIsLowPriority && !mChildrenExpanded) {
+ return mNotificationHeader.getHeight();
+ }
int minExpandHeight = mNotificationHeaderMargin;
int visibleChildren = 0;
boolean firstChild = true;
@@ -922,4 +932,8 @@
mClipBottomAmount = clipBottomAmount;
updateChildrenClipping();
}
+
+ public void setIsLowPriority(boolean isLowPriority) {
+ mIsLowPriority = isLowPriority;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java b/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java
deleted file mode 100644
index a068172..0000000
--- a/packages/SystemUI/src/com/android/systemui/tuner/ThemePreference.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2016 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.systemui.tuner;
-
-import android.app.AlertDialog;
-import android.app.UiModeManager;
-import android.content.Context;
-import android.os.SystemProperties;
-import android.support.v7.preference.ListPreference;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-
-import com.android.systemui.R;
-
-import libcore.util.Objects;
-
-import com.google.android.collect.Lists;
-
-import java.io.File;
-import java.util.ArrayList;
-
-public class ThemePreference extends ListPreference {
-
- public ThemePreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- public void onAttached() {
- super.onAttached();
- String def = SystemProperties.get("ro.boot.vendor.overlay.theme");
- if (TextUtils.isEmpty(def)) {
- def = getContext().getString(R.string.default_theme);
- }
- String[] fileList = new File("/vendor/overlay").list();
- ArrayList<String> options = fileList != null
- ? Lists.newArrayList(fileList) : new ArrayList<>();
- if (!options.contains(def)) {
- options.add(0, def);
- }
- String[] list = options.toArray(new String[options.size()]);
- setVisible(options.size() > 1);
- setEntries(list);
- setEntryValues(list);
- updateValue();
- }
-
- private void updateValue() {
- setValue(getContext().getSystemService(UiModeManager.class).getTheme());
- }
-
- @Override
- protected void notifyChanged() {
- super.notifyChanged();
- if (!Objects.equal(getValue(),
- getContext().getSystemService(UiModeManager.class).getTheme())) {
- new AlertDialog.Builder(getContext())
- .setTitle(R.string.change_theme_reboot)
- .setPositiveButton(com.android.internal.R.string.global_action_restart, (d, i)
- -> getContext().getSystemService(UiModeManager.class)
- .setTheme(getValue()))
- .setNegativeButton(android.R.string.cancel, (d, i) -> updateValue())
- .show();
- }
- }
-}
diff --git a/packages/SystemUI/tests/AndroidManifest.xml b/packages/SystemUI/tests/AndroidManifest.xml
index 6516369..90e9321 100644
--- a/packages/SystemUI/tests/AndroidManifest.xml
+++ b/packages/SystemUI/tests/AndroidManifest.xml
@@ -30,6 +30,9 @@
<uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_VR_MANAGER" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
+ <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
index 973f1f2..fb4b6bd 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/DependencyTest.java
@@ -15,6 +15,7 @@
package com.android.systemui;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -25,6 +26,8 @@
import org.junit.Test;
+import java.io.PrintWriter;
+
public class DependencyTest extends SysuiTestCase {
@Test
@@ -46,8 +49,8 @@
Dumpable d = mock(Dumpable.class);
injectTestDependency("test", d);
Dependency.get("test");
- mDependency.dump(null, null, null);
- verify(d).dump(eq(null), eq(null), eq(null));
+ mDependency.dump(null, mock(PrintWriter.class), null);
+ verify(d).dump(eq(null), any(), eq(null));
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index 5fe5174..f258e5d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -43,6 +43,7 @@
public void SysuiSetup() throws Exception {
System.setProperty("dexmaker.share_classloader", "true");
mContext = new TestableContext(InstrumentationRegistry.getTargetContext(), this);
+ SystemUIFactory.createFromConfig(mContext);
mDependency = new TestDependency();
mDependency.mContext = mContext;
mDependency.start();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index e3ee851..5345031 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -58,6 +58,7 @@
@Before
public void addLeakCheckDependencies() {
+ injectTestDependency(Dependency.BG_LOOPER, Looper.getMainLooper());
injectMockDependency(UserSwitcherController.class);
injectLeakCheckedDependencies(BluetoothController.class, LocationController.class,
RotationLockController.class, NetworkController.class, ZenModeController.class,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 9fcb5f7..525a361 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -40,6 +40,7 @@
mContext.putComponent(PhoneStatusBar.class, mock(PhoneStatusBar.class));
mContext.putComponent(Recents.class, mock(Recents.class));
mContext.putComponent(Divider.class, mock(Divider.class));
+ mContext.addMockSystemService(Context.WINDOW_SERVICE, mock(WindowManager.class));
}
@Test
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 036b6c2..a474759 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3336,6 +3336,9 @@
// OS: 8.0
TTS_SLIDERS = 815;
+ // ACTION: Settings -> Display -> Theme
+ ACTION_THEME = 816;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
index 87eaf29..6779657 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerService.java
@@ -19,10 +19,6 @@
import static android.Manifest.permission.MANAGE_AUTO_FILL;
import static android.content.Context.AUTO_FILL_MANAGER_SERVICE;
import static android.view.View.AUTO_FILL_FLAG_TYPE_FILL;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_SAVE;
-
-import static com.android.server.autofill.AutoFillUI.MSG_SHOW_ALL_NOTIFICATIONS;
-import static com.android.server.autofill.AutoFillUI.SHOW_ALL_NOTIFICATIONS_DELAY_MS;
import android.Manifest;
import android.app.AppGlobals;
@@ -32,11 +28,13 @@
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.database.ContentObserver;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -51,9 +49,12 @@
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
+import android.view.autofill.AutoFillId;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
import com.android.server.FgThread;
import com.android.server.SystemService;
@@ -70,13 +71,12 @@
public final class AutoFillManagerService extends SystemService {
private static final String TAG = "AutoFillManagerService";
- static final boolean DEBUG = true; // TODO: change to false once stable
+ static final boolean DEBUG = true; // TODO(b/33197203): change to false once stable
private static final long SERVICE_BINDING_LIFETIME_MS = 5 * DateUtils.MINUTE_IN_MILLIS;
- private static final int ARG_NOT_USED = 0;
-
protected static final int MSG_UNBIND = 1;
+ protected static final int MSG_SHOW_AUTO_FILL = 2;
private final AutoFillManagerServiceStub mServiceStub;
private final AutoFillUI mUi;
@@ -85,23 +85,28 @@
private final Object mLock = new Object();
- private final Handler mHandler = new Handler() {
+ private final HandlerCaller.Callback mHandlerCallback = new HandlerCaller.Callback() {
+
@Override
- public void handleMessage(Message msg) {
+ public void executeMessage(Message msg) {
switch (msg.what) {
- case MSG_UNBIND:
+ case MSG_UNBIND: {
removeStaleServiceForUser(msg.arg1);
return;
- case MSG_SHOW_ALL_NOTIFICATIONS:
- mUi.showAllNotifications();
+ } case MSG_SHOW_AUTO_FILL: {
+ final SomeArgs args = (SomeArgs) msg.obj;
+ showAutoFillInput(msg.arg1, (AutoFillId) args.arg1, (Rect) args.arg2);
return;
- default:
+ } default: {
Slog.w(TAG, "Invalid message: " + msg);
+ }
}
}
};
+ private HandlerCaller mHandlerCaller;
+
/**
* Cache of {@link AutoFillManagerServiceImpl} per user id.
* <p>
@@ -122,6 +127,8 @@
public AutoFillManagerService(Context context) {
super(context);
+ mHandlerCaller = new HandlerCaller(null, Looper.getMainLooper(), mHandlerCallback, true);
+
mContext = context;
mUi = new AutoFillUI(context, this, mLock);
mResolver = context.getContentResolver();
@@ -139,14 +146,6 @@
if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
new SettingsObserver(BackgroundThread.getHandler());
}
- if (phase == PHASE_BOOT_COMPLETED) {
- // TODO: if sent right away, the notification is not displayed. Since the notification
- // mechanism is a temporary approach anyways, just delay it..
- if (DEBUG)
- Slog.d(TAG, "Showing notifications in " + SHOW_ALL_NOTIFICATIONS_DELAY_MS + "ms");
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SHOW_ALL_NOTIFICATIONS),
- SHOW_ALL_NOTIFICATIONS_DELAY_MS);
- }
}
private AutoFillManagerServiceImpl newServiceForUser(int userId) {
@@ -200,7 +199,7 @@
}
// Keep service connection alive for a while, in case user needs to interact with it
// (for example, to save the data that was inputted in)
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_UNBIND, userId, ARG_NOT_USED),
+ mHandlerCaller.sendMessageDelayed(mHandlerCaller.obtainMessageI(MSG_UNBIND, userId),
SERVICE_BINDING_LIFETIME_MS);
return service;
}
@@ -245,18 +244,41 @@
}
+
+ private void requestAutoFillLocked(IBinder activityToken, int userId, Bundle extras,
+ int flags) {
+ final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
+ if (service != null) {
+ service.requestAutoFill(activityToken, extras, flags);
+ }
+ }
+
+ private void showAutoFillInput(int userId, AutoFillId id, Rect rect) {
+ if (DEBUG) Slog.d(TAG, "handler.showAutoFillInput(): id=" + id + ", rect=" + rect);
+
+ synchronized (mLock) {
+ requestAutoFillLocked(null, userId, null, AUTO_FILL_FLAG_TYPE_FILL);
+ }
+ }
+
final class AutoFillManagerServiceStub extends IAutoFillManagerService.Stub {
@Override
+ public void showAutoFillInput(AutoFillId id, Rect boundaries) {
+ if (DEBUG) Slog.d(TAG, "showAutoFillInput(): id=" + id + ", boundaries=" + boundaries);
+
+ // TODO(b/33197203): fail if it's not called by same uid as the top activity
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(MSG_SHOW_AUTO_FILL,
+ UserHandle.getCallingUserId(), id, boundaries));
+ }
+
+ @Override
public void requestAutoFill(IBinder activityToken, int userId, Bundle extras, int flags) {
if (DEBUG) Slog.d(TAG, "requestAutoFill: flags=" + flags + ", userId=" + userId);
mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
synchronized (mLock) {
- final AutoFillManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
- service.requestAutoFill(activityToken, extras, flags);
- }
+ requestAutoFillLocked(activityToken, userId, extras, flags);
}
}
@@ -307,7 +329,6 @@
if (DEBUG) Slog.d(TAG, "settings (" + uri + " changed for " + userId);
synchronized (mLock) {
removeCachedServiceForUserLocked(userId);
- mUi.updateNotification(userId);
}
}
}
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
index ae21b07..83faf1b 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillManagerServiceImpl.java
@@ -163,7 +163,6 @@
}
final AssistStructure structure = resultData
.getParcelable(VoiceInteractionSession.KEY_STRUCTURE);
- final Bundle data = resultData.getBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS);
final int flags = resultData.getInt(VoiceInteractionSession.KEY_FLAGS, 0);
final ServerCallback serverCallback;
diff --git a/services/autofill/java/com/android/server/autofill/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
index 08e81d3..6fafd5d 100644
--- a/services/autofill/java/com/android/server/autofill/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/AutoFillUI.java
@@ -16,40 +16,29 @@
package com.android.server.autofill;
import static android.view.View.AUTO_FILL_FLAG_TYPE_SAVE;
-import static android.view.View.AUTO_FILL_FLAG_TYPE_FILL;
import static com.android.server.autofill.AutoFillManagerService.DEBUG;
import android.app.Activity;
-import android.app.AppGlobals;
import android.app.Notification;
import android.app.Notification.Action;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ServiceInfo;
-import android.content.pm.UserInfo;
import android.os.Binder;
import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.UserManager;
-import android.provider.Settings;
import android.service.autofill.AutoFillService;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
-import android.view.autofill.Dataset;
import android.view.autofill.AutoFillId;
+import android.view.autofill.Dataset;
import android.view.autofill.FillResponse;
import android.widget.Toast;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.UiThread;
import java.util.Arrays;
@@ -69,9 +58,10 @@
AutoFillUI(Context context, AutoFillManagerService service, Object lock) {
mContext = context;
- mResolver = context.getContentResolver();
mService = service;
mLock = lock;
+
+ setNotificationListener();
}
/**
@@ -121,56 +111,60 @@
private static final String EXTRA_FILL_RESPONSE = "fill_response";
private static final String EXTRA_DATASET = "dataset";
- private static final String TYPE_EMULATE = "emulate";
private static final String TYPE_OPTIONS = "options";
private static final String TYPE_DELETE_CALLBACK = "delete_callback";
private static final String TYPE_PICK_DATASET = "pick_dataset";
private static final String TYPE_SAVE = "save";
- static final int MSG_SHOW_ALL_NOTIFICATIONS = 42;
- static final int SHOW_ALL_NOTIFICATIONS_DELAY_MS = 5000;
-
+ @GuardedBy("mLock")
private BroadcastReceiver mNotificationReceiver;
- private final ContentResolver mResolver;
+ @GuardedBy("mLock")
private final AutoFillManagerService mService;
private final Object mLock;
// Hack used to generate unique pending intents
static int sResultCode = 0;
+ private void setNotificationListener() {
+ synchronized (mLock) {
+ if (mNotificationReceiver == null) {
+ mNotificationReceiver = new NotificationReceiver();
+ mContext.registerReceiver(mNotificationReceiver,
+ new IntentFilter(NOTIFICATION_AUTO_FILL_INTENT));
+ }
+ }
+ }
+
final class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
final int userId = intent.getIntExtra(EXTRA_USER_ID, -1);
- final AutoFillManagerServiceImpl service = mService.getServiceForUserLocked(userId);
- if (service == null) {
- Slog.w(TAG, "no auto-fill service for user " + userId);
- return;
- }
-
- final int callbackId = intent.getIntExtra(EXTRA_CALLBACK_ID, -1);
- final String type = intent.getStringExtra(EXTRA_NOTIFICATION_TYPE);
- if (type == null) {
- Slog.wtf(TAG, "No extra " + EXTRA_NOTIFICATION_TYPE + " on intent " + intent);
- return;
- }
- final FillResponse fillData = intent.getParcelableExtra(EXTRA_FILL_RESPONSE);
- final Dataset dataset = intent.getParcelableExtra(EXTRA_DATASET);
- final Bundle datasetArgs = dataset == null ? null : dataset.getExtras();
- final Bundle fillDataArgs = fillData == null ? null : fillData.getExtras();
-
- // Bundle sent on AutoFillService methods - only set if service provided a bundle
- final Bundle extras = (datasetArgs == null && fillDataArgs == null)
- ? null : new Bundle();
-
- if (DEBUG) Slog.d(TAG, "Notification received: type=" + type + ", userId=" + userId
- + ", callbackId=" + callbackId);
synchronized (mLock) {
+ final AutoFillManagerServiceImpl service = mService.getServiceForUserLocked(userId);
+ if (service == null) {
+ Slog.w(TAG, "no auto-fill service for user " + userId);
+ return;
+ }
+
+ final int callbackId = intent.getIntExtra(EXTRA_CALLBACK_ID, -1);
+ final String type = intent.getStringExtra(EXTRA_NOTIFICATION_TYPE);
+ if (type == null) {
+ Slog.wtf(TAG, "No extra " + EXTRA_NOTIFICATION_TYPE + " on intent " + intent);
+ return;
+ }
+ final FillResponse fillData = intent.getParcelableExtra(EXTRA_FILL_RESPONSE);
+ final Dataset dataset = intent.getParcelableExtra(EXTRA_DATASET);
+ final Bundle datasetArgs = dataset == null ? null : dataset.getExtras();
+ final Bundle fillDataArgs = fillData == null ? null : fillData.getExtras();
+
+ // Bundle sent on AutoFillService methods - only set if service provided a bundle
+ final Bundle extras = (datasetArgs == null && fillDataArgs == null)
+ ? null : new Bundle();
+
+ if (DEBUG) Slog.d(TAG, "Notification received: type=" + type + ", userId=" + userId
+ + ", callbackId=" + callbackId);
switch (type) {
- case TYPE_EMULATE:
- service.requestAutoFill(null, extras, AUTO_FILL_FLAG_TYPE_FILL);
- break;
case TYPE_SAVE:
if (datasetArgs != null) {
if (DEBUG) Log.d(TAG, "filldata args on save notificataion: " +
@@ -210,54 +204,6 @@
}
}
- private ComponentName getProviderForUser(int userId) {
- ComponentName serviceComponent = null;
- ServiceInfo serviceInfo = null;
- final String componentName = Settings.Secure.getStringForUser(
- mResolver, Settings.Secure.AUTO_FILL_SERVICE, userId);
- if (!TextUtils.isEmpty(componentName)) {
- try {
- serviceComponent = ComponentName.unflattenFromString(componentName);
- serviceInfo =
- AppGlobals.getPackageManager().getServiceInfo(serviceComponent, 0, userId);
- } catch (RuntimeException | RemoteException e) {
- Slog.wtf(TAG, "Bad auto-fill service name " + componentName, e);
- return null;
- }
- }
-
- if (DEBUG) Slog.d(TAG, "getServiceComponentForUser(" + userId + "): component="
- + serviceComponent + ", info: " + serviceInfo);
- if (serviceInfo == null) {
- Slog.w(TAG, "no service info for " + serviceComponent);
- return null;
- }
- return serviceComponent;
- }
-
- void showAllNotifications() {
- final UserManager userManager =
- (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-
- final List<UserInfo> allUsers = userManager.getUsers(true);
-
- for (UserInfo user : allUsers) {
- final ComponentName serviceComponent = getProviderForUser(user.id);
- if (serviceComponent != null) {
- showMainNotification(serviceComponent, user.id);
- }
- }
- }
-
- void updateNotification(int userId) {
- final ComponentName serviceComponent = getProviderForUser(userId);
- if (serviceComponent == null) {
- cancelMainNotification(userId);
- } else {
- showMainNotification(serviceComponent, userId);
- }
- }
-
private static Intent newNotificationIntent(int userId, String type) {
final Intent intent = new Intent(NOTIFICATION_AUTO_FILL_INTENT);
intent.putExtra(EXTRA_USER_ID, userId);
@@ -296,65 +242,6 @@
}
/**
- * Shows a permanent notification that triggers the auto-fill workflow for the given user.
- *
- * <p>It emulates calling the auto-fill service when the IME is shown.
- */
- private void showMainNotification(ComponentName serviceComponent, int userId) {
- if (DEBUG) Log.d(TAG, "showNotification() for " + userId + ": " + serviceComponent);
-
- synchronized (mLock) {
- if (mNotificationReceiver == null) {
- mNotificationReceiver = new NotificationReceiver();
- mContext.registerReceiver(mNotificationReceiver,
- new IntentFilter(NOTIFICATION_AUTO_FILL_INTENT));
- }
- }
-
- final Intent fillIntent = newNotificationIntent(userId, TYPE_EMULATE);
- final PendingIntent fillPendingIntent = PendingIntent.getBroadcast(mContext,
- -1, fillIntent, PendingIntent.FLAG_UPDATE_CURRENT);
-
- final String packageName = serviceComponent.getPackageName();
- String providerName = null;
- final PackageManager pm = mContext.getPackageManager();
- try {
- final ApplicationInfo info = pm.getApplicationInfoAsUser(packageName, 0, userId);
- if (info != null) {
- providerName = pm.getApplicationLabel(info).toString();
- }
- } catch (Exception e) {
- providerName = packageName;
- }
- final String title = "AutoFill IME Emulation";
- final String subTitle = "Tap notification to start auto-fill workflow (by '" + providerName
- + "' on top activity on user " + userId + ".\n"
- + "Once provider replies, a new notification will show your options.";
-
- final Notification notification = new Notification.Builder(mContext)
- .setCategory(Notification.CATEGORY_SYSTEM)
- .setOngoing(true)
- .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
- .setLocalOnly(true)
- .setColor(mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .setContentTitle(title)
- .setStyle(new Notification.BigTextStyle().bigText(subTitle))
- .setContentIntent(fillPendingIntent)
- .build();
- NotificationManager.from(mContext).notify(TYPE_EMULATE, userId, notification);
- }
-
- /**
- * Cancels the permament notification created by
- * {@link #showMainNotification(ComponentName, int)}.
- */
- private void cancelMainNotification(int userId) {
- if (DEBUG) Log.d(TAG, "cancelNotificationLocked(): " + userId);
- NotificationManager.from(mContext).cancel(TYPE_EMULATE, userId);
- }
-
- /**
* Shows a notification with the results of an auto-fill request, using notications actions
* to emulate the auto-fill bar buttons displaying the dataset names.
*/
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 440ac90..8f99127 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -45,12 +45,16 @@
import android.service.dreams.Sandman;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
+import android.text.TextUtils;
import android.util.Slog;
import android.view.WindowManagerInternal;
import android.view.WindowManagerPolicy;
+import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
import com.android.internal.R;
import com.android.internal.app.DisableCarModeActivity;
@@ -343,6 +347,28 @@
}
@Override
+ public String[] getAvailableThemes() {
+ if (getContext().checkCallingOrSelfPermission(
+ android.Manifest.permission.MODIFY_THEME_OVERLAY)
+ != PackageManager.PERMISSION_GRANTED) {
+ Slog.e(TAG, "getAvailableThemes requires MODIFY_THEME_OVERLAY permission");
+ return null;
+ }
+ String def = SystemProperties.get("ro.boot.vendor.overlay.theme");
+ if (TextUtils.isEmpty(def)) {
+ def = null;
+ }
+ String[] fileList = new File("/vendor/overlay").list();
+ if (fileList == null) return new String[0];
+ ArrayList<String> options = new ArrayList(fileList.length + 1);
+ Collections.addAll(options, fileList);
+ if (!options.contains(def)) {
+ options.add(0, def);
+ }
+ return options.toArray(new String[options.size()]);
+ }
+
+ @Override
public int getNightMode() {
synchronized (mLock) {
return mNightMode;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 973951e..98b5835c 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -557,6 +557,7 @@
void getWindowContainerBounds(Rect outBounds) {
if (mWindowContainerController != null) {
mWindowContainerController.getBounds(outBounds);
+ return;
}
outBounds.setEmpty();
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 13358da8..5e458d4 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -3199,8 +3199,10 @@
if (task == null) {
return false;
}
+ if (!StackId.isStackAffectedByDragResizing(getStackId())) {
+ return false;
+ }
if (mAttrs.width != MATCH_PARENT || mAttrs.height != MATCH_PARENT) {
-
// Floating windows never enter drag resize mode.
return false;
}