diff options
91 files changed, 3191 insertions, 1409 deletions
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java index 9d48efc..616b796 100644 --- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java +++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java @@ -63,6 +63,8 @@ public class UiTestAutomationBridge { private AccessibilityEvent mLastEvent; + private AccessibilityEvent mLastWindowStateChangeEvent; + private volatile boolean mWaitingForEventDelivery; private volatile boolean mUnprocessedEventAvailable; @@ -138,12 +140,22 @@ public class UiTestAutomationBridge { public void onAccessibilityEvent(AccessibilityEvent event) { synchronized (mLock) { while (true) { + mLastEvent = AccessibilityEvent.obtain(event); + + final int eventType = event.getEventType(); + if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED + || eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) { + if (mLastWindowStateChangeEvent != null) { + mLastWindowStateChangeEvent.recycle(); + } + mLastWindowStateChangeEvent = mLastEvent; + } + if (!mWaitingForEventDelivery) { break; } if (!mUnprocessedEventAvailable) { mUnprocessedEventAvailable = true; - mLastEvent = AccessibilityEvent.obtain(event); mLock.notifyAll(); break; } @@ -409,6 +421,20 @@ public class UiTestAutomationBridge { accessibilityWindowId, accessibilityNodeId, action); } + /** + * Gets the root {@link AccessibilityNodeInfo} in the active window. + * + * @return The root info. + */ + public AccessibilityNodeInfo getRootAccessibilityNodeInfoInActiveWindow() { + synchronized (mLock) { + if (mLastWindowStateChangeEvent != null) { + return mLastWindowStateChangeEvent.getSource(); + } + } + return null; + } + private void ensureValidConnection(int connectionId) { if (connectionId == AccessibilityInteractionClient.NO_ID) { throw new IllegalStateException("UiAutomationService not connected." diff --git a/core/java/android/net/INetworkPolicyListener.aidl b/core/java/android/net/INetworkPolicyListener.aidl index a45ec54..31dc965 100644 --- a/core/java/android/net/INetworkPolicyListener.aidl +++ b/core/java/android/net/INetworkPolicyListener.aidl @@ -21,5 +21,6 @@ oneway interface INetworkPolicyListener { void onUidRulesChanged(int uid, int uidRules); void onMeteredIfacesChanged(in String[] meteredIfaces); + void onRestrictBackgroundChanged(boolean restrictBackground); } diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index fa4dd25..1e92b43 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -723,6 +723,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawPatch(Bitmap bitmap, byte[] chunks, RectF dst, Paint paint) { + if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps"); // Shaders are ignored when drawing patches int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; final int nativePaint = paint == null ? 0 : paint.mNativePaint; @@ -736,6 +737,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { + if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps"); // Shaders are ignored when drawing bitmaps int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; final int nativePaint = paint == null ? 0 : paint.mNativePaint; @@ -748,6 +750,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { + if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps"); // Shaders are ignored when drawing bitmaps int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; final int nativePaint = paint == null ? 0 : paint.mNativePaint; @@ -761,6 +764,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { + if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps"); // Shaders are ignored when drawing bitmaps int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; final int nativePaint = paint == null ? 0 : paint.mNativePaint; @@ -784,6 +788,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { + if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps"); // Shaders are ignored when drawing bitmaps int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE; final int nativePaint = paint == null ? 0 : paint.mNativePaint; @@ -832,6 +837,7 @@ class GLES20Canvas extends HardwareCanvas { @Override public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint) { + if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps"); if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) { throw new ArrayIndexOutOfBoundsException(); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 8d32edc..7658d04 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -12734,9 +12734,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal * </p> * * <p> - * The actual mesurement work of a view is performed in + * The actual measurement work of a view is performed in * {@link #onMeasure(int, int)}, called by this method. Therefore, only - * {@link #onMeasure(int, int)} can and must be overriden by subclasses. + * {@link #onMeasure(int, int)} can and must be overridden by subclasses. * </p> * * diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index b4c38db..c463b40 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -1156,8 +1156,13 @@ public class WebSettings { } /** - * Tell the WebView to load image resources automatically. - * @param flag True if the WebView should load images automatically. + * Sets whether the WebView should load image resources. Note that this method + * controls loading of all images, including those embedded using the data + * URI scheme. Use {@link #setBlockNetworkImage} to control loading only + * of images specified using network URI schemes. Note that if the value of this + * setting is changed from false to true, all images resources referenced + * by content currently displayed by the WebView are loaded automatically. + * @param flag Whether the WebView should load image resources. */ public synchronized void setLoadsImagesAutomatically(boolean flag) { if (mLoadsImagesAutomatically != flag) { @@ -1167,20 +1172,26 @@ public class WebSettings { } /** - * Return true if the WebView will load image resources automatically. - * The default is true. - * @return True if the WebView loads images automatically. + * Returns true if the WebView loads image resources. This includes + * images embedded using the data URI scheme. The default is true. + * @return True if the WebView loads image resources. */ public synchronized boolean getLoadsImagesAutomatically() { return mLoadsImagesAutomatically; } /** - * Tell the WebView to block network images. This is only checked when - * {@link #getLoadsImagesAutomatically} is true. If you set the value to - * false, images will automatically be loaded. Use this api to reduce - * bandwidth only. Use {@link #setBlockNetworkLoads} if possible. - * @param flag True if the WebView should block network images. + * Sets whether the WebView should not load image resources from the + * network (resources accessed via http and https URI schemes). Note + * that this method has no effect unless + * {@link #getLoadsImagesAutomatically} returns true. Also note that + * disabling all network loads using {@link #setBlockNetworkLoads} + * will also prevent network images from loading, even if this flag is set + * to false. When the value of this setting is changed from true to false, + * network images resources referenced by content currently displayed by + * the WebView are fetched automatically. + * @param flag Whether the WebView should not load image resources from + * the network. * @see #setBlockNetworkLoads */ public synchronized void setBlockNetworkImage(boolean flag) { @@ -1191,20 +1202,27 @@ public class WebSettings { } /** - * Return true if the WebView will block network images. The default is - * false. - * @return True if the WebView blocks network images. + * Returns true if the WebView does not load image resources from the network. + * The default is false. + * @return True if the WebView does not load image resources from the network. */ public synchronized boolean getBlockNetworkImage() { return mBlockNetworkImage; } /** - * Tell the WebView to block all network load requests. If you set the - * value to false, you must call {@link android.webkit.WebView#reload} to - * fetch remote resources. This flag supercedes the value passed to - * {@link #setBlockNetworkImage}. - * @param flag True if the WebView should block all network loads. + * Sets whether the WebView should not load resources from the network. + * Use {@link #setBlockNetworkImage} to only avoid loading + * image resources. Note that if the value of this setting is + * changed from true to false, network resources referenced by content + * currently displayed by the WebView are not fetched until + * {@link android.webkit.WebView#reload} is called. + * If the application does not have the + * {@link android.Manifest.permission#INTERNET} permission, attempts to set + * a value of false will cause a {@link java.lang.SecurityException} + * to be thrown. + * @param flag Whether the WebView should not load any resources + * from the network. * @see android.webkit.WebView#reload */ public synchronized void setBlockNetworkLoads(boolean flag) { @@ -1216,9 +1234,11 @@ public class WebSettings { } /** - * Return true if the WebView will block all network loads. The default is - * false. - * @return True if the WebView blocks all network loads. + * Returns true if the WebView does not load any resources from the network. + * The default value is false if the application has the + * {@link android.Manifest.permission#INTERNET} permission, otherwise it is + * true. + * @return True if the WebView does not load any resources from the network. */ public synchronized boolean getBlockNetworkLoads() { return mBlockNetworkLoads; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 164bc64..99349b0 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -1205,6 +1205,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (imm != null) imm.restartInput(this); } + mTextDisplayListIsValid = false; prepareCursorControllers(); // start or stop the cursor blinking as appropriate @@ -2310,6 +2311,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener public void setHighlightColor(int color) { if (mHighlightColor != color) { mHighlightColor = color; + mTextDisplayListIsValid = false; invalidate(); } } @@ -2330,6 +2332,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mShadowDx = dx; mShadowDy = dy; + mTextDisplayListIsValid = false; invalidate(); } @@ -2821,6 +2824,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } if (inval) { + mTextDisplayListIsValid = false; invalidate(); } } @@ -4834,10 +4838,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int extendedPaddingTop = getExtendedPaddingTop(); int extendedPaddingBottom = getExtendedPaddingBottom(); + final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop; + final int maxScrollY = mLayout.getHeight() - vspace; + float clipLeft = compoundPaddingLeft + scrollX; - float clipTop = extendedPaddingTop + scrollY; + float clipTop = (scrollY == 0) ? 0 : extendedPaddingTop + scrollY; float clipRight = right - left - compoundPaddingRight + scrollX; - float clipBottom = bottom - top - extendedPaddingBottom + scrollY; + float clipBottom = bottom - top + scrollY - + ((scrollY == maxScrollY) ? 0 : extendedPaddingBottom); if (mShadowRadius != 0) { clipLeft += Math.min(0, mShadowDx - mShadowRadius); diff --git a/core/res/MakeJavaSymbols.sed b/core/res/MakeJavaSymbols.sed new file mode 100644 index 0000000..d02fffa --- /dev/null +++ b/core/res/MakeJavaSymbols.sed @@ -0,0 +1,25 @@ +# Run this on the errors output by javac of missing resource symbols, +# to generate the set of <java-symbol> commands to have aapt generate +# the symbol for them. +# +# For example: make framework 2>&1 | sed -n -f MakeJavaSymbols.sed | sort -u + +s|.*R.id.\([a-zA-Z0-9_]*\).*| <java-symbol type="id" name="\1" />|gp +s|.*R.attr.\([a-zA-Z0-9_]*\).*| <java-symbol type="attr" name="\1" />|gp +s|.*R.bool.\([a-zA-Z0-9_]*\).*| <java-symbol type="bool" name="\1" />|gp +s|.*R.integer.\([a-zA-Z0-9_]*\).*| <java-symbol type="integer" name="\1" />|gp +s|.*R.color.\([a-zA-Z0-9_]*\).*| <java-symbol type="color" name="\1" />|gp +s|.*R.dimen.\([a-zA-Z0-9_]*\).*| <java-symbol type="dimen" name="\1" />|gp +s|.*R.fraction.\([a-zA-Z0-9_]*\).*| <java-symbol type="fraction" name="\1" />|gp +s|.*R.string.\([a-zA-Z0-9_]*\).*| <java-symbol type="string" name="\1" />|gp +s|.*R.plurals.\([a-zA-Z0-9_]*\).*| <java-symbol type="plurals" name="\1" />|gp +s|.*R.array.\([a-zA-Z0-9_]*\).*| <java-symbol type="array" name="\1" />|gp +s|.*R.drawable.\([a-zA-Z0-9_]*\).*| <java-symbol type="drawable" name="\1" />|gp +s|.*R.layout.\([a-zA-Z0-9_]*\).*| <java-symbol type="layout" name="\1" />|gp +s|.*R.anim.\([a-zA-Z0-9_]*\).*| <java-symbol type="anim" name="\1" />|gp +s|.*R.animator.\([a-zA-Z0-9_]*\).*| <java-symbol type="animator" name="\1" />|gp +s|.*R.interpolator.\([a-zA-Z0-9_]*\).*| <java-symbol type="interpolator" name="\1" />|gp +s|.*R.menu.\([a-zA-Z0-9_]*\).*| <java-symbol type="menu" name="\1" />|gp +s|.*R.xml.\([a-zA-Z0-9_]*\).*| <java-symbol type="xml" name="\1" />|gp +s|.*R.raw.\([a-zA-Z0-9_]*\).*| <java-symbol type="raw" name="\1" />|gp +s|.*R.style.\([a-zA-Z0-9_]*\).*| <java-symbol type="style" name="\1" />|gp diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 4d97ad2..e3c2bd8 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -23,6 +23,1514 @@ SDK. Instead, put them here. --> <private-symbols package="com.android.internal" /> + <!-- Private symbols that we need to reference from framework code. See + frameworks/base/core/res/MakeJavaSymbols.sed for how to easily generate + this. + --> + <java-symbol type="id" name="account_name" /> + <java-symbol type="id" name="account_row_checkmark" /> + <java-symbol type="id" name="account_row_icon" /> + <java-symbol type="id" name="account_row_text" /> + <java-symbol type="id" name="account_type" /> + <java-symbol type="id" name="action_bar" /> + <java-symbol type="id" name="action_bar_container" /> + <java-symbol type="id" name="action_bar_title" /> + <java-symbol type="id" name="action_bar_subtitle" /> + <java-symbol type="id" name="action_context_bar" /> + <java-symbol type="id" name="action_menu_presenter" /> + <java-symbol type="id" name="action_mode_close_button" /> + <java-symbol type="id" name="activity_chooser_view_content" /> + <java-symbol type="id" name="addAccount" /> + <java-symbol type="id" name="albumart" /> + <java-symbol type="id" name="alertTitle" /> + <java-symbol type="id" name="allow_button" /> + <java-symbol type="id" name="alwaysUse" /> + <java-symbol type="id" name="amPm" /> + <java-symbol type="id" name="authtoken_type" /> + <java-symbol type="id" name="back_button" /> + <java-symbol type="id" name="btn_next" /> + <java-symbol type="id" name="btn_play" /> + <java-symbol type="id" name="btn_prev" /> + <java-symbol type="id" name="button_bar" /> + <java-symbol type="id" name="buttonPanel" /> + <java-symbol type="id" name="by_common" /> + <java-symbol type="id" name="by_org" /> + <java-symbol type="id" name="by_org_unit" /> + <java-symbol type="id" name="calendar_view" /> + <java-symbol type="id" name="cancel" /> + <java-symbol type="id" name="characterPicker" /> + <java-symbol type="id" name="clearDefaultHint" /> + <java-symbol type="id" name="contentPanel" /> + <java-symbol type="id" name="customPanel" /> + <java-symbol type="id" name="dangerous_perms_list" /> + <java-symbol type="id" name="datePicker" /> + <java-symbol type="id" name="day" /> + <java-symbol type="id" name="day_names" /> + <java-symbol type="id" name="decrement" /> + <java-symbol type="id" name="default_activity_button" /> + <java-symbol type="id" name="deny_button" /> + <java-symbol type="id" name="description" /> + <java-symbol type="id" name="divider" /> + <java-symbol type="id" name="edit_query" /> + <java-symbol type="id" name="edittext_container" /> + <java-symbol type="id" name="enter_pin_section" /> + <java-symbol type="id" name="expand_activities_button" /> + <java-symbol type="id" name="expand_button" /> + <java-symbol type="id" name="expand_button_divider" /> + <java-symbol type="id" name="expires_on" /> + <java-symbol type="id" name="find_next" /> + <java-symbol type="id" name="find_prev" /> + <java-symbol type="id" name="ffwd" /> + <java-symbol type="id" name="fillInIntent" /> + <java-symbol type="id" name="find" /> + <java-symbol type="id" name="fullscreenArea" /> + <java-symbol type="id" name="headers" /> + <java-symbol type="id" name="hour" /> + <java-symbol type="id" name="icon" /> + <java-symbol type="id" name="image" /> + <java-symbol type="id" name="imageButton" /> + <java-symbol type="id" name="increment" /> + <java-symbol type="id" name="internalEmpty" /> + <java-symbol type="id" name="info" /> + <java-symbol type="id" name="inputExtractAccessories" /> + <java-symbol type="id" name="inputExtractAction" /> + <java-symbol type="id" name="inputExtractEditButton" /> + <java-symbol type="id" name="issued_on" /> + <java-symbol type="id" name="left_icon" /> + <java-symbol type="id" name="leftSpacer" /> + <java-symbol type="id" name="line3" /> + <java-symbol type="id" name="list_footer" /> + <java-symbol type="id" name="list_item" /> + <java-symbol type="id" name="listContainer" /> + <java-symbol type="id" name="locale" /> + <java-symbol type="id" name="matches" /> + <java-symbol type="id" name="mediacontroller_progress" /> + <java-symbol type="id" name="minute" /> + <java-symbol type="id" name="mode_normal" /> + <java-symbol type="id" name="month" /> + <java-symbol type="id" name="month_name" /> + <java-symbol type="id" name="name" /> + <java-symbol type="id" name="next" /> + <java-symbol type="id" name="next_button" /> + <java-symbol type="id" name="new_app_action" /> + <java-symbol type="id" name="new_app_description" /> + <java-symbol type="id" name="new_app_icon" /> + <java-symbol type="id" name="no_permissions" /> + <java-symbol type="id" name="non_dangerous_perms_list" /> + <java-symbol type="id" name="numberpicker_input" /> + <java-symbol type="id" name="old_app_action" /> + <java-symbol type="id" name="old_app_description" /> + <java-symbol type="id" name="old_app_icon" /> + <java-symbol type="id" name="package_label" /> + <java-symbol type="id" name="packages_list" /> + <java-symbol type="id" name="pause" /> + <java-symbol type="id" name="perm_icon" /> + <java-symbol type="id" name="permission_group" /> + <java-symbol type="id" name="permission_list" /> + <java-symbol type="id" name="pickers" /> + <java-symbol type="id" name="prefs" /> + <java-symbol type="id" name="prefs_frame" /> + <java-symbol type="id" name="prev" /> + <java-symbol type="id" name="progress" /> + <java-symbol type="id" name="progress_circular" /> + <java-symbol type="id" name="progress_horizontal" /> + <java-symbol type="id" name="progress_number" /> + <java-symbol type="id" name="progress_percent" /> + <java-symbol type="id" name="progressContainer" /> + <java-symbol type="id" name="rew" /> + <java-symbol type="id" name="rightSpacer" /> + <java-symbol type="id" name="rowTypeId" /> + <java-symbol type="id" name="scrollView" /> + <java-symbol type="id" name="search_app_icon" /> + <java-symbol type="id" name="search_badge" /> + <java-symbol type="id" name="search_bar" /> + <java-symbol type="id" name="search_button" /> + <java-symbol type="id" name="search_close_btn" /> + <java-symbol type="id" name="search_edit_frame" /> + <java-symbol type="id" name="search_go_btn" /> + <java-symbol type="id" name="search_mag_icon" /> + <java-symbol type="id" name="search_plate" /> + <java-symbol type="id" name="search_src_text" /> + <java-symbol type="id" name="search_view" /> + <java-symbol type="id" name="search_voice_btn" /> + <java-symbol type="id" name="select_all" /> + <java-symbol type="id" name="serial_number" /> + <java-symbol type="id" name="seekbar" /> + <java-symbol type="id" name="sha1_fingerprint" /> + <java-symbol type="id" name="sha256_fingerprint" /> + <java-symbol type="id" name="share" /> + <java-symbol type="id" name="shortcut" /> + <java-symbol type="id" name="show_more" /> + <java-symbol type="id" name="show_more_icon" /> + <java-symbol type="id" name="show_more_text" /> + <java-symbol type="id" name="skip_button" /> + <java-symbol type="id" name="slider_group" /> + <java-symbol type="id" name="split_action_bar" /> + <java-symbol type="id" name="stream_icon" /> + <java-symbol type="id" name="submit_area" /> + <java-symbol type="id" name="switch_new" /> + <java-symbol type="id" name="switch_old" /> + <java-symbol type="id" name="switchWidget" /> + <java-symbol type="id" name="text" /> + <java-symbol type="id" name="textButton" /> + <java-symbol type="id" name="time" /> + <java-symbol type="id" name="time_current" /> + <java-symbol type="id" name="timeDisplayBackground" /> + <java-symbol type="id" name="timeDisplayForeground" /> + <java-symbol type="id" name="titleDivider" /> + <java-symbol type="id" name="titleDividerTop" /> + <java-symbol type="id" name="timePicker" /> + <java-symbol type="id" name="title_template" /> + <java-symbol type="id" name="to_common" /> + <java-symbol type="id" name="to_org" /> + <java-symbol type="id" name="to_org_unit" /> + <java-symbol type="id" name="topPanel" /> + <java-symbol type="id" name="up" /> + <java-symbol type="id" name="value" /> + <java-symbol type="id" name="visible_panel" /> + <java-symbol type="id" name="websearch" /> + <java-symbol type="id" name="wifi_p2p_wps_pin" /> + <java-symbol type="id" name="year" /> + <java-symbol type="id" name="zoomControls" /> + <java-symbol type="id" name="zoomIn" /> + <java-symbol type="id" name="zoomMagnify" /> + <java-symbol type="id" name="zoomOut" /> + + <java-symbol type="attr" name="actionModeShareDrawable" /> + <java-symbol type="attr" name="alertDialogCenterButtons" /> + <java-symbol type="attr" name="gestureOverlayViewStyle" /> + <java-symbol type="attr" name="keyboardViewStyle" /> + <java-symbol type="attr" name="numberPickerStyle" /> + <java-symbol type="attr" name="pointerStyle" /> + <java-symbol type="attr" name="preferenceFrameLayoutStyle" /> + <java-symbol type="attr" name="searchDialogTheme" /> + <java-symbol type="attr" name="searchViewSearchIcon" /> + <java-symbol type="attr" name="stackViewStyle" /> + <java-symbol type="attr" name="switchStyle" /> + <java-symbol type="attr" name="textAppearanceAutoCorrectionSuggestion" /> + <java-symbol type="attr" name="textAppearanceEasyCorrectSuggestion" /> + <java-symbol type="attr" name="textAppearanceMisspelledSuggestion" /> + <java-symbol type="attr" name="textColorSearchUrl" /> + <java-symbol type="attr" name="timePickerStyle" /> + + <java-symbol type="bool" name="action_bar_embed_tabs" /> + <java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" /> + <java-symbol type="bool" name="config_allowActionMenuItemTextWithIcon" /> + <java-symbol type="bool" name="config_bluetooth_adapter_quick_switch" /> + <java-symbol type="bool" name="config_bluetooth_sco_off_call" /> + <java-symbol type="bool" name="config_duplicate_port_omadm_wappush" /> + <java-symbol type="bool" name="config_enable_emergency_call_while_sim_locked" /> + <java-symbol type="bool" name="config_enable_puk_unlock_screen" /> + <java-symbol type="bool" name="config_mms_content_disposition_support" /> + <java-symbol type="bool" name="config_showMenuShortcutsWhenKeyboardPresent" /> + <java-symbol type="bool" name="config_sip_wifi_only" /> + <java-symbol type="bool" name="config_sms_capable" /> + <java-symbol type="bool" name="config_sms_utf8_support" /> + <java-symbol type="bool" name="config_swipeDisambiguation" /> + <java-symbol type="bool" name="config_telephony_use_own_number_for_voicemail" /> + <java-symbol type="bool" name="config_ui_enableFadingMarquee" /> + <java-symbol type="bool" name="config_use_strict_phone_number_comparation" /> + <java-symbol type="bool" name="config_voice_capable" /> + <java-symbol type="bool" name="preferences_prefer_dual_pane" /> + <java-symbol type="bool" name="skip_restoring_network_selection" /> + <java-symbol type="bool" name="split_action_bar_is_narrow" /> + + <java-symbol type="integer" name="config_cursorWindowSize" /> + <java-symbol type="integer" name="config_longPressOnPowerBehavior" /> + <java-symbol type="integer" name="config_max_pan_devices" /> + <java-symbol type="integer" name="config_ntpTimeout" /> + <java-symbol type="integer" name="config_wifi_framework_scan_interval" /> + <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" /> + <java-symbol type="integer" name="db_connection_pool_size" /> + <java-symbol type="integer" name="max_action_buttons" /> + + <java-symbol type="color" name="tab_indicator_text_v4" /> + + <java-symbol type="dimen" name="config_prefDialogWidth" /> + <java-symbol type="dimen" name="config_viewConfigurationTouchSlop" /> + <java-symbol type="dimen" name="default_app_widget_padding_bottom" /> + <java-symbol type="dimen" name="default_app_widget_padding_left" /> + <java-symbol type="dimen" name="default_app_widget_padding_right" /> + <java-symbol type="dimen" name="default_app_widget_padding_top" /> + <java-symbol type="dimen" name="default_gap" /> + <java-symbol type="dimen" name="dropdownitem_icon_width" /> + <java-symbol type="dimen" name="dropdownitem_text_padding_left" /> + <java-symbol type="dimen" name="fastscroll_overlay_size" /> + <java-symbol type="dimen" name="fastscroll_thumb_height" /> + <java-symbol type="dimen" name="fastscroll_thumb_width" /> + <java-symbol type="dimen" name="fastscroll_thumb_width" /> + <java-symbol type="dimen" name="password_keyboard_spacebar_vertical_correction" /> + <java-symbol type="dimen" name="search_view_preferred_width" /> + <java-symbol type="dimen" name="textview_error_popup_default_width" /> + <java-symbol type="dimen" name="toast_y_offset" /> + <java-symbol type="dimen" name="volume_panel_top" /> + + <java-symbol type="string" name="addToDictionary" /> + <java-symbol type="string" name="action_bar_home_description" /> + <java-symbol type="string" name="action_bar_up_description" /> + <java-symbol type="string" name="delete" /> + <java-symbol type="string" name="deleteText" /> + <java-symbol type="string" name="ellipsis_two_dots" /> + <java-symbol type="string" name="ellipsis" /> + <java-symbol type="string" name="grant_permissions_header_text" /> + <java-symbol type="string" name="list_delimeter" /> + <java-symbol type="string" name="menu_delete_shortcut_label" /> + <java-symbol type="string" name="menu_enter_shortcut_label" /> + <java-symbol type="string" name="menu_space_shortcut_label" /> + <java-symbol type="string" name="notification_title" /> + <java-symbol type="string" name="permission_request_notification_with_subtitle" /> + <java-symbol type="string" name="prepend_shortcut_label" /> + <java-symbol type="string" name="replace" /> + <java-symbol type="string" name="textSelectionCABTitle" /> + <java-symbol type="string" name="BaMmi" /> + <java-symbol type="string" name="CLIRDefaultOffNextCallOff" /> + <java-symbol type="string" name="CLIRDefaultOffNextCallOn" /> + <java-symbol type="string" name="CLIRDefaultOnNextCallOff" /> + <java-symbol type="string" name="CLIRDefaultOnNextCallOn" /> + <java-symbol type="string" name="CLIRPermanent" /> + <java-symbol type="string" name="CfMmi" /> + <java-symbol type="string" name="ClipMmi" /> + <java-symbol type="string" name="ClirMmi" /> + <java-symbol type="string" name="CwMmi" /> + <java-symbol type="string" name="Midnight" /> + <java-symbol type="string" name="Noon" /> + <java-symbol type="string" name="PinMmi" /> + <java-symbol type="string" name="PwdMmi" /> + <java-symbol type="string" name="RestrictedChangedTitle" /> + <java-symbol type="string" name="RestrictedOnAllVoice" /> + <java-symbol type="string" name="RestrictedOnData" /> + <java-symbol type="string" name="RestrictedOnEmergency" /> + <java-symbol type="string" name="RestrictedOnNormal" /> + <java-symbol type="string" name="SetupCallDefault" /> + <java-symbol type="string" name="abbrev_month" /> + <java-symbol type="string" name="abbrev_month_day" /> + <java-symbol type="string" name="abbrev_month_day_year" /> + <java-symbol type="string" name="abbrev_month_year" /> + <java-symbol type="string" name="accept" /> + <java-symbol type="string" name="activity_chooser_view_see_all" /> + <java-symbol type="string" name="activitychooserview_choose_application" /> + <java-symbol type="string" name="alternate_eri_file" /> + <java-symbol type="string" name="alwaysUse" /> + <java-symbol type="string" name="am" /> + <java-symbol type="string" name="autofill_address_line_1_label_re" /> + <java-symbol type="string" name="autofill_address_line_1_re" /> + <java-symbol type="string" name="autofill_address_line_2_re" /> + <java-symbol type="string" name="autofill_address_line_3_re" /> + <java-symbol type="string" name="autofill_address_name_separator" /> + <java-symbol type="string" name="autofill_address_summary_format" /> + <java-symbol type="string" name="autofill_address_summary_name_format" /> + <java-symbol type="string" name="autofill_address_summary_separator" /> + <java-symbol type="string" name="autofill_address_type_same_as_re" /> + <java-symbol type="string" name="autofill_address_type_use_my_re" /> + <java-symbol type="string" name="autofill_area" /> + <java-symbol type="string" name="autofill_area_code_notext_re" /> + <java-symbol type="string" name="autofill_area_code_re" /> + <java-symbol type="string" name="autofill_attention_ignored_re" /> + <java-symbol type="string" name="autofill_billing_designator_re" /> + <java-symbol type="string" name="autofill_card_cvc_re" /> + <java-symbol type="string" name="autofill_card_ignored_re" /> + <java-symbol type="string" name="autofill_card_number_re" /> + <java-symbol type="string" name="autofill_city_re" /> + <java-symbol type="string" name="autofill_company_re" /> + <java-symbol type="string" name="autofill_country_code_re" /> + <java-symbol type="string" name="autofill_country_re" /> + <java-symbol type="string" name="autofill_county" /> + <java-symbol type="string" name="autofill_department" /> + <java-symbol type="string" name="autofill_district" /> + <java-symbol type="string" name="autofill_email_re" /> + <java-symbol type="string" name="autofill_emirate" /> + <java-symbol type="string" name="autofill_expiration_date_re" /> + <java-symbol type="string" name="autofill_expiration_month_re" /> + <java-symbol type="string" name="autofill_fax_re" /> + <java-symbol type="string" name="autofill_first_name_re" /> + <java-symbol type="string" name="autofill_island" /> + <java-symbol type="string" name="autofill_last_name_re" /> + <java-symbol type="string" name="autofill_middle_initial_re" /> + <java-symbol type="string" name="autofill_middle_name_re" /> + <java-symbol type="string" name="autofill_name_on_card_contextual_re" /> + <java-symbol type="string" name="autofill_name_on_card_re" /> + <java-symbol type="string" name="autofill_name_re" /> + <java-symbol type="string" name="autofill_name_specific_re" /> + <java-symbol type="string" name="autofill_parish" /> + <java-symbol type="string" name="autofill_phone_extension_re" /> + <java-symbol type="string" name="autofill_phone_prefix_re" /> + <java-symbol type="string" name="autofill_phone_prefix_separator_re" /> + <java-symbol type="string" name="autofill_phone_re" /> + <java-symbol type="string" name="autofill_phone_suffix_re" /> + <java-symbol type="string" name="autofill_phone_suffix_separator_re" /> + <java-symbol type="string" name="autofill_postal_code" /> + <java-symbol type="string" name="autofill_prefecture" /> + <java-symbol type="string" name="autofill_province" /> + <java-symbol type="string" name="autofill_region_ignored_re" /> + <java-symbol type="string" name="autofill_shipping_designator_re" /> + <java-symbol type="string" name="autofill_state" /> + <java-symbol type="string" name="autofill_state_re" /> + <java-symbol type="string" name="autofill_this_form" /> + <java-symbol type="string" name="autofill_username_re" /> + <java-symbol type="string" name="autofill_zip_4_re" /> + <java-symbol type="string" name="autofill_zip_code" /> + <java-symbol type="string" name="autofill_zip_code_re" /> + <java-symbol type="string" name="badPin" /> + <java-symbol type="string" name="badPuk" /> + <java-symbol type="string" name="byteShort" /> + <java-symbol type="string" name="cfTemplateForwarded" /> + <java-symbol type="string" name="cfTemplateForwardedTime" /> + <java-symbol type="string" name="cfTemplateNotForwarded" /> + <java-symbol type="string" name="cfTemplateRegistered" /> + <java-symbol type="string" name="cfTemplateRegisteredTime" /> + <java-symbol type="string" name="checkbox_checked" /> + <java-symbol type="string" name="checkbox_not_checked" /> + <java-symbol type="string" name="chooseActivity" /> + <java-symbol type="string" name="config_default_dns_server" /> + <java-symbol type="string" name="config_ethernet_iface_regex" /> + <java-symbol type="string" name="config_ntpServer" /> + <java-symbol type="string" name="config_tether_apndata" /> + <java-symbol type="string" name="config_useragentprofile_url" /> + <java-symbol type="string" name="config_wifi_p2p_device_type" /> + <java-symbol type="string" name="contentServiceSync" /> + <java-symbol type="string" name="contentServiceSyncNotificationTitle" /> + <java-symbol type="string" name="contentServiceTooManyDeletesNotificationDesc" /> + <java-symbol type="string" name="date1_date2" /> + <java-symbol type="string" name="date1_time1_date2_time2" /> + <java-symbol type="string" name="date_and_time" /> + <java-symbol type="string" name="date_picker_decrement_day_button" /> + <java-symbol type="string" name="date_picker_decrement_month_button" /> + <java-symbol type="string" name="date_picker_decrement_year_button" /> + <java-symbol type="string" name="date_picker_dialog_title" /> + <java-symbol type="string" name="date_picker_increment_day_button" /> + <java-symbol type="string" name="date_picker_increment_month_button" /> + <java-symbol type="string" name="date_picker_increment_year_button" /> + <java-symbol type="string" name="date_time" /> + <java-symbol type="string" name="date_time_set" /> + <java-symbol type="string" name="day_of_week_long_friday" /> + <java-symbol type="string" name="day_of_week_long_monday" /> + <java-symbol type="string" name="day_of_week_long_saturday" /> + <java-symbol type="string" name="day_of_week_long_sunday" /> + <java-symbol type="string" name="day_of_week_long_thursday" /> + <java-symbol type="string" name="day_of_week_long_tuesday" /> + <java-symbol type="string" name="day_of_week_long_wednesday" /> + <java-symbol type="string" name="day_of_week_medium_friday" /> + <java-symbol type="string" name="day_of_week_medium_monday" /> + <java-symbol type="string" name="day_of_week_medium_saturday" /> + <java-symbol type="string" name="day_of_week_medium_sunday" /> + <java-symbol type="string" name="day_of_week_medium_thursday" /> + <java-symbol type="string" name="day_of_week_medium_tuesday" /> + <java-symbol type="string" name="day_of_week_medium_wednesday" /> + <java-symbol type="string" name="day_of_week_short_friday" /> + <java-symbol type="string" name="day_of_week_short_monday" /> + <java-symbol type="string" name="day_of_week_short_saturday" /> + <java-symbol type="string" name="day_of_week_short_sunday" /> + <java-symbol type="string" name="day_of_week_short_thursday" /> + <java-symbol type="string" name="day_of_week_short_tuesday" /> + <java-symbol type="string" name="day_of_week_short_wednesday" /> + <java-symbol type="string" name="day_of_week_shortest_friday" /> + <java-symbol type="string" name="day_of_week_shortest_monday" /> + <java-symbol type="string" name="day_of_week_shortest_saturday" /> + <java-symbol type="string" name="day_of_week_shortest_sunday" /> + <java-symbol type="string" name="day_of_week_shortest_thursday" /> + <java-symbol type="string" name="day_of_week_shortest_tuesday" /> + <java-symbol type="string" name="day_of_week_shortest_wednesday" /> + <java-symbol type="string" name="decline" /> + <java-symbol type="string" name="default_permission_group" /> + <java-symbol type="string" name="default_text_encoding" /> + <java-symbol type="string" name="description_target_unlock_tablet" /> + <java-symbol type="string" name="double_tap_toast" /> + <java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" /> + <java-symbol type="string" name="elapsed_time_short_format_mm_ss" /> + <java-symbol type="string" name="emailTypeCustom" /> + <java-symbol type="string" name="emailTypeHome" /> + <java-symbol type="string" name="emailTypeMobile" /> + <java-symbol type="string" name="emailTypeOther" /> + <java-symbol type="string" name="emailTypeWork" /> + <java-symbol type="string" name="emergency_call_dialog_number_for_display" /> + <java-symbol type="string" name="emergency_calls_only" /> + <java-symbol type="string" name="eventTypeAnniversary" /> + <java-symbol type="string" name="eventTypeBirthday" /> + <java-symbol type="string" name="eventTypeCustom" /> + <java-symbol type="string" name="eventTypeOther" /> + <java-symbol type="string" name="extmedia_format_button_format" /> + <java-symbol type="string" name="extmedia_format_message" /> + <java-symbol type="string" name="extmedia_format_title" /> + <java-symbol type="string" name="fileSizeSuffix" /> + <java-symbol type="string" name="force_close" /> + <java-symbol type="string" name="format_error" /> + <java-symbol type="string" name="gadget_host_error_inflating" /> + <java-symbol type="string" name="gigabyteShort" /> + <java-symbol type="string" name="gpsNotifMessage" /> + <java-symbol type="string" name="gpsNotifTicker" /> + <java-symbol type="string" name="gpsNotifTitle" /> + <java-symbol type="string" name="gpsVerifNo" /> + <java-symbol type="string" name="gpsVerifYes" /> + <java-symbol type="string" name="gsm_alphabet_default_charset" /> + <java-symbol type="string" name="hour_ampm" /> + <java-symbol type="string" name="hour_cap_ampm" /> + <java-symbol type="string" name="hour_minute_24" /> + <java-symbol type="string" name="hour_minute_ampm" /> + <java-symbol type="string" name="hour_minute_cap_ampm" /> + <java-symbol type="string" name="httpError" /> + <java-symbol type="string" name="httpErrorAuth" /> + <java-symbol type="string" name="httpErrorConnect" /> + <java-symbol type="string" name="httpErrorFailedSslHandshake" /> + <java-symbol type="string" name="httpErrorFile" /> + <java-symbol type="string" name="httpErrorFileNotFound" /> + <java-symbol type="string" name="httpErrorIO" /> + <java-symbol type="string" name="httpErrorLookup" /> + <java-symbol type="string" name="httpErrorOk" /> + <java-symbol type="string" name="httpErrorProxyAuth" /> + <java-symbol type="string" name="httpErrorRedirectLoop" /> + <java-symbol type="string" name="httpErrorTimeout" /> + <java-symbol type="string" name="httpErrorTooManyRequests" /> + <java-symbol type="string" name="httpErrorUnsupportedAuthScheme" /> + <java-symbol type="string" name="imProtocolAim" /> + <java-symbol type="string" name="imProtocolCustom" /> + <java-symbol type="string" name="imProtocolGoogleTalk" /> + <java-symbol type="string" name="imProtocolIcq" /> + <java-symbol type="string" name="imProtocolJabber" /> + <java-symbol type="string" name="imProtocolMsn" /> + <java-symbol type="string" name="imProtocolNetMeeting" /> + <java-symbol type="string" name="imProtocolQq" /> + <java-symbol type="string" name="imProtocolSkype" /> + <java-symbol type="string" name="imProtocolYahoo" /> + <java-symbol type="string" name="imTypeCustom" /> + <java-symbol type="string" name="imTypeHome" /> + <java-symbol type="string" name="imTypeOther" /> + <java-symbol type="string" name="imTypeWork" /> + <java-symbol type="string" name="ime_action_default" /> + <java-symbol type="string" name="ime_action_done" /> + <java-symbol type="string" name="ime_action_go" /> + <java-symbol type="string" name="ime_action_next" /> + <java-symbol type="string" name="ime_action_previous" /> + <java-symbol type="string" name="ime_action_search" /> + <java-symbol type="string" name="ime_action_send" /> + <java-symbol type="string" name="invalidPin" /> + <java-symbol type="string" name="js_dialog_before_unload" /> + <java-symbol type="string" name="js_dialog_title" /> + <java-symbol type="string" name="js_dialog_title_default" /> + <java-symbol type="string" name="keyboard_headset_required_to_hear_password" /> + <java-symbol type="string" name="keyboard_password_character_no_headset" /> + <java-symbol type="string" name="keyboardview_keycode_alt" /> + <java-symbol type="string" name="keyboardview_keycode_cancel" /> + <java-symbol type="string" name="keyboardview_keycode_delete" /> + <java-symbol type="string" name="keyboardview_keycode_done" /> + <java-symbol type="string" name="keyboardview_keycode_enter" /> + <java-symbol type="string" name="keyboardview_keycode_mode_change" /> + <java-symbol type="string" name="keyboardview_keycode_shift" /> + <java-symbol type="string" name="kilobyteShort" /> + <java-symbol type="string" name="last_month" /> + <java-symbol type="string" name="launchBrowserDefault" /> + <java-symbol type="string" name="lockscreen_access_pattern_cell_added" /> + <java-symbol type="string" name="lockscreen_access_pattern_cleared" /> + <java-symbol type="string" name="lockscreen_access_pattern_detected" /> + <java-symbol type="string" name="lockscreen_access_pattern_start" /> + <java-symbol type="string" name="lockscreen_emergency_call" /> + <java-symbol type="string" name="lockscreen_return_to_call" /> + <java-symbol type="string" name="lockscreen_transport_pause_description" /> + <java-symbol type="string" name="lockscreen_transport_play_description" /> + <java-symbol type="string" name="lockscreen_transport_stop_description" /> + <java-symbol type="string" name="low_memory" /> + <java-symbol type="string" name="media_bad_removal" /> + <java-symbol type="string" name="media_checking" /> + <java-symbol type="string" name="media_removed" /> + <java-symbol type="string" name="media_shared" /> + <java-symbol type="string" name="media_unknown_state" /> + <java-symbol type="string" name="megabyteShort" /> + <java-symbol type="string" name="midnight" /> + <java-symbol type="string" name="mismatchPin" /> + <java-symbol type="string" name="mmiComplete" /> + <java-symbol type="string" name="mmiError" /> + <java-symbol type="string" name="mmiFdnError" /> + <java-symbol type="string" name="month" /> + <java-symbol type="string" name="month_day" /> + <java-symbol type="string" name="month_day_year" /> + <java-symbol type="string" name="month_long_april" /> + <java-symbol type="string" name="month_long_august" /> + <java-symbol type="string" name="month_long_december" /> + <java-symbol type="string" name="month_long_february" /> + <java-symbol type="string" name="month_long_january" /> + <java-symbol type="string" name="month_long_july" /> + <java-symbol type="string" name="month_long_june" /> + <java-symbol type="string" name="month_long_march" /> + <java-symbol type="string" name="month_long_may" /> + <java-symbol type="string" name="month_long_november" /> + <java-symbol type="string" name="month_long_october" /> + <java-symbol type="string" name="month_long_september" /> + <java-symbol type="string" name="month_long_standalone_april" /> + <java-symbol type="string" name="month_long_standalone_august" /> + <java-symbol type="string" name="month_long_standalone_december" /> + <java-symbol type="string" name="month_long_standalone_february" /> + <java-symbol type="string" name="month_long_standalone_january" /> + <java-symbol type="string" name="month_long_standalone_july" /> + <java-symbol type="string" name="month_long_standalone_june" /> + <java-symbol type="string" name="month_long_standalone_march" /> + <java-symbol type="string" name="month_long_standalone_may" /> + <java-symbol type="string" name="month_long_standalone_november" /> + <java-symbol type="string" name="month_long_standalone_october" /> + <java-symbol type="string" name="month_long_standalone_september" /> + <java-symbol type="string" name="month_medium_april" /> + <java-symbol type="string" name="month_medium_august" /> + <java-symbol type="string" name="month_medium_december" /> + <java-symbol type="string" name="month_medium_february" /> + <java-symbol type="string" name="month_medium_january" /> + <java-symbol type="string" name="month_medium_july" /> + <java-symbol type="string" name="month_medium_june" /> + <java-symbol type="string" name="month_medium_march" /> + <java-symbol type="string" name="month_medium_may" /> + <java-symbol type="string" name="month_medium_november" /> + <java-symbol type="string" name="month_medium_october" /> + <java-symbol type="string" name="month_medium_september" /> + <java-symbol type="string" name="month_shortest_april" /> + <java-symbol type="string" name="month_shortest_august" /> + <java-symbol type="string" name="month_shortest_december" /> + <java-symbol type="string" name="month_shortest_february" /> + <java-symbol type="string" name="month_shortest_january" /> + <java-symbol type="string" name="month_shortest_july" /> + <java-symbol type="string" name="month_shortest_june" /> + <java-symbol type="string" name="month_shortest_march" /> + <java-symbol type="string" name="month_shortest_may" /> + <java-symbol type="string" name="month_shortest_november" /> + <java-symbol type="string" name="month_shortest_october" /> + <java-symbol type="string" name="month_shortest_september" /> + <java-symbol type="string" name="month_year" /> + <java-symbol type="string" name="more_item_label" /> + <java-symbol type="string" name="needPuk" /> + <java-symbol type="string" name="needPuk2" /> + <java-symbol type="string" name="new_app_action" /> + <java-symbol type="string" name="new_app_description" /> + <java-symbol type="string" name="noApplications" /> + <java-symbol type="string" name="no_file_chosen" /> + <java-symbol type="string" name="no_matches" /> + <java-symbol type="string" name="noon" /> + <java-symbol type="string" name="number_picker_increment_scroll_action" /> + <java-symbol type="string" name="number_picker_increment_scroll_mode" /> + <java-symbol type="string" name="numeric_date" /> + <java-symbol type="string" name="numeric_date_format" /> + <java-symbol type="string" name="numeric_date_template" /> + <java-symbol type="string" name="numeric_md1_md2" /> + <java-symbol type="string" name="numeric_md1_time1_md2_time2" /> + <java-symbol type="string" name="numeric_mdy1_mdy2" /> + <java-symbol type="string" name="numeric_mdy1_time1_mdy2_time2" /> + <java-symbol type="string" name="numeric_wday1_md1_time1_wday2_md2_time2" /> + <java-symbol type="string" name="numeric_wday1_md1_wday2_md2" /> + <java-symbol type="string" name="numeric_wday1_mdy1_time1_wday2_mdy2_time2" /> + <java-symbol type="string" name="numeric_wday1_mdy1_wday2_mdy2" /> + <java-symbol type="string" name="old_app_action" /> + <java-symbol type="string" name="old_app_description" /> + <java-symbol type="string" name="older" /> + <java-symbol type="string" name="open_permission_deny" /> + <java-symbol type="string" name="orgTypeCustom" /> + <java-symbol type="string" name="orgTypeOther" /> + <java-symbol type="string" name="orgTypeWork" /> + <java-symbol type="string" name="passwordIncorrect" /> + <java-symbol type="string" name="permissions_format" /> + <java-symbol type="string" name="perms_hide" /> + <java-symbol type="string" name="perms_show_all" /> + <java-symbol type="string" name="petabyteShort" /> + <java-symbol type="string" name="phoneTypeAssistant" /> + <java-symbol type="string" name="phoneTypeCallback" /> + <java-symbol type="string" name="phoneTypeCar" /> + <java-symbol type="string" name="phoneTypeCompanyMain" /> + <java-symbol type="string" name="phoneTypeCustom" /> + <java-symbol type="string" name="phoneTypeFaxHome" /> + <java-symbol type="string" name="phoneTypeFaxWork" /> + <java-symbol type="string" name="phoneTypeHome" /> + <java-symbol type="string" name="phoneTypeIsdn" /> + <java-symbol type="string" name="phoneTypeMain" /> + <java-symbol type="string" name="phoneTypeMms" /> + <java-symbol type="string" name="phoneTypeMobile" /> + <java-symbol type="string" name="phoneTypeOther" /> + <java-symbol type="string" name="phoneTypeOtherFax" /> + <java-symbol type="string" name="phoneTypePager" /> + <java-symbol type="string" name="phoneTypeRadio" /> + <java-symbol type="string" name="phoneTypeTelex" /> + <java-symbol type="string" name="phoneTypeTtyTdd" /> + <java-symbol type="string" name="phoneTypeWork" /> + <java-symbol type="string" name="phoneTypeWorkMobile" /> + <java-symbol type="string" name="phoneTypeWorkPager" /> + <java-symbol type="string" name="pm" /> + <java-symbol type="string" name="policydesc_disableCamera" /> + <java-symbol type="string" name="policydesc_encryptedStorage" /> + <java-symbol type="string" name="policydesc_expirePassword" /> + <java-symbol type="string" name="policydesc_forceLock" /> + <java-symbol type="string" name="policydesc_limitPassword" /> + <java-symbol type="string" name="policydesc_resetPassword" /> + <java-symbol type="string" name="policydesc_setGlobalProxy" /> + <java-symbol type="string" name="policydesc_watchLogin" /> + <java-symbol type="string" name="policydesc_wipeData" /> + <java-symbol type="string" name="policylab_disableCamera" /> + <java-symbol type="string" name="policylab_encryptedStorage" /> + <java-symbol type="string" name="policylab_expirePassword" /> + <java-symbol type="string" name="policylab_forceLock" /> + <java-symbol type="string" name="policylab_limitPassword" /> + <java-symbol type="string" name="policylab_resetPassword" /> + <java-symbol type="string" name="policylab_setGlobalProxy" /> + <java-symbol type="string" name="policylab_watchLogin" /> + <java-symbol type="string" name="policylab_wipeData" /> + <java-symbol type="string" name="postalTypeCustom" /> + <java-symbol type="string" name="postalTypeHome" /> + <java-symbol type="string" name="postalTypeOther" /> + <java-symbol type="string" name="postalTypeWork" /> + <java-symbol type="string" name="power_off" /> + <java-symbol type="string" name="preposition_for_date" /> + <java-symbol type="string" name="preposition_for_time" /> + <java-symbol type="string" name="progress_erasing" /> + <java-symbol type="string" name="progress_unmounting" /> + <java-symbol type="string" name="radiobutton_not_selected" /> + <java-symbol type="string" name="radiobutton_selected" /> + <java-symbol type="string" name="relationTypeAssistant" /> + <java-symbol type="string" name="relationTypeBrother" /> + <java-symbol type="string" name="relationTypeChild" /> + <java-symbol type="string" name="relationTypeDomesticPartner" /> + <java-symbol type="string" name="relationTypeFather" /> + <java-symbol type="string" name="relationTypeFriend" /> + <java-symbol type="string" name="relationTypeManager" /> + <java-symbol type="string" name="relationTypeMother" /> + <java-symbol type="string" name="relationTypeParent" /> + <java-symbol type="string" name="relationTypePartner" /> + <java-symbol type="string" name="relationTypeReferredBy" /> + <java-symbol type="string" name="relationTypeRelative" /> + <java-symbol type="string" name="relationTypeSister" /> + <java-symbol type="string" name="relationTypeSpouse" /> + <java-symbol type="string" name="relative_time" /> + <java-symbol type="string" name="reset" /> + <java-symbol type="string" name="ringtone_default" /> + <java-symbol type="string" name="ringtone_default_with_actual" /> + <java-symbol type="string" name="ringtone_picker_title" /> + <java-symbol type="string" name="ringtone_silent" /> + <java-symbol type="string" name="ringtone_unknown" /> + <java-symbol type="string" name="roamingText0" /> + <java-symbol type="string" name="roamingText1" /> + <java-symbol type="string" name="roamingText10" /> + <java-symbol type="string" name="roamingText11" /> + <java-symbol type="string" name="roamingText12" /> + <java-symbol type="string" name="roamingText2" /> + <java-symbol type="string" name="roamingText3" /> + <java-symbol type="string" name="roamingText4" /> + <java-symbol type="string" name="roamingText5" /> + <java-symbol type="string" name="roamingText6" /> + <java-symbol type="string" name="roamingText7" /> + <java-symbol type="string" name="roamingText8" /> + <java-symbol type="string" name="roamingText9" /> + <java-symbol type="string" name="roamingTextSearching" /> + <java-symbol type="string" name="same_month_md1_md2" /> + <java-symbol type="string" name="same_month_md1_time1_md2_time2" /> + <java-symbol type="string" name="same_month_mdy1_mdy2" /> + <java-symbol type="string" name="same_month_mdy1_time1_mdy2_time2" /> + <java-symbol type="string" name="same_month_wday1_md1_time1_wday2_md2_time2" /> + <java-symbol type="string" name="same_month_wday1_md1_wday2_md2" /> + <java-symbol type="string" name="same_month_wday1_mdy1_time1_wday2_mdy2_time2" /> + <java-symbol type="string" name="same_month_wday1_mdy1_wday2_mdy2" /> + <java-symbol type="string" name="same_year_md1_md2" /> + <java-symbol type="string" name="same_year_md1_time1_md2_time2" /> + <java-symbol type="string" name="same_year_mdy1_mdy2" /> + <java-symbol type="string" name="same_year_mdy1_time1_mdy2_time2" /> + <java-symbol type="string" name="same_year_wday1_md1_time1_wday2_md2_time2" /> + <java-symbol type="string" name="same_year_wday1_md1_wday2_md2" /> + <java-symbol type="string" name="same_year_wday1_mdy1_time1_wday2_mdy2_time2" /> + <java-symbol type="string" name="same_year_wday1_mdy1_wday2_mdy2" /> + <java-symbol type="string" name="save_password_label" /> + <java-symbol type="string" name="save_password_message" /> + <java-symbol type="string" name="save_password_never" /> + <java-symbol type="string" name="save_password_notnow" /> + <java-symbol type="string" name="save_password_remember" /> + <java-symbol type="string" name="sendText" /> + <java-symbol type="string" name="sending" /> + <java-symbol type="string" name="serviceClassData" /> + <java-symbol type="string" name="serviceClassDataAsync" /> + <java-symbol type="string" name="serviceClassDataSync" /> + <java-symbol type="string" name="serviceClassFAX" /> + <java-symbol type="string" name="serviceClassPAD" /> + <java-symbol type="string" name="serviceClassPacket" /> + <java-symbol type="string" name="serviceClassSMS" /> + <java-symbol type="string" name="serviceClassVoice" /> + <java-symbol type="string" name="serviceDisabled" /> + <java-symbol type="string" name="serviceEnabled" /> + <java-symbol type="string" name="serviceEnabledFor" /> + <java-symbol type="string" name="serviceErased" /> + <java-symbol type="string" name="serviceNotProvisioned" /> + <java-symbol type="string" name="serviceRegistered" /> + <java-symbol type="string" name="setup_autofill" /> + <java-symbol type="string" name="shareactionprovider_share_with" /> + <java-symbol type="string" name="shareactionprovider_share_with_application" /> + <java-symbol type="string" name="short_format_month" /> + <java-symbol type="string" name="shutdown_confirm" /> + <java-symbol type="string" name="shutdown_confirm_question" /> + <java-symbol type="string" name="shutdown_progress" /> + <java-symbol type="string" name="sim_added_message" /> + <java-symbol type="string" name="sim_added_title" /> + <java-symbol type="string" name="sim_removed_message" /> + <java-symbol type="string" name="sim_removed_title" /> + <java-symbol type="string" name="sim_restart_button" /> + <java-symbol type="string" name="sipAddressTypeCustom" /> + <java-symbol type="string" name="sipAddressTypeHome" /> + <java-symbol type="string" name="sipAddressTypeOther" /> + <java-symbol type="string" name="sipAddressTypeWork" /> + <java-symbol type="string" name="sms_control_default_app_name" /> + <java-symbol type="string" name="sms_control_message" /> + <java-symbol type="string" name="sms_control_no" /> + <java-symbol type="string" name="sms_control_title" /> + <java-symbol type="string" name="sms_control_yes" /> + <java-symbol type="string" name="submit" /> + <java-symbol type="string" name="switch_off" /> + <java-symbol type="string" name="switch_on" /> + <java-symbol type="string" name="sync_binding_label" /> + <java-symbol type="string" name="sync_do_nothing" /> + <java-symbol type="string" name="sync_really_delete" /> + <java-symbol type="string" name="sync_too_many_deletes_desc" /> + <java-symbol type="string" name="sync_undo_deletes" /> + <java-symbol type="string" name="terabyteShort" /> + <java-symbol type="string" name="text_copied" /> + <java-symbol type="string" name="time1_time2" /> + <java-symbol type="string" name="time_date" /> + <java-symbol type="string" name="time_of_day" /> + <java-symbol type="string" name="time_picker_decrement_hour_button" /> + <java-symbol type="string" name="time_picker_decrement_minute_button" /> + <java-symbol type="string" name="time_picker_decrement_set_am_button" /> + <java-symbol type="string" name="time_picker_dialog_title" /> + <java-symbol type="string" name="time_picker_increment_hour_button" /> + <java-symbol type="string" name="time_picker_increment_minute_button" /> + <java-symbol type="string" name="time_picker_increment_set_pm_button" /> + <java-symbol type="string" name="time_picker_separator" /> + <java-symbol type="string" name="time_wday" /> + <java-symbol type="string" name="time_wday_date" /> + <java-symbol type="string" name="today" /> + <java-symbol type="string" name="togglebutton_not_pressed" /> + <java-symbol type="string" name="togglebutton_pressed" /> + <java-symbol type="string" name="tomorrow" /> + <java-symbol type="string" name="twelve_hour_time_format" /> + <java-symbol type="string" name="twenty_four_hour_time_format" /> + <java-symbol type="string" name="upload_file" /> + <java-symbol type="string" name="volume_alarm" /> + <java-symbol type="string" name="volume_icon_description_bluetooth" /> + <java-symbol type="string" name="volume_icon_description_incall" /> + <java-symbol type="string" name="volume_icon_description_media" /> + <java-symbol type="string" name="volume_icon_description_notification" /> + <java-symbol type="string" name="volume_icon_description_ringer" /> + <java-symbol type="string" name="wait" /> + <java-symbol type="string" name="wday1_date1_time1_wday2_date2_time2" /> + <java-symbol type="string" name="wday1_date1_wday2_date2" /> + <java-symbol type="string" name="wday_date" /> + <java-symbol type="string" name="web_user_agent" /> + <java-symbol type="string" name="web_user_agent_target_content" /> + <java-symbol type="string" name="webpage_unresponsive" /> + <java-symbol type="string" name="whichApplication" /> + <java-symbol type="string" name="wifi_available_sign_in" /> + <java-symbol type="string" name="wifi_available_sign_in_detailed" /> + <java-symbol type="string" name="wifi_p2p_dialog_title" /> + <java-symbol type="string" name="wifi_p2p_enabled_notification_message" /> + <java-symbol type="string" name="wifi_p2p_enabled_notification_title" /> + <java-symbol type="string" name="wifi_p2p_failed_message" /> + <java-symbol type="string" name="wifi_p2p_from_message" /> + <java-symbol type="string" name="wifi_p2p_invitation_sent_title" /> + <java-symbol type="string" name="wifi_p2p_invitation_to_connect_title" /> + <java-symbol type="string" name="wifi_p2p_show_pin_message" /> + <java-symbol type="string" name="wifi_p2p_to_message" /> + <java-symbol type="string" name="wifi_p2p_turnon_message" /> + <java-symbol type="string" name="wifi_tether_configure_ssid_default" /> + <java-symbol type="string" name="wifi_watchdog_network_disabled" /> + <java-symbol type="string" name="wifi_watchdog_network_disabled_detailed" /> + <java-symbol type="string" name="yesterday" /> + + <java-symbol type="plurals" name="abbrev_in_num_days" /> + <java-symbol type="plurals" name="abbrev_in_num_hours" /> + <java-symbol type="plurals" name="abbrev_in_num_minutes" /> + <java-symbol type="plurals" name="abbrev_in_num_seconds" /> + <java-symbol type="plurals" name="abbrev_num_days_ago" /> + <java-symbol type="plurals" name="abbrev_num_hours_ago" /> + <java-symbol type="plurals" name="abbrev_num_minutes_ago" /> + <java-symbol type="plurals" name="abbrev_num_seconds_ago" /> + <java-symbol type="plurals" name="in_num_days" /> + <java-symbol type="plurals" name="in_num_hours" /> + <java-symbol type="plurals" name="in_num_minutes" /> + <java-symbol type="plurals" name="in_num_seconds" /> + <java-symbol type="plurals" name="last_num_days" /> + <java-symbol type="plurals" name="matches_found" /> + <java-symbol type="plurals" name="num_days_ago" /> + <java-symbol type="plurals" name="num_hours_ago" /> + <java-symbol type="plurals" name="num_minutes_ago" /> + <java-symbol type="plurals" name="num_seconds_ago" /> + + <java-symbol type="array" name="carrier_properties" /> + <java-symbol type="array" name="config_data_usage_network_types" /> + <java-symbol type="array" name="config_sms_enabled_locking_shift_tables" /> + <java-symbol type="array" name="config_sms_enabled_single_shift_tables" /> + <java-symbol type="array" name="config_twoDigitNumberPattern" /> + <java-symbol type="array" name="networkAttributes" /> + <java-symbol type="array" name="preloaded_color_state_lists" /> + <java-symbol type="array" name="preloaded_drawables" /> + <java-symbol type="array" name="special_locale_codes" /> + <java-symbol type="array" name="special_locale_names" /> + + <java-symbol type="drawable" name="default_wallpaper" /> + <java-symbol type="drawable" name="ic_suggestions_add" /> + <java-symbol type="drawable" name="ic_suggestions_delete" /> + <java-symbol type="drawable" name="indicator_input_error" /> + <java-symbol type="drawable" name="overscroll_edge" /> + <java-symbol type="drawable" name="overscroll_glow" /> + <java-symbol type="drawable" name="popup_bottom_dark" /> + <java-symbol type="drawable" name="popup_bottom_bright" /> + <java-symbol type="drawable" name="popup_bottom_medium" /> + <java-symbol type="drawable" name="popup_center_dark" /> + <java-symbol type="drawable" name="popup_center_bright" /> + <java-symbol type="drawable" name="popup_full_dark" /> + <java-symbol type="drawable" name="popup_full_bright" /> + <java-symbol type="drawable" name="popup_top_dark" /> + <java-symbol type="drawable" name="popup_top_bright" /> + <java-symbol type="drawable" name="search_spinner" /> + <java-symbol type="drawable" name="sym_app_on_sd_unavailable_icon" /> + <java-symbol type="drawable" name="text_edit_side_paste_window" /> + <java-symbol type="drawable" name="text_edit_paste_window" /> + <java-symbol type="drawable" name="btn_check_off" /> + <java-symbol type="drawable" name="btn_code_lock_default_holo" /> + <java-symbol type="drawable" name="btn_code_lock_touched_holo" /> + <java-symbol type="drawable" name="clock_dial" /> + <java-symbol type="drawable" name="clock_hand_hour" /> + <java-symbol type="drawable" name="clock_hand_minute" /> + <java-symbol type="drawable" name="emo_im_angel" /> + <java-symbol type="drawable" name="emo_im_cool" /> + <java-symbol type="drawable" name="emo_im_crying" /> + <java-symbol type="drawable" name="emo_im_embarrassed" /> + <java-symbol type="drawable" name="emo_im_foot_in_mouth" /> + <java-symbol type="drawable" name="emo_im_happy" /> + <java-symbol type="drawable" name="emo_im_kissing" /> + <java-symbol type="drawable" name="emo_im_laughing" /> + <java-symbol type="drawable" name="emo_im_lips_are_sealed" /> + <java-symbol type="drawable" name="emo_im_money_mouth" /> + <java-symbol type="drawable" name="emo_im_sad" /> + <java-symbol type="drawable" name="emo_im_surprised" /> + <java-symbol type="drawable" name="emo_im_tongue_sticking_out" /> + <java-symbol type="drawable" name="emo_im_undecided" /> + <java-symbol type="drawable" name="emo_im_winking" /> + <java-symbol type="drawable" name="emo_im_wtf" /> + <java-symbol type="drawable" name="emo_im_yelling" /> + <java-symbol type="drawable" name="expander_close_holo_dark" /> + <java-symbol type="drawable" name="expander_open_holo_dark" /> + <java-symbol type="drawable" name="ic_audio_alarm" /> + <java-symbol type="drawable" name="ic_audio_alarm_mute" /> + <java-symbol type="drawable" name="ic_audio_bt" /> + <java-symbol type="drawable" name="ic_audio_bt_mute" /> + <java-symbol type="drawable" name="ic_audio_notification" /> + <java-symbol type="drawable" name="ic_audio_notification_mute" /> + <java-symbol type="drawable" name="ic_audio_phone" /> + <java-symbol type="drawable" name="ic_audio_ring_notif" /> + <java-symbol type="drawable" name="ic_audio_ring_notif_mute" /> + <java-symbol type="drawable" name="ic_audio_ring_notif_vibrate" /> + <java-symbol type="drawable" name="ic_audio_vol" /> + <java-symbol type="drawable" name="ic_audio_vol_mute" /> + <java-symbol type="drawable" name="ic_bullet_key_permission" /> + <java-symbol type="drawable" name="ic_contact_picture" /> + <java-symbol type="drawable" name="ic_dialog_usb" /> + <java-symbol type="drawable" name="ic_emergency" /> + <java-symbol type="drawable" name="ic_media_stop" /> + <java-symbol type="drawable" name="ic_text_dot" /> + <java-symbol type="drawable" name="indicator_code_lock_drag_direction_green_up" /> + <java-symbol type="drawable" name="indicator_code_lock_drag_direction_red_up" /> + <java-symbol type="drawable" name="indicator_code_lock_point_area_default_holo" /> + <java-symbol type="drawable" name="indicator_code_lock_point_area_green_holo" /> + <java-symbol type="drawable" name="indicator_code_lock_point_area_red_holo" /> + <java-symbol type="drawable" name="jog_dial_arrow_long_left_green" /> + <java-symbol type="drawable" name="jog_dial_arrow_long_right_red" /> + <java-symbol type="drawable" name="jog_dial_arrow_short_left_and_right" /> + <java-symbol type="drawable" name="jog_dial_bg" /> + <java-symbol type="drawable" name="jog_dial_dimple" /> + <java-symbol type="drawable" name="jog_dial_dimple_dim" /> + <java-symbol type="drawable" name="jog_tab_bar_left_generic" /> + <java-symbol type="drawable" name="jog_tab_bar_right_generic" /> + <java-symbol type="drawable" name="jog_tab_left_generic" /> + <java-symbol type="drawable" name="jog_tab_right_generic" /> + <java-symbol type="drawable" name="jog_tab_target_gray" /> + <java-symbol type="drawable" name="picture_emergency" /> + <java-symbol type="drawable" name="platlogo" /> + <java-symbol type="drawable" name="stat_notify_sync_error" /> + <java-symbol type="drawable" name="stat_notify_wifi_in_range" /> + <java-symbol type="drawable" name="stat_sys_gps_on" /> + <java-symbol type="drawable" name="stat_sys_tether_wifi" /> + <java-symbol type="drawable" name="status_bar_background" /> + <java-symbol type="drawable" name="sym_keyboard_shift" /> + <java-symbol type="drawable" name="sym_keyboard_shift_locked" /> + <java-symbol type="drawable" name="tab_bottom_left" /> + <java-symbol type="drawable" name="tab_bottom_left_v4" /> + <java-symbol type="drawable" name="tab_bottom_right" /> + <java-symbol type="drawable" name="tab_bottom_right_v4" /> + <java-symbol type="drawable" name="tab_indicator_v4" /> + <java-symbol type="drawable" name="text_select_handle_left" /> + <java-symbol type="drawable" name="text_select_handle_right" /> + <java-symbol type="drawable" name="unknown_image" /> + <java-symbol type="drawable" name="unlock_default" /> + <java-symbol type="drawable" name="unlock_halo" /> + <java-symbol type="drawable" name="unlock_ring" /> + <java-symbol type="drawable" name="unlock_wave" /> + + <java-symbol type="layout" name="action_bar_home" /> + <java-symbol type="layout" name="action_bar_title_item" /> + <java-symbol type="layout" name="action_menu_item_layout" /> + <java-symbol type="layout" name="action_menu_layout" /> + <java-symbol type="layout" name="action_mode_close_item" /> + <java-symbol type="layout" name="alert_dialog" /> + <java-symbol type="layout" name="choose_account" /> + <java-symbol type="layout" name="choose_account_row" /> + <java-symbol type="layout" name="choose_account_type" /> + <java-symbol type="layout" name="choose_selected_account_row" /> + <java-symbol type="layout" name="choose_type_and_account" /> + <java-symbol type="layout" name="grant_credentials_permission" /> + <java-symbol type="layout" name="number_picker" /> + <java-symbol type="layout" name="permissions_package_list_item" /> + <java-symbol type="layout" name="popup_menu_item_layout" /> + <java-symbol type="layout" name="remote_views_adapter_default_loading_view" /> + <java-symbol type="layout" name="search_bar" /> + <java-symbol type="layout" name="search_dropdown_item_icons_2line" /> + <java-symbol type="layout" name="search_view" /> + <java-symbol type="layout" name="select_dialog" /> + <java-symbol type="layout" name="simple_dropdown_hint" /> + <java-symbol type="layout" name="status_bar_latest_event_content" /> + <java-symbol type="layout" name="status_bar_latest_event_content_large_icon" /> + <java-symbol type="layout" name="status_bar_latest_event_ticker" /> + <java-symbol type="layout" name="status_bar_latest_event_ticker_large_icon" /> + <java-symbol type="layout" name="text_edit_action_popup_text" /> + <java-symbol type="layout" name="text_drag_thumbnail" /> + <java-symbol type="layout" name="typing_filter" /> + <java-symbol type="layout" name="activity_chooser_view" /> + <java-symbol type="layout" name="activity_chooser_view_list_item" /> + <java-symbol type="layout" name="activity_list" /> + <java-symbol type="layout" name="activity_list_item_2" /> + <java-symbol type="layout" name="alert_dialog_progress" /> + <java-symbol type="layout" name="always_use_checkbox" /> + <java-symbol type="layout" name="app_permission_item" /> + <java-symbol type="layout" name="app_perms_summary" /> + <java-symbol type="layout" name="calendar_view" /> + <java-symbol type="layout" name="character_picker" /> + <java-symbol type="layout" name="character_picker_button" /> + <java-symbol type="layout" name="date_picker" /> + <java-symbol type="layout" name="date_picker_dialog" /> + <java-symbol type="layout" name="expanded_menu_layout" /> + <java-symbol type="layout" name="fragment_bread_crumb_item" /> + <java-symbol type="layout" name="fragment_bread_crumbs" /> + <java-symbol type="layout" name="heavy_weight_switcher" /> + <java-symbol type="layout" name="icon_menu_item_layout" /> + <java-symbol type="layout" name="icon_menu_layout" /> + <java-symbol type="layout" name="input_method" /> + <java-symbol type="layout" name="input_method_extract_view" /> + <java-symbol type="layout" name="js_prompt" /> + <java-symbol type="layout" name="list_content_simple" /> + <java-symbol type="layout" name="list_menu_item_checkbox" /> + <java-symbol type="layout" name="list_menu_item_icon" /> + <java-symbol type="layout" name="list_menu_item_layout" /> + <java-symbol type="layout" name="list_menu_item_radio" /> + <java-symbol type="layout" name="locale_picker_item" /> + <java-symbol type="layout" name="media_controller" /> + <java-symbol type="layout" name="preference" /> + <java-symbol type="layout" name="preference_header_item" /> + <java-symbol type="layout" name="preference_list_content" /> + <java-symbol type="layout" name="preference_list_content_single" /> + <java-symbol type="layout" name="preference_list_fragment" /> + <java-symbol type="layout" name="preference_widget_seekbar" /> + <java-symbol type="layout" name="progress_dialog" /> + <java-symbol type="layout" name="resolve_list_item" /> + <java-symbol type="layout" name="seekbar_dialog" /> + <java-symbol type="layout" name="select_dialog_singlechoice_holo" /> + <java-symbol type="layout" name="ssl_certificate" /> + <java-symbol type="layout" name="tab_content" /> + <java-symbol type="layout" name="tab_indicator_holo" /> + <java-symbol type="layout" name="textview_hint" /> + <java-symbol type="layout" name="time_picker" /> + <java-symbol type="layout" name="time_picker_dialog" /> + <java-symbol type="layout" name="transient_notification" /> + <java-symbol type="layout" name="volume_adjust" /> + <java-symbol type="layout" name="volume_adjust_item" /> + <java-symbol type="layout" name="web_text_view_dropdown" /> + <java-symbol type="layout" name="webview_find" /> + <java-symbol type="layout" name="webview_select_singlechoice" /> + <java-symbol type="layout" name="wifi_p2p_dialog" /> + <java-symbol type="layout" name="wifi_p2p_dialog_row" /> + <java-symbol type="layout" name="zoom_container" /> + <java-symbol type="layout" name="zoom_controls" /> + <java-symbol type="layout" name="zoom_magnify" /> + + <java-symbol type="anim" name="slide_in_child_bottom" /> + <java-symbol type="anim" name="slide_in_right" /> + <java-symbol type="anim" name="slide_out_left" /> + + <java-symbol type="menu" name="webview_copy" /> + <java-symbol type="menu" name="webview_find" /> + + <java-symbol type="xml" name="password_kbd_qwerty" /> + <java-symbol type="xml" name="autotext" /> + <java-symbol type="xml" name="eri" /> + <java-symbol type="xml" name="password_kbd_numeric" /> + <java-symbol type="xml" name="password_kbd_qwerty_shifted" /> + <java-symbol type="xml" name="password_kbd_symbols" /> + <java-symbol type="xml" name="password_kbd_symbols_shift" /> + <java-symbol type="xml" name="power_profile" /> + <java-symbol type="xml" name="time_zones_by_country" /> + + <java-symbol type="raw" name="incognito_mode_start_page" /> + <java-symbol type="raw" name="loaderror" /> + <java-symbol type="raw" name="nodomain" /> + + <java-symbol type="style" name="Animation.DropDownUp" /> + <java-symbol type="style" name="Animation.DropDownDown" /> + <java-symbol type="style" name="Animation.PopupWindow" /> + <java-symbol type="style" name="Animation.TypingFilter" /> + <java-symbol type="style" name="Animation.TypingFilterRestore" /> + <java-symbol type="style" name="Theme.DeviceDefault.Dialog.Alert" /> + <java-symbol type="style" name="Theme.DeviceDefault.Light.Dialog.Alert" /> + <java-symbol type="style" name="Theme.Dialog.Alert" /> + <java-symbol type="style" name="Theme.Holo.Dialog.Alert" /> + <java-symbol type="style" name="Theme.Holo.Light.Dialog.Alert" /> + <java-symbol type="style" name="ActiveWallpaperSettings" /> + <java-symbol type="style" name="Animation.InputMethodFancy" /> + <java-symbol type="style" name="Animation.Wallpaper" /> + <java-symbol type="style" name="Animation.ZoomButtons" /> + <java-symbol type="style" name="PreviewWallpaperSettings" /> + <java-symbol type="style" name="TextAppearance.SlidingTabActive" /> + <java-symbol type="style" name="TextAppearance.SlidingTabNormal" /> + <java-symbol type="style" name="Theme.DeviceDefault.Dialog.NoFrame" /> + <java-symbol type="style" name="Theme.IconMenu" /> + <java-symbol type="style" name="Theme.Panel.Volume" /> + + <!-- From android.policy --> + <java-symbol type="anim" name="app_starting_exit" /> + <java-symbol type="anim" name="lock_screen_behind_enter" /> + <java-symbol type="array" name="config_keyboardTapVibePattern" /> + <java-symbol type="array" name="config_longPressVibePattern" /> + <java-symbol type="array" name="config_safeModeDisabledVibePattern" /> + <java-symbol type="array" name="config_safeModeEnabledVibePattern" /> + <java-symbol type="array" name="config_virtualKeyVibePattern" /> + <java-symbol type="array" name="lockscreen_targets_when_silent" /> + <java-symbol type="array" name="lockscreen_targets_when_soundon" /> + <java-symbol type="array" name="lockscreen_targets_with_camera" /> + <java-symbol type="attr" name="actionModePopupWindowStyle" /> + <java-symbol type="attr" name="dialogCustomTitleDecorLayout" /> + <java-symbol type="attr" name="dialogTitleDecorLayout" /> + <java-symbol type="attr" name="dialogTitleIconsDecorLayout" /> + <java-symbol type="bool" name="config_allowAllRotations" /> + <java-symbol type="bool" name="config_bypass_keyguard_if_slider_open" /> + <java-symbol type="bool" name="config_carDockEnablesAccelerometer" /> + <java-symbol type="bool" name="config_deskDockEnablesAccelerometer" /> + <java-symbol type="bool" name="config_disableMenuKeyInLockScreen" /> + <java-symbol type="bool" name="config_enableLockBeforeUnlockScreen" /> + <java-symbol type="bool" name="config_enableLockScreenRotation" /> + <java-symbol type="bool" name="config_reverseDefaultRotation" /> + <java-symbol type="bool" name="config_showNavigationBar" /> + <java-symbol type="bool" name="target_honeycomb_needs_options_menu" /> + <java-symbol type="dimen" name="navigation_bar_height" /> + <java-symbol type="dimen" name="navigation_bar_width" /> + <java-symbol type="dimen" name="status_bar_height" /> + <java-symbol type="dimen" name="system_bar_height" /> + <java-symbol type="drawable" name="ic_jog_dial_sound_off" /> + <java-symbol type="drawable" name="ic_jog_dial_sound_on" /> + <java-symbol type="drawable" name="ic_jog_dial_unlock" /> + <java-symbol type="drawable" name="ic_jog_dial_vibrate_on" /> + <java-symbol type="drawable" name="ic_lock_airplane_mode" /> + <java-symbol type="drawable" name="ic_lock_airplane_mode_off" /> + <java-symbol type="drawable" name="ic_menu_cc" /> + <java-symbol type="drawable" name="jog_tab_bar_left_unlock" /> + <java-symbol type="drawable" name="jog_tab_bar_right_sound_off" /> + <java-symbol type="drawable" name="jog_tab_bar_right_sound_on" /> + <java-symbol type="drawable" name="jog_tab_left_unlock" /> + <java-symbol type="drawable" name="jog_tab_right_sound_off" /> + <java-symbol type="drawable" name="jog_tab_right_sound_on" /> + <java-symbol type="drawable" name="jog_tab_target_green" /> + <java-symbol type="drawable" name="jog_tab_target_yellow" /> + <java-symbol type="drawable" name="menu_background" /> + <java-symbol type="drawable" name="stat_sys_secure" /> + <java-symbol type="id" name="action_mode_bar_stub" /> + <java-symbol type="id" name="alarm_status" /> + <java-symbol type="id" name="backspace" /> + <java-symbol type="id" name="button0" /> + <java-symbol type="id" name="button4" /> + <java-symbol type="id" name="button5" /> + <java-symbol type="id" name="button6" /> + <java-symbol type="id" name="button7" /> + <java-symbol type="id" name="carrier" /> + <java-symbol type="id" name="date" /> + <java-symbol type="id" name="eight" /> + <java-symbol type="id" name="emergencyCallButton" /> + <java-symbol type="id" name="faceLockAreaView" /> + <java-symbol type="id" name="five" /> + <java-symbol type="id" name="forgotPatternButton" /> + <java-symbol type="id" name="four" /> + <java-symbol type="id" name="headerText" /> + <java-symbol type="id" name="icon_menu_presenter" /> + <java-symbol type="id" name="instructions" /> + <java-symbol type="id" name="keyboard" /> + <java-symbol type="id" name="list_menu_presenter" /> + <java-symbol type="id" name="lockPattern" /> + <java-symbol type="id" name="lock_screen" /> + <java-symbol type="id" name="login" /> + <java-symbol type="id" name="nine" /> + <java-symbol type="id" name="no_applications_message" /> + <java-symbol type="id" name="ok" /> + <java-symbol type="id" name="one" /> + <java-symbol type="id" name="option1" /> + <java-symbol type="id" name="option2" /> + <java-symbol type="id" name="option3" /> + <java-symbol type="id" name="password" /> + <java-symbol type="id" name="passwordEntry" /> + <java-symbol type="id" name="pinDel" /> + <java-symbol type="id" name="pinDisplay" /> + <java-symbol type="id" name="propertyOf" /> + <java-symbol type="id" name="pukDel" /> + <java-symbol type="id" name="pukDisplay" /> + <java-symbol type="id" name="right_icon" /> + <java-symbol type="id" name="seven" /> + <java-symbol type="id" name="six" /> + <java-symbol type="id" name="status" /> + <java-symbol type="id" name="status1" /> + <java-symbol type="id" name="switch_ime_button" /> + <java-symbol type="id" name="three" /> + <java-symbol type="id" name="title_container" /> + <java-symbol type="id" name="topHeader" /> + <java-symbol type="id" name="transport" /> + <java-symbol type="id" name="transport_bg_protect" /> + <java-symbol type="id" name="two" /> + <java-symbol type="id" name="unlock_widget" /> + <java-symbol type="id" name="zero" /> + <java-symbol type="integer" name="config_carDockRotation" /> + <java-symbol type="integer" name="config_defaultUiModeType" /> + <java-symbol type="integer" name="config_deskDockRotation" /> + <java-symbol type="integer" name="config_lidKeyboardAccessibility" /> + <java-symbol type="integer" name="config_lidNavigationAccessibility" /> + <java-symbol type="integer" name="config_lidOpenRotation" /> + <java-symbol type="integer" name="config_longPressOnHomeBehavior" /> + <java-symbol type="layout" name="global_actions_item" /> + <java-symbol type="layout" name="global_actions_silent_mode" /> + <java-symbol type="layout" name="keyguard_screen_glogin_unlock" /> + <java-symbol type="layout" name="keyguard_screen_password_landscape" /> + <java-symbol type="layout" name="keyguard_screen_password_portrait" /> + <java-symbol type="layout" name="keyguard_screen_sim_pin_landscape" /> + <java-symbol type="layout" name="keyguard_screen_sim_pin_portrait" /> + <java-symbol type="layout" name="keyguard_screen_sim_puk_landscape" /> + <java-symbol type="layout" name="keyguard_screen_sim_puk_portrait" /> + <java-symbol type="layout" name="keyguard_screen_tab_unlock" /> + <java-symbol type="layout" name="keyguard_screen_tab_unlock_land" /> + <java-symbol type="layout" name="keyguard_screen_unlock_landscape" /> + <java-symbol type="layout" name="keyguard_screen_unlock_portrait" /> + <java-symbol type="layout" name="recent_apps_dialog" /> + <java-symbol type="layout" name="screen_action_bar" /> + <java-symbol type="layout" name="screen_action_bar_overlay" /> + <java-symbol type="layout" name="screen_custom_title" /> + <java-symbol type="layout" name="screen_progress" /> + <java-symbol type="layout" name="screen_simple" /> + <java-symbol type="layout" name="screen_simple_overlay_action_mode" /> + <java-symbol type="layout" name="screen_title" /> + <java-symbol type="layout" name="screen_title_icons" /> + <java-symbol type="string" name="abbrev_wday_month_day_no_year" /> + <java-symbol type="string" name="android_upgrading_title" /> + <java-symbol type="string" name="config_defaultDreamComponent" /> + <java-symbol type="string" name="faceunlock_multiple_failures" /> + <java-symbol type="string" name="global_action_power_off" /> + <java-symbol type="string" name="global_actions_airplane_mode_off_status" /> + <java-symbol type="string" name="global_actions_airplane_mode_on_status" /> + <java-symbol type="string" name="global_actions_toggle_airplane_mode" /> + <java-symbol type="string" name="invalidPuk" /> + <java-symbol type="string" name="keyguard_password_enter_pin_code" /> + <java-symbol type="string" name="keyguard_password_enter_puk_code" /> + <java-symbol type="string" name="keyguard_password_wrong_pin_code" /> + <java-symbol type="string" name="lockscreen_carrier_default" /> + <java-symbol type="string" name="lockscreen_charged" /> + <java-symbol type="string" name="lockscreen_failed_attempts_almost_at_wipe" /> + <java-symbol type="string" name="lockscreen_failed_attempts_almost_glogin" /> + <java-symbol type="string" name="lockscreen_failed_attempts_now_wiping" /> + <java-symbol type="string" name="lockscreen_forgot_pattern_button_text" /> + <java-symbol type="string" name="lockscreen_glogin_checking_password" /> + <java-symbol type="string" name="lockscreen_glogin_forgot_pattern" /> + <java-symbol type="string" name="lockscreen_glogin_invalid_input" /> + <java-symbol type="string" name="lockscreen_glogin_too_many_attempts" /> + <java-symbol type="string" name="lockscreen_instructions_when_pattern_disabled" /> + <java-symbol type="string" name="lockscreen_low_battery" /> + <java-symbol type="string" name="lockscreen_missing_sim_instructions" /> + <java-symbol type="string" name="lockscreen_missing_sim_instructions_long" /> + <java-symbol type="string" name="lockscreen_missing_sim_message_short" /> + <java-symbol type="string" name="lockscreen_network_locked_message" /> + <java-symbol type="string" name="lockscreen_password_wrong" /> + <java-symbol type="string" name="lockscreen_pattern_instructions" /> + <java-symbol type="string" name="lockscreen_pattern_wrong" /> + <java-symbol type="string" name="lockscreen_permanent_disabled_sim_instructions" /> + <java-symbol type="string" name="lockscreen_plugged_in" /> + <java-symbol type="string" name="lockscreen_sim_locked_message" /> + <java-symbol type="string" name="lockscreen_sim_puk_locked_message" /> + <java-symbol type="string" name="lockscreen_sim_unlock_progress_dialog_message" /> + <java-symbol type="string" name="lockscreen_sound_off_label" /> + <java-symbol type="string" name="lockscreen_sound_on_label" /> + <java-symbol type="string" name="lockscreen_too_many_failed_attempts_countdown" /> + <java-symbol type="string" name="lockscreen_too_many_failed_attempts_dialog_message" /> + <java-symbol type="string" name="lockscreen_too_many_failed_password_attempts_dialog_message" /> + <java-symbol type="string" name="lockscreen_too_many_failed_pin_attempts_dialog_message" /> + <java-symbol type="string" name="lockscreen_unlock_label" /> + <java-symbol type="string" name="status_bar_device_locked" /> + <java-symbol type="style" name="Animation.LockScreen" /> + <java-symbol type="style" name="Theme.Dialog.RecentApplications" /> + <java-symbol type="style" name="Theme.ExpandedMenu" /> + + <!-- From services --> + <java-symbol type="anim" name="screen_rotate_0_enter" /> + <java-symbol type="anim" name="screen_rotate_0_exit" /> + <java-symbol type="anim" name="screen_rotate_180_enter" /> + <java-symbol type="anim" name="screen_rotate_180_exit" /> + <java-symbol type="anim" name="screen_rotate_finish_enter" /> + <java-symbol type="anim" name="screen_rotate_finish_exit" /> + <java-symbol type="anim" name="screen_rotate_minus_90_enter" /> + <java-symbol type="anim" name="screen_rotate_minus_90_exit" /> + <java-symbol type="anim" name="screen_rotate_plus_90_enter" /> + <java-symbol type="anim" name="screen_rotate_plus_90_exit" /> + <java-symbol type="anim" name="screen_rotate_start_enter" /> + <java-symbol type="anim" name="screen_rotate_start_exit" /> + <java-symbol type="anim" name="window_move_from_decor" /> + <java-symbol type="array" name="config_autoBrightnessButtonBacklightValues" /> + <java-symbol type="array" name="config_autoBrightnessKeyboardBacklightValues" /> + <java-symbol type="array" name="config_autoBrightnessLcdBacklightValues" /> + <java-symbol type="array" name="config_autoBrightnessLevels" /> + <java-symbol type="array" name="config_protectedNetworks" /> + <java-symbol type="array" name="config_statusBarIcons" /> + <java-symbol type="array" name="config_tether_bluetooth_regexs" /> + <java-symbol type="array" name="config_tether_dhcp_range" /> + <java-symbol type="array" name="config_tether_upstream_types" /> + <java-symbol type="array" name="config_tether_usb_regexs" /> + <java-symbol type="array" name="config_tether_wifi_regexs" /> + <java-symbol type="array" name="config_usbHostBlacklist" /> + <java-symbol type="array" name="radioAttributes" /> + <java-symbol type="bool" name="config_animateScreenLights" /> + <java-symbol type="bool" name="config_automatic_brightness_available" /> + <java-symbol type="bool" name="config_sf_limitedAlpha" /> + <java-symbol type="bool" name="config_unplugTurnsOnScreen" /> + <java-symbol type="bool" name="config_wifi_background_scan_support" /> + <java-symbol type="bool" name="config_wifi_dual_band_support" /> + <java-symbol type="bool" name="config_wimaxEnabled" /> + <java-symbol type="bool" name="show_ongoing_ime_switcher" /> + <java-symbol type="color" name="config_defaultNotificationColor" /> + <java-symbol type="drawable" name="ic_notification_ime_default" /> + <java-symbol type="drawable" name="stat_notify_car_mode" /> + <java-symbol type="drawable" name="stat_notify_disabled" /> + <java-symbol type="drawable" name="stat_notify_disk_full" /> + <java-symbol type="drawable" name="stat_sys_adb" /> + <java-symbol type="drawable" name="stat_sys_battery" /> + <java-symbol type="drawable" name="stat_sys_battery_charge" /> + <java-symbol type="drawable" name="stat_sys_battery_unknown" /> + <java-symbol type="drawable" name="stat_sys_data_usb" /> + <java-symbol type="drawable" name="stat_sys_tether_bluetooth" /> + <java-symbol type="drawable" name="stat_sys_tether_general" /> + <java-symbol type="drawable" name="stat_sys_tether_usb" /> + <java-symbol type="drawable" name="stat_sys_throttled" /> + <java-symbol type="drawable" name="vpn_connected" /> + <java-symbol type="id" name="ask_checkbox" /> + <java-symbol type="id" name="compat_checkbox" /> + <java-symbol type="id" name="original_app_icon" /> + <java-symbol type="id" name="original_message" /> + <java-symbol type="id" name="radio" /> + <java-symbol type="id" name="reask_hint" /> + <java-symbol type="id" name="replace_app_icon" /> + <java-symbol type="id" name="replace_message" /> + <java-symbol type="fraction" name="config_dimBehindFadeDuration" /> + <java-symbol type="integer" name="config_carDockKeepsScreenOn" /> + <java-symbol type="integer" name="config_criticalBatteryWarningLevel" /> + <java-symbol type="integer" name="config_datause_notification_type" /> + <java-symbol type="integer" name="config_datause_polling_period_sec" /> + <java-symbol type="integer" name="config_datause_threshold_bytes" /> + <java-symbol type="integer" name="config_datause_throttle_kbitsps" /> + <java-symbol type="integer" name="config_defaultNotificationLedOff" /> + <java-symbol type="integer" name="config_defaultNotificationLedOn" /> + <java-symbol type="integer" name="config_deskDockKeepsScreenOn" /> + <java-symbol type="integer" name="config_lightSensorWarmupTime" /> + <java-symbol type="integer" name="config_lowBatteryCloseWarningLevel" /> + <java-symbol type="integer" name="config_lowBatteryWarningLevel" /> + <java-symbol type="integer" name="config_networkPolicyDefaultWarning" /> + <java-symbol type="integer" name="config_networkTransitionTimeout" /> + <java-symbol type="integer" name="config_notificationsBatteryFullARGB" /> + <java-symbol type="integer" name="config_notificationsBatteryLedOff" /> + <java-symbol type="integer" name="config_notificationsBatteryLedOn" /> + <java-symbol type="integer" name="config_notificationsBatteryLowARGB" /> + <java-symbol type="integer" name="config_notificationsBatteryMediumARGB" /> + <java-symbol type="integer" name="config_radioScanningTimeout" /> + <java-symbol type="integer" name="config_screenBrightnessDim" /> + <java-symbol type="integer" name="config_virtualKeyQuietTimeMillis" /> + <java-symbol type="layout" name="am_compat_mode_dialog" /> + <java-symbol type="layout" name="launch_warning" /> + <java-symbol type="layout" name="safe_mode" /> + <java-symbol type="layout" name="simple_list_item_2_single_choice" /> + <java-symbol type="plurals" name="wifi_available" /> + <java-symbol type="plurals" name="wifi_available_detailed" /> + <java-symbol type="string" name="accessibility_binding_label" /> + <java-symbol type="string" name="adb_active_notification_message" /> + <java-symbol type="string" name="adb_active_notification_title" /> + <java-symbol type="string" name="aerr_application" /> + <java-symbol type="string" name="aerr_process" /> + <java-symbol type="string" name="aerr_title" /> + <java-symbol type="string" name="android_upgrading_apk" /> + <java-symbol type="string" name="android_upgrading_complete" /> + <java-symbol type="string" name="android_upgrading_starting_apps" /> + <java-symbol type="string" name="anr_activity_application" /> + <java-symbol type="string" name="anr_activity_process" /> + <java-symbol type="string" name="anr_application_process" /> + <java-symbol type="string" name="anr_process" /> + <java-symbol type="string" name="anr_title" /> + <java-symbol type="string" name="car_mode_disable_notification_message" /> + <java-symbol type="string" name="car_mode_disable_notification_title" /> + <java-symbol type="string" name="chooser_wallpaper" /> + <java-symbol type="string" name="config_datause_iface" /> + <java-symbol type="string" name="config_geocodeProvider" /> + <java-symbol type="string" name="config_networkLocationProvider" /> + <java-symbol type="string" name="config_wimaxManagerClassname" /> + <java-symbol type="string" name="config_wimaxNativeLibLocation" /> + <java-symbol type="string" name="config_wimaxServiceClassname" /> + <java-symbol type="string" name="config_wimaxServiceJarLocation" /> + <java-symbol type="string" name="config_wimaxStateTrackerClassname" /> + <java-symbol type="string" name="configure_input_methods" /> + <java-symbol type="string" name="data_usage_3g_limit_snoozed_title" /> + <java-symbol type="string" name="data_usage_3g_limit_title" /> + <java-symbol type="string" name="data_usage_4g_limit_snoozed_title" /> + <java-symbol type="string" name="data_usage_4g_limit_title" /> + <java-symbol type="string" name="data_usage_limit_body" /> + <java-symbol type="string" name="data_usage_limit_snoozed_body" /> + <java-symbol type="string" name="data_usage_mobile_limit_snoozed_title" /> + <java-symbol type="string" name="data_usage_mobile_limit_title" /> + <java-symbol type="string" name="data_usage_restricted_body" /> + <java-symbol type="string" name="data_usage_restricted_title" /> + <java-symbol type="string" name="data_usage_warning_body" /> + <java-symbol type="string" name="data_usage_warning_title" /> + <java-symbol type="string" name="data_usage_wifi_limit_snoozed_title" /> + <java-symbol type="string" name="data_usage_wifi_limit_title" /> + <java-symbol type="string" name="default_wallpaper_component" /> + <java-symbol type="string" name="dlg_ok" /> + <java-symbol type="string" name="factorytest_failed" /> + <java-symbol type="string" name="factorytest_no_action" /> + <java-symbol type="string" name="factorytest_not_system" /> + <java-symbol type="string" name="factorytest_reboot" /> + <java-symbol type="string" name="heavy_weight_notification" /> + <java-symbol type="string" name="heavy_weight_notification_detail" /> + <java-symbol type="string" name="input_method_binding_label" /> + <java-symbol type="string" name="launch_warning_original" /> + <java-symbol type="string" name="launch_warning_replace" /> + <java-symbol type="string" name="launch_warning_title" /> + <java-symbol type="string" name="low_internal_storage_view_text" /> + <java-symbol type="string" name="low_internal_storage_view_title" /> + <java-symbol type="string" name="report" /> + <java-symbol type="string" name="select_input_method" /> + <java-symbol type="string" name="smv_application" /> + <java-symbol type="string" name="smv_process" /> + <java-symbol type="string" name="tethered_notification_message" /> + <java-symbol type="string" name="tethered_notification_title" /> + <java-symbol type="string" name="throttle_warning_notification_message" /> + <java-symbol type="string" name="throttle_warning_notification_title" /> + <java-symbol type="string" name="throttled_notification_message" /> + <java-symbol type="string" name="throttled_notification_title" /> + <java-symbol type="string" name="usb_accessory_notification_title" /> + <java-symbol type="string" name="usb_cd_installer_notification_title" /> + <java-symbol type="string" name="usb_mtp_notification_title" /> + <java-symbol type="string" name="usb_notification_message" /> + <java-symbol type="string" name="usb_ptp_notification_title" /> + <java-symbol type="string" name="vpn_text" /> + <java-symbol type="string" name="vpn_text_long" /> + <java-symbol type="string" name="vpn_title" /> + <java-symbol type="string" name="vpn_title_long" /> + <java-symbol type="string" name="wallpaper_binding_label" /> + <java-symbol type="style" name="Theme.Dialog.AppError" /> + <java-symbol type="style" name="Theme.Toast" /> + <java-symbol type="xml" name="storage_list" /> + + <!-- From SystemUI --> + <java-symbol type="anim" name="push_down_in" /> + <java-symbol type="anim" name="push_down_out" /> + <java-symbol type="anim" name="push_up_in" /> + <java-symbol type="anim" name="push_up_out" /> + <java-symbol type="dimen" name="status_bar_icon_size" /> + <java-symbol type="dimen" name="system_bar_icon_size" /> + <java-symbol type="drawable" name="list_selector_pressed_holo_dark" /> + <java-symbol type="drawable" name="scrubber_control_disabled_holo" /> + <java-symbol type="drawable" name="scrubber_control_selector_holo" /> + <java-symbol type="drawable" name="scrubber_progress_horizontal_holo_dark" /> + <java-symbol type="drawable" name="usb_android" /> + <java-symbol type="drawable" name="usb_android_connected" /> + <java-symbol type="id" name="banner" /> + <java-symbol type="id" name="mount_button" /> + <java-symbol type="id" name="unmount_button" /> + <java-symbol type="layout" name="usb_storage_activity" /> + <java-symbol type="string" name="chooseUsbActivity" /> + <java-symbol type="string" name="dlg_confirm_kill_storage_users_text" /> + <java-symbol type="string" name="dlg_confirm_kill_storage_users_title" /> + <java-symbol type="string" name="dlg_error_title" /> + <java-symbol type="string" name="ext_media_badremoval_notification_message" /> + <java-symbol type="string" name="ext_media_badremoval_notification_title" /> + <java-symbol type="string" name="ext_media_checking_notification_message" /> + <java-symbol type="string" name="ext_media_checking_notification_title" /> + <java-symbol type="string" name="ext_media_nofs_notification_message" /> + <java-symbol type="string" name="ext_media_nofs_notification_title" /> + <java-symbol type="string" name="ext_media_nomedia_notification_message" /> + <java-symbol type="string" name="ext_media_nomedia_notification_title" /> + <java-symbol type="string" name="ext_media_safe_unmount_notification_message" /> + <java-symbol type="string" name="ext_media_safe_unmount_notification_title" /> + <java-symbol type="string" name="ext_media_unmountable_notification_message" /> + <java-symbol type="string" name="ext_media_unmountable_notification_title" /> + <java-symbol type="string" name="usb_storage_error_message" /> + <java-symbol type="string" name="usb_storage_message" /> + <java-symbol type="string" name="usb_storage_notification_message" /> + <java-symbol type="string" name="usb_storage_notification_title" /> + <java-symbol type="string" name="usb_storage_stop_message" /> + <java-symbol type="string" name="usb_storage_stop_notification_message" /> + <java-symbol type="string" name="usb_storage_stop_notification_title" /> + <java-symbol type="string" name="usb_storage_stop_title" /> + <java-symbol type="string" name="usb_storage_title" /> + + <!-- ImfTest --> + <java-symbol type="layout" name="auto_complete_list" /> + + <!-- From SettingsProvider --> + <java-symbol type="raw" name="fallbackring" /> + + <!-- From Settings --> + <java-symbol type="array" name="config_mobile_hotspot_provision_app" /> + <java-symbol type="bool" name="config_intrusiveNotificationLed" /> + <java-symbol type="dimen" name="preference_fragment_padding_bottom" /> + <java-symbol type="dimen" name="preference_fragment_padding_side" /> + <java-symbol type="drawable" name="expander_ic_maximized" /> + <java-symbol type="drawable" name="expander_ic_minimized" /> + <java-symbol type="drawable" name="ic_menu_archive" /> + <java-symbol type="drawable" name="ic_menu_goto" /> + <java-symbol type="drawable" name="title_bar_medium" /> + <java-symbol type="id" name="body" /> + <java-symbol type="string" name="fast_scroll_alphabet" /> + <java-symbol type="string" name="ssl_certificate" /> + + <!-- From Phone --> + <java-symbol type="bool" name="config_built_in_sip_phone" /> + + <!-- From TelephonyProvider --> + <java-symbol type="xml" name="apns" /> + + <!-- From ContactsProvider --> + <java-symbol type="array" name="common_nicknames" /> + <java-symbol type="drawable" name="call_contact" /> + <java-symbol type="drawable" name="create_contact" /> + <java-symbol type="string" name="common_name_prefixes" /> + <java-symbol type="string" name="common_last_name_prefixes" /> + <java-symbol type="string" name="common_name_suffixes" /> + <java-symbol type="string" name="common_name_conjunctions" /> + <java-symbol type="string" name="dial_number_using" /> + <java-symbol type="string" name="create_contact_using" /> + + <!-- From DownloadProvider --> + <java-symbol type="integer" name="config_MaxConcurrentDownloadsAllowed" /> + <java-symbol type="integer" name="config_downloadDataDirSize" /> + <java-symbol type="integer" name="config_downloadDataDirLowSpaceThreshold" /> + + <!-- From Contacts --> + <java-symbol type="drawable" name="quickcontact_badge_overlay_dark" /> + + <!-- From Browser --> + <java-symbol type="drawable" name="ic_menu_moreoverflow_normal_holo_dark" /> + <java-symbol type="id" name="placeholder" /> + <java-symbol type="string" name="ssl_certificate_is_valid" /> + + <!-- From Mms --> + <java-symbol type="drawable" name="ic_menu_play_clip" /> + + <!-- From Stk --> + <java-symbol type="bool" name="config_sf_slowBlur" /> + <java-symbol type="drawable" name="ic_volume" /> + <java-symbol type="drawable" name="stat_notify_sim_toolkit" /> + + <!-- From PinyinIME(!!!) --> + <java-symbol type="string" name="inputMethod" /> + <!-- AndroidManifest.xml attributes. --> <eat-comment /> diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java index fa48093..2fb4237 100644 --- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java +++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java @@ -430,4 +430,35 @@ public class InterrogationActivityTest } } } + + @LargeTest + public void testGetRootAccessibilityNodeInfoInActiveWindow() throws Exception { + final long startTimeMillis = SystemClock.uptimeMillis(); + try { + // get the root via the designated API + AccessibilityNodeInfo fetched = mUiTestAutomationBridge + .getRootAccessibilityNodeInfoInActiveWindow(); + assertNotNull(fetched); + + // get the root via traversal + AccessibilityNodeInfo expected = mUiTestAutomationBridge + .findAccessibilityNodeInfoByViewIdInActiveWindow(R.id.root); + while (true) { + AccessibilityNodeInfo parent = expected.getParent(); + if (parent == null) { + break; + } + expected = parent; + } + assertNotNull(expected); + + assertEquals("The node with id \"root\" should be the root.", expected, fetched); + } finally { + if (DEBUG) { + final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; + Log.i(LOG_TAG, "testGetRootAccessibilityNodeInfoInActiveWindow: " + + elapsedTimeMillis + "ms"); + } + } + } } diff --git a/docs/html/guide/topics/ui/menus.jd b/docs/html/guide/topics/ui/menus.jd index a2313b3..d51a378 100644 --- a/docs/html/guide/topics/ui/menus.jd +++ b/docs/html/guide/topics/ui/menus.jd @@ -17,7 +17,7 @@ parent.link=index.html <li><a href="#context-menu">Creating Contextual Menus</a> <ol> <li><a href="#FloatingContextMenu">Creating a floating context menu</a></li> - <li><a href="#CAB">Using the contextual action bar</a></li> + <li><a href="#CAB">Using the contextual action mode</a></li> </ol> </li> <li><a href="#PopupMenu">Creating a Popup Menu</a> diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 8d17561..bff2a76 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -518,15 +518,16 @@ public class BitmapFactory { byte[] np = bm.getNinePatchChunk(); final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np); if (opts.inScaled || isNinePatch) { - float scale = targetDensity / (float)density; - // TODO: This is very inefficient and should be done in native by Skia - final Bitmap oldBitmap = bm; - bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f), - (int) (bm.getHeight() * scale + 0.5f), true); - oldBitmap.recycle(); + float scale = targetDensity / (float) density; + if (scale != 1.0f) { + final Bitmap oldBitmap = bm; + bm = Bitmap.createScaledBitmap(oldBitmap, (int) (bm.getWidth() * scale + 0.5f), + (int) (bm.getHeight() * scale + 0.5f), true); + if (bm != oldBitmap) oldBitmap.recycle(); + } if (isNinePatch) { - np = nativeScaleNinePatch(np, scale, outPadding); + if (scale != 1.0f) np = nativeScaleNinePatch(np, scale, outPadding); bm.setNinePatchChunk(np); } bm.setDensity(targetDensity); diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index 07bf7bf..9622bd2 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -623,7 +623,7 @@ nAllocationData2D_alloc(JNIEnv *_env, jobject _this, RsContext con, jint srcAlloc, jint srcXoff, jint srcYoff, jint srcMip, jint srcFace) { - LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff, dstYoff," + LOG_API("nAllocation2DData_s, con(%p), dstAlloc(%p), dstXoff(%i), dstYoff(%i)," " dstMip(%i), dstFace(%i), width(%i), height(%i)," " srcAlloc(%p), srcXoff(%i), srcYoff(%i), srcMip(%i), srcFace(%i)", con, (RsAllocation)dstAlloc, dstXoff, dstYoff, dstMip, dstFace, diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index 7b0b443..02dfc1b 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -108,7 +108,8 @@ public: * Returned value * *descriptor updated with effect descriptor */ - static status_t getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor); + static status_t getEffectDescriptor(const effect_uuid_t *uuid, + effect_descriptor_t *descriptor) /*const*/; /* diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h index c8c5dba..ca57f9e 100644 --- a/include/media/AudioRecord.h +++ b/include/media/AudioRecord.h @@ -344,7 +344,6 @@ private: virtual status_t readyToRun() { return NO_ERROR; } virtual void onFirstRef() {} AudioRecord& mReceiver; - Mutex mLock; }; bool processAudioBuffer(const sp<ClientRecordThread>& thread); diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h index 74a1e62..da99620 100644 --- a/include/media/AudioSystem.h +++ b/include/media/AudioSystem.h @@ -55,8 +55,10 @@ public: static status_t getMasterMute(bool* mute); // set/get stream volume on specified output - static status_t setStreamVolume(audio_stream_type_t stream, float value, int output); - static status_t getStreamVolume(audio_stream_type_t stream, float* volume, int output); + static status_t setStreamVolume(audio_stream_type_t stream, float value, + audio_io_handle_t output); + static status_t getStreamVolume(audio_stream_type_t stream, float* volume, + audio_io_handle_t output); // mute/unmute stream static status_t setStreamMute(audio_stream_type_t stream, bool mute); @@ -217,7 +219,7 @@ private: // indicate a change in the configuration of an output or input: keeps the cached // values for output/input parameters upto date in client process - virtual void ioConfigChanged(int event, int ioHandle, void *param2); + virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, void *param2); }; class AudioPolicyServiceClient: public IBinder::DeathRecipient diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h index 02c85cd..11db81b 100644 --- a/include/media/AudioTrack.h +++ b/include/media/AudioTrack.h @@ -273,18 +273,18 @@ public: * left and right volumes. Levels must be >= 0.0 and <= 1.0. */ status_t setVolume(float left, float right); - void getVolume(float* left, float* right); + void getVolume(float* left, float* right) const; /* Set the send level for this track. An auxiliary effect should be attached * to the track with attachEffect(). Level must be >= 0.0 and <= 1.0. */ status_t setAuxEffectSendLevel(float level); - void getAuxEffectSendLevel(float* level); + void getAuxEffectSendLevel(float* level) const; /* Set sample rate for this track, mostly used for games' sound effects */ status_t setSampleRate(int sampleRate); - uint32_t getSampleRate(); + uint32_t getSampleRate() const; /* Enables looping and sets the start and end points of looping. * @@ -299,7 +299,7 @@ public: * (loopEnd-loopStart) <= framecount() */ status_t setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount); - status_t getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount); + status_t getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) const; /* Sets marker position. When playback reaches the number of frames specified, a callback with * event type EVENT_MARKER is called. Calling setMarkerPosition with marker == 0 cancels marker @@ -315,7 +315,7 @@ public: * - INVALID_OPERATION: the AudioTrack has no callback installed. */ status_t setMarkerPosition(uint32_t marker); - status_t getMarkerPosition(uint32_t *marker); + status_t getMarkerPosition(uint32_t *marker) const; /* Sets position update period. Every time the number of frames specified has been played, @@ -333,7 +333,7 @@ public: * - INVALID_OPERATION: the AudioTrack has no callback installed. */ status_t setPositionUpdatePeriod(uint32_t updatePeriod); - status_t getPositionUpdatePeriod(uint32_t *updatePeriod); + status_t getPositionUpdatePeriod(uint32_t *updatePeriod) const; /* Sets playback head position within AudioTrack buffer. The new position is specified * in number of frames. @@ -384,7 +384,7 @@ public: * Returned value: * AudioTrack session ID. */ - int getSessionId(); + int getSessionId() const; /* Attach track auxiliary output to specified effect. Use effectId = 0 * to detach track from effect. @@ -446,7 +446,6 @@ private: virtual status_t readyToRun(); virtual void onFirstRef(); AudioTrack& mReceiver; - Mutex mLock; }; bool processAudioBuffer(const sp<AudioTrackThread>& thread); diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h index 8ae13cc..df83995 100644 --- a/include/media/EffectsFactoryApi.h +++ b/include/media/EffectsFactoryApi.h @@ -109,7 +109,7 @@ int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor); // *pHandle: updated with the effect handle. // //////////////////////////////////////////////////////////////////////////////// -int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle); +int EffectCreate(const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle); //////////////////////////////////////////////////////////////////////////////// // @@ -151,7 +151,7 @@ int EffectRelease(effect_handle_t handle); // *pDescriptor: updated with the effect descriptor. // //////////////////////////////////////////////////////////////////////////////// -int EffectGetDescriptor(effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor); +int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptor); //////////////////////////////////////////////////////////////////////////////// // @@ -167,7 +167,7 @@ int EffectGetDescriptor(effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescri // 1 if uuid is equal to EFFECT_UUID_NULL. // //////////////////////////////////////////////////////////////////////////////// -int EffectIsNullUuid(effect_uuid_t *pEffectUuid); +int EffectIsNullUuid(const effect_uuid_t *pEffectUuid); #if __cplusplus } // extern "C" diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 760595c..433ce7c 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -27,6 +27,7 @@ #include <media/IAudioTrack.h> #include <media/IAudioRecord.h> #include <media/IAudioFlingerClient.h> +#include <system/audio.h> #include <hardware/audio_effect.h> #include <media/IEffect.h> #include <media/IEffectClient.h> @@ -53,13 +54,13 @@ public: int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, - int output, + audio_io_handle_t output, int *sessionId, status_t *status) = 0; virtual sp<IAudioRecord> openRecord( pid_t pid, - int input, + audio_io_handle_t input, uint32_t sampleRate, audio_format_t format, uint32_t channelMask, @@ -71,11 +72,11 @@ public: /* query the audio hardware state. This state never changes, * and therefore can be cached. */ - virtual uint32_t sampleRate(int output) const = 0; - virtual int channelCount(int output) const = 0; - virtual audio_format_t format(int output) const = 0; - virtual size_t frameCount(int output) const = 0; - virtual uint32_t latency(int output) const = 0; + virtual uint32_t sampleRate(audio_io_handle_t output) const = 0; + virtual int channelCount(audio_io_handle_t output) const = 0; + virtual audio_format_t format(audio_io_handle_t output) const = 0; + virtual size_t frameCount(audio_io_handle_t output) const = 0; + virtual uint32_t latency(audio_io_handle_t output) const = 0; /* set/get the audio hardware state. This will probably be used by * the preference panel, mostly. @@ -89,10 +90,12 @@ public: /* set/get stream type state. This will probably be used by * the preference panel, mostly. */ - virtual status_t setStreamVolume(audio_stream_type_t stream, float value, int output) = 0; + virtual status_t setStreamVolume(audio_stream_type_t stream, float value, + audio_io_handle_t output) = 0; virtual status_t setStreamMute(audio_stream_type_t stream, bool muted) = 0; - virtual float streamVolume(audio_stream_type_t stream, int output) const = 0; + virtual float streamVolume(audio_stream_type_t stream, + audio_io_handle_t output) const = 0; virtual bool streamMute(audio_stream_type_t stream) const = 0; // set audio mode @@ -102,63 +105,68 @@ public: virtual status_t setMicMute(bool state) = 0; virtual bool getMicMute() const = 0; - virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) = 0; - virtual String8 getParameters(int ioHandle, const String8& keys) = 0; + virtual status_t setParameters(audio_io_handle_t ioHandle, + const String8& keyValuePairs) = 0; + virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const = 0; // register a current process for audio output change notifications virtual void registerClient(const sp<IAudioFlingerClient>& client) = 0; // retrieve the audio recording buffer size - virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) = 0; + virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const = 0; - virtual int openOutput(uint32_t *pDevices, + virtual audio_io_handle_t openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, uint32_t *pLatencyMs, uint32_t flags) = 0; - virtual int openDuplicateOutput(int output1, int output2) = 0; - virtual status_t closeOutput(int output) = 0; - virtual status_t suspendOutput(int output) = 0; - virtual status_t restoreOutput(int output) = 0; + virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, + audio_io_handle_t output2) = 0; + virtual status_t closeOutput(audio_io_handle_t output) = 0; + virtual status_t suspendOutput(audio_io_handle_t output) = 0; + virtual status_t restoreOutput(audio_io_handle_t output) = 0; - virtual int openInput(uint32_t *pDevices, + virtual audio_io_handle_t openInput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, audio_in_acoustics_t acoustics) = 0; - virtual status_t closeInput(int input) = 0; + virtual status_t closeInput(audio_io_handle_t input) = 0; - virtual status_t setStreamOutput(audio_stream_type_t stream, int output) = 0; + virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) = 0; virtual status_t setVoiceVolume(float volume) = 0; - virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) = 0; + virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, + audio_io_handle_t output) const = 0; - virtual unsigned int getInputFramesLost(int ioHandle) = 0; + virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const = 0; virtual int newAudioSessionId() = 0; virtual void acquireAudioSessionId(int audioSession) = 0; virtual void releaseAudioSessionId(int audioSession) = 0; - virtual status_t queryNumberEffects(uint32_t *numEffects) = 0; + virtual status_t queryNumberEffects(uint32_t *numEffects) const = 0; - virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) = 0; + virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const = 0; - virtual status_t getEffectDescriptor(effect_uuid_t *pEffectUUID, effect_descriptor_t *pDescriptor) = 0; + virtual status_t getEffectDescriptor(const effect_uuid_t *pEffectUUID, + effect_descriptor_t *pDescriptor) const = 0; virtual sp<IEffect> createEffect(pid_t pid, effect_descriptor_t *pDesc, const sp<IEffectClient>& client, int32_t priority, - int output, + audio_io_handle_t output, int sessionId, status_t *status, int *id, int *enabled) = 0; - virtual status_t moveEffects(int session, int srcOutput, int dstOutput) = 0; + virtual status_t moveEffects(int session, audio_io_handle_t srcOutput, + audio_io_handle_t dstOutput) = 0; }; diff --git a/include/media/IAudioFlingerClient.h b/include/media/IAudioFlingerClient.h index aa0cdcf..f3b4df1 100644 --- a/include/media/IAudioFlingerClient.h +++ b/include/media/IAudioFlingerClient.h @@ -21,6 +21,7 @@ #include <utils/RefBase.h> #include <binder/IInterface.h> #include <utils/KeyedVector.h> +#include <system/audio.h> namespace android { @@ -32,7 +33,7 @@ public: DECLARE_META_INTERFACE(AudioFlingerClient); // Notifies a change of audio input/output configuration. - virtual void ioConfigChanged(int event, int ioHandle, void *param2) = 0; + virtual void ioConfigChanged(int event, audio_io_handle_t ioHandle, void *param2) = 0; }; diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index 4c30e04..e541c18 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -335,7 +335,7 @@ private: status_t applyRotation(); status_t waitForBufferFilled_l(); - int64_t retrieveDecodingTimeUs(bool isCodecSpecific); + int64_t getDecodingTimeUs(); status_t parseAVCCodecSpecificData( const void *data, size_t size, diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h index dd97ce4..23226c0 100644 --- a/include/private/media/AudioTrackShared.h +++ b/include/private/media/AudioTrackShared.h @@ -54,6 +54,7 @@ namespace android { #define CBLK_RESTORED_ON 0x0040 // track has been restored after invalidation #define CBLK_RESTORED_OFF 0x0040 // by AudioFlinger +// Important: do not add any virtual methods, including ~ struct audio_track_cblk_t { diff --git a/include/ui/Region.h b/include/ui/Region.h index 6c9a620..f242f18 100644 --- a/include/ui/Region.h +++ b/include/ui/Region.h @@ -55,43 +55,51 @@ public: void set(uint32_t w, uint32_t h); Region& orSelf(const Rect& rhs); + Region& xorSelf(const Rect& rhs); Region& andSelf(const Rect& rhs); Region& subtractSelf(const Rect& rhs); // boolean operators, applied on this Region& orSelf(const Region& rhs); + Region& xorSelf(const Region& rhs); Region& andSelf(const Region& rhs); Region& subtractSelf(const Region& rhs); // boolean operators const Region merge(const Rect& rhs) const; + const Region mergeExclusive(const Rect& rhs) const; const Region intersect(const Rect& rhs) const; const Region subtract(const Rect& rhs) const; // boolean operators const Region merge(const Region& rhs) const; + const Region mergeExclusive(const Region& rhs) const; const Region intersect(const Region& rhs) const; const Region subtract(const Region& rhs) const; // these translate rhs first Region& translateSelf(int dx, int dy); Region& orSelf(const Region& rhs, int dx, int dy); + Region& xorSelf(const Region& rhs, int dx, int dy); Region& andSelf(const Region& rhs, int dx, int dy); Region& subtractSelf(const Region& rhs, int dx, int dy); // these translate rhs first const Region translate(int dx, int dy) const; const Region merge(const Region& rhs, int dx, int dy) const; + const Region mergeExclusive(const Region& rhs, int dx, int dy) const; const Region intersect(const Region& rhs, int dx, int dy) const; const Region subtract(const Region& rhs, int dx, int dy) const; // convenience operators overloads inline const Region operator | (const Region& rhs) const; + inline const Region operator ^ (const Region& rhs) const; inline const Region operator & (const Region& rhs) const; inline const Region operator - (const Region& rhs) const; inline const Region operator + (const Point& pt) const; inline Region& operator |= (const Region& rhs); + inline Region& operator ^= (const Region& rhs); inline Region& operator &= (const Region& rhs); inline Region& operator -= (const Region& rhs); inline Region& operator += (const Point& pt); @@ -158,6 +166,9 @@ private: const Region Region::operator | (const Region& rhs) const { return merge(rhs); } +const Region Region::operator ^ (const Region& rhs) const { + return mergeExclusive(rhs); +} const Region Region::operator & (const Region& rhs) const { return intersect(rhs); } @@ -172,6 +183,9 @@ const Region Region::operator + (const Point& pt) const { Region& Region::operator |= (const Region& rhs) { return orSelf(rhs); } +Region& Region::operator ^= (const Region& rhs) { + return xorSelf(rhs); +} Region& Region::operator &= (const Region& rhs) { return andSelf(rhs); } diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp index a85362d..de2c674 100644 --- a/libs/hwui/Snapshot.cpp +++ b/libs/hwui/Snapshot.cpp @@ -31,6 +31,7 @@ Snapshot::Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), transform = &mTransformRoot; clipRect = &mClipRectRoot; region = NULL; + clipRegion = NULL; } /** @@ -42,6 +43,8 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): invisible(s->invisible), empty(false), viewport(s->viewport), height(s->height) { + clipRegion = NULL; + if (saveFlags & SkCanvas::kMatrix_SaveFlag) { mTransformRoot.load(*s->transform); transform = &mTransformRoot; @@ -52,8 +55,17 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): if (saveFlags & SkCanvas::kClip_SaveFlag) { mClipRectRoot.set(*s->clipRect); clipRect = &mClipRectRoot; +#if STENCIL_BUFFER_SIZE + if (s->clipRegion) { + mClipRegionRoot.merge(*s->clipRegion); + clipRegion = &mClipRegionRoot; + } +#endif } else { clipRect = s->clipRect; +#if STENCIL_BUFFER_SIZE + clipRegion = s->clipRegion; +#endif } if (s->flags & Snapshot::kFlagFboTarget) { @@ -68,6 +80,77 @@ Snapshot::Snapshot(const sp<Snapshot>& s, int saveFlags): // Clipping /////////////////////////////////////////////////////////////////////////////// +void Snapshot::ensureClipRegion() { +#if STENCIL_BUFFER_SIZE + if (!clipRegion) { + clipRegion = &mClipRegionRoot; + android::Rect tmp(clipRect->left, clipRect->top, clipRect->right, clipRect->bottom); + clipRegion->set(tmp); + } +#endif +} + +void Snapshot::copyClipRectFromRegion() { +#if STENCIL_BUFFER_SIZE + if (!clipRegion->isEmpty()) { + android::Rect bounds(clipRegion->bounds()); + clipRect->set(bounds.left, bounds.top, bounds.right, bounds.bottom); + + if (clipRegion->isRect()) { + clipRegion->clear(); + clipRegion = NULL; + } + } else { + clipRect->setEmpty(); + clipRegion = NULL; + } +#endif +} + +bool Snapshot::clipRegionOr(float left, float top, float right, float bottom) { +#if STENCIL_BUFFER_SIZE + android::Rect tmp(left, top, right, bottom); + clipRegion->orSelf(tmp); + copyClipRectFromRegion(); + return true; +#else + return false; +#endif +} + +bool Snapshot::clipRegionXor(float left, float top, float right, float bottom) { +#if STENCIL_BUFFER_SIZE + android::Rect tmp(left, top, right, bottom); + clipRegion->xorSelf(tmp); + copyClipRectFromRegion(); + return true; +#else + return false; +#endif +} + +bool Snapshot::clipRegionAnd(float left, float top, float right, float bottom) { +#if STENCIL_BUFFER_SIZE + android::Rect tmp(left, top, right, bottom); + clipRegion->andSelf(tmp); + copyClipRectFromRegion(); + return true; +#else + return false; +#endif +} + +bool Snapshot::clipRegionNand(float left, float top, float right, float bottom) { +#if STENCIL_BUFFER_SIZE + android::Rect tmp(left, top, right, bottom); + clipRegion->subtractSelf(tmp); + copyClipRectFromRegion(); + return true; +#else + return false; +#endif +} + bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) { Rect r(left, top, right, bottom); transform->mapRect(r); @@ -77,32 +160,46 @@ bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion:: bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { bool clipped = false; - // NOTE: The unimplemented operations require support for regions - // Supporting regions would require using a stencil buffer instead - // of the scissor. The stencil buffer itself is not too expensive - // (memory cost excluded) but on fillrate limited devices, managing - // the stencil might have a negative impact on the framerate. switch (op) { - case SkRegion::kDifference_Op: + case SkRegion::kDifference_Op: { + ensureClipRegion(); + clipped = clipRegionNand(r.left, r.top, r.right, r.bottom); break; - case SkRegion::kIntersect_Op: - clipped = clipRect->intersect(r); - if (!clipped) { - clipRect->setEmpty(); - clipped = true; + } + case SkRegion::kIntersect_Op: { + if (CC_UNLIKELY(clipRegion)) { + clipped = clipRegionOr(r.left, r.top, r.right, r.bottom); + } else { + clipped = clipRect->intersect(r); + if (!clipped) { + clipRect->setEmpty(); + clipped = true; + } } break; - case SkRegion::kUnion_Op: - clipped = clipRect->unionWith(r); + } + case SkRegion::kUnion_Op: { + if (CC_UNLIKELY(clipRegion)) { + clipped = clipRegionAnd(r.left, r.top, r.right, r.bottom); + } else { + clipped = clipRect->unionWith(r); + } break; - case SkRegion::kXOR_Op: + } + case SkRegion::kXOR_Op: { + ensureClipRegion(); + clipped = clipRegionXor(r.left, r.top, r.right, r.bottom); break; - case SkRegion::kReverseDifference_Op: + } + case SkRegion::kReverseDifference_Op: { + // TODO!!!!!!! break; - case SkRegion::kReplace_Op: - clipRect->set(r); + } + case SkRegion::kReplace_Op: { + setClip(r.left, r.top, r.right, r.bottom); clipped = true; break; + } } if (clipped) { @@ -114,6 +211,12 @@ bool Snapshot::clipTransformed(const Rect& r, SkRegion::Op op) { void Snapshot::setClip(float left, float top, float right, float bottom) { clipRect->set(left, top, right, bottom); +#if STENCIL_BUFFER_SIZE + if (clipRegion) { + clipRegion->clear(); + clipRegion = NULL; + } +#endif flags |= Snapshot::kFlagClipSet; } @@ -129,8 +232,7 @@ const Rect& Snapshot::getLocalClip() { void Snapshot::resetClip(float left, float top, float right, float bottom) { clipRect = &mClipRectRoot; - clipRect->set(left, top, right, bottom); - flags |= Snapshot::kFlagClipSet; + setClip(left, top, right, bottom); } /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h index c94af7e..b2bc879 100644 --- a/libs/hwui/Snapshot.h +++ b/libs/hwui/Snapshot.h @@ -181,7 +181,7 @@ public: mat4* transform; /** - * Current clip region. The clip is stored in canvas-space coordinates, + * Current clip rect. The clip is stored in canvas-space coordinates, * (screen-space coordinates in the regular case.) * * This is a reference to a rect owned by this snapshot or another @@ -190,6 +190,17 @@ public: Rect* clipRect; /** + * Current clip region. The clip is stored in canvas-space coordinates, + * (screen-space coordinates in the regular case.) + * + * This is a reference to a region owned by this snapshot or another + * snapshot. This pointer must not be freed. See ::mClipRegionRoot. + * + * This field is used only if STENCIL_BUFFER_SIZE is > 0. + */ + Region* clipRegion; + + /** * The ancestor layer's dirty region. * * This is a reference to a region owned by a layer. This pointer must @@ -198,10 +209,22 @@ public: Region* region; private: + void ensureClipRegion(); + void copyClipRectFromRegion(); + + bool clipRegionOr(float left, float top, float right, float bottom); + bool clipRegionXor(float left, float top, float right, float bottom); + bool clipRegionAnd(float left, float top, float right, float bottom); + bool clipRegionNand(float left, float top, float right, float bottom); + mat4 mTransformRoot; Rect mClipRectRoot; Rect mLocalClip; +#if STENCIL_BUFFER_SIZE + Region mClipRegionRoot; +#endif + }; // class Snapshot }; // namespace uirenderer diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk index 58d3e5c..2166ce7 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -89,7 +89,6 @@ LOCAL_SRC_FILES:= \ rsFifoSocket.cpp \ rsFileA3D.cpp \ rsFont.cpp \ - rsLocklessFifo.cpp \ rsObjectBase.cpp \ rsMatrix2x2.cpp \ rsMatrix3x3.cpp \ @@ -128,7 +127,7 @@ LOCAL_SRC_FILES:= \ driver/rsdShaderCache.cpp \ driver/rsdVertexArray.cpp -LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo +LOCAL_SHARED_LIBRARIES += libz libcutils libutils libEGL libGLESv1_CM libGLESv2 libui libbcc libbcinfo libgui LOCAL_STATIC_LIBRARIES := libdex libft2 @@ -196,7 +195,6 @@ LOCAL_SRC_FILES:= \ rsFifoSocket.cpp \ rsFileA3D.cpp \ rsFont.cpp \ - rsLocklessFifo.cpp \ rsObjectBase.cpp \ rsMatrix2x2.cpp \ rsMatrix3x3.cpp \ diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp index 7acc054..368dd71 100644 --- a/libs/rs/driver/rsdGL.cpp +++ b/libs/rs/driver/rsdGL.cpp @@ -215,6 +215,8 @@ bool rsdGLInit(const Context *rsc) { ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs); checkEglError("eglGetConfigs", ret); + eglSwapInterval(dc->gl.egl.display, 0); + if (numConfigs) { EGLConfig* const configs = new EGLConfig[numConfigs]; diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec index 6887b22..ffb1196 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -115,6 +115,7 @@ ContextSetPriority { } ContextDestroyWorker { + sync } AssignName { diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index ad2ff0f..04284dd 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -18,6 +18,7 @@ #include "rsContext.h" #include "rsThreadIO.h" #include <ui/FramebufferNativeWindow.h> +#include <gui/DisplayEventReceiver.h> #include <sys/types.h> #include <sys/resource.h> @@ -245,42 +246,55 @@ void * Context::threadProc(void *vrsc) { } rsc->mRunning = true; - bool mDraw = true; - bool doWait = true; - - uint64_t targetTime = rsc->getTime(); - while (!rsc->mExit) { - uint64_t waitTime = 0; - uint64_t now = rsc->getTime(); - if (!doWait) { - if (now < targetTime) { - waitTime = targetTime - now; - doWait = true; - } + if (!rsc->mIsGraphicsContext) { + while (!rsc->mExit) { + rsc->mIO.playCoreCommands(rsc, true, -1); } + } else { +#ifndef ANDROID_RS_SERIALIZE + DisplayEventReceiver displayEvent; + DisplayEventReceiver::Event eventBuffer[1]; +#endif + int vsyncRate = 0; + int targetRate = 0; - mDraw |= rsc->mIO.playCoreCommands(rsc, doWait, waitTime); - mDraw &= (rsc->mRootScript.get() != NULL); - mDraw &= rsc->mHasSurface; - - if (mDraw && rsc->mIsGraphicsContext) { - uint64_t delay = rsc->runRootScript() * 1000000; - targetTime = rsc->getTime() + delay; - doWait = (delay == 0); + bool drawOnce = false; + while (!rsc->mExit) { + rsc->timerSet(RS_TIMER_IDLE); - if (rsc->props.mLogVisual) { - rsc->displayDebugStats(); +#ifndef ANDROID_RS_SERIALIZE + if (vsyncRate != targetRate) { + displayEvent.setVsyncRate(targetRate); + vsyncRate = targetRate; + } + if (targetRate) { + drawOnce |= rsc->mIO.playCoreCommands(rsc, true, displayEvent.getFd()); + while (displayEvent.getEvents(eventBuffer, 1) != 0) { + //ALOGE("vs2 time past %lld", (rsc->getTime() - eventBuffer[0].header.timestamp) / 1000000); + } + } else +#endif + { + drawOnce |= rsc->mIO.playCoreCommands(rsc, true, -1); } - mDraw = !rsc->mPaused; - rsc->timerSet(RS_TIMER_CLEAR_SWAP); - rsc->mHal.funcs.swap(rsc); - rsc->timerFrame(); - rsc->timerSet(RS_TIMER_INTERNAL); - rsc->timerPrint(); - rsc->timerReset(); - } else { - doWait = true; + if ((rsc->mRootScript.get() != NULL) && rsc->mHasSurface && + (targetRate || drawOnce) && !rsc->mPaused) { + + drawOnce = false; + targetRate = ((rsc->runRootScript() + 15) / 16); + + if (rsc->props.mLogVisual) { + rsc->displayDebugStats(); + } + + rsc->timerSet(RS_TIMER_CLEAR_SWAP); + rsc->mHal.funcs.swap(rsc); + rsc->timerFrame(); + rsc->timerSet(RS_TIMER_INTERNAL); + rsc->timerPrint(); + rsc->timerReset(); + } } } @@ -315,8 +329,8 @@ void Context::destroyWorkerThreadResources() { mFBOCache.deinit(this); } ObjectBase::freeAllChildren(this); - //ALOGV("destroyWorkerThreadResources 2"); mExit = true; + //ALOGV("destroyWorkerThreadResources 2"); } void Context::printWatchdogInfo(void *ctx) { @@ -382,7 +396,7 @@ bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) { pthread_mutex_lock(&gInitMutex); mIO.init(); - mIO.setTimoutCallback(printWatchdogInfo, this, 2e9); + mIO.setTimeoutCallback(printWatchdogInfo, this, 2e9); dev->addContext(this); mDev = dev; @@ -434,14 +448,12 @@ Context::~Context() { ALOGV("%p Context::~Context", this); if (!mIsContextLite) { - mIO.coreFlush(); - rsAssert(mExit); - mExit = true; mPaused = false; void *res; mIO.shutdown(); int status = pthread_join(mThreadId, &res); + rsAssert(mExit); if (mHal.funcs.shutdownDriver) { mHal.funcs.shutdownDriver(this); diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index 61c29f9..a844a20 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -39,7 +39,6 @@ #include "rsFBOCache.h" #include "rsgApiStructs.h" -#include "rsLocklessFifo.h" // --------------------------------------------------------------------------- namespace android { diff --git a/libs/rs/rsFifo.cpp b/libs/rs/rsFifo.cpp deleted file mode 100644 index 3d5d8c4..0000000 --- a/libs/rs/rsFifo.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "rsFifoSocket.h" -#include "utils/Timers.h" -#include "utils/StopWatch.h" - -using namespace android; -using namespace android::renderscript; - -Fifo::Fifo() { - -} - -Fifo::~Fifo() { - -} - diff --git a/libs/rs/rsFifo.h b/libs/rs/rsFifo.h index f924b95..911f446 100644 --- a/libs/rs/rsFifo.h +++ b/libs/rs/rsFifo.h @@ -35,9 +35,9 @@ protected: virtual ~Fifo(); public: - void virtual writeAsync(const void *data, size_t bytes) = 0; + bool virtual writeAsync(const void *data, size_t bytes, bool waitForSpace = true) = 0; void virtual writeWaitReturn(void *ret, size_t retSize) = 0; - size_t virtual read(void *data, size_t bytes) = 0; + size_t virtual read(void *data, size_t bytes, bool doWait = true, uint64_t timeToWait = 0) = 0; void virtual readReturn(const void *data, size_t bytes) = 0; void virtual flush() = 0; diff --git a/libs/rs/rsFifoSocket.cpp b/libs/rs/rsFifoSocket.cpp index 163a44b..bd511cf 100644 --- a/libs/rs/rsFifoSocket.cpp +++ b/libs/rs/rsFifoSocket.cpp @@ -22,6 +22,7 @@ #include <stdlib.h> #include <ctype.h> #include <unistd.h> +#include <poll.h> #include <sys/types.h> #include <sys/socket.h> @@ -29,55 +30,79 @@ using namespace android; using namespace android::renderscript; FifoSocket::FifoSocket() { - sequence = 1; + mShutdown = false; } FifoSocket::~FifoSocket() { } -bool FifoSocket::init() { +bool FifoSocket::init(bool supportNonBlocking, bool supportReturnValues, size_t maxDataSize) { int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); return false; } void FifoSocket::shutdown() { + mShutdown = true; + uint64_t d = 0; + ::send(sv[0], &d, sizeof(d), 0); + ::send(sv[1], &d, sizeof(d), 0); + close(sv[0]); + close(sv[1]); } -void FifoSocket::writeAsync(const void *data, size_t bytes) { +bool FifoSocket::writeAsync(const void *data, size_t bytes, bool waitForSpace) { if (bytes == 0) { - return; + return true; } //ALOGE("writeAsync %p %i", data, bytes); size_t ret = ::send(sv[0], data, bytes, 0); //ALOGE("writeAsync ret %i", ret); rsAssert(ret == bytes); + return true; } void FifoSocket::writeWaitReturn(void *retData, size_t retBytes) { + if (mShutdown) { + return; + } + //ALOGE("writeWaitReturn %p %i", retData, retBytes); - size_t ret = ::recv(sv[0], retData, retBytes, 0); + size_t ret = ::recv(sv[0], retData, retBytes, MSG_WAITALL); //ALOGE("writeWaitReturn %i", ret); rsAssert(ret == retBytes); } size_t FifoSocket::read(void *data, size_t bytes) { + if (mShutdown) { + return 0; + } + //ALOGE("read %p %i", data, bytes); - size_t ret = ::recv(sv[1], data, bytes, 0); - rsAssert(ret == bytes); - //ALOGE("read ret %i", ret); + size_t ret = ::recv(sv[1], data, bytes, MSG_WAITALL); + rsAssert(ret == bytes || mShutdown); + //ALOGE("read ret %i bytes %i", ret, bytes); + if (mShutdown) { + ret = 0; + } return ret; } -void FifoSocket::readReturn(const void *data, size_t bytes) { - ALOGE("readReturn %p %Zu", data, bytes); - size_t ret = ::send(sv[1], data, bytes, 0); - ALOGE("readReturn %Zu", ret); - rsAssert(ret == bytes); +bool FifoSocket::isEmpty() { + struct pollfd p; + p.fd = sv[1]; + p.events = POLLIN; + int r = poll(&p, 1, 0); + //ALOGE("poll r=%i", r); + return r == 0; } -void FifoSocket::flush() { +void FifoSocket::readReturn(const void *data, size_t bytes) { + //ALOGE("readReturn %p %Zu", data, bytes); + size_t ret = ::send(sv[1], data, bytes, 0); + //ALOGE("readReturn %Zu", ret); + //rsAssert(ret == bytes); } diff --git a/libs/rs/rsFifoSocket.h b/libs/rs/rsFifoSocket.h index 7df2b67..cac0a75 100644 --- a/libs/rs/rsFifoSocket.h +++ b/libs/rs/rsFifoSocket.h @@ -29,23 +29,23 @@ public: FifoSocket(); virtual ~FifoSocket(); - bool init(); + bool init(bool supportNonBlocking = true, + bool supportReturnValues = true, + size_t maxDataSize = 0); void shutdown(); + bool writeAsync(const void *data, size_t bytes, bool waitForSpace = true); + void writeWaitReturn(void *ret, size_t retSize); + size_t read(void *data, size_t bytes); + void readReturn(const void *data, size_t bytes); + bool isEmpty(); - - void virtual writeAsync(const void *data, size_t bytes); - void virtual writeWaitReturn(void *ret, size_t retSize); - size_t virtual read(void *data, size_t bytes); - void virtual readReturn(const void *data, size_t bytes); - - void virtual flush(); + int getWriteFd() {return sv[0];} + int getReadFd() {return sv[1];} protected: int sv[2]; - uint32_t sequence; - - + bool mShutdown; }; } diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp deleted file mode 100644 index 0466d8b..0000000 --- a/libs/rs/rsLocklessFifo.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "rsLocklessFifo.h" -#include "utils/Timers.h" -#include "utils/StopWatch.h" - -using namespace android; -using namespace android::renderscript; - -LocklessCommandFifo::LocklessCommandFifo() : mBuffer(0), mInitialized(false) { - mTimeoutCallback = NULL; - mTimeoutCallbackData = NULL; - mTimeoutWait = 0; -} - -LocklessCommandFifo::~LocklessCommandFifo() { - if (!mInShutdown && mInitialized) { - shutdown(); - } - if (mBuffer) { - free(mBuffer); - } -} - -void LocklessCommandFifo::shutdown() { - mInShutdown = true; - mSignalToWorker.set(); -} - -bool LocklessCommandFifo::init(uint32_t sizeInBytes) { - // Add room for a buffer reset command - mBuffer = static_cast<uint8_t *>(malloc(sizeInBytes + 4)); - if (!mBuffer) { - ALOGE("LocklessFifo allocation failure"); - return false; - } - - if (!mSignalToControl.init() || !mSignalToWorker.init()) { - ALOGE("Signal setup failed"); - free(mBuffer); - return false; - } - - mInShutdown = false; - mSize = sizeInBytes; - mPut = mBuffer; - mGet = mBuffer; - mEnd = mBuffer + (sizeInBytes) - 1; - //dumpState("init"); - mInitialized = true; - return true; -} - -uint32_t LocklessCommandFifo::getFreeSpace() const { - int32_t freeSpace = 0; - //dumpState("getFreeSpace"); - - if (mPut >= mGet) { - freeSpace = mEnd - mPut; - } else { - freeSpace = mGet - mPut; - } - - if (freeSpace < 0) { - freeSpace = 0; - } - return freeSpace; -} - -bool LocklessCommandFifo::isEmpty() const { - uint32_t p = android_atomic_acquire_load((int32_t *)&mPut); - return ((uint8_t *)p) == mGet; -} - - -void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) { - // Add space for command header and loop token; - sizeInBytes += 8; - - //dumpState("reserve"); - if (getFreeSpace() < sizeInBytes) { - makeSpace(sizeInBytes); - } - - return mPut + 4; -} - -void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) { - if (mInShutdown) { - return; - } - //dumpState("commit 1"); - reinterpret_cast<uint16_t *>(mPut)[0] = command; - reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes; - - int32_t s = ((sizeInBytes + 3) & ~3) + 4; - android_atomic_add(s, (int32_t *)&mPut); - //dumpState("commit 2"); - mSignalToWorker.set(); -} - -void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) { - if (mInShutdown) { - return; - } - - //char buf[1024]; - //sprintf(buf, "RenderScript LocklessCommandFifo::commitSync %p %i %i", this, command, sizeInBytes); - //StopWatch compileTimer(buf); - commit(command, sizeInBytes); - flush(); -} - -void LocklessCommandFifo::flush() { - //dumpState("flush 1"); - while (mPut != mGet) { - while (!mSignalToControl.wait(mTimeoutWait)) { - if (mTimeoutCallback) { - mTimeoutCallback(mTimeoutCallbackData); - } - } - } - //dumpState("flush 2"); -} - -void LocklessCommandFifo::setTimoutCallback(void (*cbk)(void *), void *data, uint64_t timeout) { - mTimeoutCallback = cbk; - mTimeoutCallbackData = data; - mTimeoutWait = timeout; -} - -bool LocklessCommandFifo::wait(uint64_t timeout) { - while (isEmpty() && !mInShutdown) { - mSignalToControl.set(); - return mSignalToWorker.wait(timeout); - } - return true; -} - -const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData, uint64_t timeout) { - while (1) { - //dumpState("get"); - wait(timeout); - - if (isEmpty() || mInShutdown) { - *command = 0; - *bytesData = 0; - return NULL; - } - - *command = reinterpret_cast<const uint16_t *>(mGet)[0]; - *bytesData = reinterpret_cast<const uint16_t *>(mGet)[1]; - if (*command) { - // non-zero command is valid - return mGet+4; - } - - // zero command means reset to beginning. - mGet = mBuffer; - } -} - -void LocklessCommandFifo::next() { - uint32_t bytes = reinterpret_cast<const uint16_t *>(mGet)[1]; - - android_atomic_add(((bytes + 3) & ~3) + 4, (int32_t *)&mGet); - //mGet += ((bytes + 3) & ~3) + 4; - if (isEmpty()) { - mSignalToControl.set(); - } - //dumpState("next"); -} - -bool LocklessCommandFifo::makeSpaceNonBlocking(uint32_t bytes) { - //dumpState("make space non-blocking"); - if ((mPut+bytes) > mEnd) { - // Need to loop regardless of where get is. - if ((mGet > mPut) || (mBuffer+4 >= mGet)) { - return false; - } - - // Toss in a reset then the normal wait for space will do the rest. - reinterpret_cast<uint16_t *>(mPut)[0] = 0; - reinterpret_cast<uint16_t *>(mPut)[1] = 0; - mPut = mBuffer; - mSignalToWorker.set(); - } - - // it will fit here so we just need to wait for space. - if (getFreeSpace() < bytes) { - return false; - } - - return true; -} - -void LocklessCommandFifo::makeSpace(uint32_t bytes) { - //dumpState("make space"); - if ((mPut+bytes) > mEnd) { - // Need to loop regardless of where get is. - while ((mGet > mPut) || (mBuffer+4 >= mGet)) { - usleep(100); - } - - // Toss in a reset then the normal wait for space will do the rest. - reinterpret_cast<uint16_t *>(mPut)[0] = 0; - reinterpret_cast<uint16_t *>(mPut)[1] = 0; - mPut = mBuffer; - mSignalToWorker.set(); - } - - // it will fit here so we just need to wait for space. - while (getFreeSpace() < bytes) { - usleep(100); - } - -} - -void LocklessCommandFifo::dumpState(const char *s) const { - ALOGV("%s %p put %p, get %p, buf %p, end %p", s, this, mPut, mGet, mBuffer, mEnd); -} - -void LocklessCommandFifo::printDebugData() const { - dumpState("printing fifo debug"); - const uint32_t *pptr = (const uint32_t *)mGet; - pptr -= 8 * 4; - if (mGet < mBuffer) { - pptr = (const uint32_t *)mBuffer; - } - - - for (int ct=0; ct < 16; ct++) { - ALOGV("fifo %p = 0x%08x 0x%08x 0x%08x 0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]); - pptr += 4; - } - -} diff --git a/libs/rs/rsLocklessFifo.h b/libs/rs/rsLocklessFifo.h deleted file mode 100644 index dafc512..0000000 --- a/libs/rs/rsLocklessFifo.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_RS_LOCKLESS_FIFO_H -#define ANDROID_RS_LOCKLESS_FIFO_H - - -#include "rsUtils.h" -#include "rsSignal.h" - -namespace android { -namespace renderscript { - - -// A simple FIFO to be used as a producer / consumer between two -// threads. One is writer and one is reader. The common cases -// will not require locking. It is not threadsafe for multiple -// readers or writers by design. - -class LocklessCommandFifo { -public: - bool init(uint32_t size); - void shutdown(); - void setTimoutCallback(void (*)(void *), void *, uint64_t timeout); - - void printDebugData() const; - - LocklessCommandFifo(); - ~LocklessCommandFifo(); - -protected: - uint8_t * volatile mPut; - uint8_t * volatile mGet; - uint8_t * mBuffer; - uint8_t * mEnd; - uint8_t mSize; - bool mInShutdown; - bool mInitialized; - - Signal mSignalToWorker; - Signal mSignalToControl; - -public: - void * reserve(uint32_t bytes); - void commit(uint32_t command, uint32_t bytes); - void commitSync(uint32_t command, uint32_t bytes); - - void flush(); - bool wait(uint64_t timeout = 0); - - const void * get(uint32_t *command, uint32_t *bytesData, uint64_t timeout = 0); - void next(); - - void makeSpace(uint32_t bytes); - bool makeSpaceNonBlocking(uint32_t bytes); - - bool isEmpty() const; - uint32_t getFreeSpace() const; - -private: - void dumpState(const char *) const; - - void (*mTimeoutCallback)(void *); - void * mTimeoutCallbackData; - uint64_t mTimeoutWait; -}; - - -} -} -#endif diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 1917774..8e4b988 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -18,227 +18,189 @@ #include "rsThreadIO.h" +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <fcntl.h> +#include <poll.h> + + using namespace android; using namespace android::renderscript; -ThreadIO::ThreadIO() : mUsingSocket(false) { +ThreadIO::ThreadIO() { + mRunning = true; } ThreadIO::~ThreadIO() { } -void ThreadIO::init(bool useSocket) { - mUsingSocket = useSocket; - mToCore.init(16 * 1024); - - if (mUsingSocket) { - mToClientSocket.init(); - mToCoreSocket.init(); - } else { - mToClient.init(1024); - } +void ThreadIO::init() { + mToClient.init(); + mToCore.init(); } void ThreadIO::shutdown() { - //ALOGE("shutdown 1"); + mRunning = false; mToCore.shutdown(); - //ALOGE("shutdown 2"); -} - -void ThreadIO::coreFlush() { - //ALOGE("coreFlush 1"); - if (mUsingSocket) { - } else { - mToCore.flush(); - } - //ALOGE("coreFlush 2"); } void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) { //ALOGE("coreHeader %i %i", cmdID, dataLen); - if (mUsingSocket) { - CoreCmdHeader hdr; - hdr.bytes = dataLen; - hdr.cmdID = cmdID; - mToCoreSocket.writeAsync(&hdr, sizeof(hdr)); - } else { - mCoreCommandSize = dataLen; - mCoreCommandID = cmdID; - mCoreDataPtr = (uint8_t *)mToCore.reserve(dataLen); - mCoreDataBasePtr = mCoreDataPtr; - } - //ALOGE("coreHeader ret %p", mCoreDataPtr); - return mCoreDataPtr; -} - -void ThreadIO::coreData(const void *data, size_t dataLen) { - //ALOGE("coreData %p %i", data, dataLen); - mToCoreSocket.writeAsync(data, dataLen); - //ALOGE("coreData ret %p", mCoreDataPtr); + CoreCmdHeader *hdr = (CoreCmdHeader *)&mSendBuffer[0]; + hdr->bytes = dataLen; + hdr->cmdID = cmdID; + mSendLen = dataLen + sizeof(CoreCmdHeader); + //mToCoreSocket.writeAsync(&hdr, sizeof(hdr)); + //ALOGE("coreHeader ret "); + return &mSendBuffer[sizeof(CoreCmdHeader)]; } void ThreadIO::coreCommit() { - //ALOGE("coreCommit %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize); - if (mUsingSocket) { - } else { - rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize); - mToCore.commit(mCoreCommandID, mCoreCommandSize); - } - //ALOGE("coreCommit ret"); -} - -void ThreadIO::coreCommitSync() { - //ALOGE("coreCommitSync %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize); - if (mUsingSocket) { - } else { - rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize); - mToCore.commitSync(mCoreCommandID, mCoreCommandSize); - } - //ALOGE("coreCommitSync ret"); + mToCore.writeAsync(&mSendBuffer, mSendLen); } void ThreadIO::clientShutdown() { - //ALOGE("coreShutdown 1"); mToClient.shutdown(); - //ALOGE("coreShutdown 2"); } void ThreadIO::coreSetReturn(const void *data, size_t dataLen) { - rsAssert(dataLen <= sizeof(mToCoreRet)); - memcpy(&mToCoreRet, data, dataLen); + uint32_t buf; + if (data == NULL) { + data = &buf; + dataLen = sizeof(buf); + } + + mToCore.readReturn(data, dataLen); } void ThreadIO::coreGetReturn(void *data, size_t dataLen) { - memcpy(data, &mToCoreRet, dataLen); -} + uint32_t buf; + if (data == NULL) { + data = &buf; + dataLen = sizeof(buf); + } -void ThreadIO::setTimoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) { - mToCore.setTimoutCallback(cb, dat, timeout); + mToCore.writeWaitReturn(data, dataLen); } +void ThreadIO::setTimeoutCallback(void (*cb)(void *), void *dat, uint64_t timeout) { + //mToCore.setTimeoutCallback(cb, dat, timeout); +} -bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait) { +bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, int waitFd) { bool ret = false; - uint64_t startTime = con->getTime(); - while (!mToCore.isEmpty() || waitForCommand) { - uint32_t cmdID = 0; - uint32_t cmdSize = 0; - if (con->props.mLogTimes) { - con->timerSet(Context::RS_TIMER_IDLE); - } + uint8_t buf[2 * 1024]; + const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0]; + const void * data = (const void *)&buf[sizeof(CoreCmdHeader)]; + + struct pollfd p[2]; + p[0].fd = mToCore.getReadFd(); + p[0].events = POLLIN; + p[0].revents = 0; + p[1].fd = waitFd; + p[1].events = POLLIN; + p[1].revents = 0; + int pollCount = 1; + if (waitFd >= 0) { + pollCount = 2; + } - uint64_t delay = 0; - if (waitForCommand) { - delay = timeToWait - (con->getTime() - startTime); - if (delay > timeToWait) { - delay = 0; - } - } + if (con->props.mLogTimes) { + con->timerSet(Context::RS_TIMER_IDLE); + } - if (delay == 0 && timeToWait != 0 && mToCore.isEmpty()) { + int waitTime = -1; + while (mRunning) { + int pr = poll(p, pollCount, waitTime); + if (pr <= 0) { break; } - const void * data = mToCore.get(&cmdID, &cmdSize, delay); - if (!cmdSize) { - // exception or timeout occurred. - break; - } - ret = true; - if (con->props.mLogTimes) { - con->timerSet(Context::RS_TIMER_INTERNAL); + if (p[0].revents) { + size_t r = mToCore.read(&buf[0], sizeof(CoreCmdHeader)); + mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes); + + if (r != sizeof(CoreCmdHeader)) { + // exception or timeout occurred. + break; + } + + ret = true; + if (con->props.mLogTimes) { + con->timerSet(Context::RS_TIMER_INTERNAL); + } + waitForCommand = false; + //ALOGV("playCoreCommands 3 %i %i", cmd->cmdID, cmd->bytes); + + if (cmd->cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) { + rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); + ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID); + } + gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes); + + if (con->props.mLogTimes) { + con->timerSet(Context::RS_TIMER_IDLE); + } + + if (waitFd < 0) { + // If we don't have a secondary wait object we should stop blocking now + // that at least one command has been processed. + waitTime = 0; + } } - waitForCommand = false; - //ALOGV("playCoreCommands 3 %i %i", cmdID, cmdSize); - if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) { - rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *))); - ALOGE("playCoreCommands error con %p, cmd %i", con, cmdID); - mToCore.printDebugData(); + if (p[1].revents && !p[0].revents) { + // We want to finish processing fifo events before processing the vsync. + // Otherwise we can end up falling behind and having tremendous lag. + break; } - gPlaybackFuncs[cmdID](con, data, cmdSize << 2); - mToCore.next(); } return ret; } RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) { - if (mUsingSocket) { - mToClientSocket.read(&mLastClientHeader, sizeof(mLastClientHeader)); - } else { - size_t bytesData = 0; - const uint32_t *d = (const uint32_t *)mToClient.get(&mLastClientHeader.cmdID, (uint32_t*)&bytesData); - if (bytesData >= sizeof(uint32_t)) { - mLastClientHeader.userID = d[0]; - mLastClientHeader.bytes = bytesData - sizeof(uint32_t); - } else { - mLastClientHeader.userID = 0; - mLastClientHeader.bytes = 0; - } - } + //ALOGE("getClientHeader"); + mToClient.read(&mLastClientHeader, sizeof(mLastClientHeader)); + receiveLen[0] = mLastClientHeader.bytes; usrID[0] = mLastClientHeader.userID; + //ALOGE("getClientHeader %i %i %i", mLastClientHeader.cmdID, usrID[0], receiveLen[0]); return (RsMessageToClientType)mLastClientHeader.cmdID; } RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen, uint32_t *usrID, size_t bufferLen) { + //ALOGE("getClientPayload"); receiveLen[0] = mLastClientHeader.bytes; usrID[0] = mLastClientHeader.userID; if (bufferLen < mLastClientHeader.bytes) { return RS_MESSAGE_TO_CLIENT_RESIZE; } - if (mUsingSocket) { - if (receiveLen[0]) { - mToClientSocket.read(data, receiveLen[0]); - } - return (RsMessageToClientType)mLastClientHeader.cmdID; - } else { - uint32_t bytesData = 0; - uint32_t commandID = 0; - const uint32_t *d = (const uint32_t *)mToClient.get(&commandID, &bytesData); - //ALOGE("getMessageToClient 3 %i %i", commandID, bytesData); - //ALOGE("getMessageToClient %i %i", commandID, *subID); - if (bufferLen >= receiveLen[0]) { - memcpy(data, d+1, receiveLen[0]); - mToClient.next(); - return (RsMessageToClientType)commandID; - } + if (receiveLen[0]) { + mToClient.read(data, receiveLen[0]); } - return RS_MESSAGE_TO_CLIENT_RESIZE; + //ALOGE("getClientPayload x"); + return (RsMessageToClientType)mLastClientHeader.cmdID; } bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data, size_t dataLen, bool waitForSpace) { + + //ALOGE("sendToClient %i %i %i", cmdID, usrID, (int)dataLen); ClientCmdHeader hdr; hdr.bytes = dataLen; hdr.cmdID = cmdID; hdr.userID = usrID; - if (mUsingSocket) { - mToClientSocket.writeAsync(&hdr, sizeof(hdr)); - if (dataLen) { - mToClientSocket.writeAsync(data, dataLen); - } - return true; - } else { - if (!waitForSpace) { - if (!mToClient.makeSpaceNonBlocking(dataLen + sizeof(hdr))) { - // Not enough room, and not waiting. - return false; - } - } - //ALOGE("sendMessageToClient 2"); - uint32_t *p = (uint32_t *)mToClient.reserve(dataLen + sizeof(usrID)); - p[0] = usrID; - if (dataLen > 0) { - memcpy(p+1, data, dataLen); - } - mToClient.commit(cmdID, dataLen + sizeof(usrID)); - //ALOGE("sendMessageToClient 3"); - return true; + mToClient.writeAsync(&hdr, sizeof(hdr)); + if (dataLen) { + mToClient.writeAsync(data, dataLen); } - return false; + + //ALOGE("sendToClient x"); + return true; } diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h index ebce0ab..d56a1c9 100644 --- a/libs/rs/rsThreadIO.h +++ b/libs/rs/rsThreadIO.h @@ -18,7 +18,6 @@ #define ANDROID_RS_THREAD_IO_H #include "rsUtils.h" -#include "rsLocklessFifo.h" #include "rsFifoSocket.h" // --------------------------------------------------------------------------- @@ -32,23 +31,17 @@ public: ThreadIO(); ~ThreadIO(); - void init(bool useSocket = false); + void init(); void shutdown(); // Plays back commands from the client. // Returns true if any commands were processed. - bool playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait); + bool playCoreCommands(Context *con, bool waitForCommand, int waitFd); - void setTimoutCallback(void (*)(void *), void *, uint64_t timeout); - //LocklessCommandFifo mToCore; + void setTimeoutCallback(void (*)(void *), void *, uint64_t timeout); - - - void coreFlush(); void * coreHeader(uint32_t, size_t dataLen); - void coreData(const void *data, size_t dataLen); void coreCommit(); - void coreCommitSync(); void coreSetReturn(const void *data, size_t dataLen); void coreGetReturn(void *data, size_t dataLen); @@ -71,20 +64,16 @@ protected: } ClientCmdHeader; ClientCmdHeader mLastClientHeader; - size_t mCoreCommandSize; - uint32_t mCoreCommandID; - uint8_t * mCoreDataPtr; - uint8_t * mCoreDataBasePtr; + bool mRunning; - bool mUsingSocket; - LocklessCommandFifo mToClient; - LocklessCommandFifo mToCore; - - FifoSocket mToClientSocket; - FifoSocket mToCoreSocket; + FifoSocket mToClient; + FifoSocket mToCore; intptr_t mToCoreRet; + size_t mSendLen; + uint8_t mSendBuffer[2 * 1024]; + }; diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c index 6b84e56..385c8b5 100644 --- a/libs/rs/rsg_generator.c +++ b/libs/rs/rsg_generator.c @@ -256,7 +256,7 @@ void printApiCpp(FILE *f) { fprintf(f, " memcpy(payload, %s, %s_length);\n", vt->name, vt->name); fprintf(f, " cmd->%s = (", vt->name); printVarType(f, vt); - fprintf(f, ")payload;\n"); + fprintf(f, ")(payload - ((uint8_t *)&cmd[1]));\n"); fprintf(f, " payload += %s_length;\n", vt->name); fprintf(f, " } else {\n"); fprintf(f, " cmd->%s = %s;\n", vt->name, vt->name); @@ -270,26 +270,19 @@ void printApiCpp(FILE *f) { needFlush = 1; } + fprintf(f, " io->coreCommit();\n"); if (hasInlineDataPointers(api)) { - fprintf(f, " if (dataSize < 1024) {\n"); - fprintf(f, " io->coreCommit();\n"); - fprintf(f, " } else {\n"); - fprintf(f, " io->coreCommitSync();\n"); + fprintf(f, " if (dataSize >= 1024) {\n"); + fprintf(f, " io->coreGetReturn(NULL, 0);\n"); fprintf(f, " }\n"); - } else { - fprintf(f, " io->coreCommit"); - if (needFlush) { - fprintf(f, "Sync"); - } - fprintf(f, "();\n"); - } - - if (api->ret.typeName[0]) { + } else if (api->ret.typeName[0]) { fprintf(f, "\n "); printVarType(f, &api->ret); fprintf(f, " ret;\n"); fprintf(f, " io->coreGetReturn(&ret, sizeof(ret));\n"); fprintf(f, " return ret;\n"); + } else if (needFlush) { + fprintf(f, " io->coreGetReturn(NULL, 0);\n"); } } fprintf(f, "};\n\n"); @@ -434,6 +427,7 @@ void printPlaybackCpp(FILE *f) { for (ct=0; ct < apiCount; ct++) { const ApiEntry * api = &apis[ct]; + int needFlush = 0; if (api->direct) { continue; @@ -444,6 +438,13 @@ void printPlaybackCpp(FILE *f) { //fprintf(f, " ALOGE(\"play command %s\\n\");\n", api->name); fprintf(f, " const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name); + if (hasInlineDataPointers(api)) { + fprintf(f, " const uint8_t *baseData = 0;\n"); + fprintf(f, " if (cmdSizeBytes != sizeof(RS_CMD_%s)) {\n", api->name); + fprintf(f, " baseData = &((const uint8_t *)vp)[sizeof(*cmd)];\n"); + fprintf(f, " }\n"); + } + fprintf(f, " "); if (api->ret.typeName[0]) { fprintf(f, "\n "); @@ -453,12 +454,31 @@ void printPlaybackCpp(FILE *f) { fprintf(f, "rsi_%s(con", api->name); for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; - fprintf(f, ",\n cmd->%s", vt->name); + needFlush += vt->ptrLevel; + + if (hasInlineDataPointers(api) && vt->ptrLevel) { + fprintf(f, ",\n (const %s *)&baseData[(intptr_t)cmd->%s]", vt->typeName, vt->name); + } else { + fprintf(f, ",\n cmd->%s", vt->name); + } } fprintf(f, ");\n"); - if (api->ret.typeName[0]) { + if (hasInlineDataPointers(api)) { + fprintf(f, " size_t totalSize = 0;\n"); + for (ct2=0; ct2 < api->paramCount; ct2++) { + if (api->params[ct2].ptrLevel) { + fprintf(f, " totalSize += cmd->%s_length;\n", api->params[ct2].name); + } + } + + fprintf(f, " if ((totalSize != 0) && (cmdSizeBytes == sizeof(RS_CMD_%s))) {\n", api->name); + fprintf(f, " con->mIO.coreSetReturn(NULL, 0);\n"); + fprintf(f, " }\n"); + } else if (api->ret.typeName[0]) { fprintf(f, " con->mIO.coreSetReturn(&ret, sizeof(ret));\n"); + } else if (api->sync || needFlush) { + fprintf(f, " con->mIO.coreSetReturn(NULL, 0);\n"); } fprintf(f, "};\n\n"); @@ -466,6 +486,7 @@ void printPlaybackCpp(FILE *f) { for (ct=0; ct < apiCount; ct++) { const ApiEntry * api = &apis[ct]; + int needFlush = 0; fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name); @@ -475,6 +496,7 @@ void printPlaybackCpp(FILE *f) { for (ct2=0; ct2 < api->paramCount; ct2++) { const VarType *vt = &api->params[ct2]; + needFlush += vt->ptrLevel; if (vt->ptrLevel == 1) { fprintf(f, " cmd.%s = (", vt->name); printVarType(f, vt); @@ -515,6 +537,8 @@ void printPlaybackCpp(FILE *f) { if (api->ret.typeName[0]) { fprintf(f, " f->readReturn(&ret, sizeof(ret));\n"); + } else if (needFlush) { + fprintf(f, " f->readReturn(NULL, 0);\n"); } fprintf(f, "};\n\n"); diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp index 8cd047a..6e2e731 100644 --- a/libs/ui/Region.cpp +++ b/libs/ui/Region.cpp @@ -126,6 +126,9 @@ void Region::addRectUnchecked(int l, int t, int r, int b) Region& Region::orSelf(const Rect& r) { return operationSelf(r, op_or); } +Region& Region::xorSelf(const Rect& r) { + return operationSelf(r, op_xor); +} Region& Region::andSelf(const Rect& r) { return operationSelf(r, op_and); } @@ -143,6 +146,9 @@ Region& Region::operationSelf(const Rect& r, int op) { Region& Region::orSelf(const Region& rhs) { return operationSelf(rhs, op_or); } +Region& Region::xorSelf(const Region& rhs) { + return operationSelf(rhs, op_xor); +} Region& Region::andSelf(const Region& rhs) { return operationSelf(rhs, op_and); } @@ -165,6 +171,9 @@ Region& Region::translateSelf(int x, int y) { const Region Region::merge(const Rect& rhs) const { return operation(rhs, op_or); } +const Region Region::mergeExclusive(const Rect& rhs) const { + return operation(rhs, op_xor); +} const Region Region::intersect(const Rect& rhs) const { return operation(rhs, op_and); } @@ -182,6 +191,9 @@ const Region Region::operation(const Rect& rhs, int op) const { const Region Region::merge(const Region& rhs) const { return operation(rhs, op_or); } +const Region Region::mergeExclusive(const Region& rhs) const { + return operation(rhs, op_xor); +} const Region Region::intersect(const Region& rhs) const { return operation(rhs, op_and); } @@ -205,6 +217,9 @@ const Region Region::translate(int x, int y) const { Region& Region::orSelf(const Region& rhs, int dx, int dy) { return operationSelf(rhs, dx, dy, op_or); } +Region& Region::xorSelf(const Region& rhs, int dx, int dy) { + return operationSelf(rhs, dx, dy, op_xor); +} Region& Region::andSelf(const Region& rhs, int dx, int dy) { return operationSelf(rhs, dx, dy, op_and); } @@ -222,6 +237,9 @@ Region& Region::operationSelf(const Region& rhs, int dx, int dy, int op) { const Region Region::merge(const Region& rhs, int dx, int dy) const { return operation(rhs, dx, dy, op_or); } +const Region Region::mergeExclusive(const Region& rhs, int dx, int dy) const { + return operation(rhs, dx, dy, op_xor); +} const Region Region::intersect(const Region& rhs, int dx, int dy) const { return operation(rhs, dx, dy, op_and); } @@ -421,6 +439,7 @@ void Region::boolean_operation(int op, Region& dst, SkRegion::Op sk_op; switch (op) { case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break; + case op_xor: sk_op = SkRegion::kUnion_XOR; name="XOR"; break; case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break; case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break; } diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk index 77b8424..ecb455a 100644 --- a/libs/usb/tests/AccessoryChat/Android.mk +++ b/libs/usb/tests/AccessoryChat/Android.mk @@ -23,9 +23,4 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_PACKAGE_NAME := AccessoryChat -LOCAL_JAVA_LIBRARIES := com.android.future.usb.accessory - -# Force an old SDK version to make sure we aren't using newer UsbManager APIs -LOCAL_SDK_VERSION := 8 - include $(BUILD_PACKAGE) diff --git a/libs/usb/tests/AccessoryChat/AndroidManifest.xml b/libs/usb/tests/AccessoryChat/AndroidManifest.xml index 802b715..6667eba 100644 --- a/libs/usb/tests/AccessoryChat/AndroidManifest.xml +++ b/libs/usb/tests/AccessoryChat/AndroidManifest.xml @@ -17,8 +17,9 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.accessorychat"> + <uses-feature android:name="android.hardware.usb.accessory" /> + <application android:label="Accessory Chat"> - <uses-library android:name="com.android.future.usb.accessory" /> <activity android:name="AccessoryChat" android:label="Accessory Chat"> <intent-filter> @@ -35,5 +36,5 @@ android:resource="@xml/accessory_filter" /> </activity> </application> - <uses-sdk android:minSdkVersion="10" /> + <uses-sdk android:minSdkVersion="12" /> </manifest> diff --git a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c index 85b52dd..06b477f 100644 --- a/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c +++ b/libs/usb/tests/AccessoryChat/accessorychat/accessorychat.c @@ -98,7 +98,7 @@ static int usb_device_added(const char *devname, void* client_data) { vendorId = usb_device_get_vendor_id(device); productId = usb_device_get_product_id(device); - if (vendorId == 0x18D1 || vendorId == 0x22B8) { + if (vendorId == 0x18D1 || vendorId == 0x22B8 || vendorId == 0x04e8) { if (!sDevice && (productId == 0x2D00 || productId == 0x2D01)) { struct usb_descriptor_header* desc; struct usb_descriptor_iter iter; diff --git a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java index c3f4fa3..bf0cef0 100644 --- a/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java +++ b/libs/usb/tests/AccessoryChat/src/com/android/accessorychat/AccessoryChat.java @@ -33,8 +33,8 @@ import android.util.Log; import android.widget.EditText; import android.widget.TextView; -import com.android.future.usb.UsbAccessory; -import com.android.future.usb.UsbManager; +import android.hardware.usb.UsbManager; +import android.hardware.usb.UsbAccessory; import java.io.FileDescriptor; import java.io.FileInputStream; @@ -64,9 +64,11 @@ public class AccessoryChat extends Activity implements Runnable, TextView.OnEdit public void onReceive(Context context, Intent intent) { if (ACTION_USB_PERMISSION.equals(intent.getAction())) { synchronized (this) { - UsbAccessory accessory = UsbManager.getAccessory(intent); + UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY); if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) { - openAccessory(accessory); + if (accessory != null) { + openAccessory(accessory); + } } else { Log.d(TAG, "permission denied for accessory " + accessory); } @@ -80,7 +82,7 @@ public class AccessoryChat extends Activity implements Runnable, TextView.OnEdit public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mUsbManager = UsbManager.getInstance(this); + mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(mUsbReceiver, filter); diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 9dc9cef..69ca58b 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -1150,9 +1150,44 @@ public class MediaScanner } } + static class MediaBulkDeleter { + StringBuilder idList = new StringBuilder(); + IContentProvider mProvider; + Uri mBaseUri; + + public MediaBulkDeleter(IContentProvider provider, Uri baseUri) { + mProvider = provider; + mBaseUri = baseUri; + } + + public void delete(long id) throws RemoteException { + if (idList.length() != 0) { + idList.append(","); + } + idList.append(id); + if (idList.length() > 1024) { + flush(); + } + } + public void flush() throws RemoteException { + int numrows = mProvider.delete(mBaseUri, MediaStore.MediaColumns._ID + " IN (" + + idList.toString() + ")", null); + //Log.i("@@@@@@@@@", "rows deleted: " + numrows); + idList.setLength(0); + } + } + private void postscan(String[] directories) throws RemoteException { Iterator<FileCacheEntry> iterator = mFileCache.values().iterator(); + // Tell the provider to not delete the file. + // If the file is truly gone the delete is unnecessary, and we want to avoid + // accidentally deleting files that are really there (this may happen if the + // filesystem is mounted and unmounted while the scanner is running). + Uri.Builder builder = mFilesUri.buildUpon(); + builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false"); + MediaBulkDeleter deleter = new MediaBulkDeleter(mMediaProvider, builder.build()); + while (iterator.hasNext()) { FileCacheEntry entry = iterator.next(); String path = entry.mPath; @@ -1176,15 +1211,6 @@ public class MediaScanner } if (fileMissing) { - // Tell the provider to not delete the file. - // If the file is truly gone the delete is unnecessary, and we want to avoid - // accidentally deleting files that are really there (this may happen if the - // filesystem is mounted and unmounted while the scanner is running). - Uri.Builder builder = mFilesUri.buildUpon(); - builder.appendEncodedPath(String.valueOf(entry.mRowId)); - builder.appendQueryParameter(MediaStore.PARAM_DELETE_DATA, "false"); - Uri missingUri = builder.build(); - // do not delete missing playlists, since they may have been modified by the user. // the user can delete them in the media player instead. // instead, clear the path and lastModified fields in the row @@ -1192,15 +1218,17 @@ public class MediaScanner int fileType = (mediaFileType == null ? 0 : mediaFileType.fileType); if (!MediaFile.isPlayListFileType(fileType)) { - mMediaProvider.delete(missingUri, null, null); + deleter.delete(entry.mRowId); iterator.remove(); if (entry.mPath.toLowerCase(Locale.US).endsWith("/.nomedia")) { + deleter.flush(); File f = new File(path); mMediaProvider.call(MediaStore.UNHIDE_CALL, f.getParent(), null); } } } } + deleter.flush(); // handle playlists last, after we know what media files are on the storage. if (mProcessPlaylists) { diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index 9f6599f..59cd9e3 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -53,8 +53,8 @@ static int loadEffect(cnode *node); static lib_entry_t *getLibrary(const char *path); static void resetEffectEnumeration(); static uint32_t updateNumEffects(); -static int findEffect(effect_uuid_t *type, - effect_uuid_t *uuid, +static int findEffect(const effect_uuid_t *type, + const effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc); static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len); @@ -236,7 +236,7 @@ int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) return ret; } -int EffectGetDescriptor(effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) +int EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { lib_entry_t *l = NULL; effect_descriptor_t *d = NULL; @@ -257,7 +257,7 @@ int EffectGetDescriptor(effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) return ret; } -int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) +int EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) { list_elem_t *e = gLibraryList; lib_entry_t *l = NULL; @@ -372,7 +372,7 @@ exit: return ret; } -int EffectIsNullUuid(effect_uuid_t *uuid) +int EffectIsNullUuid(const effect_uuid_t *uuid) { if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) { return 0; @@ -628,8 +628,8 @@ uint32_t updateNumEffects() { return cnt; } -int findEffect(effect_uuid_t *type, - effect_uuid_t *uuid, +int findEffect(const effect_uuid_t *type, + const effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc) { diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp index 108d36a..3714283 100644 --- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp +++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp @@ -195,7 +195,7 @@ extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescripto return 0; } /* end EffectQueryEffect */ -extern "C" int EffectCreate(effect_uuid_t *uuid, +extern "C" int EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle){ @@ -471,7 +471,7 @@ extern "C" int EffectRelease(effect_handle_t handle){ } /* end EffectRelease */ -extern "C" int EffectGetDescriptor(effect_uuid_t *uuid, +extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { const effect_descriptor_t *desc = NULL; diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp index 09cd5cc..358357e 100755 --- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp +++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp @@ -210,7 +210,7 @@ extern "C" int EffectQueryEffect(uint32_t index, return 0; } /* end EffectQueryEffect */ -extern "C" int EffectCreate(effect_uuid_t *uuid, +extern "C" int EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle){ @@ -317,7 +317,7 @@ extern "C" int EffectRelease(effect_handle_t handle){ return 0; } /* end EffectRelease */ -extern "C" int EffectGetDescriptor(effect_uuid_t *uuid, +extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { int i; int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *); diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp index 9fd6764..4d94a75 100755 --- a/media/libeffects/preprocessing/PreProcessing.cpp +++ b/media/libeffects/preprocessing/PreProcessing.cpp @@ -1072,7 +1072,7 @@ int PreProc_Init() { return sInitStatus; } -const effect_descriptor_t *PreProc_GetDescriptor(effect_uuid_t *uuid) +const effect_descriptor_t *PreProc_GetDescriptor(const effect_uuid_t *uuid) { size_t i; for (i = 0; i < PREPROC_NUM_EFFECTS; i++) { @@ -1568,7 +1568,7 @@ int PreProcessingLib_QueryEffect(uint32_t index, effect_descriptor_t *pDescripto return 0; } -int PreProcessingLib_Create(effect_uuid_t *uuid, +int PreProcessingLib_Create(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pInterface) @@ -1620,7 +1620,7 @@ int PreProcessingLib_Release(effect_handle_t interface) return Session_ReleaseEffect(fx->session, fx); } -int PreProcessingLib_GetDescriptor(effect_uuid_t *uuid, +int PreProcessingLib_GetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { if (pDescriptor == NULL || uuid == NULL){ diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp index 5241660..35a4a61 100644 --- a/media/libeffects/testlibs/EffectEqualizer.cpp +++ b/media/libeffects/testlibs/EffectEqualizer.cpp @@ -140,7 +140,7 @@ extern "C" int EffectQueryEffect(uint32_t index, return 0; } /* end EffectQueryNext */ -extern "C" int EffectCreate(effect_uuid_t *uuid, +extern "C" int EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) { @@ -195,7 +195,7 @@ extern "C" int EffectRelease(effect_handle_t handle) { return 0; } /* end EffectRelease */ -extern "C" int EffectGetDescriptor(effect_uuid_t *uuid, +extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { if (pDescriptor == NULL || uuid == NULL){ diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c index ebb72c1..8351712 100644 --- a/media/libeffects/testlibs/EffectReverb.c +++ b/media/libeffects/testlibs/EffectReverb.c @@ -111,7 +111,7 @@ int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) { return 0; } -int EffectCreate(effect_uuid_t *uuid, +int EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) { @@ -182,7 +182,7 @@ int EffectRelease(effect_handle_t handle) { return 0; } -int EffectGetDescriptor(effect_uuid_t *uuid, +int EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { int i; int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *); diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h index 5137074..1fb14a7 100644 --- a/media/libeffects/testlibs/EffectReverb.h +++ b/media/libeffects/testlibs/EffectReverb.h @@ -303,12 +303,12 @@ typedef struct reverb_module_s { int EffectQueryNumberEffects(uint32_t *pNumEffects); int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor); -int EffectCreate(effect_uuid_t *effectUID, +int EffectCreate(const effect_uuid_t *effectUID, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle); int EffectRelease(effect_handle_t handle); -int EffectGetDescriptor(effect_uuid_t *uuid, +int EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor); static int Reverb_Process(effect_handle_t self, diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp index 5d70a9b..51c8b68 100644 --- a/media/libeffects/visualizer/EffectVisualizer.cpp +++ b/media/libeffects/visualizer/EffectVisualizer.cpp @@ -190,7 +190,7 @@ int VisualizerLib_QueryEffect(uint32_t index, return 0; } -int VisualizerLib_Create(effect_uuid_t *uuid, +int VisualizerLib_Create(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) { @@ -240,7 +240,7 @@ int VisualizerLib_Release(effect_handle_t handle) { return 0; } -int VisualizerLib_GetDescriptor(effect_uuid_t *uuid, +int VisualizerLib_GetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) { if (pDescriptor == NULL || uuid == NULL){ diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp index a242846..6549ce6 100644 --- a/media/libmedia/AudioEffect.cpp +++ b/media/libmedia/AudioEffect.cpp @@ -412,7 +412,8 @@ status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descripto return af->queryEffect(index, descriptor); } -status_t AudioEffect::getEffectDescriptor(effect_uuid_t *uuid, effect_descriptor_t *descriptor) +status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid, + effect_descriptor_t *descriptor) /*const*/ { const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index c96bc76..b74b3e3 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -293,7 +293,6 @@ status_t AudioRecord::start() return WOULD_BLOCK; } } - t->mLock.lock(); } AutoMutex lock(mLock); @@ -334,10 +333,6 @@ status_t AudioRecord::start() } } - if (t != 0) { - t->mLock.unlock(); - } - return ret; } @@ -347,10 +342,6 @@ status_t AudioRecord::stop() ALOGV("stop"); - if (t != 0) { - t->mLock.lock(); - } - AutoMutex lock(mLock); if (mActive == 1) { mActive = 0; @@ -367,10 +358,6 @@ status_t AudioRecord::stop() } } - if (t != 0) { - t->mLock.unlock(); - } - return NO_ERROR; } diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 110a294..ec4c044 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -121,7 +121,8 @@ status_t AudioSystem::getMasterMute(bool* mute) return NO_ERROR; } -status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value, int output) +status_t AudioSystem::setStreamVolume(audio_stream_type_t stream, float value, + audio_io_handle_t output) { if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE; const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); @@ -139,7 +140,8 @@ status_t AudioSystem::setStreamMute(audio_stream_type_t stream, bool mute) return NO_ERROR; } -status_t AudioSystem::getStreamVolume(audio_stream_type_t stream, float* volume, int output) +status_t AudioSystem::getStreamVolume(audio_stream_type_t stream, float* volume, + audio_io_handle_t output) { if (uint32_t(stream) >= AUDIO_STREAM_CNT) return BAD_VALUE; const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); @@ -402,7 +404,8 @@ void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) { ALOGW("AudioFlinger server died!"); } -void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, int ioHandle, void *param2) { +void AudioSystem::AudioFlingerClient::ioConfigChanged(int event, audio_io_handle_t ioHandle, + void *param2) { ALOGV("ioConfigChanged() event %d", event); OutputDescriptor *desc; audio_stream_type_t stream; diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 8c33f41..087d7b2 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -345,7 +345,6 @@ void AudioTrack::start() return; } } - t->mLock.lock(); } AutoMutex lock(mLock); @@ -396,9 +395,6 @@ void AudioTrack::start() } } - if (t != 0) { - t->mLock.unlock(); - } } void AudioTrack::stop() @@ -406,9 +402,6 @@ void AudioTrack::stop() sp<AudioTrackThread> t = mAudioTrackThread; ALOGV("stop %p", this); - if (t != 0) { - t->mLock.lock(); - } AutoMutex lock(mLock); if (mActive) { @@ -434,9 +427,6 @@ void AudioTrack::stop() } } - if (t != 0) { - t->mLock.unlock(); - } } bool AudioTrack::stopped() const @@ -506,7 +496,7 @@ status_t AudioTrack::setVolume(float left, float right) return NO_ERROR; } -void AudioTrack::getVolume(float* left, float* right) +void AudioTrack::getVolume(float* left, float* right) const { if (left != NULL) { *left = mVolume[LEFT]; @@ -531,7 +521,7 @@ status_t AudioTrack::setAuxEffectSendLevel(float level) return NO_ERROR; } -void AudioTrack::getAuxEffectSendLevel(float* level) +void AudioTrack::getAuxEffectSendLevel(float* level) const { if (level != NULL) { *level = mSendLevel; @@ -553,7 +543,7 @@ status_t AudioTrack::setSampleRate(int rate) return NO_ERROR; } -uint32_t AudioTrack::getSampleRate() +uint32_t AudioTrack::getSampleRate() const { AutoMutex lock(mLock); return mCblk->sampleRate; @@ -601,7 +591,7 @@ status_t AudioTrack::setLoop_l(uint32_t loopStart, uint32_t loopEnd, int loopCou return NO_ERROR; } -status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) +status_t AudioTrack::getLoop(uint32_t *loopStart, uint32_t *loopEnd, int *loopCount) const { AutoMutex lock(mLock); if (loopStart != NULL) { @@ -631,7 +621,7 @@ status_t AudioTrack::setMarkerPosition(uint32_t marker) return NO_ERROR; } -status_t AudioTrack::getMarkerPosition(uint32_t *marker) +status_t AudioTrack::getMarkerPosition(uint32_t *marker) const { if (marker == NULL) return BAD_VALUE; @@ -652,7 +642,7 @@ status_t AudioTrack::setPositionUpdatePeriod(uint32_t updatePeriod) return NO_ERROR; } -status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) +status_t AudioTrack::getPositionUpdatePeriod(uint32_t *updatePeriod) const { if (updatePeriod == NULL) return BAD_VALUE; @@ -712,7 +702,7 @@ audio_io_handle_t AudioTrack::getOutput_l() mCblk->sampleRate, mFormat, mChannelMask, (audio_policy_output_flags_t)mFlags); } -int AudioTrack::getSessionId() +int AudioTrack::getSessionId() const { return mSessionId; } diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp index fc5520f..c3252e7 100644 --- a/media/libmedia/IAudioFlinger.cpp +++ b/media/libmedia/IAudioFlinger.cpp @@ -89,7 +89,7 @@ public: int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, - int output, + audio_io_handle_t output, int *sessionId, status_t *status) { @@ -104,7 +104,7 @@ public: data.writeInt32(frameCount); data.writeInt32(flags); data.writeStrongBinder(sharedBuffer->asBinder()); - data.writeInt32(output); + data.writeInt32((int32_t) output); int lSessionId = 0; if (sessionId != NULL) { lSessionId = *sessionId; @@ -129,7 +129,7 @@ public: virtual sp<IAudioRecord> openRecord( pid_t pid, - int input, + audio_io_handle_t input, uint32_t sampleRate, audio_format_t format, uint32_t channelMask, @@ -142,7 +142,7 @@ public: sp<IAudioRecord> record; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32(pid); - data.writeInt32(input); + data.writeInt32((int32_t) input); data.writeInt32(sampleRate); data.writeInt32(format); data.writeInt32(channelMask); @@ -170,47 +170,47 @@ public: return record; } - virtual uint32_t sampleRate(int output) const + virtual uint32_t sampleRate(audio_io_handle_t output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(SAMPLE_RATE, data, &reply); return reply.readInt32(); } - virtual int channelCount(int output) const + virtual int channelCount(audio_io_handle_t output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(CHANNEL_COUNT, data, &reply); return reply.readInt32(); } - virtual audio_format_t format(int output) const + virtual audio_format_t format(audio_io_handle_t output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(FORMAT, data, &reply); return (audio_format_t) reply.readInt32(); } - virtual size_t frameCount(int output) const + virtual size_t frameCount(audio_io_handle_t output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(FRAME_COUNT, data, &reply); return reply.readInt32(); } - virtual uint32_t latency(int output) const + virtual uint32_t latency(audio_io_handle_t output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(LATENCY, data, &reply); return reply.readInt32(); } @@ -249,13 +249,14 @@ public: return reply.readInt32(); } - virtual status_t setStreamVolume(audio_stream_type_t stream, float value, int output) + virtual status_t setStreamVolume(audio_stream_type_t stream, float value, + audio_io_handle_t output) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32((int32_t) stream); data.writeFloat(value); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(SET_STREAM_VOLUME, data, &reply); return reply.readInt32(); } @@ -270,12 +271,12 @@ public: return reply.readInt32(); } - virtual float streamVolume(audio_stream_type_t stream, int output) const + virtual float streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32((int32_t) stream); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(STREAM_VOLUME, data, &reply); return reply.readFloat(); } @@ -315,21 +316,21 @@ public: return reply.readInt32(); } - virtual status_t setParameters(int ioHandle, const String8& keyValuePairs) + virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(ioHandle); + data.writeInt32((int32_t) ioHandle); data.writeString8(keyValuePairs); remote()->transact(SET_PARAMETERS, data, &reply); return reply.readInt32(); } - virtual String8 getParameters(int ioHandle, const String8& keys) + virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(ioHandle); + data.writeInt32((int32_t) ioHandle); data.writeString8(keys); remote()->transact(GET_PARAMETERS, data, &reply); return reply.readString8(); @@ -343,7 +344,7 @@ public: remote()->transact(REGISTER_CLIENT, data, &reply); } - virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) + virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); @@ -354,7 +355,7 @@ public: return reply.readInt32(); } - virtual int openOutput(uint32_t *pDevices, + virtual audio_io_handle_t openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, @@ -376,8 +377,8 @@ public: data.writeInt32(latency); data.writeInt32(flags); remote()->transact(OPEN_OUTPUT, data, &reply); - int output = reply.readInt32(); - ALOGV("openOutput() returned output, %p", output); + audio_io_handle_t output = (audio_io_handle_t) reply.readInt32(); + ALOGV("openOutput() returned output, %d", output); devices = reply.readInt32(); if (pDevices) *pDevices = devices; samplingRate = reply.readInt32(); @@ -391,44 +392,45 @@ public: return output; } - virtual int openDuplicateOutput(int output1, int output2) + virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, + audio_io_handle_t output2) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output1); - data.writeInt32(output2); + data.writeInt32((int32_t) output1); + data.writeInt32((int32_t) output2); remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply); - return reply.readInt32(); + return (audio_io_handle_t) reply.readInt32(); } - virtual status_t closeOutput(int output) + virtual status_t closeOutput(audio_io_handle_t output) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(CLOSE_OUTPUT, data, &reply); return reply.readInt32(); } - virtual status_t suspendOutput(int output) + virtual status_t suspendOutput(audio_io_handle_t output) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(SUSPEND_OUTPUT, data, &reply); return reply.readInt32(); } - virtual status_t restoreOutput(int output) + virtual status_t restoreOutput(audio_io_handle_t output) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(RESTORE_OUTPUT, data, &reply); return reply.readInt32(); } - virtual int openInput(uint32_t *pDevices, + virtual audio_io_handle_t openInput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, @@ -447,7 +449,7 @@ public: data.writeInt32(channels); data.writeInt32((int32_t) acoustics); remote()->transact(OPEN_INPUT, data, &reply); - int input = reply.readInt32(); + audio_io_handle_t input = (audio_io_handle_t) reply.readInt32(); devices = reply.readInt32(); if (pDevices) *pDevices = devices; samplingRate = reply.readInt32(); @@ -468,12 +470,12 @@ public: return reply.readInt32(); } - virtual status_t setStreamOutput(audio_stream_type_t stream, int output) + virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32((int32_t) stream); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(SET_STREAM_OUTPUT, data, &reply); return reply.readInt32(); } @@ -487,11 +489,12 @@ public: return reply.readInt32(); } - virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) + virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, + audio_io_handle_t output) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(output); + data.writeInt32((int32_t) output); remote()->transact(GET_RENDER_POSITION, data, &reply); status_t status = reply.readInt32(); if (status == NO_ERROR) { @@ -507,11 +510,11 @@ public: return status; } - virtual unsigned int getInputFramesLost(int ioHandle) + virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); - data.writeInt32(ioHandle); + data.writeInt32((int32_t) ioHandle); remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply); return reply.readInt32(); } @@ -544,7 +547,7 @@ public: remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply); } - virtual status_t queryNumberEffects(uint32_t *numEffects) + virtual status_t queryNumberEffects(uint32_t *numEffects) const { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); @@ -562,7 +565,7 @@ public: return NO_ERROR; } - virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) + virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const { if (pDescriptor == NULL) { return BAD_VALUE; @@ -582,7 +585,8 @@ public: return NO_ERROR; } - virtual status_t getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *pDescriptor) + virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid, + effect_descriptor_t *pDescriptor) const { if (pUuid == NULL || pDescriptor == NULL) { return BAD_VALUE; @@ -606,7 +610,7 @@ public: effect_descriptor_t *pDesc, const sp<IEffectClient>& client, int32_t priority, - int output, + audio_io_handle_t output, int sessionId, status_t *status, int *id, @@ -627,7 +631,7 @@ public: data.write(pDesc, sizeof(effect_descriptor_t)); data.writeStrongBinder(client->asBinder()); data.writeInt32(priority); - data.writeInt32(output); + data.writeInt32((int32_t) output); data.writeInt32(sessionId); status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply); @@ -653,13 +657,14 @@ public: return effect; } - virtual status_t moveEffects(int session, int srcOutput, int dstOutput) + virtual status_t moveEffects(int session, audio_io_handle_t srcOutput, + audio_io_handle_t dstOutput) { Parcel data, reply; data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor()); data.writeInt32(session); - data.writeInt32(srcOutput); - data.writeInt32(dstOutput); + data.writeInt32((int32_t) srcOutput); + data.writeInt32((int32_t) dstOutput); remote()->transact(MOVE_EFFECTS, data, &reply); return reply.readInt32(); } @@ -683,7 +688,7 @@ status_t BnAudioFlinger::onTransact( size_t bufferCount = data.readInt32(); uint32_t flags = data.readInt32(); sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder()); - int output = data.readInt32(); + audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); int sessionId = data.readInt32(); status_t status; sp<IAudioTrack> track = createTrack(pid, @@ -697,7 +702,7 @@ status_t BnAudioFlinger::onTransact( case OPEN_RECORD: { CHECK_INTERFACE(IAudioFlinger, data, reply); pid_t pid = data.readInt32(); - int input = data.readInt32(); + audio_io_handle_t input = (audio_io_handle_t) data.readInt32(); uint32_t sampleRate = data.readInt32(); audio_format_t format = (audio_format_t) data.readInt32(); int channelCount = data.readInt32(); @@ -714,27 +719,27 @@ status_t BnAudioFlinger::onTransact( } break; case SAMPLE_RATE: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( sampleRate(data.readInt32()) ); + reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) ); return NO_ERROR; } break; case CHANNEL_COUNT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( channelCount(data.readInt32()) ); + reply->writeInt32( channelCount((audio_io_handle_t) data.readInt32()) ); return NO_ERROR; } break; case FORMAT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( format(data.readInt32()) ); + reply->writeInt32( format((audio_io_handle_t) data.readInt32()) ); return NO_ERROR; } break; case FRAME_COUNT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( frameCount(data.readInt32()) ); + reply->writeInt32( frameCount((audio_io_handle_t) data.readInt32()) ); return NO_ERROR; } break; case LATENCY: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32( latency(data.readInt32()) ); + reply->writeInt32( latency((audio_io_handle_t) data.readInt32()) ); return NO_ERROR; } break; case SET_MASTER_VOLUME: { @@ -761,7 +766,7 @@ status_t BnAudioFlinger::onTransact( CHECK_INTERFACE(IAudioFlinger, data, reply); int stream = data.readInt32(); float volume = data.readFloat(); - int output = data.readInt32(); + audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) ); return NO_ERROR; } break; @@ -803,14 +808,14 @@ status_t BnAudioFlinger::onTransact( } break; case SET_PARAMETERS: { CHECK_INTERFACE(IAudioFlinger, data, reply); - int ioHandle = data.readInt32(); + audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); String8 keyValuePairs(data.readString8()); reply->writeInt32(setParameters(ioHandle, keyValuePairs)); return NO_ERROR; } break; case GET_PARAMETERS: { CHECK_INTERFACE(IAudioFlinger, data, reply); - int ioHandle = data.readInt32(); + audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); String8 keys(data.readString8()); reply->writeString8(getParameters(ioHandle, keys)); return NO_ERROR; @@ -838,14 +843,14 @@ status_t BnAudioFlinger::onTransact( uint32_t channels = data.readInt32(); uint32_t latency = data.readInt32(); uint32_t flags = data.readInt32(); - int output = openOutput(&devices, + audio_io_handle_t output = openOutput(&devices, &samplingRate, &format, &channels, &latency, flags); ALOGV("OPEN_OUTPUT output, %p", output); - reply->writeInt32(output); + reply->writeInt32((int32_t) output); reply->writeInt32(devices); reply->writeInt32(samplingRate); reply->writeInt32(format); @@ -855,24 +860,24 @@ status_t BnAudioFlinger::onTransact( } break; case OPEN_DUPLICATE_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - int output1 = data.readInt32(); - int output2 = data.readInt32(); - reply->writeInt32(openDuplicateOutput(output1, output2)); + audio_io_handle_t output1 = (audio_io_handle_t) data.readInt32(); + audio_io_handle_t output2 = (audio_io_handle_t) data.readInt32(); + reply->writeInt32((int32_t) openDuplicateOutput(output1, output2)); return NO_ERROR; } break; case CLOSE_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(closeOutput(data.readInt32())); + reply->writeInt32(closeOutput((audio_io_handle_t) data.readInt32())); return NO_ERROR; } break; case SUSPEND_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(suspendOutput(data.readInt32())); + reply->writeInt32(suspendOutput((audio_io_handle_t) data.readInt32())); return NO_ERROR; } break; case RESTORE_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(restoreOutput(data.readInt32())); + reply->writeInt32(restoreOutput((audio_io_handle_t) data.readInt32())); return NO_ERROR; } break; case OPEN_INPUT: { @@ -883,12 +888,12 @@ status_t BnAudioFlinger::onTransact( uint32_t channels = data.readInt32(); audio_in_acoustics_t acoustics = (audio_in_acoustics_t) data.readInt32(); - int input = openInput(&devices, + audio_io_handle_t input = openInput(&devices, &samplingRate, &format, &channels, acoustics); - reply->writeInt32(input); + reply->writeInt32((int32_t) input); reply->writeInt32(devices); reply->writeInt32(samplingRate); reply->writeInt32(format); @@ -897,13 +902,13 @@ status_t BnAudioFlinger::onTransact( } break; case CLOSE_INPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); - reply->writeInt32(closeInput(data.readInt32())); + reply->writeInt32(closeInput((audio_io_handle_t) data.readInt32())); return NO_ERROR; } break; case SET_STREAM_OUTPUT: { CHECK_INTERFACE(IAudioFlinger, data, reply); uint32_t stream = data.readInt32(); - int output = data.readInt32(); + audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); reply->writeInt32(setStreamOutput((audio_stream_type_t) stream, output)); return NO_ERROR; } break; @@ -915,7 +920,7 @@ status_t BnAudioFlinger::onTransact( } break; case GET_RENDER_POSITION: { CHECK_INTERFACE(IAudioFlinger, data, reply); - int output = data.readInt32(); + audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); uint32_t halFrames; uint32_t dspFrames; status_t status = getRenderPosition(&halFrames, &dspFrames, output); @@ -928,7 +933,7 @@ status_t BnAudioFlinger::onTransact( } case GET_INPUT_FRAMES_LOST: { CHECK_INTERFACE(IAudioFlinger, data, reply); - int ioHandle = data.readInt32(); + audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); reply->writeInt32(getInputFramesLost(ioHandle)); return NO_ERROR; } break; @@ -988,7 +993,7 @@ status_t BnAudioFlinger::onTransact( data.read(&desc, sizeof(effect_descriptor_t)); sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder()); int32_t priority = data.readInt32(); - int output = data.readInt32(); + audio_io_handle_t output = (audio_io_handle_t) data.readInt32(); int sessionId = data.readInt32(); status_t status; int id; @@ -1005,8 +1010,8 @@ status_t BnAudioFlinger::onTransact( case MOVE_EFFECTS: { CHECK_INTERFACE(IAudioFlinger, data, reply); int session = data.readInt32(); - int srcOutput = data.readInt32(); - int dstOutput = data.readInt32(); + audio_io_handle_t srcOutput = (audio_io_handle_t) data.readInt32(); + audio_io_handle_t dstOutput = (audio_io_handle_t) data.readInt32(); reply->writeInt32(moveEffects(session, srcOutput, dstOutput)); return NO_ERROR; } break; diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp index 9458bc0..ce28b33 100644 --- a/media/libmedia/IAudioFlingerClient.cpp +++ b/media/libmedia/IAudioFlingerClient.cpp @@ -39,12 +39,12 @@ public: { } - void ioConfigChanged(int event, int ioHandle, void *param2) + void ioConfigChanged(int event, audio_io_handle_t ioHandle, void *param2) { Parcel data, reply; data.writeInterfaceToken(IAudioFlingerClient::getInterfaceDescriptor()); data.writeInt32(event); - data.writeInt32(ioHandle); + data.writeInt32((int32_t) ioHandle); if (event == AudioSystem::STREAM_CONFIG_CHANGED) { uint32_t stream = *(uint32_t *)param2; ALOGV("ioConfigChanged stream %d", stream); @@ -72,7 +72,7 @@ status_t BnAudioFlingerClient::onTransact( case IO_CONFIG_CHANGED: { CHECK_INTERFACE(IAudioFlingerClient, data, reply); int event = data.readInt32(); - int ioHandle = data.readInt32(); + audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32(); void *param2 = NULL; AudioSystem::OutputDescriptor desc; uint32_t stream; diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp index 068660b..c7a8b32 100755 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -70,6 +70,10 @@ public: status_t dump(int fd, const Vector<String16>& args) const; private: + enum { + kMaxCttsOffsetTimeUs = 1000000LL, // 1 second + }; + MPEG4Writer *mOwner; sp<MetaData> mMeta; sp<MediaSource> mSource; @@ -139,9 +143,10 @@ private: uint32_t sampleCount; int32_t sampleDuration; // time scale based }; - bool mHasNegativeCttsDeltaDuration; size_t mNumCttsTableEntries; List<CttsTableEntry> mCttsTableEntries; + int64_t mMinCttsOffsetTimeUs; + int64_t mMaxCttsOffsetTimeUs; // Sequence parameter set or picture parameter set struct AVCParamSet { @@ -172,6 +177,8 @@ private: // Update the audio track's drift information. void updateDriftTime(const sp<MetaData>& meta); + int32_t getStartTimeOffsetScaledTime() const; + static void *ThreadWrapper(void *me); status_t threadEntry(); @@ -1186,9 +1193,6 @@ void MPEG4Writer::Track::addOneCttsTableEntry( if (mIsAudio) { return; } - if (duration < 0 && !mHasNegativeCttsDeltaDuration) { - mHasNegativeCttsDeltaDuration = true; - } CttsTableEntry cttsEntry(sampleCount, duration); mCttsTableEntries.push_back(cttsEntry); ++mNumCttsTableEntries; @@ -1509,7 +1513,6 @@ status_t MPEG4Writer::Track::start(MetaData *params) { mMdatSizeBytes = 0; mMaxChunkDurationUs = 0; - mHasNegativeCttsDeltaDuration = false; pthread_create(&mThread, &attr, ThreadWrapper, this); pthread_attr_destroy(&attr); @@ -1833,29 +1836,18 @@ status_t MPEG4Writer::Track::threadEntry() { int32_t nChunks = 0; int32_t nZeroLengthFrames = 0; int64_t lastTimestampUs = 0; // Previous sample time stamp - int64_t lastCttsTimeUs = 0; // Previous sample time stamp int64_t lastDurationUs = 0; // Between the previous two samples int64_t currDurationTicks = 0; // Timescale based ticks int64_t lastDurationTicks = 0; // Timescale based ticks int32_t sampleCount = 1; // Sample count in the current stts table entry - int64_t currCttsDurTicks = 0; // Timescale based ticks - int64_t lastCttsDurTicks = 0; // Timescale based ticks - int32_t cttsSampleCount = 1; // Sample count in the current ctts table entry - uint32_t previousSampleSize = 0; // Size of the previous sample + uint32_t previousSampleSize = 0; // Size of the previous sample int64_t previousPausedDurationUs = 0; int64_t timestampUs = 0; - int64_t cttsDeltaTimeUs = 0; - bool hasBFrames = false; + int64_t cttsOffsetTimeUs = 0; + int64_t currCttsOffsetTimeTicks = 0; // Timescale based ticks + int64_t lastCttsOffsetTimeTicks = -1; // Timescale based ticks + int32_t cttsSampleCount = 1; // Sample count in the current ctts table entry -#if 1 - // XXX: Samsung's video encoder's output buffer timestamp - // is not correct. see bug 4724339 - char value[PROPERTY_VALUE_MAX]; - if (property_get("rw.media.record.hasb", value, NULL) && - (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) { - hasBFrames = true; - } -#endif if (mIsAudio) { prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0); } else { @@ -1972,23 +1964,48 @@ status_t MPEG4Writer::Track::threadEntry() { timestampUs -= previousPausedDurationUs; CHECK(timestampUs >= 0); - if (!mIsAudio && hasBFrames) { + if (!mIsAudio) { /* * Composition time: timestampUs * Decoding time: decodingTimeUs - * Composition time delta = composition time - decoding time - * - * We save picture decoding time stamp delta in stts table entries, - * and composition time delta duration in ctts table entries. + * Composition time offset = composition time - decoding time */ int64_t decodingTimeUs; CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs)); decodingTimeUs -= previousPausedDurationUs; - int64_t timeUs = decodingTimeUs; - cttsDeltaTimeUs = timestampUs - decodingTimeUs; + cttsOffsetTimeUs = + timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs; + CHECK(cttsOffsetTimeUs >= 0); timestampUs = decodingTimeUs; - ALOGV("decoding time: %lld and ctts delta time: %lld", - timestampUs, cttsDeltaTimeUs); + ALOGV("decoding time: %lld and ctts offset time: %lld", + timestampUs, cttsOffsetTimeUs); + + // Update ctts box table if necessary + currCttsOffsetTimeTicks = + (cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL; + CHECK(currCttsOffsetTimeTicks <= 0x7FFFFFFFLL); +#if 0 + // FIXME: + // Optimize to reduce the number of ctts table entries. + // Also, make sure that the very first ctts table entry contains + // only a single sample. +#else + addOneCttsTableEntry(1, currCttsOffsetTimeTicks); +#endif + lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks; + + // Update ctts time offset range + if (mNumSamples == 0) { + mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks; + mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks; + } else { + if (currCttsOffsetTimeTicks > mMaxCttsOffsetTimeUs) { + mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks; + } else if (currCttsOffsetTimeTicks < mMinCttsOffsetTimeUs) { + mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks; + } + } + } if (mIsRealTimeRecording) { @@ -2012,6 +2029,7 @@ status_t MPEG4Writer::Track::threadEntry() { currDurationTicks = ((timestampUs * mTimeScale + 500000LL) / 1000000LL - (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL); + CHECK(currDurationTicks >= 0); mSampleSizes.push_back(sampleSize); ++mNumSamples; @@ -2020,25 +2038,12 @@ status_t MPEG4Writer::Track::threadEntry() { // Force the first sample to have its own stts entry so that // we can adjust its value later to maintain the A/V sync. if (mNumSamples == 3 || currDurationTicks != lastDurationTicks) { - ALOGV("%s lastDurationUs: %lld us, currDurationTicks: %lld us", - mIsAudio? "Audio": "Video", lastDurationUs, currDurationTicks); addOneSttsTableEntry(sampleCount, lastDurationTicks); sampleCount = 1; } else { ++sampleCount; } - if (!mIsAudio) { - currCttsDurTicks = - ((cttsDeltaTimeUs * mTimeScale + 500000LL) / 1000000LL - - (lastCttsTimeUs * mTimeScale + 500000LL) / 1000000LL); - if (currCttsDurTicks != lastCttsDurTicks) { - addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks); - cttsSampleCount = 1; - } else { - ++cttsSampleCount; - } - } } if (mSamplesHaveSameSize) { if (mNumSamples >= 2 && previousSampleSize != sampleSize) { @@ -2052,11 +2057,6 @@ status_t MPEG4Writer::Track::threadEntry() { lastDurationTicks = currDurationTicks; lastTimestampUs = timestampUs; - if (!mIsAudio) { - lastCttsDurTicks = currCttsDurTicks; - lastCttsTimeUs = cttsDeltaTimeUs; - } - if (isSync != 0) { addOneStssTableEntry(mNumSamples); } @@ -2125,7 +2125,6 @@ status_t MPEG4Writer::Track::threadEntry() { if (mNumSamples == 1) { lastDurationUs = 0; // A single sample's duration lastDurationTicks = 0; - lastCttsDurTicks = 0; } else { ++sampleCount; // Count for the last sample ++cttsSampleCount; @@ -2140,7 +2139,6 @@ status_t MPEG4Writer::Track::threadEntry() { addOneSttsTableEntry(sampleCount, lastDurationTicks); } - addOneCttsTableEntry(cttsSampleCount, lastCttsDurTicks); mTrackDurationUs += lastDurationUs; mReachedEOS = true; @@ -2690,23 +2688,26 @@ void MPEG4Writer::Track::writePaspBox() { mOwner->endBox(); // pasp } -void MPEG4Writer::Track::writeSttsBox() { - mOwner->beginBox("stts"); - mOwner->writeInt32(0); // version=0, flags=0 - mOwner->writeInt32(mNumSttsTableEntries); - - // Compensate for small start time difference from different media tracks +int32_t MPEG4Writer::Track::getStartTimeOffsetScaledTime() const { int64_t trackStartTimeOffsetUs = 0; int64_t moovStartTimeUs = mOwner->getStartTimestampUs(); if (mStartTimestampUs != moovStartTimeUs) { CHECK(mStartTimestampUs > moovStartTimeUs); trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs; } + return (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL; +} + +void MPEG4Writer::Track::writeSttsBox() { + mOwner->beginBox("stts"); + mOwner->writeInt32(0); // version=0, flags=0 + mOwner->writeInt32(mNumSttsTableEntries); + + // Compensate for small start time difference from different media tracks List<SttsTableEntry>::iterator it = mSttsTableEntries.begin(); CHECK(it != mSttsTableEntries.end() && it->sampleCount == 1); mOwner->writeInt32(it->sampleCount); - int32_t dur = (trackStartTimeOffsetUs * mTimeScale + 500000LL) / 1000000LL; - mOwner->writeInt32(dur + it->sampleDuration); + mOwner->writeInt32(getStartTimeOffsetScaledTime() + it->sampleDuration); int64_t totalCount = 1; while (++it != mSttsTableEntries.end()) { @@ -2723,6 +2724,11 @@ void MPEG4Writer::Track::writeCttsBox() { return; } + // There is no B frame at all + if (mMinCttsOffsetTimeUs == mMaxCttsOffsetTimeUs) { + return; + } + // Do not write ctts box when there is no need to have it. if ((mNumCttsTableEntries == 1 && mCttsTableEntries.begin()->sampleDuration == 0) || @@ -2730,21 +2736,26 @@ void MPEG4Writer::Track::writeCttsBox() { return; } - ALOGV("ctts box has %d entries", mNumCttsTableEntries); + ALOGD("ctts box has %d entries with range [%lld, %lld]", + mNumCttsTableEntries, mMinCttsOffsetTimeUs, mMaxCttsOffsetTimeUs); mOwner->beginBox("ctts"); - if (mHasNegativeCttsDeltaDuration) { - mOwner->writeInt32(0x00010000); // version=1, flags=0 - } else { - mOwner->writeInt32(0); // version=0, flags=0 - } + // Version 1 allows to use negative offset time value, but + // we are sticking to version 0 for now. + mOwner->writeInt32(0); // version=0, flags=0 mOwner->writeInt32(mNumCttsTableEntries); - int64_t totalCount = 0; - for (List<CttsTableEntry>::iterator it = mCttsTableEntries.begin(); - it != mCttsTableEntries.end(); ++it) { + // Compensate for small start time difference from different media tracks + List<CttsTableEntry>::iterator it = mCttsTableEntries.begin(); + CHECK(it != mCttsTableEntries.end() && it->sampleCount == 1); + mOwner->writeInt32(it->sampleCount); + mOwner->writeInt32(getStartTimeOffsetScaledTime() + + it->sampleDuration - mMinCttsOffsetTimeUs); + + int64_t totalCount = 1; + while (++it != mCttsTableEntries.end()) { mOwner->writeInt32(it->sampleCount); - mOwner->writeInt32(it->sampleDuration); + mOwner->writeInt32(it->sampleDuration - mMinCttsOffsetTimeUs); totalCount += it->sampleCount; } CHECK(totalCount == mNumSamples); diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 381320b..470f750 100755 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -2187,7 +2187,7 @@ error: } } -int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) { +int64_t OMXCodec::getDecodingTimeUs() { CHECK(mIsEncoder && mIsVideo); if (mDecodingTimeList.empty()) { @@ -2199,12 +2199,7 @@ int64_t OMXCodec::retrieveDecodingTimeUs(bool isCodecSpecific) { List<int64_t>::iterator it = mDecodingTimeList.begin(); int64_t timeUs = *it; - - // If the output buffer is codec specific configuration, - // do not remove the decoding time from the list. - if (!isCodecSpecific) { - mDecodingTimeList.erase(it); - } + mDecodingTimeList.erase(it); return timeUs; } @@ -2384,7 +2379,7 @@ void OMXCodec::on_message(const omx_message &msg) { } if (mIsEncoder && mIsVideo) { - int64_t decodingTimeUs = retrieveDecodingTimeUs(isCodecSpecific); + int64_t decodingTimeUs = isCodecSpecific? 0: getDecodingTimeUs(); buffer->meta_data()->setInt64(kKeyDecodingTime, decodingTimeUs); } diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index f71ba0a..93c91fb 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -245,7 +245,6 @@ AudioFlinger::~AudioFlinger() audio_hw_device_t *dev = mAudioHwDevs[i]; audio_hw_device_close(dev); } - mAudioHwDevs.clear(); } audio_hw_device_t* AudioFlinger::findSuitableHwDev_l(uint32_t devices) @@ -371,6 +370,18 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args) return NO_ERROR; } +sp<AudioFlinger::Client> AudioFlinger::registerPid_l(pid_t pid) +{ + // If pid is already in the mClients wp<> map, then use that entry + // (for which promote() is always != 0), otherwise create a new entry and Client. + sp<Client> client = mClients.valueFor(pid).promote(); + if (client == 0) { + client = new Client(this, pid); + mClients.add(pid, client); + } + + return client; +} // IAudioFlinger interface @@ -384,14 +395,13 @@ sp<IAudioTrack> AudioFlinger::createTrack( int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, - int output, + audio_io_handle_t output, int *sessionId, status_t *status) { sp<PlaybackThread::Track> track; sp<TrackHandle> trackHandle; sp<Client> client; - wp<Client> wclient; status_t lStatus; int lSessionId; @@ -413,14 +423,7 @@ sp<IAudioTrack> AudioFlinger::createTrack( goto Exit; } - wclient = mClients.valueFor(pid); - - if (wclient != NULL) { - client = wclient.promote(); - } else { - client = new Client(this, pid); - mClients.add(pid, client); - } + client = registerPid_l(pid); ALOGV("createTrack() sessionId: %d", (sessionId == NULL) ? -2 : *sessionId); if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) { @@ -477,7 +480,7 @@ Exit: return trackHandle; } -uint32_t AudioFlinger::sampleRate(int output) const +uint32_t AudioFlinger::sampleRate(audio_io_handle_t output) const { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -488,7 +491,7 @@ uint32_t AudioFlinger::sampleRate(int output) const return thread->sampleRate(); } -int AudioFlinger::channelCount(int output) const +int AudioFlinger::channelCount(audio_io_handle_t output) const { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -499,7 +502,7 @@ int AudioFlinger::channelCount(int output) const return thread->channelCount(); } -audio_format_t AudioFlinger::format(int output) const +audio_format_t AudioFlinger::format(audio_io_handle_t output) const { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -510,7 +513,7 @@ audio_format_t AudioFlinger::format(int output) const return thread->format(); } -size_t AudioFlinger::frameCount(int output) const +size_t AudioFlinger::frameCount(audio_io_handle_t output) const { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -521,7 +524,7 @@ size_t AudioFlinger::frameCount(int output) const return thread->frameCount(); } -uint32_t AudioFlinger::latency(int output) const +uint32_t AudioFlinger::latency(audio_io_handle_t output) const { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -655,7 +658,8 @@ bool AudioFlinger::masterMute() const return masterMute_l(); } -status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, int output) +status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value, + audio_io_handle_t output) { // check calling permissions if (!settingsAllowed()) { @@ -710,7 +714,7 @@ status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted) return NO_ERROR; } -float AudioFlinger::streamVolume(audio_stream_type_t stream, int output) const +float AudioFlinger::streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const { if (uint32_t(stream) >= AUDIO_STREAM_CNT) { return 0.0f; @@ -740,7 +744,7 @@ bool AudioFlinger::streamMute(audio_stream_type_t stream) const return mStreamTypes[stream].mute; } -status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs) +status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs) { status_t result; @@ -809,14 +813,13 @@ status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs) } } } - if (thread != NULL) { - result = thread->setParameters(keyValuePairs); - return result; + if (thread != 0) { + return thread->setParameters(keyValuePairs); } return BAD_VALUE; } -String8 AudioFlinger::getParameters(int ioHandle, const String8& keys) +String8 AudioFlinger::getParameters(audio_io_handle_t ioHandle, const String8& keys) const { // ALOGV("getParameters() io %d, keys %s, tid %d, calling tid %d", // ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid()); @@ -846,7 +849,7 @@ String8 AudioFlinger::getParameters(int ioHandle, const String8& keys) return String8(""); } -size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) +size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const { status_t ret = initCheck(); if (ret != NO_ERROR) { @@ -856,7 +859,7 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form return mPrimaryHardwareDev->get_input_buffer_size(mPrimaryHardwareDev, sampleRate, format, channelCount); } -unsigned int AudioFlinger::getInputFramesLost(int ioHandle) +unsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const { if (ioHandle == 0) { return 0; @@ -891,7 +894,8 @@ status_t AudioFlinger::setVoiceVolume(float value) return ret; } -status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output) +status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, + audio_io_handle_t output) const { status_t status; @@ -910,7 +914,7 @@ void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) Mutex::Autolock _l(mLock); - int pid = IPCThreadState::self()->getCallingPid(); + pid_t pid = IPCThreadState::self()->getCallingPid(); if (mNotificationClients.indexOfKey(pid) < 0) { sp<NotificationClient> notificationClient = new NotificationClient(this, client, @@ -966,7 +970,7 @@ void AudioFlinger::removeNotificationClient(pid_t pid) } // audioConfigChanged_l() must be called with AudioFlinger::mLock held -void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) +void AudioFlinger::audioConfigChanged_l(int event, audio_io_handle_t ioHandle, void *param2) { size_t size = mNotificationClients.size(); for (size_t i = 0; i < size; i++) { @@ -985,8 +989,8 @@ void AudioFlinger::removeClient_l(pid_t pid) // ---------------------------------------------------------------------------- -AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device, - type_t type) +AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, + uint32_t device, type_t type) : Thread(false), mType(type), mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), @@ -1027,26 +1031,6 @@ void AudioFlinger::ThreadBase::exit() requestExitAndWait(); } -uint32_t AudioFlinger::ThreadBase::sampleRate() const -{ - return mSampleRate; -} - -int AudioFlinger::ThreadBase::channelCount() const -{ - return (int)mChannelCount; -} - -audio_format_t AudioFlinger::ThreadBase::format() const -{ - return mFormat; -} - -size_t AudioFlinger::ThreadBase::frameCount() const -{ - return mFrameCount; -} - status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs) { status_t status; @@ -1248,8 +1232,7 @@ void AudioFlinger::ThreadBase::setEffectSuspended( void AudioFlinger::ThreadBase::setEffectSuspended_l( const effect_uuid_t *type, bool suspend, int sessionId) { - sp<EffectChain> chain; - chain = getEffectChain_l(sessionId); + sp<EffectChain> chain = getEffectChain_l(sessionId); if (chain != 0) { if (type != NULL) { chain->setEffectSuspended_l(type, suspend); @@ -1377,7 +1360,7 @@ void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled_l(const sp<EffectModu AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, - int id, + audio_io_handle_t id, uint32_t device, type_t type) : ThreadBase(audioFlinger, id, device, type), @@ -1611,16 +1594,6 @@ status_t AudioFlinger::PlaybackThread::setMasterMute(bool muted) return NO_ERROR; } -float AudioFlinger::PlaybackThread::masterVolume() const -{ - return mMasterVolume; -} - -bool AudioFlinger::PlaybackThread::masterMute() const -{ - return mMasterMute; -} - status_t AudioFlinger::PlaybackThread::setStreamVolume(audio_stream_type_t stream, float value) { mStreamTypes[stream].volume = value; @@ -1853,7 +1826,7 @@ uint32_t AudioFlinger::PlaybackThread::activeSleepTimeUs() // ---------------------------------------------------------------------------- AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, - int id, uint32_t device, type_t type) + audio_io_handle_t id, uint32_t device, type_t type) : PlaybackThread(audioFlinger, output, id, device, type), mAudioMixer(new AudioMixer(mFrameCount, mSampleRate)), mPrevMixerStatus(MIXER_IDLE) @@ -2520,7 +2493,8 @@ uint32_t AudioFlinger::MixerThread::suspendSleepTimeUs() } // ---------------------------------------------------------------------------- -AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device) +AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, + AudioStreamOut* output, audio_io_handle_t id, uint32_t device) : PlaybackThread(audioFlinger, output, id, device, DIRECT) // mLeftVolFloat, mRightVolFloat // mLeftVolShort, mRightVolShort @@ -3002,7 +2976,7 @@ uint32_t AudioFlinger::DirectOutputThread::suspendSleepTimeUs() // ---------------------------------------------------------------------------- AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, - AudioFlinger::MixerThread* mainThread, int id) + AudioFlinger::MixerThread* mainThread, audio_io_handle_t id) : MixerThread(audioFlinger, mainThread->getOutput(), id, mainThread->device(), DUPLICATING), mWaitTimeMs(UINT_MAX) { @@ -3014,7 +2988,6 @@ AudioFlinger::DuplicatingThread::~DuplicatingThread() for (size_t i = 0; i < mOutputTracks.size(); i++) { mOutputTracks[i]->destroy(); } - mOutputTracks.clear(); } bool AudioFlinger::DuplicatingThread::threadLoop() @@ -3206,7 +3179,7 @@ void AudioFlinger::DuplicatingThread::updateWaitTime() mWaitTimeMs = UINT_MAX; for (size_t i = 0; i < mOutputTracks.size(); i++) { sp<ThreadBase> strong = mOutputTracks[i]->thread().promote(); - if (strong != NULL) { + if (strong != 0) { uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate(); if (waitTimeMs < mWaitTimeMs) { mWaitTimeMs = waitTimeMs; @@ -3259,7 +3232,6 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( // mBufferEnd mFrameCount(0), mState(IDLE), - mClientTid(-1), mFormat(format), mFlags(flags & ~SYSTEM_FLAGS_MASK), mSessionId(sessionId) @@ -3324,15 +3296,19 @@ AudioFlinger::ThreadBase::TrackBase::TrackBase( AudioFlinger::ThreadBase::TrackBase::~TrackBase() { if (mCblk != NULL) { - mCblk->~audio_track_cblk_t(); // destroy our shared-structure. - if (mClient == NULL) { + if (mClient == 0) { delete mCblk; + } else { + mCblk->~audio_track_cblk_t(); // destroy our shared-structure. } } - mCblkMemory.clear(); // and free the shared memory - if (mClient != NULL) { + mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to + if (mClient != 0) { // Client destructor must run with AudioFlinger mutex locked Mutex::Autolock _l(mClient->audioFlinger()->mLock); + // If the client's reference count drops to zero, the associated destructor + // must run with AudioFlinger lock held. Thus the explicit clear() rather than + // relying on the automatic clear() at end of scope. mClient.clear(); } } @@ -3368,23 +3344,10 @@ void AudioFlinger::ThreadBase::TrackBase::reset() { ALOGV("TrackBase::reset"); } -sp<IMemory> AudioFlinger::ThreadBase::TrackBase::getCblk() const -{ - return mCblkMemory; -} - int AudioFlinger::ThreadBase::TrackBase::sampleRate() const { return (int)mCblk->sampleRate; } -int AudioFlinger::ThreadBase::TrackBase::channelCount() const { - return (const int)mChannelCount; -} - -uint32_t AudioFlinger::ThreadBase::TrackBase::channelMask() const { - return mChannelMask; -} - void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const { audio_track_cblk_t* cblk = this->cblk(); size_t frameSize = cblk->frameSize; @@ -3486,7 +3449,7 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size) uint32_t vlr = mCblk->getVolumeLR(); snprintf(buffer, size, " %05d %05d %03u %03u 0x%08x %05u %04u %1d %1d %1d %05u %05u %05u 0x%08x 0x%08x 0x%08x 0x%08x\n", mName - AudioMixer::TRACK0, - (mClient == NULL) ? getpid() : mClient->pid(), + (mClient == 0) ? getpid() : mClient->pid(), mStreamType, mFormat, mChannelMask, @@ -3813,7 +3776,7 @@ void AudioFlinger::RecordThread::RecordTrack::stop() void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size) { snprintf(buffer, size, " %05d %03u 0x%08x %05d %04u %01d %05u %08x %08x\n", - (mClient == NULL) ? getpid() : mClient->pid(), + (mClient == 0) ? getpid() : mClient->pid(), mFormat, mChannelMask, mSessionId, @@ -4160,7 +4123,7 @@ status_t AudioFlinger::TrackHandle::onTransact( sp<IAudioRecord> AudioFlinger::openRecord( pid_t pid, - int input, + audio_io_handle_t input, uint32_t sampleRate, audio_format_t format, uint32_t channelMask, @@ -4172,7 +4135,6 @@ sp<IAudioRecord> AudioFlinger::openRecord( sp<RecordThread::RecordTrack> recordTrack; sp<RecordHandle> recordHandle; sp<Client> client; - wp<Client> wclient; status_t lStatus; RecordThread *thread; size_t inFrameCount; @@ -4193,13 +4155,7 @@ sp<IAudioRecord> AudioFlinger::openRecord( goto Exit; } - wclient = mClients.valueFor(pid); - if (wclient != NULL) { - client = wclient.promote(); - } else { - client = new Client(this, pid); - mClients.add(pid, client); - } + client = registerPid_l(pid); // If no audio session id is provided, create one here if (sessionId != NULL && *sessionId != AUDIO_SESSION_OUTPUT_MIX) { @@ -4277,7 +4233,7 @@ AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, - int id, + audio_io_handle_t id, uint32_t device) : ThreadBase(audioFlinger, id, device, RECORD), mInput(input), mTrack(NULL), mResampler(NULL), mRsmpOutBuffer(NULL), mRsmpInBuffer(NULL), @@ -4528,7 +4484,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR track = new RecordTrack(this, client, sampleRate, format, channelMask, frameCount, flags, sessionId); - if (track->getCblk() == NULL) { + if (track->getCblk() == 0) { lStatus = NO_MEMORY; goto Exit; } @@ -4631,7 +4587,6 @@ status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args) const size_t SIZE = 256; char buffer[SIZE]; String8 result; - pid_t pid = 0; snprintf(buffer, SIZE, "\nInput thread %p internals\n", this); result.append(buffer); @@ -4938,7 +4893,7 @@ audio_stream_t* AudioFlinger::RecordThread::stream() // ---------------------------------------------------------------------------- -int AudioFlinger::openOutput(uint32_t *pDevices, +audio_io_handle_t AudioFlinger::openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, @@ -4984,7 +4939,7 @@ int AudioFlinger::openOutput(uint32_t *pDevices, mHardwareStatus = AUDIO_HW_IDLE; if (outStream != NULL) { AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream); - int id = nextUniqueId(); + audio_io_handle_t id = nextUniqueId(); if ((flags & AUDIO_POLICY_OUTPUT_FLAG_DIRECT) || (format != AUDIO_FORMAT_PCM_16_BIT) || @@ -5010,7 +4965,8 @@ int AudioFlinger::openOutput(uint32_t *pDevices, return 0; } -int AudioFlinger::openDuplicateOutput(int output1, int output2) +audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1, + audio_io_handle_t output2) { Mutex::Autolock _l(mLock); MixerThread *thread1 = checkMixerThread_l(output1); @@ -5021,7 +4977,7 @@ int AudioFlinger::openDuplicateOutput(int output1, int output2) return 0; } - int id = nextUniqueId(); + audio_io_handle_t id = nextUniqueId(); DuplicatingThread *thread = new DuplicatingThread(this, thread1, id); thread->addOutputTrack(thread2); mPlaybackThreads.add(id, thread); @@ -5030,7 +4986,7 @@ int AudioFlinger::openDuplicateOutput(int output1, int output2) return id; } -status_t AudioFlinger::closeOutput(int output) +status_t AudioFlinger::closeOutput(audio_io_handle_t output) { // keep strong reference on the playback thread so that // it is not destroyed while exit() is executed @@ -5068,7 +5024,7 @@ status_t AudioFlinger::closeOutput(int output) return NO_ERROR; } -status_t AudioFlinger::suspendOutput(int output) +status_t AudioFlinger::suspendOutput(audio_io_handle_t output) { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -5083,7 +5039,7 @@ status_t AudioFlinger::suspendOutput(int output) return NO_ERROR; } -status_t AudioFlinger::restoreOutput(int output) +status_t AudioFlinger::restoreOutput(audio_io_handle_t output) { Mutex::Autolock _l(mLock); PlaybackThread *thread = checkPlaybackThread_l(output); @@ -5099,7 +5055,7 @@ status_t AudioFlinger::restoreOutput(int output) return NO_ERROR; } -int AudioFlinger::openInput(uint32_t *pDevices, +audio_io_handle_t AudioFlinger::openInput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, @@ -5155,7 +5111,7 @@ int AudioFlinger::openInput(uint32_t *pDevices, if (inStream != NULL) { AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream); - int id = nextUniqueId(); + audio_io_handle_t id = nextUniqueId(); // Start record thread // RecorThread require both input and output device indication to forward to audio // pre processing modules @@ -5182,7 +5138,7 @@ int AudioFlinger::openInput(uint32_t *pDevices, return 0; } -status_t AudioFlinger::closeInput(int input) +status_t AudioFlinger::closeInput(audio_io_handle_t input) { // keep strong reference on the record thread so that // it is not destroyed while exit() is executed @@ -5210,7 +5166,7 @@ status_t AudioFlinger::closeInput(int input) return NO_ERROR; } -status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, int output) +status_t AudioFlinger::setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output) { Mutex::Autolock _l(mLock); MixerThread *dstThread = checkMixerThread_l(output); @@ -5246,7 +5202,7 @@ int AudioFlinger::newAudioSessionId() void AudioFlinger::acquireAudioSessionId(int audioSession) { Mutex::Autolock _l(mLock); - int caller = IPCThreadState::self()->getCallingPid(); + pid_t caller = IPCThreadState::self()->getCallingPid(); ALOGV("acquiring %d from %d", audioSession, caller); int num = mAudioSessionRefs.size(); for (int i = 0; i< num; i++) { @@ -5264,7 +5220,7 @@ void AudioFlinger::acquireAudioSessionId(int audioSession) void AudioFlinger::releaseAudioSessionId(int audioSession) { Mutex::Autolock _l(mLock); - int caller = IPCThreadState::self()->getCallingPid(); + pid_t caller = IPCThreadState::self()->getCallingPid(); ALOGV("releasing %d from %d", audioSession, caller); int num = mAudioSessionRefs.size(); for (int i = 0; i< num; i++) { @@ -5348,7 +5304,7 @@ void AudioFlinger::purgeStaleEffects_l() { } // checkPlaybackThread_l() must be called with AudioFlinger::mLock held -AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(int output) const +AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const { PlaybackThread *thread = NULL; if (mPlaybackThreads.indexOfKey(output) >= 0) { @@ -5358,7 +5314,7 @@ AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(int output) co } // checkMixerThread_l() must be called with AudioFlinger::mLock held -AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(int output) const +AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const { PlaybackThread *thread = checkPlaybackThread_l(output); if (thread != NULL) { @@ -5370,7 +5326,7 @@ AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(int output) const } // checkRecordThread_l() must be called with AudioFlinger::mLock held -AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(int input) const +AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const { RecordThread *thread = NULL; if (mRecordThreads.indexOfKey(input) >= 0) { @@ -5413,19 +5369,20 @@ uint32_t AudioFlinger::primaryOutputDevice_l() // ---------------------------------------------------------------------------- -status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) +status_t AudioFlinger::queryNumberEffects(uint32_t *numEffects) const { Mutex::Autolock _l(mLock); return EffectQueryNumberEffects(numEffects); } -status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) +status_t AudioFlinger::queryEffect(uint32_t index, effect_descriptor_t *descriptor) const { Mutex::Autolock _l(mLock); return EffectQueryEffect(index, descriptor); } -status_t AudioFlinger::getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *descriptor) +status_t AudioFlinger::getEffectDescriptor(const effect_uuid_t *pUuid, + effect_descriptor_t *descriptor) const { Mutex::Autolock _l(mLock); return EffectGetDescriptor(pUuid, descriptor); @@ -5436,7 +5393,7 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid, effect_descriptor_t *pDesc, const sp<IEffectClient>& effectClient, int32_t priority, - int io, + audio_io_handle_t io, int sessionId, status_t *status, int *id, @@ -5445,10 +5402,8 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid, status_t lStatus = NO_ERROR; sp<EffectHandle> handle; effect_descriptor_t desc; - sp<Client> client; - wp<Client> wclient; - ALOGV("createEffect pid %d, client %p, priority %d, sessionId %d, io %d", + ALOGV("createEffect pid %d, effectClient %p, priority %d, sessionId %d, io %d", pid, effectClient.get(), priority, sessionId, io); if (pDesc == NULL) { @@ -5599,14 +5554,7 @@ sp<IEffect> AudioFlinger::createEffect(pid_t pid, } } - wclient = mClients.valueFor(pid); - - if (wclient != NULL) { - client = wclient.promote(); - } else { - client = new Client(this, pid); - mClients.add(pid, client); - } + sp<Client> client = registerPid_l(pid); // create effect on selected output thread handle = thread->createEffect_l(client, effectClient, priority, sessionId, @@ -5623,7 +5571,8 @@ Exit: return handle; } -status_t AudioFlinger::moveEffects(int sessionId, int srcOutput, int dstOutput) +status_t AudioFlinger::moveEffects(int sessionId, audio_io_handle_t srcOutput, + audio_io_handle_t dstOutput) { ALOGV("moveEffects() session %d, srcOutput %d, dstOutput %d", sessionId, srcOutput, dstOutput); @@ -5674,7 +5623,7 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, // transfer all effects one by one so that new effect chain is created on new thread with // correct buffer sizes and audio parameters and effect engines reconfigured accordingly - int dstOutput = dstThread->id(); + audio_io_handle_t dstOutput = dstThread->id(); sp<EffectChain> dstChain; uint32_t strategy = 0; // prevent compiler warning sp<EffectModule> effect = chain->getEffectFromId_l(0); @@ -5830,13 +5779,8 @@ Exit: sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId) { - sp<EffectModule> effect; - sp<EffectChain> chain = getEffectChain_l(sessionId); - if (chain != 0) { - effect = chain->getEffectFromId_l(effectId); - } - return effect; + return chain != 0 ? chain->getEffectFromId_l(effectId) : 0; } // PlaybackThread::addEffect_l() must be called with AudioFlinger::mLock and @@ -5921,16 +5865,13 @@ sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain(int sessi sp<AudioFlinger::EffectChain> AudioFlinger::ThreadBase::getEffectChain_l(int sessionId) { - sp<EffectChain> chain; - size_t size = mEffectChains.size(); for (size_t i = 0; i < size; i++) { if (mEffectChains[i]->sessionId() == sessionId) { - chain = mEffectChains[i]; - break; + return mEffectChains[i]; } } - return chain; + return 0; } void AudioFlinger::ThreadBase::setMode(audio_mode_t mode) @@ -6263,11 +6204,7 @@ size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle) sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle() { Mutex::Autolock _l(mLock); - sp<EffectHandle> handle; - if (mHandles.size() != 0) { - handle = mHandles[0].promote(); - } - return handle; + return mHandles.size() != 0 ? mHandles[0].promote() : 0; } void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle, bool unpiniflast) @@ -6622,7 +6559,7 @@ status_t AudioFlinger::EffectModule::setEnabled(bool enabled) return NO_ERROR; } -bool AudioFlinger::EffectModule::isEnabled() +bool AudioFlinger::EffectModule::isEnabled() const { switch (mState) { case RESTART: @@ -6638,7 +6575,7 @@ bool AudioFlinger::EffectModule::isEnabled() } } -bool AudioFlinger::EffectModule::isProcessEnabled() +bool AudioFlinger::EffectModule::isProcessEnabled() const { switch (mState) { case RESTART: @@ -6970,9 +6907,11 @@ void AudioFlinger::EffectHandle::disconnect(bool unpiniflast) mEffect.clear(); if (mClient != 0) { if (mCblk != NULL) { + // unlike ~TrackBase(), mCblk is never a local new, so don't delete mCblk->~effect_param_cblk_t(); // destroy our shared-structure. } - mCblkMemory.clear(); // and free the shared memory + mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to + // Client destructor must run with AudioFlinger mutex locked Mutex::Autolock _l(mClient->audioFlinger()->mLock); mClient.clear(); } @@ -7054,10 +6993,6 @@ status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode, return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData); } -sp<IMemory> AudioFlinger::EffectHandle::getCblk() const { - return mCblkMemory; -} - void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled) { ALOGV("setControl %p control %d", this, hasControl); @@ -7102,7 +7037,7 @@ void AudioFlinger::EffectHandle::dump(char* buffer, size_t size) bool locked = mCblk != NULL && tryLock(mCblk->lock); snprintf(buffer, size, "\t\t\t%05d %05d %01u %01u %05u %05u\n", - (mClient == NULL) ? getpid() : mClient->pid(), + (mClient == 0) ? getpid() : mClient->pid(), mPriority, mHasControl, !locked, @@ -7144,48 +7079,42 @@ AudioFlinger::EffectChain::~EffectChain() // getEffectFromDesc_l() must be called with ThreadBase::mLock held sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(effect_descriptor_t *descriptor) { - sp<EffectModule> effect; size_t size = mEffects.size(); for (size_t i = 0; i < size; i++) { if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) { - effect = mEffects[i]; - break; + return mEffects[i]; } } - return effect; + return 0; } // getEffectFromId_l() must be called with ThreadBase::mLock held sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id) { - sp<EffectModule> effect; size_t size = mEffects.size(); for (size_t i = 0; i < size; i++) { // by convention, return first effect if id provided is 0 (0 is never a valid id) if (id == 0 || mEffects[i]->id() == id) { - effect = mEffects[i]; - break; + return mEffects[i]; } } - return effect; + return 0; } // getEffectFromType_l() must be called with ThreadBase::mLock held sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l( const effect_uuid_t *type) { - sp<EffectModule> effect; size_t size = mEffects.size(); for (size_t i = 0; i < size; i++) { if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) { - effect = mEffects[i]; - break; + return mEffects[i]; } } - return effect; + return 0; } // Must be called with EffectChain::mLock locked @@ -7626,12 +7555,8 @@ void AudioFlinger::EffectChain::getSuspendEligibleEffects(Vector< sp<AudioFlinge sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled( const effect_uuid_t *type) { - sp<EffectModule> effect; - effect = getEffectFromType_l(type); - if (effect != 0 && !effect->isEnabled()) { - effect.clear(); - } - return effect; + sp<EffectModule> effect = getEffectFromType_l(type); + return effect != 0 && effect->isEnabled() ? effect : 0; } void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 3f3188c..97103c4 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -77,15 +77,15 @@ public: int frameCount, uint32_t flags, const sp<IMemory>& sharedBuffer, - int output, + audio_io_handle_t output, int *sessionId, status_t *status); - virtual uint32_t sampleRate(int output) const; - virtual int channelCount(int output) const; - virtual audio_format_t format(int output) const; - virtual size_t frameCount(int output) const; - virtual uint32_t latency(int output) const; + virtual uint32_t sampleRate(audio_io_handle_t output) const; + virtual int channelCount(audio_io_handle_t output) const; + virtual audio_format_t format(audio_io_handle_t output) const; + virtual size_t frameCount(audio_io_handle_t output) const; + virtual uint32_t latency(audio_io_handle_t output) const; virtual status_t setMasterVolume(float value); virtual status_t setMasterMute(bool muted); @@ -93,10 +93,12 @@ public: virtual float masterVolume() const; virtual bool masterMute() const; - virtual status_t setStreamVolume(audio_stream_type_t stream, float value, int output); + virtual status_t setStreamVolume(audio_stream_type_t stream, float value, + audio_io_handle_t output); virtual status_t setStreamMute(audio_stream_type_t stream, bool muted); - virtual float streamVolume(audio_stream_type_t stream, int output) const; + virtual float streamVolume(audio_stream_type_t stream, + audio_io_handle_t output) const; virtual bool streamMute(audio_stream_type_t stream) const; virtual status_t setMode(audio_mode_t mode); @@ -104,42 +106,44 @@ public: virtual status_t setMicMute(bool state); virtual bool getMicMute() const; - virtual status_t setParameters(int ioHandle, const String8& keyValuePairs); - virtual String8 getParameters(int ioHandle, const String8& keys); + virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs); + virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const; virtual void registerClient(const sp<IAudioFlingerClient>& client); - virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount); - virtual unsigned int getInputFramesLost(int ioHandle); + virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format, int channelCount) const; + virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const; - virtual int openOutput(uint32_t *pDevices, + virtual audio_io_handle_t openOutput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, uint32_t *pLatencyMs, uint32_t flags); - virtual int openDuplicateOutput(int output1, int output2); + virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, + audio_io_handle_t output2); - virtual status_t closeOutput(int output); + virtual status_t closeOutput(audio_io_handle_t output); - virtual status_t suspendOutput(int output); + virtual status_t suspendOutput(audio_io_handle_t output); - virtual status_t restoreOutput(int output); + virtual status_t restoreOutput(audio_io_handle_t output); - virtual int openInput(uint32_t *pDevices, + virtual audio_io_handle_t openInput(uint32_t *pDevices, uint32_t *pSamplingRate, audio_format_t *pFormat, uint32_t *pChannels, audio_in_acoustics_t acoustics); - virtual status_t closeInput(int input); + virtual status_t closeInput(audio_io_handle_t input); - virtual status_t setStreamOutput(audio_stream_type_t stream, int output); + virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output); virtual status_t setVoiceVolume(float volume); - virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output); + virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, + audio_io_handle_t output) const; virtual int newAudioSessionId(); @@ -147,23 +151,25 @@ public: virtual void releaseAudioSessionId(int audioSession); - virtual status_t queryNumberEffects(uint32_t *numEffects); + virtual status_t queryNumberEffects(uint32_t *numEffects) const; - virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor); + virtual status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor) const; - virtual status_t getEffectDescriptor(effect_uuid_t *pUuid, effect_descriptor_t *descriptor); + virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid, + effect_descriptor_t *descriptor) const; virtual sp<IEffect> createEffect(pid_t pid, effect_descriptor_t *pDesc, const sp<IEffectClient>& effectClient, int32_t priority, - int io, + audio_io_handle_t io, int sessionId, status_t *status, int *id, int *enabled); - virtual status_t moveEffects(int sessionId, int srcOutput, int dstOutput); + virtual status_t moveEffects(int sessionId, audio_io_handle_t srcOutput, + audio_io_handle_t dstOutput); enum hardware_call_state { AUDIO_HW_IDLE = 0, @@ -187,7 +193,7 @@ public: // record interface virtual sp<IAudioRecord> openRecord( pid_t pid, - int input, + audio_io_handle_t input, uint32_t sampleRate, audio_format_t format, uint32_t channelMask, @@ -204,7 +210,7 @@ public: audio_mode_t getMode() const { return mMode; } - bool btNrecIsOff() { return mBtNrecIsOff; } + bool btNrecIsOff() const { return mBtNrecIsOff; } private: @@ -228,7 +234,7 @@ private: virtual ~Client(); sp<MemoryDealer> heap() const; pid_t pid() const { return mPid; } - sp<AudioFlinger> audioFlinger() { return mAudioFlinger; } + sp<AudioFlinger> audioFlinger() const { return mAudioFlinger; } private: Client(const Client&); @@ -285,7 +291,7 @@ private: RECORD // Thread class is RecordThread }; - ThreadBase (const sp<AudioFlinger>& audioFlinger, int id, uint32_t device, type_t type); + ThreadBase (const sp<AudioFlinger>& audioFlinger, audio_io_handle_t id, uint32_t device, type_t type); virtual ~ThreadBase(); status_t dumpBase(int fd, const Vector<String16>& args); @@ -322,13 +328,13 @@ private: uint32_t flags, const sp<IMemory>& sharedBuffer, int sessionId); - ~TrackBase(); + virtual ~TrackBase(); virtual status_t start() = 0; virtual void stop() = 0; - sp<IMemory> getCblk() const; + sp<IMemory> getCblk() const { return mCblkMemory; } audio_track_cblk_t* cblk() const { return mCblk; } - int sessionId() { return mSessionId; } + int sessionId() const { return mSessionId; } protected: friend class ThreadBase; @@ -348,11 +354,11 @@ private: return mFormat; } - int channelCount() const ; + int channelCount() const { return mChannelCount; } - uint32_t channelMask() const; + uint32_t channelMask() const { return mChannelMask; } - int sampleRate() const; + int sampleRate() const; // FIXME inline after cblk sr moved void* getBuffer(uint32_t offset, uint32_t frames) const; @@ -376,7 +382,6 @@ private: uint32_t mFrameCount; // we don't really need a lock for these track_state mState; - int mClientTid; const audio_format_t mFormat; uint32_t mFlags; const int mSessionId; @@ -409,10 +414,10 @@ private: virtual status_t initCheck() const = 0; type_t type() const { return mType; } - uint32_t sampleRate() const; - int channelCount() const; - audio_format_t format() const; - size_t frameCount() const; + uint32_t sampleRate() const { return mSampleRate; } + int channelCount() const { return mChannelCount; } + audio_format_t format() const { return mFormat; } + size_t frameCount() const { return mFrameCount; } void wakeUp() { mWaitWorkCV.broadcast(); } void exit(); virtual bool checkForNewParameters_l() = 0; @@ -422,7 +427,7 @@ private: void sendConfigEvent(int event, int param = 0); void sendConfigEvent_l(int event, int param = 0); void processConfigEvents(); - int id() const { return mId;} + audio_io_handle_t id() const { return mId;} bool standby() { return mStandby; } uint32_t device() { return mDevice; } virtual audio_stream_t* stream() = 0; @@ -544,7 +549,7 @@ private: status_t mParamStatus; Vector<ConfigEvent> mConfigEvents; bool mStandby; - int mId; + const audio_io_handle_t mId; bool mExiting; Vector< sp<EffectChain> > mEffectChains; uint32_t mDevice; // output device for PlaybackThread @@ -581,7 +586,7 @@ private: int frameCount, const sp<IMemory>& sharedBuffer, int sessionId); - ~Track(); + virtual ~Track(); void dump(char* buffer, size_t size); virtual status_t start(); @@ -600,10 +605,10 @@ private: } status_t attachAuxEffect(int EffectId); void setAuxBuffer(int EffectId, int32_t *buffer); - int32_t *auxBuffer() { return mAuxBuffer; } + int32_t *auxBuffer() const { return mAuxBuffer; } void setMainBuffer(int16_t *buffer) { mMainBuffer = buffer; } - int16_t *mainBuffer() { return mMainBuffer; } - int auxEffectId() { return mAuxEffectId; } + int16_t *mainBuffer() const { return mMainBuffer; } + int auxEffectId() const { return mAuxEffectId; } protected: @@ -617,7 +622,7 @@ private: Track& operator = (const Track&); virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer); - bool isMuted() { return mMute; } + bool isMuted() const { return mMute; } bool isPausing() const { return mState == PAUSING; } @@ -664,14 +669,14 @@ private: audio_format_t format, uint32_t channelMask, int frameCount); - ~OutputTrack(); + virtual ~OutputTrack(); virtual status_t start(); virtual void stop(); bool write(int16_t* data, uint32_t frames); - bool bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; } - bool isActive() { return mActive; } - const wp<ThreadBase>& thread() { return mThread; } + bool bufferQueueEmpty() const { return (mBufferQueue.size() == 0) ? true : false; } + bool isActive() const { return mActive; } + const wp<ThreadBase>& thread() const { return mThread; } private: @@ -691,8 +696,8 @@ private: DuplicatingThread* const mSourceThread; // for waitTimeMs() in write() }; // end of OutputTrack - PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, - uint32_t device, type_t type); + PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, + audio_io_handle_t id, uint32_t device, type_t type); virtual ~PlaybackThread(); virtual status_t dump(int fd, const Vector<String16>& args); @@ -708,8 +713,8 @@ private: virtual status_t setMasterVolume(float value); virtual status_t setMasterMute(bool muted); - virtual float masterVolume() const; - virtual bool masterMute() const; + virtual float masterVolume() const { return mMasterVolume; } + virtual bool masterMute() const { return mMasterMute; } virtual status_t setStreamVolume(audio_stream_type_t stream, float value); virtual status_t setStreamMute(audio_stream_type_t stream, bool muted); @@ -738,7 +743,7 @@ private: virtual String8 getParameters(const String8& keys); virtual void audioConfigChanged_l(int event, int param = 0); virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames); - int16_t *mixBuffer() { return mMixBuffer; }; + int16_t *mixBuffer() const { return mMixBuffer; }; virtual void detachAuxEffect_l(int effectId); status_t attachAuxEffect(const sp<AudioFlinger::PlaybackThread::Track> track, @@ -817,7 +822,7 @@ private: public: MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, - int id, + audio_io_handle_t id, uint32_t device, type_t type = MIXER); virtual ~MixerThread(); @@ -844,8 +849,9 @@ private: class DirectOutputThread : public PlaybackThread { public: - DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id, uint32_t device); - ~DirectOutputThread(); + DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, + audio_io_handle_t id, uint32_t device); + virtual ~DirectOutputThread(); // Thread virtuals virtual bool threadLoop(); @@ -870,8 +876,9 @@ private: class DuplicatingThread : public MixerThread { public: - DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, int id); - ~DuplicatingThread(); + DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, + audio_io_handle_t id); + virtual ~DuplicatingThread(); // Thread virtuals virtual bool threadLoop(); @@ -889,13 +896,16 @@ private: uint32_t mWaitTimeMs; }; - PlaybackThread *checkPlaybackThread_l(int output) const; - MixerThread *checkMixerThread_l(int output) const; - RecordThread *checkRecordThread_l(int input) const; - float streamVolumeInternal(audio_stream_type_t stream) const { return mStreamTypes[stream].volume; } - void audioConfigChanged_l(int event, int ioHandle, void *param2); + PlaybackThread *checkPlaybackThread_l(audio_io_handle_t output) const; + MixerThread *checkMixerThread_l(audio_io_handle_t output) const; + RecordThread *checkRecordThread_l(audio_io_handle_t input) const; + float streamVolumeInternal(audio_stream_type_t stream) const + { return mStreamTypes[stream].volume; } + void audioConfigChanged_l(int event, audio_io_handle_t ioHandle, void *param2); + // allocate an audio_io_handle_t, session ID, or effect ID uint32_t nextUniqueId(); + status_t moveEffectChain_l(int sessionId, AudioFlinger::PlaybackThread *srcThread, AudioFlinger::PlaybackThread *dstThread, @@ -946,7 +956,7 @@ private: int frameCount, uint32_t flags, int sessionId); - ~RecordTrack(); + virtual ~RecordTrack(); virtual status_t start(); virtual void stop(); @@ -973,9 +983,9 @@ private: AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, - int id, + audio_io_handle_t id, uint32_t device); - ~RecordThread(); + virtual ~RecordThread(); virtual bool threadLoop(); virtual status_t readyToRun(); @@ -1064,7 +1074,7 @@ private: effect_descriptor_t *desc, int id, int sessionId); - ~EffectModule(); + virtual ~EffectModule(); enum effect_state { IDLE, @@ -1076,7 +1086,7 @@ private: DESTROYED }; - int id() { return mId; } + int id() const { return mId; } void process(); void updateState(); status_t command(uint32_t cmdCode, @@ -1094,12 +1104,12 @@ private: uint32_t status() { return mStatus; } - int sessionId() { + int sessionId() const { return mSessionId; } status_t setEnabled(bool enabled); - bool isEnabled(); - bool isProcessEnabled(); + bool isEnabled() const; + bool isProcessEnabled() const; void setInBuffer(int16_t *buffer) { mConfig.inputCfg.buffer.s16 = buffer; } int16_t *inBuffer() { return mConfig.inputCfg.buffer.s16; } @@ -1126,7 +1136,7 @@ private: sp<EffectHandle> controlHandle(); - bool isPinned() { return mPinned; } + bool isPinned() const { return mPinned; } void unPin() { mPinned = false; } status_t dump(int fd, const Vector<String16>& args); @@ -1187,7 +1197,7 @@ mutable Mutex mLock; // mutex for process, commands and handl void *pReplyData); virtual void disconnect(); virtual void disconnect(bool unpiniflast); - virtual sp<IMemory> getCblk() const; + virtual sp<IMemory> getCblk() const { return mCblkMemory; } virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); @@ -1203,13 +1213,13 @@ mutable Mutex mLock; // mutex for process, commands and handl uint32_t replySize, void *pReplyData); void setEnabled(bool enabled); - bool enabled() { return mEnabled; } + bool enabled() const { return mEnabled; } // Getters - int id() { return mEffect->id(); } - int priority() { return mPriority; } - bool hasControl() { return mHasControl; } - sp<EffectModule> effect() { return mEffect; } + int id() const { return mEffect->id(); } + int priority() const { return mPriority; } + bool hasControl() const { return mHasControl; } + sp<EffectModule> effect() const { return mEffect; } void dump(char* buffer, size_t size); @@ -1221,7 +1231,7 @@ mutable Mutex mLock; // mutex for process, commands and handl sp<EffectModule> mEffect; // pointer to controlled EffectModule sp<IEffectClient> mEffectClient; // callback interface for client notifications - sp<Client> mClient; // client for shared memory allocation + /*const*/ sp<Client> mClient; // client for shared memory allocation, see disconnect() sp<IMemory> mCblkMemory; // shared memory for control block effect_param_cblk_t* mCblk; // control block for deferred parameter setting via shared memory uint8_t* mBuffer; // pointer to parameter area in shared memory @@ -1241,7 +1251,7 @@ mutable Mutex mLock; // mutex for process, commands and handl class EffectChain: public RefBase { public: EffectChain(const wp<ThreadBase>& wThread, int sessionId); - ~EffectChain(); + virtual ~EffectChain(); // special key used for an entry in mSuspendedEffects keyed vector // corresponding to a suspend all request. @@ -1263,7 +1273,7 @@ mutable Mutex mLock; // mutex for process, commands and handl status_t addEffect_l(const sp<EffectModule>& handle); size_t removeEffect_l(const sp<EffectModule>& handle); - int sessionId() { return mSessionId; } + int sessionId() const { return mSessionId; } void setSessionId(int sessionId) { mSessionId = sessionId; } sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor); @@ -1277,26 +1287,26 @@ mutable Mutex mLock; // mutex for process, commands and handl mInBuffer = buffer; mOwnInBuffer = ownsBuffer; } - int16_t *inBuffer() { + int16_t *inBuffer() const { return mInBuffer; } void setOutBuffer(int16_t *buffer) { mOutBuffer = buffer; } - int16_t *outBuffer() { + int16_t *outBuffer() const { return mOutBuffer; } void incTrackCnt() { android_atomic_inc(&mTrackCnt); } void decTrackCnt() { android_atomic_dec(&mTrackCnt); } - int32_t trackCnt() { return mTrackCnt;} + int32_t trackCnt() const { return mTrackCnt;} void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); mTailBufferCount = mMaxTailBuffers; } void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); } - int32_t activeTrackCnt() { return mActiveTrackCnt;} + int32_t activeTrackCnt() const { return mActiveTrackCnt;} - uint32_t strategy() { return mStrategy; } + uint32_t strategy() const { return mStrategy; } void setStrategy(uint32_t strategy) { mStrategy = strategy; } @@ -1393,7 +1403,7 @@ mutable Mutex mLock; // mutex for process, commands and handl mutable Mutex mLock; - DefaultKeyedVector< pid_t, wp<Client> > mClients; + DefaultKeyedVector< pid_t, wp<Client> > mClients; // see ~Client() mutable Mutex mHardwareLock; audio_hw_device_t* mPrimaryHardwareDev; @@ -1401,14 +1411,14 @@ mutable Mutex mLock; // mutex for process, commands and handl mutable hardware_call_state mHardwareStatus; // for dump only - DefaultKeyedVector< int, sp<PlaybackThread> > mPlaybackThreads; + DefaultKeyedVector< audio_io_handle_t, sp<PlaybackThread> > mPlaybackThreads; PlaybackThread::stream_type_t mStreamTypes[AUDIO_STREAM_CNT]; // both are protected by mLock float mMasterVolume; bool mMasterMute; - DefaultKeyedVector< int, sp<RecordThread> > mRecordThreads; + DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> > mRecordThreads; DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients; volatile int32_t mNextUniqueId; @@ -1419,6 +1429,10 @@ mutable Mutex mLock; // mutex for process, commands and handl float masterVolume_l() const { return mMasterVolume; } bool masterMute_l() const { return mMasterMute; } + +private: + sp<Client> registerPid_l(pid_t pid); // always returns non-0 + }; diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 0b9f8ba..191520a 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -68,7 +68,7 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate) // t->prevAuxLevel // t->frameCount t->channelCount = 2; - t->enabled = 0; + t->enabled = false; t->format = 16; t->channelMask = AUDIO_CHANNEL_OUT_STEREO; t->bufferProvider = NULL; @@ -121,8 +121,8 @@ void AudioMixer::deleteTrackName(int name) assert(uint32_t(name) < MAX_NUM_TRACKS); ALOGV("deleteTrackName(%d)", name); track_t& track(mState.tracks[ name ]); - if (track.enabled != 0) { - track.enabled = 0; + if (track.enabled) { + track.enabled = false; invalidateState(1<<name); } if (track.resampler != NULL) { @@ -143,8 +143,8 @@ void AudioMixer::enable(int name) assert(uint32_t(name) < MAX_NUM_TRACKS); track_t& track = mState.tracks[name]; - if (track.enabled != 1) { - track.enabled = 1; + if (!track.enabled) { + track.enabled = true; ALOGV("enable(%d)", name); invalidateState(1 << name); } @@ -156,8 +156,8 @@ void AudioMixer::disable(int name) assert(uint32_t(name) < MAX_NUM_TRACKS); track_t& track = mState.tracks[name]; - if (track.enabled != 0) { - track.enabled = 0; + if (track.enabled) { + track.enabled = false; ALOGV("disable(%d)", name); invalidateState(1 << name); } @@ -296,18 +296,6 @@ bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) return false; } -bool AudioMixer::track_t::doesResample() const -{ - return resampler != NULL; -} - -void AudioMixer::track_t::resetResampler() -{ - if (resampler != NULL) { - resampler->reset(); - } -} - inline void AudioMixer::track_t::adjustVolumeRamp(bool aux) { @@ -327,20 +315,11 @@ void AudioMixer::track_t::adjustVolumeRamp(bool aux) } } -size_t AudioMixer::track_t::getUnreleasedFrames() -{ - if (resampler != NULL) { - return resampler->getUnreleasedFrames(); - } - return 0; -} - -size_t AudioMixer::getUnreleasedFrames(int name) +size_t AudioMixer::getUnreleasedFrames(int name) const { name -= TRACK0; if (uint32_t(name) < MAX_NUM_TRACKS) { - track_t& track(mState.tracks[name]); - return track.getUnreleasedFrames(); + return mState.tracks[name].getUnreleasedFrames(); } return 0; } @@ -383,9 +362,9 @@ void AudioMixer::process__validate(state_t* state) // compute everything we need... int countActiveTracks = 0; - int all16BitsStereoNoResample = 1; - int resampling = 0; - int volumeRamp = 0; + bool all16BitsStereoNoResample = true; + bool resampling = false; + bool volumeRamp = false; uint32_t en = state->enabledTracks; while (en) { const int i = 31 - __builtin_clz(en); @@ -402,7 +381,7 @@ void AudioMixer::process__validate(state_t* state) } if (t.volumeInc[0]|t.volumeInc[1]) { - volumeRamp = 1; + volumeRamp = true; } else if (!t.doesResample() && t.volumeRL == 0) { n |= NEEDS_MUTE_ENABLED; } @@ -412,16 +391,16 @@ void AudioMixer::process__validate(state_t* state) t.hook = track__nop; } else { if ((n & NEEDS_AUX__MASK) == NEEDS_AUX_ENABLED) { - all16BitsStereoNoResample = 0; + all16BitsStereoNoResample = false; } if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) { - all16BitsStereoNoResample = 0; - resampling = 1; + all16BitsStereoNoResample = false; + resampling = true; t.hook = track__genericResample; } else { if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){ t.hook = track__16BitsMono; - all16BitsStereoNoResample = 0; + all16BitsStereoNoResample = false; } if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){ t.hook = track__16BitsStereo; @@ -469,7 +448,7 @@ void AudioMixer::process__validate(state_t* state) // Now that the volume ramp has been done, set optimal state and // track hooks for subsequent mixer process if (countActiveTracks) { - int allMuted = 1; + bool allMuted = true; uint32_t en = state->enabledTracks; while (en) { const int i = 31 - __builtin_clz(en); @@ -480,7 +459,7 @@ void AudioMixer::process__validate(state_t* state) t.needs |= NEEDS_MUTE_ENABLED; t.hook = track__nop; } else { - allMuted = 0; + allMuted = false; } } if (allMuted) { diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h index 84f6330..c709686 100644 --- a/services/audioflinger/AudioMixer.h +++ b/services/audioflinger/AudioMixer.h @@ -33,7 +33,7 @@ class AudioMixer public: AudioMixer(size_t frameCount, uint32_t sampleRate); - ~AudioMixer(); + /*virtual*/ ~AudioMixer(); // non-virtual saves a v-table, restore if sub-classed static const uint32_t MAX_NUM_TRACKS = 32; static const uint32_t MAX_NUM_CHANNELS = 2; @@ -83,7 +83,7 @@ public: uint32_t trackNames() const { return mTrackNames; } - size_t getUnreleasedFrames(int name); + size_t getUnreleasedFrames(int name) const; private: @@ -153,10 +153,11 @@ private: int32_t* auxBuffer; bool setResampler(uint32_t sampleRate, uint32_t devSampleRate); - bool doesResample() const; - void resetResampler(); + bool doesResample() const { return resampler != NULL; } + void resetResampler() { if (resampler != NULL) resampler->reset(); } void adjustVolumeRamp(bool aux); - size_t getUnreleasedFrames(); + size_t getUnreleasedFrames() const { return resampler != NULL ? + resampler->getUnreleasedFrames() : 0; }; }; // pad to 32-bytes to fill cache line diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 1dddbb3..10efd85 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -819,7 +819,7 @@ void AudioPolicyService::AudioCommandThread::stopToneCommand() status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream, float volume, - int output, + audio_io_handle_t output, int delayMs) { status_t status = NO_ERROR; @@ -849,7 +849,7 @@ status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type return status; } -status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, +status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle, const char *keyValuePairs, int delayMs) { @@ -1019,7 +1019,7 @@ void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, const char *keyValuePairs, int delayMs) { - mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, + mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs, delayMs); } @@ -1029,7 +1029,7 @@ int AudioPolicyService::setStreamVolume(audio_stream_type_t stream, int delayMs) { return (int)mAudioCommandThread->volumeCommand(stream, volume, - (int)output, delayMs); + output, delayMs); } int AudioPolicyService::startTone(audio_policy_tone_t tone, @@ -1362,7 +1362,7 @@ static audio_io_handle_t aps_open_output(void *service, audio_policy_output_flags_t flags) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) { + if (af == 0) { ALOGW("%s: could not get AudioFlinger", __func__); return 0; } @@ -1376,7 +1376,7 @@ static audio_io_handle_t aps_open_dup_output(void *service, audio_io_handle_t output2) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) { + if (af == 0) { ALOGW("%s: could not get AudioFlinger", __func__); return 0; } @@ -1386,7 +1386,7 @@ static audio_io_handle_t aps_open_dup_output(void *service, static int aps_close_output(void *service, audio_io_handle_t output) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) + if (af == 0) return PERMISSION_DENIED; return af->closeOutput(output); @@ -1395,7 +1395,7 @@ static int aps_close_output(void *service, audio_io_handle_t output) static int aps_suspend_output(void *service, audio_io_handle_t output) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) { + if (af == 0) { ALOGW("%s: could not get AudioFlinger", __func__); return PERMISSION_DENIED; } @@ -1406,7 +1406,7 @@ static int aps_suspend_output(void *service, audio_io_handle_t output) static int aps_restore_output(void *service, audio_io_handle_t output) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) { + if (af == 0) { ALOGW("%s: could not get AudioFlinger", __func__); return PERMISSION_DENIED; } @@ -1422,7 +1422,7 @@ static audio_io_handle_t aps_open_input(void *service, audio_in_acoustics_t acoustics) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) { + if (af == 0) { ALOGW("%s: could not get AudioFlinger", __func__); return 0; } @@ -1434,7 +1434,7 @@ static audio_io_handle_t aps_open_input(void *service, static int aps_close_input(void *service, audio_io_handle_t input) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) + if (af == 0) return PERMISSION_DENIED; return af->closeInput(input); @@ -1444,7 +1444,7 @@ static int aps_set_stream_output(void *service, audio_stream_type_t stream, audio_io_handle_t output) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) + if (af == 0) return PERMISSION_DENIED; return af->setStreamOutput(stream, output); @@ -1455,10 +1455,10 @@ static int aps_move_effects(void *service, int session, audio_io_handle_t dst_output) { sp<IAudioFlinger> af = AudioSystem::get_audio_flinger(); - if (af == NULL) + if (af == 0) return PERMISSION_DENIED; - return af->moveEffects(session, (int)src_output, (int)dst_output); + return af->moveEffects(session, src_output, dst_output); } static char * aps_get_parameters(void *service, audio_io_handle_t io_handle, diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h index 62219e5..fdaf576 100644 --- a/services/audioflinger/AudioPolicyService.h +++ b/services/audioflinger/AudioPolicyService.h @@ -174,8 +174,10 @@ private: void startToneCommand(ToneGenerator::tone_type type, audio_stream_type_t stream); void stopToneCommand(); - status_t volumeCommand(audio_stream_type_t stream, float volume, int output, int delayMs = 0); - status_t parametersCommand(int ioHandle, const char *keyValuePairs, int delayMs = 0); + status_t volumeCommand(audio_stream_type_t stream, float volume, + audio_io_handle_t output, int delayMs = 0); + status_t parametersCommand(audio_io_handle_t ioHandle, + const char *keyValuePairs, int delayMs = 0); status_t voiceVolumeCommand(float volume, int delayMs = 0); void insertCommand_l(AudioCommand *command, int delayMs = 0); @@ -207,12 +209,12 @@ private: public: audio_stream_type_t mStream; float mVolume; - int mIO; + audio_io_handle_t mIO; }; class ParametersData { public: - int mIO; + audio_io_handle_t mIO; String8 mKeyValuePairs; }; diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp index feacd96..6e17a4a 100644 --- a/services/audioflinger/AudioResampler.cpp +++ b/services/audioflinger/AudioResampler.cpp @@ -130,12 +130,6 @@ AudioResampler::AudioResampler(int bitDepth, int inChannelCount, mVolume[0] = mVolume[1] = 0; mBuffer.frameCount = 0; - // save format for quick lookup - if (inChannelCount == 1) { - mFormat = MONO_16_BIT; - } else { - mFormat = STEREO_16_BIT; - } } AudioResampler::~AudioResampler() { diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h index ffa690a..ee171ff 100644 --- a/services/audioflinger/AudioResampler.h +++ b/services/audioflinger/AudioResampler.h @@ -54,7 +54,7 @@ public: AudioBufferProvider* provider) = 0; virtual void reset(); - virtual size_t getUnreleasedFrames() { return mInputIndex; } + virtual size_t getUnreleasedFrames() const { return mInputIndex; } protected: // number of bits for phase fraction - 30 bits allows nearly 2x downsampling @@ -66,7 +66,6 @@ protected: // multiplier to calculate fixed point phase increment static const double kPhaseMultiplier = 1L << kNumPhaseBits; - enum format {MONO_16_BIT, STEREO_16_BIT}; AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate); // prevent copying @@ -83,7 +82,6 @@ protected: uint32_t mVolumeRL; }; int16_t mTargetVolume[2]; - format mFormat; size_t mInputIndex; int32_t mPhaseIncrement; uint32_t mPhaseFraction; diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h index 0e1bc44..f0a07b8 100644 --- a/services/audioflinger/AudioResamplerSinc.h +++ b/services/audioflinger/AudioResamplerSinc.h @@ -31,7 +31,7 @@ class AudioResamplerSinc : public AudioResampler { public: AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate); - ~AudioResamplerSinc(); + virtual ~AudioResamplerSinc(); virtual void resample(int32_t* out, size_t outFrameCount, AudioBufferProvider* provider); diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index a372fb8..eab60a7 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -1394,9 +1394,7 @@ private NetworkStateTracker makeWimaxStateTracker() { private INetworkPolicyListener mPolicyListener = new INetworkPolicyListener.Stub() { @Override public void onUidRulesChanged(int uid, int uidRules) { - // only someone like NPMS should only be calling us - mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); - + // caller is NPMS, since we only register with them if (LOGD_RULES) { log("onUidRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")"); } @@ -1415,9 +1413,7 @@ private NetworkStateTracker makeWimaxStateTracker() { @Override public void onMeteredIfacesChanged(String[] meteredIfaces) { - // only someone like NPMS should only be calling us - mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG); - + // caller is NPMS, since we only register with them if (LOGD_RULES) { log("onMeteredIfacesChanged(ifaces=" + Arrays.toString(meteredIfaces) + ")"); } @@ -1429,6 +1425,27 @@ private NetworkStateTracker makeWimaxStateTracker() { } } } + + @Override + public void onRestrictBackgroundChanged(boolean restrictBackground) { + // caller is NPMS, since we only register with them + if (LOGD_RULES) { + log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")"); + } + + // kick off connectivity change broadcast for active network, since + // global background policy change is radical. + final int networkType = mActiveDefaultNetwork; + if (isNetworkTypeValid(networkType)) { + final NetworkStateTracker tracker = mNetTrackers[networkType]; + if (tracker != null) { + final NetworkInfo info = tracker.getNetworkInfo(); + if (info != null && info.isConnected()) { + sendConnectedBroadcast(info); + } + } + } + } }; /** diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index e6a1e68..5c53902 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -138,6 +138,7 @@ import java.io.StringWriter; import java.lang.IllegalStateException; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -3520,13 +3521,7 @@ public final class ActivityManagerService extends ActivityManagerNative } // Just in case... - if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) { - if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity); - mMainStack.mPausingActivity = null; - } - if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) { - mMainStack.mLastPausedActivity = null; - } + mMainStack.appDiedLocked(app); // Remove this application's activities from active lists. mMainStack.removeHistoryRecordsForAppLocked(app); @@ -7231,7 +7226,7 @@ public final class ActivityManagerService extends ActivityManagerNative mMainStack.stopIfSleepingLocked(); final long endTime = System.currentTimeMillis() + timeout; while (mMainStack.mResumedActivity != null - || mMainStack.mPausingActivity != null) { + || mMainStack.mPausingActivities.size() > 0) { long delay = endTime - System.currentTimeMillis(); if (delay <= 0) { Slog.w(TAG, "Activity manager shutdown timed out"); @@ -9025,8 +9020,13 @@ public final class ActivityManagerService extends ActivityManagerNative } pw.println(" "); - if (mMainStack.mPausingActivity != null) { - pw.println(" mPausingActivity: " + mMainStack.mPausingActivity); + if (mMainStack.mPausingActivities.size() > 0) { + pw.println(" mPausingActivities: " + Arrays.toString( + mMainStack.mPausingActivities.toArray())); + } + if (mMainStack.mInputPausedActivities.size() > 0) { + pw.println(" mInputPausedActivities: " + Arrays.toString( + mMainStack.mInputPausedActivities.toArray())); } pw.println(" mResumedActivity: " + mMainStack.mResumedActivity); pw.println(" mFocusedActivity: " + mFocusedActivity); @@ -14759,7 +14759,13 @@ public final class ActivityManagerService extends ActivityManagerNative private final ActivityRecord resumedAppLocked() { ActivityRecord resumedActivity = mMainStack.mResumedActivity; if (resumedActivity == null || resumedActivity.app == null) { - resumedActivity = mMainStack.mPausingActivity; + for (int i=mMainStack.mPausingActivities.size()-1; i>=0; i--) { + ActivityRecord r = mMainStack.mPausingActivities.get(i); + if (r.app != null) { + resumedActivity = r; + break; + } + } if (resumedActivity == null || resumedActivity.app == null) { resumedActivity = mMainStack.topRunningActivityLocked(null); } diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index cdab6c6..977ee84 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -602,6 +602,7 @@ final class ActivityRecord { public void windowsDrawn() { synchronized(service) { + stack.reportActivityDrawnLocked(this); if (launchTime != 0) { final long curTime = SystemClock.uptimeMillis(); final long thisTime = curTime - launchTime; @@ -690,7 +691,9 @@ final class ActivityRecord { // Hmmm, who might we be waiting for? r = stack.mResumedActivity; if (r == null) { - r = stack.mPausingActivity; + if (stack.mPausingActivities.size() > 0) { + r = stack.mPausingActivities.get(stack.mPausingActivities.size()-1); + } } // Both of those null? Fall back to 'this' again if (r == null) { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index c3ae6a1..0d21760 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -227,7 +227,13 @@ final class ActivityStack { * When we are in the process of pausing an activity, before starting the * next one, this variable holds the activity that is currently being paused. */ - ActivityRecord mPausingActivity = null; + final ArrayList<ActivityRecord> mPausingActivities = new ArrayList<ActivityRecord>(); + + /** + * These activities currently have their input paused, as they want for + * the next top activity to have its windows visible. + */ + final ArrayList<ActivityRecord> mInputPausedActivities = new ArrayList<ActivityRecord>(); /** * This is the last activity that we put into the paused state. This is @@ -807,9 +813,9 @@ final class ActivityStack { startPausingLocked(false, true); return; } - if (mPausingActivity != null) { + if (mPausingActivities.size() > 0) { // Still waiting for something to pause; can't sleep yet. - if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivity); + if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivities); return; } @@ -872,11 +878,6 @@ final class ActivityStack { } private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { - if (mPausingActivity != null) { - RuntimeException e = new RuntimeException(); - Slog.e(TAG, "Trying to pause when pause is already pending for " - + mPausingActivity, e); - } ActivityRecord prev = mResumedActivity; if (prev == null) { RuntimeException e = new RuntimeException(); @@ -884,19 +885,25 @@ final class ActivityStack { resumeTopActivityLocked(null); return; } + if (mPausingActivities.contains(prev)) { + RuntimeException e = new RuntimeException(); + Slog.e(TAG, "Trying to pause when pause when already pausing " + prev, e); + } if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev); else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev); mResumedActivity = null; - mPausingActivity = prev; + mPausingActivities.add(prev); mLastPausedActivity = prev; prev.state = ActivityState.PAUSING; prev.task.touchActiveTime(); prev.updateThumbnail(screenshotActivities(prev), null); mService.updateCpuStats(); + ActivityRecord pausing; if (prev.app != null && prev.app.thread != null) { if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev); + pausing = prev; try { EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY, System.identityHashCode(prev), @@ -909,12 +916,14 @@ final class ActivityStack { } catch (Exception e) { // Ignore exception, if process died other code will cleanup. Slog.w(TAG, "Exception thrown during pause", e); - mPausingActivity = null; + mPausingActivities.remove(prev); mLastPausedActivity = null; + pausing = null; } } else { - mPausingActivity = null; + mPausingActivities.remove(prev); mLastPausedActivity = null; + pausing = null; } // If we are not going to sleep, we want to ensure the device is @@ -928,18 +937,28 @@ final class ActivityStack { } } - - if (mPausingActivity != null) { + if (pausing != null) { // Have the window manager pause its key dispatching until the new // activity has started. If we're pausing the activity just because // the screen is being turned off and the UI is sleeping, don't interrupt // key dispatch; the same activity will pick it up again on wakeup. if (!uiSleeping) { - prev.pauseKeyDispatchingLocked(); + pausing.pauseKeyDispatchingLocked(); + mInputPausedActivities.add(prev); } else { if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off"); } + if (pausing.configDestroy) { + // The previous is being paused because the configuration + // is changing, which means it is actually stopping... + // To juggle the fact that we are also starting a new + // instance right now, we need to first completely stop + // the current instance before starting the new one. + if (DEBUG_PAUSE) Slog.v(TAG, "Destroying at pause: " + prev); + destroyActivityLocked(pausing, true, false, "pause-config"); + } + // Schedule a pause timeout in case the app doesn't respond. // We don't give it much time because this directly impacts the // responsiveness seen by the user. @@ -951,7 +970,10 @@ final class ActivityStack { // This activity failed to schedule the // pause, so just treat it as being paused now. if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next."); - resumeTopActivityLocked(null); + } + + if (!mService.isSleeping()) { + resumeTopActivityLocked(pausing); } } @@ -966,16 +988,17 @@ final class ActivityStack { if (index >= 0) { r = mHistory.get(index); mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); - if (mPausingActivity == r) { + if (mPausingActivities.contains(r)) { if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r + (timeout ? " (due to timeout)" : " (pause complete)")); r.state = ActivityState.PAUSED; - completePauseLocked(); + completePauseLocked(r); } else { + ActivityRecord old = mPausingActivities.size() > 0 + ? mPausingActivities.get(0) : null; EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, System.identityHashCode(r), r.shortComponentName, - mPausingActivity != null - ? mPausingActivity.shortComponentName : "(none)"); + old != null ? old.shortComponentName : "(none)"); } } } @@ -1001,8 +1024,14 @@ final class ActivityStack { ProcessRecord fgApp = null; if (mResumedActivity != null) { fgApp = mResumedActivity.app; - } else if (mPausingActivity != null) { - fgApp = mPausingActivity.app; + } else { + for (int i=mPausingActivities.size()-1; i>=0; i--) { + ActivityRecord pausing = mPausingActivities.get(i); + if (pausing.app == r.app) { + fgApp = pausing.app; + break; + } + } } if (r.app != null && fgApp != null && r.app != fgApp && r.lastVisibleTime > mService.mPreviousProcessVisibleTime @@ -1014,58 +1043,49 @@ final class ActivityStack { } } - private final void completePauseLocked() { - ActivityRecord prev = mPausingActivity; + private final void completePauseLocked(ActivityRecord prev) { if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev); - if (prev != null) { - if (prev.finishing) { - if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev); - prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); - } else if (prev.app != null) { - if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev); - if (prev.waitingVisible) { - prev.waitingVisible = false; - mWaitingVisibleActivities.remove(prev); - if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v( - TAG, "Complete pause, no longer waiting: " + prev); - } - if (prev.configDestroy) { - // The previous is being paused because the configuration - // is changing, which means it is actually stopping... - // To juggle the fact that we are also starting a new - // instance right now, we need to first completely stop - // the current instance before starting the new one. - if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev); - destroyActivityLocked(prev, true, false, "pause-config"); + if (prev.finishing) { + if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev); + prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE); + } else if (prev.app != null) { + if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev); + if (prev.waitingVisible) { + prev.waitingVisible = false; + mWaitingVisibleActivities.remove(prev); + if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v( + TAG, "Complete pause, no longer waiting: " + prev); + } + if (prev.configDestroy) { + // The previous is being paused because the configuration + // is changing, which means it is actually stopping... + // To juggle the fact that we are also starting a new + // instance right now, we need to first completely stop + // the current instance before starting the new one. + if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev); + destroyActivityLocked(prev, true, false, "pause-config"); + } else { + mStoppingActivities.add(prev); + if (mStoppingActivities.size() > 3) { + // If we already have a few activities waiting to stop, + // then give up on things going idle and start clearing + // them out. + if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle"); + scheduleIdleLocked(); } else { - mStoppingActivities.add(prev); - if (mStoppingActivities.size() > 3) { - // If we already have a few activities waiting to stop, - // then give up on things going idle and start clearing - // them out. - if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle"); - scheduleIdleLocked(); - } else { - checkReadyForSleepLocked(); - } + checkReadyForSleepLocked(); } - } else { - if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev); - prev = null; } - mPausingActivity = null; + } else { + if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev); + prev = null; } + mPausingActivities.remove(prev); - if (!mService.isSleeping()) { - resumeTopActivityLocked(prev); - } else { + if (mService.isSleeping()) { checkReadyForSleepLocked(); } - - if (prev != null) { - prev.resumeKeyDispatchingLocked(); - } if (prev.app != null && prev.cpuTimeAtResume > 0 && mService.mBatteryStatsService.isOnBattery()) { @@ -1122,7 +1142,9 @@ final class ActivityStack { if (mMainStack) { mService.setFocusedActivityLocked(next); } - next.resumeKeyDispatchingLocked(); + if (mInputPausedActivities.remove(next)) { + next.resumeKeyDispatchingLocked(); + } ensureActivitiesVisibleLocked(null, 0); mService.mWindowManager.executeAppTransition(); mNoAnimActivities.clear(); @@ -1352,13 +1374,6 @@ final class ActivityStack { if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next); - // If we are currently pausing an activity, then don't do anything - // until that is done. - if (mPausingActivity != null) { - if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity); - return false; - } - // Okay we are now going to start a switch, to 'next'. We may first // have to pause the current activity, but this is an important point // where we have decided to go to 'next' so keep track of that. @@ -2440,7 +2455,7 @@ final class ActivityStack { err = startActivityUncheckedLocked(r, sourceRecord, grantedUriPermissions, grantedMode, onlyIfNeeded, true); - if (mDismissKeyguardOnNextActivity && mPausingActivity == null) { + if (mDismissKeyguardOnNextActivity && mPausingActivities.size() == 0) { // Someone asked to have the keyguard dismissed on the next // activity start, but we are not actually doing an activity // switch... just dismiss the keyguard now, because we @@ -3111,7 +3126,18 @@ final class ActivityStack { } mService.notifyAll(); } - + + void reportActivityDrawnLocked(ActivityRecord r) { + if (mResumedActivity == r) { + // Once the resumed activity has been drawn, we can stop + // pausing input on all other activities. + for (int i=mInputPausedActivities.size()-1; i>=0; i--) { + mInputPausedActivities.get(i).resumeKeyDispatchingLocked(); + } + mInputPausedActivities.clear(); + } + } + void reportActivityVisibleLocked(ActivityRecord r) { for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) { WaitResult w = mWaitingActivityVisible.get(i); @@ -3170,7 +3196,9 @@ final class ActivityStack { mService.setFocusedActivityLocked(topRunningActivityLocked(null)); } } - r.resumeKeyDispatchingLocked(); + if (mInputPausedActivities.remove(r)) { + r.resumeKeyDispatchingLocked(); + } try { r.stopped = false; if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r @@ -3496,7 +3524,7 @@ final class ActivityStack { // Tell window manager to prepare for this one to be removed. mService.mWindowManager.setAppVisibility(r.appToken, false); - if (mPausingActivity == null) { + if (!mPausingActivities.contains(r)) { if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r); if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false"); startPausingLocked(false, false); @@ -3580,6 +3608,20 @@ final class ActivityStack { return r; } + final void appDiedLocked(ProcessRecord app) { + for (int i=mPausingActivities.size()-1; i>=0; i--) { + ActivityRecord r = mPausingActivities.get(i); + if (r.app == app) { + if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " + r); + mPausingActivities.remove(i); + mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); + } + } + if (mLastPausedActivity != null && mLastPausedActivity.app == app) { + mLastPausedActivity = null; + } + } + /** * Perform the common clean-up of an activity record. This is called both * as part of destroyActivityLocked() (when destroying the client-side diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java index 9772d6a..a890068 100644 --- a/services/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java @@ -195,6 +195,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { private static final int MSG_FOREGROUND_ACTIVITIES_CHANGED = 3; private static final int MSG_PROCESS_DIED = 4; private static final int MSG_LIMIT_REACHED = 5; + private static final int MSG_RESTRICT_BACKGROUND_CHANGED = 6; private final Context mContext; private final IActivityManager mActivityManager; @@ -1225,6 +1226,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateNotificationsLocked(); writePolicyLocked(); } + + mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED, restrictBackground ? 1 : 0, 0) + .sendToTarget(); } @Override @@ -1573,6 +1577,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } return true; } + case MSG_RESTRICT_BACKGROUND_CHANGED: { + final boolean restrictBackground = msg.arg1 != 0; + final int length = mListeners.beginBroadcast(); + for (int i = 0; i < length; i++) { + final INetworkPolicyListener listener = mListeners.getBroadcastItem(i); + if (listener != null) { + try { + listener.onRestrictBackgroundChanged(restrictBackground); + } catch (RemoteException e) { + } + } + } + mListeners.finishBroadcast(); + } default: { return false; } diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java index e7ba358..240cc1c 100644 --- a/services/java/com/android/server/net/NetworkStatsRecorder.java +++ b/services/java/com/android/server/net/NetworkStatsRecorder.java @@ -51,6 +51,7 @@ import java.util.Map; public class NetworkStatsRecorder { private static final String TAG = "NetworkStatsRecorder"; private static final boolean LOGD = true; + private static final boolean LOGV = false; private final FileRotator mRotator; private final NonMonotonicObserver<String> mObserver; @@ -170,7 +171,7 @@ public class NetworkStatsRecorder { mLastSnapshot = snapshot; - if (LOGD && unknownIfaces.size() > 0) { + if (LOGV && unknownIfaces.size() > 0) { Slog.w(TAG, "unknown interfaces " + unknownIfaces + ", ignoring those stats"); } } diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ab09bfa..40717f4 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1793,6 +1793,7 @@ status_t SurfaceFlinger::onTransact( reply->writeInt32(0); reply->writeInt32(mDebugRegion); reply->writeInt32(mDebugBackground); + reply->writeInt32(mDebugDisableHWC); return NO_ERROR; case 1013: { Mutex::Autolock _l(mStateLock); diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java index 893d7a8..35cdf9b 100644 --- a/telephony/java/com/android/internal/telephony/BaseCommands.java +++ b/telephony/java/com/android/internal/telephony/BaseCommands.java @@ -715,4 +715,7 @@ public abstract class BaseCommands implements CommandsInterface { "' lteOnCdmaProductType='" + sLteOnCdmaProductType + "'"); return retVal; } + + @Override + public void testingEmergencyCall() {} } diff --git a/telephony/java/com/android/internal/telephony/CallTracker.java b/telephony/java/com/android/internal/telephony/CallTracker.java index 31f9e18..958481c 100644 --- a/telephony/java/com/android/internal/telephony/CallTracker.java +++ b/telephony/java/com/android/internal/telephony/CallTracker.java @@ -19,6 +19,8 @@ package com.android.internal.telephony; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; +import android.os.SystemProperties; +import android.text.TextUtils; import android.util.Log; import com.android.internal.telephony.CommandException; @@ -116,6 +118,48 @@ public abstract class CallTracker extends Handler { return pendingOperations == 0; } + /** + * Routine called from dial to check if the number is a test Emergency number + * and if so remap the number. This allows a short emergency number to be remapped + * to a regular number for testing how the frameworks handles emergency numbers + * without actually calling an emergency number. + * + * This is not a full test and is not a substitute for testing real emergency + * numbers but can be useful. + * + * To use this feature set a system property ril.test.emergencynumber to a pair of + * numbers separated by a colon. If the first number matches the number parameter + * this routine returns the second number. Example: + * + * ril.test.emergencynumber=112:1-123-123-45678 + * + * To test Dial 112 take call then hang up on MO device to enter ECM + * see RIL#processSolicited RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND + * + * @param number to test if it should be remapped + * @return the same number or the remapped number. + */ + protected String checkForTestEmergencyNumber(String dialString) { + String testEn = SystemProperties.get("ril.test.emergencynumber"); + if (DBG_POLL) { + log("checkForTestEmergencyNumber: dialString=" + dialString + + " testEn=" + testEn); + } + if (!TextUtils.isEmpty(testEn)) { + String values[] = testEn.split(":"); + log("checkForTestEmergencyNumber: values.length=" + values.length); + if (values.length == 2) { + if (values[0].equals( + android.telephony.PhoneNumberUtils.stripSeparators(dialString))) { + cm.testingEmergencyCall(); + log("checkForTestEmergencyNumber: remap " + + dialString + " to " + values[1]); + dialString = values[1]; + } + } + } + return dialString; + } //***** Overridden from Handler public abstract void handleMessage (Message msg); diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java index a0efab2..f7757b3 100644 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java @@ -1571,4 +1571,9 @@ public interface CommandsInterface { * @param response a callback message with the String response in the obj field */ public void requestIsimAuthentication(String nonce, Message response); + + /** + * Notifiy that we are testing an emergency call + */ + public void testingEmergencyCall(); } diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index 664a091..5d76484 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -225,7 +225,8 @@ public abstract class DataConnectionTracker extends Handler { // having to have different values for GSM and // CDMA. If so we can then remove the need for // getActionIntentReconnectAlarm. - protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason"; + protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = + "reconnect_alarm_extra_reason"; // Used for debugging. Send the INTENT with an optional counter value with the number // of times the setup is to fail before succeeding. If the counter isn't passed the diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index f587fe1..5afc1f3 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -60,6 +60,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; +import java.util.concurrent.atomic.AtomicBoolean; /** * {@hide} @@ -232,6 +233,9 @@ public final class RIL extends BaseCommands implements CommandsInterface { Object mLastNITZTimeInfo; + // When we are testing emergency calls + AtomicBoolean mTestingEmergencyCall = new AtomicBoolean(false); + //***** Events static final int EVENT_SEND = 1; @@ -2213,7 +2217,16 @@ public final class RIL extends BaseCommands implements CommandsInterface { case RIL_REQUEST_GET_IMSI: ret = responseString(p); break; case RIL_REQUEST_HANGUP: ret = responseVoid(p); break; case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: ret = responseVoid(p); break; - case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: ret = responseVoid(p); break; + case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: { + if (mTestingEmergencyCall.getAndSet(false)) { + if (mEmergencyCallbackModeRegistrant != null) { + riljLog("testing emergency call, notify ECM Registrants"); + mEmergencyCallbackModeRegistrant.notifyRegistrant(); + } + } + ret = responseVoid(p); + break; + } case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: ret = responseVoid(p); break; case RIL_REQUEST_CONFERENCE: ret = responseVoid(p); break; case RIL_REQUEST_UDUB: ret = responseVoid(p); break; @@ -3014,6 +3027,11 @@ public final class RIL extends BaseCommands implements CommandsInterface { num = p.readInt(); response = new ArrayList<DriverCall>(num); + if (RILJ_LOGV) { + riljLog("responseCallList: num=" + num + + " mEmergencyCallbackModeRegistrant=" + mEmergencyCallbackModeRegistrant + + " mTestingEmergencyCall=" + mTestingEmergencyCall.get()); + } for (int i = 0 ; i < num ; i++) { dc = new DriverCall(); @@ -3065,6 +3083,14 @@ public final class RIL extends BaseCommands implements CommandsInterface { Collections.sort(response); + if ((num == 0) && mTestingEmergencyCall.getAndSet(false)) { + if (mEmergencyCallbackModeRegistrant != null) { + riljLog("responseCallList: call ended, testing emergency call," + + " notify ECM Registrants"); + mEmergencyCallbackModeRegistrant.notifyRegistrant(); + } + } + return response; } @@ -3791,4 +3817,13 @@ public final class RIL extends BaseCommands implements CommandsInterface { send(rr); } + + /* (non-Javadoc) + * @see com.android.internal.telephony.BaseCommands#testingEmergencyCall() + */ + @Override + public void testingEmergencyCall() { + if (RILJ_LOGD) riljLog("testingEmergencyCall"); + mTestingEmergencyCall.set(true); + } } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java index 83efc51..f918dce 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java @@ -210,7 +210,8 @@ public final class CdmaCallTracker extends CallTracker { return dialThreeWay(dialString); } - pendingMO = new CdmaConnection(phone.getContext(), dialString, this, foregroundCall); + pendingMO = new CdmaConnection(phone.getContext(), checkForTestEmergencyNumber(dialString), + this, foregroundCall); hangupPendingMO = false; if (pendingMO.address == null || pendingMO.address.length() == 0 @@ -259,7 +260,7 @@ public final class CdmaCallTracker extends CallTracker { // Attach the new connection to foregroundCall pendingMO = new CdmaConnection(phone.getContext(), - dialString, this, foregroundCall); + checkForTestEmergencyNumber(dialString), this, foregroundCall); cm.sendCDMAFeatureCode(pendingMO.address, obtainMessage(EVENT_THREE_WAY_DIAL_L2_RESULT_CDMA)); return pendingMO; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java index 06f310c..425afe6 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmCallTracker.java @@ -198,7 +198,8 @@ public final class GsmCallTracker extends CallTracker { throw new CallStateException("cannot dial in current state"); } - pendingMO = new GsmConnection(phone.getContext(), dialString, this, foregroundCall); + pendingMO = new GsmConnection(phone.getContext(), checkForTestEmergencyNumber(dialString), + this, foregroundCall); hangupPendingMO = false; if (pendingMO.address == null || pendingMO.address.length() == 0 diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 8f04dba..66e9487 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -131,7 +131,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { private static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect"; - private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "type"; + private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type"; private static final String INTENT_DATA_STALL_ALARM = "com.android.internal.telephony.gprs-data-stall"; diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 643cb8d..3904c21 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -40,6 +40,15 @@ <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + + <activity + android:name="ClipRegionActivity" + android:label="_ClipRegion"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> <activity android:name="DisplayListLayersActivity" diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java new file mode 100644 index 0000000..b2a508b --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipRegionActivity.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.test.hwui; + +import android.app.Activity; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Region; +import android.os.Bundle; +import android.view.View; + +@SuppressWarnings({"UnusedDeclaration"}) +public class ClipRegionActivity extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final RegionView view = new RegionView(this); + setContentView(view); + } + + public static class RegionView extends View { + public RegionView(Context c) { + super(c); + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + canvas.save(); + canvas.clipRect(100.0f, 100.0f, getWidth() - 100.0f, getHeight() - 100.0f, + Region.Op.DIFFERENCE); + canvas.drawARGB(255, 255, 0, 0); + canvas.restore(); + } + } +} diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 6ce665b..ec61403 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -1837,6 +1837,49 @@ String8 AaptDir::getPrintableSource() const // ========================================================================= // ========================================================================= +status_t AaptSymbols::applyJavaSymbols(const sp<AaptSymbols>& javaSymbols) +{ + status_t err = NO_ERROR; + size_t N = javaSymbols->mSymbols.size(); + for (size_t i=0; i<N; i++) { + const String8& name = javaSymbols->mSymbols.keyAt(i); + const AaptSymbolEntry& entry = javaSymbols->mSymbols.valueAt(i); + ssize_t pos = mSymbols.indexOfKey(name); + if (pos < 0) { + entry.sourcePos.error("Symbol '%s' declared with <java-symbol> not defined\n", name.string()); + err = UNKNOWN_ERROR; + continue; + } + //printf("**** setting symbol #%d/%d %s to isJavaSymbol=%d\n", + // i, N, name.string(), entry.isJavaSymbol ? 1 : 0); + mSymbols.editValueAt(pos).isJavaSymbol = entry.isJavaSymbol; + } + + N = javaSymbols->mNestedSymbols.size(); + for (size_t i=0; i<N; i++) { + const String8& name = javaSymbols->mNestedSymbols.keyAt(i); + const sp<AaptSymbols>& symbols = javaSymbols->mNestedSymbols.valueAt(i); + ssize_t pos = mNestedSymbols.indexOfKey(name); + if (pos < 0) { + SourcePos pos; + pos.error("Java symbol dir %s not defined\n", name.string()); + err = UNKNOWN_ERROR; + continue; + } + //printf("**** applying java symbols in dir %s\n", name.string()); + status_t myerr = mNestedSymbols.valueAt(pos)->applyJavaSymbols(symbols); + if (myerr != NO_ERROR) { + err = myerr; + } + } + + return err; +} + +// ========================================================================= +// ========================================================================= +// ========================================================================= + AaptAssets::AaptAssets() : AaptDir(String8(), String8()), mChanged(false), mHaveIncludedAssets(false), mRes(NULL) @@ -2404,6 +2447,48 @@ sp<AaptSymbols> AaptAssets::getSymbolsFor(const String8& name) return sym; } +sp<AaptSymbols> AaptAssets::getJavaSymbolsFor(const String8& name) +{ + sp<AaptSymbols> sym = mJavaSymbols.valueFor(name); + if (sym == NULL) { + sym = new AaptSymbols(); + mJavaSymbols.add(name, sym); + } + return sym; +} + +status_t AaptAssets::applyJavaSymbols() +{ + size_t N = mJavaSymbols.size(); + for (size_t i=0; i<N; i++) { + const String8& name = mJavaSymbols.keyAt(i); + const sp<AaptSymbols>& symbols = mJavaSymbols.valueAt(i); + ssize_t pos = mSymbols.indexOfKey(name); + if (pos < 0) { + SourcePos pos; + pos.error("Java symbol dir %s not defined\n", name.string()); + return UNKNOWN_ERROR; + } + //printf("**** applying java symbols in dir %s\n", name.string()); + status_t err = mSymbols.valueAt(pos)->applyJavaSymbols(symbols); + if (err != NO_ERROR) { + return err; + } + } + + return NO_ERROR; +} + +bool AaptAssets::isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const { + //printf("isJavaSymbol %s: public=%d, includePrivate=%d, isJavaSymbol=%d\n", + // sym.name.string(), sym.isPublic ? 1 : 0, includePrivate ? 1 : 0, + // sym.isJavaSymbol ? 1 : 0); + if (!mHavePrivateSymbols) return true; + if (sym.isPublic) return true; + if (includePrivate && sym.isJavaSymbol) return true; + return false; +} + status_t AaptAssets::buildIncludedResources(Bundle* bundle) { if (!mHaveIncludedAssets) { diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index c5a397c..1c653e1 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -315,16 +315,16 @@ class AaptSymbolEntry { public: AaptSymbolEntry() - : isPublic(false), typeCode(TYPE_UNKNOWN) + : isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN) { } AaptSymbolEntry(const String8& _name) - : name(_name), isPublic(false), typeCode(TYPE_UNKNOWN) + : name(_name), isPublic(false), isJavaSymbol(false), typeCode(TYPE_UNKNOWN) { } AaptSymbolEntry(const AaptSymbolEntry& o) : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic) - , comment(o.comment), typeComment(o.typeComment) + , isJavaSymbol(o.isJavaSymbol), comment(o.comment), typeComment(o.typeComment) , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal) { } @@ -332,6 +332,7 @@ public: { sourcePos = o.sourcePos; isPublic = o.isPublic; + isJavaSymbol = o.isJavaSymbol; comment = o.comment; typeComment = o.typeComment; typeCode = o.typeCode; @@ -344,6 +345,7 @@ public: SourcePos sourcePos; bool isPublic; + bool isJavaSymbol; String16 comment; String16 typeComment; @@ -401,6 +403,15 @@ public: return NO_ERROR; } + status_t makeSymbolJavaSymbol(const String8& name, const SourcePos& pos) { + if (!check_valid_symbol_name(name, pos, "symbol")) { + return BAD_VALUE; + } + AaptSymbolEntry& sym = edit_symbol(name, &pos); + sym.isJavaSymbol = true; + return NO_ERROR; + } + void appendComment(const String8& name, const String16& comment, const SourcePos& pos) { if (comment.size() <= 0) { return; @@ -441,6 +452,8 @@ public: return sym; } + status_t applyJavaSymbols(const sp<AaptSymbols>& javaSymbols); + const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const { return mSymbols; } const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const @@ -509,7 +522,11 @@ public: virtual ~AaptAssets() { delete mRes; } const String8& getPackage() const { return mPackage; } - void setPackage(const String8& package) { mPackage = package; mSymbolsPrivatePackage = package; } + void setPackage(const String8& package) { + mPackage = package; + mSymbolsPrivatePackage = package; + mHavePrivateSymbols = false; + } const SortedVector<AaptGroupEntry>& getGroupEntries() const; @@ -532,11 +549,22 @@ public: sp<AaptSymbols> getSymbolsFor(const String8& name); + sp<AaptSymbols> getJavaSymbolsFor(const String8& name); + + status_t applyJavaSymbols(); + const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; } String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; } - void setSymbolsPrivatePackage(const String8& pkg) { mSymbolsPrivatePackage = pkg; } - + void setSymbolsPrivatePackage(const String8& pkg) { + mSymbolsPrivatePackage = pkg; + mHavePrivateSymbols = mSymbolsPrivatePackage != mPackage; + } + + bool havePrivateSymbols() const { return mHavePrivateSymbols; } + + bool isJavaSymbol(const AaptSymbolEntry& sym, bool includePrivate) const; + status_t buildIncludedResources(Bundle* bundle); status_t addIncludedResources(const sp<AaptFile>& file); const ResTable& getIncludedResources() const; @@ -576,7 +604,9 @@ private: String8 mPackage; SortedVector<AaptGroupEntry> mGroupEntries; DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols; + DefaultKeyedVector<String8, sp<AaptSymbols> > mJavaSymbols; String8 mSymbolsPrivatePackage; + bool mHavePrivateSymbols; Vector<sp<AaptDir> > mResDirs; diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 607056a..c79e243 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -1617,6 +1617,12 @@ int doPackage(Bundle* bundle) goto bail; } + // Update symbols with information about which ones are needed as Java symbols. + assets->applyJavaSymbols(); + if (SourcePos::hasErrors()) { + goto bail; + } + // If we've been asked to generate a dependency file, do that here if (bundle->getGenDependencies()) { // If this is the packaging step, generate the dependency file next to @@ -1638,7 +1644,7 @@ int doPackage(Bundle* bundle) } // Write out R.java constants - if (assets->getPackage() == assets->getSymbolsPrivatePackage()) { + if (!assets->havePrivateSymbols()) { if (bundle->getCustomPackage() == NULL) { // Write the R.java file into the appropriate class directory // e.g. gen/com/foo/app/R.java diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index c0fe538..7eaf528 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -1808,7 +1808,7 @@ static status_t writeSymbolClass( if (sym.typeCode != AaptSymbolEntry::TYPE_INT32) { continue; } - if (!includePrivate && !sym.isPublic) { + if (!assets->isJavaSymbol(sym, includePrivate)) { continue; } String16 name(sym.name); @@ -1864,7 +1864,7 @@ static status_t writeSymbolClass( if (sym.typeCode != AaptSymbolEntry::TYPE_STRING) { continue; } - if (!includePrivate && !sym.isPublic) { + if (!assets->isJavaSymbol(sym, includePrivate)) { continue; } String16 name(sym.name); @@ -1976,7 +1976,8 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets, "\n" "package %s;\n\n", package.string()); - status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0, bundle->getNonConstantId()); + status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, + className, 0, bundle->getNonConstantId()); if (err != NO_ERROR) { return err; } diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index f59bba2..7a0499c 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -753,6 +753,7 @@ status_t compileResourceFile(Bundle* bundle, const String16 public16("public"); const String16 public_padding16("public-padding"); const String16 private_symbols16("private-symbols"); + const String16 java_symbol16("java-symbol"); const String16 add_resource16("add-resource"); const String16 skip16("skip"); const String16 eat_comment16("eat-comment"); @@ -1058,6 +1059,49 @@ status_t compileResourceFile(Bundle* bundle, } continue; + } else if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { + SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); + + String16 type; + ssize_t typeIdx = block.indexOfAttribute(NULL, "type"); + if (typeIdx < 0) { + srcPos.error("A 'type' attribute is required for <public>\n"); + hasErrors = localHasErrors = true; + } + type = String16(block.getAttributeStringValue(typeIdx, &len)); + + String16 name; + ssize_t nameIdx = block.indexOfAttribute(NULL, "name"); + if (nameIdx < 0) { + srcPos.error("A 'name' attribute is required for <public>\n"); + hasErrors = localHasErrors = true; + } + name = String16(block.getAttributeStringValue(nameIdx, &len)); + + sp<AaptSymbols> symbols = assets->getJavaSymbolsFor(String8("R")); + if (symbols != NULL) { + symbols = symbols->addNestedSymbol(String8(type), srcPos); + } + if (symbols != NULL) { + symbols->makeSymbolJavaSymbol(String8(name), srcPos); + String16 comment( + block.getComment(&len) ? block.getComment(&len) : nulStr); + symbols->appendComment(String8(name), comment, srcPos); + } else { + srcPos.error("Unable to create symbols!\n"); + hasErrors = localHasErrors = true; + } + + while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) { + if (code == ResXMLTree::END_TAG) { + if (strcmp16(block.getElementName(&len), java_symbol16.string()) == 0) { + break; + } + } + } + continue; + + } else if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) { SourcePos srcPos(in->getPrintableSource(), block.getLineNumber()); |
