From fd110a27d854ea307f3cc70b7c9c7a398a76b7f7 Mon Sep 17 00:00:00 2001 From: Chet Haase Date: Thu, 16 Jun 2011 13:55:11 -0700 Subject: Fix crash in ViewPropertyAnimator for unparented view. Mechanism for removing possible earlier animations should call removeCallbacks on the view, not on the (possibly null) handler of the view. Change-Id: I76c6f0bea5e009be9197a6e49e9360ed9ef1a9cb --- core/java/android/view/ViewPropertyAnimator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index 9eddf233cd12..a3de285eaa48 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.java @@ -349,7 +349,7 @@ public class ViewPropertyAnimator { } } mPendingAnimations.clear(); - mView.getHandler().removeCallbacks(mAnimationStarter); + mView.removeCallbacks(mAnimationStarter); } /** @@ -705,7 +705,7 @@ public class ViewPropertyAnimator { NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue); mPendingAnimations.add(nameValuePair); - mView.getHandler().removeCallbacks(mAnimationStarter); + mView.removeCallbacks(mAnimationStarter); mView.post(mAnimationStarter); } -- cgit v1.2.3-59-g8ed1b From 247d77c206f3fbc5a52e55db0417d1a282b8052f Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Thu, 16 Jun 2011 14:40:48 -0700 Subject: Fix network state handling Change I242cda97 introduced a regression where network state was being modified on any supplicant state change. Revert the old behavior of only changeing network detailed state based on supplicant state change in a disconnected state Bug: 4690073 Change-Id: I927cc5fa36b862cc54661b033939f543cd15d31f --- wifi/java/android/net/wifi/WifiStateMachine.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 3df3736f0497..81bbcf39e1f5 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -1438,7 +1438,6 @@ public class WifiStateMachine extends StateMachine { /* BSSID is valid only in ASSOCIATING state */ mWifiInfo.setBSSID(stateChangeResult.BSSID); } - setNetworkDetailedState(WifiInfo.getDetailedStateOf(state)); mSupplicantStateTracker.sendMessage(Message.obtain(message)); mWpsStateMachine.sendMessage(Message.obtain(message)); @@ -2979,7 +2978,12 @@ public class WifiStateMachine extends StateMachine { /* Ignore network disconnect */ case NETWORK_DISCONNECTION_EVENT: break; - case CMD_START_SCAN: + case SUPPLICANT_STATE_CHANGE_EVENT: + StateChangeResult stateChangeResult = (StateChangeResult) message.obj; + setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state)); + /* ConnectModeState does the rest of the handling */ + return NOT_HANDLED; + case CMD_START_SCAN: /* Disable background scan temporarily during a regular scan */ if (mEnableBackgroundScan) { WifiNative.enableBackgroundScanCommand(false); -- cgit v1.2.3-59-g8ed1b From 3e9f139f436678d7561183d835d9ac2b9af73850 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Mon, 20 Jun 2011 10:35:27 -0700 Subject: Fix bug 4729242 - Crash while launching browser app. Change-Id: Id049bcc53943b0cbe17e9f345af67adc2b10bdef --- .../com/android/internal/widget/ActionBarView.java | 58 +++++++++++++--------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 290f90dc6eba..c475eff94283 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -463,7 +463,7 @@ public class ActionBarView extends AbsActionBarView { } } - if ((flagsChanged & + if (mTitleLayout != null && (flagsChanged & (ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) { final boolean homeAsUp = (options & ActionBar.DISPLAY_HOME_AS_UP) != 0; final boolean titleUp = homeAsUp && !showHome; @@ -650,27 +650,35 @@ public class ActionBarView extends AbsActionBarView { } private void initTitle() { - LayoutInflater inflater = LayoutInflater.from(getContext()); - mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item, null); - mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title); - mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle); - mTitleUpView = (View) mTitleLayout.findViewById(R.id.up); + if (mTitleLayout == null) { + LayoutInflater inflater = LayoutInflater.from(getContext()); + mTitleLayout = (LinearLayout) inflater.inflate(R.layout.action_bar_title_item, null); + mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title); + mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle); + mTitleUpView = (View) mTitleLayout.findViewById(R.id.up); - mTitleLayout.setOnClickListener(mUpClickListener); + mTitleLayout.setOnClickListener(mUpClickListener); - if (mTitleStyleRes != 0) { - mTitleView.setTextAppearance(mContext, mTitleStyleRes); - } - if (mTitle != null) { - mTitleView.setText(mTitle); - } + if (mTitleStyleRes != 0) { + mTitleView.setTextAppearance(mContext, mTitleStyleRes); + } + if (mTitle != null) { + mTitleView.setText(mTitle); + } - if (mSubtitleStyleRes != 0) { - mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); - } - if (mSubtitle != null) { - mSubtitleView.setText(mSubtitle); - mSubtitleView.setVisibility(VISIBLE); + if (mSubtitleStyleRes != 0) { + mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes); + } + if (mSubtitle != null) { + mSubtitleView.setText(mSubtitle); + mSubtitleView.setVisibility(VISIBLE); + } + + final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0; + final boolean titleUp = homeAsUp && + (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) == 0; + mTitleUpView.setVisibility(titleUp ? VISIBLE : GONE); + mTitleLayout.setEnabled(titleUp); } addView(mTitleLayout); @@ -750,7 +758,7 @@ public class ActionBarView extends AbsActionBarView { if (mExpandedActionView == null) { boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; + (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; if (showTitle) { availableWidth = measureChildView(mTitleLayout, availableWidth, childSpecHeight, 0); leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth()); @@ -888,7 +896,7 @@ public class ActionBarView extends AbsActionBarView { if (mExpandedActionView == null) { final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE && - (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; + (mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0; if (showTitle) { x += positionChild(mTitleLayout, x, y, contentHeight); } @@ -1209,7 +1217,7 @@ public class ActionBarView extends AbsActionBarView { addView(mExpandedHomeLayout); } mHomeLayout.setVisibility(GONE); - mTitleLayout.setVisibility(GONE); + if (mTitleLayout != null) mTitleLayout.setVisibility(GONE); if (mTabScrollView != null) mTabScrollView.setVisibility(GONE); if (mSpinner != null) mSpinner.setVisibility(GONE); if (mCustomNavView != null) mCustomNavView.setVisibility(GONE); @@ -1226,7 +1234,11 @@ public class ActionBarView extends AbsActionBarView { mHomeLayout.setVisibility(VISIBLE); } if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) { - mTitleLayout.setVisibility(VISIBLE); + if (mTitleLayout == null) { + initTitle(); + } else { + mTitleLayout.setVisibility(VISIBLE); + } } if (mTabScrollView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) { mTabScrollView.setVisibility(VISIBLE); -- cgit v1.2.3-59-g8ed1b From 4d3fec0ab068882ae27a3615adf87aa21491fd67 Mon Sep 17 00:00:00 2001 From: Daniel Sandler Date: Tue, 21 Jun 2011 12:57:08 -0400 Subject: Fix statusbar crash when DeskClock alarms go off. Bug: 4723790 Change-Id: Ia819b6a35b5b103d28f6db3b25c815f77827f80f --- .../src/com/android/systemui/statusbar/phone/PhoneStatusBar.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 0b82123b6c63..f3c26239afd0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1721,7 +1721,7 @@ public class PhoneStatusBar extends StatusBar { || Intent.ACTION_SCREEN_OFF.equals(action)) { boolean excludeRecents = false; if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { - String reason = intent.getExtras().getString("reason"); + String reason = intent.getStringExtra("reason"); if (reason != null) { excludeRecents = reason.equals("recentapps"); } -- cgit v1.2.3-59-g8ed1b From eff16e13299a322caa7e64892c5fa8bde70b5c4e Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Thu, 23 Jun 2011 14:13:28 -0700 Subject: NetworkStatsService: check kernel bandwidth support before enabling And catch the actual errors reported by the other side of NetworkManager. Change-Id: I9a9393b659d6f896ee1bf40a8deaca7853ef8f94 Signed-off-by: JP Abgrall --- services/java/com/android/server/net/NetworkStatsService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index a80bc043a4fe..524dd4090520 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -71,6 +71,7 @@ import android.util.Slog; import android.util.TrustedTime; import com.android.internal.os.AtomicFile; +import com.android.server.NativeDaemonConnectorException; import com.google.android.collect.Maps; import com.google.android.collect.Sets; @@ -214,7 +215,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // TODO: consider shipping with this enabled by default mNetworkManager.setBandwidthControlEnabled(true); } catch (RemoteException e) { - Slog.e(TAG, "problem enabling bandwidth controls", e); + Slog.e(TAG, "problem talking to netd while enabling bandwidth controls", e); + } catch (NativeDaemonConnectorException ndce) { + Slog.e(TAG, "problem enabling bandwidth controls", ndce); } } else { Slog.w(TAG, "detailed network stats disabled"); @@ -1055,6 +1058,10 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } public boolean getEnabled() { + if (!new File("/proc/net/xt_qtaguid/ctrl").exists()) { + Slog.w(TAG, "kernel does not support bandwidth control"); + return false; + } return Settings.Secure.getInt(mResolver, NETSTATS_ENABLED, 1) != 0; } public long getPollInterval() { -- cgit v1.2.3-59-g8ed1b From 383f81c5b7a51f33faf9d2543f02c4539d6d991d Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Mon, 27 Jun 2011 19:33:27 -0700 Subject: Fix 4691563: Fix memory leak caused by Tweeners hanging onto references. This fixes a bug where the animations in MultiWaveView were keeping references to bitmaps and preventing them from being reclaimed during GC. The solution is two-fold: 1. When any given animation completes, it is now removed from the list of running animators objects. 2. When the client explicitly calls reset(), we release all references to animators and objects. Change-Id: Ice434ed1720fe4c253b9607ef61699d41f87f777 --- .../widget/multiwaveview/MultiWaveView.java | 5 +- .../internal/widget/multiwaveview/Tweener.java | 90 ++++++++++++++++------ 2 files changed, 69 insertions(+), 26 deletions(-) diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java index 3e7b976aedb7..5b3510428f7b 100644 --- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java +++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java @@ -224,8 +224,8 @@ public class MultiWaveView extends View implements AnimatorUpdateListener { /** * Animation used to attract user's attention to the target button. - * Assumes mChevronDrawables is an a list with an even number of chevrons filled with left - * followed by right chevrons. + * Assumes mChevronDrawables is an a list with an even number of chevrons filled with + * mFeedbackCount items in the order: left, right, top, bottom. */ private void startChevronAnimation() { final float r = mHandleDrawable.getWidth() / 2; @@ -442,6 +442,7 @@ public class MultiWaveView extends View implements AnimatorUpdateListener { mHandleDrawable.setX(mWaveCenterX); mHandleDrawable.setY(mWaveCenterY); mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE); + Tweener.reset(); } @Override diff --git a/core/java/com/android/internal/widget/multiwaveview/Tweener.java b/core/java/com/android/internal/widget/multiwaveview/Tweener.java index 0cff00a514ab..bc8a62f2ca0b 100644 --- a/core/java/com/android/internal/widget/multiwaveview/Tweener.java +++ b/core/java/com/android/internal/widget/multiwaveview/Tweener.java @@ -18,25 +18,42 @@ package com.android.internal.widget.multiwaveview; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; import android.animation.Animator.AnimatorListener; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.util.Log; class Tweener { private static final String TAG = "Tweener"; + private static final boolean DEBUG = false; - private Object object; ObjectAnimator animator; private static HashMap sTweens = new HashMap(); - public Tweener(Object obj, ObjectAnimator anim) { - object = obj; + public Tweener(ObjectAnimator anim) { animator = anim; } + private static void remove(Animator animator) { + Iterator> iter = sTweens.entrySet().iterator(); + while (iter.hasNext()) { + Entry entry = iter.next(); + if (entry.getValue().animator == animator) { + if (DEBUG) Log.v(TAG, "Removing tweener " + sTweens.get(entry.getKey()) + + " sTweens.size() = " + sTweens.size()); + iter.remove(); + break; // an animator can only be attached to one object + } + } + } + public static Tweener to(Object object, long duration, Object... vars) { long delay = 0; AnimatorUpdateListener updateListener = null; @@ -77,32 +94,35 @@ class Tweener { // Re-use existing tween, if present Tweener tween = sTweens.get(object); + ObjectAnimator anim = null; if (tween == null) { - ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(object, + anim = ObjectAnimator.ofPropertyValuesHolder(object, props.toArray(new PropertyValuesHolder[props.size()])); - tween = new Tweener(object, anim); + tween = new Tweener(anim); sTweens.put(object, tween); + if (DEBUG) Log.v(TAG, "Added new Tweener " + tween); } else { - tween.animator.cancel(); - replace(props, object); + anim = sTweens.get(object).animator; + replace(props, object); // Cancel all animators for given object } if (interpolator != null) { - tween.animator.setInterpolator(interpolator); + anim.setInterpolator(interpolator); } // Update animation with properties discovered in loop above - tween.animator.setStartDelay(delay); - tween.animator.setDuration(duration); + anim.setStartDelay(delay); + anim.setDuration(duration); if (updateListener != null) { - tween.animator.removeAllUpdateListeners(); // There should be only one - tween.animator.addUpdateListener(updateListener); + anim.removeAllUpdateListeners(); // There should be only one + anim.addUpdateListener(updateListener); } if (listener != null) { - tween.animator.removeAllListeners(); // There should be only one. - tween.animator.addListener(listener); + anim.removeAllListeners(); // There should be only one. + anim.addListener(listener); } - tween.animator.start(); + anim.addListener(mCleanupListener); + anim.start(); return tween; } @@ -114,18 +134,40 @@ class Tweener { return Tweener.to(object, duration, vars); } - static void replace(ArrayList props, Object... args) { + // Listener to watch for completed animations and remove them. + private static AnimatorListener mCleanupListener = new AnimatorListenerAdapter() { + + @Override + public void onAnimationEnd(Animator animation) { + remove(animation); + } + + @Override + public void onAnimationCancel(Animator animation) { + remove(animation); + } + }; + + public static void reset() { + if (DEBUG) { + Log.v(TAG, "Reset()"); + if (sTweens.size() > 0) { + Log.v(TAG, "Cleaning up " + sTweens.size() + " animations"); + } + } + sTweens.clear(); + } + + private static void replace(ArrayList props, Object... args) { for (final Object killobject : args) { Tweener tween = sTweens.get(killobject); if (tween != null) { - if (killobject == tween.object) { - tween.animator.cancel(); - if (props != null) { - tween.animator.setValues( - props.toArray(new PropertyValuesHolder[props.size()])); - } else { - sTweens.remove(tween); - } + tween.animator.cancel(); + if (props != null) { + tween.animator.setValues( + props.toArray(new PropertyValuesHolder[props.size()])); + } else { + sTweens.remove(tween); } } } -- cgit v1.2.3-59-g8ed1b From f9a10524bc411a663850f9a9a11509c5b351a237 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Thu, 30 Jun 2011 18:19:51 -0700 Subject: Add API to report the presence of a permanent menu key on the device. Action bar now uses this to determine whether to show an overflow menu. Change-Id: Ife4f724d02bbc0d9d86d94740c85299f6dacae91 --- api/current.txt | 1 + core/java/android/view/ViewConfiguration.java | 39 ++++++++++++++++++++-- .../internal/view/menu/ActionMenuPresenter.java | 5 ++- core/res/res/values/config.xml | 4 +++ packages/SystemUI/res/values/config.xml | 4 --- .../systemui/statusbar/phone/PhoneStatusBar.java | 2 +- 6 files changed, 44 insertions(+), 11 deletions(-) diff --git a/api/current.txt b/api/current.txt index f21a4f3b721d..d25d25fc14f9 100644 --- a/api/current.txt +++ b/api/current.txt @@ -22261,6 +22261,7 @@ package android.view { method public static deprecated int getTouchSlop(); method public static deprecated int getWindowTouchSlop(); method public static long getZoomControlsTimeout(); + method public boolean hasPermanentMenuKey(); } public class ViewDebug { diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index f3a5050001ea..dbcbd6e5ae1f 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -19,6 +19,8 @@ package android.view; import android.app.AppGlobals; import android.content.Context; import android.content.res.Configuration; +import android.content.res.Resources; +import android.os.RemoteException; import android.provider.Settings; import android.util.DisplayMetrics; import android.util.SparseArray; @@ -219,6 +221,9 @@ public class ViewConfiguration { private final int mOverscrollDistance; private final int mOverflingDistance; + private boolean sHasPermanentMenuKey; + private boolean sHasPermanentMenuKeySet; + private static final SparseArray sConfigurations = new SparseArray(2); @@ -254,11 +259,12 @@ public class ViewConfiguration { * @see android.util.DisplayMetrics */ private ViewConfiguration(Context context) { - final DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + final Resources res = context.getResources(); + final DisplayMetrics metrics = res.getDisplayMetrics(); + final Configuration config = res.getConfiguration(); final float density = metrics.density; final float sizeAndDensity; - if (context.getResources().getConfiguration().isLayoutSizeAtLeast( - Configuration.SCREENLAYOUT_SIZE_XLARGE)) { + if (config.isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_XLARGE)) { sizeAndDensity = density * 1.5f; } else { sizeAndDensity = density; @@ -280,6 +286,17 @@ public class ViewConfiguration { mOverscrollDistance = (int) (sizeAndDensity * OVERSCROLL_DISTANCE + 0.5f); mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f); + + if (!sHasPermanentMenuKeySet) { + IWindowManager wm = Display.getWindowManager(); + try { + sHasPermanentMenuKey = wm.canStatusBarHide() && !res.getBoolean( + com.android.internal.R.bool.config_showNavigationBar); + sHasPermanentMenuKeySet = true; + } catch (RemoteException ex) { + sHasPermanentMenuKey = false; + } + } } /** @@ -640,4 +657,20 @@ public class ViewConfiguration { public static float getScrollFriction() { return SCROLL_FRICTION; } + + /** + * Report if the device has a permanent menu key available to the user. + * + *

As of Android 3.0, devices may not have a permanent menu key available. + * Apps should use the action bar to present menu options to users. + * However, there are some apps where the action bar is inappropriate + * or undesirable. This method may be used to detect if a menu key is present. + * If not, applications should provide another on-screen affordance to access + * functionality. + * + * @return true if a permanent menu key is present, false otherwise. + */ + public boolean hasPermanentMenuKey() { + return sHasPermanentMenuKey; + } } diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java index 322a8545d559..2fec9cd09f5b 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java +++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java @@ -26,6 +26,7 @@ import android.view.MenuItem; import android.view.SoundEffectConstants; import android.view.View; import android.view.View.MeasureSpec; +import android.view.ViewConfiguration; import android.view.ViewGroup; import android.widget.ImageButton; @@ -69,9 +70,7 @@ public class ActionMenuPresenter extends BaseMenuPresenter { final Resources res = context.getResources(); if (!mReserveOverflowSet) { - // TODO Use the no-buttons specifier instead here - mReserveOverflow = res.getConfiguration() - .isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE); + mReserveOverflow = !ViewConfiguration.get(context).hasPermanentMenuKey(); } if (!mWidthLimitSet) { diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 827153e7243e..2c10b3dabe8f 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -658,4 +658,8 @@ This is intended to allow packaging drivers or tools for installation on a PC. --> + + false + diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 7a4ac5d816f6..5298f2e66927 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -36,10 +36,6 @@ true - - false - 5 diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index d8474db3c2ef..4c7b0dd2ca54 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -246,7 +246,7 @@ public class PhoneStatusBar extends StatusBar { mIntruderAlertView.setClickable(true); try { - boolean showNav = res.getBoolean(R.bool.config_showNavigationBar); + boolean showNav = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar); if (showNav) { mNavigationBarView = (NavigationBarView) View.inflate(context, R.layout.navigation_bar, null); -- cgit v1.2.3-59-g8ed1b From 65b7011129752e38ca06cfcecc4caf919ac23789 Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Thu, 30 Jun 2011 23:53:07 -0700 Subject: Query input device for initial slot index. This fixes a problem where touches can get stuck because the driver and the framework have different ideas of what the initial slot index is. The framework assumed it was slot 0 but it could in principle be any slot, such as slot 1. When that happened, the framework would start tracking the first touch as slot 0, but it might never receive an "up" for that slot. Change-Id: Idaffc4534b275d66b9d4360987b28dc2d0f63218 --- services/input/EventHub.cpp | 31 +++++++++++++++++++++++++++++-- services/input/EventHub.h | 4 ++++ services/input/InputDispatcher.cpp | 5 +++-- services/input/InputReader.cpp | 21 ++++++++++++++++++++- services/input/tests/InputReader_test.cpp | 20 ++++++++++++++++++++ 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index 95b8a5723e2f..ca2540bfad20 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -212,8 +212,8 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, struct input_absinfo info; if(ioctl(device->fd, EVIOCGABS(axis), &info)) { - LOGW("Error reading absolute controller %d for device %s fd %d\n", - axis, device->identifier.name.string(), device->fd); + LOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", + axis, device->identifier.name.string(), device->fd, errno); return -errno; } @@ -335,6 +335,33 @@ int32_t EventHub::getSwitchStateLocked(Device* device, int32_t sw) const { return AKEY_STATE_UNKNOWN; } +status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const { + if (axis >= 0 && axis <= ABS_MAX) { + AutoMutex _l(mLock); + + Device* device = getDeviceLocked(deviceId); + if (device != NULL) { + return getAbsoluteAxisValueLocked(device, axis, outValue); + } + } + *outValue = 0; + return -1; +} + +status_t EventHub::getAbsoluteAxisValueLocked(Device* device, int32_t axis, + int32_t* outValue) const { + struct input_absinfo info; + + if(ioctl(device->fd, EVIOCGABS(axis), &info)) { + LOGW("Error reading absolute controller %d for device %s fd %d, errno=%d", + axis, device->identifier.name.string(), device->fd, errno); + return -errno; + } + + *outValue = info.value; + return OK; +} + bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const { AutoMutex _l(mLock); diff --git a/services/input/EventHub.h b/services/input/EventHub.h index 0a34e45a565c..695dfdfb25e6 100644 --- a/services/input/EventHub.h +++ b/services/input/EventHub.h @@ -186,6 +186,8 @@ public: virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0; virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0; virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0; + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, + int32_t* outValue) const = 0; /* * Examine key input devices for specific framework keycode support @@ -237,6 +239,7 @@ public: virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const; virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const; virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const; + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* outValue) const; virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const; @@ -305,6 +308,7 @@ private: int32_t getScanCodeStateLocked(Device* device, int32_t scanCode) const; int32_t getKeyCodeStateLocked(Device* device, int32_t keyCode) const; int32_t getSwitchStateLocked(Device* device, int32_t sw) const; + int32_t getAbsoluteAxisValueLocked(Device* device, int32_t axis, int32_t* outValue) const; bool markSupportedKeyCodesLocked(Device* device, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const; diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index 85ce38ae2020..10b9083549f2 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -1239,8 +1239,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, const InputWindow* newHoverWindow = NULL; bool isSplit = mTouchState.split; - bool switchedDevice = mTouchState.deviceId != entry->deviceId - || mTouchState.source != entry->source; + bool switchedDevice = mTouchState.deviceId >= 0 + && (mTouchState.deviceId != entry->deviceId + || mTouchState.source != entry->source); bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT); diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index 82c3af370ea8..79218a5581ca 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -5394,7 +5394,6 @@ void SingleTouchInputMapper::configureRawAxes() { MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device) : TouchInputMapper(device), mSlotCount(0), mUsingSlotsProtocol(false) { - clearState(); } MultiTouchInputMapper::~MultiTouchInputMapper() { @@ -5404,6 +5403,24 @@ void MultiTouchInputMapper::clearState() { mAccumulator.clearSlots(mSlotCount); mAccumulator.clearButtons(); mButtonState = 0; + + if (mUsingSlotsProtocol) { + // Query the driver for the current slot index and use it as the initial slot + // before we start reading events from the device. It is possible that the + // current slot index will not be the same as it was when the first event was + // written into the evdev buffer, which means the input mapper could start + // out of sync with the initial state of the events in the evdev buffer. + // In the extremely unlikely case that this happens, the data from + // two slots will be confused until the next ABS_MT_SLOT event is received. + // This can cause the touch point to "jump", but at least there will be + // no stuck touches. + status_t status = getEventHub()->getAbsoluteAxisValue(getDeviceId(), ABS_MT_SLOT, + &mAccumulator.currentSlot); + if (status) { + LOGW("Could not retrieve current multitouch slot index. status=%d", status); + mAccumulator.currentSlot = -1; + } + } } void MultiTouchInputMapper::reset() { @@ -5682,6 +5699,8 @@ void MultiTouchInputMapper::configureRawAxes() { } mAccumulator.allocateSlots(mSlotCount); + + clearState(); } diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index e349248b1c5a..d3c5ece7cbef 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -429,6 +429,7 @@ class FakeEventHub : public EventHubInterface { KeyedVector keyCodeStates; KeyedVector scanCodeStates; KeyedVector switchStates; + KeyedVector absoluteAxisValue; KeyedVector keys; KeyedVector leds; Vector virtualKeys; @@ -514,6 +515,11 @@ public: device->switchStates.replaceValueFor(switchCode, state); } + void setAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t value) { + Device* device = getDevice(deviceId); + device->absoluteAxisValue.replaceValueFor(axis, value); + } + void addKey(int32_t deviceId, int32_t scanCode, int32_t keyCode, uint32_t flags) { Device* device = getDevice(deviceId); KeyInfo info; @@ -677,6 +683,20 @@ private: return AKEY_STATE_UNKNOWN; } + virtual status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis, + int32_t* outValue) const { + Device* device = getDevice(deviceId); + if (device) { + ssize_t index = device->absoluteAxisValue.indexOfKey(axis); + if (index >= 0) { + *outValue = device->absoluteAxisValue.valueAt(index); + return OK; + } + } + *outValue = 0; + return -1; + } + virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const { bool result = false; -- cgit v1.2.3-59-g8ed1b From c5ed7d5db4cff74f3afad013ae38e1333d87135e Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Thu, 7 Jul 2011 10:22:27 -0700 Subject: Action bar layout tweaks Fix a Spinner issue that reported odd baselines Fix detection of expandable items for action menus and allocation of cells Use the right asset for home-as-up in Theme.Holo.Light.SolidActionBar.Inverse Add TextAppearance.Holo.Widget.ActionBar.Menu as a basis for further menu item styling Sync with design for tab/menu text appearance Change-Id: I32026bbde1cd4e15b6cda30d78d3d48250c84c94 --- api/current.txt | 27 +++++++------ core/java/android/widget/Spinner.java | 3 +- .../android/internal/view/menu/ActionMenuView.java | 46 +++++++++++----------- core/res/res/values/public.xml | 1 + core/res/res/values/styles.xml | 12 ++++-- core/res/res/values/themes.xml | 3 +- 6 files changed, 51 insertions(+), 41 deletions(-) diff --git a/api/current.txt b/api/current.txt index 9ad7b4ed2257..5103b47ec489 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1512,6 +1512,7 @@ package android { field public static final int TextAppearance_Holo_Small = 16974081; // 0x1030101 field public static final int TextAppearance_Holo_Small_Inverse = 16974082; // 0x1030102 field public static final int TextAppearance_Holo_Widget = 16974085; // 0x1030105 + field public static final int TextAppearance_Holo_Widget_ActionBar_Menu = 16974113; // 0x1030121 field public static final int TextAppearance_Holo_Widget_ActionBar_Subtitle = 16974099; // 0x1030113 field public static final int TextAppearance_Holo_Widget_ActionBar_Subtitle_Inverse = 16974110; // 0x103011e field public static final int TextAppearance_Holo_Widget_ActionBar_Title = 16974098; // 0x1030112 @@ -1582,16 +1583,16 @@ package android { field public static final int Theme_Holo_Light_NoActionBar = 16974064; // 0x10300f0 field public static final int Theme_Holo_Light_NoActionBar_Fullscreen = 16974065; // 0x10300f1 field public static final int Theme_Holo_Light_Panel = 16973948; // 0x103007c - field public static final int Theme_Holo_Light_SolidActionBar = 16974121; // 0x1030129 - field public static final int Theme_Holo_Light_SolidActionBar_Inverse = 16974122; // 0x103012a - field public static final int Theme_Holo_Light_SolidActionBar_Inverse_SplitActionBarWhenNarrow = 16974125; // 0x103012d - field public static final int Theme_Holo_Light_SolidActionBar_SplitActionBarWhenNarrow = 16974124; // 0x103012c + field public static final int Theme_Holo_Light_SolidActionBar = 16974122; // 0x103012a + field public static final int Theme_Holo_Light_SolidActionBar_Inverse = 16974123; // 0x103012b + field public static final int Theme_Holo_Light_SolidActionBar_Inverse_SplitActionBarWhenNarrow = 16974126; // 0x103012e + field public static final int Theme_Holo_Light_SolidActionBar_SplitActionBarWhenNarrow = 16974125; // 0x103012d field public static final int Theme_Holo_Light_SplitActionBarWhenNarrow = 16974106; // 0x103011a field public static final int Theme_Holo_NoActionBar = 16973932; // 0x103006c field public static final int Theme_Holo_NoActionBar_Fullscreen = 16973933; // 0x103006d field public static final int Theme_Holo_Panel = 16973947; // 0x103007b - field public static final int Theme_Holo_SolidActionBar = 16974120; // 0x1030128 - field public static final int Theme_Holo_SolidActionBar_SplitActionBarWhenNarrow = 16974123; // 0x103012b + field public static final int Theme_Holo_SolidActionBar = 16974121; // 0x1030129 + field public static final int Theme_Holo_SolidActionBar_SplitActionBarWhenNarrow = 16974124; // 0x103012c field public static final int Theme_Holo_SplitActionBarWhenNarrow = 16974105; // 0x1030119 field public static final int Theme_Holo_Wallpaper = 16973949; // 0x103007d field public static final int Theme_Holo_Wallpaper_NoTitleBar = 16973950; // 0x103007e @@ -1643,7 +1644,7 @@ package android { field public static final int Widget_GridView = 16973874; // 0x1030032 field public static final int Widget_Holo = 16973962; // 0x103008a field public static final int Widget_Holo_ActionBar = 16974004; // 0x10300b4 - field public static final int Widget_Holo_ActionBar_Solid = 16974113; // 0x1030121 + field public static final int Widget_Holo_ActionBar_Solid = 16974114; // 0x1030122 field public static final int Widget_Holo_ActionBar_TabBar = 16974071; // 0x10300f7 field public static final int Widget_Holo_ActionBar_TabText = 16974070; // 0x10300f6 field public static final int Widget_Holo_ActionBar_TabView = 16974069; // 0x10300f5 @@ -1673,19 +1674,19 @@ package android { field public static final int Widget_Holo_ImageButton = 16973974; // 0x1030096 field public static final int Widget_Holo_Light = 16974005; // 0x10300b5 field public static final int Widget_Holo_Light_ActionBar = 16974049; // 0x10300e1 - field public static final int Widget_Holo_Light_ActionBar_Solid = 16974114; // 0x1030122 - field public static final int Widget_Holo_Light_ActionBar_Solid_Inverse = 16974115; // 0x1030123 + field public static final int Widget_Holo_Light_ActionBar_Solid = 16974115; // 0x1030123 + field public static final int Widget_Holo_Light_ActionBar_Solid_Inverse = 16974116; // 0x1030124 field public static final int Widget_Holo_Light_ActionBar_TabBar = 16974074; // 0x10300fa - field public static final int Widget_Holo_Light_ActionBar_TabBar_Inverse = 16974116; // 0x1030124 + field public static final int Widget_Holo_Light_ActionBar_TabBar_Inverse = 16974117; // 0x1030125 field public static final int Widget_Holo_Light_ActionBar_TabText = 16974073; // 0x10300f9 - field public static final int Widget_Holo_Light_ActionBar_TabText_Inverse = 16974118; // 0x1030126 + field public static final int Widget_Holo_Light_ActionBar_TabText_Inverse = 16974119; // 0x1030127 field public static final int Widget_Holo_Light_ActionBar_TabView = 16974072; // 0x10300f8 - field public static final int Widget_Holo_Light_ActionBar_TabView_Inverse = 16974117; // 0x1030125 + field public static final int Widget_Holo_Light_ActionBar_TabView_Inverse = 16974118; // 0x1030126 field public static final int Widget_Holo_Light_ActionButton = 16974045; // 0x10300dd field public static final int Widget_Holo_Light_ActionButton_CloseMode = 16974048; // 0x10300e0 field public static final int Widget_Holo_Light_ActionButton_Overflow = 16974046; // 0x10300de field public static final int Widget_Holo_Light_ActionMode = 16974047; // 0x10300df - field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974119; // 0x1030127 + field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974120; // 0x1030128 field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6 field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974108; // 0x103011c diff --git a/core/java/android/widget/Spinner.java b/core/java/android/widget/Spinner.java index b23a855f4d65..485c67861f37 100644 --- a/core/java/android/widget/Spinner.java +++ b/core/java/android/widget/Spinner.java @@ -231,7 +231,8 @@ public class Spinner extends AbsSpinner implements OnClickListener { } if (child != null) { - return child.getTop() + child.getBaseline(); + final int childBaseline = child.getBaseline(); + return childBaseline >= 0 ? child.getTop() + childBaseline : -1; } else { return -1; } diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java index cfe9e5990e02..bf2965b0b469 100644 --- a/core/java/com/android/internal/view/menu/ActionMenuView.java +++ b/core/java/com/android/internal/view/menu/ActionMenuView.java @@ -112,7 +112,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo int cellsRemaining = cellCount; int maxChildHeight = 0; int maxCellsUsed = 0; - int multiCellItemCount = 0; + int expandableItemCount = 0; if (mReserveOverflow) cellsRemaining--; @@ -123,7 +123,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo lp.expanded = false; lp.extraPixels = 0; lp.cellsUsed = 0; - lp.multiCell = false; + lp.expandable = false; // Overflow always gets 1 cell. No more, no less. final int cellsAvailable = lp.isOverflowButton ? 1 : cellsRemaining; @@ -132,7 +132,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo heightMeasureSpec, heightPadding); maxCellsUsed = Math.max(maxCellsUsed, cellsUsed); - if (lp.multiCell) multiCellItemCount++; + if (lp.expandable) expandableItemCount++; cellsRemaining -= cellsUsed; maxChildHeight = Math.max(maxChildHeight, child.getMeasuredHeight()); @@ -142,8 +142,8 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo // Try distributing whole leftover cells to smaller items first. boolean needsExpansion = false; - long smallestMultiCellItemsAt = 0; - while (multiCellItemCount > 0 && cellsRemaining > 0) { + long smallestExpandableItemsAt = 0; + while (expandableItemCount > 0 && cellsRemaining > 0) { int minCells = Integer.MAX_VALUE; long minCellsAt = 0; // Bit locations are indices of relevant child views int minCellsItemCount = 0; @@ -152,7 +152,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo final LayoutParams lp = (LayoutParams) child.getLayoutParams(); // Don't try to expand items that shouldn't. - if (!lp.multiCell) continue; + if (!lp.expandable) continue; // Mark indices of children that can receive an extra cell. if (lp.cellsUsed < minCells) { @@ -165,10 +165,10 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo } } - if (minCellsItemCount < cellsRemaining) break; // Couldn't expand anything evenly. Stop. + if (minCellsItemCount > cellsRemaining) break; // Couldn't expand anything evenly. Stop. // Items that get expanded will always be in the set of smallest items when we're done. - smallestMultiCellItemsAt |= minCellsAt; + smallestExpandableItemsAt |= minCellsAt; for (int i = 0; i < childCount; i++) { if ((minCellsAt & (1 << i)) == 0) continue; @@ -186,12 +186,12 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo // Divide any space left that wouldn't divide along cell boundaries // evenly among the smallest multi-cell (expandable) items. - if (cellsRemaining > 0 && smallestMultiCellItemsAt != 0) { - final int expandCount = Long.bitCount(smallestMultiCellItemsAt); + if (cellsRemaining > 0 && smallestExpandableItemsAt != 0) { + final int expandCount = Long.bitCount(smallestExpandableItemsAt); final int extraPixels = cellsRemaining * cellSize / expandCount; for (int i = 0; i < childCount; i++) { - if ((smallestMultiCellItemsAt & (1 << i)) == 0) continue; + if ((smallestExpandableItemsAt & (1 << i)) == 0) continue; final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); @@ -229,7 +229,7 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo * Measure a child view to fit within cell-based formatting. The child's width * will be measured to a whole multiple of cellSize. * - *

Sets the multiCell and cellsUsed fields of LayoutParams. + *

Sets the expandable and cellsUsed fields of LayoutParams. * * @param child Child to measure * @param cellSize Size of one cell @@ -241,21 +241,14 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo static int measureChildForCells(View child, int cellSize, int cellsRemaining, int parentHeightMeasureSpec, int parentHeightPadding) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); - final ActionMenuItemView itemView = child instanceof ActionMenuItemView ? - (ActionMenuItemView) child : null; final int childHeightSize = MeasureSpec.getSize(parentHeightMeasureSpec) - parentHeightPadding; final int childHeightMode = MeasureSpec.getMode(parentHeightMeasureSpec); final int childHeightSpec = MeasureSpec.makeMeasureSpec(childHeightSize, childHeightMode); - int cellsUsed = cellsRemaining > 0 ? 1 : 0; - final boolean multiCell = !lp.isOverflowButton && - (itemView == null || itemView.hasText()); - - lp.multiCell = multiCell; - - if (multiCell && cellsRemaining > 0) { + int cellsUsed = 0; + if (cellsRemaining > 0) { final int childWidthSpec = MeasureSpec.makeMeasureSpec( cellSize * cellsRemaining, MeasureSpec.AT_MOST); child.measure(childWidthSpec, childHeightSpec); @@ -264,6 +257,12 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo cellsUsed = measuredWidth / cellSize; if (measuredWidth % cellSize != 0) cellsUsed++; } + + final ActionMenuItemView itemView = child instanceof ActionMenuItemView ? + (ActionMenuItemView) child : null; + final boolean expandable = !lp.isOverflowButton && itemView != null && itemView.hasText(); + lp.expandable = expandable; + lp.cellsUsed = cellsUsed; final int targetWidth = cellsUsed * cellSize; child.measure(MeasureSpec.makeMeasureSpec(targetWidth, MeasureSpec.EXACTLY), @@ -426,9 +425,10 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo @ViewDebug.ExportedProperty(category = "layout") public int cellsUsed; @ViewDebug.ExportedProperty(category = "layout") - public boolean multiCell; - @ViewDebug.ExportedProperty(category = "layout") public int extraPixels; + @ViewDebug.ExportedProperty(category = "layout") + public boolean expandable; + public boolean expanded; public LayoutParams(Context c, AttributeSet attrs) { diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 75acb37b4ded..73aa9890d9b3 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1789,6 +1789,7 @@ + diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 9ee4b6ade4a1..11016f4a5dee 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1314,6 +1314,13 @@ @android:dimen/action_bar_subtitle_text_size + + @@ -1848,7 +1855,8 @@