18f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania/* 28f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * Copyright (C) 2009 The Android Open Source Project 38f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * 48f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * Licensed under the Apache License, Version 2.0 (the "License"); 58f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * you may not use this file except in compliance with the License. 68f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * You may obtain a copy of the License at 78f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * 88f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * http://www.apache.org/licenses/LICENSE-2.0 98f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * 108f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * Unless required by applicable law or agreed to in writing, software 118f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * distributed under the License is distributed on an "AS IS" BASIS, 128f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * See the License for the specific language governing permissions and 148f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania * limitations under the License. 158f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania */ 168f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 178f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania//#define LOG_NDEBUG 0 188f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#define LOG_TAG "TestPlayerStub" 198f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include "utils/Log.h" 208f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 218f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include "TestPlayerStub.h" 228f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 238f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include <dlfcn.h> // for dlopen/dlclose 248f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include <stdlib.h> 258f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include <string.h> 268f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include <cutils/properties.h> 278f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include <utils/Errors.h> // for status_t 288f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 298f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania#include "media/MediaPlayerInterface.h" 308f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 318f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 328f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catanianamespace { 338f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniausing android::status_t; 348f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniausing android::MediaPlayerBase; 358f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 368f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniaconst char *kTestUrlScheme = "test:"; 378f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniaconst char *kUrlParam = "url="; 388f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 398f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniaconst char *kBuildTypePropName = "ro.build.type"; 408f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniaconst char *kEngBuild = "eng"; 418f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniaconst char *kTestBuild = "test"; 428f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 438f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// @return true if the current build is 'eng' or 'test'. 448f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniabool isTestBuild() 458f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania{ 468f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania char prop[PROPERTY_VALUE_MAX] = { '\0', }; 478f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 488f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania property_get(kBuildTypePropName, prop, '\0'); 498f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return strcmp(prop, kEngBuild) == 0 || strcmp(prop, kTestBuild) == 0; 508f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 518f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 528f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// @return true if the url scheme is 'test:' 538f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniabool isTestUrl(const char *url) 548f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania{ 558f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return url && strncmp(url, kTestUrlScheme, strlen(kTestUrlScheme)) == 0; 568f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 578f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 588f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} // anonymous namespace 598f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 608f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catanianamespace android { 618f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 628f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas CataniaTestPlayerStub::TestPlayerStub() 638f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania :mUrl(NULL), mFilename(NULL), mContentUrl(NULL), 648f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mHandle(NULL), mNewPlayer(NULL), mDeletePlayer(NULL), 658f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mPlayer(NULL) { } 668f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 678f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas CataniaTestPlayerStub::~TestPlayerStub() 688f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania{ 698f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania resetInternal(); 708f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 718f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 728f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniastatus_t TestPlayerStub::initCheck() 738f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania{ 748f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return isTestBuild() ? OK : INVALID_OPERATION; 758f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 768f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 778f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// Parse mUrl to get: 788f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// * The library to be dlopened. 798f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// * The url to be passed to the real setDataSource impl. 808f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// 818f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// mUrl is expected to be in following format: 828f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// 838f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// test:<name of the .so>?url=<url for setDataSource> 848f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// 858f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// The value of the url parameter is treated as a string (no 868f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// unescaping of illegal charaters). 878f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniastatus_t TestPlayerStub::parseUrl() 888f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania{ 898f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (strlen(mUrl) < strlen(kTestUrlScheme)) { 908f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania resetInternal(); 918f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return BAD_VALUE; 928f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 938f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 948f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania char *i = mUrl + strlen(kTestUrlScheme); 958f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 968f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mFilename = i; 978f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 988f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania while (*i != '\0' && *i != '?') { 998f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania ++i; 1008f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1018f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1028f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (*i == '\0' || strncmp(i + 1, kUrlParam, strlen(kUrlParam)) != 0) { 1038f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania resetInternal(); 1048f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return BAD_VALUE; 1058f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1068f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania *i = '\0'; // replace '?' to nul-terminate mFilename 1078f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1088f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mContentUrl = i + 1 + strlen(kUrlParam); 1098f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return OK; 1108f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 1118f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1128f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// Load the dynamic library. 1138f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// Create the test player. 1148f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// Call setDataSource on the test player with the url in param. 115256430093679e1d62b54fb0c852126e54d162f6fAndreas Huberstatus_t TestPlayerStub::setDataSource( 116256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber const char *url, const KeyedVector<String8, String8> *headers) { 1178f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (!isTestUrl(url) || NULL != mHandle) { 1188f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return INVALID_OPERATION; 1198f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1208f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1218f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mUrl = strdup(url); 1228f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1238f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania status_t status = parseUrl(); 1248f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1258f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (OK != status) { 1268f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania resetInternal(); 1278f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return status; 1288f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1298f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1308f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania ::dlerror(); // Clears any pending error. 1318f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1328f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania // Load the test player from the url. dlopen will fail if the lib 1338f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania // is not there. dls are under /system/lib 1348f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania // None of the entry points should be NULL. 1358f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mHandle = ::dlopen(mFilename, RTLD_NOW | RTLD_GLOBAL); 1368f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (!mHandle) { 1378f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania LOGE("dlopen failed: %s", ::dlerror()); 1388f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania resetInternal(); 1398f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return UNKNOWN_ERROR; 1408f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1418f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1428f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania // Load the 2 entry points to create and delete instances. 1438f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania const char *err; 1448f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mNewPlayer = reinterpret_cast<NEW_PLAYER>(dlsym(mHandle, 1458f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania "newPlayer")); 1468f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania err = ::dlerror(); 1478f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (err || mNewPlayer == NULL) { 1488f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania // if err is NULL the string <null> is inserted in the logs => 1498f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania // mNewPlayer was NULL. 1508f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania LOGE("dlsym for newPlayer failed %s", err); 1518f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania resetInternal(); 1528f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return UNKNOWN_ERROR; 1538f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1548f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1558f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mDeletePlayer = reinterpret_cast<DELETE_PLAYER>(dlsym(mHandle, 1568f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania "deletePlayer")); 1578f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania err = ::dlerror(); 1588f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (err || mDeletePlayer == NULL) { 1598f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania LOGE("dlsym for deletePlayer failed %s", err); 1608f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania resetInternal(); 1618f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return UNKNOWN_ERROR; 1628f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1638f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1648f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mPlayer = (*mNewPlayer)(); 165256430093679e1d62b54fb0c852126e54d162f6fAndreas Huber return mPlayer->setDataSource(mContentUrl, headers); 1668f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 1678f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1688f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania// Internal cleanup. 1698f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Cataniastatus_t TestPlayerStub::resetInternal() 1708f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania{ 1718f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if(mUrl) { 1728f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania free(mUrl); 1738f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mUrl = NULL; 1748f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1758f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mFilename = NULL; 1768f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mContentUrl = NULL; 1778f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1788f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (mPlayer) { 179c5e3d73f92f33b3fffef57f95d017211f4169c49Patrick Scott LOG_ASSERT(mDeletePlayer != NULL, "mDeletePlayer is null"); 1808f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania (*mDeletePlayer)(mPlayer); 1818f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mPlayer = NULL; 1828f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1838f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1848f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania if (mHandle) { 1858f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania ::dlclose(mHandle); 1868f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania mHandle = NULL; 1878f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania } 1888f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return OK; 1898f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 1908f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1918f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania/* static */ bool TestPlayerStub::canBeUsed(const char *url) 1928f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania{ 1938f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania return isTestBuild() && isTestUrl(url); 1948f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} 1958f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania 1968f5fcab05f1d6f644a9c30f012b8ff302f24a118Nicolas Catania} // namespace android 197