Commit 93ee1837 authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

[Media Session] [1/4] Move MediaMetadata to service

This CL moves the MediaMetadata and MediaImage mojo types
from Blink to the Media Session service along with their
mapped types in content.

This is the first of four parts.

BUG=875004

Change-Id: Ie862229bbeb474a60ccc4d2f82d8c4e1f8017b74
Reviewed-on: https://chromium-review.googlesource.com/c/1227401Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605481}
parent 42840420
......@@ -32,6 +32,7 @@ _typemap_imports = [
"//services/audio/public/cpp/typemaps.gni",
"//services/device/public/mojom/typemaps.gni",
"//services/identity/public/cpp/typemaps.gni",
"//services/media_session/public/cpp/typemaps.gni",
"//services/network/public/cpp/typemaps.gni",
"//services/preferences/public/cpp/typemaps.gni",
"//services/proxy_resolver/public/cpp/typemaps.gni",
......
......@@ -58,6 +58,7 @@ service_test("services_unittests") {
deps += [
"//services/data_decoder/public/cpp/android:safe_json_java",
"//services/device:java",
"//services/media_session/public/cpp/android:media_session_java",
# Some tests make network requests.
"//net/android:net_java",
......
include_rules = [
"+jni",
"+ui/gfx",
]
......@@ -6,15 +6,24 @@ component("cpp") {
output_name = "media_session_cpp"
sources = [
"media_metadata.cc",
"media_metadata.h",
"switches.cc",
"switches.h",
]
deps = [
"//base",
"//ui/gfx/geometry",
"//url",
]
configs += [ "//build/config/compiler:wexit_time_destructors" ]
if (is_android) {
sources += [ "media_metadata_android.cc" ]
deps += [ "android:media_session_jni_headers" ]
}
defines = [ "IS_MEDIA_SESSION_CPP_IMPL" ]
}
per-file *_mojom_traits*.*=set noparent
per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
per-file *.typemap=set noparent
per-file *.typemap=file://ipc/SECURITY_OWNERS
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/rules.gni")
_jni_sources =
[ "java/src/org/chromium/services/media_session/MediaMetadata.java" ]
generate_jni("media_session_jni_headers") {
sources = _jni_sources
jni_package = "media_metadata"
}
if (current_toolchain == default_toolchain) {
android_library("media_session_java") {
deps = [
"//base:base_java",
]
java_files = _jni_sources
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.services.media_session;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import java.util.ArrayList;
import java.util.List;
/**
* The MediaMetadata class carries information related to a media session. It is
* the Java counterpart of media_session::MediaMetadata.
*/
@JNINamespace("media_session")
public final class MediaMetadata {
/**
* The MediaImage class carries the artwork information in MediaMetadata. It is the Java
* counterpart of media_session::MediaMetadata::MediaImage.
*/
public static final class MediaImage {
@NonNull
private String mSrc;
private String mType;
@NonNull
private List<Rect> mSizes = new ArrayList<Rect>();
/**
* Creates a new MediaImage.
*/
public MediaImage(@NonNull String src, @NonNull String type, @NonNull List<Rect> sizes) {
mSrc = src;
mType = type;
mSizes = sizes;
}
/**
* @return The URL of this MediaImage.
*/
@NonNull
public String getSrc() {
return mSrc;
}
/**
* @return The MIME type of this MediaImage.
*/
public String getType() {
return mType;
}
/**
* @return The hinted sizes of this MediaImage.
*/
public List<Rect> getSizes() {
return mSizes;
}
/**
* Sets the URL of this MediaImage.
*/
public void setSrc(@NonNull String src) {
mSrc = src;
}
/**
* Sets the MIME type of this MediaImage.
*/
public void setType(@NonNull String type) {
mType = type;
}
/**
* Sets the sizes of this MediaImage.
*/
public void setSizes(@NonNull List<Rect> sizes) {
mSizes = sizes;
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof MediaImage)) return false;
MediaImage other = (MediaImage) obj;
return TextUtils.equals(mSrc, other.mSrc) && TextUtils.equals(mType, other.mType)
&& mSizes.equals(other.mSizes);
}
/**
* @return The hash code of this {@link MediaImage}. The method uses the same algorithm in
* {@link java.util.List} for combinine hash values.
*/
@Override
public int hashCode() {
int result = mSrc.hashCode();
result = 31 * result + mType.hashCode();
result = 31 * result + mSizes.hashCode();
return result;
}
}
@NonNull
private String mTitle;
@NonNull
private String mArtist;
@NonNull
private String mAlbum;
@NonNull
private List<MediaImage> mArtwork = new ArrayList<MediaImage>();
/**
* Returns the title associated with the media session.
*/
public String getTitle() {
return mTitle;
}
/**
* Returns the artist name associated with the media session.
*/
public String getArtist() {
return mArtist;
}
/**
* Returns the album name associated with the media session.
*/
public String getAlbum() {
return mAlbum;
}
public List<MediaImage> getArtwork() {
return mArtwork;
}
/**
* Sets the title associated with the media session.
* @param title The title to use for the media session.
*/
public void setTitle(@NonNull String title) {
mTitle = title;
}
/**
* Sets the arstist name associated with the media session.
* @param arstist The artist name to use for the media session.
*/
public void setArtist(@NonNull String artist) {
mArtist = artist;
}
/**
* Sets the album name associated with the media session.
* @param album The album name to use for the media session.
*/
public void setAlbum(@NonNull String album) {
mAlbum = album;
}
/**
* Create a new {@link MediaImage} from the C++ code, and add it to the Metadata.
* @param src The URL of the image.
* @param type The MIME type of the image.
* @param flattenedSizes The flattened array of image sizes. In native code, it is of type
* `std::vector<gfx::Size>` before flattening.
*/
@CalledByNative
private void createAndAddMediaImage(String src, String type, int[] flattenedSizes) {
assert(flattenedSizes.length % 2) == 0;
List<Rect> sizes = new ArrayList<Rect>();
for (int i = 0; (i + 1) < flattenedSizes.length; i += 2) {
sizes.add(new Rect(0, 0, flattenedSizes[i], flattenedSizes[i + 1]));
}
mArtwork.add(new MediaImage(src, type, sizes));
}
/**
* Creates a new MediaMetadata from the C++ code. This is exactly like the
* constructor below apart that it can be called by native code.
*/
@CalledByNative
private static MediaMetadata create(String title, String artist, String album) {
return new MediaMetadata(title, artist, album);
}
/**
* Creates a new MediaMetadata.
*/
public MediaMetadata(@NonNull String title, @NonNull String artist, @NonNull String album) {
mTitle = title;
mArtist = artist;
mAlbum = album;
}
/**
* Comparing MediaMetadata is expensive and should be used sparingly
*/
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof MediaMetadata)) return false;
MediaMetadata other = (MediaMetadata) obj;
return TextUtils.equals(mTitle, other.mTitle) && TextUtils.equals(mArtist, other.mArtist)
&& TextUtils.equals(mAlbum, other.mAlbum) && mArtwork.equals(other.mArtwork);
}
/**
* @return The hash code of this {@link MediaMetadata}. The method uses the same algorithm in
* {@link java.util.List} for combinine hash values.
*/
@Override
public int hashCode() {
int result = mTitle.hashCode();
result = 31 * result + mArtist.hashCode();
result = 31 * result + mAlbum.hashCode();
result = 31 * result + mArtwork.hashCode();
return result;
}
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/media_session/public/cpp/media_metadata.h"
#include <algorithm>
#include <iterator>
namespace media_session {
MediaMetadata::MediaImage::MediaImage() = default;
MediaMetadata::MediaImage::MediaImage(const MediaImage& other) = default;
MediaMetadata::MediaImage::~MediaImage() = default;
bool MediaMetadata::MediaImage::operator==(
const MediaMetadata::MediaImage& other) const {
return src == other.src && type == other.type && sizes == other.sizes;
}
MediaMetadata::MediaMetadata() = default;
MediaMetadata::~MediaMetadata() = default;
MediaMetadata::MediaMetadata(const MediaMetadata& other) = default;
bool MediaMetadata::operator==(const MediaMetadata& other) const {
return title == other.title && artist == other.artist &&
album == other.album && artwork == other.artwork;
}
bool MediaMetadata::operator!=(const MediaMetadata& other) const {
return !(*this == other);
}
} // namespace media_session
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_MEDIA_SESSION_PUBLIC_CPP_MEDIA_METADATA_H_
#define SERVICES_MEDIA_SESSION_PUBLIC_CPP_MEDIA_METADATA_H_
#include <vector>
#include "base/component_export.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
#if defined(OS_ANDROID)
#include <jni.h>
#include "base/android/scoped_java_ref.h"
#endif // defined(OS_ANDROID)
namespace media_session {
// The MediaMetadata is a structure carrying information associated to a
// MediaSession.
struct COMPONENT_EXPORT(MEDIA_SESSION_CPP) MediaMetadata {
// Structure representing an MediaImage as per the MediaSession API, see:
// https://wicg.github.io/mediasession/#dictdef-mediaimage
struct COMPONENT_EXPORT(MEDIA_SESSION_CPP) MediaImage {
MediaImage();
MediaImage(const MediaImage& other);
~MediaImage();
bool operator==(const MediaImage& other) const;
// MUST be a valid url. If an icon doesn't have a valid URL, it will not be
// successfully parsed, thus will not be represented in the Manifest.
GURL src;
// Empty if the parsing failed or the field was not present. The type can be
// any string and doesn't have to be a valid image MIME type at this point.
// It is up to the consumer of the object to check if the type matches a
// supported type.
base::string16 type;
// Empty if the parsing failed, the field was not present or empty.
// The special value "any" is represented by gfx::Size(0, 0).
std::vector<gfx::Size> sizes;
};
MediaMetadata();
~MediaMetadata();
MediaMetadata(const MediaMetadata& other);
bool operator==(const MediaMetadata& other) const;
bool operator!=(const MediaMetadata& other) const;
#if defined(OS_ANDROID)
// Creates a Java MediaMetadata instance and returns the JNI ref.
base::android::ScopedJavaLocalRef<jobject> CreateJavaObject(JNIEnv* env);
#endif
// Title associated to the MediaSession.
base::string16 title;
// Artist associated to the MediaSession.
base::string16 artist;
// Album associated to the MediaSession.
base::string16 album;
// Artwork associated to the MediaSession.
std::vector<MediaImage> artwork;
};
} // namespace media_session
#endif // SERVICES_MEDIA_SESSION_PUBLIC_CPP_MEDIA_METADATA_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/media_session/public/cpp/media_metadata.h"
#include <string>
#include <vector>
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "jni/MediaMetadata_jni.h"
using base::android::ScopedJavaLocalRef;
namespace media_session {
namespace {
std::vector<int> GetFlattenedSizeArray(const std::vector<gfx::Size>& sizes) {
std::vector<int> flattened_array;
flattened_array.reserve(2 * sizes.size());
for (const auto& size : sizes) {
flattened_array.push_back(size.width());
flattened_array.push_back(size.height());
}
return flattened_array;
}
} // anonymous namespace
base::android::ScopedJavaLocalRef<jobject> MediaMetadata::CreateJavaObject(
JNIEnv* env) {
ScopedJavaLocalRef<jstring> j_title(
base::android::ConvertUTF16ToJavaString(env, title));
ScopedJavaLocalRef<jstring> j_artist(
base::android::ConvertUTF16ToJavaString(env, artist));
ScopedJavaLocalRef<jstring> j_album(
base::android::ConvertUTF16ToJavaString(env, album));
ScopedJavaLocalRef<jobject> j_metadata =
Java_MediaMetadata_create(env, j_title, j_artist, j_album);
for (const auto& image : artwork) {
std::string src = image.src.spec();
ScopedJavaLocalRef<jstring> j_src(
base::android::ConvertUTF8ToJavaString(env, src));
ScopedJavaLocalRef<jstring> j_type(
base::android::ConvertUTF16ToJavaString(env, image.type));
ScopedJavaLocalRef<jintArray> j_sizes(
base::android::ToJavaIntArray(env, GetFlattenedSizeArray(image.sizes)));
Java_MediaMetadata_createAndAddMediaImage(env, j_metadata, j_src, j_type,
j_sizes);
}
return j_metadata;
}
} // namespace media_session
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
mojom = "//services/media_session/public/mojom/media_session.mojom"
public_headers = [ "//services/media_session/public/cpp/media_metadata.h" ]
traits_headers =
[ "//services/media_session/public/cpp/media_session_mojom_traits.h" ]
public_deps = [
"//services/media_session/public/cpp",
]
deps = [
"//ui/gfx/geometry/mojo:struct_traits",
]
type_mappings = [
"media_session.mojom.MediaImage=media_session::MediaMetadata::MediaImage",
"media_session.mojom.MediaMetadata=media_session::MediaMetadata",
]
sources = [
"//services/media_session/public/cpp/media_session_mojom_traits.cc",
"//services/media_session/public/cpp/media_session_mojom_traits.h",
]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/media_session/public/cpp/media_session_mojom_traits.h"
#include "mojo/public/cpp/base/string16_mojom_traits.h"
#include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
#include "url/mojom/url_gurl_mojom_traits.h"
namespace mojo {
// static
bool StructTraits<media_session::mojom::MediaImageDataView,
media_session::MediaMetadata::MediaImage>::
Read(media_session::mojom::MediaImageDataView data,
media_session::MediaMetadata::MediaImage* out) {
if (!data.ReadSrc(&out->src))
return false;
if (!data.ReadType(&out->type))
return false;
if (!data.ReadSizes(&out->sizes))
return false;
return true;
}
// static
bool StructTraits<media_session::mojom::MediaMetadataDataView,
media_session::MediaMetadata>::
Read(media_session::mojom::MediaMetadataDataView data,
media_session::MediaMetadata* out) {
if (!data.ReadTitle(&out->title))
return false;
if (!data.ReadArtist(&out->artist))
return false;
if (!data.ReadAlbum(&out->album))
return false;
if (!data.ReadArtwork(&out->artwork))
return false;
return true;
}
} // namespace mojo
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_MEDIA_SESSION_PUBLIC_CPP_MEDIA_SESSION_MOJOM_TRAITS_H_
#define SERVICES_MEDIA_SESSION_PUBLIC_CPP_MEDIA_SESSION_MOJOM_TRAITS_H_
#include "services/media_session/public/mojom/media_session.mojom.h"
namespace mojo {
template <>
struct StructTraits<media_session::mojom::MediaImageDataView,
media_session::MediaMetadata::MediaImage> {
static const GURL& src(
const media_session::MediaMetadata::MediaImage& image) {
return image.src;
}
static const base::string16& type(
const media_session::MediaMetadata::MediaImage& image) {
return image.type;
}
static const std::vector<gfx::Size>& sizes(
const media_session::MediaMetadata::MediaImage& image) {
return image.sizes;
}
static bool Read(media_session::mojom::MediaImageDataView data,
media_session::MediaMetadata::MediaImage* out);
};
template <>
struct StructTraits<media_session::mojom::MediaMetadataDataView,
media_session::MediaMetadata> {
static const base::string16& title(
const media_session::MediaMetadata& metadata) {
return metadata.title;
}
static const base::string16& artist(
const media_session::MediaMetadata& metadata) {
return metadata.artist;
}
static const base::string16& album(
const media_session::MediaMetadata& metadata) {
return metadata.album;
}
static const std::vector<media_session::MediaMetadata::MediaImage>& artwork(
const media_session::MediaMetadata& metadata) {
return metadata.artwork;
}
static bool Read(media_session::mojom::MediaMetadataDataView data,
media_session::MediaMetadata* out);
};
} // namespace mojo
#endif // SERVICES_MEDIA_SESSION_PUBLIC_CPP_MEDIA_SESSION_MOJOM_TRAITS_H_
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
typemaps = [ "//services/media_session/public/cpp/media_session.typemap" ]
......@@ -4,10 +4,7 @@
import("//mojo/public/tools/bindings/mojom.gni")
mojom_component("mojom") {
output_prefix = "media_session_public_mojom"
macro_prefix = "MEDIA_SESSION_PUBLIC_MOJOM"
mojom("mojom") {
sources = [
"audio_focus.mojom",
"constants.mojom",
......@@ -17,5 +14,7 @@ mojom_component("mojom") {
public_deps = [
"//mojo/public/mojom/base",
"//ui/gfx/geometry/mojo",
"//url/mojom:url_mojom_gurl",
]
}
......@@ -4,6 +4,10 @@
module media_session.mojom;
import "mojo/public/mojom/base/string16.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
import "url/mojom/url.mojom";
// Next MinVersion: 2
[Extensible]
......@@ -12,6 +16,23 @@ enum MediaPlaybackState {
kPlaying,
};
// Album art in MediaMetadata
// Spec: https://wicg.github.io/mediasession/
struct MediaImage {
url.mojom.Url src;
mojo_base.mojom.String16 type;
array<gfx.mojom.Size> sizes;
};
// MediaMetadata
// Spec: https://wicg.github.io/mediasession/
struct MediaMetadata {
mojo_base.mojom.String16 title;
mojo_base.mojom.String16 artist;
mojo_base.mojom.String16 album;
array<MediaImage> artwork;
};
// Contains state information about a MediaSession.
struct MediaSessionInfo {
[Extensible]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment