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

Commit fe3cc4b9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Initial commit of updatable media API"

parents 229d2cdb cfa03706
Loading
Loading
Loading
Loading
+236 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.widget;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Canvas;
import android.media.session.MediaController;
import android.media.update.ApiLoader;
import android.media.update.MediaController2Provider;
import android.media.update.ViewProvider;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;

/**
 * TODO PUBLIC API
 * @hide
 */
public class MediaController2 extends FrameLayout {
    private final MediaController2Provider mProvider;

    public MediaController2(@NonNull Context context) {
        this(context, null);
    }

    public MediaController2(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MediaController2(@NonNull Context context, @Nullable AttributeSet attrs,
                            int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public MediaController2(@NonNull Context context, @Nullable AttributeSet attrs,
                            int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        mProvider = ApiLoader.getProvider(context)
                .createMediaController2(this, new SuperProvider());
    }

    public void setController(MediaController controller) {
        mProvider.setController_impl(controller);
    }

    public void setAnchorView(View view) {
        mProvider.setAnchorView_impl(view);
    }

    public void show() {
        mProvider.show_impl();
    }

    public void show(int timeout) {
        mProvider.show_impl(timeout);
    }

    public boolean isShowing() {
        return mProvider.isShowing_impl();
    }

    public void hide() {
        mProvider.hide_impl();
    }

    public void setPrevNextListeners(OnClickListener next, OnClickListener prev) {
        mProvider.setPrevNextListeners_impl(next, prev);
    }

    public void showCCButton() {
        mProvider.showCCButton_impl();
    }

    public boolean isPlaying() {
        return mProvider.isPlaying_impl();
    }

    public int getCurrentPosition() {
        return mProvider.getCurrentPosition_impl();
    }

    public int getBufferPercentage() {
        return mProvider.getBufferPercentage_impl();
    }

    public boolean canPause() {
        return mProvider.canPause_impl();
    }

    public boolean canSeekBackward() {
        return mProvider.canSeekBackward_impl();
    }

    public boolean canSeekForward() {
        return mProvider.canSeekForward_impl();
    }

    public void showSubtitle() {
        mProvider.showSubtitle_impl();
    }

    public void hideSubtitle() {
        mProvider.hideSubtitle_impl();
    }

    @Override
    protected void onAttachedToWindow() {
        mProvider.onAttachedToWindow_impl();
    }

    @Override
    protected void onDetachedFromWindow() {
        mProvider.onDetachedFromWindow_impl();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        mProvider.onLayout_impl(changed, left, top, right, bottom);
    }

    @Override
    public void draw(Canvas canvas) {
        mProvider.draw_impl(canvas);
    }

    @Override
    public CharSequence getAccessibilityClassName() {
        return mProvider.getAccessibilityClassName_impl();
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return mProvider.onTouchEvent_impl(ev);
    }

    @Override
    public boolean onTrackballEvent(MotionEvent ev) {
        return mProvider.onTrackballEvent_impl(ev);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return mProvider.onKeyDown_impl(keyCode, event);
    }

    @Override
    public void onFinishInflate() {
        mProvider.onFinishInflate_impl();
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        return mProvider.dispatchKeyEvent_impl(event);
    }

    @Override
    public void setEnabled(boolean enabled) {
        mProvider.setEnabled_impl(enabled);
    }

    private class SuperProvider implements ViewProvider {
        @Override
        public void onAttachedToWindow_impl() {
            MediaController2.super.onAttachedToWindow();
        }

        @Override
        public void onDetachedFromWindow_impl() {
            MediaController2.super.onDetachedFromWindow();
        }

        @Override
        public void onLayout_impl(boolean changed, int left, int top, int right, int bottom) {
            MediaController2.super.onLayout(changed, left, top, right, bottom);
        }

        @Override
        public void draw_impl(Canvas canvas) {
            MediaController2.super.draw(canvas);
        }

        @Override
        public CharSequence getAccessibilityClassName_impl() {
            return MediaController2.super.getAccessibilityClassName();
        }

        @Override
        public boolean onTouchEvent_impl(MotionEvent ev) {
            return MediaController2.super.onTouchEvent(ev);
        }

        @Override
        public boolean onTrackballEvent_impl(MotionEvent ev) {
            return MediaController2.super.onTrackballEvent(ev);
        }

        @Override
        public boolean onKeyDown_impl(int keyCode, KeyEvent event) {
            return MediaController2.super.onKeyDown(keyCode, event);
        }

        @Override
        public void onFinishInflate_impl() {
            MediaController2.super.onFinishInflate();
        }

        @Override
        public boolean dispatchKeyEvent_impl(KeyEvent event) {
            return MediaController2.super.dispatchKeyEvent(event);
        }

        @Override
        public void setEnabled_impl(boolean enabled) {
            MediaController2.super.setEnabled(enabled);
        }
    }
}
+56 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.update;

import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;

/**
 * @hide
 */
public final class ApiLoader {
    private static Object sMediaLibrary;

    private static final String UPDATE_PACKAGE = "com.android.media.update";
    private static final String UPDATE_CLASS = "com.android.media.update.ApiFactory";
    private static final String UPDATE_METHOD = "initialize";

    private ApiLoader() { }

    public static StaticProvider getProvider(Context context) {
        try {
            return (StaticProvider) getMediaLibraryImpl(context);
        } catch (NameNotFoundException | ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }

    // TODO This method may do I/O; Ensure it does not violate (emit warnings in) strict mode.
    private static synchronized Object getMediaLibraryImpl(Context appContext)
            throws NameNotFoundException, ReflectiveOperationException {
        if (sMediaLibrary != null) return sMediaLibrary;

        // TODO Dynamically find the package name
        Context libContext = appContext.createPackageContext(UPDATE_PACKAGE,
                Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
        sMediaLibrary = libContext.getClassLoader()
                .loadClass(UPDATE_CLASS)
                .getMethod(UPDATE_METHOD, Context.class)
                .invoke(null, appContext);
        return sMediaLibrary;
    }
}
+55 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.update;

import android.annotation.SystemApi;
import android.media.session.MediaController;
import android.view.View;
import android.view.View.OnClickListener;

/**
 * Interface for connecting the public API to an updatable implementation.
 *
 * Each instance object is connected to one corresponding updatable object which implements the
 * runtime behavior of that class. There should a corresponding provider method for all public
 * methods.
 *
 * All methods behave as per their namesake in the public API.
 *
 * @see android.widget.MediaController2
 *
 * @hide
 */
// TODO @SystemApi
public interface MediaController2Provider extends ViewProvider {
    void setController_impl(MediaController controller);
    void setAnchorView_impl(View view);
    void show_impl();
    void show_impl(int timeout);
    boolean isShowing_impl();
    void hide_impl();
    void setPrevNextListeners_impl(OnClickListener next, OnClickListener prev);
    void showCCButton_impl();
    boolean isPlaying_impl();
    int getCurrentPosition_impl();
    int getBufferPercentage_impl();
    boolean canPause_impl();
    boolean canSeekBackward_impl();
    boolean canSeekForward_impl();
    void showSubtitle_impl();
    void hideSubtitle_impl();
}
+34 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.update;

import android.annotation.SystemApi;
import android.widget.MediaController2;

/**
 * Interface for connecting the public API to an updatable implementation.
 *
 * This interface provides access to constructors and static methods that are otherwise not directly
 * accessible via an implementation object.
 *
 * @hide
 */
// TODO @SystemApi
public interface StaticProvider {
    MediaController2Provider createMediaController2(
            MediaController2 instance, ViewProvider superProvider);
}
+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.update;

import android.annotation.SystemApi;
import android.graphics.Canvas;
import android.view.KeyEvent;
import android.view.MotionEvent;

/**
 * Interface for connecting the public API to an updatable implementation.
 *
 * Each instance object is connected to one corresponding updatable object which implements the
 * runtime behavior of that class. There should a corresponding provider method for all public
 * methods.
 *
 * All methods behave as per their namesake in the public API.
 *
 * @see android.view.View
 *
 * @hide
 */
// TODO @SystemApi
public interface ViewProvider {
    // TODO Add more (all?) methods from View
    void onAttachedToWindow_impl();
    void onDetachedFromWindow_impl();
    void onLayout_impl(boolean changed, int left, int top, int right, int bottom);
    void draw_impl(Canvas canvas);
    CharSequence getAccessibilityClassName_impl();
    boolean onTouchEvent_impl(MotionEvent ev);
    boolean onTrackballEvent_impl(MotionEvent ev);
    boolean onKeyDown_impl(int keyCode, KeyEvent event);
    void onFinishInflate_impl();
    boolean dispatchKeyEvent_impl(KeyEvent event);
    void setEnabled_impl(boolean enabled);
}