1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)package org.chromium.content.browser; 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.content.Context; 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)import android.content.pm.PackageManager; 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.media.MediaMetadataRetriever; 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.ConnectivityManager; 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.NetworkInfo; 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.net.Uri; 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.text.TextUtils; 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import android.util.Log; 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.chromium.base.CalledByNative; 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.chromium.base.JNINamespace; 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import org.chromium.base.PathUtils; 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import java.io.File; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import java.util.HashMap; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/** 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * Java counterpart of android MediaResourceGetter. 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)@JNINamespace("content") 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class MediaResourceGetter { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static final String TAG = "MediaResourceGetter"; 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static class MediaMetadata { 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private final int mDurationInMilliseconds; 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private final int mWidth; 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private final int mHeight; 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private final boolean mSuccess; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private MediaMetadata(int durationInMilliseconds, int width, int height, boolean success) { 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mDurationInMilliseconds = durationInMilliseconds; 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mWidth = width; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mHeight = height; 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mSuccess = success; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative("MediaMetadata") 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private int getDurationInMilliseconds() { return mDurationInMilliseconds; } 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative("MediaMetadata") 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private int getWidth() { return mWidth; } 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative("MediaMetadata") 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private int getHeight() { return mHeight; } 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative("MediaMetadata") 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private boolean isSuccess() { return mSuccess; } 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) @CalledByNative 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private static MediaMetadata extractMediaMetadata(Context context, String url, String cookies) { 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int durationInMilliseconds = 0; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int width = 0; 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int height = 0; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) boolean success = false; 63d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if ("GT-I9100".contentEquals(android.os.Build.MODEL) 64d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) && android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) { 65d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) return new MediaMetadata(0, 0, 0, success); 66d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(qinmin): use ConnectionTypeObserver to listen to the network type change. 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ConnectivityManager mConnectivityManager = 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (mConnectivityManager != null) { 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (context.checkCallingOrSelfPermission( 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) android.Manifest.permission.ACCESS_NETWORK_STATE) != 733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) PackageManager.PERMISSION_GRANTED) { 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return new MediaMetadata(0, 0, 0, false); 753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NetworkInfo info = mConnectivityManager.getActiveNetworkInfo(); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (info == null) { 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new MediaMetadata(durationInMilliseconds, width, height, success); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (info.getType()) { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case ConnectivityManager.TYPE_ETHERNET: 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case ConnectivityManager.TYPE_WIFI: 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case ConnectivityManager.TYPE_WIMAX: 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case ConnectivityManager.TYPE_MOBILE: 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new MediaMetadata(durationInMilliseconds, width, height, success); 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) try { 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Uri uri = Uri.parse(url); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) String scheme = uri.getScheme(); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (scheme == null || scheme.equals("file")) { 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) File file = new File(uri.getPath()); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) String path = file.getAbsolutePath(); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (file.exists() && (path.startsWith("/mnt/sdcard/") || 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) path.startsWith("/sdcard/") || 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) path.startsWith(PathUtils.getExternalStorageDirectory()))) { 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) retriever.setDataSource(path); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Log.e(TAG, "Unable to read file: " + url); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new MediaMetadata(durationInMilliseconds, width, height, success); 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HashMap<String, String> headersMap = new HashMap<String, String>(); 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!TextUtils.isEmpty(cookies)) { 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) headersMap.put("Cookie", cookies); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) retriever.setDataSource(url, headersMap); 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) String duration = retriever.extractMetadata( 1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MediaMetadataRetriever.METADATA_KEY_DURATION); 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) String videoWidth = retriever.extractMetadata( 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) String videoHeight = retriever.extractMetadata( 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (duration == null || videoWidth == null || videoHeight == null) { 1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return new MediaMetadata(durationInMilliseconds, width, height, success); 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) durationInMilliseconds = Integer.parseInt(duration); 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) width = Integer.parseInt(videoWidth); 1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) height = Integer.parseInt(videoHeight); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) success = true; 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } catch (IllegalArgumentException e) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Log.e(TAG, "Invalid url: " + e); 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } catch (RuntimeException e) { 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Log.e(TAG, "Invalid url: " + e); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return new MediaMetadata(durationInMilliseconds, width, height, success); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 135