Merge change 6382
* changes:
add a virtual destructor to region_rasterizer, to be on the safe side
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index afda98d..b624402 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -88,8 +88,10 @@
import android.telephony.TelephonyManager;
import android.text.ClipboardManager;
import android.util.AndroidRuntimeException;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextThemeWrapper;
+import android.view.Display;
import android.view.LayoutInflater;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityManager;
@@ -151,6 +153,7 @@
*/
class ApplicationContext extends Context {
private final static String TAG = "ApplicationContext";
+ private final static boolean DEBUG = false;
private final static boolean DEBUG_ICONS = false;
private static final Object sSync = new Object();
@@ -1254,7 +1257,7 @@
@Override
public int checkUriPermission(Uri uri, String readPermission,
String writePermission, int pid, int uid, int modeFlags) {
- if (false) {
+ if (DEBUG) {
Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
+ readPermission + " writePermission=" + writePermission
+ " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
@@ -1356,6 +1359,19 @@
c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
c.init(pi, null, mMainThread);
if (c.mResources != null) {
+ Resources newRes = c.mResources;
+ if (mResources.getCompatibilityInfo().applicationScale !=
+ newRes.getCompatibilityInfo().applicationScale) {
+ DisplayMetrics dm = mMainThread.getDisplayMetricsLocked(false);
+ c.mResources = new Resources(newRes.getAssets(), dm,
+ newRes.getConfiguration(),
+ mResources.getCompatibilityInfo().copy());
+ if (DEBUG) {
+ Log.d(TAG, "loaded context has different scaling. Using container's" +
+ " compatiblity info:" + mResources.getDisplayMetrics());
+ }
+
+ }
return c;
}
}
@@ -1475,7 +1491,7 @@
if ((mode&MODE_WORLD_WRITEABLE) != 0) {
perms |= FileUtils.S_IWOTH;
}
- if (false) {
+ if (DEBUG) {
Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
+ ", perms=0x" + Integer.toHexString(perms));
}
diff --git a/core/java/android/backup/BackupManager.java b/core/java/android/backup/BackupManager.java
index 5b4ac0d..34a1a0c 100644
--- a/core/java/android/backup/BackupManager.java
+++ b/core/java/android/backup/BackupManager.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.util.Log;
/**
* BackupManager is the interface to the system's backup service.
@@ -39,14 +40,17 @@
* @hide pending API solidification
*/
public class BackupManager {
- private Context mContext;
- private IBackupManager mService;
+ private static final String TAG = "BackupManager";
- /**
- * Defined backup transports understood by {@link IBackupManager.selectBackupTransport}.
- */
- public static final int TRANSPORT_LOCAL = 1;
- public static final int TRANSPORT_GOOGLE = 2;
+ private Context mContext;
+ private static IBackupManager sService;
+
+ private static void checkServiceBinder() {
+ if (sService == null) {
+ sService = IBackupManager.Stub.asInterface(
+ ServiceManager.getService(Context.BACKUP_SERVICE));
+ }
+ }
/**
* Constructs a BackupManager object through which the application can
@@ -58,8 +62,6 @@
*/
public BackupManager(Context context) {
mContext = context;
- mService = IBackupManager.Stub.asInterface(
- ServiceManager.getService(Context.BACKUP_SERVICE));
}
/**
@@ -68,10 +70,31 @@
* {@link android.app.BackupAgent} subclass will be scheduled when you call this method.
*/
public void dataChanged() {
- if (mService != null) {
+ checkServiceBinder();
+ if (sService != null) {
try {
- mService.dataChanged(mContext.getPackageName());
+ sService.dataChanged(mContext.getPackageName());
} catch (RemoteException e) {
+ Log.d(TAG, "dataChanged() couldn't connect");
+ }
+ }
+ }
+
+ /**
+ * Convenience method for callers who need to indicate that some other package
+ * needs a backup pass. This can be relevant in the case of groups of packages
+ * that share a uid, for example.
+ *
+ * This method requires that the application hold the "android.permission.BACKUP"
+ * permission if the package named in the argument is not the caller's own.
+ */
+ public static void dataChanged(String packageName) {
+ checkServiceBinder();
+ if (sService != null) {
+ try {
+ sService.dataChanged(packageName);
+ } catch (RemoteException e) {
+ Log.d(TAG, "dataChanged(pkg) couldn't connect");
}
}
}
@@ -85,10 +108,12 @@
*/
public IRestoreSession beginRestoreSession(String transport) {
IRestoreSession binder = null;
- if (mService != null) {
+ checkServiceBinder();
+ if (sService != null) {
try {
- binder = mService.beginRestoreSession(transport);
+ binder = sService.beginRestoreSession(transport);
} catch (RemoteException e) {
+ Log.d(TAG, "beginRestoreSession() couldn't connect");
}
}
return binder;
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 4e6fe07..dfe304d 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -159,14 +159,32 @@
}
}
- private CompatibilityInfo() {
- appFlags = ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
- | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
- | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
- applicationScale = applicationInvertedScale = 1.0f;
- mCompatibilityFlags = EXPANDABLE | CONFIGURED_EXPANDABLE;
+ private CompatibilityInfo(int appFlags, int compFlags, float scale, float invertedScale) {
+ this.appFlags = appFlags;
+ mCompatibilityFlags = compFlags;
+ applicationScale = scale;
+ applicationInvertedScale = invertedScale;
}
+ private CompatibilityInfo() {
+ this(ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS,
+ EXPANDABLE | CONFIGURED_EXPANDABLE,
+ 1.0f,
+ 1.0f);
+ }
+
+ /**
+ * Returns the copy of this instance.
+ */
+ public CompatibilityInfo copy() {
+ CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags,
+ applicationScale, applicationInvertedScale);
+ info.setVisibleRect(mXOffset, mWidth, mHeight);
+ return info;
+ }
+
/**
* Sets the application's visible rect in compatibility mode.
* @param xOffset the application's x offset that is added to center the content.
@@ -470,4 +488,4 @@
return mVisibleInsets;
}
}
-}
\ No newline at end of file
+}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index d7512bb..49ad656 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -129,7 +129,7 @@
*/
public Resources(AssetManager assets, DisplayMetrics metrics,
Configuration config) {
- this(assets, metrics, config, null);
+ this(assets, metrics, config, (ApplicationInfo) null);
}
/**
@@ -166,6 +166,26 @@
}
/**
+ * Creates a new resources that uses the given compatibility info. Used to create
+ * a context for widgets using the container's compatibility info.
+ * {@see ApplicationContext#createPackageCotnext}.
+ * @hide
+ */
+ public Resources(AssetManager assets, DisplayMetrics metrics,
+ Configuration config, CompatibilityInfo info) {
+ mAssets = assets;
+ mMetrics.setToDefaults();
+ mCompatibilityInfo = info;
+ updateConfiguration(config, metrics);
+ assets.ensureStringBlocks();
+ if (mCompatibilityInfo.isScalingRequired()) {
+ mPreloadedDrawables = emptySparseArray();
+ } else {
+ mPreloadedDrawables = sPreloadedDrawables;
+ }
+ }
+
+ /**
* Return a global shared Resources object that provides access to only
* system resources (no application resources), and is not configured for
* the current screen (can not use dimension units, does not change based
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index fca318e..5f90071 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2693,6 +2693,12 @@
public static final String GMAIL_DISCARD_ERROR_UPHILL_OP = "gmail_discard_error_uphill_op";
/**
+ * Controls how many attempts Gmail will try to upload an uphill operations before it
+ * abandons the operation. Defaults to 20.
+ */
+ public static final String GMAIL_NUM_RETRY_UPHILL_OP = "gmail_discard_error_uphill_op";
+
+ /**
* the transcoder URL for mobile devices.
*/
public static final String TRANSCODER_URL = "mobile_transcoder_url";
diff --git a/core/java/android/util/EventLog.java b/core/java/android/util/EventLog.java
index 7c87248..0f0be79 100644
--- a/core/java/android/util/EventLog.java
+++ b/core/java/android/util/EventLog.java
@@ -73,7 +73,7 @@
* </ul>
* </li>
* <li> '\n': 1 byte - an automatically generated newline, used to help detect and recover from log
- * corruption and enable stansard unix tools like grep, tail and wc to operate
+ * corruption and enable standard unix tools like grep, tail and wc to operate
* on event logs. </li>
* </ul>
*
@@ -289,4 +289,13 @@
*/
public static native void readEvents(int[] tags, Collection<Event> output)
throws IOException;
+
+ /**
+ * Read events from a file.
+ * @param path to read from
+ * @param output container to add events into
+ * @throws IOException if something goes wrong reading events
+ */
+ public static native void readEvents(String path, Collection<Event> output)
+ throws IOException;
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index a12b14a..41cc86a 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -553,13 +553,16 @@
if (DEBUG_DRAW) Log.v(TAG, "Invalidate child: " + dirty);
if (mCurScrollY != 0 || mTranslator != null) {
mTempRect.set(dirty);
+ dirty = mTempRect;
if (mCurScrollY != 0) {
- mTempRect.offset(0, -mCurScrollY);
+ dirty.offset(0, -mCurScrollY);
}
if (mTranslator != null) {
- mTranslator.translateRectInAppWindowToScreen(mTempRect);
+ mTranslator.translateRectInAppWindowToScreen(dirty);
}
- dirty = mTempRect;
+ if (mAttachInfo.mScalingRequired) {
+ dirty.inset(-1, -1);
+ }
}
mDirty.union(dirty);
if (!mWillDrawSoon) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b2f2e51..899d636 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3024,7 +3024,12 @@
*/
/* package */ void deleteSelection(int start, int end) {
mTextGeneration++;
- mWebViewCore.sendMessage(EventHub.DELETE_SELECTION, start, end);
+ WebViewCore.DeleteSelectionData data
+ = new WebViewCore.DeleteSelectionData();
+ data.mStart = start;
+ data.mEnd = end;
+ data.mTextGeneration = mTextGeneration;
+ mWebViewCore.sendMessage(EventHub.DELETE_SELECTION, data);
}
/**
@@ -4672,6 +4677,7 @@
arg.mNewStart = newStart;
arg.mNewEnd = newEnd;
mTextGeneration++;
+ arg.mTextGeneration = mTextGeneration;
mWebViewCore.sendMessage(EventHub.REPLACE_TEXT, oldStart, oldEnd, arg);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 44d8b7e..20f7239 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -370,7 +370,8 @@
// Start: functions that deal with text editing
private native void nativeReplaceTextfieldText(
- int oldStart, int oldEnd, String replace, int newStart, int newEnd);
+ int oldStart, int oldEnd, String replace, int newStart, int newEnd,
+ int textGeneration);
private native void passToJs(int gen,
String currentText, int keyCode, int keyValue, boolean down,
@@ -415,8 +416,10 @@
* order, swap them.
* @param start Beginning of selection to delete.
* @param end End of selection to delete.
+ * @param textGeneration Text generation number when delete was pressed.
*/
- private native void nativeDeleteSelection(int start, int end);
+ private native void nativeDeleteSelection(int start, int end,
+ int textGeneration);
/**
* Set the selection to (start, end) in the focused textfield. If start and
@@ -551,10 +554,17 @@
byte[] mPostData;
}
+ static class DeleteSelectionData {
+ int mStart;
+ int mEnd;
+ int mTextGeneration;
+ }
+
static class ReplaceTextData {
String mReplace;
int mNewStart;
int mNewEnd;
+ int mTextGeneration;
}
static class TouchUpData {
@@ -920,7 +930,8 @@
case REPLACE_TEXT:
ReplaceTextData rep = (ReplaceTextData) msg.obj;
nativeReplaceTextfieldText(msg.arg1, msg.arg2,
- rep.mReplace, rep.mNewStart, rep.mNewEnd);
+ rep.mReplace, rep.mNewStart, rep.mNewEnd,
+ rep.mTextGeneration);
break;
case PASS_TO_JS: {
@@ -1029,7 +1040,11 @@
break;
case DELETE_SELECTION:
- nativeDeleteSelection(msg.arg1, msg.arg2);
+ DeleteSelectionData deleteSelectionData
+ = (DeleteSelectionData) msg.obj;
+ nativeDeleteSelection(deleteSelectionData.mStart,
+ deleteSelectionData.mEnd,
+ deleteSelectionData.mTextGeneration);
break;
case SET_SELECTION:
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 0cce3a6..cf3ba7f 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -539,16 +539,17 @@
// ----------------------------------------------------------------------------
-static void android_media_AudioTrack_set_playback_rate(JNIEnv *env, jobject thiz,
+static jint android_media_AudioTrack_set_playback_rate(JNIEnv *env, jobject thiz,
jint sampleRateInHz) {
AudioTrack *lpTrack = (AudioTrack *)env->GetIntField(
thiz, javaAudioTrackFields.nativeTrackInJavaObj);
if (lpTrack) {
- lpTrack->setSampleRate(sampleRateInHz);
+ return android_media_translateErrorCode(lpTrack->setSampleRate(sampleRateInHz));
} else {
jniThrowException(env, "java/lang/IllegalStateException",
"Unable to retrieve AudioTrack pointer for setSampleRate()");
+ return AUDIOTRACK_ERROR;
}
}
@@ -788,7 +789,7 @@
{"native_get_native_frame_count",
"()I", (void *)android_media_AudioTrack_get_native_frame_count},
{"native_set_playback_rate",
- "(I)V", (void *)android_media_AudioTrack_set_playback_rate},
+ "(I)I", (void *)android_media_AudioTrack_set_playback_rate},
{"native_get_playback_rate",
"()I", (void *)android_media_AudioTrack_get_playback_rate},
{"native_set_marker_pos","(I)I", (void *)android_media_AudioTrack_set_marker_pos},
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 5e5103a..34b7c89 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -51,17 +51,17 @@
size_t len;
size_t capacity;
uint8_t* buf;
-
+
ByteBuf(size_t initSize) {
buf = (uint8_t*)malloc(initSize);
len = 0;
- capacity = initSize;
+ capacity = initSize;
}
-
+
~ByteBuf() {
free(buf);
}
-
+
bool ensureExtraCapacity(size_t extra) {
size_t spaceNeeded = len + extra;
if (spaceNeeded > capacity) {
@@ -77,7 +77,7 @@
return true;
}
}
-
+
void putIntEvent(jint value) {
bool succeeded = ensureExtraCapacity(INT_BUFFER_SIZE);
buf[len++] = EVENT_TYPE_INT;
@@ -162,7 +162,7 @@
* In class android.util.EventLog:
* static native int writeEvent(long tag, long value)
*/
-static jint android_util_EventLog_writeEvent_Long(JNIEnv* env, jobject clazz,
+static jint android_util_EventLog_writeEvent_Long(JNIEnv* env, jobject clazz,
jint tag, jlong value)
{
return android_btWriteLog(tag, EVENT_TYPE_LONG, &value, sizeof(value));
@@ -210,6 +210,8 @@
/*
* In class android.util.EventLog:
* static native void readEvents(int[] tags, Collection<Event> output)
+ *
+ * Reads events from the event log, typically /dev/log/events
*/
static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz,
jintArray tags,
@@ -273,6 +275,80 @@
env->ReleaseIntArrayElements(tags, tagValues, 0);
}
+/*
+ * In class android.util.EventLog:
+ * static native void readEvents(String path, Collection<Event> output)
+ *
+ * Reads events from a file (See Checkin.Aggregation). Events are stored in
+ * native raw format (logger_entry + payload).
+ */
+static void android_util_EventLog_readEventsFile(JNIEnv* env, jobject clazz, jstring path,
+ jobject out) {
+ if (path == NULL || out == NULL) {
+ jniThrowException(env, "java/lang/NullPointerException", NULL);
+ return;
+ }
+
+ const char *pathString = env->GetStringUTFChars(path, 0);
+ int fd = open(pathString, O_RDONLY | O_NONBLOCK);
+ env->ReleaseStringUTFChars(path, pathString);
+
+ if (fd < 0) {
+ jniThrowIOException(env, errno);
+ return;
+ }
+
+ uint8_t buf[LOGGER_ENTRY_MAX_LEN];
+ for (;;) {
+ // read log entry structure from file
+ int len = read(fd, buf, sizeof(logger_entry));
+ if (len == 0) {
+ break; // end of file
+ } else if (len < 0) {
+ jniThrowIOException(env, errno);
+ } else if ((size_t) len < sizeof(logger_entry)) {
+ jniThrowException(env, "java/io/IOException", "Event header too short");
+ break;
+ }
+
+ // read event payload
+ logger_entry* entry = (logger_entry*) buf;
+ if (entry->len > LOGGER_ENTRY_MAX_PAYLOAD) {
+ jniThrowException(env,
+ "java/lang/IllegalArgumentException",
+ "Too much data for event payload. Corrupt file?");
+ break;
+ }
+
+ len = read(fd, buf + sizeof(logger_entry), entry->len);
+ if (len == 0) {
+ break; // end of file
+ } else if (len < 0) {
+ jniThrowIOException(env, errno);
+ } else if ((size_t) len < entry->len) {
+ jniThrowException(env, "java/io/IOException", "Event payload too short");
+ break;
+ }
+
+ // create EventLog$Event and add it to the collection
+ int buffer_size = sizeof(logger_entry) + entry->len;
+ jbyteArray array = env->NewByteArray(buffer_size);
+ if (array == NULL) break;
+
+ jbyte *bytes = env->GetByteArrayElements(array, NULL);
+ memcpy(bytes, buf, buffer_size);
+ env->ReleaseByteArrayElements(array, bytes, 0);
+
+ jobject event = env->NewObject(gEventClass, gEventInitID, array);
+ if (event == NULL) break;
+
+ env->CallBooleanMethod(out, gCollectionAddID, event);
+ env->DeleteLocalRef(event);
+ env->DeleteLocalRef(array);
+ }
+
+ close(fd);
+}
/*
* JNI registration.
@@ -292,6 +368,10 @@
{ "readEvents",
"([ILjava/util/Collection;)V",
(void*) android_util_EventLog_readEvents
+ },
+ { "readEvents",
+ "(Ljava/lang/String;Ljava/util/Collection;)V",
+ (void*) android_util_EventLog_readEventsFile
}
};
diff --git a/core/res/res/drawable/rate_star_big_half.png b/core/res/res/drawable/rate_star_big_half.png
index e73ca79..9762292 100644
--- a/core/res/res/drawable/rate_star_big_half.png
+++ b/core/res/res/drawable/rate_star_big_half.png
Binary files differ
diff --git a/core/res/res/drawable/rate_star_big_off.png b/core/res/res/drawable/rate_star_big_off.png
index b4dfa9d..6b5039f 100644
--- a/core/res/res/drawable/rate_star_big_off.png
+++ b/core/res/res/drawable/rate_star_big_off.png
Binary files differ
diff --git a/core/res/res/drawable/rate_star_big_on.png b/core/res/res/drawable/rate_star_big_on.png
index 7442c93..a972db2 100644
--- a/core/res/res/drawable/rate_star_big_on.png
+++ b/core/res/res/drawable/rate_star_big_on.png
Binary files differ
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index 106807e..83ff508 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -197,7 +197,6 @@
/* getters, see constructor */
- uint32_t sampleRate() const;
int format() const;
int channelCount() const;
uint32_t frameCount() const;
@@ -217,7 +216,7 @@
status_t stop();
bool stopped() const;
- /* get sample rate for this track
+ /* get sample rate for this record track
*/
uint32_t getSampleRate();
@@ -323,7 +322,6 @@
sp<ClientRecordThread> mClientRecordThread;
Mutex mRecordThreadLock;
- uint32_t mSampleRate;
uint32_t mFrameCount;
audio_track_cblk_t* mCblk;
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index 0955819..2e1fbda 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -201,7 +201,6 @@
/* getters, see constructor */
int streamType() const;
- uint32_t sampleRate() const;
int format() const;
int channelCount() const;
uint32_t frameCount() const;
@@ -246,7 +245,7 @@
/* set sample rate for this track, mostly used for games' sound effects
*/
- void setSampleRate(int sampleRate);
+ status_t setSampleRate(int sampleRate);
uint32_t getSampleRate();
/* Enables looping and sets the start and end points of looping.
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index bda969c..496a739 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -26,7 +26,6 @@
// ----------------------------------------------------------------------------
-#define MAX_SAMPLE_RATE 65535
#define THREAD_PRIORITY_AUDIO_CLIENT (ANDROID_PRIORITY_AUDIO)
// Maximum cumulated timeout milliseconds before restarting audioflinger thread
#define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time
@@ -55,9 +54,9 @@
uint16_t volume[2];
uint32_t volumeLR;
};
- uint16_t sampleRate;
- uint16_t channels;
- int16_t flowControlFlag; // underrun (out) or overrrun (in) indication
+ uint32_t sampleRate;
+ uint8_t channels;
+ uint8_t flowControlFlag; // underrun (out) or overrrun (in) indication
uint8_t out; // out equals 1 for AudioTrack and 0 for AudioRecord
uint8_t forceReady;
uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger
diff --git a/include/utils/List.h b/include/utils/List.h
index 4041a89..403cd7f 100644
--- a/include/utils/List.h
+++ b/include/utils/List.h
@@ -154,9 +154,9 @@
inline _NodePtr getNode() const { return mpNode; }
+ _NodePtr mpNode; /* should be private, but older gcc fails */
private:
friend class List;
- _NodePtr mpNode;
};
public:
diff --git a/libs/audioflinger/AudioBufferProvider.h b/libs/audioflinger/AudioBufferProvider.h
index 1a467c7..81c5c39 100644
--- a/libs/audioflinger/AudioBufferProvider.h
+++ b/libs/audioflinger/AudioBufferProvider.h
@@ -36,6 +36,8 @@
};
size_t frameCount;
};
+
+ virtual ~AudioBufferProvider() {}
virtual status_t getNextBuffer(Buffer* buffer) = 0;
virtual void releaseBuffer(Buffer* buffer) = 0;
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index a5b91f6..82289dd 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1288,7 +1288,7 @@
status_t lStatus;
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
- if (sampleRate > MAX_SAMPLE_RATE || sampleRate > mSampleRate*2) {
+ if (sampleRate > mSampleRate*2) {
LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
lStatus = BAD_VALUE;
goto Exit;
@@ -1603,8 +1603,8 @@
new(mCblk) audio_track_cblk_t();
// clear all buffers
mCblk->frameCount = frameCount;
- mCblk->sampleRate = (uint16_t)sampleRate;
- mCblk->channels = (uint16_t)channelCount;
+ mCblk->sampleRate = sampleRate;
+ mCblk->channels = (uint8_t)channelCount;
if (sharedBuffer == 0) {
mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
@@ -1627,8 +1627,8 @@
new(mCblk) audio_track_cblk_t();
// clear all buffers
mCblk->frameCount = frameCount;
- mCblk->sampleRate = (uint16_t)sampleRate;
- mCblk->channels = (uint16_t)channelCount;
+ mCblk->sampleRate = sampleRate;
+ mCblk->channels = (uint8_t)channelCount;
mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
// Force underrun condition to avoid false underrun callback until first data is
@@ -1689,7 +1689,7 @@
}
int AudioFlinger::MixerThread::TrackBase::channelCount() const {
- return mCblk->channels;
+ return (int)mCblk->channels;
}
void* AudioFlinger::MixerThread::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
@@ -2274,12 +2274,6 @@
goto Exit;
}
- if (sampleRate > MAX_SAMPLE_RATE) {
- LOGE("Sample rate out of range");
- lStatus = BAD_VALUE;
- goto Exit;
- }
-
if (mAudioRecordThread == 0) {
LOGE("Audio record thread not started");
lStatus = NO_INIT;
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 3cd841d..5f1be9d 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -425,8 +425,7 @@
}
/**
- * Returns the current playback rate in Hz. Note that this rate may differ from the one set
- * with {@link #setPlaybackRate(int)} as the value effectively used is implementation-dependent.
+ * Returns the current playback rate in Hz.
*/
public int getPlaybackRate() {
return native_get_playback_rate();
@@ -651,18 +650,13 @@
* Sets the playback sample rate for this track. This sets the sampling rate at which
* the audio data will be consumed and played back, not the original sampling rate of the
* content. Setting it to half the sample rate of the content will cause the playback to
- * last twice as long, but will also result result in a negative pitch shift.
- * The current implementation supports a maximum sample rate of 64kHz.
- * Use {@link #getSampleRate()} to check the rate actually used in hardware after
- * potential clamping.
+ * last twice as long, but will also result in a negative pitch shift.
+ * The valid sample rate range if from 1Hz to twice the value returned by
+ * {@link #getNativeOutputSampleRate(int)}.
* @param sampleRateInHz the sample rate expressed in Hz
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
* {@link #ERROR_INVALID_OPERATION}
*/
- // FIXME: the implementation should support twice the hardware output sample rate
- // (see {@link #getNativeOutputSampleRate(int)}), but currently
- // due to the representation of the sample rate in the native layer, the sample rate
- // is limited to 65535Hz
public int setPlaybackRate(int sampleRateInHz) {
if (mState != STATE_INITIALIZED) {
return ERROR_INVALID_OPERATION;
@@ -670,8 +664,7 @@
if (sampleRateInHz <= 0) {
return ERROR_BAD_VALUE;
}
- native_set_playback_rate(sampleRateInHz);
- return SUCCESS;
+ return native_set_playback_rate(sampleRateInHz);
}
@@ -1031,8 +1024,8 @@
private native final void native_setVolume(float leftVolume, float rightVolume);
- private native final void native_set_playback_rate(int sampleRateInHz);
- private native final int native_get_playback_rate();
+ private native final int native_set_playback_rate(int sampleRateInHz);
+ private native final int native_get_playback_rate();
private native final int native_set_marker_pos(int marker);
private native final int native_get_marker_pos();
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index cf0965e..0a6f4f7 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -185,7 +185,6 @@
mCblk = static_cast<audio_track_cblk_t*>(cblk->pointer());
mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
mCblk->out = 0;
- mSampleRate = sampleRate;
mFormat = format;
// Update buffer size in case it has been limited by AudioFlinger during track creation
mFrameCount = mCblk->frameCount;
@@ -196,7 +195,7 @@
mRemainingFrames = notificationFrames;
mUserData = user;
// TODO: add audio hardware input latency here
- mLatency = (1000*mFrameCount) / mSampleRate;
+ mLatency = (1000*mFrameCount) / sampleRate;
mMarkerPosition = 0;
mMarkerReached = false;
mNewPosition = 0;
@@ -218,11 +217,6 @@
return mLatency;
}
-uint32_t AudioRecord::sampleRate() const
-{
- return mSampleRate;
-}
-
int AudioRecord::format() const
{
return mFormat;
@@ -321,6 +315,11 @@
return !mActive;
}
+uint32_t AudioRecord::getSampleRate()
+{
+ return mCblk->sampleRate;
+}
+
status_t AudioRecord::setMarkerPosition(uint32_t marker)
{
if (mCbf == 0) return INVALID_OPERATION;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 4a1b69e..af7dae5 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -243,7 +243,6 @@
mCblk->volume[0] = mCblk->volume[1] = 0x1000;
mVolume[LEFT] = 1.0f;
mVolume[RIGHT] = 1.0f;
- mSampleRate = sampleRate;
mStreamType = streamType;
mFormat = format;
mChannelCount = channelCount;
@@ -254,7 +253,7 @@
mNotificationFrames = notificationFrames;
mRemainingFrames = notificationFrames;
mUserData = user;
- mLatency = afLatency + (1000*mFrameCount) / mSampleRate;
+ mLatency = afLatency + (1000*mFrameCount) / sampleRate;
mLoopCount = 0;
mMarkerPosition = 0;
mMarkerReached = false;
@@ -281,11 +280,6 @@
return mStreamType;
}
-uint32_t AudioTrack::sampleRate() const
-{
- return mSampleRate;
-}
-
int AudioTrack::format() const
{
return mFormat;
@@ -438,24 +432,23 @@
*right = mVolume[RIGHT];
}
-void AudioTrack::setSampleRate(int rate)
+status_t AudioTrack::setSampleRate(int rate)
{
int afSamplingRate;
if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
- return;
+ return NO_INIT;
}
// Resampler implementation limits input sampling rate to 2 x output sampling rate.
- if (rate <= 0) rate = 1;
- if (rate > afSamplingRate*2) rate = afSamplingRate*2;
- if (rate > MAX_SAMPLE_RATE) rate = MAX_SAMPLE_RATE;
+ if (rate <= 0 || rate > afSamplingRate*2 ) return BAD_VALUE;
- mCblk->sampleRate = (uint16_t)rate;
+ mCblk->sampleRate = rate;
+ return NO_ERROR;
}
uint32_t AudioTrack::getSampleRate()
{
- return uint32_t(mCblk->sampleRate);
+ return mCblk->sampleRate;
}
status_t AudioTrack::setLoop(uint32_t loopStart, uint32_t loopEnd, int loopCount)
@@ -866,7 +859,7 @@
result.append(buffer);
snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat, mChannelCount, mFrameCount);
result.append(buffer);
- snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n", mSampleRate, mStatus, mMuted);
+ snprintf(buffer, 255, " sample rate(%d), status(%d), muted(%d)\n", (mCblk == 0) ? 0 : mCblk->sampleRate, mStatus, mMuted);
result.append(buffer);
snprintf(buffer, 255, " active(%d), latency (%d)\n", mActive, mLatency);
result.append(buffer);
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 0bed72bd..10f4d6e 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -36,6 +36,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.Locale;
import java.util.concurrent.locks.ReentrantLock;
/**
@@ -183,7 +184,8 @@
String defaultLang = android.provider.Settings.Secure.getString(mResolver,
android.provider.Settings.Secure.TTS_DEFAULT_LANG);
if (defaultLang == null) {
- return TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_LANG;
+ // no setting found, use the current Locale to determine the default language
+ return Locale.getDefault().getISO3Language();
} else {
return defaultLang;
}
@@ -194,7 +196,8 @@
String defaultCountry = android.provider.Settings.Secure.getString(mResolver,
android.provider.Settings.Secure.TTS_DEFAULT_COUNTRY);
if (defaultCountry == null) {
- return TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_COUNTRY;
+ // no setting found, use the current Locale to determine the default country
+ return Locale.getDefault().getISO3Country();
} else {
return defaultCountry;
}
@@ -205,7 +208,8 @@
String defaultVar = android.provider.Settings.Secure.getString(mResolver,
android.provider.Settings.Secure.TTS_DEFAULT_VARIANT);
if (defaultVar == null) {
- return TextToSpeech.Engine.FALLBACK_TTS_DEFAULT_VARIANT;
+ // no setting found, use the current Locale to determine the default variant
+ return Locale.getDefault().getVariant();
} else {
return defaultVar;
}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 0f5b3fd..fab97b1 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -648,14 +648,14 @@
private void checkPermissionsSafe(String provider) {
if (LocationManager.GPS_PROVIDER.equals(provider)
- && (mContext.checkCallingPermission(ACCESS_FINE_LOCATION)
+ && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
}
if (LocationManager.NETWORK_PROVIDER.equals(provider)
- && (mContext.checkCallingPermission(ACCESS_FINE_LOCATION)
+ && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
- && (mContext.checkCallingPermission(ACCESS_COARSE_LOCATION)
+ && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
throw new SecurityException(
"Requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission");
@@ -664,14 +664,14 @@
private boolean isAllowedProviderSafe(String provider) {
if (LocationManager.GPS_PROVIDER.equals(provider)
- && (mContext.checkCallingPermission(ACCESS_FINE_LOCATION)
+ && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
return false;
}
if (LocationManager.NETWORK_PROVIDER.equals(provider)
- && (mContext.checkCallingPermission(ACCESS_FINE_LOCATION)
+ && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
- && (mContext.checkCallingPermission(ACCESS_COARSE_LOCATION)
+ && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)) {
return false;
}
@@ -1075,7 +1075,7 @@
if (mGpsStatusProvider == null) {
return false;
}
- if (mContext.checkCallingPermission(ACCESS_FINE_LOCATION) !=
+ if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) !=
PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires ACCESS_FINE_LOCATION permission");
}
@@ -1103,7 +1103,7 @@
// first check for permission to the provider
checkPermissionsSafe(provider);
// and check for ACCESS_LOCATION_EXTRA_COMMANDS
- if ((mContext.checkCallingPermission(ACCESS_LOCATION_EXTRA_COMMANDS)
+ if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS)
!= PackageManager.PERMISSION_GRANTED)) {
throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission");
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index ab6e49c1..9da29fa 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -38,6 +38,7 @@
import android.net.wifi.WifiStateTracker;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
+import android.net.wifi.SupplicantState;
import android.net.NetworkStateTracker;
import android.net.DhcpInfo;
import android.os.Binder;
@@ -1577,8 +1578,9 @@
* or plugged in to AC).
*/
if (!shouldWifiStayAwake(stayAwakeConditions, mPluggedType)) {
- if (!mWifiStateTracker.hasIpAddress()) {
- // do not keep Wifi awake when screen is off if Wifi is not fully active
+ WifiInfo info = mWifiStateTracker.requestConnectionInfo();
+ if (info.getSupplicantState() != SupplicantState.COMPLETED) {
+ // do not keep Wifi awake when screen is off if Wifi is not associated
mDeviceIdle = true;
updateWifiState();
} else {
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index eaeda64..ef3afff 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -455,7 +455,14 @@
}
}
- private static byte[] encode7bitGsm(String msg)
+ private static int calcUdhSeptetPadding(int userDataHeaderLen) {
+ int udhBits = userDataHeaderLen * 8;
+ int udhSeptets = (udhBits + 6) / 7;
+ int paddingBits = (udhSeptets * 7) - udhBits;
+ return paddingBits;
+ }
+
+ private static byte[] encode7bitGsm(String msg, int paddingBits)
throws CodingException
{
try {
@@ -464,11 +471,9 @@
* an option to produce just the data without prepending
* the length.
*/
- byte []fullData = GsmAlphabet.stringToGsm7BitPacked(msg);
+ byte []fullData = GsmAlphabet.stringToGsm7BitPacked(msg, 0, -1, paddingBits, true);
byte []data = new byte[fullData.length - 1];
- for (int i = 0; i < data.length; i++) {
- data[i] = fullData[i + 1];
- }
+ System.arraycopy(fullData, 1, data, 0, fullData.length - 1);
return data;
} catch (com.android.internal.telephony.EncodeException ex) {
throw new CodingException("7bit GSM encode failed: " + ex);
@@ -478,9 +483,11 @@
private static void encodeUserDataPayload(UserData uData)
throws CodingException
{
+ // TODO(cleanup): UDH can only occur in EMS mode, meaning
+ // encapsulation of GSM encoding, and so the logic here should
+ // be refactored to more cleanly reflect this constraint.
+
byte[] headerData = null;
- // TODO: if there is a header, meaning EMS mode, we probably
- // also want the total UD length prior to the UDH length...
if (uData.userDataHeader != null) headerData = SmsHeader.toByteArray(uData.userDataHeader);
int headerDataLen = (headerData == null) ? 0 : headerData.length + 1; // + length octet
@@ -502,8 +509,9 @@
uData.payloadStr = "";
}
if (uData.msgEncoding == UserData.ENCODING_GSM_7BIT_ALPHABET) {
- payloadData = encode7bitGsm(uData.payloadStr);
- codeUnitCount = (payloadData.length * 8) / 7;
+ int paddingBits = calcUdhSeptetPadding(headerDataLen);
+ payloadData = encode7bitGsm(uData.payloadStr, paddingBits);
+ codeUnitCount = ((payloadData.length + headerDataLen) * 8) / 7;
} else if (uData.msgEncoding == UserData.ENCODING_7BIT_ASCII) {
payloadData = encode7bitAscii(uData.payloadStr, true);
codeUnitCount = uData.payloadStr.length();
@@ -528,8 +536,9 @@
} else {
// If there is a header, we are in EMS mode, in
// which case we use GSM encodings.
- payloadData = encode7bitGsm(uData.payloadStr);
- codeUnitCount = (payloadData.length * 8) / 7;
+ int paddingBits = calcUdhSeptetPadding(headerDataLen);
+ payloadData = encode7bitGsm(uData.payloadStr, paddingBits);
+ codeUnitCount = ((payloadData.length + headerDataLen) * 8) / 7;
uData.msgEncoding = UserData.ENCODING_GSM_7BIT_ALPHABET;
}
} catch (CodingException ex) {
@@ -880,7 +889,12 @@
private static String decode7bitGsm(byte[] data, int offset, int numFields)
throws CodingException
{
- String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields);
+ int paddingBits = calcUdhSeptetPadding(offset);
+ numFields -= (((offset * 8) + paddingBits) / 7);
+ // TODO: It seems wrong that only Gsm7 bit encodings would
+ // take into account the header in numFields calculations.
+ // This should be verified.
+ String result = GsmAlphabet.gsm7BitPackedToString(data, offset, numFields, paddingBits);
if (result == null) {
throw new CodingException("7bit GSM decoding failed");
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
index 2ff0a6a..f0ba573 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
@@ -108,6 +108,21 @@
userData.payloadStr = "More @ testing\nis great^|^~woohoo";
revBearerData = BearerData.decode(BearerData.encode(bearerData));
assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
+ SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
+ concatRef.refNumber = 0xEE;
+ concatRef.msgCount = 2;
+ concatRef.seqNumber = 2;
+ concatRef.isEightBits = true;
+ SmsHeader smsHeader = new SmsHeader();
+ smsHeader.concatRef = concatRef;
+ byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
+ userData.userDataHeader = smsHeader;
+ revBearerData = BearerData.decode(BearerData.encode(bearerData));
+ assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
+ SmsHeader decodedHeader = revBearerData.userData.userDataHeader;
+ assertEquals(decodedHeader.concatRef.refNumber, concatRef.refNumber);
+ assertEquals(decodedHeader.concatRef.msgCount, concatRef.msgCount);
+ assertEquals(decodedHeader.concatRef.seqNumber, concatRef.seqNumber);
}
@SmallTest
diff --git a/tests/backup/src/com/android/backuptest/BackupTestActivity.java b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
index 7f30c91..afbc703 100644
--- a/tests/backup/src/com/android/backuptest/BackupTestActivity.java
+++ b/tests/backup/src/com/android/backuptest/BackupTestActivity.java
@@ -52,6 +52,8 @@
static final String PREF_KEY = "pref";
static final String FILE_NAME = "file.txt";
+ BackupManager sBm = new BackupManager(this);
+
Test[] mTests = new Test[] {
new Test("Show File") {
void run() {
@@ -85,8 +87,7 @@
output.close();
}
}
- BackupManager bm = new BackupManager(BackupTestActivity.this);
- bm.dataChanged();
+ sBm.dataChanged();
}
},
new Test("Clear File") {
@@ -100,14 +101,12 @@
output.close();
}
}
- BackupManager bm = new BackupManager(BackupTestActivity.this);
- bm.dataChanged();
+ sBm.dataChanged();
}
},
new Test("Poke") {
void run() {
- BackupManager bm = new BackupManager(BackupTestActivity.this);
- bm.dataChanged();
+ sBm.dataChanged();
}
},
new Test("Show Shared Pref") {
@@ -126,8 +125,7 @@
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(PREF_KEY, val+1);
editor.commit();
- BackupManager bm = new BackupManager(BackupTestActivity.this);
- bm.dataChanged();
+ sBm.dataChanged();
}
},
new Test("Backup Helpers") {