summaryrefslogtreecommitdiffstats
path: root/core/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/com')
-rw-r--r--core/java/com/android/internal/app/AlertController.java157
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl4
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuItem.java49
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java58
-rw-r--r--core/java/com/android/internal/widget/SwipeDismissLayout.java13
5 files changed, 226 insertions, 55 deletions
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 20d209f..9dabb4e 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -20,6 +20,7 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import com.android.internal.R;
+import android.annotation.Nullable;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
@@ -38,7 +39,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
-import android.view.ViewTreeObserver;
+import android.view.ViewStub;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -450,27 +451,107 @@ public class AlertController {
}
}
+ /**
+ * Resolves whether a custom or default panel should be used. Removes the
+ * default panel if a custom panel should be used. If the resolved panel is
+ * a view stub, inflates before returning.
+ *
+ * @param customPanel the custom panel
+ * @param defaultPanel the default panel
+ * @return the panel to use
+ */
+ @Nullable
+ private ViewGroup resolvePanel(@Nullable View customPanel, @Nullable View defaultPanel) {
+ if (customPanel == null) {
+ // Inflate the default panel, if needed.
+ if (defaultPanel instanceof ViewStub) {
+ defaultPanel = ((ViewStub) defaultPanel).inflate();
+ }
+
+ return (ViewGroup) defaultPanel;
+ }
+
+ // Remove the default panel entirely.
+ if (defaultPanel != null) {
+ final ViewParent parent = defaultPanel.getParent();
+ if (parent instanceof ViewGroup) {
+ ((ViewGroup) parent).removeView(defaultPanel);
+ }
+ }
+
+ // Inflate the custom panel, if needed.
+ if (customPanel instanceof ViewStub) {
+ customPanel = ((ViewStub) customPanel).inflate();
+ }
+
+ return (ViewGroup) customPanel;
+ }
+
private void setupView() {
- final ViewGroup contentPanel = (ViewGroup) mWindow.findViewById(R.id.contentPanel);
- setupContent(contentPanel);
- final boolean hasButtons = setupButtons();
+ final View parentPanel = mWindow.findViewById(R.id.parentPanel);
+ final View defaultTopPanel = parentPanel.findViewById(R.id.topPanel);
+ final View defaultContentPanel = parentPanel.findViewById(R.id.contentPanel);
+ final View defaultButtonPanel = parentPanel.findViewById(R.id.buttonPanel);
- final ViewGroup topPanel = (ViewGroup) mWindow.findViewById(R.id.topPanel);
- final TypedArray a = mContext.obtainStyledAttributes(
- null, R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
- final boolean hasTitle = setupTitle(topPanel);
+ // Install custom content before setting up the title or buttons so
+ // that we can handle panel overrides.
+ final ViewGroup customPanel = (ViewGroup) parentPanel.findViewById(R.id.customPanel);
+ setupCustomContent(customPanel);
- final View buttonPanel = mWindow.findViewById(R.id.buttonPanel);
- if (!hasButtons) {
- buttonPanel.setVisibility(View.GONE);
- final View spacer = mWindow.findViewById(R.id.textSpacerNoButtons);
- if (spacer != null) {
- spacer.setVisibility(View.VISIBLE);
+ final View customTopPanel = customPanel.findViewById(R.id.topPanel);
+ final View customContentPanel = customPanel.findViewById(R.id.contentPanel);
+ final View customButtonPanel = customPanel.findViewById(R.id.buttonPanel);
+
+ // Resolve the correct panels and remove the defaults, if needed.
+ final ViewGroup topPanel = resolvePanel(customTopPanel, defaultTopPanel);
+ final ViewGroup contentPanel = resolvePanel(customContentPanel, defaultContentPanel);
+ final ViewGroup buttonPanel = resolvePanel(customButtonPanel, defaultButtonPanel);
+
+ setupContent(contentPanel);
+ setupButtons(buttonPanel);
+ setupTitle(topPanel);
+
+ final boolean hasCustomPanel = customPanel != null
+ && customPanel.getVisibility() != View.GONE;
+ final boolean hasTopPanel = topPanel != null
+ && topPanel.getVisibility() != View.GONE;
+ final boolean hasButtonPanel = buttonPanel != null
+ && buttonPanel.getVisibility() != View.GONE;
+
+ // Only display the text spacer if we don't have buttons.
+ if (!hasButtonPanel) {
+ if (contentPanel != null) {
+ final View spacer = contentPanel.findViewById(R.id.textSpacerNoButtons);
+ if (spacer != null) {
+ spacer.setVisibility(View.VISIBLE);
+ }
}
mWindow.setCloseOnTouchOutsideIfNotSet(true);
}
- final FrameLayout customPanel = (FrameLayout) mWindow.findViewById(R.id.customPanel);
+ // Only display the divider if we have a title and a custom view or a
+ // message.
+ if (hasTopPanel) {
+ final View divider;
+ if (mMessage != null || hasCustomPanel || mListView != null) {
+ divider = topPanel.findViewById(R.id.titleDivider);
+ } else {
+ divider = topPanel.findViewById(R.id.titleDividerTop);
+ }
+
+ if (divider != null) {
+ divider.setVisibility(View.VISIBLE);
+ }
+ }
+
+ final TypedArray a = mContext.obtainStyledAttributes(
+ null, R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
+ setBackground(a, topPanel, contentPanel, customPanel, buttonPanel,
+ hasTopPanel, hasCustomPanel, hasButtonPanel);
+ a.recycle();
+ }
+
+ private void setupCustomContent(ViewGroup customPanel) {
final View customView;
if (mView != null) {
customView = mView;
@@ -502,30 +583,9 @@ public class AlertController {
} else {
customPanel.setVisibility(View.GONE);
}
-
- // Only display the divider if we have a title and a custom view or a
- // message.
- if (hasTitle) {
- final View divider;
- if (mMessage != null || customView != null || mListView != null) {
- divider = mWindow.findViewById(R.id.titleDivider);
- } else {
- divider = mWindow.findViewById(R.id.titleDividerTop);
- }
-
- if (divider != null) {
- divider.setVisibility(View.VISIBLE);
- }
- }
-
- setBackground(a, topPanel, contentPanel, customPanel, buttonPanel, hasTitle, hasCustomView,
- hasButtons);
- a.recycle();
}
- private boolean setupTitle(ViewGroup topPanel) {
- boolean hasTitle = true;
-
+ private void setupTitle(ViewGroup topPanel) {
if (mCustomTitleView != null) {
// Add the custom title view directly to the topPanel layout
LayoutParams lp = new LayoutParams(
@@ -567,18 +627,16 @@ public class AlertController {
titleTemplate.setVisibility(View.GONE);
mIconView.setVisibility(View.GONE);
topPanel.setVisibility(View.GONE);
- hasTitle = false;
}
}
- return hasTitle;
}
private void setupContent(ViewGroup contentPanel) {
- mScrollView = (ScrollView) mWindow.findViewById(R.id.scrollView);
+ mScrollView = (ScrollView) contentPanel.findViewById(R.id.scrollView);
mScrollView.setFocusable(false);
// Special case for users that only want to display a String
- mMessageView = (TextView) mWindow.findViewById(R.id.message);
+ mMessageView = (TextView) contentPanel.findViewById(R.id.message);
if (mMessageView == null) {
return;
}
@@ -601,8 +659,8 @@ public class AlertController {
}
// Set up scroll indicators (if present).
- final View indicatorUp = mWindow.findViewById(R.id.scrollIndicatorUp);
- final View indicatorDown = mWindow.findViewById(R.id.scrollIndicatorDown);
+ final View indicatorUp = contentPanel.findViewById(R.id.scrollIndicatorUp);
+ final View indicatorDown = contentPanel.findViewById(R.id.scrollIndicatorDown);
if (indicatorUp != null || indicatorDown != null) {
if (mMessage != null) {
// We're just showing the ScrollView, set up listener.
@@ -663,12 +721,12 @@ public class AlertController {
}
}
- private boolean setupButtons() {
+ private void setupButtons(ViewGroup buttonPanel) {
int BIT_BUTTON_POSITIVE = 1;
int BIT_BUTTON_NEGATIVE = 2;
int BIT_BUTTON_NEUTRAL = 4;
int whichButtons = 0;
- mButtonPositive = (Button) mWindow.findViewById(R.id.button1);
+ mButtonPositive = (Button) buttonPanel.findViewById(R.id.button1);
mButtonPositive.setOnClickListener(mButtonHandler);
if (TextUtils.isEmpty(mButtonPositiveText)) {
@@ -679,7 +737,7 @@ public class AlertController {
whichButtons = whichButtons | BIT_BUTTON_POSITIVE;
}
- mButtonNegative = (Button) mWindow.findViewById(R.id.button2);
+ mButtonNegative = (Button) buttonPanel.findViewById(R.id.button2);
mButtonNegative.setOnClickListener(mButtonHandler);
if (TextUtils.isEmpty(mButtonNegativeText)) {
@@ -691,7 +749,7 @@ public class AlertController {
whichButtons = whichButtons | BIT_BUTTON_NEGATIVE;
}
- mButtonNeutral = (Button) mWindow.findViewById(R.id.button3);
+ mButtonNeutral = (Button) buttonPanel.findViewById(R.id.button3);
mButtonNeutral.setOnClickListener(mButtonHandler);
if (TextUtils.isEmpty(mButtonNeutralText)) {
@@ -717,7 +775,10 @@ public class AlertController {
}
}
- return whichButtons != 0;
+ final boolean hasButtons = whichButtons != 0;
+ if (!hasButtons) {
+ buttonPanel.setVisibility(View.GONE);
+ }
}
private void centerButton(Button button) {
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 6d90420..8f549a6 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -26,9 +26,11 @@ import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
interface IVoiceInteractionManagerService {
- void startSession(IVoiceInteractionService service, in Bundle sessionArgs, int flags);
+ void showSession(IVoiceInteractionService service, in Bundle sessionArgs, int flags);
boolean deliverNewSession(IBinder token, IVoiceInteractionSession session,
IVoiceInteractor interactor);
+ boolean showSessionFromSession(IBinder token, in Bundle sessionArgs, int flags);
+ boolean hideSessionFromSession(IBinder token);
int startVoiceActivity(IBinder token, in Intent intent, String resolvedType);
void finish(IBinder token);
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index ed676bb..00af401 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -18,6 +18,8 @@ package com.android.internal.view.menu;
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.view.ActionProvider;
import android.view.ContextMenu.ContextMenuInfo;
@@ -42,6 +44,7 @@ public class ActionMenuItem implements MenuItem {
private Drawable mIconDrawable;
private int mIconResId = NO_ICON;
+ private TintInfo mIconTintInfo;
private Context mContext;
@@ -158,12 +161,14 @@ public class ActionMenuItem implements MenuItem {
public MenuItem setIcon(Drawable icon) {
mIconDrawable = icon;
mIconResId = NO_ICON;
+ applyIconTint();
return this;
}
public MenuItem setIcon(int iconRes) {
mIconResId = iconRes;
mIconDrawable = mContext.getDrawable(iconRes);
+ applyIconTint();
return this;
}
@@ -274,4 +279,48 @@ public class ActionMenuItem implements MenuItem {
// No need to save the listener; ActionMenuItem does not support collapsing items.
return this;
}
+
+ @Override
+ public MenuItem setIconTintList(ColorStateList tintList) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintList = tintList;
+ mIconTintInfo.mHasTintList = true;
+ applyIconTint();
+ return this;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintMode = tintMode;
+ mIconTintInfo.mHasTintMode = true;
+ applyIconTint();
+ return this;
+ }
+
+ private void applyIconTint() {
+ final TintInfo tintInfo = mIconTintInfo;
+ if (mIconDrawable != null && tintInfo != null) {
+ if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
+ mIconDrawable = mIconDrawable.mutate();
+ if (tintInfo.mHasTintList) {
+ mIconDrawable.setTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mIconDrawable.setTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 3b1f20d..ef4e546 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -21,6 +21,8 @@ import com.android.internal.view.menu.MenuView.ItemView;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.ActionProvider;
@@ -60,6 +62,11 @@ public final class MenuItemImpl implements MenuItem {
* needed).
*/
private int mIconResId = NO_ICON;
+
+ /**
+ * Tint info for the icon
+ */
+ private TintInfo mIconTintInfo;
/** The menu to which this item belongs */
private MenuBuilder mMenu;
@@ -385,10 +392,10 @@ public final class MenuItemImpl implements MenuItem {
}
if (mIconResId != NO_ICON) {
- Drawable icon = mMenu.getContext().getDrawable(mIconResId);
+ mIconDrawable = mMenu.getContext().getDrawable(mIconResId);
mIconResId = NO_ICON;
- mIconDrawable = icon;
- return icon;
+ applyIconTint();
+ return mIconDrawable;
}
return null;
@@ -397,6 +404,7 @@ public final class MenuItemImpl implements MenuItem {
public MenuItem setIcon(Drawable icon) {
mIconResId = NO_ICON;
mIconDrawable = icon;
+ applyIconTint();
mMenu.onItemsChanged(false);
return this;
@@ -670,4 +678,48 @@ public final class MenuItemImpl implements MenuItem {
public boolean isActionViewExpanded() {
return mIsActionViewExpanded;
}
+
+ @Override
+ public MenuItem setIconTintList(ColorStateList tintList) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintList = tintList;
+ mIconTintInfo.mHasTintList = true;
+ applyIconTint();
+ return this;
+ }
+
+ @Override
+ public MenuItem setIconTintMode(PorterDuff.Mode tintMode) {
+ if (mIconTintInfo == null) {
+ mIconTintInfo = new TintInfo();
+ }
+ mIconTintInfo.mTintMode = tintMode;
+ mIconTintInfo.mHasTintMode = true;
+ applyIconTint();
+ return this;
+ }
+
+ private void applyIconTint() {
+ final TintInfo tintInfo = mIconTintInfo;
+ if (mIconDrawable != null && tintInfo != null) {
+ if (tintInfo.mHasTintList || tintInfo.mHasTintMode) {
+ mIconDrawable = mIconDrawable.mutate();
+ if (tintInfo.mHasTintList) {
+ mIconDrawable.setTintList(tintInfo.mTintList);
+ }
+ if (tintInfo.mHasTintMode) {
+ mIconDrawable.setTintMode(tintInfo.mTintMode);
+ }
+ }
+ }
+ }
+
+ private static class TintInfo {
+ ColorStateList mTintList;
+ PorterDuff.Mode mTintMode;
+ boolean mHasTintMode;
+ boolean mHasTintList;
+ }
}
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index d617c05..89990c2 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -19,6 +19,7 @@ package com.android.internal.widget;
import android.animation.TimeInterpolator;
import android.app.Activity;
import android.content.Context;
+import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
@@ -38,6 +39,7 @@ public class SwipeDismissLayout extends FrameLayout {
private static final String TAG = "SwipeDismissLayout";
private static final float DISMISS_MIN_DRAG_WIDTH_RATIO = .33f;
+ private boolean mUseDynamicTranslucency = true;
public interface OnDismissedListener {
void onDismissed(SwipeDismissLayout layout);
@@ -85,7 +87,7 @@ public class SwipeDismissLayout extends FrameLayout {
// and temporarily disables translucency when it is fully visible.
// As soon as the user starts swiping, we will re-enable
// translucency.
- if (getContext() instanceof Activity) {
+ if (mUseDynamicTranslucency && getContext() instanceof Activity) {
((Activity) getContext()).convertFromTranslucent();
}
}
@@ -117,6 +119,11 @@ public class SwipeDismissLayout extends FrameLayout {
android.R.integer.config_shortAnimTime);
mCancelInterpolator = new DecelerateInterpolator(1.5f);
mDismissInterpolator = new AccelerateInterpolator(1.5f);
+ TypedArray a = context.getTheme().obtainStyledAttributes(
+ com.android.internal.R.styleable.Theme);
+ mUseDynamicTranslucency = !a.hasValue(
+ com.android.internal.R.styleable.Window_windowIsTranslucent);
+ a.recycle();
}
public void setOnDismissedListener(OnDismissedListener listener) {
@@ -230,7 +237,7 @@ public class SwipeDismissLayout extends FrameLayout {
mLastX = ev.getRawX();
updateSwiping(ev);
if (mSwiping) {
- if (getContext() instanceof Activity) {
+ if (mUseDynamicTranslucency && getContext() instanceof Activity) {
((Activity) getContext()).convertToTranslucent(null, null);
}
setProgress(ev.getRawX() - mDownX);
@@ -254,7 +261,7 @@ public class SwipeDismissLayout extends FrameLayout {
}
protected void cancel() {
- if (getContext() instanceof Activity) {
+ if (mUseDynamicTranslucency && getContext() instanceof Activity) {
((Activity) getContext()).convertFromTranslucent();
}
if (mProgressListener != null) {