diff options
34 files changed, 331 insertions, 142 deletions
diff --git a/api/current.txt b/api/current.txt index 971db1dc8991..f946dda21ce8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -24619,6 +24619,7 @@ package android.view.inputmethod { field public static final int IME_ACTION_SEARCH = 3; // 0x3 field public static final int IME_ACTION_SEND = 4; // 0x4 field public static final int IME_ACTION_UNSPECIFIED = 0; // 0x0 + field public static final int IME_FLAG_FORCE_ASCII = -2147483648; // 0x80000000 field public static final int IME_FLAG_NAVIGATE_NEXT = 134217728; // 0x8000000 field public static final int IME_FLAG_NAVIGATE_PREVIOUS = 67108864; // 0x4000000 field public static final int IME_FLAG_NO_ACCESSORY_ACTION = 536870912; // 0x20000000 diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 3c4e54533699..ba24036f0973 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -1034,6 +1034,7 @@ public class SyncManager implements OnAccountsUpdateListener { protected void dumpSyncState(PrintWriter pw) { pw.print("data connected: "); pw.println(mDataConnectionIsConnected); + pw.print("auto sync: "); pw.println(mSyncStorageEngine.getMasterSyncAutomatically()); pw.print("memory low: "); pw.println(mStorageIsLow); final Account[] accounts = mAccounts; @@ -1272,57 +1273,17 @@ public class SyncManager implements OnAccountsUpdateListener { } - pw.println(); - pw.printf("Detailed Statistics (Recent history): %d (# of times) %ds (sync time)\n", - totalTimes, totalElapsedTime / 1000); - - final List<AuthoritySyncStats> sortedAuthorities = - new ArrayList<AuthoritySyncStats>(authorityMap.values()); - Collections.sort(sortedAuthorities, new Comparator<AuthoritySyncStats>() { - @Override - public int compare(AuthoritySyncStats lhs, AuthoritySyncStats rhs) { - // reverse order - int compare = Integer.compare(rhs.times, lhs.times); - if (compare == 0) { - compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime); - } - return compare; - } - }); - - final int maxLength = Math.max(maxAuthority, maxAccount + 3); - final int padLength = 2 + 2 + maxLength + 2 + 10 + 11; - final char chars[] = new char[padLength]; - Arrays.fill(chars, '-'); - final String separator = new String(chars); - - final String authorityFormat = String.format(" %%-%ds: %%-9s %%-11s\n", maxLength + 2); - final String accountFormat = String.format(" %%-%ds: %%-9s %%-11s\n", maxLength); - - pw.println(separator); - for (AuthoritySyncStats authoritySyncStats : sortedAuthorities) { - String name = authoritySyncStats.name; - long elapsedTime; - int times; - String timeStr; - String timesStr; - - elapsedTime = authoritySyncStats.elapsedTime; - times = authoritySyncStats.times; - timeStr = String.format("%ds/%d%%", - elapsedTime / 1000, - elapsedTime * 100 / totalElapsedTime); - timesStr = String.format("%d/%d%%", - times, - times * 100 / totalTimes); - pw.printf(authorityFormat, name, timesStr, timeStr); - - final List<AccountSyncStats> sortedAccounts = - new ArrayList<AccountSyncStats>( - authoritySyncStats.accountMap.values()); - Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() { + if (totalElapsedTime > 0) { + pw.println(); + pw.printf("Detailed Statistics (Recent history): " + + "%d (# of times) %ds (sync time)\n", + totalTimes, totalElapsedTime / 1000); + + final List<AuthoritySyncStats> sortedAuthorities = + new ArrayList<AuthoritySyncStats>(authorityMap.values()); + Collections.sort(sortedAuthorities, new Comparator<AuthoritySyncStats>() { @Override - public int compare(AccountSyncStats lhs, AccountSyncStats rhs) { + public int compare(AuthoritySyncStats lhs, AuthoritySyncStats rhs) { // reverse order int compare = Integer.compare(rhs.times, lhs.times); if (compare == 0) { @@ -1331,18 +1292,63 @@ public class SyncManager implements OnAccountsUpdateListener { return compare; } }); - for (AccountSyncStats stats: sortedAccounts) { - elapsedTime = stats.elapsedTime; - times = stats.times; + + final int maxLength = Math.max(maxAuthority, maxAccount + 3); + final int padLength = 2 + 2 + maxLength + 2 + 10 + 11; + final char chars[] = new char[padLength]; + Arrays.fill(chars, '-'); + final String separator = new String(chars); + + final String authorityFormat = + String.format(" %%-%ds: %%-9s %%-11s\n", maxLength + 2); + final String accountFormat = + String.format(" %%-%ds: %%-9s %%-11s\n", maxLength); + + pw.println(separator); + for (AuthoritySyncStats authoritySyncStats : sortedAuthorities) { + String name = authoritySyncStats.name; + long elapsedTime; + int times; + String timeStr; + String timesStr; + + elapsedTime = authoritySyncStats.elapsedTime; + times = authoritySyncStats.times; timeStr = String.format("%ds/%d%%", elapsedTime / 1000, elapsedTime * 100 / totalElapsedTime); timesStr = String.format("%d/%d%%", times, times * 100 / totalTimes); - pw.printf(accountFormat, stats.name, timesStr, timeStr); + pw.printf(authorityFormat, name, timesStr, timeStr); + + final List<AccountSyncStats> sortedAccounts = + new ArrayList<AccountSyncStats>( + authoritySyncStats.accountMap.values()); + Collections.sort(sortedAccounts, new Comparator<AccountSyncStats>() { + @Override + public int compare(AccountSyncStats lhs, AccountSyncStats rhs) { + // reverse order + int compare = Integer.compare(rhs.times, lhs.times); + if (compare == 0) { + compare = Long.compare(rhs.elapsedTime, lhs.elapsedTime); + } + return compare; + } + }); + for (AccountSyncStats stats: sortedAccounts) { + elapsedTime = stats.elapsedTime; + times = stats.times; + timeStr = String.format("%ds/%d%%", + elapsedTime / 1000, + elapsedTime * 100 / totalElapsedTime); + timesStr = String.format("%d/%d%%", + times, + times * 100 / totalTimes); + pw.printf(accountFormat, stats.name, timesStr, timeStr); + } + pw.println(separator); } - pw.println(separator); } pw.println(); diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index ac378fc46bdd..514656752618 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -168,6 +168,22 @@ public class EditorInfo implements InputType, Parcelable { public static final int IME_FLAG_NO_ENTER_ACTION = 0x40000000; /** + * Flag of {@link #imeOptions}: used to request that the IME is capable of + * inputting ASCII characters. The intention of this flag is to ensure that + * the user can type Roman alphabet characters in a {@link android.widget.TextView} + * used for, typically, account ID or password input. It is expected that IMEs + * normally are able to input ASCII even without being told so (such IMEs + * already respect this flag in a sense), but there could be some cases they + * aren't when, for instance, only non-ASCII input languagaes like Arabic, + * Greek, Hebrew, Russian are enabled in the IME. Applications need to be + * aware that the flag is not a guarantee, and not all IMEs will respect it. + * However, it is strongly recommended for IME authors to respect this flag + * especially when their IME could end up with a state that has only non-ASCII + * input languages enabled. + */ + public static final int IME_FLAG_FORCE_ASCII = 0x80000000; + + /** * Generic unspecified type for {@link #imeOptions}. */ public static final int IME_NULL = 0x00000000; diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 71e357532f66..545a55529a8a 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -1154,6 +1154,21 @@ <p>Corresponds to {@link android.view.inputmethod.EditorInfo#IME_FLAG_NO_ENTER_ACTION}. --> <flag name="flagNoEnterAction" value="0x40000000" /> + <!-- Used to request that the IME should be capable of inputting ASCII + characters. The intention of this flag is to ensure that the user + can type Roman alphabet characters in a {@link android.widget.TextView} + used for, typically, account ID or password input. It is expected that IMEs + normally are able to input ASCII even without being told so (such IMEs + already respect this flag in a sense), but there could be some cases they + aren't when, for instance, only non-ASCII input languagaes like Arabic, + Greek, Hebrew, Russian are enabled in the IME. Applications need to be + aware that the flag is not a guarantee, and not all IMEs will respect it. + However, it is strongly recommended for IME authors to respect this flag + especially when their IME could end up with a state that has only non-ASCII + input languages enabled. + <p>Corresponds to + {@link android.view.inputmethod.EditorInfo#IME_FLAG_FORCE_ASCII}. --> + <flag name="flagForceAscii" value="0x80000000" /> </attr> <!-- A coordinate in the X dimension. --> diff --git a/data/fonts/DroidSansFallback.ttf b/data/fonts/DroidSansFallback.ttf Binary files differindex 391755e8a969..2379b2d758a1 100644 --- a/data/fonts/DroidSansFallback.ttf +++ b/data/fonts/DroidSansFallback.ttf diff --git a/data/fonts/DroidSansFallbackFull.ttf b/data/fonts/DroidSansFallbackFull.ttf Binary files differindex 8bd5e6333216..41b015d5a052 100644 --- a/data/fonts/DroidSansFallbackFull.ttf +++ b/data/fonts/DroidSansFallbackFull.ttf diff --git a/drm/common/DrmEngineBase.cpp b/drm/common/DrmEngineBase.cpp index 9b16c3685442..1c345a2a2d61 100644 --- a/drm/common/DrmEngineBase.cpp +++ b/drm/common/DrmEngineBase.cpp @@ -120,13 +120,23 @@ DrmSupportInfo* DrmEngineBase::getSupportInfo(int uniqueId) { } status_t DrmEngineBase::openDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length) { - return onOpenDecryptSession(uniqueId, decryptHandle, fd, offset, length); + int uniqueId, DecryptHandle* decryptHandle, + int fd, off64_t offset, off64_t length, const char* mime) { + + if (!mime || mime[0] == '\0') { + return onOpenDecryptSession(uniqueId, decryptHandle, fd, offset, length); + } + + return onOpenDecryptSession(uniqueId, decryptHandle, fd, offset, length, mime); } status_t DrmEngineBase::openDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, const char* uri) { - return onOpenDecryptSession(uniqueId, decryptHandle, uri); + int uniqueId, DecryptHandle* decryptHandle, + const char* uri, const char* mime) { + if (!mime || mime[0] == '\0') { + return onOpenDecryptSession(uniqueId, decryptHandle, uri); + } + return onOpenDecryptSession(uniqueId, decryptHandle, uri, mime); } status_t DrmEngineBase::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) { diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index 3ed8ade720ba..43f64f22e319 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -600,7 +600,7 @@ status_t BpDrmManagerService::getAllSupportInfo( } DecryptHandle* BpDrmManagerService::openDecryptSession( - int uniqueId, int fd, off64_t offset, off64_t length) { + int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) { ALOGV("Entering BpDrmManagerService::openDecryptSession"); Parcel data, reply; @@ -609,6 +609,11 @@ DecryptHandle* BpDrmManagerService::openDecryptSession( data.writeFileDescriptor(fd); data.writeInt64(offset); data.writeInt64(length); + String8 mimeType; + if (mime) { + mimeType = mime; + } + data.writeString8(mimeType); remote()->transact(OPEN_DECRYPT_SESSION, data, &reply); @@ -620,13 +625,20 @@ DecryptHandle* BpDrmManagerService::openDecryptSession( return handle; } -DecryptHandle* BpDrmManagerService::openDecryptSession(int uniqueId, const char* uri) { - ALOGV("Entering BpDrmManagerService::openDecryptSession"); +DecryptHandle* BpDrmManagerService::openDecryptSession( + int uniqueId, const char* uri, const char* mime) { + + ALOGV("Entering BpDrmManagerService::openDecryptSession: mime=%s", mime? mime: "NULL"); Parcel data, reply; data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor()); data.writeInt32(uniqueId); data.writeString8(String8(uri)); + String8 mimeType; + if (mime) { + mimeType = mime; + } + data.writeString8(mimeType); remote()->transact(OPEN_DECRYPT_SESSION_FROM_URI, data, &reply); @@ -1265,8 +1277,10 @@ status_t BnDrmManagerService::onTransact( const off64_t offset = data.readInt64(); const off64_t length = data.readInt64(); + const String8 mime = data.readString8(); + DecryptHandle* handle - = openDecryptSession(uniqueId, fd, offset, length); + = openDecryptSession(uniqueId, fd, offset, length, mime.string()); if (NULL != handle) { writeDecryptHandleToParcelData(handle, reply); @@ -1283,8 +1297,9 @@ status_t BnDrmManagerService::onTransact( const int uniqueId = data.readInt32(); const String8 uri = data.readString8(); + const String8 mime = data.readString8(); - DecryptHandle* handle = openDecryptSession(uniqueId, uri.string()); + DecryptHandle* handle = openDecryptSession(uniqueId, uri.string(), mime.string()); if (NULL != handle) { writeDecryptHandleToParcelData(handle, reply); diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp index 3abf3d335290..999295acb734 100644 --- a/drm/drmserver/DrmManager.cpp +++ b/drm/drmserver/DrmManager.cpp @@ -426,7 +426,9 @@ status_t DrmManager::getAllSupportInfo( return DRM_NO_ERROR; } -DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) { +DecryptHandle* DrmManager::openDecryptSession( + int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) { + Mutex::Autolock _l(mDecryptLock); status_t result = DRM_ERROR_CANNOT_HANDLE; Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); @@ -438,7 +440,7 @@ DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offs for (unsigned int index = 0; index < plugInIdList.size(); index++) { String8 plugInId = plugInIdList.itemAt(index); IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); - result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length); + result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime); if (DRM_NO_ERROR == result) { ++mDecryptSessionId; @@ -453,7 +455,8 @@ DecryptHandle* DrmManager::openDecryptSession(int uniqueId, int fd, off64_t offs return handle; } -DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) { +DecryptHandle* DrmManager::openDecryptSession( + int uniqueId, const char* uri, const char* mime) { Mutex::Autolock _l(mDecryptLock); status_t result = DRM_ERROR_CANNOT_HANDLE; Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList(); @@ -465,7 +468,7 @@ DecryptHandle* DrmManager::openDecryptSession(int uniqueId, const char* uri) { for (unsigned int index = 0; index < plugInIdList.size(); index++) { String8 plugInId = plugInIdList.itemAt(index); IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId); - result = rDrmEngine.openDecryptSession(uniqueId, handle, uri); + result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime); if (DRM_NO_ERROR == result) { ++mDecryptSessionId; diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp index df17ac5d134d..caeb026ce8fc 100644 --- a/drm/drmserver/DrmManagerService.cpp +++ b/drm/drmserver/DrmManagerService.cpp @@ -208,20 +208,20 @@ status_t DrmManagerService::getAllSupportInfo( } DecryptHandle* DrmManagerService::openDecryptSession( - int uniqueId, int fd, off64_t offset, off64_t length) { + int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) { ALOGV("Entering DrmManagerService::openDecryptSession"); if (isProtectedCallAllowed()) { - return mDrmManager->openDecryptSession(uniqueId, fd, offset, length); + return mDrmManager->openDecryptSession(uniqueId, fd, offset, length, mime); } return NULL; } DecryptHandle* DrmManagerService::openDecryptSession( - int uniqueId, const char* uri) { + int uniqueId, const char* uri, const char* mime) { ALOGV("Entering DrmManagerService::openDecryptSession with uri"); if (isProtectedCallAllowed()) { - return mDrmManager->openDecryptSession(uniqueId, uri); + return mDrmManager->openDecryptSession(uniqueId, uri, mime); } return NULL; diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp index c9c0d57961b9..8768c0834f60 100644 --- a/drm/libdrmframework/DrmManagerClient.cpp +++ b/drm/libdrmframework/DrmManagerClient.cpp @@ -116,12 +116,18 @@ status_t DrmManagerClient::getAllSupportInfo(int* length, DrmSupportInfo** drmSu return mDrmManagerClientImpl->getAllSupportInfo(mUniqueId, length, drmSupportInfoArray); } -sp<DecryptHandle> DrmManagerClient::openDecryptSession(int fd, off64_t offset, off64_t length) { - return mDrmManagerClientImpl->openDecryptSession(mUniqueId, fd, offset, length); +sp<DecryptHandle> DrmManagerClient::openDecryptSession( + int fd, off64_t offset, off64_t length, const char* mime) { + + return mDrmManagerClientImpl->openDecryptSession( + mUniqueId, fd, offset, length, mime); } -sp<DecryptHandle> DrmManagerClient::openDecryptSession(const char* uri) { - return mDrmManagerClientImpl->openDecryptSession(mUniqueId, uri); +sp<DecryptHandle> DrmManagerClient::openDecryptSession( + const char* uri, const char* mime) { + + return mDrmManagerClientImpl->openDecryptSession( + mUniqueId, uri, mime); } status_t DrmManagerClient::closeDecryptSession(sp<DecryptHandle> &decryptHandle) { diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp index b222b8f03a97..fb0439ebf6fe 100644 --- a/drm/libdrmframework/DrmManagerClientImpl.cpp +++ b/drm/libdrmframework/DrmManagerClientImpl.cpp @@ -255,15 +255,19 @@ status_t DrmManagerClientImpl::getAllSupportInfo( } sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession( - int uniqueId, int fd, off64_t offset, off64_t length) { - return getDrmManagerService()->openDecryptSession(uniqueId, fd, offset, length); + int uniqueId, int fd, off64_t offset, + off64_t length, const char* mime) { + + return getDrmManagerService()->openDecryptSession( + uniqueId, fd, offset, length, mime); } sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession( - int uniqueId, const char* uri) { + int uniqueId, const char* uri, const char* mime) { + DecryptHandle* handle = NULL; if (NULL != uri) { - handle = getDrmManagerService()->openDecryptSession(uniqueId, uri); + handle = getDrmManagerService()->openDecryptSession(uniqueId, uri, mime); } return handle; } diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h index ac2b94606576..c9167d4708f2 100644 --- a/drm/libdrmframework/include/DrmManager.h +++ b/drm/libdrmframework/include/DrmManager.h @@ -111,9 +111,10 @@ public: status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray); - DecryptHandle* openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length); + DecryptHandle* openDecryptSession( + int uniqueId, int fd, off64_t offset, off64_t length, const char* mime); - DecryptHandle* openDecryptSession(int uniqueId, const char* uri); + DecryptHandle* openDecryptSession(int uniqueId, const char* uri, const char* mime); status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle); diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h index e3338d9e8679..2aa493f4ebe1 100644 --- a/drm/libdrmframework/include/DrmManagerClientImpl.h +++ b/drm/libdrmframework/include/DrmManagerClientImpl.h @@ -300,20 +300,24 @@ public: * @param[in] fd File descriptor of the protected content to be decrypted * @param[in] offset Start position of the content * @param[in] length The length of the protected content + * @param[in] mime The mime type of the protected content if it is not NULL or empty * @return * Handle for the decryption session */ - sp<DecryptHandle> openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length); + sp<DecryptHandle> openDecryptSession( + int uniqueId, int fd, off64_t offset, off64_t length, const char* mime); /** * Open the decrypt session to decrypt the given protected content * * @param[in] uniqueId Unique identifier for a session * @param[in] uri Path of the protected content to be decrypted + * @param[in] mime The mime type of the protected content if it is not NULL or empty * @return * Handle for the decryption session */ - sp<DecryptHandle> openDecryptSession(int uniqueId, const char* uri); + sp<DecryptHandle> openDecryptSession( + int uniqueId, const char* uri, const char* mime); /** * Close the decrypt session for the given handle diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h index 9cb5804e6915..1a8c2ae5c994 100644 --- a/drm/libdrmframework/include/DrmManagerService.h +++ b/drm/libdrmframework/include/DrmManagerService.h @@ -98,9 +98,11 @@ public: status_t getAllSupportInfo(int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray); - DecryptHandle* openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length); + DecryptHandle* openDecryptSession( + int uniqueId, int fd, off64_t offset, off64_t length, const char *mime); - DecryptHandle* openDecryptSession(int uniqueId, const char* uri); + DecryptHandle* openDecryptSession( + int uniqueId, const char* uri, const char* mime); status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle); diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h index b9618bbc27aa..a7d21c5a6181 100644 --- a/drm/libdrmframework/include/IDrmManagerService.h +++ b/drm/libdrmframework/include/IDrmManagerService.h @@ -139,9 +139,12 @@ public: virtual status_t getAllSupportInfo( int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) = 0; - virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length) = 0; + virtual DecryptHandle* openDecryptSession( + int uniqueId, int fd, off64_t offset, + off64_t length, const char* mime) = 0; - virtual DecryptHandle* openDecryptSession(int uniqueId, const char* uri) = 0; + virtual DecryptHandle* openDecryptSession( + int uniqueId, const char* uri, const char* mime) = 0; virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) = 0; @@ -222,9 +225,12 @@ public: virtual status_t getAllSupportInfo( int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray); - virtual DecryptHandle* openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length); + virtual DecryptHandle* openDecryptSession( + int uniqueId, int fd, off64_t offset, off64_t length, + const char* mime); - virtual DecryptHandle* openDecryptSession(int uniqueId, const char* uri); + virtual DecryptHandle* openDecryptSession( + int uniqueId, const char* uri, const char* mime); virtual status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle); diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h index 4a5afcf42c6b..08f6e6d2ad5c 100644 --- a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h +++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h @@ -80,10 +80,12 @@ public: DrmSupportInfo* getSupportInfo(int uniqueId); status_t openDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length); + int uniqueId, DecryptHandle* decryptHandle, + int fd, off64_t offset, off64_t length, const char* mime); status_t openDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, const char* uri); + int uniqueId, DecryptHandle* decryptHandle, + const char* uri, const char* mime); status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle); @@ -375,7 +377,29 @@ protected: * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success */ virtual status_t onOpenDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length) = 0; + int uniqueId, DecryptHandle* decryptHandle, + int fd, off64_t offset, off64_t length) = 0; + + /** + * Open the decrypt session to decrypt the given protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the current decryption session + * @param[in] fd File descriptor of the protected content to be decrypted + * @param[in] offset Start position of the content + * @param[in] length The length of the protected content + * @param[in] mime Mime type of the protected content + * drm plugin may do some optimization since the mime type is known. + * @return + * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success + */ + virtual status_t onOpenDecryptSession( + int uniqueId, DecryptHandle* decryptHandle, + int fd, off64_t offset, off64_t length, + const char* mime) { + + return DRM_ERROR_CANNOT_HANDLE; + } /** * Open the decrypt session to decrypt the given protected content @@ -387,7 +411,26 @@ protected: * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success */ virtual status_t onOpenDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, const char* uri) = 0; + int uniqueId, DecryptHandle* decryptHandle, + const char* uri) = 0; + + /** + * Open the decrypt session to decrypt the given protected content + * + * @param[in] uniqueId Unique identifier for a session + * @param[in] decryptHandle Handle for the current decryption session + * @param[in] uri Path of the protected content to be decrypted + * @param[in] mime Mime type of the protected content. The corresponding + * drm plugin may do some optimization since the mime type is known. + * @return + * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success + */ + virtual status_t onOpenDecryptSession( + int uniqueId, DecryptHandle* decryptHandle, + const char* uri, const char* mime) { + + return DRM_ERROR_CANNOT_HANDLE; + } /** * Close the decrypt session for the given handle diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h index 77460f6f1fba..dcf59775700b 100644 --- a/drm/libdrmframework/plugins/common/include/IDrmEngine.h +++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h @@ -320,11 +320,14 @@ public: * @param[in] fd File descriptor of the protected content to be decrypted * @param[in] offset Start position of the content * @param[in] length The length of the protected content + * @param[in] mime Mime type of the protected content if it is + * not NULL or empty * @return * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success */ virtual status_t openDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, int fd, off64_t offset, off64_t length) = 0; + int uniqueId, DecryptHandle* decryptHandle, + int fd, off64_t offset, off64_t length, const char* mime) = 0; /** * Open the decrypt session to decrypt the given protected content @@ -332,11 +335,14 @@ public: * @param[in] uniqueId Unique identifier for a session * @param[in] decryptHandle Handle for the current decryption session * @param[in] uri Path of the protected content to be decrypted + * @param[in] mime Mime type of the protected content if it is + * not NULL or empty * @return * DRM_ERROR_CANNOT_HANDLE for failure and DRM_NO_ERROR for success */ virtual status_t openDecryptSession( - int uniqueId, DecryptHandle* decryptHandle, const char* uri) = 0; + int uniqueId, DecryptHandle* decryptHandle, + const char* uri, const char* mime) = 0; /** * Close the decrypt session for the given handle diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h index b8fe46d08e31..c47bbfbfdce6 100644 --- a/include/drm/DrmManagerClient.h +++ b/include/drm/DrmManagerClient.h @@ -66,19 +66,21 @@ public: * @param[in] fd File descriptor of the protected content to be decrypted * @param[in] offset Start position of the content * @param[in] length The length of the protected content + * @param[in] mime Mime type of the protected content if it is not NULL or empty * @return * Handle for the decryption session */ - sp<DecryptHandle> openDecryptSession(int fd, off64_t offset, off64_t length); + sp<DecryptHandle> openDecryptSession(int fd, off64_t offset, off64_t length, const char* mime); /** * Open the decrypt session to decrypt the given protected content * * @param[in] uri Path of the protected content to be decrypted + * @param[in] mime Mime type of the protected content if it is not NULL or empty * @return * Handle for the decryption session */ - sp<DecryptHandle> openDecryptSession(const char* uri); + sp<DecryptHandle> openDecryptSession(const char* uri, const char* mime); /** * Close the decrypt session for the given handle diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h index 713af92860ef..00d583e531fd 100644 --- a/include/media/stagefright/DataSource.h +++ b/include/media/stagefright/DataSource.h @@ -81,7 +81,7 @@ public: static void RegisterDefaultSniffers(); // for DRM - virtual sp<DecryptHandle> DrmInitialization() { + virtual sp<DecryptHandle> DrmInitialization(const char *mime = NULL) { return NULL; } virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {}; diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h index 6cf86dc1323d..d994cb3fa721 100644 --- a/include/media/stagefright/FileSource.h +++ b/include/media/stagefright/FileSource.h @@ -38,7 +38,7 @@ public: virtual status_t getSize(off64_t *size); - virtual sp<DecryptHandle> DrmInitialization(); + virtual sp<DecryptHandle> DrmInitialization(const char *mime); virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client); diff --git a/include/media/stagefright/MediaExtractor.h b/include/media/stagefright/MediaExtractor.h index eb45237ca999..94090eef26a3 100644 --- a/include/media/stagefright/MediaExtractor.h +++ b/include/media/stagefright/MediaExtractor.h @@ -56,10 +56,10 @@ public: virtual uint32_t flags() const; // for DRM - virtual void setDrmFlag(bool flag) { + void setDrmFlag(bool flag) { mIsDrm = flag; }; - virtual bool getDrmFlag() { + bool getDrmFlag() { return mIsDrm; } virtual char* getDrmTrackInfo(size_t trackID, int *len) { diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index d0cb7ff6f7cb..8480b6d7466f 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -335,6 +335,14 @@ status_t AwesomePlayer::setDataSource_l( return UNKNOWN_ERROR; } + if (extractor->getDrmFlag()) { + checkDrmStatus(dataSource); + } + + return setDataSource_l(extractor); +} + +void AwesomePlayer::checkDrmStatus(const sp<DataSource>& dataSource) { dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); if (mDecryptHandle != NULL) { CHECK(mDrmManagerClient); @@ -342,8 +350,6 @@ status_t AwesomePlayer::setDataSource_l( notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); } } - - return setDataSource_l(extractor); } status_t AwesomePlayer::setDataSource_l(const sp<MediaExtractor> &extractor) { @@ -2095,7 +2101,7 @@ status_t AwesomePlayer::finishSetDataSource_l() { String8 mimeType; float confidence; sp<AMessage> dummy; - bool success = SniffDRM(dataSource, &mimeType, &confidence, &dummy); + bool success = SniffWVM(dataSource, &mimeType, &confidence, &dummy); if (!success || strcasecmp( @@ -2115,13 +2121,8 @@ status_t AwesomePlayer::finishSetDataSource_l() { } } - dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient); - - if (mDecryptHandle != NULL) { - CHECK(mDrmManagerClient); - if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) { - notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_DRM_NO_LICENSE); - } + if (extractor->getDrmFlag()) { + checkDrmStatus(dataSource); } status_t err = setDataSource_l(extractor); diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp index 9452ab17180a..afc4a803518d 100644 --- a/media/libstagefright/DRMExtractor.cpp +++ b/media/libstagefright/DRMExtractor.cpp @@ -282,13 +282,13 @@ bool SniffDRM( if (decryptHandle != NULL) { if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) { *mimeType = String8("drm+container_based+") + decryptHandle->mimeType; + *confidence = 10.0f; } else if (decryptHandle->decryptApiType == DecryptApiType::ELEMENTARY_STREAM_BASED) { *mimeType = String8("drm+es_based+") + decryptHandle->mimeType; - } else if (decryptHandle->decryptApiType == DecryptApiType::WV_BASED) { - *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM; - ALOGW("SniffWVM: found match\n"); + *confidence = 10.0f; + } else { + return false; } - *confidence = 10.0f; return true; } diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp index e471f73da59b..d0a788088301 100644 --- a/media/libstagefright/DataSource.cpp +++ b/media/libstagefright/DataSource.cpp @@ -32,6 +32,7 @@ #include "include/DRMExtractor.h" #include "include/FLACExtractor.h" #include "include/AACExtractor.h" +#include "include/WVMExtractor.h" #include "matroska/MatroskaExtractor.h" @@ -120,6 +121,7 @@ void DataSource::RegisterDefaultSniffers() { RegisterSniffer(SniffAAC); RegisterSniffer(SniffAVI); RegisterSniffer(SniffMPEG2PS); + RegisterSniffer(SniffWVM); char value[PROPERTY_VALUE_MAX]; if (property_get("drm.service.enabled", value, NULL) diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp index 73cb48c74248..01f53e4b6eb6 100644 --- a/media/libstagefright/FileSource.cpp +++ b/media/libstagefright/FileSource.cpp @@ -127,7 +127,7 @@ status_t FileSource::getSize(off64_t *size) { return OK; } -sp<DecryptHandle> FileSource::DrmInitialization() { +sp<DecryptHandle> FileSource::DrmInitialization(const char *mime) { if (mDrmManagerClient == NULL) { mDrmManagerClient = new DrmManagerClient(); } @@ -138,7 +138,7 @@ sp<DecryptHandle> FileSource::DrmInitialization() { if (mDecryptHandle == NULL) { mDecryptHandle = mDrmManagerClient->openDecryptSession( - mFd, mOffset, mLength); + mFd, mOffset, mLength, mime); } if (mDecryptHandle == NULL) { diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp index 249c29854a03..693c506879e4 100644 --- a/media/libstagefright/NuCachedSource2.cpp +++ b/media/libstagefright/NuCachedSource2.cpp @@ -603,8 +603,8 @@ void NuCachedSource2::resumeFetchingIfNecessary() { restartPrefetcherIfNecessary_l(true /* ignore low water threshold */); } -sp<DecryptHandle> NuCachedSource2::DrmInitialization() { - return mSource->DrmInitialization(); +sp<DecryptHandle> NuCachedSource2::DrmInitialization(const char* mime) { + return mSource->DrmInitialization(mime); } void NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) { diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp index 2092cb6d55af..1e4e049edb7f 100644 --- a/media/libstagefright/WVMExtractor.cpp +++ b/media/libstagefright/WVMExtractor.cpp @@ -45,17 +45,12 @@ namespace android { static Mutex gWVMutex; WVMExtractor::WVMExtractor(const sp<DataSource> &source) - : mDataSource(source) { - { - Mutex::Autolock autoLock(gWVMutex); - if (gVendorLibHandle == NULL) { - gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW); - } + : mDataSource(source) +{ + Mutex::Autolock autoLock(gWVMutex); - if (gVendorLibHandle == NULL) { - ALOGE("Failed to open libwvm.so"); - return; - } + if (!getVendorLibHandle()) { + return; } typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>); @@ -64,13 +59,28 @@ WVMExtractor::WVMExtractor(const sp<DataSource> &source) "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE"); if (getInstanceFunc) { + CHECK(source->DrmInitialization(MEDIA_MIMETYPE_CONTAINER_WVM) != NULL); mImpl = (*getInstanceFunc)(source); CHECK(mImpl != NULL); + setDrmFlag(true); } else { ALOGE("Failed to locate GetInstance in libwvm.so"); } } +bool WVMExtractor::getVendorLibHandle() +{ + if (gVendorLibHandle == NULL) { + gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW); + } + + if (gVendorLibHandle == NULL) { + ALOGE("Failed to open libwvm.so"); + } + + return gVendorLibHandle != NULL; +} + WVMExtractor::~WVMExtractor() { } @@ -113,5 +123,33 @@ void WVMExtractor::setAdaptiveStreamingMode(bool adaptive) { } } +bool SniffWVM( + const sp<DataSource> &source, String8 *mimeType, float *confidence, + sp<AMessage> *) { + + Mutex::Autolock autoLock(gWVMutex); + + if (!WVMExtractor::getVendorLibHandle()) { + return false; + } + + typedef WVMLoadableExtractor *(*SnifferFunc)(const sp<DataSource>&); + SnifferFunc snifferFunc = + (SnifferFunc) dlsym(gVendorLibHandle, + "_ZN7android15IsWidevineMediaERKNS_2spINS_10DataSourceEEE"); + + if (snifferFunc) { + if ((*snifferFunc)(source)) { + *mimeType = MEDIA_MIMETYPE_CONTAINER_WVM; + *confidence = 10.0f; + return true; + } + } else { + ALOGE("IsWidevineMedia not found in libwvm.so"); + } + + return false; +} + } //namespace android diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp index 180460b5e33d..76f7946229e9 100644 --- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp +++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp @@ -259,7 +259,7 @@ void ChromiumHTTPDataSource::onDisconnectComplete() { mCondition.broadcast(); } -sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization() { +sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization(const char* mime) { Mutex::Autolock autoLock(mLock); if (mDrmManagerClient == NULL) { @@ -275,7 +275,7 @@ sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization() { * original one */ mDecryptHandle = mDrmManagerClient->openDecryptSession( - String8(mURI.c_str())); + String8(mURI.c_str()), mime); } if (mDecryptHandle == NULL) { diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 0985f479d561..82c647623e5b 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -290,6 +290,7 @@ private: bool isStreamingHTTP() const; void sendCacheStats(); + void checkDrmStatus(const sp<DataSource>& dataSource); enum FlagMode { SET, diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h index 18f89130c747..82e08fd1ba1e 100644 --- a/media/libstagefright/include/ChromiumHTTPDataSource.h +++ b/media/libstagefright/include/ChromiumHTTPDataSource.h @@ -43,7 +43,7 @@ struct ChromiumHTTPDataSource : public HTTPBase { virtual status_t getSize(off64_t *size); virtual uint32_t flags(); - virtual sp<DecryptHandle> DrmInitialization(); + virtual sp<DecryptHandle> DrmInitialization(const char *mime); virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client); diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h index 7a03e7e4f976..c27a29b76624 100644 --- a/media/libstagefright/include/NuCachedSource2.h +++ b/media/libstagefright/include/NuCachedSource2.h @@ -40,7 +40,7 @@ struct NuCachedSource2 : public DataSource { virtual status_t getSize(off64_t *size); virtual uint32_t flags(); - virtual sp<DecryptHandle> DrmInitialization(); + virtual sp<DecryptHandle> DrmInitialization(const char* mime); virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client); virtual String8 getUri(); diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h index deecd2543a92..9f763f9debef 100644 --- a/media/libstagefright/include/WVMExtractor.h +++ b/media/libstagefright/include/WVMExtractor.h @@ -23,6 +23,8 @@ namespace android { +struct AMessage; +class String8; class DataSource; class WVMLoadableExtractor : public MediaExtractor { @@ -58,6 +60,8 @@ public: // is used. void setAdaptiveStreamingMode(bool adaptive); + static bool getVendorLibHandle(); + protected: virtual ~WVMExtractor(); @@ -69,6 +73,10 @@ private: WVMExtractor &operator=(const WVMExtractor &); }; +bool SniffWVM( + const sp<DataSource> &source, String8 *mimeType, float *confidence, + sp<AMessage> *); + } // namespace android #endif // DRM_EXTRACTOR_H_ diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp index 035836ed2992..80ab5195cec5 100644 --- a/services/surfaceflinger/EventThread.cpp +++ b/services/surfaceflinger/EventThread.cpp @@ -102,7 +102,7 @@ bool EventThread::threadLoop() { nsecs_t timestamp; DisplayEventReceiver::Event vsync; - KeyedVector< wp<DisplayEventConnection>, ConnectionInfo > displayEventConnections; + Vector< wp<DisplayEventConnection> > displayEventConnections; { // scope for the lock Mutex::Autolock _l(mLock); @@ -153,6 +153,9 @@ bool EventThread::threadLoop() { } info.count--; } + if (reportVsync) { + displayEventConnections.add(mDisplayEventConnections.keyAt(i)); + } } if (reportVsync) { @@ -164,15 +167,11 @@ bool EventThread::threadLoop() { vsync.header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC; vsync.header.timestamp = timestamp; vsync.vsync.count = mDeliveredEvents; - - // make a copy of our connection list, so we can - // dispatch events without holding mLock - displayEventConnections = mDisplayEventConnections; } const size_t count = displayEventConnections.size(); for (size_t i=0 ; i<count ; i++) { - sp<DisplayEventConnection> conn(displayEventConnections.keyAt(i).promote()); + sp<DisplayEventConnection> conn(displayEventConnections[i].promote()); // make sure the connection didn't die if (conn != NULL) { status_t err = conn->postEvent(vsync); @@ -186,12 +185,12 @@ bool EventThread::threadLoop() { // handle any other error on the pipe as fatal. the only // reasonable thing to do is to clean-up this connection. // The most common error we'll get here is -EPIPE. - removeDisplayEventConnection(displayEventConnections.keyAt(i)); + removeDisplayEventConnection(displayEventConnections[i]); } } else { // somehow the connection is dead, but we still have it in our list // just clean the list. - removeDisplayEventConnection(displayEventConnections.keyAt(i)); + removeDisplayEventConnection(displayEventConnections[i]); } } |