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

Commit cfa03706 authored by Christofer Åkersten's avatar Christofer Åkersten
Browse files

Initial commit of updatable media API

Test: Created instance & called method
Change-Id: I85f6ea946ef7886abe496b7a851d5b6d50e235b5
parent c0fec9c4
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);
}