Merge change 23861 into eclair
* changes:
Replace the bugreport symlink with a tool that starts the new dumpstate service.
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index ef67611..51a0649 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -24,6 +24,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
+ SineSource.cpp \
record.cpp
LOCAL_SHARED_LIBRARIES := \
diff --git a/cmds/stagefright/JPEGSource.cpp b/cmds/stagefright/JPEGSource.cpp
index a7994ed..4e9ca4e 100644
--- a/cmds/stagefright/JPEGSource.cpp
+++ b/cmds/stagefright/JPEGSource.cpp
@@ -102,7 +102,7 @@
meta->setCString(kKeyMIMEType, "image/jpeg");
meta->setInt32(kKeyWidth, mWidth);
meta->setInt32(kKeyHeight, mHeight);
- meta->setInt32(kKeyCompressedSize, mSize);
+ meta->setInt32(kKeyMaxInputSize, mSize);
return meta;
}
diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp
new file mode 100644
index 0000000..3c25a7f
--- /dev/null
+++ b/cmds/stagefright/SineSource.cpp
@@ -0,0 +1,100 @@
+#include "SineSource.h"
+
+#include <math.h>
+
+#include <media/stagefright/MediaBufferGroup.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MetaData.h>
+
+namespace android {
+
+SineSource::SineSource(int32_t sampleRate, int32_t numChannels)
+ : mStarted(false),
+ mSampleRate(sampleRate),
+ mNumChannels(numChannels),
+ mPhase(0),
+ mGroup(NULL) {
+ CHECK(numChannels == 1 || numChannels == 2);
+}
+
+SineSource::~SineSource() {
+ if (mStarted) {
+ stop();
+ }
+}
+
+status_t SineSource::start(MetaData *params) {
+ CHECK(!mStarted);
+
+ mGroup = new MediaBufferGroup;
+ mGroup->add_buffer(new MediaBuffer(kBufferSize));
+
+ mPhase = 0;
+ mStarted = true;
+
+ return OK;
+}
+
+status_t SineSource::stop() {
+ CHECK(mStarted);
+
+ delete mGroup;
+ mGroup = NULL;
+
+ mStarted = false;
+
+ return OK;
+}
+
+sp<MetaData> SineSource::getFormat() {
+ sp<MetaData> meta = new MetaData;
+ meta->setCString(kKeyMIMEType, "audio/raw");
+ meta->setInt32(kKeyChannelCount, mNumChannels);
+ meta->setInt32(kKeySampleRate, mSampleRate);
+
+ return meta;
+}
+
+status_t SineSource::read(
+ MediaBuffer **out, const ReadOptions *options) {
+ *out = NULL;
+
+ MediaBuffer *buffer;
+ status_t err = mGroup->acquire_buffer(&buffer);
+
+ if (err != OK) {
+ return err;
+ }
+
+ size_t frameSize = mNumChannels * sizeof(int16_t);
+ size_t numFramesPerBuffer = buffer->size() / frameSize;
+
+ int16_t *ptr = (int16_t *)buffer->data();
+
+ const double k = kFrequency / mSampleRate * (2.0 * M_PI);
+
+ double x = mPhase * k;
+ for (size_t i = 0; i < numFramesPerBuffer; ++i) {
+ int16_t amplitude = (int16_t)(32767.0 * sin(x));
+
+ *ptr++ = amplitude;
+ if (mNumChannels == 2) {
+ *ptr++ = amplitude;
+ }
+
+ x += k;
+ }
+
+ buffer->meta_data()->setInt32(kKeyTimeUnits, mPhase);
+ buffer->meta_data()->setInt32(kKeyTimeScale, mSampleRate);
+
+ mPhase += numFramesPerBuffer;
+
+ buffer->set_range(0, numFramesPerBuffer * frameSize);
+
+ *out = buffer;
+
+ return OK;
+}
+
+} // namespace android
diff --git a/cmds/stagefright/SineSource.h b/cmds/stagefright/SineSource.h
new file mode 100644
index 0000000..76ab669
--- /dev/null
+++ b/cmds/stagefright/SineSource.h
@@ -0,0 +1,39 @@
+#ifndef SINE_SOURCE_H_
+
+#define SINE_SOURCE_H_
+
+#include <media/stagefright/MediaSource.h>
+
+namespace android {
+
+struct MediaBufferGroup;
+
+struct SineSource : public MediaSource {
+ SineSource(int32_t sampleRate, int32_t numChannels);
+
+ virtual status_t start(MetaData *params);
+ virtual status_t stop();
+
+ virtual sp<MetaData> getFormat();
+
+ virtual status_t read(
+ MediaBuffer **out, const ReadOptions *options = NULL);
+
+protected:
+ virtual ~SineSource();
+
+private:
+ enum { kBufferSize = 8192 };
+ static const double kFrequency = 500.0;
+
+ bool mStarted;
+ int32_t mSampleRate;
+ int32_t mNumChannels;
+ size_t mPhase;
+
+ MediaBufferGroup *mGroup;
+};
+
+} // namespace android
+
+#endif // SINE_SOURCE_H_
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index 4b44761..81a1c0a 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -14,7 +14,10 @@
* limitations under the License.
*/
+#include "SineSource.h"
+
#include <binder/ProcessState.h>
+#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/CameraSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
@@ -24,9 +27,11 @@
#include <media/stagefright/MmapSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/OMXCodec.h>
+#include <media/MediaPlayerInterface.h>
using namespace android;
+#if 0
class DummySource : public MediaSource {
public:
DummySource(int width, int height)
@@ -45,11 +50,6 @@
return meta;
}
- virtual status_t getMaxSampleSize(size_t *max_size) {
- *max_size = mSize;
- return OK;
- }
-
virtual status_t start(MetaData *params) {
return OK;
}
@@ -158,7 +158,7 @@
OMXCodec::Create(
client.interface(), enc_meta, true /* createEncoder */, decoder);
-#if 1
+#if 0
sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/output.mp4");
writer->addSource(enc_meta, encoder);
writer->start();
@@ -204,4 +204,60 @@
return 0;
}
+#else
+int main(int argc, char **argv) {
+ android::ProcessState::self()->startThreadPool();
+
+ OMXClient client;
+ CHECK_EQ(client.connect(), OK);
+
+ const int32_t kSampleRate = 22050;
+ const int32_t kNumChannels = 2;
+ sp<MediaSource> audioSource = new SineSource(kSampleRate, kNumChannels);
+
+#if 0
+ sp<MediaPlayerBase::AudioSink> audioSink;
+ AudioPlayer *player = new AudioPlayer(audioSink);
+ player->setSource(audioSource);
+ player->start();
+
+ sleep(10);
+
+ player->stop();
+#endif
+
+ sp<MetaData> encMeta = new MetaData;
+ encMeta->setCString(kKeyMIMEType, 1 ? "audio/3gpp" : "audio/mp4a-latm");
+ encMeta->setInt32(kKeySampleRate, kSampleRate);
+ encMeta->setInt32(kKeyChannelCount, kNumChannels);
+ encMeta->setInt32(kKeyMaxInputSize, 8192);
+
+ sp<MediaSource> encoder =
+ OMXCodec::Create(client.interface(), encMeta, true, audioSource);
+
+ encoder->start();
+
+ int32_t n = 0;
+ status_t err;
+ MediaBuffer *buffer;
+ while ((err = encoder->read(&buffer)) == OK) {
+ printf(".");
+ fflush(stdout);
+
+ buffer->release();
+ buffer = NULL;
+
+ if (++n == 10000) {
+ break;
+ }
+ }
+ printf("$\n");
+
+ encoder->stop();
+
+ client.disconnect();
+
+ return 0;
+}
+#endif
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 342de2b..f5f8f30 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -54,7 +54,7 @@
private final String mAttributesName;
// no need to be synchronized since the map is never changed once mService is written
- private volatile Map<V, ServiceInfo<V>> mServices;
+ volatile Map<V, ServiceInfo<V>> mServices;
// synchronized on "this"
private BroadcastReceiver mReceiver = null;
@@ -81,6 +81,7 @@
if (mReceiver == null) {
synchronized (this) {
mReceiver = new BroadcastReceiver() {
+ @Override
public void onReceive(Context context, Intent intent) {
mServices = generateServicesMap();
}
@@ -91,6 +92,7 @@
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ intentFilter.addDataScheme("package");
mContext.registerReceiver(mReceiver, intentFilter);
return true;
}
@@ -122,6 +124,7 @@
this.uid = uid;
}
+ @Override
public String toString() {
return "ServiceInfo: " + type + ", " + componentName;
}
@@ -159,6 +162,7 @@
maybeUnregisterForPackageChanges();
}
+ @Override
protected void finalize() throws Throwable {
synchronized (this) {
if (mReceiver != null) {
@@ -169,7 +173,7 @@
super.finalize();
}
- private Map<V, ServiceInfo<V>> generateServicesMap() {
+ Map<V, ServiceInfo<V>> generateServicesMap() {
Map<V, ServiceInfo<V>> services = Maps.newHashMap();
PackageManager pm = mContext.getPackageManager();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d569220..82bff4a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5410,6 +5410,18 @@
}
/**
+ * @hide
+ */
+ protected void onDrawVScrollBar(Canvas canvas, ScrollBarDrawable scrollBar,
+ int l, int t, int r, int b) {
+ scrollBar.setBounds(l, t, r, b);
+ scrollBar.setParameters(computeVerticalScrollRange(),
+ computeVerticalScrollOffset(),
+ computeVerticalScrollExtent(), true);
+ scrollBar.draw(canvas);
+ }
+
+ /**
* <p>Draw the vertical scrollbar if {@link #isVerticalScrollBarEnabled()}
* returns true.</p>
*
@@ -5441,13 +5453,11 @@
// TODO: Deal with RTL languages to position scrollbar on left
final int left = scrollX + width - size - (mUserPaddingRight & inside);
- scrollBar.setBounds(left, scrollY + (mPaddingTop & inside),
- left + size, scrollY + height - (mUserPaddingBottom & inside));
- scrollBar.setParameters(
- computeVerticalScrollRange(),
- computeVerticalScrollOffset(),
- computeVerticalScrollExtent(), true);
- scrollBar.draw(canvas);
+ onDrawVScrollBar(canvas, scrollBar,
+ left,
+ scrollY + (mPaddingTop & inside),
+ left + size,
+ scrollY + height - (mUserPaddingBottom & inside));
}
/**
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 41e604d..e504591 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -177,17 +177,6 @@
}
/**
- * Tell the host application that the WebView has changed viewing modes.
- * @param newViewingMode One of the values described in WebView as possible
- * values for the viewing mode
- */
- /* package */ void uiOnChangeViewingMode(int newViewingMode) {
- if (mWebChromeClient != null) {
- mWebChromeClient.onChangeViewingMode(mWebView, newViewingMode);
- }
- }
-
- /**
* Called by the UI side. Calling overrideUrlLoading from the WebCore
* side will post a message to call this method.
*/
diff --git a/core/java/android/webkit/GeolocationService.java b/core/java/android/webkit/GeolocationService.java
index 78b25ba..646f8c5 100755
--- a/core/java/android/webkit/GeolocationService.java
+++ b/core/java/android/webkit/GeolocationService.java
@@ -156,11 +156,16 @@
* Registers this object with the location service.
*/
private void registerForLocationUpdates() {
- mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
- mIsNetworkProviderAvailable = true;
- if (mIsGpsEnabled) {
- mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
- mIsGpsProviderAvailable = true;
+ try {
+ mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
+ mIsNetworkProviderAvailable = true;
+ if (mIsGpsEnabled) {
+ mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
+ mIsGpsProviderAvailable = true;
+ }
+ } catch(SecurityException e) {
+ Log.e(TAG, "Caught security exception registering for location updates from system. " +
+ "This should only happen in DumpRenderTree.");
}
}
diff --git a/core/java/android/webkit/ViewManager.java b/core/java/android/webkit/ViewManager.java
index af33b4f..63f4033 100644
--- a/core/java/android/webkit/ViewManager.java
+++ b/core/java/android/webkit/ViewManager.java
@@ -50,8 +50,8 @@
}
setBounds(x, y, width, height);
final AbsoluteLayout.LayoutParams lp =
- new AbsoluteLayout.LayoutParams(ctv(width), ctv(height),
- ctv(x), ctv(y));
+ new AbsoluteLayout.LayoutParams(ctvX(width), ctvX(height),
+ ctvX(x), ctvY(y));
mWebView.mPrivateHandler.post(new Runnable() {
public void run() {
// This method may be called multiple times. If the view is
@@ -97,9 +97,21 @@
return new ChildView();
}
- // contentToView shorthand.
- private int ctv(int val) {
- return mWebView.contentToView(val);
+ /**
+ * Shorthand for calling mWebView.contentToViewX. Used when obtaining a
+ * view x coordinate from a content x coordinate, or when getting a
+ * view dimension from a content dimension, whether it be in x or y.
+ */
+ private int ctvX(int val) {
+ return mWebView.contentToViewX(val);
+ }
+
+ /**
+ * Shorthand for calling mWebView.contentToViewY. Used when obtaining a
+ * view y coordinate from a content y coordinate.
+ */
+ private int ctvY(int val) {
+ return mWebView.contentToViewY(val);
}
void scaleAll() {
@@ -107,10 +119,10 @@
View view = v.mView;
AbsoluteLayout.LayoutParams lp =
(AbsoluteLayout.LayoutParams) view.getLayoutParams();
- lp.width = ctv(v.width);
- lp.height = ctv(v.height);
- lp.x = ctv(v.x);
- lp.y = ctv(v.y);
+ lp.width = ctvX(v.width);
+ lp.height = ctvX(v.height);
+ lp.x = ctvX(v.x);
+ lp.y = ctvY(v.y);
view.setLayoutParams(lp);
}
}
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index ad4ba05..6421fe7 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -23,15 +23,6 @@
public class WebChromeClient {
/**
- * Tell the host application that the WebView has changed viewing modes.
- * @param view The WebView that initiated the callback.
- * @param newViewingMode One of the values described in WebView as possible
- * values for the viewing mode
- * @hide
- */
- public void onChangeViewingMode(WebView view, int newViewingMode) {}
-
- /**
* Tell the host application the current progress of loading a page.
* @param view The WebView that initiated the callback.
* @param newProgress Current page loading progress, represented by
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 792fdf2..611681f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -525,48 +525,6 @@
// the last zoom scale.
boolean mInZoomOverview = false;
- // The viewing mode of this webview. Reported back to the WebChromeClient
- // so we can hide and display the title bar as appropriate.
- private int mViewingMode;
- /**
- * Not supporting overview vs reading mode
- * @hide
- */
- public final static int NO_VIEWING_MODE = 0;
- /**
- * Zoom overview mode. The page is zoomed all the way out, mInZoomOverview
- * is true, and the title bar is showing. Double tapping will change to
- * reading mode.
- * @hide
- */
- public final static int OVERVIEW_MODE = 1;
- /**
- * Reading mode. The page is at the level specified by the user,
- * mInZoomOverview is false, and the title bar is not showing. Double
- * tapping will change to zoom overview mode.
- * @hide
- */
- public final static int READING_MODE = 2;
- /**
- * Modified reading mode, which shows the title bar. mInZoomOverview is
- * false, and double tapping will change to zoom overview mode. However,
- * if the scrolling will change to reading mode. Used when swiping a
- * tab into view which was in reading mode, unless it was a mobile site
- * with zero scroll.
- * @hide
- */
- public final static int READING_MODE_WITH_TITLE_BAR = 3;
- /**
- * Another modified reading mode. For loading a mobile site, or swiping a
- * tab into view which was displaying a mobile site in reading mode
- * with zero scroll
- * @hide
- */
- public final static int TITLE_BAR_DISMISS_MODE = 4;
- // Whether the current site is a mobile site. Determined when we receive
- // NEW_PICTURE_MSG_ID to help determine how to handle double taps
- private boolean mMobileSite;
-
// ideally mZoomOverviewWidth should be mContentWidth. But sites like espn,
// engadget always have wider mContentWidth no matter what viewport size is.
int mZoomOverviewWidth = WebViewCore.DEFAULT_VIEWPORT_WIDTH;
@@ -962,14 +920,20 @@
/*
* Return the height of the view where the content of WebView should render
- * to.
+ * to. Note that this excludes mTitleBar, if there is one.
*/
private int getViewHeight() {
- if (!isHorizontalScrollBarEnabled() || mOverlayHorizontalScrollbar) {
- return getHeight();
- } else {
- return getHeight() - getHorizontalScrollbarHeight();
+ int height = getHeight();
+ if (isHorizontalScrollBarEnabled() && mOverlayHorizontalScrollbar) {
+ height -= getHorizontalScrollbarHeight();
}
+ if (mTitleBar != null) {
+ int titleBarVisibleHeight = mTitleBar.getHeight() - mScrollY;
+ if (titleBarVisibleHeight > 0) {
+ height -= titleBarVisibleHeight;
+ }
+ }
+ return height;
}
/**
@@ -1180,7 +1144,6 @@
if (mInZoomOverview) {
b.putFloat("lastScale", mLastScale);
}
- b.putBoolean("mobile", mMobileSite);
return true;
}
return false;
@@ -1226,20 +1189,12 @@
// correctly
mActualScale = scale;
float lastScale = b.getFloat("lastScale", -1.0f);
- mMobileSite = b.getBoolean("mobile", false);
if (lastScale > 0) {
mInZoomOverview = true;
- mViewingMode = OVERVIEW_MODE;
mLastScale = lastScale;
} else {
mInZoomOverview = false;
- if (mMobileSite && (mScrollX | mScrollY) == 0) {
- mViewingMode = TITLE_BAR_DISMISS_MODE;
- } else {
- mViewingMode = READING_MODE_WITH_TITLE_BAR;
- }
}
- mCallbackProxy.uiOnChangeViewingMode(mViewingMode);
invalidate();
return true;
}
@@ -1692,8 +1647,8 @@
if (type == HitTestResult.UNKNOWN_TYPE
|| type == HitTestResult.SRC_ANCHOR_TYPE) {
// Now check to see if it is an image.
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX((int) mLastTouchX + mScrollX);
+ int contentY = viewToContentY((int) mLastTouchY + mScrollY);
String text = nativeImageURI(contentX, contentY);
if (text != null) {
result.setType(type == HitTestResult.UNKNOWN_TYPE ?
@@ -1736,8 +1691,8 @@
* as the data member with "url" as key. The result can be null.
*/
public void requestImageRef(Message msg) {
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX((int) mLastTouchX + mScrollX);
+ int contentY = viewToContentY((int) mLastTouchY + mScrollY);
String ref = nativeImageURI(contentX, contentY);
Bundle data = msg.getData();
data.putString("url", ref);
@@ -1771,31 +1726,88 @@
return pinLoc(y, getViewHeight(), computeVerticalScrollRange());
}
- /*package*/ int viewToContent(int x) {
+ /**
+ * A title bar which is embedded in this WebView, and scrolls along with it
+ * vertically, but not horizontally.
+ */
+ private View mTitleBar;
+
+ /**
+ * Add or remove a title bar to be embedded into the WebView, and scroll
+ * along with it vertically, while remaining in view horizontally. Pass
+ * null to remove the title bar from the WebView, and return to drawing
+ * the WebView normally without translating to account for the title bar.
+ * @hide
+ */
+ public void addTitleBar(View v) {
+ if (null == v) {
+ removeView(mTitleBar);
+ } else {
+ addView(v, new AbsoluteLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, mScrollX, 0));
+ }
+ mTitleBar = v;
+ }
+
+ /**
+ * Given an x coordinate in view space, convert it to content space. Also
+ * may be used for absolute heights (such as for the WebTextView's
+ * textSize, which is unaffected by the height of the title bar).
+ */
+ /*package*/ int viewToContentX(int x) {
return Math.round(x * mInvActualScale);
}
- /*package*/ int contentToView(int x) {
+ /**
+ * Given a y coordinate in view space, convert it to content space.
+ * Takes into account the height of the title bar if there is one
+ * embedded into the WebView.
+ */
+ /*package*/ int viewToContentY(int y) {
+ if (mTitleBar != null) {
+ y -= mTitleBar.getHeight();
+ }
+ return viewToContentX(y);
+ }
+
+ /**
+ * Given an x coordinate in content space, convert it to view
+ * space. Also used for absolute heights.
+ */
+ /*package*/ int contentToViewX(int x) {
return Math.round(x * mActualScale);
}
+ /**
+ * Given a y coordinate in content space, convert it to view
+ * space. Takes into account the height of the title bar.
+ */
+ /*package*/ int contentToViewY(int y) {
+ int val = Math.round(y * mActualScale);
+ if (mTitleBar != null) {
+ val += mTitleBar.getHeight();
+ }
+ return val;
+ }
+
// Called by JNI to invalidate the View, given rectangle coordinates in
// content space
private void viewInvalidate(int l, int t, int r, int b) {
- invalidate(contentToView(l), contentToView(t), contentToView(r),
- contentToView(b));
+ invalidate(contentToViewX(l), contentToViewY(t), contentToViewX(r),
+ contentToViewY(b));
}
// Called by JNI to invalidate the View after a delay, given rectangle
// coordinates in content space
private void viewInvalidateDelayed(long delay, int l, int t, int r, int b) {
- postInvalidateDelayed(delay, contentToView(l), contentToView(t),
- contentToView(r), contentToView(b));
+ postInvalidateDelayed(delay, contentToViewX(l), contentToViewY(t),
+ contentToViewX(r), contentToViewY(b));
}
private Rect contentToView(Rect x) {
- return new Rect(contentToView(x.left), contentToView(x.top)
- , contentToView(x.right), contentToView(x.bottom));
+ return new Rect(contentToViewX(x.left), contentToViewY(x.top)
+ , contentToViewX(x.right), contentToViewY(x.bottom));
}
// stop the scroll animation, and don't let a subsequent fling add
@@ -1934,10 +1946,10 @@
// Sets r to be our visible rectangle in content coordinates
private void calcOurContentVisibleRect(Rect r) {
calcOurVisibleRect(r);
- r.left = viewToContent(r.left);
- r.top = viewToContent(r.top);
- r.right = viewToContent(r.right);
- r.bottom = viewToContent(r.bottom);
+ r.left = viewToContentX(r.left);
+ r.top = viewToContentY(r.top);
+ r.right = viewToContentX(r.right);
+ r.bottom = viewToContentY(r.bottom);
}
static class ViewSizeData {
@@ -1994,7 +2006,7 @@
if (mDrawHistory) {
return mHistoryWidth;
} else {
- return contentToView(mContentWidth);
+ return contentToViewX(mContentWidth);
}
}
@@ -2006,7 +2018,7 @@
if (mDrawHistory) {
return mHistoryHeight;
} else {
- int height = contentToView(mContentHeight);
+ int height = contentToViewX(mContentHeight);
if (mFindIsUp) {
height += FIND_HEIGHT;
}
@@ -2014,6 +2026,23 @@
}
}
+ @Override
+ protected int computeVerticalScrollOffset() {
+ int offset = super.computeVerticalScrollOffset();
+ if (mTitleBar != null) {
+ // Need to adjust so that the resulting offset is at minimum
+ // the height of the title bar, if it is visible.
+ offset += mTitleBar.getHeight()*computeVerticalScrollRange()
+ /getViewHeight();
+ }
+ return offset;
+ }
+
+ @Override
+ protected int computeVerticalScrollExtent() {
+ return getViewHeight();
+ }
+
/**
* Get the url for the current page. This is not always the same as the url
* passed to WebViewClient.onPageStarted because although the load for
@@ -2365,8 +2394,8 @@
// keys are hit, this should be safe. Right?
return false;
}
- cx = contentToView(cx);
- cy = contentToView(cy);
+ cx = contentToViewX(cx);
+ cy = contentToViewY(cy);
if (mHeightCanMeasure) {
// move our visible rect according to scroll request
if (cy != 0) {
@@ -2398,8 +2427,8 @@
// saved scroll position, it is ok to skip this.
return false;
}
- int vx = contentToView(cx);
- int vy = contentToView(cy);
+ int vx = contentToViewX(cx);
+ int vy = contentToViewY(cy);
// Log.d(LOGTAG, "content scrollTo [" + cx + " " + cy + "] view=[" +
// vx + " " + vy + "]");
pinScrollTo(vx, vy, false, 0);
@@ -2417,8 +2446,8 @@
// is used in the view system.
return;
}
- int vx = contentToView(cx);
- int vy = contentToView(cy);
+ int vx = contentToViewX(cx);
+ int vy = contentToViewY(cy);
pinScrollTo(vx, vy, true, 0);
}
@@ -2435,12 +2464,12 @@
}
if (mHeightCanMeasure) {
- if (getMeasuredHeight() != contentToView(mContentHeight)
+ if (getMeasuredHeight() != contentToViewX(mContentHeight)
&& updateLayout) {
requestLayout();
}
} else if (mWidthCanMeasure) {
- if (getMeasuredWidth() != contentToView(mContentWidth)
+ if (getMeasuredWidth() != contentToViewX(mContentWidth)
&& updateLayout) {
requestLayout();
}
@@ -2582,7 +2611,22 @@
}
@Override
+ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ if (child == mTitleBar) {
+ // When drawing the title bar, move it horizontally to always show
+ // at the top of the WebView.
+ mTitleBar.offsetLeftAndRight(mScrollX - mTitleBar.getLeft());
+ }
+ return super.drawChild(canvas, child, drawingTime);
+ }
+
+ @Override
protected void onDraw(Canvas canvas) {
+ int saveCount = canvas.getSaveCount();
+ if (mTitleBar != null) {
+ canvas.save();
+ canvas.translate(0, (int) mTitleBar.getHeight());
+ }
// if mNativeClass is 0, the WebView has been destroyed. Do nothing.
if (mNativeClass == 0) {
return;
@@ -2596,7 +2640,7 @@
mTouchMode = TOUCH_DONE_MODE;
}
}
- int sc = canvas.save();
+ canvas.save();
if (mTouchMode >= FIRST_SCROLL_ZOOM && mTouchMode <= LAST_SCROLL_ZOOM) {
scrollZoomDraw(canvas);
} else {
@@ -2613,7 +2657,7 @@
|| mTrackballDown || mGotCenterDown, false);
drawCoreAndCursorRing(canvas, mBackgroundColor, mDrawCursorRing);
}
- canvas.restoreToCount(sc);
+ canvas.restoreToCount(saveCount);
if (AUTO_REDRAW_HACK && mAutoRedraw) {
invalidate();
@@ -3210,7 +3254,7 @@
// Initialize our generation number.
mTextGeneration = 0;
}
- mWebTextView.setTextSize(contentToView(nativeFocusCandidateTextSize()));
+ mWebTextView.setTextSize(contentToViewX(nativeFocusCandidateTextSize()));
Rect visibleRect = new Rect();
calcOurContentVisibleRect(visibleRect);
// Note that sendOurVisibleRect calls viewToContent, so the coordinates
@@ -3370,8 +3414,8 @@
mShiftIsPressed = true;
if (nativeHasCursorNode()) {
Rect rect = nativeCursorNodeBounds();
- mSelectX = contentToView(rect.left);
- mSelectY = contentToView(rect.top);
+ mSelectX = contentToViewX(rect.left);
+ mSelectY = contentToViewY(rect.top);
} else {
mSelectX = mScrollX + (int) mLastTouchX;
mSelectY = mScrollY + (int) mLastTouchY;
@@ -3758,12 +3802,6 @@
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
- if (mViewingMode == READING_MODE_WITH_TITLE_BAR
- || mViewingMode == TITLE_BAR_DISMISS_MODE) {
- mViewingMode = READING_MODE;
- mCallbackProxy.uiOnChangeViewingMode(mViewingMode);
- }
-
sendOurVisibleRect();
}
@@ -3840,8 +3878,8 @@
eventTime - mLastSentTouchTime > TOUCH_SENT_INTERVAL)) {
WebViewCore.TouchEventData ted = new WebViewCore.TouchEventData();
ted.mAction = action;
- ted.mX = viewToContent((int) x + mScrollX);
- ted.mY = viewToContent((int) y + mScrollY);
+ ted.mX = viewToContentX((int) x + mScrollX);
+ ted.mY = viewToContentY((int) y + mScrollY);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mLastSentTouchTime = eventTime;
}
@@ -3873,8 +3911,8 @@
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "select=" + mSelectX + "," + mSelectY);
}
- nativeMoveSelection(viewToContent(mSelectX)
- , viewToContent(mSelectY), false);
+ nativeMoveSelection(viewToContentX(mSelectX),
+ viewToContentY(mSelectY), false);
mTouchSelection = mExtendSelection = true;
} else if (mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
@@ -3930,8 +3968,8 @@
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "xtend=" + mSelectX + "," + mSelectY);
}
- nativeMoveSelection(viewToContent(mSelectX)
- , viewToContent(mSelectY), true);
+ nativeMoveSelection(viewToContentX(mSelectX),
+ viewToContentY(mSelectY), true);
invalidate();
break;
}
@@ -3981,13 +4019,6 @@
deltaY = newScrollY - mScrollY;
boolean done = false;
if (deltaX == 0 && deltaY == 0) {
- // The user attempted to pan the page, so dismiss the title
- // bar
- if (mViewingMode == READING_MODE_WITH_TITLE_BAR
- || mViewingMode == TITLE_BAR_DISMISS_MODE) {
- mViewingMode = READING_MODE;
- mCallbackProxy.uiOnChangeViewingMode(mViewingMode);
- }
done = true;
} else {
if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
@@ -4307,8 +4338,8 @@
+ " yRate=" + yRate
);
}
- nativeMoveSelection(viewToContent(mSelectX)
- , viewToContent(mSelectY), mExtendSelection);
+ nativeMoveSelection(viewToContentX(mSelectX),
+ viewToContentY(mSelectY), mExtendSelection);
int scrollX = mSelectX < mScrollX ? -SELECT_CURSOR_OFFSET
: mSelectX > maxX - SELECT_CURSOR_OFFSET ? SELECT_CURSOR_OFFSET
: 0;
@@ -4687,8 +4718,8 @@
return;
}
// mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX((int) mLastTouchX + mScrollX);
+ int contentY = viewToContentY((int) mLastTouchY + mScrollY);
Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
contentX + mNavSlop, contentY + mNavSlop);
nativeSelectBestAt(rect);
@@ -4703,8 +4734,8 @@
if (!inEditingMode() || mWebViewCore == null) {
return;
}
- mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, viewToContent(x),
- viewToContent(y));
+ mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, viewToContentX(x),
+ viewToContentY(y));
}
/**
@@ -4751,16 +4782,16 @@
if (!inEditingMode()) {
return;
}
- int x = viewToContent((int) event.getX() + mWebTextView.getLeft());
- int y = viewToContent((int) event.getY() + mWebTextView.getTop());
+ int x = viewToContentX((int) event.getX() + mWebTextView.getLeft());
+ int y = viewToContentY((int) event.getY() + mWebTextView.getTop());
nativeTextInputMotionUp(x, y);
}
/*package*/ void shortPressOnTextField() {
if (inEditingMode()) {
View v = mWebTextView;
- int x = viewToContent((v.getLeft() + v.getRight()) >> 1);
- int y = viewToContent((v.getTop() + v.getBottom()) >> 1);
+ int x = viewToContentX((v.getLeft() + v.getRight()) >> 1);
+ int y = viewToContentY((v.getTop() + v.getBottom()) >> 1);
nativeTextInputMotionUp(x, y);
}
}
@@ -4771,8 +4802,8 @@
}
switchOutDrawHistory();
// mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX((int) mLastTouchX + mScrollX);
+ int contentY = viewToContentY((int) mLastTouchY + mScrollY);
if (nativeMotionUp(contentX, contentY, mNavSlop)) {
if (mLogEvent) {
Checkin.updateStats(mContext.getContentResolver(),
@@ -4784,42 +4815,13 @@
}
}
- /**
- * Called when the Tabs are used to slide this WebView's tab into view.
- * @hide
- */
- public void slideIntoFocus() {
- if (mViewingMode == READING_MODE) {
- if (!mMobileSite || (mScrollX | mScrollY) != 0) {
- mViewingMode = READING_MODE_WITH_TITLE_BAR;
- } else {
- mViewingMode = TITLE_BAR_DISMISS_MODE;
- }
- mCallbackProxy.uiOnChangeViewingMode(mViewingMode);
- }
- }
-
private void doDoubleTap() {
- if (mWebViewCore.getSettings().getUseWideViewPort() == false ||
- mViewingMode == NO_VIEWING_MODE) {
+ if (mWebViewCore.getSettings().getUseWideViewPort() == false) {
return;
}
- if (mViewingMode == TITLE_BAR_DISMISS_MODE) {
- mViewingMode = READING_MODE;
- // mInZoomOverview will not change, so change the viewing mode
- // and return
- mCallbackProxy.uiOnChangeViewingMode(mViewingMode);
- return;
- }
- if (mViewingMode == READING_MODE_WITH_TITLE_BAR && mMobileSite) {
- scrollTo(0,0);
- }
- // READING_MODE_WITH_TITLE_BAR will go to OVERVIEW_MODE here.
mZoomCenterX = mLastTouchX;
mZoomCenterY = mLastTouchY;
mInZoomOverview = !mInZoomOverview;
- mViewingMode = mInZoomOverview ? OVERVIEW_MODE : READING_MODE;
- mCallbackProxy.uiOnChangeViewingMode(mViewingMode);
// remove the zoom control after double tap
if (getSettings().getBuiltInZoomControls()) {
if (mZoomButtonsController.isVisible()) {
@@ -4837,8 +4839,8 @@
zoomWithPreview((float) getViewWidth() / mZoomOverviewWidth);
} else {
// mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX((int) mLastTouchX + mScrollX);
+ int contentY = viewToContentY((int) mLastTouchY + mScrollY);
int left = nativeGetBlockLeftEdge(contentX, contentY, mActualScale);
if (left != NO_LEFTEDGE) {
// add a 5pt padding to the left edge. Re-calculate the zoom
@@ -5169,22 +5171,12 @@
restoreState.mScrollY);
if (!ENABLE_DOUBLETAP_ZOOM
|| !settings.getLoadWithOverviewMode()) {
- mMobileSite = false;
- mViewingMode = NO_VIEWING_MODE;
} else {
- mMobileSite = restoreState.mMobileSite;
if (useWideViewport
&& restoreState.mViewScale == 0) {
- mViewingMode = OVERVIEW_MODE;
mInZoomOverview = true;
- } else if (mMobileSite
- && (mScrollX | mScrollY) == 0) {
- mViewingMode = TITLE_BAR_DISMISS_MODE;
- } else {
- mViewingMode = READING_MODE_WITH_TITLE_BAR;
}
}
- mCallbackProxy.uiOnChangeViewingMode(mViewingMode);
// As we are on a new page, remove the WebTextView. This
// is necessary for page loads driven by webkit, and in
// particular when the user was on a password field, so
@@ -5648,7 +5640,7 @@
width = visRect.width() / 2;
}
// FIXME the divisor should be retrieved from somewhere
- return viewToContent(width);
+ return viewToContentX(width);
}
private int getScaledMaxYScroll() {
@@ -5663,7 +5655,7 @@
// FIXME the divisor should be retrieved from somewhere
// the closest thing today is hard-coded into ScrollView.java
// (from ScrollView.java, line 363) int maxJump = height/2;
- return viewToContent(height);
+ return viewToContentY(height);
}
/**
diff --git a/core/res/res/drawable-hdpi/divider_vertical_bright.9.png b/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
index 128a4de..1035656 100644
--- a/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
+++ b/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_focus.9.png b/core/res/res/drawable-hdpi/tab_focus.9.png
index 0c3a9ee..6e8a71f 100644
--- a/core/res/res/drawable-hdpi/tab_focus.9.png
+++ b/core/res/res/drawable-hdpi/tab_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_focus_bar_left.9.png b/core/res/res/drawable-hdpi/tab_focus_bar_left.9.png
index 54e3022..51194a4 100644
--- a/core/res/res/drawable-hdpi/tab_focus_bar_left.9.png
+++ b/core/res/res/drawable-hdpi/tab_focus_bar_left.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_focus_bar_right.9.png b/core/res/res/drawable-hdpi/tab_focus_bar_right.9.png
index 34a85f0..51194a4 100644
--- a/core/res/res/drawable-hdpi/tab_focus_bar_right.9.png
+++ b/core/res/res/drawable-hdpi/tab_focus_bar_right.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_press.9.png b/core/res/res/drawable-hdpi/tab_press.9.png
index 6b3c1c7..119b2c6 100644
--- a/core/res/res/drawable-hdpi/tab_press.9.png
+++ b/core/res/res/drawable-hdpi/tab_press.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_press_bar_left.9.png b/core/res/res/drawable-hdpi/tab_press_bar_left.9.png
index f998532..dc2fbce 100644
--- a/core/res/res/drawable-hdpi/tab_press_bar_left.9.png
+++ b/core/res/res/drawable-hdpi/tab_press_bar_left.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_press_bar_right.9.png b/core/res/res/drawable-hdpi/tab_press_bar_right.9.png
index 43515bd..dc2fbce 100644
--- a/core/res/res/drawable-hdpi/tab_press_bar_right.9.png
+++ b/core/res/res/drawable-hdpi/tab_press_bar_right.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected.9.png b/core/res/res/drawable-hdpi/tab_selected.9.png
index b128b48..29d45a17 100644
--- a/core/res/res/drawable-hdpi/tab_selected.9.png
+++ b/core/res/res/drawable-hdpi/tab_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_bar_left.9.png b/core/res/res/drawable-hdpi/tab_selected_bar_left.9.png
index a49ef68..aa935fe 100644
--- a/core/res/res/drawable-hdpi/tab_selected_bar_left.9.png
+++ b/core/res/res/drawable-hdpi/tab_selected_bar_left.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_selected_bar_right.9.png b/core/res/res/drawable-hdpi/tab_selected_bar_right.9.png
index 472f839..aa935fe 100644
--- a/core/res/res/drawable-hdpi/tab_selected_bar_right.9.png
+++ b/core/res/res/drawable-hdpi/tab_selected_bar_right.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_unselected.9.png b/core/res/res/drawable-hdpi/tab_unselected.9.png
index ed9e311..f5781ab 100644
--- a/core/res/res/drawable-hdpi/tab_unselected.9.png
+++ b/core/res/res/drawable-hdpi/tab_unselected.9.png
Binary files differ
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index 7749566..cd0b86e 100644
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -59,16 +59,17 @@
class MediaScannerClient
{
public:
- MediaScannerClient();
- virtual ~MediaScannerClient();
- void setLocale(const char* locale);
- void beginFile();
- bool addStringTag(const char* name, const char* value);
- void endFile();
-
- virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0;
- virtual bool handleStringTag(const char* name, const char* value) = 0;
- virtual bool setMimeType(const char* mimeType) = 0;
+ MediaScannerClient();
+ virtual ~MediaScannerClient();
+ void setLocale(const char* locale);
+ void beginFile();
+ bool addStringTag(const char* name, const char* value);
+ void endFile();
+
+ virtual bool scanFile(const char* path, long long lastModified, long long fileSize) = 0;
+ virtual bool handleStringTag(const char* name, const char* value) = 0;
+ virtual bool setMimeType(const char* mimeType) = 0;
+ virtual bool addNoMediaFolder(const char* path) = 0;
protected:
void convertValues(uint32_t encoding);
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index be60565..abb45a9 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -45,7 +45,7 @@
kKeyPlatformPrivate = 'priv',
kKeyDecoderComponent = 'decC',
kKeyBufferID = 'bfID',
- kKeyCompressedSize = 'cmpS',
+ kKeyMaxInputSize = 'inpS',
};
enum {
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 5b0e0b4..ac45481 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -135,6 +135,8 @@
void addCodecSpecificData(const void *data, size_t size);
void clearCodecSpecificData();
+ void setComponentRole();
+
void setAMRFormat();
void setAACFormat(int32_t numChannels, int32_t sampleRate);
@@ -155,6 +157,11 @@
void setJPEGInputFormat(
OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize);
+ void setMinBufferSize(OMX_U32 portIndex, OMX_U32 size);
+
+ void setRawAudioFormat(
+ OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
+
status_t allocateBuffers();
status_t allocateBuffersOnPort(OMX_U32 portIndex);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 3d5aae3..fcc76ca5 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -825,6 +825,22 @@
}
}
+ public void addNoMediaFolder(String path) {
+ ContentValues values = new ContentValues();
+ values.put(MediaStore.Images.ImageColumns.DATA, "");
+ String [] pathSpec = new String[] {path + '%'};
+ try {
+ mMediaProvider.update(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values,
+ MediaStore.Images.ImageColumns.DATA + " LIKE ?", pathSpec);
+ mMediaProvider.update(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values,
+ MediaStore.Images.ImageColumns.DATA + " LIKE ?", pathSpec);
+ mMediaProvider.update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values,
+ MediaStore.Images.ImageColumns.DATA + " LIKE ?", pathSpec);
+ } catch (RemoteException e) {
+ throw new RuntimeException();
+ }
+ }
+
}; // end of anonymous MediaScannerClient instance
private void prescan(String filePath) throws RemoteException {
diff --git a/media/java/android/media/MediaScannerClient.java b/media/java/android/media/MediaScannerClient.java
index cf1a8da..258c3b4 100644
--- a/media/java/android/media/MediaScannerClient.java
+++ b/media/java/android/media/MediaScannerClient.java
@@ -25,11 +25,13 @@
public void scanFile(String path, String mimeType, long lastModified, long fileSize);
+ public void addNoMediaFolder(String path);
+
/**
* Called by native code to return metadata extracted from media files.
*/
public void handleStringTag(String name, String value);
-
+
/**
* Called by native code to return mime type extracted from DRM content.
*/
diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp
index 97de486..6a5404e3 100644
--- a/media/jni/android_media_MediaScanner.cpp
+++ b/media/jni/android_media_MediaScanner.cpp
@@ -65,6 +65,8 @@
"(Ljava/lang/String;Ljava/lang/String;)V");
mSetMimeTypeMethodID = env->GetMethodID(mediaScannerClientInterface, "setMimeType",
"(Ljava/lang/String;)V");
+ mAddNoMediaFolderMethodID = env->GetMethodID(mediaScannerClientInterface, "addNoMediaFolder",
+ "(Ljava/lang/String;)V");
}
}
@@ -111,12 +113,26 @@
return (!mEnv->ExceptionCheck());
}
+ // returns true if it succeeded, false if an exception occured in the Java code
+ virtual bool addNoMediaFolder(const char* path)
+ {
+ jstring pathStr;
+ if ((pathStr = mEnv->NewStringUTF(path)) == NULL) return false;
+
+ mEnv->CallVoidMethod(mClient, mAddNoMediaFolderMethodID, pathStr);
+
+ mEnv->DeleteLocalRef(pathStr);
+ return (!mEnv->ExceptionCheck());
+ }
+
+
private:
JNIEnv *mEnv;
jobject mClient;
jmethodID mScanFileMethodID;
jmethodID mHandleStringTagMethodID;
jmethodID mSetMimeTypeMethodID;
+ jmethodID mAddNoMediaFolderMethodID;
};
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 7c8defc..de808e5 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -77,6 +77,8 @@
{ "video/avc", "OMX.PV.avcenc" },
};
+#define CODEC_LOGV(x, ...) LOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
+
struct OMXCodecObserver : public BnOMXObserver {
OMXCodecObserver(const wp<OMXCodec> &target)
: mTarget(target) {
@@ -150,6 +152,15 @@
}
}
+template<class T>
+static void InitOMXParams(T *params) {
+ params->nSize = sizeof(T);
+ params->nVersion.s.nVersionMajor = 1;
+ params->nVersion.s.nVersionMinor = 0;
+ params->nVersion.s.nRevision = 0;
+ params->nVersion.s.nStep = 0;
+}
+
// static
sp<OMXCodec> OMXCodec::Create(
const sp<IOMX> &omx,
@@ -180,6 +191,7 @@
status_t err = omx->allocate_node(componentName, &node);
if (err == OK) {
+ LOGV("Successfully allocated OMX node '%s'", componentName);
break;
}
}
@@ -301,7 +313,7 @@
if (!strcasecmp("audio/3gpp", mime)) {
codec->setAMRFormat();
}
- if (!createEncoder && !strcasecmp("audio/mp4a-latm", mime)) {
+ if (!strcasecmp("audio/mp4a-latm", mime)) {
int32_t numChannels, sampleRate;
CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
@@ -334,7 +346,7 @@
int32_t compressedSize;
success = success && meta->findInt32(
- kKeyCompressedSize, &compressedSize);
+ kKeyMaxInputSize, &compressedSize);
CHECK(success);
CHECK(compressedSize > 0);
@@ -343,19 +355,46 @@
codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
}
+ int32_t maxInputSize;
+ if (createEncoder && meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
+ codec->setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
+ }
+
+ if (!strcmp(componentName, "OMX.TI.AMR.encode")
+ || !strcmp(componentName, "OMX.TI.WBAMR.encode")) {
+ codec->setMinBufferSize(kPortIndexOutput, 8192); // XXX
+ }
+
codec->initOutputFormat(meta);
return codec;
}
+void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ InitOMXParams(&def);
+ def.nPortIndex = portIndex;
+
+ status_t err = mOMX->get_parameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+ CHECK_EQ(err, OK);
+
+ if (def.nBufferSize < size) {
+ def.nBufferSize = size;
+
+ }
+
+ err = mOMX->set_parameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+ CHECK_EQ(err, OK);
+}
+
status_t OMXCodec::setVideoPortFormatType(
OMX_U32 portIndex,
OMX_VIDEO_CODINGTYPE compressionFormat,
OMX_COLOR_FORMATTYPE colorFormat) {
OMX_VIDEO_PARAM_PORTFORMATTYPE format;
- format.nSize = sizeof(format);
- format.nVersion.s.nVersionMajor = 1;
- format.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&format);
format.nPortIndex = portIndex;
format.nIndex = 0;
bool found = false;
@@ -447,13 +486,11 @@
kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
OMX_PARAM_PORTDEFINITIONTYPE def;
- OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
-
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
+ OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
+
status_t err = mOMX->get_parameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
@@ -472,9 +509,7 @@
////////////////////////////////////////////////////////////////////////////
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
err = mOMX->get_parameter(
@@ -482,7 +517,7 @@
CHECK_EQ(err, OK);
def.nBufferSize = (width * height * 2); // (width * height * 3) / 2;
- LOGI("setting nBufferSize = %ld", def.nBufferSize);
+ LOGI("Setting nBufferSize = %ld", def.nBufferSize);
CHECK_EQ(def.eDomain, OMX_PortDomainVideo);
@@ -500,37 +535,6 @@
const char *mime, OMX_U32 width, OMX_U32 height) {
LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);
- // Enabling this code appears to be the right thing(tm), but,...
- // the TI decoder then loses the ability to output YUV420 and only outputs
- // YCbYCr (16bit)
-
-#if 1
- if (!strcmp("OMX.TI.Video.Decoder", mComponentName)) {
- OMX_PARAM_COMPONENTROLETYPE role;
- role.nSize = sizeof(role);
- role.nVersion.s.nVersionMajor = 1;
- role.nVersion.s.nVersionMinor = 1;
-
- if (!strcasecmp("video/avc", mime)) {
- strncpy((char *)role.cRole, "video_decoder.avc",
- OMX_MAX_STRINGNAME_SIZE - 1);
- } else if (!strcasecmp("video/mp4v-es", mime)) {
- strncpy((char *)role.cRole, "video_decoder.mpeg4",
- OMX_MAX_STRINGNAME_SIZE - 1);
- } else if (!strcasecmp("video/3gpp", mime)) {
- strncpy((char *)role.cRole, "video_decoder.h263",
- OMX_MAX_STRINGNAME_SIZE - 1);
- }
-
- role.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
-
- status_t err = mOMX->set_parameter(
- mNode, OMX_IndexParamStandardComponentRole,
- &role, sizeof(role));
- CHECK_EQ(err, OK);
- }
-#endif
-
OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
if (!strcasecmp("video/avc", mime)) {
compressionFormat = OMX_VIDEO_CodingAVC;
@@ -549,9 +553,7 @@
#if 1
{
OMX_VIDEO_PARAM_PORTFORMATTYPE format;
- format.nSize = sizeof(format);
- format.nVersion.s.nVersionMajor = 1;
- format.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&format);
format.nPortIndex = kPortIndexOutput;
format.nIndex = 0;
@@ -576,13 +578,11 @@
#endif
OMX_PARAM_PORTDEFINITIONTYPE def;
- OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
-
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
+ OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
+
status_t err = mOMX->get_parameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
@@ -609,9 +609,7 @@
////////////////////////////////////////////////////////////////////////////
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
err = mOMX->get_parameter(
@@ -657,6 +655,63 @@
mObserver = new OMXCodecObserver(this);
mOMX->observe_node(mNode, mObserver);
+
+ setComponentRole();
+}
+
+void OMXCodec::setComponentRole() {
+ struct MimeToRole {
+ const char *mime;
+ const char *decoderRole;
+ const char *encoderRole;
+ };
+
+ static const MimeToRole kMimeToRole[] = {
+ { "audio/mpeg", "audio_decoder.mp3", "audio_encoder.mp3" },
+ { "audio/3gpp", "audio_decoder.amrnb", "audio_encoder.amrnb" },
+ { "audio/mp4a-latm", "audio_decoder.aac", "audio_encoder.aac" },
+ { "video/avc", "video_decoder.avc", "video_encoder.avc" },
+ { "video/mp4v-es", "video_decoder.mpeg4", "video_encoder.mpeg4" },
+ { "video/3gpp", "video_decoder.h263", "video_encoder.h263" },
+ };
+
+ static const size_t kNumMimeToRole =
+ sizeof(kMimeToRole) / sizeof(kMimeToRole[0]);
+
+ size_t i;
+ for (i = 0; i < kNumMimeToRole; ++i) {
+ if (!strcasecmp(mMIME, kMimeToRole[i].mime)) {
+ break;
+ }
+ }
+
+ if (i == kNumMimeToRole) {
+ return;
+ }
+
+ const char *role =
+ mIsEncoder ? kMimeToRole[i].encoderRole
+ : kMimeToRole[i].decoderRole;
+
+ if (role != NULL) {
+ CODEC_LOGV("Setting component role '%s'.", role);
+
+ OMX_PARAM_COMPONENTROLETYPE roleParams;
+ InitOMXParams(&roleParams);
+
+ strncpy((char *)roleParams.cRole,
+ role, OMX_MAX_STRINGNAME_SIZE - 1);
+
+ roleParams.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
+
+ status_t err = mOMX->set_parameter(
+ mNode, OMX_IndexParamStandardComponentRole,
+ &roleParams, sizeof(roleParams));
+
+ if (err != OK) {
+ LOGW("Failed to set standard component role '%s'.", role);
+ }
+ }
}
OMXCodec::~OMXCodec() {
@@ -689,7 +744,6 @@
if (!(mQuirks & kRequiresLoadedToIdleAfterAllocation)) {
err = mOMX->send_command(mNode, OMX_CommandStateSet, OMX_StateIdle);
CHECK_EQ(err, OK);
-
setState(LOADED_TO_IDLE);
}
@@ -731,11 +785,7 @@
status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
OMX_PARAM_PORTDEFINITIONTYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
- def.nVersion.s.nRevision = 0;
- def.nVersion.s.nStep = 0;
+ InitOMXParams(&def);
def.nPortIndex = portIndex;
status_t err = mOMX->get_parameter(
@@ -783,7 +833,7 @@
mPortBuffers[portIndex].push(info);
- LOGV("allocated buffer %p on %s port", buffer,
+ CODEC_LOGV("allocated buffer %p on %s port", buffer,
portIndex == kPortIndexInput ? "input" : "output");
}
@@ -809,7 +859,7 @@
{
IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
- LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
+ CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
size_t i = 0;
@@ -826,7 +876,7 @@
buffers->editItemAt(i).mOwnedByComponent = false;
if (mPortStatus[kPortIndexInput] == DISABLING) {
- LOGV("Port is disabled, freeing buffer %p", buffer);
+ CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
status_t err =
mOMX->free_buffer(mNode, kPortIndexInput, buffer);
@@ -846,12 +896,12 @@
IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
OMX_U32 flags = msg.u.extended_buffer_data.flags;
- LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)",
+ CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx)",
buffer,
msg.u.extended_buffer_data.range_length,
flags);
- LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))",
+ CODEC_LOGV("FILL_BUFFER_DONE(timestamp: %lld us (%.2f secs))",
msg.u.extended_buffer_data.timestamp,
msg.u.extended_buffer_data.timestamp / 1E6);
@@ -872,7 +922,7 @@
info->mOwnedByComponent = false;
if (mPortStatus[kPortIndexOutput] == DISABLING) {
- LOGV("Port is disabled, freeing buffer %p", buffer);
+ CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
status_t err =
mOMX->free_buffer(mNode, kPortIndexOutput, buffer);
@@ -881,7 +931,7 @@
buffers->removeAt(i);
} else if (mPortStatus[kPortIndexOutput] == ENABLED
&& (flags & OMX_BUFFERFLAG_EOS)) {
- LOGV("No more output data.");
+ CODEC_LOGV("No more output data.");
mNoMoreOutputData = true;
mBufferFilled.signal();
} else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) {
@@ -953,7 +1003,7 @@
case OMX_EventBufferFlag:
{
- LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
+ CODEC_LOGV("EVENT_BUFFER_FLAG(%ld)", data1);
if (data1 == kPortIndexOutput) {
mNoMoreOutputData = true;
@@ -963,7 +1013,7 @@
default:
{
- LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
+ CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
break;
}
}
@@ -980,7 +1030,7 @@
case OMX_CommandPortDisable:
{
OMX_U32 portIndex = data;
- LOGV("PORT_DISABLED(%ld)", portIndex);
+ CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
CHECK(mState == EXECUTING || mState == RECONFIGURING);
CHECK_EQ(mPortStatus[portIndex], DISABLING);
@@ -1002,7 +1052,7 @@
case OMX_CommandPortEnable:
{
OMX_U32 portIndex = data;
- LOGV("PORT_ENABLED(%ld)", portIndex);
+ CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
CHECK(mState == EXECUTING || mState == RECONFIGURING);
CHECK_EQ(mPortStatus[portIndex], ENABLING);
@@ -1023,7 +1073,7 @@
{
OMX_U32 portIndex = data;
- LOGV("FLUSH_DONE(%ld)", portIndex);
+ CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
CHECK_EQ(mPortStatus[portIndex], SHUTTING_DOWN);
mPortStatus[portIndex] = ENABLED;
@@ -1038,7 +1088,7 @@
} else if (mState == EXECUTING_TO_IDLE) {
if (mPortStatus[kPortIndexInput] == ENABLED
&& mPortStatus[kPortIndexOutput] == ENABLED) {
- LOGV("Finished flushing both ports, now completing "
+ CODEC_LOGV("Finished flushing both ports, now completing "
"transition from EXECUTING to IDLE.");
mPortStatus[kPortIndexInput] = SHUTTING_DOWN;
@@ -1053,7 +1103,7 @@
if (mPortStatus[kPortIndexInput] == ENABLED
&& mPortStatus[kPortIndexOutput] == ENABLED) {
- LOGV("Finished flushing both ports, now continuing from"
+ CODEC_LOGV("Finished flushing both ports, now continuing from"
" seek-time.");
drainInputBuffers();
@@ -1066,7 +1116,7 @@
default:
{
- LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
+ CODEC_LOGV("CMD_COMPLETE(%d, %ld)", cmd, data);
break;
}
}
@@ -1076,7 +1126,7 @@
switch (newState) {
case OMX_StateIdle:
{
- LOGV("Now Idle.");
+ CODEC_LOGV("Now Idle.");
if (mState == LOADED_TO_IDLE) {
status_t err = mOMX->send_command(
mNode, OMX_CommandStateSet, OMX_StateExecuting);
@@ -1118,7 +1168,7 @@
{
CHECK_EQ(mState, IDLE_TO_EXECUTING);
- LOGV("Now Executing.");
+ CODEC_LOGV("Now Executing.");
setState(EXECUTING);
@@ -1134,7 +1184,7 @@
{
CHECK_EQ(mState, IDLE_TO_LOADED);
- LOGV("Now Loaded.");
+ CODEC_LOGV("Now Loaded.");
setState(LOADED);
break;
@@ -1200,7 +1250,7 @@
}
void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
- LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
+ CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
CHECK_EQ(mState, EXECUTING);
CHECK_EQ(portIndex, kPortIndexOutput);
@@ -1219,7 +1269,7 @@
CHECK(mState == EXECUTING || mState == RECONFIGURING
|| mState == EXECUTING_TO_IDLE);
- LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
+ CODEC_LOGV("flushPortAsync(%ld): we own %d out of %d buffers already.",
portIndex, countBuffersWeOwn(mPortBuffers[portIndex]),
mPortBuffers[portIndex].size());
@@ -1342,7 +1392,7 @@
size_t srcLength = 0;
if (err != OK) {
- LOGV("signalling end of input stream.");
+ CODEC_LOGV("signalling end of input stream.");
flags |= OMX_BUFFERFLAG_EOS;
mSignalledEOS = true;
@@ -1363,9 +1413,9 @@
&& srcBuffer->meta_data()->findInt32(kKeyTimeScale, &scale)) {
timestamp = ((OMX_TICKS)units * 1000000) / scale;
- LOGV("Calling empty_buffer on buffer %p (length %d)",
+ CODEC_LOGV("Calling empty_buffer on buffer %p (length %d)",
info->mBuffer, srcLength);
- LOGV("Calling empty_buffer with timestamp %lld us (%.2f secs)",
+ CODEC_LOGV("Calling empty_buffer with timestamp %lld us (%.2f secs)",
timestamp, timestamp / 1E6);
}
}
@@ -1386,12 +1436,12 @@
CHECK_EQ(info->mOwnedByComponent, false);
if (mNoMoreOutputData) {
- LOGV("There is no more output data available, not "
+ CODEC_LOGV("There is no more output data available, not "
"calling fillOutputBuffer");
return;
}
- LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
+ CODEC_LOGV("Calling fill_buffer on buffer %p", info->mBuffer);
mOMX->fill_buffer(mNode, info->mBuffer);
info->mOwnedByComponent = true;
@@ -1430,12 +1480,43 @@
mBufferFilled.signal();
}
+void OMXCodec::setRawAudioFormat(
+ OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
+ OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
+ InitOMXParams(&pcmParams);
+ pcmParams.nPortIndex = portIndex;
+
+ status_t err = mOMX->get_parameter(
+ mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
+
+ CHECK_EQ(err, OK);
+
+ pcmParams.nChannels = numChannels;
+ pcmParams.eNumData = OMX_NumericalDataSigned;
+ pcmParams.bInterleaved = OMX_TRUE;
+ pcmParams.nBitPerSample = 16;
+ pcmParams.nSamplingRate = sampleRate;
+ pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
+
+ if (numChannels == 1) {
+ pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
+ } else {
+ CHECK_EQ(numChannels, 2);
+
+ pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
+ pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ }
+
+ err = mOMX->set_parameter(
+ mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
+
+ CHECK_EQ(err, OK);
+}
+
void OMXCodec::setAMRFormat() {
if (!mIsEncoder) {
OMX_AUDIO_PARAM_AMRTYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
status_t err =
@@ -1459,62 +1540,35 @@
CHECK(format->findInt32(kKeySampleRate, &sampleRate));
CHECK(format->findInt32(kKeyChannelCount, &numChannels));
- OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
- pcmParams.nSize = sizeof(pcmParams);
- pcmParams.nVersion.s.nVersionMajor = 1;
- pcmParams.nVersion.s.nVersionMinor = 1;
- pcmParams.nPortIndex = kPortIndexInput;
-
- status_t err = mOMX->get_parameter(
- mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
-
- CHECK_EQ(err, OK);
-
- pcmParams.nChannels = numChannels;
- pcmParams.eNumData = OMX_NumericalDataSigned;
- pcmParams.bInterleaved = OMX_TRUE;
- pcmParams.nBitPerSample = 16;
- pcmParams.nSamplingRate = sampleRate;
- pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
-
- if (numChannels == 1) {
- pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelCF;
- } else {
- CHECK_EQ(numChannels, 2);
-
- pcmParams.eChannelMapping[0] = OMX_AUDIO_ChannelLF;
- pcmParams.eChannelMapping[1] = OMX_AUDIO_ChannelRF;
- }
-
- err = mOMX->set_parameter(
- mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
-
- CHECK_EQ(err, OK);
+ setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
}
}
void OMXCodec::setAACFormat(int32_t numChannels, int32_t sampleRate) {
- OMX_AUDIO_PARAM_AACPROFILETYPE profile;
- profile.nSize = sizeof(profile);
- profile.nVersion.s.nVersionMajor = 1;
- profile.nVersion.s.nVersionMinor = 1;
- profile.nPortIndex = kPortIndexInput;
+ if (mIsEncoder) {
+ setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
+ } else {
+ OMX_AUDIO_PARAM_AACPROFILETYPE profile;
+ InitOMXParams(&profile);
+ profile.nPortIndex = kPortIndexInput;
- status_t err =
- mOMX->get_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
- CHECK_EQ(err, OK);
+ status_t err = mOMX->get_parameter(
+ mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+ CHECK_EQ(err, OK);
- profile.nChannels = numChannels;
- profile.nSampleRate = sampleRate;
- profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
+ profile.nChannels = numChannels;
+ profile.nSampleRate = sampleRate;
+ profile.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
- err = mOMX->set_parameter(mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
- CHECK_EQ(err, OK);
+ err = mOMX->set_parameter(
+ mNode, OMX_IndexParamAudioAac, &profile, sizeof(profile));
+ CHECK_EQ(err, OK);
+ }
}
void OMXCodec::setImageOutputFormat(
OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height) {
- LOGV("setImageOutputFormat(%ld, %ld)", width, height);
+ CODEC_LOGV("setImageOutputFormat(%ld, %ld)", width, height);
#if 0
OMX_INDEXTYPE index;
@@ -1527,9 +1581,7 @@
#endif
OMX_PARAM_PORTDEFINITIONTYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
status_t err = mOMX->get_parameter(
@@ -1580,9 +1632,7 @@
void OMXCodec::setJPEGInputFormat(
OMX_U32 width, OMX_U32 height, OMX_U32 compressedSize) {
OMX_PARAM_PORTDEFINITIONTYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexInput;
status_t err = mOMX->get_parameter(
@@ -1650,7 +1700,7 @@
}
status_t OMXCodec::stop() {
- LOGV("stop");
+ CODEC_LOGV("stop");
Mutex::Autolock autoLock(mLock);
@@ -1668,7 +1718,7 @@
setState(EXECUTING_TO_IDLE);
if (mQuirks & kRequiresFlushBeforeShutdown) {
- LOGV("This component requires a flush before transitioning "
+ CODEC_LOGV("This component requires a flush before transitioning "
"from EXECUTING to IDLE...");
bool emulateInputFlushCompletion =
@@ -1740,7 +1790,7 @@
int64_t seekTimeUs;
if (options && options->getSeekTo(&seekTimeUs)) {
- LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
+ CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
mSignalledEOS = false;
mNoMoreOutputData = false;
@@ -1969,9 +2019,7 @@
void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
OMX_PARAM_PORTDEFINITIONTYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = portIndex;
status_t err = mOMX->get_parameter(
@@ -2037,9 +2085,7 @@
if (audioDef->eEncoding == OMX_AUDIO_CodingPCM) {
OMX_AUDIO_PARAM_PCMMODETYPE params;
- params.nSize = sizeof(params);
- params.nVersion.s.nVersionMajor = 1;
- params.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(¶ms);
params.nPortIndex = portIndex;
err = mOMX->get_parameter(
@@ -2076,9 +2122,7 @@
mOutputFormat->setCString(kKeyDecoderComponent, mComponentName);
OMX_PARAM_PORTDEFINITIONTYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
+ InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
status_t err = mOMX->get_parameter(
@@ -2102,40 +2146,44 @@
{
OMX_AUDIO_PORTDEFINITIONTYPE *audio_def = &def.format.audio;
- CHECK_EQ(audio_def->eEncoding, OMX_AUDIO_CodingPCM);
+ if (audio_def->eEncoding == OMX_AUDIO_CodingPCM) {
+ OMX_AUDIO_PARAM_PCMMODETYPE params;
+ InitOMXParams(¶ms);
+ params.nPortIndex = kPortIndexOutput;
- OMX_AUDIO_PARAM_PCMMODETYPE params;
- params.nSize = sizeof(params);
- params.nVersion.s.nVersionMajor = 1;
- params.nVersion.s.nVersionMinor = 1;
- params.nPortIndex = kPortIndexOutput;
+ err = mOMX->get_parameter(
+ mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params));
+ CHECK_EQ(err, OK);
- err = mOMX->get_parameter(
- mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params));
- CHECK_EQ(err, OK);
+ CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
+ CHECK_EQ(params.nBitPerSample, 16);
+ CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
- CHECK_EQ(params.eNumData, OMX_NumericalDataSigned);
- CHECK_EQ(params.nBitPerSample, 16);
- CHECK_EQ(params.ePCMMode, OMX_AUDIO_PCMModeLinear);
+ int32_t numChannels, sampleRate;
+ inputFormat->findInt32(kKeyChannelCount, &numChannels);
+ inputFormat->findInt32(kKeySampleRate, &sampleRate);
- int32_t numChannels, sampleRate;
- inputFormat->findInt32(kKeyChannelCount, &numChannels);
- inputFormat->findInt32(kKeySampleRate, &sampleRate);
+ if ((OMX_U32)numChannels != params.nChannels) {
+ LOGW("Codec outputs a different number of channels than "
+ "the input stream contains.");
+ }
- if ((OMX_U32)numChannels != params.nChannels) {
- LOGW("Codec outputs a different number of channels than "
- "the input stream contains.");
+ mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
+
+ // 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);
+
+ // The codec-reported sampleRate is not reliable...
+ mOutputFormat->setInt32(kKeySampleRate, sampleRate);
+ } else if (audio_def->eEncoding == OMX_AUDIO_CodingAMR) {
+ mOutputFormat->setCString(kKeyMIMEType, "audio/3gpp");
+ } else if (audio_def->eEncoding == OMX_AUDIO_CodingAAC) {
+ mOutputFormat->setCString(kKeyMIMEType, "audio/mp4a-latm");
+ } else {
+ CHECK(!"Should not be here. Unknown audio encoding.");
}
-
- mOutputFormat->setCString(kKeyMIMEType, "audio/raw");
-
- // 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);
-
- // The codec-reported sampleRate is not reliable...
- mOutputFormat->setInt32(kKeySampleRate, sampleRate);
break;
}
diff --git a/telephony/java/com/android/internal/telephony/IccRecords.java b/telephony/java/com/android/internal/telephony/IccRecords.java
index ea24c25..b8d9e3c 100644
--- a/telephony/java/com/android/internal/telephony/IccRecords.java
+++ b/telephony/java/com/android/internal/telephony/IccRecords.java
@@ -31,7 +31,7 @@
public abstract class IccRecords extends Handler implements IccConstants {
protected static final boolean DBG = true;
- //***** Instance Variables
+ // ***** Instance Variables
protected PhoneBase phone;
protected RegistrantList recordsLoadedRegistrants = new RegistrantList();
@@ -40,7 +40,7 @@
protected AdnRecordCache adnCache;
- //***** Cached SIM State; cleared on channel close
+ // ***** Cached SIM State; cleared on channel close
protected boolean recordsRequested = false; // true if we've made requests for the sim records
@@ -54,23 +54,26 @@
protected boolean isVoiceMailFixed = false;
protected int countVoiceMessages = 0;
- protected int mncLength = 0; // 0 is used to indicate that the value
- // is not initialized
+ protected int mncLength = UNINITIALIZED;
protected int mailboxIndex = 0; // 0 is no mailbox dailing number associated
protected String spn;
protected int spnDisplayCondition;
- //***** Constants
+ // ***** Constants
+
+ // Markers for mncLength
+ protected static final int UNINITIALIZED = -1;
+ protected static final int UNKNOWN = 0;
// Bitmasks for SPN display rules.
protected static final int SPN_RULE_SHOW_SPN = 0x01;
protected static final int SPN_RULE_SHOW_PLMN = 0x02;
- //***** Event Constants
+ // ***** Event Constants
protected static final int EVENT_SET_MSISDN_DONE = 30;
- //***** Constructor
+ // ***** Constructor
public IccRecords(PhoneBase p) {
this.phone = p;
@@ -234,4 +237,3 @@
protected abstract void log(String s);
}
-
diff --git a/telephony/java/com/android/internal/telephony/gsm/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java
similarity index 84%
rename from telephony/java/com/android/internal/telephony/gsm/MccTable.java
rename to telephony/java/com/android/internal/telephony/MccTable.java
index 9343f44..0d11f8c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/MccTable.java
@@ -14,7 +14,17 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
+
+import android.app.ActivityManagerNative;
+import android.app.AlarmManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.net.wifi.WifiManager;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.util.Log;
import java.util.Arrays;
@@ -475,8 +485,10 @@
0x65630400, 0x67660400, 0x70790400, 0x73720400, 0x75790400, 0x666b0400
};
+ static final String LOG_TAG = "MccTable";
+
/**
- * Given a GSM Mobile Country Code, returns a default time zone ID
+ * Given a Mobile Country Code, returns a default time zone ID
* if available. Returns null if unavailable.
*/
public static String defaultTimeZoneForMcc(int mcc) {
@@ -494,7 +506,7 @@
}
/**
- * Given a GSM Mobile Country Code, returns an ISO two-character
+ * Given a Mobile Country Code, returns an ISO two-character
* country code if available. Returns "" if unavailable.
*/
public static String countryCodeForMcc(int mcc) {
@@ -553,4 +565,95 @@
return wifi;
}
+ /**
+ * Updates MCC and MNC device configuration information for application retrieving
+ * correct version of resources. If either MCC or MNC is 0, they will be ignored (not set).
+ * @param phone PhoneBae to act on.
+ * @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
+ */
+ public static void updateMccMncConfiguration(PhoneBase phone, String mccmnc) {
+ Configuration config = new Configuration();
+ int mcc, mnc;
+
+ try {
+ mcc = Integer.parseInt(mccmnc.substring(0,3));
+ mnc = Integer.parseInt(mccmnc.substring(3));
+ } catch (NumberFormatException e) {
+ Log.e(LOG_TAG, "Error parsing IMSI");
+ return;
+ }
+
+ Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
+
+ if (mcc != 0) {
+ config.mcc = mcc;
+ setTimezoneFromMccIfNeeded(phone, mcc);
+ setLocaleFromMccIfNeeded(phone, mcc);
+ setWifiChannelsFromMccIfNeeded(phone, mcc);
+ }
+ if (mnc != 0) {
+ config.mnc = mnc;
+ }
+ try {
+ ActivityManagerNative.getDefault().updateConfiguration(config);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Can't update configuration", e);
+ }
+ }
+
+ /**
+ * If the timezone is not already set, set it based on the MCC of the SIM.
+ * @param phone PhoneBase to act on (get context from).
+ * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
+ */
+ private static void setTimezoneFromMccIfNeeded(PhoneBase phone, int mcc) {
+ String timezone = SystemProperties.get(ServiceStateTracker.TIMEZONE_PROPERTY);
+ if (timezone == null || timezone.length() == 0) {
+ String zoneId = defaultTimeZoneForMcc(mcc);
+ if (zoneId != null && zoneId.length() > 0) {
+ Context context = phone.getContext();
+ // Set time zone based on MCC
+ AlarmManager alarm =
+ (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ alarm.setTimeZone(zoneId);
+ Log.d(LOG_TAG, "timezone set to "+zoneId);
+ }
+ }
+ }
+
+ /**
+ * If the locale is not already set, set it based on the MCC of the SIM.
+ * @param phone PhoneBase to act on.
+ * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
+ */
+ private static void setLocaleFromMccIfNeeded(PhoneBase phone, int mcc) {
+ String language = MccTable.defaultLanguageForMcc(mcc);
+ String country = MccTable.countryCodeForMcc(mcc);
+
+ Log.d(LOG_TAG, "locale set to "+language+"_"+country);
+ phone.setSystemLocale(language, country);
+ }
+
+ /**
+ * If the number of allowed wifi channels has not been set, set it based on
+ * the MCC of the SIM.
+ * @param phone PhoneBase to act on (get context from).
+ * @param mcc Mobile Country Code of the SIM or SIM-like entity (build prop on CDMA)
+ */
+ private static void setWifiChannelsFromMccIfNeeded(PhoneBase phone, int mcc) {
+ int wifiChannels = MccTable.wifiChannelsForMcc(mcc);
+ if (wifiChannels != 0) {
+ Context context = phone.getContext();
+ // only set to this default if the user hasn't manually set it
+ try {
+ Settings.Secure.getInt(context.getContentResolver(),
+ Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
+ } catch (Settings.SettingNotFoundException e) {
+ Log.d(LOG_TAG, "WIFI_NUM_ALLOWED_CHANNESL set to " + wifiChannels);
+ WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ // don't persist
+ wM.setNumAllowedChannels(wifiChannels, false);
+ }
+ }
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 958e96d..ff06bc0 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -48,10 +48,7 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.Connection;
import com.android.internal.telephony.DataConnection;
-// TODO(Moto): need to move MccTable from telephony.gsm to telephony
-// since there is no difference between CDMA and GSM for MccTable and
-// CDMA uses gsm's MccTable is not good.
-import com.android.internal.telephony.gsm.MccTable;
+import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccException;
import com.android.internal.telephony.IccFileHandler;
@@ -179,6 +176,10 @@
// This is needed to handle phone process crashes
String inEcm=SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE, "false");
mIsPhoneInEcmState = inEcm.equals("true");
+ if (mIsPhoneInEcmState) {
+ // Send a message which will invoke handleExitEmergencyCallbackMode
+ mCM.exitEmergencyCallbackMode(obtainMessage(EVENT_EXIT_EMERGENCY_CALLBACK_RESPONSE));
+ }
// get the string that specifies the carrier OTA Sp number
mCarrierOtaSpNumSchema = SystemProperties.get(
@@ -199,7 +200,7 @@
updateCurrentCarrierInProvider(operatorNumeric);
// Updates MCC MNC device configuration information
- updateMccMncConfiguration(operatorNumeric);
+ MccTable.updateMccMncConfiguration(this, operatorNumeric);
// Notify voicemails.
@@ -1011,7 +1012,6 @@
Log.d(LOG_TAG, "ERI read, notify registrants");
mEriFileLoadedRegistrants.notifyRegistrants();
}
- setSystemProperty(TelephonyProperties.PROPERTY_INECM_MODE,"false");
}
break;
@@ -1403,21 +1403,4 @@
return false;
}
- /**
- * Updates MCC and MNC device configuration information for application retrieving
- * correct version of resources
- *
- */
- private void updateMccMncConfiguration(String operatorNumeric) {
- if (operatorNumeric.length() >= 5) {
- Configuration config = new Configuration();
- config.mcc = Integer.parseInt(operatorNumeric.substring(0,3));
- config.mnc = Integer.parseInt(operatorNumeric.substring(3));
- try {
- ActivityManagerNative.getDefault().updateConfiguration(config);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Can't update configuration", e);
- }
- }
- }
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index dab529e..46e360b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -45,9 +45,8 @@
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
-import com.android.internal.telephony.gsm.MccTable;
import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.PhoneProxy;
+import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import com.android.internal.telephony.TelephonyIntents;
diff --git a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
index 7c74314..b9ece8b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
+++ b/telephony/java/com/android/internal/telephony/cdma/RuimRecords.java
@@ -28,7 +28,7 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.RuimCard;
-import com.android.internal.telephony.gsm.MccTable;
+import com.android.internal.telephony.MccTable;
// can't be used since VoiceMailConstants is not public
//import com.android.internal.telephony.gsm.VoiceMailConstants;
@@ -47,7 +47,7 @@
private static final boolean DBG = true;
private boolean m_ota_commited=false;
- //***** Instance Variables
+ // ***** Instance Variables
private String mImsi;
private String mMyMobileNumber;
@@ -55,7 +55,7 @@
private String mPrlVersion;
- //***** Event Constants
+ // ***** Event Constants
private static final int EVENT_RUIM_READY = 1;
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
@@ -109,7 +109,7 @@
@Override
protected void onRadioOffOrNotAvailable() {
countVoiceMessages = 0;
- mncLength = 0;
+ mncLength = UNINITIALIZED;
iccid = null;
adnCache.reset();
@@ -167,7 +167,7 @@
}
// TODO(Moto): mncLength is not set anywhere.
- if (mncLength != 0) {
+ 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)
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index a9be068..65463e5 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -49,6 +49,7 @@
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.MccTable;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
index 4272faa..7f7855a 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SIMRecords.java
@@ -19,13 +19,10 @@
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import android.app.AlarmManager;
import android.content.Context;
-import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Message;
import android.os.SystemProperties;
-import android.provider.Settings;
import android.util.Log;
import com.android.internal.telephony.AdnRecord;
@@ -37,6 +34,7 @@
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.IccVmFixedException;
import com.android.internal.telephony.IccVmNotSupportedException;
+import com.android.internal.telephony.MccTable;
import java.util.ArrayList;
@@ -51,14 +49,14 @@
private static final boolean DBG = true;
- //***** Instance Variables
+ // ***** Instance Variables
VoiceMailConstants mVmConfig;
SpnOverride mSpnOverride;
- //***** Cached SIM State; cleared on channel close
+ // ***** Cached SIM State; cleared on channel close
String imsi;
boolean callForwardingEnabled;
@@ -88,7 +86,7 @@
String pnnHomeName = null;
- //***** Constants
+ // ***** Constants
// Bitmasks for SPN display rules.
static final int SPN_RULE_SHOW_SPN = 0x01;
@@ -113,7 +111,7 @@
private static final int CPHS_SST_MBN_MASK = 0x30;
private static final int CPHS_SST_MBN_ENABLED = 0x30;
- //***** Event Constants
+ // ***** Event Constants
private static final int EVENT_SIM_READY = 1;
private static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE = 2;
@@ -143,9 +141,7 @@
private static final int EVENT_SIM_REFRESH = 31;
private static final int EVENT_GET_CFIS_DONE = 32;
- private static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
-
- //***** Constructor
+ // ***** Constructor
SIMRecords(GSMPhone p) {
super(p);
@@ -188,7 +184,7 @@
msisdn = null;
voiceMailNum = null;
countVoiceMessages = 0;
- mncLength = 0;
+ mncLength = UNINITIALIZED;
iccid = null;
// -1 means no EF_SPN found; treat accordingly.
spnDisplayCondition = -1;
@@ -453,79 +449,16 @@
* provided the SIM card. Returns null of SIM is not yet ready
*/
String getSIMOperatorNumeric() {
- if (imsi == null) {
+ if (imsi == null || mncLength == UNINITIALIZED || mncLength == UNKNOWN) {
return null;
}
- if (mncLength != 0) {
- // Length = length of MCC + length of MNC
- // length of mcc = 3 (TS 23.003 Section 2.2)
- return imsi.substring(0, 3 + mncLength);
- }
-
- // Guess the MNC length based on the MCC if we don't
- // have a valid value in ef[ad]
-
- int mcc;
-
- mcc = Integer.parseInt(imsi.substring(0,3));
-
- return imsi.substring(0, 3 + MccTable.smallestDigitsMccForMnc(mcc));
+ // Length = length of MCC + length of MNC
+ // length of mcc = 3 (TS 23.003 Section 2.2)
+ return imsi.substring(0, 3 + mncLength);
}
- /**
- * If the timezone is not already set, set it based on the MCC of the SIM.
- * @param mcc Mobile Country Code of the SIM
- */
- private void setTimezoneFromMccIfNeeded(int mcc) {
- String timezone = SystemProperties.get(TIMEZONE_PROPERTY);
- if (timezone == null || timezone.length() == 0) {
- String zoneId = MccTable.defaultTimeZoneForMcc(mcc);
-
- if (zoneId != null && zoneId.length() > 0) {
- // Set time zone based on MCC
- AlarmManager alarm =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
- alarm.setTimeZone(zoneId);
- }
- }
- }
-
- /**
- * If the locale is not already set, set it based on the MCC of the SIM.
- * @param mcc Mobile Country Code of the SIM
- */
- private void setLocaleFromMccIfNeeded(int mcc) {
- String language = MccTable.defaultLanguageForMcc(mcc);
- String country = MccTable.countryCodeForMcc(mcc);
-
- phone.setSystemLocale(language, country);
- }
-
- /**
- * If the number of allowed wifi channels has not been set, set it based on
- * the MCC of the SIM.
- * @param mcc Mobile Country Code of the SIM
- */
- private void setWifiChannelsFromMccIfNeeded(int mcc) {
- int wifiChannels = MccTable.wifiChannelsForMcc(mcc);
-
- if (wifiChannels != 0) {
- Context context = phone.getContext();
- // only set to this default if the user hasn't manually set it
- try {
- Settings.Secure.getInt(context.getContentResolver(),
- Settings.Secure.WIFI_NUM_ALLOWED_CHANNELS);
- } catch (Settings.SettingNotFoundException e) {
- WifiManager wM = (WifiManager)
- context.getSystemService(Context.WIFI_SERVICE);
- // don't persist
- wM.setNumAllowedChannels(wifiChannels, false);
- }
- }
- }
-
- //***** Overridden from Handler
+ // ***** Overridden from Handler
public void handleMessage(Message msg) {
AsyncResult ar;
AdnRecord adn;
@@ -564,14 +497,25 @@
}
Log.d(LOG_TAG, "IMSI: " + imsi.substring(0, 6) + "xxxxxxxxx");
- ((GSMPhone) phone).mSimCard.updateImsiConfiguration(imsi);
+
+ if (mncLength == UNKNOWN) {
+ // the SIM has told us all it knows, but it didn't know the mnc length.
+ // guess using the mcc
+ try {
+ int mcc = Integer.parseInt(imsi.substring(0,3));
+ mncLength = MccTable.smallestDigitsMccForMnc(mcc);
+ } catch (NumberFormatException e) {
+ mncLength = UNKNOWN;
+ Log.e(LOG_TAG, "SIMRecords: Corrupt IMSI!");
+ }
+ }
+
+ if (mncLength != UNKNOWN && mncLength != UNINITIALIZED) {
+ // finally have both the imsi and the mncLength and can parse the imsi properly
+ MccTable.updateMccMncConfiguration(phone, imsi.substring(0, 3 + mncLength));
+ }
((GSMPhone) phone).mSimCard.broadcastIccStateChangedIntent(
SimCard.INTENT_VALUE_ICC_IMSI, null);
-
- int mcc = Integer.parseInt(imsi.substring(0, 3));
- setTimezoneFromMccIfNeeded(mcc);
- setLocaleFromMccIfNeeded(mcc);
- setWifiChannelsFromMccIfNeeded(mcc);
break;
case EVENT_GET_MBI_DONE:
@@ -794,12 +738,25 @@
mncLength = (int)data[3] & 0xf;
if (mncLength == 0xf) {
- // Resetting mncLength to 0 to indicate that it is not
- // initialised
- mncLength = 0;
+ if (imsi != null) {
+ try {
+ int mcc = Integer.parseInt(imsi.substring(0,3));
- Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD");
- break;
+ mncLength = MccTable.smallestDigitsMccForMnc(mcc);
+ } catch (NumberFormatException e) {
+ mncLength = UNKNOWN;
+ Log.e(LOG_TAG, "SIMRecords: Corrupt IMSI!");
+ }
+ } else {
+ // Indicate we got this info, but it didn't contain the length.
+ mncLength = UNKNOWN;
+
+ Log.d(LOG_TAG, "SIMRecords: MNC length not present in EF_AD");
+ }
+ }
+ if (imsi != null && mncLength != UNKNOWN) {
+ // finally have both imsi and the length of the mnc and can parse it properly
+ MccTable.updateMccMncConfiguration(phone, imsi.substring(0, 3 + mncLength));
}
break;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SimCard.java b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
index 6c56682..835cb29 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SimCard.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SimCard.java
@@ -16,9 +16,6 @@
package com.android.internal.telephony.gsm;
-import android.app.ActivityManagerNative;
-import android.content.res.Configuration;
-import android.os.RemoteException;
import android.util.Log;
import com.android.internal.telephony.IccCard;
@@ -50,20 +47,4 @@
return ((GSMPhone)mPhone).mSIMRecords.getServiceProviderName();
}
- public void updateImsiConfiguration(String imsi) {
- if (imsi.length() >= 6) {
- Configuration config = new Configuration();
- config.mcc = ((imsi.charAt(0)-'0')*100)
- + ((imsi.charAt(1)-'0')*10)
- + (imsi.charAt(2)-'0');
- config.mnc = ((imsi.charAt(3)-'0')*100)
- + ((imsi.charAt(4)-'0')*10)
- + (imsi.charAt(5)-'0');
- try {
- ActivityManagerNative.getDefault().updateConfiguration(config);
- } catch (RemoteException e) {
- Log.e(mLogTag, "[SimCard] Remote Exception when updating imsi configuration");
- }
- }
- }
}
diff --git a/test-runner/android/test/IsolatedContext.java b/test-runner/android/test/IsolatedContext.java
index 4bd9528..5c66169 100644
--- a/test-runner/android/test/IsolatedContext.java
+++ b/test-runner/android/test/IsolatedContext.java
@@ -4,6 +4,7 @@
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdatedListener;
+import android.accounts.Account;
import android.content.ContextWrapper;
import android.content.ContentResolver;
import android.content.Intent;
@@ -101,6 +102,10 @@
Handler handler, boolean updateImmediately) {
// do nothing
}
+
+ public Account[] getAccounts() {
+ return new Account[]{};
+ }
}
@Override
public File getFilesDir() {
diff --git a/tests/AndroidTests/src/com/android/unit_tests/MccTableTest.java b/tests/AndroidTests/src/com/android/unit_tests/MccTableTest.java
index 875376a..b2f1ded 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/MccTableTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/MccTableTest.java
@@ -16,7 +16,7 @@
package com.android.unit_tests;
-import com.android.internal.telephony.gsm.MccTable;
+import com.android.internal.telephony.MccTable;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
diff --git a/tests/BrowserPowerTest/Android.mk b/tests/BrowserPowerTest/Android.mk
new file mode 100644
index 0000000..f2c07b3
--- /dev/null
+++ b/tests/BrowserPowerTest/Android.mk
@@ -0,0 +1,30 @@
+# Copyright 2008, 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := BrowserPowerTests
+
+#LOCAL_INSTRUMENTATION_FOR := browserpowertest
+
+include $(BUILD_PACKAGE)
diff --git a/tests/BrowserPowerTest/AndroidManifest.xml b/tests/BrowserPowerTest/AndroidManifest.xml
new file mode 100644
index 0000000..43eeaad
--- /dev/null
+++ b/tests/BrowserPowerTest/AndroidManifest.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.browserpowertest">
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <activity android:name="PowerTestActivity" android:label="Power">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.TEST" />
+ </intent-filter>
+ </activity>
+ </application>
+ <!--
+ This declares that this app uses the instrumentation test runner targeting
+ the package of browserpowertest. To run the tests use the command:
+ "adb shell am instrument -w com.android.browserpowertest/.PowerTestRunner"
+ -->
+ <instrumentation android:name=".PowerTestRunner"
+ android:targetPackage="com.android.browserpowertest"
+ android:label="Test runner for Browser Power Tests."
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_SDCARD" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+</manifest>
diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
new file mode 100644
index 0000000..74ac865f
--- /dev/null
+++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerMeasurement.java
@@ -0,0 +1,51 @@
+package com.android.browserpowertest;
+
+import android.content.Intent;
+import android.app.Instrumentation;
+import android.os.Handler;
+import android.os.Message;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import junit.framework.*;
+
+public class PowerMeasurement extends ActivityInstrumentationTestCase2<PowerTestActivity> {
+
+ private static final String LOGTAG = "PowerMeasurement";
+ private static final String PKG_NAME = "com.android.browserpowertest";
+ private static final String TESTING_URL = "http://www.espn.com";
+ private static final int TIME_OUT = 2 * 60 * 1000;
+ private static final int DELAY = 0;
+
+ public PowerMeasurement() {
+ super(PKG_NAME, PowerTestActivity.class);
+ }
+
+ public void testPageLoad() throws Throwable {
+ Instrumentation mInst = getInstrumentation();
+ PowerTestActivity act = getActivity();
+
+ Intent intent = new Intent(mInst.getContext(), PowerTestActivity.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ long start = System.currentTimeMillis();
+ PowerTestActivity activity = (PowerTestActivity)mInst.startActivitySync(
+ intent);
+ activity.reset();
+ //send a message with the new URL
+ Handler handler = activity.getHandler();
+ Message msg = handler.obtainMessage(
+ PowerTestActivity.MSG_NAVIGATE, TIME_OUT, DELAY);
+ msg.getData().putString(PowerTestActivity.MSG_NAV_URL, TESTING_URL);
+ msg.getData().putBoolean(PowerTestActivity.MSG_NAV_LOGTIME, true);
+
+ handler.sendMessage(msg);
+ boolean timeoutFlag = activity.waitUntilDone();
+ long end = System.currentTimeMillis();
+ assertFalse(TESTING_URL + " failed to load", timeoutFlag);
+ boolean pageErrorFlag = activity.getPageError();
+ assertFalse(TESTING_URL + " is not available, either network is down or the server is down",
+ pageErrorFlag);
+ Log.v(LOGTAG, "Page is loaded in " + activity.getPageLoadTime() + " ms.");
+
+ activity.finish();
+ }
+}
diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java
new file mode 100644
index 0000000..77e390b
--- /dev/null
+++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestActivity.java
@@ -0,0 +1,253 @@
+package com.android.browserpowertest;
+
+import android.app.Activity;
+import android.app.ActivityThread;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.ViewGroup;
+import android.webkit.WebChromeClient;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.webkit.WebSettings.LayoutAlgorithm;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+
+public class PowerTestActivity extends Activity {
+
+ public static final String LOGTAG = "PowerTestActivity";
+ public static final String PARAM_URL = "URL";
+ public static final String PARAM_TIMEOUT = "Timeout";
+ public static final int RESULT_TIMEOUT = 0xDEAD;
+ public static final int MSG_TIMEOUT = 0xC001;
+ public static final int MSG_NAVIGATE = 0xC002;
+ public static final String MSG_NAV_URL = "url";
+ public static final String MSG_NAV_LOGTIME = "logtime";
+
+ private WebView webView;
+ private SimpleWebViewClient webViewClient;
+ private SimpleChromeClient chromeClient;
+ private Handler handler;
+ private boolean timeoutFlag;
+ private boolean logTime;
+ private boolean pageDone;
+ private Object pageDoneLock;
+ private int pageStartCount;
+ private int manualDelay;
+ private long startTime;
+ private long pageLoadTime;
+ private PageDoneRunner pageDoneRunner = new PageDoneRunner();
+
+ public PowerTestActivity() {
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
+
+ LinearLayout contentView = new LinearLayout(this);
+ contentView.setOrientation(LinearLayout.VERTICAL);
+ setContentView(contentView);
+ setTitle("Idle");
+
+ webView = new WebView(this);
+ webView.getSettings().setJavaScriptEnabled(true);
+ webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
+ webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
+
+ webViewClient = new SimpleWebViewClient();
+ chromeClient = new SimpleChromeClient();
+ webView.setWebViewClient(webViewClient);
+ webView.setWebChromeClient(chromeClient);
+
+ contentView.addView(webView, new LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT, 0.0f));
+
+ handler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_TIMEOUT:
+ handleTimeout();
+ return;
+ case MSG_NAVIGATE:
+ manualDelay = msg.arg2;
+ navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1);
+ logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME);
+ return;
+ }
+ }
+ };
+
+ pageDoneLock = new Object();
+ }
+
+ public void reset() {
+ synchronized (pageDoneLock) {
+ pageDone = false;
+ }
+ timeoutFlag = false;
+ pageStartCount = 0;
+ chromeClient.resetJsTimeout();
+ }
+
+ private void navigate(String url, int timeout) {
+ if(url == null) {
+ Log.v(LOGTAG, "URL is null, cancelling...");
+ finish();
+ }
+ webView.stopLoading();
+ if(logTime) {
+ webView.clearCache(true);
+ }
+ startTime = System.currentTimeMillis();
+ Log.v(LOGTAG, "Navigating to URL: " + url);
+ webView.loadUrl(url);
+
+ if(timeout != 0) {
+ //set a timer with specified timeout (in ms)
+ handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
+ timeout);
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
+ webView.clearCache(true);
+ webView.destroy();
+ }
+
+ private boolean isPageDone() {
+ synchronized (pageDoneLock) {
+ return pageDone;
+ }
+ }
+
+ private void setPageDone(boolean pageDone) {
+ synchronized (pageDoneLock) {
+ this.pageDone = pageDone;
+ pageDoneLock.notifyAll();
+ }
+ }
+
+ private void handleTimeout() {
+ int progress = webView.getProgress();
+ webView.stopLoading();
+ Log.v(LOGTAG, "Page timeout triggered, progress = " + progress);
+ timeoutFlag = true;
+ handler.postDelayed(pageDoneRunner, manualDelay);
+ }
+
+ public boolean waitUntilDone() {
+ validateNotAppThread();
+ synchronized (pageDoneLock) {
+ while(!isPageDone()) {
+ try {
+ pageDoneLock.wait();
+ } catch (InterruptedException ie) {
+ //no-op
+ }
+ }
+ }
+ return timeoutFlag;
+ }
+
+ public Handler getHandler() {
+ return handler;
+ }
+
+ private final void validateNotAppThread() {
+ if (ActivityThread.currentActivityThread() != null) {
+ throw new RuntimeException(
+ "This method can not be called from the main application thread");
+ }
+ }
+
+ public long getPageLoadTime() {
+ return pageLoadTime;
+ }
+
+ public boolean getPageError() {
+ return webViewClient.getPageErrorFlag();
+ }
+
+ class SimpleWebViewClient extends WebViewClient {
+
+ private boolean pageErrorFlag = false;
+
+ @Override
+ public void onReceivedError(WebView view, int errorCode, String description,
+ String failingUrl) {
+ pageErrorFlag = true;
+ Log.v(LOGTAG, "WebCore error: code=" + errorCode
+ + ", description=" + description
+ + ", url=" + failingUrl);
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ pageStartCount++;
+ Log.v(LOGTAG, "onPageStarted: " + url);
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ Log.v(LOGTAG, "onPageFinished: " + url);
+ // let handleTimeout take care of finishing the page
+ if(!timeoutFlag)
+ handler.postDelayed(new WebViewStatusChecker(), 500);
+ }
+
+ // return true if the URL is not available or the page is down
+ public boolean getPageErrorFlag() {
+ return pageErrorFlag;
+ }
+ }
+
+ class SimpleChromeClient extends WebChromeClient {
+
+ private int timeoutCounter = 0;
+
+ public void resetJsTimeout() {
+ timeoutCounter = 0;
+ }
+
+ @Override
+ public void onReceivedTitle(WebView view, String title) {
+ PowerTestActivity.this.setTitle(title);
+ }
+ }
+
+ class WebViewStatusChecker implements Runnable {
+
+ private int initialStartCount;
+
+ public WebViewStatusChecker() {
+ initialStartCount = pageStartCount;
+ }
+
+ public void run() {
+ if (initialStartCount == pageStartCount && !isPageDone()) {
+ handler.removeMessages(MSG_TIMEOUT);
+ webView.stopLoading();
+ handler.postDelayed(pageDoneRunner, manualDelay);
+ }
+ }
+ }
+
+ class PageDoneRunner implements Runnable {
+
+ public void run() {
+ Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
+ pageLoadTime = System.currentTimeMillis() - startTime;
+ setPageDone(true);
+ }
+ }
+}
diff --git a/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestRunner.java b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestRunner.java
new file mode 100644
index 0000000..4857209
--- /dev/null
+++ b/tests/BrowserPowerTest/src/com/android/browserpowertest/PowerTestRunner.java
@@ -0,0 +1,31 @@
+package com.android.browserpowertest;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+
+import junit.framework.TestSuite;
+
+
+/**
+ * Instrumentation Test Runner for all browser power tests.
+ *
+ * Running power tests:
+ *
+ * adb shell am instrument \
+ * -w com.android.browserpowertest/.PowerTestRunner
+ */
+
+public class PowerTestRunner extends InstrumentationTestRunner {
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(PowerMeasurement.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return PowerTestRunner.class.getClassLoader();
+ }
+
+}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index f9d2434..3cf6a71 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -984,7 +984,7 @@
while ((code=block.next()) != ResXMLTree::END_DOCUMENT && code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
- if (strcmp16(block.getElementName(&len), private_symbols16.string()) == 0) {
+ if (strcmp16(block.getElementName(&len), add_resource16.string()) == 0) {
break;
}
}