Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df59cbd5 authored by hkuang's avatar hkuang
Browse files

transcoding: Add ApplicationMediaCapabilities.

Bug: 169849854
Test: Unit test

Change-Id: I4a20aa2ac2433b228e80707281d8c747ec9ff7d6
parent 8cc563eb
Loading
Loading
Loading
Loading
+153 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

import android.annotation.NonNull;
import android.content.ContentResolver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * ApplicationMediaCapabilities is an immutable class that encapsulates an application's
 * capabilities of handling advanced media formats.
 *
 * The ApplicationMediaCapabilities class is used by the platform to to represent an application's
 * media capabilities as defined in their manifest(TODO: Add link) in order to determine
 * whether modern media files need to be transcoded for that application (TODO: Add link).
 *
 * ApplicationMediaCapabilities objects can also be built by applications at runtime for use with
 * {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)} to provide more
 * control over the transcoding that is built into the platform. ApplicationMediaCapabilities
 * provided by applications at runtime like this override the default manifest capabilities for that
 * media access.
 *
 * TODO(huang): Correct openTypedAssetFileDescriptor with the new API after it is added.
 * TODO(hkuang): Add a link to seamless transcoding detail when it is published
 * TODO(hkuang): Add code sample on how to build a capability object with MediaCodecList
 *
 * @hide
 */
public final class ApplicationMediaCapabilities implements Parcelable {
    private static final String TAG = "ApplicationMediaCapabilities";

    /** Whether handling of HEVC video is supported. */
    private final boolean mIsHevcSupported;

    /** Whether handling of slow-motion video is supported. */
    private final boolean mIsSlowMotionSupported;

    /** Whether handling of high dynamic range video is supported. */
    private final boolean mIsHdrSupported;

    private ApplicationMediaCapabilities(Builder b) {
        mIsHevcSupported = b.mIsHevcSupported;
        mIsHdrSupported = b.mIsHdrSupported;
        mIsSlowMotionSupported = b.mIsSlowMotionSupported;
    }

    /** Whether handling of HEVC video is supported. */
    public boolean isHevcSupported() {
        return mIsHevcSupported;
    }

    /** Whether handling of slow-motion video is supported. */
    public boolean isSlowMotionSupported() {
        return mIsSlowMotionSupported;
    }

    /** Whether handling of high dynamic range video is supported. */
    public boolean isHdrSupported() {
        return mIsHdrSupported;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeBoolean(mIsHevcSupported);
        dest.writeBoolean(mIsHdrSupported);
        dest.writeBoolean(mIsSlowMotionSupported);
    }

    /**
     * Builder class for {@link ApplicationMediaCapabilities} objects.
     * Use this class to configure and create an ApplicationMediaCapabilities instance. Builder
     * could be created from an existing ApplicationMediaCapabilities object, from a xml file or
     * MediaCodecList.
     * //TODO(hkuang): Add xml parsing support to the builder.
     */
    public final static class Builder {
        private boolean mIsHevcSupported = false;
        private boolean mIsHdrSupported = false;
        private boolean mIsSlowMotionSupported = false;

        /**
         * Constructs a new Builder with all the supports default to false.
         */
        public Builder() {
        }

        /**
         * Builds a {@link ApplicationMediaCapabilities} object.
         *
         * @return a new {@link ApplicationMediaCapabilities} instance successfully initialized
         * with all the parameters set on this <code>Builder</code>.
         * @throws UnsupportedOperationException if the parameters set on the
         *         <code>Builder</code> were incompatible, or if they are not supported by the
         *         device.
         */
        @NonNull
        public ApplicationMediaCapabilities build() {
            if (mIsHdrSupported && !mIsHevcSupported) {
                throw new UnsupportedOperationException("Must also support HEVC if support HDR.");
            }
            return new ApplicationMediaCapabilities(this);
        }

