diff options
45 files changed, 754 insertions, 306 deletions
diff --git a/api/current.xml b/api/current.xml index 2fbd374..9bd5c01 100644 --- a/api/current.xml +++ b/api/current.xml @@ -78032,17 +78032,6 @@ visibility="public" > </method> -<method name="isEnabled" - return="boolean" - abstract="true" - native="false" - synchronized="false" - static="false" - final="false" - deprecated="not deprecated" - visibility="public" -> -</method> <method name="removeListener" return="void" abstract="true" diff --git a/common/java/com/android/common/speech/LoggingEvents.java b/common/java/com/android/common/speech/LoggingEvents.java index eb9476f..3b3ecb8 100644 --- a/common/java/com/android/common/speech/LoggingEvents.java +++ b/common/java/com/android/common/speech/LoggingEvents.java @@ -16,9 +16,6 @@ package com.android.common.speech; -import android.content.Intent; -import android.content.Context; - /** * Logging event constants used for Voice Search and VoiceIME. These are the * keys and values of extras to be specified in logging broadcast intents. diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 3dfbe71..ec9f3b4 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -903,15 +903,14 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS if (mSearchable == null) { return; } + SearchableInfo searchable = mSearchable; + // First stop the existing search before starting voice search, or else we'll end + // up showing the search dialog again once we return to the app. + cancel(); try { - // First stop the existing search before starting voice search, or else we'll end - // up showing the search dialog again once we return to the app. - ((SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE)). - stopSearch(); - - if (mSearchable.getVoiceSearchLaunchWebSearch()) { + if (searchable.getVoiceSearchLaunchWebSearch()) { getContext().startActivity(mVoiceWebSearchIntent); - } else if (mSearchable.getVoiceSearchLaunchRecognizer()) { + } else if (searchable.getVoiceSearchLaunchRecognizer()) { Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent); getContext().startActivity(appSearchIntent); } diff --git a/core/java/android/backup/RestoreSession.java b/core/java/android/backup/RestoreSession.java index a884793..6b35fe8 100644 --- a/core/java/android/backup/RestoreSession.java +++ b/core/java/android/backup/RestoreSession.java @@ -21,6 +21,7 @@ import android.backup.RestoreObserver; import android.backup.RestoreSet; import android.content.Context; import android.os.Handler; +import android.os.Message; import android.os.RemoteException; import android.util.Log; @@ -116,61 +117,44 @@ public class RestoreSession { final Handler mHandler; final RestoreObserver mAppObserver; + static final int MSG_RESTORE_STARTING = 1; + static final int MSG_UPDATE = 2; + static final int MSG_RESTORE_FINISHED = 3; + RestoreObserverWrapper(Context context, RestoreObserver appObserver) { - mHandler = new Handler(context.getMainLooper()); + mHandler = new Handler(context.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_RESTORE_STARTING: + mAppObserver.restoreStarting(msg.arg1); + break; + case MSG_UPDATE: + mAppObserver.onUpdate(msg.arg1); + break; + case MSG_RESTORE_FINISHED: + mAppObserver.restoreFinished(msg.arg1); + break; + } + } + }; mAppObserver = appObserver; } - // Wrap the IRestoreObserver -> RestoreObserver callthrough in Runnables - // posted to the app's main thread looper. - class RestoreStartingRunnable implements Runnable { - int mNumPackages; - - RestoreStartingRunnable(int numPackages) { - mNumPackages = numPackages; - } - - public void run() { - mAppObserver.restoreStarting(mNumPackages); - } - } - - class OnUpdateRunnable implements Runnable { - int mNowRestoring; - - OnUpdateRunnable(int nowRestoring) { - mNowRestoring = nowRestoring; - } - - public void run() { - mAppObserver.onUpdate(mNowRestoring); - } - } - - class RestoreFinishedRunnable implements Runnable { - int mError; - - RestoreFinishedRunnable(int error) { - mError = error; - } - - public void run() { - mAppObserver.restoreFinished(mError); - } - } - - // The actual redirection code is quite simple using just the - // above Runnable subclasses + // Binder calls into this object just enqueue on the main-thread handler public void restoreStarting(int numPackages) { - mHandler.post(new RestoreStartingRunnable(numPackages)); + mHandler.sendMessage( + mHandler.obtainMessage(MSG_RESTORE_STARTING, numPackages, 0)); } public void onUpdate(int nowBeingRestored) { - mHandler.post(new OnUpdateRunnable(nowBeingRestored)); + mHandler.sendMessage( + mHandler.obtainMessage(MSG_UPDATE, nowBeingRestored, 0)); } public void restoreFinished(int error) { - mHandler.post(new RestoreFinishedRunnable(error)); + mHandler.sendMessage( + mHandler.obtainMessage(MSG_RESTORE_FINISHED, error, 0)); } } } diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java index 0b1b16b..36255d0 100644 --- a/core/java/android/provider/Browser.java +++ b/core/java/android/provider/Browser.java @@ -56,29 +56,6 @@ public class Browser { "com.android.browser.application_id"; /** - * The name of the extra data in the VIEW intent. The data is in boolean. - * <p> - * If the Browser is handling the intent and the setting for - * USE_LOCATION_FOR_SERVICES is allow, the Browser will send the location in - * the POST data if this extra data is presented and it is true. - * <p> - * pending api approval - * @hide - */ - public static final String EXTRA_APPEND_LOCATION = "com.android.browser.append_location"; - - /** - * The name of the extra data in the VIEW intent. The data is in the format of - * a byte array. - * <p> - * Any value sent here will be passed in the http request to the provided url as post data. - * <p> - * pending api approval - * @hide - */ - public static final String EXTRA_POST_DATA = "com.android.browser.post_data"; - - /** * The name of the extra data in the VIEW intent. The data are key/value * pairs in the format of Bundle. They will be sent in the HTTP request * headers for the provided url. The keys can't be the standard HTTP headers diff --git a/core/java/android/speech/RecognizerResultsIntent.java b/core/java/android/speech/RecognizerResultsIntent.java new file mode 100644 index 0000000..882f213 --- /dev/null +++ b/core/java/android/speech/RecognizerResultsIntent.java @@ -0,0 +1,122 @@ +/* + * 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 android.speech; + +import java.util.ArrayList; + +/** + * Constants for intents related to showing speech recognition results. + * + * These constants should not be needed for normal utilization of speech recognition. They + * would only be called if you wanted to trigger a view of voice search results in your + * application, or implemented if you wanted to offer a different view for voice search results + * with your application. + * + * The standard behavior here for someone receiving an {@link #ACTION_VOICE_SEARCH_RESULTS} is to + * first retrieve the list of {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS}, and use any provided + * HTML for that result in {@link #EXTRA_VOICE_SEARCH_RESULT_HTML}, if available, to display + * the search results. If that is not available, then the corresponding url for that result in + * {@link #EXTRA_VOICE_SEARCH_RESULT_URLS} should be used. And if even that is not available, + * then a search url should be constructed from the actual recognition result string. + * + * @hide for making public in a later release + */ +public class RecognizerResultsIntent { + private RecognizerResultsIntent() { + // Not for instantiating. + } + + /** + * Intent that can be sent by implementations of voice search to display the results of + * a search in, for example, a web browser. + * + * This intent should always be accompanied by at least + * {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS}, and optionally but recommended, + * {@link #EXTRA_VOICE_SEARCH_RESULT_URLS}, and sometimes + * {@link #EXTRA_VOICE_SEARCH_RESULT_HTML} and + * {@link #EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS}. + * + * These are parallel arrays, where a recognition result string at index N of + * {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS} should be accompanied by a url to use for + * searching based on that string at index N of {@link #EXTRA_VOICE_SEARCH_RESULT_URLS}, + * and, possibly, the full html to display for that result at index N of + * {@link #EXTRA_VOICE_SEARCH_RESULT_HTML}. If full html is provided, a base url (or + * list of base urls) should be provided with {@link #EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS}. + * + * @hide for making public in a later release + */ + public static final String ACTION_VOICE_SEARCH_RESULTS = + "android.speech.action.VOICE_SEARCH_RESULTS"; + + /** + * The key to an extra {@link ArrayList} of {@link String}s that contains the list of + * recognition alternates from voice search, in order from highest to lowest confidence. + * + * @hide for making public in a later release + */ + public static final String EXTRA_VOICE_SEARCH_RESULT_STRINGS = + "android.speech.extras.VOICE_SEARCH_RESULT_STRINGS"; + + /** + * The key to an extra {@link ArrayList} of {@link String}s that contains the search urls + * to use, if available, for the recognition alternates provided in + * {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS}. This list should always be the same size as the + * one provided in {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS} - if a result cannot provide a + * search url, that entry in this ArrayList should be <code>null</code>, and the implementor of + * {@link #ACTION_VOICE_SEARCH_RESULTS} should execute a search of its own choosing, + * based on the recognition result string. + * + * @hide for making public in a later release + */ + public static final String EXTRA_VOICE_SEARCH_RESULT_URLS = + "android.speech.extras.VOICE_SEARCH_RESULT_URLS"; + + /** + * The key to an extra {@link ArrayList} of {@link String}s that contains the html content to + * use, if available, for the recognition alternates provided in + * {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS}. This list should always be the same size as the + * one provided in {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS} - if a result cannot provide + * html, that entry in this list should be <code>null</code>, and the implementor of + * {@link #ACTION_VOICE_SEARCH_RESULTS} should back off to the corresponding url provided in + * {@link #EXTRA_VOICE_SEARCH_RESULT_URLS}, if available, or else should execute a search of + * its own choosing, based on the recognition result string. + * + * Currently this html content should be expected in the form of an "inline:" uri for the + * Browser. In the future this may change to a "content://" uri or some other identifier. + * Anyone who reads this extra should confirm that a result is in fact an "inline:" uri and + * back off to the urls or strings gracefully if it is not, thus maintaining future backwards + * compatibility if this changes. + * + * @hide not to be exposed immediately as the implementation details may change + */ + public static final String EXTRA_VOICE_SEARCH_RESULT_HTML = + "android.speech.extras.VOICE_SEARCH_RESULT_HTML"; + + /** + * The key to an extra {@link ArrayList} of {@link String}s that contains the base url to + * assume when interpreting html provided in {@link #EXTRA_VOICE_SEARCH_RESULT_HTML}. + * + * A list of size 1 may be provided to apply the same base url to all html results. + * A list of the same size as {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS} may be provided + * to apply different base urls to each different html result in the + * {@link #EXTRA_VOICE_SEARCH_RESULT_HTML} list. + * + * @hide not to be exposed immediately as the implementation details may change + */ + public static final String EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS = + "android.speech.extras.VOICE_SEARCH_RESULT_HTML_BASE_URLS"; +} diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 39b0a63..815e557 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -3109,6 +3109,7 @@ public class WebView extends AbsoluteLayout zoomScale = mZoomScale; // set mZoomScale to be 0 as we have done animation mZoomScale = 0; + WebViewCore.resumeUpdatePicture(mWebViewCore); // call invalidate() again to draw with the final filters invalidate(); if (mNeedToAdjustWebTextView) { @@ -3952,8 +3953,9 @@ public class WebView extends AbsoluteLayout super.onSizeChanged(w, h, ow, oh); // Center zooming to the center of the screen. if (mZoomScale == 0) { // unless we're already zooming - mZoomCenterX = getViewWidth() * .5f; - mZoomCenterY = getViewHeight() * .5f; + // To anchor at top left corner. + mZoomCenterX = 0; + mZoomCenterY = getVisibleTitleHeight(); mAnchorX = viewToContentX((int) mZoomCenterX + mScrollX); mAnchorY = viewToContentY((int) mZoomCenterY + mScrollY); } @@ -3996,7 +3998,6 @@ public class WebView extends AbsoluteLayout @Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); - sendOurVisibleRect(); } @@ -4458,7 +4459,7 @@ public class WebView extends AbsoluteLayout deltaX = 0; deltaY = 0; - WebViewCore.reducePriority(mWebViewCore); + WebViewCore.reducePriority(); if (!mDragFromTextInput) { nativeHideCursor(); } @@ -4621,7 +4622,7 @@ public class WebView extends AbsoluteLayout || computeVerticalScrollExtent() < computeVerticalScrollRange())) { // we will not rewrite drag code here, but we // will try fling if it applies. - WebViewCore.reducePriority(mWebViewCore); + WebViewCore.reducePriority(); // fall through to TOUCH_DRAG_MODE } else { break; @@ -4658,7 +4659,7 @@ public class WebView extends AbsoluteLayout break; } mLastVelocity = 0; - WebViewCore.resumePriority(mWebViewCore); + WebViewCore.resumePriority(); break; case TOUCH_DRAG_START_MODE: case TOUCH_DONE_MODE: @@ -4707,7 +4708,7 @@ public class WebView extends AbsoluteLayout mVelocityTracker = null; } if (mTouchMode == TOUCH_DRAG_MODE) { - WebViewCore.resumePriority(mWebViewCore); + WebViewCore.resumePriority(); } mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); @@ -5033,7 +5034,7 @@ public class WebView extends AbsoluteLayout vy = vy * 3 / 4; } if ((maxX == 0 && vy == 0) || (maxY == 0 && vx == 0)) { - WebViewCore.resumePriority(mWebViewCore); + WebViewCore.resumePriority(); return; } float currentVelocity = mScroller.getCurrVelocity(); @@ -5090,6 +5091,7 @@ public class WebView extends AbsoluteLayout mInvInitialZoomScale = 1.0f / oldScale; mInvFinalZoomScale = 1.0f / mActualScale; mZoomScale = mActualScale; + WebViewCore.pauseUpdatePicture(mWebViewCore); invalidate(); return true; } else { @@ -5904,7 +5906,7 @@ public class WebView extends AbsoluteLayout } break; case RESUME_WEBCORE_PRIORITY: - WebViewCore.resumePriority(mWebViewCore); + WebViewCore.resumePriority(); break; case LONG_PRESS_CENTER: @@ -6068,7 +6070,7 @@ public class WebView extends AbsoluteLayout case SHOW_RECT_MSG_ID: { WebViewCore.ShowRectData data = (WebViewCore.ShowRectData) msg.obj; int x = mScrollX; - int left = contentToViewDimension(data.mLeft); + int left = contentToViewX(data.mLeft); int width = contentToViewDimension(data.mWidth); int maxWidth = contentToViewDimension(data.mContentWidth); int viewWidth = getViewWidth(); @@ -6079,21 +6081,29 @@ public class WebView extends AbsoluteLayout x += (int) (left + data.mXPercentInDoc * width - mScrollX - data.mXPercentInView * viewWidth); } + if (DebugFlags.WEB_VIEW) { + Log.v(LOGTAG, "showRectMsg=(left=" + left + ",width=" + + width + ",maxWidth=" + maxWidth + + ",viewWidth=" + viewWidth + ",x=" + + x + ",xPercentInDoc=" + data.mXPercentInDoc + + ",xPercentInView=" + data.mXPercentInView+ ")"); + } // use the passing content width to cap x as the current // mContentWidth may not be updated yet x = Math.max(0, (Math.min(maxWidth, x + viewWidth)) - viewWidth); - int y = mScrollY; - int top = contentToViewDimension(data.mTop); + int top = contentToViewY(data.mTop); int height = contentToViewDimension(data.mHeight); int maxHeight = contentToViewDimension(data.mContentHeight); int viewHeight = getViewHeight(); - if (height < viewHeight) { - // middle align - y += top + height / 2 - mScrollY - viewHeight / 2; - } else { - y += (int) (top + data.mYPercentInDoc * height - - mScrollY - data.mYPercentInView * viewHeight); + int y = (int) (top + data.mYPercentInDoc * height - + data.mYPercentInView * viewHeight); + if (DebugFlags.WEB_VIEW) { + Log.v(LOGTAG, "showRectMsg=(top=" + top + ",height=" + + height + ",maxHeight=" + maxHeight + + ",viewHeight=" + viewHeight + ",y=" + + y + ",yPercentInDoc=" + data.mYPercentInDoc + + ",yPercentInView=" + data.mYPercentInView+ ")"); } // use the passing content height to cap y as the current // mContentHeight may not be updated yet diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index 310721f..d4bb1d2 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -1676,6 +1676,9 @@ final class WebViewCore { // Used to avoid posting more than one split picture message. private boolean mSplitPictureIsScheduled; + // Used to suspend drawing. + private boolean mDrawIsPaused; + // mRestoreState is set in didFirstLayout(), and reset in the next // webkitDraw after passing it to the UI thread. private RestoreState mRestoreState = null; @@ -1788,7 +1791,7 @@ final class WebViewCore { return result; } - static void reducePriority(WebViewCore core) { + static void reducePriority() { // remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY); sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY); @@ -1796,7 +1799,7 @@ final class WebViewCore { .obtainMessage(WebCoreThread.REDUCE_PRIORITY)); } - static void resumePriority(WebViewCore core) { + static void resumePriority() { // remove the pending REDUCE_PRIORITY and RESUME_PRIORITY messages sWebCoreHandler.removeMessages(WebCoreThread.REDUCE_PRIORITY); sWebCoreHandler.removeMessages(WebCoreThread.RESUME_PRIORITY); @@ -1814,6 +1817,33 @@ final class WebViewCore { .obtainMessage(WebCoreThread.BLOCK_CACHE_TICKER)); } + static void pauseUpdatePicture(WebViewCore core) { + // Note: there is one possible failure mode. If pauseUpdatePicture() is + // called from UI thread while WEBKIT_DRAW is just pulled out of the + // queue in WebCore thread to be executed. Then update won't be blocked. + if (core != null) { + synchronized (core) { + core.mDrawIsPaused = true; + if (core.mDrawIsScheduled) { + core.mEventHub.removeMessages(EventHub.WEBKIT_DRAW); + } + } + } + + } + + static void resumeUpdatePicture(WebViewCore core) { + if (core != null) { + synchronized (core) { + core.mDrawIsPaused = false; + if (core.mDrawIsScheduled) { + core.mDrawIsScheduled = false; + core.contentDraw(); + } + } + } + } + ////////////////////////////////////////////////////////////////////////// private void restoreState(int index) { @@ -1842,6 +1872,7 @@ final class WebViewCore { synchronized (this) { if (mDrawIsScheduled) return; mDrawIsScheduled = true; + if (mDrawIsPaused) return; mEventHub.sendMessage(Message.obtain(null, EventHub.WEBKIT_DRAW)); } } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 3a4b92d..1cc1c26 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -16,6 +16,8 @@ package android.widget; +import com.android.internal.R; + import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; @@ -30,6 +32,7 @@ import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.util.AttributeSet; +import android.util.Log; import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; @@ -41,14 +44,12 @@ import android.view.ViewConfiguration; import android.view.ViewDebug; import android.view.ViewGroup; import android.view.ViewTreeObserver; +import android.view.ContextMenu.ContextMenuInfo; import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnectionWrapper; import android.view.inputmethod.InputMethodManager; -import android.view.ContextMenu.ContextMenuInfo; - -import com.android.internal.R; import java.util.ArrayList; import java.util.List; @@ -120,13 +121,24 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * Indicates the touch gesture is a scroll */ static final int TOUCH_MODE_SCROLL = 3; - + /** * Indicates the view is in the process of being flung */ static final int TOUCH_MODE_FLING = 4; /** + * Indicates the touch gesture is an overscroll - a scroll beyond the beginning or end. + */ + static final int TOUCH_MODE_OVERSCROLL = 5; + + /** + * Indicates the view is being flung outside of normal content bounds + * and will spring back. + */ + static final int TOUCH_MODE_OVERFLING = 6; + + /** * Regular layout - usually an unsolicited layout from the view system */ static final int LAYOUT_NORMAL = 0; @@ -437,6 +449,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private int mMaximumVelocity; final boolean[] mIsScrap = new boolean[1]; + + // True when the popup should be hidden because of a call to + // dispatchDisplayHint() + private boolean mPopupHidden; /** * Interface definition for a callback to be invoked when the list or grid @@ -1915,6 +1931,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mLayoutMode = LAYOUT_NORMAL; layoutChildren(); } + } else { + int touchMode = mTouchMode; + if (touchMode == TOUCH_MODE_OVERSCROLL || touchMode == TOUCH_MODE_OVERFLING) { + mScrollY = 0; + if (mFlingRunnable != null) { + mFlingRunnable.endFling(); + } + } } } @@ -1947,43 +1971,56 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te switch (action) { case MotionEvent.ACTION_DOWN: { - int motionPosition = pointToPosition(x, y); - if (!mDataChanged) { - if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0) - && (getAdapter().isEnabled(motionPosition))) { - // User clicked on an actual view (and was not stopping a fling). It might be a - // click or a scroll. Assume it is a click until proven otherwise - mTouchMode = TOUCH_MODE_DOWN; - // FIXME Debounce - if (mPendingCheckForTap == null) { - mPendingCheckForTap = new CheckForTap(); - } - postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); - } else { - if (ev.getEdgeFlags() != 0 && motionPosition < 0) { - // If we couldn't find a view to click on, but the down event was touching - // the edge, we will bail out and try again. This allows the edge correcting - // code in ViewRoot to try to find a nearby view to select - return false; + switch (mTouchMode) { + case TOUCH_MODE_OVERFLING: { + mFlingRunnable.endFling(); + mTouchMode = TOUCH_MODE_OVERSCROLL; + mLastY = y; + mMotionCorrection = 0; + break; + } + + default: { + int motionPosition = pointToPosition(x, y); + if (!mDataChanged) { + if ((mTouchMode != TOUCH_MODE_FLING) && (motionPosition >= 0) + && (getAdapter().isEnabled(motionPosition))) { + // User clicked on an actual view (and was not stopping a fling). It might be a + // click or a scroll. Assume it is a click until proven otherwise + mTouchMode = TOUCH_MODE_DOWN; + // FIXME Debounce + if (mPendingCheckForTap == null) { + mPendingCheckForTap = new CheckForTap(); + } + postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout()); + } else { + if (ev.getEdgeFlags() != 0 && motionPosition < 0) { + // If we couldn't find a view to click on, but the down event was touching + // the edge, we will bail out and try again. This allows the edge correcting + // code in ViewRoot to try to find a nearby view to select + return false; + } + // User clicked on whitespace, or stopped a fling. It is a scroll. + createScrollingCache(); + mTouchMode = TOUCH_MODE_SCROLL; + mMotionCorrection = 0; + motionPosition = findMotionRow(y); + reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } - // User clicked on whitespace, or stopped a fling. It is a scroll. - createScrollingCache(); - mTouchMode = TOUCH_MODE_SCROLL; - mMotionCorrection = 0; - motionPosition = findMotionRow(y); - reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL); } - } - if (motionPosition >= 0) { - // Remember where the motion event started - v = getChildAt(motionPosition - mFirstPosition); - mMotionViewOriginalTop = v.getTop(); - mMotionX = x; - mMotionY = y; - mMotionPosition = motionPosition; + if (motionPosition >= 0) { + // Remember where the motion event started + v = getChildAt(motionPosition - mFirstPosition); + mMotionViewOriginalTop = v.getTop(); + mMotionX = x; + mMotionY = y; + mMotionPosition = motionPosition; + } + mLastY = Integer.MIN_VALUE; + break; + } } - mLastY = Integer.MIN_VALUE; break; } @@ -2008,17 +2045,61 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (y != mLastY) { deltaY -= mMotionCorrection; int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY; + + int motionViewPrevTop = 0; + View motionView = this.getChildAt(mMotionPosition - mFirstPosition); + if (motionView != null) { + motionViewPrevTop = motionView.getTop(); + } // No need to do all this work if we're not going to move anyway if (incrementalDeltaY != 0) { trackMotionScroll(deltaY, incrementalDeltaY); } // Check to see if we have bumped into the scroll limit - View motionView = this.getChildAt(mMotionPosition - mFirstPosition); + motionView = this.getChildAt(mMotionPosition - mFirstPosition); if (motionView != null) { // Check if the top of the motion view is where it is // supposed to be - if (motionView.getTop() != mMotionViewNewTop) { + final int motionViewRealTop = motionView.getTop(); + final int motionViewNewTop = mMotionViewNewTop; + if (motionViewRealTop != motionViewNewTop) { + // Apply overscroll + + mScrollY -= incrementalDeltaY - (motionViewRealTop - motionViewPrevTop); + mTouchMode = TOUCH_MODE_OVERSCROLL; + invalidate(); + } + } + mLastY = y; + } + break; + + case TOUCH_MODE_OVERSCROLL: + if (y != mLastY) { + deltaY -= mMotionCorrection; + int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY; + + final int oldScroll = mScrollY; + final int newScroll = oldScroll - incrementalDeltaY; + + if ((oldScroll >= 0 && newScroll <= 0) || + (oldScroll <= 0 && newScroll >= 0)) { + // Coming back to 'real' list scrolling + incrementalDeltaY = -newScroll; + mScrollY = 0; + + // No need to do all this work if we're not going to move anyway + if (incrementalDeltaY != 0) { + trackMotionScroll(incrementalDeltaY, incrementalDeltaY); + } + + // Check to see if we are back in + View motionView = this.getChildAt(mMotionPosition - mFirstPosition); + if (motionView != null) { + int topOffset = motionView.getTop() - mMotionViewNewTop; + mTouchMode = TOUCH_MODE_SCROLL; + // We did not scroll the full amount. Treat this essentially like the // start of a new touch scroll final int motionPosition = findMotionRow(y); @@ -2029,6 +2110,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mMotionY = y; mMotionPosition = motionPosition; } + } else { + mScrollY -= incrementalDeltaY; + invalidate(); } mLastY = y; } @@ -2120,6 +2204,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mFlingRunnable = new FlingRunnable(); } reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); + mFlingRunnable.start(-initialVelocity); } else { mTouchMode = TOUCH_MODE_REST; @@ -2130,6 +2215,24 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); } + break; + + case TOUCH_MODE_OVERSCROLL: + if (mFlingRunnable == null) { + mFlingRunnable = new FlingRunnable(); + } + final VelocityTracker velocityTracker = mVelocityTracker; + velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); + final int initialVelocity = (int) velocityTracker.getYVelocity(); + + reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); + if (Math.abs(initialVelocity) > mMinimumVelocity) { + mFlingRunnable.startOverfling(-initialVelocity); + } else { + mFlingRunnable.startSpringback(); + } + + break; } setPressed(false); @@ -2157,25 +2260,38 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } case MotionEvent.ACTION_CANCEL: { - mTouchMode = TOUCH_MODE_REST; - setPressed(false); - View motionView = this.getChildAt(mMotionPosition - mFirstPosition); - if (motionView != null) { - motionView.setPressed(false); - } - clearScrollingCache(); + switch (mTouchMode) { + case TOUCH_MODE_OVERSCROLL: + if (mFlingRunnable == null) { + mFlingRunnable = new FlingRunnable(); + } + mFlingRunnable.startSpringback(); + break; + + case TOUCH_MODE_OVERFLING: + // Do nothing - let it play out. + break; + + default: + mTouchMode = TOUCH_MODE_REST; + setPressed(false); + View motionView = this.getChildAt(mMotionPosition - mFirstPosition); + if (motionView != null) { + motionView.setPressed(false); + } + clearScrollingCache(); - final Handler handler = getHandler(); - if (handler != null) { - handler.removeCallbacks(mPendingCheckForLongPress); - } + final Handler handler = getHandler(); + if (handler != null) { + handler.removeCallbacks(mPendingCheckForLongPress); + } - if (mVelocityTracker != null) { - mVelocityTracker.recycle(); - mVelocityTracker = null; + if (mVelocityTracker != null) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } } } - } return true; @@ -2205,8 +2321,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te switch (action) { case MotionEvent.ACTION_DOWN: { + int touchMode = mTouchMode; + if (touchMode == TOUCH_MODE_OVERFLING || touchMode == TOUCH_MODE_OVERSCROLL) { + return true; + } + int motionPosition = findMotionRow(y); - if (mTouchMode != TOUCH_MODE_FLING && motionPosition >= 0) { + if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) { // User clicked on an actual view (and was not stopping a fling). // Remember where the motion event started v = getChildAt(motionPosition - mFirstPosition); @@ -2218,7 +2339,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te clearScrollingCache(); } mLastY = Integer.MIN_VALUE; - if (mTouchMode == TOUCH_MODE_FLING) { + if (touchMode == TOUCH_MODE_FLING) { return true; } break; @@ -2293,18 +2414,18 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te /** * Tracks the decay of a fling scroll */ - private Scroller mScroller; + private OverScroller mScroller; /** * Y value reported by mScroller on the previous fling */ private int mLastFlingY; - public FlingRunnable() { - mScroller = new Scroller(getContext()); + FlingRunnable() { + mScroller = new OverScroller(getContext()); } - public void start(int initialVelocity) { + void start(int initialVelocity) { int initialY = initialVelocity < 0 ? Integer.MAX_VALUE : 0; mLastFlingY = initialY; mScroller.fling(0, initialY, 0, initialVelocity, @@ -2319,77 +2440,117 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } } - + + void startSpringback() { + if (mScroller.springback(0, mScrollY, 0, 0, 0, 0)) { + mTouchMode = TOUCH_MODE_OVERFLING; + invalidate(); + post(this); + } + } + + void startOverfling(int initialVelocity) { + mScroller.fling(0, mScrollY, 0, initialVelocity, 0, 0, 0, 0, 0, getHeight()); + mTouchMode = TOUCH_MODE_OVERFLING; + invalidate(); + post(this); + } + private void endFling() { mTouchMode = TOUCH_MODE_REST; reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE); clearScrollingCache(); + removeCallbacks(this); } public void run() { - if (mTouchMode != TOUCH_MODE_FLING) { - return; - } - - if (mItemCount == 0 || getChildCount() == 0) { - endFling(); + switch (mTouchMode) { + default: return; - } - - final Scroller scroller = mScroller; - boolean more = scroller.computeScrollOffset(); - final int y = scroller.getCurrY(); + + case TOUCH_MODE_FLING: { + if (mItemCount == 0 || getChildCount() == 0) { + endFling(); + return; + } - // Flip sign to convert finger direction to list items direction - // (e.g. finger moving down means list is moving towards the top) - int delta = mLastFlingY - y; + final OverScroller scroller = mScroller; + boolean more = scroller.computeScrollOffset(); + final int y = scroller.getCurrY(); - // Pretend that each frame of a fling scroll is a touch scroll - if (delta > 0) { - // List is moving towards the top. Use first view as mMotionPosition - mMotionPosition = mFirstPosition; - final View firstView = getChildAt(0); - mMotionViewOriginalTop = firstView.getTop(); + // Flip sign to convert finger direction to list items direction + // (e.g. finger moving down means list is moving towards the top) + int delta = mLastFlingY - y; - // Don't fling more than 1 screen - delta = Math.min(getHeight() - mPaddingBottom - mPaddingTop - 1, delta); - } else { - // List is moving towards the bottom. Use last view as mMotionPosition - int offsetToLast = getChildCount() - 1; - mMotionPosition = mFirstPosition + offsetToLast; + // Pretend that each frame of a fling scroll is a touch scroll + if (delta > 0) { + // List is moving towards the top. Use first view as mMotionPosition + mMotionPosition = mFirstPosition; + final View firstView = getChildAt(0); + mMotionViewOriginalTop = firstView.getTop(); - final View lastView = getChildAt(offsetToLast); - mMotionViewOriginalTop = lastView.getTop(); + // Don't fling more than 1 screen + delta = Math.min(getHeight() - mPaddingBottom - mPaddingTop - 1, delta); + } else { + // List is moving towards the bottom. Use last view as mMotionPosition + int offsetToLast = getChildCount() - 1; + mMotionPosition = mFirstPosition + offsetToLast; - // Don't fling more than 1 screen - delta = Math.max(-(getHeight() - mPaddingBottom - mPaddingTop - 1), delta); - } + final View lastView = getChildAt(offsetToLast); + mMotionViewOriginalTop = lastView.getTop(); - trackMotionScroll(delta, delta); + // Don't fling more than 1 screen + delta = Math.max(-(getHeight() - mPaddingBottom - mPaddingTop - 1), delta); + } - // Check to see if we have bumped into the scroll limit - View motionView = getChildAt(mMotionPosition - mFirstPosition); - if (motionView != null) { - // Check if the top of the motion view is where it is - // supposed to be - if (motionView.getTop() != mMotionViewNewTop) { - more = false; + // Do something different on overscroll - offsetChildrenTopAndBottom() + trackMotionScroll(delta, delta); + + // Check to see if we have bumped into the scroll limit + View motionView = getChildAt(mMotionPosition - mFirstPosition); + if (motionView != null) { + // Check if the top of the motion view is where it is + // supposed to be + if (motionView.getTop() != mMotionViewNewTop) { + float vel = scroller.getCurrVelocity(); + if (delta > 0) { + vel = -vel; + } + startOverfling(Math.round(vel)); + break; + } } - } - if (more) { - invalidate(); - mLastFlingY = y; - post(this); - } else { - endFling(); - if (PROFILE_FLINGING) { - if (mFlingProfilingStarted) { - Debug.stopMethodTracing(); - mFlingProfilingStarted = false; + if (more) { + invalidate(); + mLastFlingY = y; + post(this); + } else { + endFling(); + + if (PROFILE_FLINGING) { + if (mFlingProfilingStarted) { + Debug.stopMethodTracing(); + mFlingProfilingStarted = false; + } } } + break; } + + case TOUCH_MODE_OVERFLING: { + final OverScroller scroller = mScroller; + if (scroller.computeScrollOffset()) { + mScrollY = scroller.getCurrY(); + invalidate(); + post(this); + } else { + endFling(); + } + break; + } + } + } } @@ -2867,6 +3028,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } break; } + mPopupHidden = hint == INVISIBLE; } /** @@ -2876,6 +3038,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (mPopup != null) { mPopup.dismiss(); } + mPopupHidden = false; } /** @@ -3152,7 +3315,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public void onGlobalLayout() { if (isShown()) { // Show the popup if we are filtered - if (mFiltered && mPopup != null && !mPopup.isShowing()) { + if (mFiltered && mPopup != null && !mPopup.isShowing() && !mPopupHidden) { showPopup(); } } else { diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java index 9067e26..3dab9f2 100644 --- a/core/java/android/widget/DateTimeView.java +++ b/core/java/android/widget/DateTimeView.java @@ -203,7 +203,7 @@ public class DateTimeView extends TextView { private DateFormat getDateFormat() { String format = Settings.System.getString(getContext().getContentResolver(), Settings.System.DATE_FORMAT); - if ("".equals(format)) { + if (format == null || "".equals(format)) { return DateFormat.getDateInstance(DateFormat.SHORT); } else { return new SimpleDateFormat(format); diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java index b22ae3c..44d415e 100644 --- a/core/java/android/widget/OverScroller.java +++ b/core/java/android/widget/OverScroller.java @@ -383,4 +383,15 @@ public class OverScroller { public int getFinalY() { return mCurrScroller.getFinalY(); } + + /** + * @hide + * Returns the current velocity. + * + * @return The original velocity less the deceleration. Result may be + * negative. + */ + public float getCurrVelocity() { + return mCurrScroller.getCurrVelocity(); + } } diff --git a/core/jni/CursorWindow.cpp b/core/jni/CursorWindow.cpp index 694514e..7877921 100644 --- a/core/jni/CursorWindow.cpp +++ b/core/jni/CursorWindow.cpp @@ -18,7 +18,8 @@ #define LOG_TAG "CursorWindow" #include <utils/Log.h> -#include <binder/MemoryDealer.h> +#include <binder/MemoryHeapBase.h> +#include <binder/MemoryBase.h> #include <assert.h> #include <string.h> @@ -37,7 +38,7 @@ CursorWindow::CursorWindow(size_t maxSize) : { } -bool CursorWindow::setMemory(sp<IMemory> memory) +bool CursorWindow::setMemory(const sp<IMemory>& memory) { mMemory = memory; mData = (uint8_t *) memory->pointer(); @@ -47,7 +48,6 @@ bool CursorWindow::setMemory(sp<IMemory> memory) mHeader = (window_header_t *) mData; // Make the window read-only - mHeap = NULL; ssize_t size = memory->size(); mSize = size; mMaxSize = size; @@ -60,9 +60,10 @@ bool CursorWindow::initBuffer(bool localOnly) { //TODO Use a non-memory dealer mmap region for localOnly - mHeap = new MemoryDealer(mMaxSize, "CursorWindow"); - if (mHeap != NULL) { - mMemory = mHeap->allocate(mMaxSize); + sp<MemoryHeapBase> heap; + heap = new MemoryHeapBase(mMaxSize, 0, "CursorWindow"); + if (heap != NULL) { + mMemory = new MemoryBase(heap, 0, mMaxSize); if (mMemory != NULL) { mData = (uint8_t *) mMemory->pointer(); if (mData) { @@ -75,10 +76,10 @@ bool CursorWindow::initBuffer(bool localOnly) return true; } } - LOGE("memory dealer allocation failed"); + LOGE("CursorWindow heap allocation failed"); return false; } else { - LOGE("failed to create the memory dealer"); + LOGE("failed to create the CursorWindow heap"); return false; } } diff --git a/core/jni/CursorWindow.h b/core/jni/CursorWindow.h index e98b009..3fcb560 100644 --- a/core/jni/CursorWindow.h +++ b/core/jni/CursorWindow.h @@ -21,7 +21,7 @@ #include <stddef.h> #include <stdint.h> -#include <binder/MemoryDealer.h> +#include <binder/IMemory.h> #include <utils/RefBase.h> #include <jni.h> @@ -101,7 +101,7 @@ class CursorWindow public: CursorWindow(size_t maxSize); CursorWindow(){} - bool setMemory(sp<IMemory>); + bool setMemory(const sp<IMemory>&); ~CursorWindow(); bool initBuffer(bool localOnly); @@ -189,7 +189,6 @@ private: size_t mSize; size_t mMaxSize; window_header_t * mHeader; - sp<MemoryDealer> mHeap; sp<IMemory> mMemory; /** diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 9a8af3f..2b8ddc4 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -231,4 +231,10 @@ <!-- Component name of the default wallpaper. This will be ImageWallpaper if not specified --> <string name="default_wallpaper_component">@null</string> + + <!-- Component name of the service providing network location support. --> + <string name="config_networkLocationProvider">@null</string> + + <!-- Component name of the service providing geocoder API support. --> + <string name="config_geocodeProvider">@null</string> </resources> diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index 82dd2b5..f8bc7ab 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -95,6 +95,7 @@ private: kRequiresAllocateBufferOnOutputPorts = 32, kRequiresFlushBeforeShutdown = 64, kDefersOutputBufferAllocation = 128, + kDecoderLiesAboutNumberOfChannels = 256, }; struct BufferInfo { diff --git a/include/ui/CameraParameters.h b/include/ui/CameraParameters.h index b9c2bbe..2c29bfb 100644 --- a/include/ui/CameraParameters.h +++ b/include/ui/CameraParameters.h @@ -34,8 +34,10 @@ public: void set(const char *key, const char *value); void set(const char *key, int value); + void setFloat(const char *key, float value); const char *get(const char *key) const; int getInt(const char *key) const; + float getFloat(const char *key) const; /* preview-size=176x144 */ void setPreviewSize(int width, int height); diff --git a/libs/ui/CameraParameters.cpp b/libs/ui/CameraParameters.cpp index 495e164..c4958a0 100644 --- a/libs/ui/CameraParameters.cpp +++ b/libs/ui/CameraParameters.cpp @@ -209,6 +209,13 @@ void CameraParameters::set(const char *key, int value) set(key, str); } +void CameraParameters::setFloat(const char *key, float value) +{ + char str[16]; // 14 should be enough. We overestimate to be safe. + snprintf(str, sizeof(str), "%g", value); + set(key, str); +} + const char *CameraParameters::get(const char *key) const { String8 v = mMap.valueFor(String8(key)); @@ -225,6 +232,13 @@ int CameraParameters::getInt(const char *key) const return strtol(v, 0, 0); } +float CameraParameters::getFloat(const char *key) const +{ + const char *v = get(key); + if (v == 0) return -1; + return strtof(v, 0); +} + static int parse_size(const char *str, int &width, int &height) { // Find the width. diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl index 7da16e4..9fe6ab4 100644 --- a/location/java/android/location/ILocationProvider.aidl +++ b/location/java/android/location/ILocationProvider.aidl @@ -37,7 +37,6 @@ interface ILocationProvider { int getAccuracy(); void enable(); void disable(); - boolean isEnabled(); int getStatus(out Bundle extras); long getStatusUpdateTime(); void enableLocationTracking(boolean enable); diff --git a/location/java/android/location/LocationProviderImpl.java b/location/java/android/location/LocationProviderImpl.java index 9a3624e..7148a02 100644 --- a/location/java/android/location/LocationProviderImpl.java +++ b/location/java/android/location/LocationProviderImpl.java @@ -75,10 +75,6 @@ public abstract class LocationProviderImpl extends LocationProvider { LocationProviderImpl.this.disable(); } - public boolean isEnabled() { - return LocationProviderImpl.this.isEnabled(); - } - public int getStatus(Bundle extras) { return LocationProviderImpl.this.getStatus(extras); } @@ -138,11 +134,6 @@ public abstract class LocationProviderImpl extends LocationProvider { public abstract void disable(); /** - * Returns true if the provider is currently enabled - */ - public abstract boolean isEnabled(); - - /** * Returns a information on the status of this provider. * {@link #OUT_OF_SERVICE} is returned if the provider is * out of service, and this is not expected to change in the near diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java index 9d67882..c8809a2 100755 --- a/location/java/com/android/internal/location/GpsLocationProvider.java +++ b/location/java/com/android/internal/location/GpsLocationProvider.java @@ -571,10 +571,6 @@ public class GpsLocationProvider extends ILocationProvider.Stub { } } - public boolean isEnabled() { - return mEnabled; - } - public int getStatus(Bundle extras) { if (extras != null) { extras.putInt("satellites", mSvCount); diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java index 89337b3..2e0be89 100644 --- a/location/java/com/android/internal/location/LocationProviderProxy.java +++ b/location/java/com/android/internal/location/LocationProviderProxy.java @@ -40,6 +40,7 @@ public class LocationProviderProxy implements IBinder.DeathRecipient { private final String mName; private final ILocationProvider mProvider; private boolean mLocationTracking = false; + private boolean mEnabled = false; private long mMinTime = 0; private boolean mDead; @@ -152,6 +153,7 @@ public class LocationProviderProxy implements IBinder.DeathRecipient { public void enable() { try { mProvider.enable(); + mEnabled = true; } catch (RemoteException e) { Log.e(TAG, "enable failed", e); } @@ -160,18 +162,14 @@ public class LocationProviderProxy implements IBinder.DeathRecipient { public void disable() { try { mProvider.disable(); + mEnabled = false; } catch (RemoteException e) { Log.e(TAG, "disable failed", e); } } public boolean isEnabled() { - try { - return mProvider.isEnabled(); - } catch (RemoteException e) { - Log.e(TAG, "isEnabled failed", e); - return false; - } + return mEnabled; } public int getStatus(Bundle extras) { diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java index 2614f82..7d9e86c 100644 --- a/location/java/com/android/internal/location/MockProvider.java +++ b/location/java/com/android/internal/location/MockProvider.java @@ -95,10 +95,6 @@ public class MockProvider extends ILocationProvider.Stub { return mStatusUpdateTime; } - public boolean isEnabled() { - return mEnabled; - } - public int getAccuracy() { return mAccuracy; } diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index 162bebb..550b84d 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -28,7 +28,8 @@ #include <string.h> #include <cutils/atomic.h> #include <cutils/properties.h> -#include <binder/MemoryDealer.h> +#include <binder/MemoryBase.h> +#include <binder/MemoryHeapBase.h> #include <android_runtime/ActivityManager.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> @@ -62,8 +63,6 @@ MetadataRetrieverClient::MetadataRetrieverClient(pid_t pid) { LOGV("MetadataRetrieverClient constructor pid(%d)", pid); mPid = pid; - mThumbnailDealer = NULL; - mAlbumArtDealer = NULL; mThumbnail = NULL; mAlbumArt = NULL; mRetriever = NULL; @@ -94,8 +93,6 @@ void MetadataRetrieverClient::disconnect() LOGV("disconnect from pid %d", mPid); Mutex::Autolock lock(mLock); mRetriever.clear(); - mThumbnailDealer.clear(); - mAlbumArtDealer.clear(); mThumbnail.clear(); mAlbumArt.clear(); mMode = METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL; @@ -242,7 +239,6 @@ sp<IMemory> MetadataRetrieverClient::captureFrame() LOGV("captureFrame"); Mutex::Autolock lock(mLock); mThumbnail.clear(); - mThumbnailDealer.clear(); if (mRetriever == NULL) { LOGE("retriever is not initialized"); return NULL; @@ -253,16 +249,15 @@ sp<IMemory> MetadataRetrieverClient::captureFrame() return NULL; } size_t size = sizeof(VideoFrame) + frame->mSize; - mThumbnailDealer = new MemoryDealer(size, "MetadataRetrieverClient"); - if (mThumbnailDealer == NULL) { + sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient"); + if (heap == NULL) { LOGE("failed to create MemoryDealer"); delete frame; return NULL; } - mThumbnail = mThumbnailDealer->allocate(size); + mThumbnail = new MemoryBase(heap, 0, size); if (mThumbnail == NULL) { LOGE("not enough memory for VideoFrame size=%u", size); - mThumbnailDealer.clear(); delete frame; return NULL; } @@ -283,7 +278,6 @@ sp<IMemory> MetadataRetrieverClient::extractAlbumArt() LOGV("extractAlbumArt"); Mutex::Autolock lock(mLock); mAlbumArt.clear(); - mAlbumArtDealer.clear(); if (mRetriever == NULL) { LOGE("retriever is not initialized"); return NULL; @@ -294,16 +288,15 @@ sp<IMemory> MetadataRetrieverClient::extractAlbumArt() return NULL; } size_t size = sizeof(MediaAlbumArt) + albumArt->mSize; - mAlbumArtDealer = new MemoryDealer(size, "MetadataRetrieverClient"); - if (mAlbumArtDealer == NULL) { + sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient"); + if (heap == NULL) { LOGE("failed to create MemoryDealer object"); delete albumArt; return NULL; } - mAlbumArt = mAlbumArtDealer->allocate(size); + mAlbumArt = new MemoryBase(heap, 0, size); if (mAlbumArt == NULL) { LOGE("not enough memory for MediaAlbumArt size=%u", size); - mAlbumArtDealer.clear(); delete albumArt; return NULL; } diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h index 8cb8ad1..4aab94f 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.h +++ b/media/libmediaplayerservice/MetadataRetrieverClient.h @@ -63,8 +63,6 @@ private: int mMode; // Keep the shared memory copy of album art and capture frame (for thumbnail) - sp<MemoryDealer> mAlbumArtDealer; - sp<MemoryDealer> mThumbnailDealer; sp<IMemory> mAlbumArt; sp<IMemory> mThumbnail; }; diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index e17fbb8..90bbdfe 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -290,6 +290,7 @@ uint32_t OMXCodec::getComponentQuirks(const char *componentName) { } if (!strcmp(componentName, "OMX.TI.MP3.decode")) { quirks |= kNeedsFlushBeforeDisable; + quirks |= kDecoderLiesAboutNumberOfChannels; } if (!strcmp(componentName, "OMX.TI.AAC.decode")) { quirks |= kNeedsFlushBeforeDisable; @@ -2817,7 +2818,9 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { if ((OMX_U32)numChannels != params.nChannels) { LOGW("Codec outputs a different number of channels than " - "the input stream contains."); + "the input stream contains (contains %d channels, " + "codec outputs %ld channels).", + numChannels, params.nChannels); } mOutputFormat->setCString( @@ -2825,8 +2828,12 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { // Use the codec-advertised number of channels, as some // codecs appear to output stereo even if the input data is - // mono. - mOutputFormat->setInt32(kKeyChannelCount, params.nChannels); + // mono. If we know the codec lies about this information, + // use the actual number of channels instead. + mOutputFormat->setInt32( + kKeyChannelCount, + (mQuirks & kDecoderLiesAboutNumberOfChannels) + ? numChannels : params.nChannels); // The codec-reported sampleRate is not reliable... mOutputFormat->setInt32(kKeySampleRate, sampleRate); diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index ef6ede0..ed91eea 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -20,6 +20,7 @@ #include "../include/SoftwareRenderer.h" #include <binder/MemoryHeapBase.h> +#include <binder/MemoryHeapPmem.h> #include <media/stagefright/MediaDebug.h> #include <ui/ISurface.h> @@ -38,8 +39,16 @@ SoftwareRenderer::SoftwareRenderer( mDecodedWidth(decodedWidth), mDecodedHeight(decodedHeight), mFrameSize(mDecodedWidth * mDecodedHeight * 2), // RGB565 - mMemoryHeap(new MemoryHeapBase(2 * mFrameSize)), mIndex(0) { + // TODO: How do I allocate physical memory on Droid? + mMemoryHeap = new MemoryHeapBase("/dev/pmem_adsp", 2 * mFrameSize); + if (mMemoryHeap->heapID() < 0) { + LOGI("Creating physical memory heap failed, reverting to regular heap."); + mMemoryHeap = new MemoryHeapBase(2 * mFrameSize); + } else { + mMemoryHeap = new MemoryHeapPmem(mMemoryHeap); + } + CHECK(mISurface.get() != NULL); CHECK(mDecodedWidth > 0); CHECK(mDecodedHeight > 0); diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 2875c13..fae89b9 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -1389,9 +1389,20 @@ void glCopyTexImage2D( // (x,y) is the lower-left corner of colorBuffer y = cbSurface.height - (y + height); + /* The GLES spec says: + * If any of the pixels within the specified rectangle are outside + * the framebuffer associated with the current rendering context, + * then the values obtained for those pixels are undefined. + */ + if (x+width > GLint(cbSurface.width)) + width = cbSurface.width - x; + + if (y+height > GLint(cbSurface.height)) + height = cbSurface.height - y; + int err = copyPixels(c, txSurface, 0, 0, - cbSurface, x, y, cbSurface.width, cbSurface.height); + cbSurface, x, y, width, height); if (err) { ogles_error(c, err); } @@ -1439,6 +1450,17 @@ void glCopyTexSubImage2D( const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; y = cbSurface.height - (y + height); + /* The GLES spec says: + * If any of the pixels within the specified rectangle are outside + * the framebuffer associated with the current rendering context, + * then the values obtained for those pixels are undefined. + */ + if (x+width > GLint(cbSurface.width)) + width = cbSurface.width - x; + + if (y+height > GLint(cbSurface.height)) + height = cbSurface.height - y; + int err = copyPixels(c, surface, xoffset, yoffset, cbSurface, x, y, width, height); diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java index 8797a42..ec7c60b 100644 --- a/services/java/com/android/server/AppWidgetService.java +++ b/services/java/com/android/server/AppWidgetService.java @@ -1107,10 +1107,9 @@ class AppWidgetService extends IAppWidgetService.Stub } }; - // TODO: If there's a better way of matching an intent filter against the - // packages for a given package, use that. void addProvidersForPackageLocked(String pkgName) { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + intent.setPackage(pkgName); List<ResolveInfo> broadcastReceivers = mPackageManager.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA); @@ -1125,11 +1124,10 @@ class AppWidgetService extends IAppWidgetService.Stub } } - // TODO: If there's a better way of matching an intent filter against the - // packages for a given package, use that. void updateProvidersForPackageLocked(String pkgName) { HashSet<String> keep = new HashSet<String>(); Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); + intent.setPackage(pkgName); List<ResolveInfo> broadcastReceivers = mPackageManager.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA); diff --git a/telephony/java/com/android/internal/telephony/BaseCommands.java b/telephony/java/com/android/internal/telephony/BaseCommands.java index 7586ba2..7421854 100644 --- a/telephony/java/com/android/internal/telephony/BaseCommands.java +++ b/telephony/java/com/android/internal/telephony/BaseCommands.java @@ -65,6 +65,7 @@ public abstract class BaseCommands implements CommandsInterface { protected RegistrantList mT53ClirInfoRegistrants = new RegistrantList(); protected RegistrantList mT53AudCntrlInfoRegistrants = new RegistrantList(); protected RegistrantList mRingbackToneRegistrants = new RegistrantList(); + protected RegistrantList mResendIncallMuteRegistrants = new RegistrantList(); protected Registrant mSMSRegistrant; protected Registrant mNITZTimeRegistrant; @@ -579,6 +580,15 @@ public abstract class BaseCommands implements CommandsInterface { mRingbackToneRegistrants.remove(h); } + public void registerForResendIncallMute(Handler h, int what, Object obj) { + Registrant r = new Registrant (h, what, obj); + mResendIncallMuteRegistrants.add(r); + } + + public void unregisterForResendIncallMute(Handler h) { + mResendIncallMuteRegistrants.remove(h); + } + //***** Protected Methods /** * Store new RadioState and send notification based on the changes diff --git a/telephony/java/com/android/internal/telephony/CommandsInterface.java b/telephony/java/com/android/internal/telephony/CommandsInterface.java index 1d9f10a..d90c305 100644 --- a/telephony/java/com/android/internal/telephony/CommandsInterface.java +++ b/telephony/java/com/android/internal/telephony/CommandsInterface.java @@ -537,6 +537,18 @@ public interface CommandsInterface { void registerForRingbackTone(Handler h, int what, Object obj); void unregisterForRingbackTone(Handler h); + /** + * Registers the handler when mute/unmute need to be resent to get + * uplink audio during a call.<p> + * + * @param h Handler for notification message. + * @param what User-defined message code. + * @param obj User object. + * + */ + void registerForResendIncallMute(Handler h, int what, Object obj); + void unregisterForResendIncallMute(Handler h); + /** * Supply the ICC PIN to the ICC card * diff --git a/telephony/java/com/android/internal/telephony/Phone.java b/telephony/java/com/android/internal/telephony/Phone.java index a8ad80e..7179bef 100644 --- a/telephony/java/com/android/internal/telephony/Phone.java +++ b/telephony/java/com/android/internal/telephony/Phone.java @@ -407,6 +407,16 @@ public interface Phone { void unregisterForRingbackTone(Handler h); + /** + * Registers the handler to reset the uplink mute state to get + * uplink audio. + */ + void registerForResendIncallMute(Handler h, int what, Object obj); + + /** + * Unregisters for resend incall mute notifications. + */ + void unregisterForResendIncallMute(Handler h); /** * Notifies when a voice connection has disconnected, either due to local @@ -1389,11 +1399,6 @@ public interface Phone { /* CDMA support methods */ - /* - * TODO(Moto) TODO(Teleca): can getCdmaMin, getEsn, getMeid use more generic calls - * already defined getXxxx above? - */ - /** * Retrieves the MIN for CDMA phones. */ diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index bad9ab3..358af95 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -495,6 +495,16 @@ public abstract class PhoneBase extends Handler implements Phone { mCM.unregisterForRingbackTone(h); } + // Inherited documentation suffices. + public void registerForResendIncallMute(Handler h, int what, Object obj) { + mCM.registerForResendIncallMute(h,what,obj); + } + + // Inherited documentation suffices. + public void unregisterForResendIncallMute(Handler h) { + mCM.unregisterForResendIncallMute(h); + } + /** * Subclasses of Phone probably want to replace this with a * version scoped to their packages diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index d56d99f..6d3798e 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -351,6 +351,14 @@ public class PhoneProxy extends Handler implements Phone { mActivePhone.unregisterForRingbackTone(h); } + public void registerForResendIncallMute(Handler h, int what, Object obj) { + mActivePhone.registerForResendIncallMute(h,what,obj); + } + + public void unregisterForResendIncallMute(Handler h) { + mActivePhone.unregisterForResendIncallMute(h); + } + public boolean getIccRecordsLoaded() { return mActivePhone.getIccRecordsLoaded(); } diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java index 1ffcf9b..d8e313a 100644 --- a/telephony/java/com/android/internal/telephony/RIL.java +++ b/telephony/java/com/android/internal/telephony/RIL.java @@ -2333,6 +2333,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { case RIL_UNSOL_CDMA_INFO_REC: ret = responseCdmaInformationRecord(p); break; case RIL_UNSOL_OEM_HOOK_RAW: ret = responseRaw(p); break; case RIL_UNSOL_RINGBACK_TONE: ret = responseInts(p); break; + case RIL_UNSOL_RESEND_INCALL_MUTE: ret = responseVoid(p); break; default: throw new RuntimeException("Unrecognized unsol response: " + response); @@ -2625,6 +2626,15 @@ public final class RIL extends BaseCommands implements CommandsInterface { mRingbackToneRegistrants.notifyRegistrants( new AsyncResult (null, playtone, null)); } + break; + + case RIL_UNSOL_RESEND_INCALL_MUTE: + if (RILJ_LOGD) unsljLogRet(response, ret); + + if (mResendIncallMuteRegistrants != null) { + mResendIncallMuteRegistrants.notifyRegistrants( + new AsyncResult (null, ret, null)); + } } } @@ -2972,10 +2982,9 @@ public final class RIL extends BaseCommands implements CommandsInterface { numServiceCategories = p.readInt(); if (numServiceCategories == 0) { - // TODO(Teleca) TODO(Moto): The logic of providing default - // values should not be done by this transport layer. And - // needs to be done by the vendor ril or application logic. - // TODO(Google): Remove ASAP + // TODO: The logic of providing default values should + // not be done by this transport layer. And needs to + // be done by the vendor ril or application logic. int numInts; numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES * CDMA_BSI_NO_OF_INTS_STRUCT + 1; response = new int[numInts]; @@ -3268,6 +3277,7 @@ public final class RIL extends BaseCommands implements CommandsInterface { case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC"; case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW"; case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONG"; + case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE"; default: return "<unknown reponse>"; } } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index c29adcf..4d8c7ec 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -259,4 +259,5 @@ cat include/telephony/ril.h | \ int RIL_UNSOL_CDMA_INFO_REC = 1027; int RIL_UNSOL_OEM_HOOK_RAW = 1028; int RIL_UNSOL_RINGBACK_TONE = 1029; + int RIL_UNSOL_RESEND_INCALL_MUTE = 1030; } diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java index d4b1652..1f5accf 100755 --- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java +++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java @@ -681,7 +681,7 @@ public class CDMAPhone extends PhoneBase { public String getVoiceMailNumber() { String number = null; SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); - // TODO(Moto): The default value of voicemail number should be read from a system property + // TODO: The default value of voicemail number should be read from a system property number = sp.getString(VM_NUMBER_CDMA, "*86"); return number; } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java index 7402769..ce6530a 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaInformationRecords.java @@ -74,7 +74,7 @@ public final class CdmaInformationRecords { break; case RIL_CDMA_T53_RELEASE_INFO_REC: - // TODO(Moto): WHAT to do, for now fall through and throw exception + // TODO: WHAT to do, for now fall through and throw exception default: throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got " + CdmaInformationRecords.idToString(id) + " "); diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java index 42feaa9..7f2ba47 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java @@ -1622,9 +1622,7 @@ final class CdmaServiceStateTracker extends ServiceStateTracker { * Returns IMSI as MCC + MNC + MIN */ String getImsi() { - // TODO(Moto): When RUIM is enabled, IMSI will come from RUIM - // not build-time props. Moto will provide implementation - // for RUIM-ready case later. + // TODO: When RUIM is enabled, IMSI will come from RUIM not build-time props. String operatorNumeric = SystemProperties.get( TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, ""); diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java index b9ece8b..87b0c60 100644 --- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java +++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java @@ -166,10 +166,8 @@ public final class RuimRecords extends IccRecords { return null; } - // TODO(Moto): mncLength is not set anywhere. if (mncLength != UNINITIALIZED && mncLength != UNKNOWN) { // Length = length of MCC + length of MNC - // TODO: change spec name // length of mcc = 3 (3GPP2 C.S0005 - Section 2.3) return mImsi.substring(0, 3 + mncLength); } diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h index c53f7f1..cbb5203 100644 --- a/tools/aapt/Bundle.h +++ b/tools/aapt/Bundle.h @@ -38,7 +38,7 @@ public: mUpdate(false), mExtending(false), mRequireLocalization(false), mPseudolocalize(false), mUTF8(false), mEncodingSpecified(false), mValues(false), - mCompressionMethod(0), mOutputAPKFile(NULL), + mCompressionMethod(0), mOutputAPKFile(NULL), mManifestPackageNameOverride(NULL), mAssetSourceDir(NULL), mProguardFile(NULL), mAndroidManifestFile(NULL), mPublicOutputFile(NULL), mRClassDir(NULL), mResourceIntermediatesDir(NULL), @@ -88,6 +88,8 @@ public: void setJunkPath(bool val) { mJunkPath = val; } const char* getOutputAPKFile() const { return mOutputAPKFile; } void setOutputAPKFile(const char* val) { mOutputAPKFile = val; } + const char* getManifestPackageNameOverride() const { return mManifestPackageNameOverride; } + void setManifestPackageNameOverride(const char * val) { mManifestPackageNameOverride = val; } /* * Input options. @@ -178,6 +180,7 @@ private: int mCompressionMethod; bool mJunkPath; const char* mOutputAPKFile; + const char* mManifestPackageNameOverride; const char* mAssetSourceDir; const char* mProguardFile; const char* mAndroidManifestFile; diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp index 1e6b52e..6675ac2 100644 --- a/tools/aapt/Main.cpp +++ b/tools/aapt/Main.cpp @@ -436,6 +436,15 @@ int main(int argc, char* const argv[]) } else if (strcmp(cp, "-utf16") == 0) { bundle.setEncodingSpecified(true); bundle.setUTF8(false); + } else if (strcmp(cp, "-rename-manifest-package") == 0) { + argc--; + argv++; + if (!argc) { + fprintf(stderr, "ERROR: No argument supplied for '--rename-manifest-package' option\n"); + wantUsage = true; + goto bail; + } + bundle.setManifestPackageNameOverride(argv[0]); } else { fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp); wantUsage = true; diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index d53c472..0d2ea60 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -489,11 +489,11 @@ static bool applyFileOverlay(Bundle *bundle, DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles = baseGroup->getFiles(); for (size_t i=0; i < baseFiles.size(); i++) { - printf("baseFile %d has flavor %s\n", i, + printf("baseFile %ld has flavor %s\n", i, baseFiles.keyAt(i).toString().string()); } for (size_t i=0; i < overlayFiles.size(); i++) { - printf("overlayFile %d has flavor %s\n", i, + printf("overlayFile %ld has flavor %s\n", i, overlayFiles.keyAt(i).toString().string()); } } @@ -507,7 +507,7 @@ static bool applyFileOverlay(Bundle *bundle, keyAt(overlayGroupIndex)); if(baseFileIndex < UNKNOWN_ERROR) { if (bundle->getVerbose()) { - printf("found a match (%d) for overlay file %s, for flavor %s\n", + printf("found a match (%ld) for overlay file %s, for flavor %s\n", baseFileIndex, overlayGroup->getLeaf().string(), overlayFiles.keyAt(overlayGroupIndex).toString().string()); @@ -562,6 +562,33 @@ void addTagAttribute(const sp<XMLNode>& node, const char* ns8, node->addAttribute(ns, attr, String16(value)); } +static void fullyQualifyClassName(String8& package, sp<XMLNode> node) { + XMLNode::attribute_entry* attr = node->editAttribute( + String16("http://schemas.android.com/apk/res/android"), String16("name")); + if (attr != NULL) { + String8 name(attr->string); + + // asdf --> package.asdf + // .asdf .a.b --> package.asdf package.a.b + // asdf.adsf --> asdf.asdf + String8 className; + const char* p = name.string(); + const char* q = strchr(p, '.'); + if (p == q) { + className += package; + className += name; + } else if (q == NULL) { + className += package; + className += "."; + className += name; + } else { + className += name; + } + NOISY(printf("Qualifying class '%s' to '%s'", name.string(), className.string())); + attr->string.setTo(String16(className)); + } +} + status_t massageManifest(Bundle* bundle, sp<XMLNode> root) { root = root->searchElement(String16(), String16("manifest")); @@ -591,7 +618,36 @@ status_t massageManifest(Bundle* bundle, sp<XMLNode> root) addTagAttribute(vers, RESOURCES_ANDROID_NAMESPACE, "maxSdkVersion", bundle->getMaxSdkVersion()); } - + + // Deal with manifest package name overrides + const char* manifestPackageNameOverride = bundle->getManifestPackageNameOverride(); + if (manifestPackageNameOverride != NULL) { + // Update the actual package name + XMLNode::attribute_entry* attr = root->editAttribute(String16(), String16("package")); + if (attr == NULL) { + fprintf(stderr, "package name is required with --rename-manifest-package.\n"); + return UNKNOWN_ERROR; + } + String8 origPackage(attr->string); + attr->string.setTo(String16(manifestPackageNameOverride)); + NOISY(printf("Overriding package '%s' to be '%s'\n", origPackage.string(), manifestPackageNameOverride)); + + // Make class names fully qualified + sp<XMLNode> application = root->getChildElement(String16(), String16("application")); + if (application != NULL) { + fullyQualifyClassName(origPackage, application); + + Vector<sp<XMLNode> >& children = const_cast<Vector<sp<XMLNode> >&>(application->getChildren()); + for (size_t i = 0; i < children.size(); i++) { + sp<XMLNode> child = children.editItemAt(i); + String8 tag(child->getElementName()); + if (tag == "activity" || tag == "service" || tag == "receiver" || tag == "provider") { + fullyQualifyClassName(origPackage, child); + } + } + } + } + return NO_ERROR; } @@ -1173,14 +1229,14 @@ status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets) table.writePublicDefinitions(String16(assets->getPackage()), fp); fclose(fp); } - +#if 0 NOISY( ResTable rt; rt.add(resFile->getData(), resFile->getSize(), NULL); printf("Generated resources:\n"); rt.print(); ) - +#endif // These resources are now considered to be a part of the included // resources, for others to reference. err = assets->addIncludedResources(resFile); diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp index ec58591..51afc0a 100644 --- a/tools/aapt/StringPool.cpp +++ b/tools/aapt/StringPool.cpp @@ -25,7 +25,7 @@ void printStringPool(const ResStringPool* pool) const size_t NS = pool->size(); for (size_t s=0; s<NS; s++) { size_t len; - printf("String #%d: %s\n", s, + printf("String #%ld: %s\n", s, String8(pool->stringAt(s, &len)).string()); } } diff --git a/tools/aapt/XMLNode.cpp b/tools/aapt/XMLNode.cpp index 036dde4..4c59288 100644 --- a/tools/aapt/XMLNode.cpp +++ b/tools/aapt/XMLNode.cpp @@ -555,6 +555,19 @@ const XMLNode::attribute_entry* XMLNode::getAttribute(const String16& ns, return NULL; } +XMLNode::attribute_entry* XMLNode::editAttribute(const String16& ns, + const String16& name) +{ + for (size_t i=0; i<mAttributes.size(); i++) { + attribute_entry * ae = &mAttributes.editItemAt(i); + if (ae->ns == ns && ae->name == name) { + return ae; + } + } + + return NULL; +} + const String16& XMLNode::getCData() const { return mChars; diff --git a/tools/aapt/XMLNode.h b/tools/aapt/XMLNode.h index dc92fa7..e9a263b 100644 --- a/tools/aapt/XMLNode.h +++ b/tools/aapt/XMLNode.h @@ -95,6 +95,8 @@ public: const attribute_entry* getAttribute(const String16& ns, const String16& name) const; + attribute_entry* editAttribute(const String16& ns, const String16& name); + const String16& getCData() const; const String16& getComment() const; |