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