        /**
         * Sets whether supports HEVC encoded video.
         */
        @NonNull
        public Builder setHevcSupported(boolean hevcSupported) {
            mIsHevcSupported = hevcSupported;
            return this;
        }

        /**
         * Sets whether supports high dynamic range video.
         */
        @NonNull
        public Builder setHdrSupported(boolean hdrSupported) {
            mIsHdrSupported = hdrSupported;
            return this;
        }

        /**
         * Sets whether supports slow-motion video.
         */
        @NonNull
        public Builder setSlowMotionSupported(boolean slowMotionSupported) {
            mIsSlowMotionSupported = slowMotionSupported;
            return this;
        }
    }
}
+94 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mediatranscodingtest;

/*
 * Test for ApplicationMediaCapabilities in the media framework.
 *
 * To run this test suite:
     make frameworks/base/media/tests/MediaTranscodingTest
     make mediatranscodingtest

     adb install -r testcases/mediatranscodingtest/arm64/mediatranscodingtest.apk

     adb shell am instrument -e class \
     com.android.mediatranscodingtest.MediaCapabilityTest \
     -w com.android.mediatranscodingtest/.MediaTranscodingTestRunner
 *
 */

import static org.testng.Assert.assertThrows;

import android.media.ApplicationMediaCapabilities;
import android.test.ActivityInstrumentationTestCase2;

import org.junit.Test;

public class ApplicationMediaCapabilitiesTest extends
        ActivityInstrumentationTestCase2<MediaTranscodingTest> {
    private static final String TAG = "MediaCapabilityTest";

    public ApplicationMediaCapabilitiesTest() {
        super("com.android.MediaCapabilityTest", MediaTranscodingTest.class);
    }

    @Test
    public void testSetSupportHevc() throws Exception {
        ApplicationMediaCapabilities capability =
                new ApplicationMediaCapabilities.Builder().setHevcSupported(true).build();
        assertTrue(capability.isHevcSupported());

        ApplicationMediaCapabilities capability2 =
                new ApplicationMediaCapabilities.Builder().setHevcSupported(false).build();
        assertFalse(capability2.isHevcSupported());
    }

    @Test
    public void testSetSupportHdr() throws Exception {
        ApplicationMediaCapabilities capability =
                new ApplicationMediaCapabilities.Builder().setHdrSupported(true).setHevcSupported(
                        true).build();
        assertEquals(true, capability.isHdrSupported());
    }

    @Test
    public void testSetSupportSlowMotion() throws Exception {
        ApplicationMediaCapabilities capability =
                new ApplicationMediaCapabilities.Builder().setSlowMotionSupported(
                        true).build();
        assertTrue(capability.isSlowMotionSupported());
    }

    @Test
    public void testBuilder() throws Exception {
        ApplicationMediaCapabilities capability =
                new ApplicationMediaCapabilities.Builder().setHdrSupported(
                        true).setHevcSupported(true).setSlowMotionSupported(true).build();
        assertTrue(capability.isHdrSupported());
        assertTrue(capability.isSlowMotionSupported());
        assertTrue(capability.isSlowMotionSupported());
    }

    @Test
    public void testSupportHdrWithoutSupportHevc() throws Exception {
        assertThrows(UnsupportedOperationException.class, () -> {
            ApplicationMediaCapabilities capability =
                    new ApplicationMediaCapabilities.Builder().setHdrSupported(
                            true).setHevcSupported(false).build();
        });
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ public class MediaTranscodingTestRunner extends InstrumentationTestRunner {
    public TestSuite getAllTests() {
        TestSuite suite = new InstrumentationTestSuite(this);
        suite.addTestSuite(MediaTranscodeManagerDiedTest.class);
        suite.addTestSuite(ApplicationMediaCapabilitiesTest.class);
        suite.addTestSuite(MediaTranscodeManagerTest.class);
        suite.addTestSuite(MediaTranscodingBenchmark.class);
        return suite;