MediaResourceGetter.java revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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;
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // TODO(qinmin): use ConnectionTypeObserver to listen to the network type change.
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ConnectivityManager mConnectivityManager =
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (mConnectivityManager != null) {
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            if (context.checkCallingOrSelfPermission(
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    android.Manifest.permission.ACCESS_NETWORK_STATE) !=
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    PackageManager.PERMISSION_GRANTED) {
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                return new MediaMetadata(0, 0, 0, false);
713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            }
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            if (info == null) {
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                return new MediaMetadata(durationInMilliseconds, width, height, success);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            switch (info.getType()) {
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                case ConnectivityManager.TYPE_ETHERNET:
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                case ConnectivityManager.TYPE_WIFI:
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    break;
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                case ConnectivityManager.TYPE_WIMAX:
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                case ConnectivityManager.TYPE_MOBILE:
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                default:
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    return new MediaMetadata(durationInMilliseconds, width, height, success);
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        try {
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            Uri uri = Uri.parse(url);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            String scheme = uri.getScheme();
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            if (scheme == null || scheme.equals("file")) {
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                File file = new File(uri.getPath());
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                String path = file.getAbsolutePath();
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                if (file.exists() && (path.startsWith("/mnt/sdcard/") ||
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        path.startsWith("/sdcard/") ||
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        path.startsWith(PathUtils.getExternalStorageDirectory()))) {
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    retriever.setDataSource(path);
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                } else {
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    Log.e(TAG, "Unable to read file: " + url);
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    return new MediaMetadata(durationInMilliseconds, width, height, success);
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                }
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            } else {
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                HashMap<String, String> headersMap = new HashMap<String, String>();
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                if (!TextUtils.isEmpty(cookies)) {
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    headersMap.put("Cookie", cookies);
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                }
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                retriever.setDataSource(url, headersMap);
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            }
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            String duration = retriever.extractMetadata(
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    MediaMetadataRetriever.METADATA_KEY_DURATION);
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            String videoWidth = retriever.extractMetadata(
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            String videoHeight = retriever.extractMetadata(
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            if (duration == null || videoWidth == null || videoHeight == null) {
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                return new MediaMetadata(durationInMilliseconds, width, height, success);
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            }
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            durationInMilliseconds = Integer.parseInt(duration);
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            width = Integer.parseInt(videoWidth);
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            height = Integer.parseInt(videoHeight);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            success = true;
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } catch (IllegalArgumentException e) {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            Log.e(TAG, "Invalid url: " + e);
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        } catch (RuntimeException e) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            Log.e(TAG, "Invalid url: " + e);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        return new MediaMetadata(durationInMilliseconds, width, height, success);
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
131