Merge "add more logging into DRT"
diff --git a/core/java/android/widget/MultiAutoCompleteTextView.java b/core/java/android/widget/MultiAutoCompleteTextView.java
index 02c1ec7..134e4c4 100644
--- a/core/java/android/widget/MultiAutoCompleteTextView.java
+++ b/core/java/android/widget/MultiAutoCompleteTextView.java
@@ -30,7 +30,7 @@
* can show completion suggestions for the substring of the text where
* the user is typing instead of necessarily for the entire thing.
* <p>
- * You must must provide a {@link Tokenizer} to distinguish the
+ * You must provide a {@link Tokenizer} to distinguish the
* various substrings.
*
* <p>The following code snippet shows how to create a text view which suggests
@@ -41,7 +41,7 @@
* protected void onCreate(Bundle savedInstanceState) {
* super.onCreate(savedInstanceState);
* setContentView(R.layout.autocomplete_7);
- *
+ *
* ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
* android.R.layout.simple_dropdown_item_1line, COUNTRIES);
* MultiAutoCompleteTextView textView = (MultiAutoCompleteTextView) findViewById(R.id.edit);
@@ -132,7 +132,7 @@
* Instead of validating the entire text, this subclass method validates
* each token of the text individually. Empty tokens are removed.
*/
- @Override
+ @Override
public void performValidation() {
Validator v = getValidator();
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 445f4b5..2eaedaa 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -320,8 +320,7 @@
}
jint id = (jint)rsElementCreate2(con,
(RsElement *)ids, fieldCount,
- nameArray, fieldCount,
- sizeArray, fieldCount,
+ nameArray, fieldCount * sizeof(size_t), sizeArray,
(const uint32_t *)arraySizes, fieldCount);
for (int ct=0; ct < fieldCount; ct++) {
jstring s = (jstring)_env->GetObjectArrayElement(_names, ct);
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index c336c0d..ef00b30 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -91,6 +91,7 @@
rsDevice.cpp \
rsElement.cpp \
rsFBOCache.cpp \
+ rsFifoSocket.cpp \
rsFileA3D.cpp \
rsFont.cpp \
rsLocklessFifo.cpp \
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 5370e25..00e3a0a 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -176,7 +176,6 @@
ElementCreate2 {
param const RsElement * elements
param const char ** names
- param const size_t * nameLengths
param const uint32_t * arraySize
ret RsElement
}
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index d5d5ca5..2b58e9e 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -347,13 +347,15 @@
return (RsElement)e;
}
+
RsElement rsi_ElementCreate2(Context *rsc,
const RsElement * ein,
size_t ein_length,
+
const char ** names,
- size_t names_length,
- const size_t * nameLengths,
size_t nameLengths_length,
+ const size_t * nameLengths,
+
const uint32_t * arraySizes,
size_t arraySizes_length) {
const Element *e = Element::create(rsc, ein_length, (const Element **)ein, names, nameLengths, arraySizes);
diff --git a/libs/rs/rsFifo.cpp b/libs/rs/rsFifo.cpp
new file mode 100644
index 0000000..3d5d8c4
--- /dev/null
+++ b/libs/rs/rsFifo.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsFifoSocket.h"
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+Fifo::Fifo() {
+
+}
+
+Fifo::~Fifo() {
+
+}
+
diff --git a/libs/rs/rsFifo.h b/libs/rs/rsFifo.h
new file mode 100644
index 0000000..f924b95
--- /dev/null
+++ b/libs/rs/rsFifo.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_FIFO_H
+#define ANDROID_RS_FIFO_H
+
+
+#include "rsUtils.h"
+
+namespace android {
+namespace renderscript {
+
+
+// A simple FIFO to be used as a producer / consumer between two
+// threads. One is writer and one is reader. The common cases
+// will not require locking. It is not threadsafe for multiple
+// readers or writers by design.
+
+class Fifo {
+protected:
+ Fifo();
+ virtual ~Fifo();
+
+public:
+ void virtual writeAsync(const void *data, size_t bytes) = 0;
+ void virtual writeWaitReturn(void *ret, size_t retSize) = 0;
+ size_t virtual read(void *data, size_t bytes) = 0;
+ void virtual readReturn(const void *data, size_t bytes) = 0;
+
+ void virtual flush() = 0;
+
+};
+
+}
+}
+#endif
diff --git a/libs/rs/rsFifoSocket.cpp b/libs/rs/rsFifoSocket.cpp
new file mode 100644
index 0000000..1ce57b9
--- /dev/null
+++ b/libs/rs/rsFifoSocket.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "rsFifoSocket.h"
+#include "utils/Timers.h"
+#include "utils/StopWatch.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+FifoSocket::FifoSocket() {
+ sequence = 1;
+}
+
+FifoSocket::~FifoSocket() {
+
+}
+
+bool FifoSocket::init() {
+ int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ return false;
+}
+
+void FifoSocket::shutdown() {
+}
+
+void FifoSocket::writeAsync(const void *data, size_t bytes) {
+ size_t ret = ::write(sv[0], data, bytes);
+ rsAssert(ret == bytes);
+}
+
+void FifoSocket::writeWaitReturn(void *retData, size_t retBytes) {
+ size_t ret = ::read(sv[1], retData, retBytes);
+ rsAssert(ret == retBytes);
+}
+
+size_t FifoSocket::read(void *data, size_t bytes) {
+ size_t ret = ::read(sv[0], data, bytes);
+ rsAssert(ret == bytes);
+ return ret;
+}
+
+void FifoSocket::readReturn(const void *data, size_t bytes) {
+ size_t ret = ::write(sv[1], data, bytes);
+ rsAssert(ret == bytes);
+}
+
+
+void FifoSocket::flush() {
+}
+
+
diff --git a/libs/rs/rsFifoSocket.h b/libs/rs/rsFifoSocket.h
new file mode 100644
index 0000000..7df2b67
--- /dev/null
+++ b/libs/rs/rsFifoSocket.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_RS_FIFO_SOCKET_H
+#define ANDROID_RS_FIFO_SOCKET_H
+
+
+#include "rsFifo.h"
+
+namespace android {
+namespace renderscript {
+
+
+class FifoSocket {
+public:
+ FifoSocket();
+ virtual ~FifoSocket();
+
+ bool init();
+ void shutdown();
+
+
+
+ void virtual writeAsync(const void *data, size_t bytes);
+ void virtual writeWaitReturn(void *ret, size_t retSize);
+ size_t virtual read(void *data, size_t bytes);
+ void virtual readReturn(const void *data, size_t bytes);
+
+ void virtual flush();
+
+protected:
+ int sv[2];
+ uint32_t sequence;
+
+
+};
+
+}
+}
+
+#endif
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 1d8b9b5..d550712 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -189,6 +189,7 @@
fprintf(f, "#include \"rsThreadIO.h\"\n");
//fprintf(f, "#include \"rsgApiStructs.h\"\n");
fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
+ fprintf(f, "#include \"rsFifo.h\"\n");
fprintf(f, "\n");
fprintf(f, "using namespace android;\n");
fprintf(f, "using namespace android::renderscript;\n");
@@ -290,11 +291,103 @@
if (api->ret.typeName[0]) {
fprintf(f, " return reinterpret_cast<");
- printVarTypeAndName(f, &api->ret);
+ printVarType(f, &api->ret);
fprintf(f, ">(io->mToCoreRet);\n");
}
}
fprintf(f, "};\n\n");
+
+
+ fprintf(f, "static ");
+ printFuncDecl(f, api, "RF_", 0, 0);
+ fprintf(f, "\n{\n");
+ fprintf(f, " Fifo *f = NULL;\n");
+ fprintf(f, " RS_CMD_%s cmd;\n", api->name);
+ fprintf(f, " const uint32_t cmdSize = sizeof(cmd);\n");
+ fprintf(f, " const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name);
+ fprintf(f, " f->writeAsync(&cmdID, sizeof(cmdID));\n");
+
+ if (api->handcodeApi) {
+ fprintf(f, " rsHCAPI_%s(rsc", api->name);
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if (ct2 > 0 || !api->nocontext) {
+ fprintf(f, ", ");
+ }
+ fprintf(f, "%s", vt->name);
+ }
+ fprintf(f, ");\n");
+ } else {
+ fprintf(f, " intptr_t offset = cmdSize;\n");
+ fprintf(f, " uint32_t dataSize = 0;\n");
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if (vt->isConst && vt->ptrLevel) {
+ switch(vt->ptrLevel) {
+ case 1:
+ fprintf(f, " dataSize += %s_length;\n", vt->name);
+ break;
+ case 2:
+ fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+ fprintf(f, " dataSize += %s_length[ct];\n", vt->name);
+ fprintf(f, " }\n");
+ break;
+ default:
+ printf("pointer level not handled!!");
+ }
+ }
+ }
+ fprintf(f, "\n");
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ switch(vt->ptrLevel) {
+ case 0:
+ fprintf(f, " cmd.%s = %s;\n", vt->name, vt->name);
+ break;
+ case 1:
+ fprintf(f, " cmd.%s = (", vt->name);
+ printVarType(f, vt);
+ fprintf(f, ")offset;\n");
+ fprintf(f, " offset += %s_length;\n", vt->name);
+ break;
+ case 2:
+ fprintf(f, " cmd.%s = (", vt->name);
+ printVarType(f, vt);
+ fprintf(f, ")offset;\n");
+ fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+ fprintf(f, " offset += %s_length[ct];\n", vt->name);
+ fprintf(f, " }\n");
+ break;
+ default:
+ printf("pointer level not handled!!");
+ }
+ }
+ fprintf(f, "\n");
+
+ fprintf(f, " f->writeAsync(&cmd, cmdSize);\n");
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if (vt->ptrLevel == 1) {
+ fprintf(f, " f->writeAsync(%s, %s_length);\n", vt->name, vt->name);
+ }
+ if (vt->ptrLevel == 2) {
+ fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+ fprintf(f, " f->writeAsync(%s, %s_length[ct]);\n", vt->name, vt->name);
+ fprintf(f, " offset += %s_length[ct];\n", vt->name);
+ fprintf(f, " }\n");
+ }
+ }
+
+ if (api->ret.typeName[0]) {
+ fprintf(f, " ");
+ printVarType(f, &api->ret);
+ fprintf(f, " retValue;\n");
+ fprintf(f, " f->writeWaitReturn(&retValue, sizeof(retValue));\n");
+ fprintf(f, " return retValue;\n");
+ }
+ }
+ fprintf(f, "}\n\n");
}
fprintf(f, "\n");
@@ -304,8 +397,14 @@
}
fprintf(f, "};\n");
- fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
+ fprintf(f, "\n");
+ fprintf(f, "static RsApiEntrypoints_t s_RemoteTable = {\n");
+ for (ct=0; ct < apiCount; ct++) {
+ fprintf(f, " RF_%s,\n", apis[ct].name);
+ }
+ fprintf(f, "};\n");
+ fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
for (ct=0; ct < apiCount; ct++) {
int needFlush = 0;
const ApiEntry * api = &apis[ct];
@@ -357,8 +456,7 @@
continue;
}
- fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes)\n", api->name);
- fprintf(f, "{\n");
+ fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name);
//fprintf(f, " LOGE(\"play command %s\\n\");\n", api->name);
fprintf(f, " const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
@@ -377,7 +475,63 @@
fprintf(f, "};\n\n");
}
- fprintf(f, "RsPlaybackFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
+ for (ct=0; ct < apiCount; ct++) {
+ const ApiEntry * api = &apis[ct];
+
+ fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name);
+
+ //fprintf(f, " LOGE(\"play command %s\\n\");\n", api->name);
+ fprintf(f, " RS_CMD_%s cmd;\n", api->name);
+ fprintf(f, " f->read(&cmd, sizeof(cmd));\n");
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if (vt->ptrLevel == 1) {
+ fprintf(f, " cmd.%s = (", vt->name);
+ printVarType(f, vt);
+ fprintf(f, ")scratch;\n");
+ fprintf(f, " f->read(scratch, cmd.%s_length);\n", vt->name);
+ fprintf(f, " scratch += cmd.%s_length;\n", vt->name);
+ }
+ if (vt->ptrLevel == 2) {
+ fprintf(f, " size_t sum_%s = 0;\n", vt->name);
+ fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
+ fprintf(f, " ((size_t *)scratch)[ct] = cmd.%s_length[ct];\n", vt->name);
+ fprintf(f, " sum_%s += cmd.%s_length[ct];\n", vt->name, vt->name);
+ fprintf(f, " }\n");
+ fprintf(f, " f->read(scratch, sum_%s);\n", vt->name);
+ fprintf(f, " scratch += sum_%s;\n", vt->name);
+ }
+ }
+ fprintf(f, "\n");
+
+ if (api->ret.typeName[0]) {
+ fprintf(f, " ");
+ printVarType(f, &api->ret);
+ fprintf(f, " ret =\n");
+ }
+
+ fprintf(f, " rsi_%s(", api->name);
+ if (!api->nocontext) {
+ fprintf(f, "con");
+ }
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if (ct2 > 0 || !api->nocontext) {
+ fprintf(f, ",\n");
+ }
+ fprintf(f, " cmd.%s", vt->name);
+ }
+ fprintf(f, ");\n");
+
+ if (api->ret.typeName[0]) {
+ fprintf(f, " f->readReturn(&ret, sizeof(ret));\n");
+ }
+
+ fprintf(f, "};\n\n");
+ }
+
+ fprintf(f, "RsPlaybackLocalFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
fprintf(f, " NULL,\n");
for (ct=0; ct < apiCount; ct++) {
if (apis[ct].direct) {
@@ -388,6 +542,13 @@
}
fprintf(f, "};\n");
+ fprintf(f, "RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i] = {\n", apiCount + 1);
+ fprintf(f, " NULL,\n");
+ for (ct=0; ct < apiCount; ct++) {
+ fprintf(f, " %s%s,\n", "rspr_", apis[ct].name);
+ }
+ fprintf(f, "};\n");
+
fprintf(f, "};\n");
fprintf(f, "};\n");
}
@@ -422,14 +583,21 @@
{
fprintf(f, "\n");
fprintf(f, "#include \"rsContext.h\"\n");
+ fprintf(f, "#include \"rsFifo.h\"\n");
fprintf(f, "\n");
fprintf(f, "namespace android {\n");
fprintf(f, "namespace renderscript {\n");
printStructures(f);
printFuncDecls(f, "rsi_", 1);
printPlaybackFuncs(f, "rsp_");
- fprintf(f, "\n\ntypedef void (*RsPlaybackFunc)(Context *, const void *, size_t sizeBytes);\n");
- fprintf(f, "extern RsPlaybackFunc gPlaybackFuncs[%i];\n", apiCount + 1);
+ fprintf(f, "\n\ntypedef struct RsPlaybackRemoteHeaderRec {\n");
+ fprintf(f, " uint32_t command;\n");
+ fprintf(f, " uint32_t size;\n");
+ fprintf(f, "} RsPlaybackRemoteHeader;\n\n");
+ fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n");
+ fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, Fifo *, uint8_t *scratch, size_t scratchSize);\n");
+ fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1);
+ fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1);
fprintf(f, "}\n");
fprintf(f, "}\n");
diff --git a/libs/rs/spec.l b/libs/rs/spec.l
index dcd4435..a24bfd3 100644
--- a/libs/rs/spec.l
+++ b/libs/rs/spec.l
@@ -21,15 +21,26 @@
int typeNextState;
void checkPointerType() {
- VarType *lastType = currType;
- if (lastType->ptrLevel) {
+ VarType *baseType = currType;
+ int curPtrLevel = 0;
+ while (curPtrLevel < baseType->ptrLevel) {
currType = &apis[apiCount].params[apis[apiCount].paramCount];
currType->type = 4;
+ currType->ptrLevel = curPtrLevel;
+ if (currType->ptrLevel > 0) {
+ currType->isConst = 1;
+ }
sprintf(currType->typeName, "%s", "size_t");
- if (lastType->name[0]) {
- sprintf(currType->name, "%s_length", lastType->name);
+ switch(baseType->ptrLevel - curPtrLevel) {
+ case 1:
+ sprintf(currType->name, "%s_length", baseType->name);
+ break;
+ case 2:
+ sprintf(currType->name, "%s_length_length", baseType->name);
+ break;
}
apis[apiCount].paramCount++;
+ curPtrLevel ++;
}
}
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 69f9c23..dd69e6b 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -84,7 +84,13 @@
CHECK(mFirstBuffer == NULL);
- mFirstBufferResult = mSource->read(&mFirstBuffer);
+ MediaSource::ReadOptions options;
+ if (mSeeking) {
+ options.setSeekTo(mSeekTimeUs);
+ mSeeking = false;
+ }
+
+ mFirstBufferResult = mSource->read(&mFirstBuffer, &options);
if (mFirstBufferResult == INFO_FORMAT_CHANGED) {
LOGV("INFO_FORMAT_CHANGED!!!");
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index cccd0b7..dcc268f 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -831,6 +831,8 @@
if (!(mFlags & AUDIOPLAYER_STARTED)) {
mFlags |= AUDIOPLAYER_STARTED;
+ bool wasSeeking = mAudioPlayer->isSeeking();
+
// We've already started the MediaSource in order to enable
// the prefetcher to read its data.
status_t err = mAudioPlayer->start(
@@ -840,6 +842,13 @@
notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
return err;
}
+
+ if (wasSeeking) {
+ CHECK(!mAudioPlayer->isSeeking());
+
+ // We will have finished the seek while starting the audio player.
+ postAudioSeekComplete_l();
+ }
} else {
mAudioPlayer->resume();
}
@@ -1957,6 +1966,10 @@
void AwesomePlayer::postAudioSeekComplete() {
Mutex::Autolock autoLock(mLock);
+ postAudioSeekComplete_l();
+}
+
+void AwesomePlayer::postAudioSeekComplete_l() {
postCheckAudioStatusEvent_l(0 /* delayUs */);
}
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index fd3ddf7..835d2bb 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -281,6 +281,7 @@
void ensureCacheIsFetching_l();
status_t startAudioPlayer_l();
+ void postAudioSeekComplete_l();
void shutdownVideoDecoder_l();
void setNativeWindow_l(const sp<ANativeWindow> &native);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 6e1093f..de439ca 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -2855,8 +2855,8 @@
}
private File getDataPathForPackage(String packageName, int userId) {
- return new File(mUserAppDataDir.getAbsolutePath() + File.separator
- + userId + File.separator + packageName);
+ return new File(mUserAppDataDir.getAbsolutePath() + File.separator + userId
+ + File.separator + packageName);
}
private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
@@ -3319,36 +3319,42 @@
* only for non-system apps and system app upgrades.
*/
if (pkg.applicationInfo.nativeLibraryDir != null) {
- final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
- final String dataPathString = dataPath.getPath();
+ try {
+ final File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir);
+ final String dataPathString = dataPath.getCanonicalFile().getPath();
- if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
- /*
- * Upgrading from a previous version of the OS sometimes
- * leaves native libraries in the /data/data/<app>/lib
- * directory for system apps even when they shouldn't be.
- * Recent changes in the JNI library search path
- * necessitates we remove those to match previous behavior.
- */
- if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
- Log.i(TAG, "removed obsolete native libraries for system package " + path);
+ if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
+ /*
+ * Upgrading from a previous version of the OS sometimes
+ * leaves native libraries in the /data/data/<app>/lib
+ * directory for system apps even when they shouldn't be.
+ * Recent changes in the JNI library search path
+ * necessitates we remove those to match previous behavior.
+ */
+ if (NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryDir)) {
+ Log.i(TAG, "removed obsolete native libraries for system package "
+ + path);
+ }
+ } else if (nativeLibraryDir.getCanonicalFile().getParent()
+ .equals(dataPathString)) {
+ /*
+ * If this is an internal application or our
+ * nativeLibraryPath points to our data directory, unpack
+ * the libraries. The native library path pointing to the
+ * data directory for an application in an ASEC container
+ * can happen for older apps that existed before an OTA to
+ * Gingerbread.
+ */
+ Slog.i(TAG, "Unpacking native libraries for " + path);
+ mInstaller.unlinkNativeLibraryDirectory(dataPathString);
+ NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir);
+ } else {
+ Slog.i(TAG, "Linking native library dir for " + path);
+ mInstaller.linkNativeLibraryDirectory(dataPathString,
+ pkg.applicationInfo.nativeLibraryDir);
}
- } else if (nativeLibraryDir.getParent().equals(dataPathString)) {
- /*
- * If this is an internal application or our
- * nativeLibraryPath points to our data directory, unpack
- * the libraries. The native library path pointing to the
- * data directory for an application in an ASEC container
- * can happen for older apps that existed before an OTA to
- * Gingerbread.
- */
- Slog.i(TAG, "Unpacking native libraries for " + path);
- mInstaller.unlinkNativeLibraryDirectory(dataPathString);
- NativeLibraryHelper.copyNativeBinariesLI(scanFile, nativeLibraryDir);
- } else {
- Slog.i(TAG, "Linking native library dir for " + path);
- mInstaller.linkNativeLibraryDirectory(dataPathString,
- pkg.applicationInfo.nativeLibraryDir);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Unable to get canonical file " + ioe.toString());
}
}
pkg.mScanPath = path;