Merge "Make JobSchedulerService encryption aware."
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index ddb2d46..7d0d1b4 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -27,7 +27,7 @@
return gApplicationLoaders;
}
- public ClassLoader getClassLoader(String zip, String librarySearchPath,
+ public ClassLoader getClassLoader(String zip, boolean isBundled, String librarySearchPath,
String libraryPermittedPath, ClassLoader parent)
{
/*
@@ -56,7 +56,8 @@
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
PathClassLoader pathClassloader =
- new PathClassLoader(zip, librarySearchPath, libraryPermittedPath, parent);
+ new PathClassLoader(zip, isBundled, librarySearchPath,
+ libraryPermittedPath, parent);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
mLoaders.put(zip, pathClassloader);
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 7313fd1..855b21e 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -366,12 +366,21 @@
}
}
+ String libraryPermittedPath = mAppDir + File.pathSeparator + mDataDir;
+ boolean isBundledApp = false;
+
if (mApplicationInfo.isSystemApp()) {
+ isBundledApp = true;
// Add path to system libraries to libPaths;
// Access to system libs should be limited
// to bundled applications; this is why updated
// system apps are not included.
libPaths.add(System.getProperty("java.library.path"));
+
+ // This is necessary to grant bundled apps access to
+ // libraries located in subdirectories of /system/lib
+ libraryPermittedPath += File.pathSeparator +
+ System.getProperty("java.library.path");
}
final String librarySearchPath = TextUtils.join(File.pathSeparator, libPaths);
@@ -389,10 +398,8 @@
// as this is early and necessary.
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- String libraryPermittedPath = mAppDir + File.pathSeparator + mDataDir;
-
- mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, librarySearchPath,
- libraryPermittedPath, mBaseClassLoader);
+ mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, isBundledApp,
+ librarySearchPath, libraryPermittedPath, mBaseClassLoader);
StrictMode.setThreadPolicy(oldPolicy);
} else {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 620ab50..3ff0896 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3001,6 +3001,7 @@
resetNotificationHeader(contentView);
resetContentMargins(contentView);
contentView.setViewVisibility(R.id.right_icon, View.GONE);
+ contentView.setViewVisibility(R.id.title, View.GONE);
contentView.setTextViewText(R.id.title, null);
contentView.setTextViewText(R.id.text, null);
contentView.setViewVisibility(R.id.line3, View.GONE);
@@ -3047,6 +3048,7 @@
bindNotificationHeader(contentView);
bindLargeIcon(contentView);
if (ex.getCharSequence(EXTRA_TITLE) != null) {
+ contentView.setViewVisibility(R.id.title, View.VISIBLE);
contentView.setTextViewText(R.id.title,
processLegacyText(ex.getCharSequence(EXTRA_TITLE)));
}
@@ -3065,10 +3067,26 @@
}
// Note getStandardView may hide line 3 again.
contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
+ setContentMinHeight(contentView, showProgress || mN.mLargeIcon != null);
return contentView;
}
+ /**
+ * @param remoteView the remote view to update the minheight in
+ * @param hasMinHeight does it have a mimHeight
+ * @hide
+ */
+ void setContentMinHeight(RemoteViews remoteView, boolean hasMinHeight) {
+ int minHeight = 0;
+ if (hasMinHeight) {
+ // we need to set the minHeight of the notification
+ minHeight = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_min_content_height);
+ }
+ remoteView.setInt(R.id.notification_main_column, "setMinimumHeight", minHeight);
+ }
+
private boolean handleProgressBar(boolean hasProgress, RemoteViews contentView, Bundle ex) {
final int max = ex.getInt(EXTRA_PROGRESS_MAX, 0);
final int progress = ex.getInt(EXTRA_PROGRESS, 0);
@@ -3312,6 +3330,37 @@
return applyStandardTemplateWithActions(getBigBaseLayoutResource());
}
+ /**
+ * Construct a RemoteViews for the display in public contexts like on the lockscreen.
+ *
+ * @hide
+ */
+ public RemoteViews makePublicContentView() {
+ if (mN.publicVersion != null) {
+ final Builder builder = recoverBuilder(mContext, mN.publicVersion);
+ return builder.makeContentView();
+ }
+ Bundle savedBundle = mN.extras;
+ Style style = mStyle;
+ mStyle = null;
+ Icon largeIcon = mN.mLargeIcon;
+ mN.mLargeIcon = null;
+ Bundle publicExtras = new Bundle();
+ publicExtras.putBoolean(EXTRA_SHOW_WHEN,
+ savedBundle.getBoolean(EXTRA_SHOW_WHEN));
+ publicExtras.putBoolean(EXTRA_SHOW_CHRONOMETER,
+ savedBundle.getBoolean(EXTRA_SHOW_CHRONOMETER));
+ publicExtras.putCharSequence(EXTRA_TITLE,
+ mContext.getString(R.string.notification_hidden_text));
+ mN.extras = publicExtras;
+ final RemoteViews publicView = applyStandardTemplate(getBaseLayoutResource());
+ mN.extras = savedBundle;
+ mN.mLargeIcon = largeIcon;
+ mStyle = style;
+ return publicView;
+ }
+
+
private RemoteViews generateActionButton(Action action) {
final boolean tombstone = (action.actionIntent == null);
@@ -3801,12 +3850,7 @@
contentView.setTextViewText(R.id.text, mBuilder.processLegacyText(mSummaryText));
contentView.setViewVisibility(R.id.line3, View.VISIBLE);
}
- int imageMinHeight = mBuilder.mContext.getResources().getDimensionPixelSize(
- R.dimen.notification_big_picture_content_min_height_with_picture);
- // We need to make space for the right image, so we're enforcing a minheight if there
- // is a picture.
- int minHeight = (mBuilder.mN.mLargeIcon == null) ? 0 : imageMinHeight;
- contentView.setInt(R.id.notification_main_column, "setMinimumHeight", minHeight);
+ mBuilder.setContentMinHeight(contentView, mBuilder.mN.mLargeIcon != null);
if (mBigLargeIconSet) {
mBuilder.mN.mLargeIcon = oldLargeIcon;
@@ -3873,8 +3917,7 @@
public static class BigTextStyle extends Style {
private static final int MAX_LINES = 13;
- private static final int LINES_CONSUMED_BY_ACTIONS = 3;
- private static final int LINES_CONSUMED_BY_SUMMARY = 2;
+ private static final int LINES_CONSUMED_BY_ACTIONS = 4;
private CharSequence mBigText;
@@ -3944,8 +3987,10 @@
mBuilder.getAllExtras().putCharSequence(EXTRA_TEXT, oldBuilderContentText);
- contentView.setTextViewText(R.id.big_text, mBuilder.processLegacyText(mBigText));
- contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
+ CharSequence bigTextText = mBuilder.processLegacyText(mBigText);
+ contentView.setTextViewText(R.id.big_text, bigTextText);
+ contentView.setViewVisibility(R.id.big_text,
+ TextUtils.isEmpty(bigTextText) ? View.GONE : View.VISIBLE);
contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines());
mBuilder.addProfileBadge(contentView, R.id.profile_badge_large_template);
@@ -3958,14 +4003,9 @@
private int calculateMaxLines() {
int lineCount = MAX_LINES;
boolean hasActions = mBuilder.mActions.size() > 0;
- boolean hasSummary = (mSummaryTextSet ? mSummaryText
- : mBuilder.getAllExtras().getCharSequence(EXTRA_SUB_TEXT)) != null;
if (hasActions) {
lineCount -= LINES_CONSUMED_BY_ACTIONS;
}
- if (hasSummary) {
- lineCount -= LINES_CONSUMED_BY_SUMMARY;
- }
return lineCount;
}
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2d7ea2e..537f887 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12482,8 +12482,7 @@
* Determines whether the given point, in local coordinates is inside the view.
*/
/*package*/ final boolean pointInView(float localX, float localY) {
- return localX >= 0 && localX < (mRight - mLeft)
- && localY >= 0 && localY < (mBottom - mTop);
+ return pointInView(localX, localY, 0);
}
/**
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 6ecb3fb..88a56d2 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -270,7 +270,7 @@
bool needNativeBridge = false;
void* handle = OpenNativeLibrary(env, sdkVersion, pathStr, classLoader,
- libraryPath, isolationPath);
+ false, libraryPath, isolationPath);
if (handle == NULL) {
if (NativeBridgeIsSupported(pathStr)) {
handle = NativeBridgeLoadLibrary(pathStr, RTLD_LAZY);
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index b69eb24..fdbbbd6 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -25,12 +25,12 @@
<LinearLayout
android:id="@+id/notification_main_column"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginStart="@dimen/notification_content_margin_start"
android:layout_marginEnd="@dimen/notification_content_margin_end"
android:layout_marginTop="@dimen/notification_content_margin_top"
- android:minHeight="@dimen/notification_min_content_height"
+ android:layout_marginBottom="@dimen/notification_content_margin_bottom"
android:orientation="vertical"
>
<include layout="@layout/notification_template_part_line1" />
@@ -42,7 +42,7 @@
android:layout_gravity="bottom"
android:layout_marginStart="@dimen/notification_content_margin_start"
android:layout_marginBottom="11dp"
- android:layout_marginEnd="@dimen/notification_content_margin_end">
+ android:layout_marginEnd="@dimen/notification_content_margin_end" >
<include layout="@layout/notification_template_progress" />
</FrameLayout>
<include layout="@layout/notification_template_right_icon" />
diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml
index eb02e8b..91a5ceb 100644
--- a/core/res/res/layout/notification_template_material_big_base.xml
+++ b/core/res/res/layout/notification_template_material_big_base.xml
@@ -25,7 +25,7 @@
<FrameLayout
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
- android:layout_height="@dimen/notification_min_height"
+ android:layout_height="wrap_content"
android:layout_gravity="top"
android:tag="base"
>
@@ -38,7 +38,7 @@
android:layout_marginStart="@dimen/notification_content_margin_start"
android:layout_marginEnd="@dimen/notification_content_margin_end"
android:layout_marginTop="@dimen/notification_content_margin_top"
- android:minHeight="@dimen/notification_min_content_height"
+ android:layout_marginBottom="@dimen/notification_content_margin_bottom"
android:orientation="vertical"
>
<include layout="@layout/notification_template_part_line1" />
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index 0427c8a..c3db7c5 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -33,6 +33,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/notification_content_margin_top"
android:layout_marginStart="@dimen/notification_content_margin_start"
+ android:layout_marginBottom="@dimen/notification_content_margin_bottom"
android:layout_marginEnd="24dp"
android:layout_toStartOf="@id/right_icon"
android:minHeight="@dimen/notification_min_content_height"
diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml
index 9e010f2..de9f572 100644
--- a/core/res/res/layout/notification_template_material_big_text.xml
+++ b/core/res/res/layout/notification_template_material_big_text.xml
@@ -39,10 +39,11 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
- android:paddingBottom="13dp"
+ android:paddingBottom="@dimen/notification_content_margin_bottom"
android:orientation="horizontal"
android:gravity="top"
android:layout_weight="1"
+ android:layout_marginTop="1.5dp"
>
<com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text"
android:textAppearance="@style/TextAppearance.Material.Notification"
diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml
index 8c0abc9..14bf899 100644
--- a/core/res/res/layout/notification_template_material_inbox.xml
+++ b/core/res/res/layout/notification_template_material_inbox.xml
@@ -123,13 +123,6 @@
android:visibility="gone"
android:layout_weight="1"
/>
- <FrameLayout
- android:id="@+id/inbox_end_pad"
- android:layout_width="match_parent"
- android:layout_height="13dp"
- android:visibility="gone"
- android:layout_weight="0"
- />
<include layout="@layout/notification_material_action_list" />
</LinearLayout>
<include layout="@layout/notification_template_right_icon" />
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index dc4afb8..f0ced5f 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -29,7 +29,7 @@
<LinearLayout
android:id="@+id/notification_main_column"
android:layout_width="match_parent"
- android:layout_height="@dimen/notification_min_content_height"
+ android:layout_height="wrap_content"
android:background="#00000000"
android:orientation="horizontal"
android:layout_marginStart="@dimen/notification_content_margin_start"
@@ -43,6 +43,7 @@
android:layout_gravity="fill_vertical"
android:layout_weight="1"
android:minHeight="@dimen/notification_min_content_height"
+ android:paddingBottom="@dimen/notification_content_margin_bottom"
android:orientation="vertical"
>
<include layout="@layout/notification_template_part_line1"/>
diff --git a/core/res/res/layout/notification_template_part_line1.xml b/core/res/res/layout/notification_template_part_line1.xml
index e7ac408..308b30f 100644
--- a/core/res/res/layout/notification_template_part_line1.xml
+++ b/core/res/res/layout/notification_template_part_line1.xml
@@ -20,7 +20,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:layout_marginBottom="1dp"
>
<TextView android:id="@+id/title"
android:textAppearance="@style/TextAppearance.Material.Notification.Title"
diff --git a/core/res/res/layout/notification_template_part_line3.xml b/core/res/res/layout/notification_template_part_line3.xml
index 76337ac..dc47a48 100644
--- a/core/res/res/layout/notification_template_part_line3.xml
+++ b/core/res/res/layout/notification_template_part_line3.xml
@@ -20,17 +20,18 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
- android:gravity="center_vertical"
+ android:gravity="top"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.Material.Notification"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:layout_gravity="center"
+ android:layout_gravity="top"
android:singleLine="true"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
+ android:layout_marginTop="1.5dp"
/>
<ImageView android:id="@+id/profile_badge_line3"
android:layout_width="@dimen/notification_badge_size"
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index b167711..ec24af5 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -142,6 +142,9 @@
<!-- height of the content margin to accomodate for the header -->
<dimen name="notification_content_margin_top">30dp</dimen>
+ <!-- height of the content margin on the bottom -->
+ <dimen name="notification_content_margin_bottom">13dp</dimen>
+
<!-- height of notification header view if present -->
<dimen name="notification_header_height">32dp</dimen>
@@ -153,14 +156,11 @@
<!-- The width of the big icons in notifications. -->
<dimen name="notification_large_icon_height">64dp</dimen>
- <!-- Min height of the notification content. -->
- <dimen name="notification_min_content_height">54dp</dimen>
-
<!-- The minimum width of the app name in the header if it shrinks -->
<dimen name="notification_header_shrink_min_width">72dp</dimen>
- <!-- The minimum height of the content if there is a picture present with big picture -->
- <dimen name="notification_big_picture_content_min_height_with_picture">41dp</dimen>
+ <!-- The minimum height of the content if there are at least two lines or a picture-->
+ <dimen name="notification_min_content_height">41dp</dimen>
<!-- Preferred width of the search view. -->
<dimen name="search_view_preferred_width">320dip</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a127d94..595ef54 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -537,6 +537,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>
+ <!-- Text shown in place of notification contents when the notification is hidden on a secure lockscreen -->
+ <string name="notification_hidden_text">Contents hidden</string>
+
<!-- Displayed to the user to tell them that they have started up the phone in "safe mode" -->
<string name="safeMode">Safe mode</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3ee1ca9..2c54af7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2362,6 +2362,7 @@
<java-symbol type="id" name="deleteButton" />
<java-symbol type="string" name="notification_children_count_bracketed" />
+ <java-symbol type="string" name="notification_hidden_text" />
<java-symbol type="id" name="app_name_text" />
<java-symbol type="id" name="number_of_children" />
<java-symbol type="id" name="header_sub_text" />
@@ -2377,7 +2378,7 @@
<java-symbol type="drawable" name="ic_expand_bundle" />
<java-symbol type="drawable" name="ic_collapse_bundle" />
<java-symbol type="dimen" name="notification_header_height" />
- <java-symbol type="dimen" name="notification_big_picture_content_min_height_with_picture" />
+ <java-symbol type="dimen" name="notification_min_content_height" />
<java-symbol type="dimen" name="notification_header_shrink_min_width" />
<java-symbol type="dimen" name="notification_content_margin_start" />
<java-symbol type="dimen" name="notification_content_margin_end" />
diff --git a/libs/common_time/common_time_server.cpp b/libs/common_time/common_time_server.cpp
index 01372e0..f72ffaa 100644
--- a/libs/common_time/common_time_server.cpp
+++ b/libs/common_time/common_time_server.cpp
@@ -143,7 +143,7 @@
// Create the eventfd we will use to signal our thread to wake up when
// needed.
- mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
+ mWakeupThreadFD = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
// seed the random number generator (used to generated timeline IDs)
srand48(static_cast<unsigned int>(systemTime()));
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 0cea7ae..62fdd42 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -65,7 +65,7 @@
android:id="@+id/notification_guts_stub"
android:inflatedId="@+id/notification_guts"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
/>
</com.android.systemui.statusbar.ExpandableNotificationRow>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f70f38b..24cc6bf 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -49,11 +49,14 @@
<dimen name="notification_max_heads_up_height_legacy">128dp</dimen>
<!-- Height of a heads up notification in the status bar -->
- <dimen name="notification_max_heads_up_height">140dp</dimen>
+ <dimen name="notification_max_heads_up_height">141dp</dimen>
<!-- Height of a the summary ("more card") notification on keyguard. -->
<dimen name="notification_summary_height">44dp</dimen>
+ <!-- Minimum layouted height of a notification in the statusbar-->
+ <dimen name="min_notification_layout_height">48dp</dimen>
+
<!-- size at which Notification icons will be drawn in the status bar -->
<dimen name="status_bar_icon_drawing_size">17dip</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 50e0661..6658cfe 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -906,9 +906,6 @@
<!-- Battery saver notification action text. [CHAR LIMIT=60] -->
<string name="battery_saver_notification_action_text">Turn off battery saver</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>
-
<!-- Media projection permission dialog warning text. [CHAR LIMIT=NONE] -->
<string name="media_projection_dialog_text"><xliff:g id="app_seeking_permission" example="Hangouts">%s</xliff:g> will start capturing everything that\'s displayed on your screen.</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index aad428a..7e01866 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -237,12 +237,6 @@
<item name="android:gravity">center</item>
</style>
- <style name="TextAppearance.Material.Notification.Parenthetical"
- parent="@*android:style/TextAppearance.Material.Notification">
- <item name="android:textStyle">italic</item>
- <item name="android:textColor">#60000000</item>
- </style>
-
<style name="TextAppearance.Material.Notification.HeaderTitle"
parent="@*android:style/TextAppearance.Material.Notification.Info">
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a6ca50a..3537d3e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -110,6 +110,7 @@
import com.android.systemui.statusbar.policy.PreviewInflater;
import com.android.systemui.statusbar.policy.RemoteInputView;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
import java.util.ArrayList;
import java.util.List;
@@ -988,9 +989,7 @@
protected SwipeHelper.LongPressListener getNotificationLongClicker() {
return new SwipeHelper.LongPressListener() {
@Override
- public boolean onLongPress(View v, int x, int y) {
- dismissPopups();
-
+ public boolean onLongPress(View v, final int x, final int y) {
if (!(v instanceof ExpandableNotificationRow)) {
return false;
}
@@ -1011,41 +1010,57 @@
// Already showing?
if (guts.getVisibility() == View.VISIBLE) {
- Log.e(TAG, "Trying to show notification guts, but already visible");
+ dismissPopups(x, y);
return false;
}
MetricsLogger.action(mContext, MetricsLogger.ACTION_NOTE_CONTROLS);
- guts.setVisibility(View.VISIBLE);
- final double horz = Math.max(guts.getWidth() - x, x);
- final double vert = Math.max(guts.getActualHeight() - y, y);
- final float r = (float) Math.hypot(horz, vert);
- final Animator a
- = ViewAnimationUtils.createCircularReveal(guts, x, y, 0, r);
- a.setDuration(400);
- a.setInterpolator(mLinearOutSlowIn);
- a.start();
-
- mNotificationGutsExposed = guts;
-
+ // ensure that it's layouted but not visible until actually laid out
+ guts.setVisibility(View.INVISIBLE);
+ // Post to ensure the the guts are properly layed out.
+ guts.post(new Runnable() {
+ public void run() {
+ dismissPopups();
+ guts.setVisibility(View.VISIBLE);
+ final double horz = Math.max(guts.getWidth() - x, x);
+ final double vert = Math.max(guts.getHeight() - y, y);
+ final float r = (float) Math.hypot(horz, vert);
+ final Animator a
+ = ViewAnimationUtils.createCircularReveal(guts, x, y, 0, r);
+ a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ a.setInterpolator(mLinearOutSlowIn);
+ a.start();
+ guts.setExposed(true);
+ mStackScroller.onHeightChanged(null, true /* needsAnimation */);
+ mNotificationGutsExposed = guts;
+ }
+ });
return true;
}
};
}
public void dismissPopups() {
+ dismissPopups(-1, -1);
+ }
+
+ private void dismissPopups(int x, int y) {
if (mNotificationGutsExposed != null) {
final NotificationGuts v = mNotificationGutsExposed;
mNotificationGutsExposed = null;
if (v.getWindowToken() == null) return;
-
- final int x = (v.getLeft() + v.getRight()) / 2;
- final int y = (v.getTop() + v.getActualHeight() / 2);
+ if (x == -1 || y == -1) {
+ x = (v.getLeft() + v.getRight()) / 2;
+ y = (v.getTop() + v.getHeight() / 2);
+ }
+ final double horz = Math.max(v.getWidth() - x, x);
+ final double vert = Math.max(v.getHeight() - y, y);
+ final float r = (float) Math.hypot(horz, vert);
final Animator a = ViewAnimationUtils.createCircularReveal(v,
- x, y, x, 0);
- a.setDuration(200);
+ x, y, r, 0);
+ a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
a.setInterpolator(mFastOutLinearIn);
a.addListener(new AnimatorListenerAdapter() {
@Override
@@ -1055,6 +1070,8 @@
}
});
a.start();
+ v.setExposed(false);
+ mStackScroller.onHeightChanged(null, true /* needsAnimation */);
}
}
@@ -1382,6 +1399,7 @@
View contentViewLocal = null;
View bigContentViewLocal = null;
View headsUpContentViewLocal = null;
+ View publicViewLocal = null;
try {
contentViewLocal = contentView.apply(
sbn.getPackageContext(mContext),
@@ -1399,6 +1417,11 @@
contentContainer,
mOnClickHandler);
}
+ if (publicContentView != null) {
+ publicViewLocal = publicContentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainerPublic, mOnClickHandler);
+ }
}
catch (RuntimeException e) {
final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
@@ -1418,25 +1441,9 @@
headsUpContentViewLocal.setIsRootNamespace(true);
contentContainer.setHeadsUpChild(headsUpContentViewLocal);
}
-
- // now the public version
- View publicViewLocal = null;
- if (publicContentView != null) {
- try {
- publicViewLocal = publicContentView.apply(
- sbn.getPackageContext(mContext),
- contentContainerPublic, mOnClickHandler);
-
- if (publicViewLocal != null) {
- publicViewLocal.setIsRootNamespace(true);
- contentContainerPublic.setContractedChild(publicViewLocal);
- }
- }
- catch (RuntimeException e) {
- final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
- Log.e(TAG, "couldn't inflate public view for notification " + ident, e);
- publicViewLocal = null;
- }
+ if (publicViewLocal != null) {
+ publicViewLocal.setIsRootNamespace(true);
+ contentContainerPublic.setContractedChild(publicViewLocal);
}
// Extract target SDK version.
@@ -1446,65 +1453,7 @@
} catch (NameNotFoundException ex) {
Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
}
-
- if (publicViewLocal == null) {
- // Add a basic notification template
- publicViewLocal = LayoutInflater.from(mContext).inflate(
- R.layout.notification_public_default,
- contentContainerPublic, false);
- publicViewLocal.setIsRootNamespace(true);
-
- final TextView title = (TextView) publicViewLocal.findViewById(R.id.title);
- try {
- title.setText(pmUser.getApplicationLabel(
- pmUser.getApplicationInfo(entry.notification.getPackageName(), 0)));
- } catch (NameNotFoundException e) {
- title.setText(entry.notification.getPackageName());
- }
-
- final ImageView icon = (ImageView) publicViewLocal.findViewById(R.id.icon);
- final ImageView profileBadge = (ImageView) publicViewLocal.findViewById(
- R.id.profile_badge_line3);
-
- final StatusBarIcon ic = new StatusBarIcon(
- entry.notification.getUser(),
- entry.notification.getPackageName(),
- entry.notification.getNotification().getSmallIcon(),
- entry.notification.getNotification().iconLevel,
- entry.notification.getNotification().number,
- entry.notification.getNotification().tickerText);
-
- Drawable iconDrawable = StatusBarIconView.getIcon(mContext, ic);
- icon.setImageDrawable(iconDrawable);
-
- if (profileBadge != null) {
- Drawable profileDrawable = mContext.getPackageManager().getUserBadgeForDensity(
- entry.notification.getUser(), 0);
- if (profileDrawable != null) {
- profileBadge.setImageDrawable(profileDrawable);
- profileBadge.setVisibility(View.VISIBLE);
- } else {
- profileBadge.setVisibility(View.GONE);
- }
- }
-
- final View privateTime = contentViewLocal.findViewById(com.android.internal.R.id.time);
- final DateTimeView time = (DateTimeView) publicViewLocal.findViewById(R.id.time);
- if (privateTime != null && privateTime.getVisibility() == View.VISIBLE) {
- time.setVisibility(View.VISIBLE);
- time.setTime(entry.notification.getNotification().when);
- }
-
- final TextView text = (TextView) publicViewLocal.findViewById(R.id.text);
- if (text != null) {
- text.setText(R.string.notification_hidden_text);
- text.setTextAppearance(mContext,
- R.style.TextAppearance_Material_Notification_Parenthetical);
- }
-
- contentContainerPublic.setContractedChild(publicViewLocal);
- entry.autoRedacted = true;
- }
+ entry.autoRedacted = entry.notification.getNotification().publicVersion == null;
if (MULTIUSER_DEBUG) {
TextView debug = (TextView) row.findViewById(R.id.debug_info);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 874b76a..83853a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -25,12 +25,10 @@
import android.os.Build;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewStub;
import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.LinearInterpolator;
import android.widget.Chronometer;
import android.widget.ImageView;
import android.widget.RemoteViews;
@@ -49,13 +47,11 @@
private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
private static final int COLORED_DIVIDER_ALPHA = 0x7B;
- private final LinearInterpolator mLinearInterpolator = new LinearInterpolator();
private final int mNotificationMinHeightLegacy;
private final int mMaxHeadsUpHeightLegacy;
private final int mMaxHeadsUpHeight;
private final int mNotificationMinHeight;
private final int mNotificationMaxHeight;
- private int mRowMinHeight;
/** Does this row contain layouts that can adapt to row expansion */
private boolean mExpandable;
@@ -117,7 +113,7 @@
private OnClickListener mExpandClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
- if (mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
+ if (!mShowingPublic && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
mGroupManager.toggleGroupExpansion(mStatusBarNotification);
mOnExpandClickListener.onExpandClicked(ExpandableNotificationRow.this,
mGroupManager.isGroupExpanded(mStatusBarNotification));
@@ -212,6 +208,8 @@
mNotificationParent.updateChildrenHeaderAppearance();
}
onChildrenCountChanged();
+ // The public layouts expand button is always visible
+ mPublicLayout.updateExpandButtons(true);
updateLimits();
}
@@ -226,10 +224,9 @@
!= com.android.internal.R.id.status_bar_latest_event_content;
int headsUpheight = headsUpCustom && beforeN ? mMaxHeadsUpHeightLegacy
: mMaxHeadsUpHeight;
- mRowMinHeight = minHeight;
mMaxViewHeight = mNotificationMaxHeight;
- mPrivateLayout.setHeights(mRowMinHeight, headsUpheight);
- mPublicLayout.setHeights(mRowMinHeight, headsUpheight);
+ mPrivateLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
+ mPublicLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight);
}
public StatusBarNotification getStatusBarNotification() {
@@ -489,7 +486,6 @@
@Override
public void reset() {
super.reset();
- mRowMinHeight = 0;
final boolean wasExpanded = isExpanded();
mMaxViewHeight = 0;
mExpandable = false;
@@ -518,11 +514,6 @@
}
@Override
- protected boolean filterMotionEvent(MotionEvent event) {
- return mIsHeadsUp || super.filterMotionEvent(event);
- }
-
- @Override
protected void onFinishInflate() {
super.onFinishInflate();
mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
@@ -558,12 +549,15 @@
}
private void updateChildrenVisibility() {
+ mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? VISIBLE
+ : INVISIBLE);
if (mChildrenContainer == null) {
return;
}
- mChildrenContainer.setVisibility(mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
- mNotificationHeader.setVisibility(mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
- mPrivateLayout.setVisibility(!mIsSummaryWithChildren ? VISIBLE : INVISIBLE);
+ mChildrenContainer.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
+ : INVISIBLE);
+ mNotificationHeader.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
+ : INVISIBLE);
// The limits might have changed if the view suddenly became a group or vice versa
updateLimits();
}
@@ -715,7 +709,7 @@
if (expand && mExpandable) {
setActualHeight(mMaxExpandHeight);
} else {
- setActualHeight(mRowMinHeight);
+ setActualHeight(getMinHeight());
}
}
@@ -725,20 +719,24 @@
return getActualHeight();
}
boolean inExpansionState = isExpanded();
- if (mSensitive && mHideSensitiveForIntrinsicHeight) {
- return mRowMinHeight;
+ if (mGuts != null && mGuts.areGutsExposed()) {
+ return mGuts.getHeight();
+ } else if ((isChildInGroup() && !isGroupExpanded())) {
+ return mPrivateLayout.getMinHeight();
+ } else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
+ return getMinHeight();
} else if (mIsSummaryWithChildren && !mOnKeyguard) {
return mChildrenContainer.getIntrinsicHeight();
} else if (mIsHeadsUp) {
if (inExpansionState) {
- return Math.max(mMaxExpandHeight, mHeadsUpHeight);
+ return Math.max(getMaxExpandHeight(), mHeadsUpHeight);
} else {
- return Math.max(mRowMinHeight, mHeadsUpHeight);
+ return Math.max(getMinHeight(), mHeadsUpHeight);
}
- } else if (!inExpansionState || (isChildInGroup() && !isGroupExpanded())) {
- return getMinHeight();
- } else {
+ } else if (inExpansionState) {
return getMaxExpandHeight();
+ } else {
+ return getMinHeight();
}
}
@@ -845,8 +843,7 @@
mPublicLayout.setAlpha(1f);
mPrivateLayout.setAlpha(1f);
mPublicLayout.setVisibility(mShowingPublic ? View.VISIBLE : View.INVISIBLE);
- mPrivateLayout.setVisibility(!mShowingPublic && !mIsSummaryWithChildren ? View.VISIBLE
- : View.INVISIBLE);
+ updateChildrenVisibility();
} else {
animateShowingPublic(delay, duration);
}
@@ -857,27 +854,35 @@
}
private void animateShowingPublic(long delay, long duration) {
- final View source = mShowingPublic ? mPrivateLayout : mPublicLayout;
- View target = mShowingPublic ? mPublicLayout : mPrivateLayout;
- source.setVisibility(View.VISIBLE);
- target.setVisibility(View.VISIBLE);
- target.setAlpha(0f);
- source.animate().cancel();
- target.animate().cancel();
- source.animate()
- .alpha(0f)
- .setStartDelay(delay)
- .setDuration(duration)
- .withEndAction(new Runnable() {
- @Override
- public void run() {
- source.setVisibility(View.INVISIBLE);
- }
- });
- target.animate()
- .alpha(1f)
- .setStartDelay(delay)
- .setDuration(duration);
+ View[] privateViews = mIsSummaryWithChildren ?
+ new View[] {mChildrenContainer, mNotificationHeader}
+ : new View[] {mPrivateLayout};
+ View[] publicViews = new View[] {mPublicLayout};
+ View[] hiddenChildren = mShowingPublic ? privateViews : publicViews;
+ View[] shownChildren = mShowingPublic ? publicViews : privateViews;
+ for (final View hiddenView : hiddenChildren) {
+ hiddenView.setVisibility(View.VISIBLE);
+ hiddenView.animate().cancel();
+ hiddenView.animate()
+ .alpha(0f)
+ .setStartDelay(delay)
+ .setDuration(duration)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ hiddenView.setVisibility(View.INVISIBLE);
+ }
+ });
+ }
+ for (View showView : shownChildren) {
+ showView.setVisibility(View.VISIBLE);
+ showView.setAlpha(0f);
+ showView.animate().cancel();
+ showView.animate()
+ .alpha(1f)
+ .setStartDelay(delay)
+ .setDuration(duration);
+ }
}
private void updateVetoButton() {
@@ -956,6 +961,9 @@
@Override
public int getMinHeight() {
+ if (mIsSummaryWithChildren && !isGroupExpanded() && !mShowingPublic) {
+ return mChildrenContainer.getMinHeight();
+ }
NotificationContentView showingLayout = getShowingLayout();
return showingLayout.getMinHeight();
}
@@ -963,17 +971,12 @@
@Override
public int getMinExpandHeight() {
if (mIsSummaryWithChildren && !mOnKeyguard) {
- return mChildrenContainer.getMinHeight();
+ return mChildrenContainer.getMinExpandHeight();
}
return getMinHeight();
}
@Override
- protected boolean shouldLimitViewHeight() {
- return !mIsSummaryWithChildren;
- }
-
- @Override
public void setClipTopAmount(int clipTopAmount) {
super.setClipTopAmount(clipTopAmount);
mPrivateLayout.setClipTopAmount(clipTopAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 59cbd40..d6855a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -20,10 +20,10 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
+
import com.android.systemui.R;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -45,7 +45,6 @@
private static Rect mClipRect = new Rect();
private boolean mWillBeGone;
private int mMinClipTopAmount = 0;
- private boolean mMeasuredTooHigh;
public ExpandableView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -55,13 +54,10 @@
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- boolean limitViewHeight = shouldLimitViewHeight();
final int givenSize = MeasureSpec.getSize(heightMeasureSpec);
- int ownMaxHeight = limitViewHeight ? mMaxViewHeight : Integer.MAX_VALUE;
+ int ownMaxHeight = Integer.MAX_VALUE;
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
- boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
- if (hasFixedHeight) {
- // We have a height set in our layout, so we want to be at most as big as given
+ if (heightMode != MeasureSpec.UNSPECIFIED && givenSize != 0) {
ownMaxHeight = Math.min(givenSize, ownMaxHeight);
}
int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
@@ -77,7 +73,7 @@
if (layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT) {
if (layoutParams.height >= 0) {
// An actual height is set
- childHeightSpec = layoutParams.height > ownMaxHeight && limitViewHeight
+ childHeightSpec = layoutParams.height > ownMaxHeight
? MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.EXACTLY)
: MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
}
@@ -90,7 +86,8 @@
mMatchParentViews.add(child);
}
}
- int ownHeight = hasFixedHeight ? ownMaxHeight : Math.min(ownMaxHeight, maxChildHeight);
+ int ownHeight = heightMode == MeasureSpec.EXACTLY
+ ? givenSize : Math.min(ownMaxHeight, maxChildHeight);
newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
for (View child : mMatchParentViews) {
child.measure(getChildMeasureSpec(
@@ -100,11 +97,6 @@
mMatchParentViews.clear();
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width, ownHeight);
- mMeasuredTooHigh = heightMode != MeasureSpec.UNSPECIFIED && ownHeight > givenSize;
- }
-
- protected boolean shouldLimitViewHeight() {
- return true;
}
@Override
@@ -133,26 +125,11 @@
}
@Override
- public boolean dispatchGenericMotionEvent(MotionEvent ev) {
- if (filterMotionEvent(ev)) {
- return super.dispatchGenericMotionEvent(ev);
- }
- return false;
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (filterMotionEvent(ev)) {
- return super.dispatchTouchEvent(ev);
- }
- return false;
- }
-
- protected boolean filterMotionEvent(MotionEvent event) {
- return event.getActionMasked() != MotionEvent.ACTION_DOWN
- && event.getActionMasked() != MotionEvent.ACTION_HOVER_ENTER
- && event.getActionMasked() != MotionEvent.ACTION_HOVER_MOVE
- || event.getY() > mClipTopAmount && event.getY() < mActualHeight;
+ public boolean pointInView(float localX, float localY, float slop) {
+ float top = mClipTopAmount;
+ float bottom = mActualHeight;
+ return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) &&
+ localY < (bottom + slop);
}
/**
@@ -397,7 +374,8 @@
@Override
public boolean hasOverlappingRendering() {
- return super.hasOverlappingRendering() && !mMeasuredTooHigh;
+ // Otherwise it will be clipped
+ return super.hasOverlappingRendering() && getActualHeight() <= getHeight();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 6d90329..02a39e7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -24,6 +24,7 @@
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
+import android.os.Build;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
import android.view.NotificationHeaderView;
@@ -58,6 +59,8 @@
private final int mRoundRectRadius;
private final Interpolator mLinearInterpolator = new LinearInterpolator();
private final boolean mRoundRectClippingEnabled;
+ private final int mMinContractedHeight;
+
private View mContractedChild;
private View mExpandedChild;
@@ -80,6 +83,7 @@
private boolean mIsChildInGroup;
private int mSmallHeight;
private int mHeadsUpHeight;
+ private int mNotificationMaxHeight;
private StatusBarNotification mStatusBarNotification;
private NotificationGroupManager mGroupManager;
private RemoteInputController mRemoteInputController;
@@ -102,6 +106,8 @@
}
};
private OnClickListener mExpandClickListener;
+ private boolean mBeforeN;
+ private boolean mExpandable;
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -111,13 +117,16 @@
R.dimen.notification_material_rounded_rect_radius);
mRoundRectClippingEnabled = getResources().getBoolean(
R.bool.config_notifications_round_rect_clipping);
+ mMinContractedHeight = getResources().getDimensionPixelSize(
+ R.dimen.min_notification_layout_height);
reset(true);
setOutlineProvider(mOutlineProvider);
}
- public void setHeights(int smallHeight, int headsUpMaxHeight) {
+ public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight) {
mSmallHeight = smallHeight;
mHeadsUpHeight = headsUpMaxHeight;
+ mNotificationMaxHeight = maxHeight;
}
@Override
@@ -131,13 +140,23 @@
}
int maxChildHeight = 0;
if (mContractedChild != null) {
- int size = Math.min(maxSize, mSmallHeight);
- mContractedChild.measure(widthMeasureSpec,
- MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY));
- maxChildHeight = Math.max(maxChildHeight, mContractedChild.getMeasuredHeight());
+ int heightSpec;
+ if (shouldContractedBeFixedSize()) {
+ int size = Math.min(maxSize, mSmallHeight);
+ heightSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
+ } else {
+ heightSpec = MeasureSpec.makeMeasureSpec(maxSize, MeasureSpec.AT_MOST);
+ }
+ mContractedChild.measure(widthMeasureSpec, heightSpec);
+ int measuredHeight = mContractedChild.getMeasuredHeight();
+ if (measuredHeight < mMinContractedHeight) {
+ heightSpec = MeasureSpec.makeMeasureSpec(mMinContractedHeight, MeasureSpec.EXACTLY);
+ mContractedChild.measure(widthMeasureSpec, heightSpec);
+ }
+ maxChildHeight = Math.max(maxChildHeight, measuredHeight);
}
if (mExpandedChild != null) {
- int size = maxSize;
+ int size = Math.min(maxSize, mNotificationMaxHeight);
ViewGroup.LayoutParams layoutParams = mExpandedChild.getLayoutParams();
if (layoutParams.height >= 0) {
// An actual height is set
@@ -170,6 +189,10 @@
setMeasuredDimension(width, ownHeight);
}
+ private boolean shouldContractedBeFixedSize() {
+ return mBeforeN && mContractedWrapper instanceof NotificationCustomViewWrapper;
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -292,14 +315,14 @@
} else if (mIsHeadsUp && mHeadsUpChild != null) {
return mHeadsUpChild.getHeight();
}
- return mSmallHeight;
+ return mContractedChild.getHeight();
}
public int getMinHeight() {
if (mIsChildInGroup && !isGroupExpanded()) {
return mSingleLineView.getHeight();
} else {
- return mSmallHeight;
+ return mContractedChild.getHeight();
}
}
@@ -435,6 +458,9 @@
if (!noExpandedChild && mContentHeight == mExpandedChild.getHeight()) {
return VISIBLE_TYPE_EXPANDED;
}
+ if (mIsChildInGroup && !isGroupExpanded()) {
+ return VISIBLE_TYPE_SINGLELINE;
+ }
if (mIsHeadsUp && mHeadsUpChild != null) {
if (mContentHeight <= mHeadsUpChild.getHeight() || noExpandedChild) {
@@ -443,9 +469,7 @@
return VISIBLE_TYPE_EXPANDED;
}
} else {
- if (mIsChildInGroup && !isGroupExpanded()) {
- return VISIBLE_TYPE_SINGLELINE;
- } else if (mContentHeight <= mSmallHeight || noExpandedChild) {
+ if (mContentHeight <= mContractedChild.getHeight() || noExpandedChild) {
return VISIBLE_TYPE_CONTRACTED;
} else {
return VISIBLE_TYPE_EXPANDED;
@@ -469,6 +493,7 @@
public void setHeadsUp(boolean headsUp) {
mIsHeadsUp = headsUp;
selectLayout(false /* animate */, true /* force */);
+ updateExpandButtons(mExpandable);
}
@Override
@@ -490,6 +515,7 @@
public void onNotificationUpdated(NotificationData.Entry entry) {
mStatusBarNotification = entry.notification;
+ mBeforeN = entry.targetSdk < Build.VERSION_CODES.N;
updateSingleLineView();
applyRemoteInput(entry);
selectLayout(false /* animate */, true /* force */);
@@ -587,6 +613,13 @@
}
public void updateExpandButtons(boolean expandable) {
+ mExpandable = expandable;
+ // if the expanded child has the same height as the collapsed one we hide it.
+ if (mExpandedChild != null && mExpandedChild.getHeight() != 0 &&
+ ((mIsHeadsUp && mExpandedChild.getHeight() == mHeadsUpChild.getHeight()) ||
+ (!mIsHeadsUp && mExpandedChild.getHeight() == mContractedChild.getHeight()))) {
+ expandable = false;
+ }
if (mExpandedChild != null) {
mExpandedWrapper.updateExpandability(expandable, mExpandClickListener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index c458d21..f7680a7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -115,17 +115,14 @@
updatedNotificationBuilder.makeBigContentView();
final RemoteViews newHeadsUpContentView =
updatedNotificationBuilder.makeHeadsUpContentView();
- final Notification updatedPublicNotification = updatedNotification.publicVersion;
- final RemoteViews newPubContentView = (updatedPublicNotification != null)
- ? Notification.Builder.recoverBuilder(
- ctx, updatedPublicNotification).makeContentView()
- : null;
+ final RemoteViews newPublicNotification
+ = updatedNotificationBuilder.makePublicContentView();
applyInPlace = compareRemoteViews(cachedContentView, newContentView)
&& compareRemoteViews(cachedBigContentView, newBigContentView)
&& compareRemoteViews(cachedHeadsUpContentView, newHeadsUpContentView)
- && compareRemoteViews(cachedPublicContentView, newPubContentView);
- cachedPublicContentView = newPubContentView;
+ && compareRemoteViews(cachedPublicContentView, newPublicNotification);
+ cachedPublicContentView = newPublicNotification;
cachedHeadsUpContentView = newHeadsUpContentView;
cachedBigContentView = newBigContentView;
cachedContentView = newContentView;
@@ -136,14 +133,8 @@
cachedContentView = builder.makeContentView();
cachedBigContentView = builder.makeBigContentView();
cachedHeadsUpContentView = builder.makeHeadsUpContentView();
+ cachedPublicContentView = builder.makePublicContentView();
- final Notification publicNotification =
- notification.getNotification().publicVersion;
- if (publicNotification != null) {
- final Notification.Builder publicBuilder
- = Notification.Builder.recoverBuilder(ctx, publicNotification);
- cachedPublicContentView = publicBuilder.makeContentView();
- }
applyInPlace = false;
}
return applyInPlace;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 79236be..6850f7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -45,6 +45,7 @@
private Drawable mBackground;
private int mClipTopAmount;
private int mActualHeight;
+ private boolean mExposed;
public NotificationGuts(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -224,4 +225,12 @@
// Prevents this view from creating a layer when alpha is animating.
return false;
}
+
+ public void setExposed(boolean exposed) {
+ mExposed = exposed;
+ }
+
+ public boolean areGutsExposed() {
+ return mExposed;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 5cfd174..b38c3fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -378,23 +378,22 @@
return;
}
if (mHasPinnedNotification) {
- int minX = Integer.MAX_VALUE;
+ int minX = 0;
int maxX = 0;
- int minY = Integer.MAX_VALUE;
int maxY = 0;
for (HeadsUpEntry entry : mSortedEntries) {
ExpandableNotificationRow row = entry.entry.row;
if (row.isPinned()) {
row.getLocationOnScreen(mTmpTwoArray);
- minX = Math.min(minX, mTmpTwoArray[0]);
- minY = Math.min(minY, 0);
- maxX = Math.max(maxX, mTmpTwoArray[0] + row.getWidth());
- maxY = Math.max(maxY, row.getHeadsUpHeight());
+ minX = mTmpTwoArray[0];
+ maxX = mTmpTwoArray[0] + row.getWidth();
+ maxY = row.getHeadsUpHeight();
+ break;
}
}
info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- info.touchableRegion.set(minX, minY, maxX, maxY + mNotificationsTopPadding);
+ info.touchableRegion.set(minX, 0, maxX, maxY + mNotificationsTopPadding);
} else if (mHeadsUpGoingAway || mWaitingOnCollapseWhenGoingAway) {
info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
info.touchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
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 beaa3ad..baccd2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -56,6 +56,7 @@
private ExpandableNotificationRow mNotificationParent;
private HybridNotificationView mGroupOverflowContainer;
private ViewState mGroupOverFlowState;
+ private int mRealHeight;
public NotificationChildrenContainer(Context context) {
this(context, null);
@@ -111,8 +112,8 @@
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
+ int size = MeasureSpec.getSize(heightMeasureSpec);
if (hasFixedHeight || isHeightLimited) {
- int size = MeasureSpec.getSize(heightMeasureSpec);
ownMaxHeight = Math.min(ownMaxHeight, size);
}
int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
@@ -133,9 +134,19 @@
if (mGroupOverflowContainer != null) {
mGroupOverflowContainer.measure(widthMeasureSpec, newHeightSpec);
}
+ mRealHeight = height;
+ if (heightMode != MeasureSpec.UNSPECIFIED) {
+ height = Math.min(height, size);
+ }
setMeasuredDimension(width, height);
}
+ @Override
+ public boolean pointInView(float localX, float localY, float slop) {
+ return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
+ localY < (mRealHeight + slop);
+ }
+
/**
* Add a child notification to this view.
*
@@ -452,6 +463,10 @@
}
public int getMinHeight() {
+ return getIntrinsicHeight(NUMBER_OF_CHILDREN_WHEN_COLLAPSED);
+ }
+
+ public int getMinExpandHeight() {
return getIntrinsicHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 2ce19a2..0ed1527 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -118,7 +118,7 @@
/**
* The algorithm which calculates the properties for our children
*/
- private StackScrollAlgorithm mStackScrollAlgorithm;
+ private final StackScrollAlgorithm mStackScrollAlgorithm;
/**
* The current State this Layout is in
@@ -258,6 +258,7 @@
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, getContext());
mSwipeHelper.setLongPressListener(mLongPressListener);
+ mStackScrollAlgorithm = new StackScrollAlgorithm(context);
initView(context);
if (DEBUG) {
setWillNotDraw(false);
@@ -303,8 +304,7 @@
.getDimensionPixelSize(R.dimen.notification_min_height);
mBottomStackPeekSize = context.getResources()
.getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
- mStackScrollAlgorithm = new StackScrollAlgorithm(context);
- mStackScrollAlgorithm.setDimmed(mAmbientState.isDimmed());
+ mStackScrollAlgorithm.initView(context);
mPaddingBetweenElementsDimmed = context.getResources()
.getDimensionPixelSize(R.dimen.notification_padding_dimmed);
mPaddingBetweenElementsNormal = context.getResources()
@@ -1338,7 +1338,7 @@
/**
* @return the first child which has visibility unequal to GONE
*/
- private ExpandableView getFirstChildNotGone() {
+ public ExpandableView getFirstChildNotGone() {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -2836,7 +2836,6 @@
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
mHeadsUpManager = headsUpManager;
mAmbientState.setHeadsUpManager(headsUpManager);
- mStackScrollAlgorithm.setHeadsUpManager(headsUpManager);
}
public void generateHeadsUpAnimation(ExpandableNotificationRow row, boolean isHeadsUp) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 59b446b..5496963 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -25,7 +25,6 @@
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.ArrayList;
import java.util.List;
@@ -68,19 +67,22 @@
private int mBottomStackSlowDownLength;
private int mTopStackSlowDownLength;
private int mCollapseSecondCardPadding;
- private boolean mIsSmallScreen;
- private int mMaxNotificationHeight;
private boolean mScaleDimmed;
- private HeadsUpManager mHeadsUpManager;
+ private ExpandableView mFirstChild;
private int mFirstChildMinHeight;
+ private boolean mDimmed;
public StackScrollAlgorithm(Context context) {
- initConstants(context);
- updatePadding(false);
+ initView(context);
}
- private void updatePadding(boolean dimmed) {
- mPaddingBetweenElements = dimmed && mScaleDimmed
+ public void initView(Context context) {
+ initConstants(context);
+ updatePadding();
+ }
+
+ private void updatePadding() {
+ mPaddingBetweenElements = mDimmed && mScaleDimmed
? mPaddingBetweenElementsDimmed
: mPaddingBetweenElementsNormal;
mTopStackTotalSize = mTopStackSlowDownLength + mPaddingBetweenElements
@@ -110,8 +112,6 @@
.getDimensionPixelSize(R.dimen.notifications_top_padding);
mCollapsedSize = context.getResources()
.getDimensionPixelSize(R.dimen.notification_min_height);
- mMaxNotificationHeight = context.getResources()
- .getDimensionPixelSize(R.dimen.notification_max_height);
mTopStackPeekSize = context.getResources()
.getDimensionPixelSize(R.dimen.top_stack_peek_amount);
mBottomStackPeekSize = context.getResources()
@@ -149,6 +149,7 @@
algorithmState.scrolledPixelsTop = 0;
algorithmState.itemsInBottomStack = 0.0f;
algorithmState.partialInBottom = 0.0f;
+ mFirstChildMinHeight = mFirstChild == null ? 0 : mFirstChild.getMinHeight();
float bottomOverScroll = ambientState.getOverScrollAmount(false /* onTop */);
int scrollY = ambientState.getScrollY();
@@ -544,7 +545,7 @@
if (row.isPinned()) {
childState.yTranslation = Math.max(childState.yTranslation,
mNotificationsTopPadding);
- childState.height = row.getHeadsUpHeight();
+ childState.height = Math.max(row.getHeadsUpHeight(), childState.height);
if (!isTopEntry) {
// Ensure that a headsUp doesn't vertically extend further than the heads-up at
// the top most z-position
@@ -933,10 +934,7 @@
}
public void notifyChildrenChanged(final NotificationStackScrollLayout hostView) {
- int firstItemMinHeight = hostView.getFirstItemMinHeight();
- if (firstItemMinHeight != mFirstChildMinHeight) {
- mFirstChildMinHeight = firstItemMinHeight;
- }
+ mFirstChild = hostView.getFirstChildNotGone();
if (mIsExpansionChanging) {
hostView.post(new Runnable() {
@Override
@@ -948,7 +946,8 @@
}
public void setDimmed(boolean dimmed) {
- updatePadding(dimmed);
+ mDimmed = dimmed;
+ updatePadding();
}
public void onReset(ExpandableView view) {
@@ -957,10 +956,6 @@
}
}
- public void setHeadsUpManager(HeadsUpManager headsUpManager) {
- mHeadsUpManager = headsUpManager;
- }
-
class StackScrollAlgorithmState {
/**