Commit c185420a authored by Becca Hughes's avatar Becca Hughes Committed by Commit Bot

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

This is a reland of 93ee1837

This includes a fix to //ash:ash_unittests which was throwing
a linker error which resulted in the original being reverted.

Original change's description:
> [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/1227401
> Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
> Reviewed-by: Daniel Cheng <dcheng@chromium.org>
> Reviewed-by: Ken Rockot <rockot@google.com>
> Commit-Queue: Becca Hughes <beccahughes@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#605481}

Bug: 875004
Change-Id: Id04143a89594a523f323ac16a54d93f1f2447367
Reviewed-on: https://chromium-review.googlesource.com/c/1318802Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Becca Hughes <beccahughes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612269}
parent 313debef
...@@ -1948,6 +1948,7 @@ test("ash_unittests") { ...@@ -1948,6 +1948,7 @@ test("ash_unittests") {
"//net:net", "//net:net",
"//services/catalog:lib", "//services/catalog:lib",
"//services/media_session/public/cpp/test:test_support", "//services/media_session/public/cpp/test:test_support",
"//services/media_session/public/mojom",
"//services/service_manager/public/cpp:service_test_support", "//services/service_manager/public/cpp:service_test_support",
"//services/ws:test_support", "//services/ws:test_support",
"//services/ws/public/cpp/input_devices:test_support", "//services/ws/public/cpp/input_devices:test_support",
......
...@@ -32,6 +32,7 @@ _typemap_imports = [ ...@@ -32,6 +32,7 @@ _typemap_imports = [
"//services/audio/public/cpp/typemaps.gni", "//services/audio/public/cpp/typemaps.gni",
"//services/device/public/mojom/typemaps.gni", "//services/device/public/mojom/typemaps.gni",
"//services/identity/public/cpp/typemaps.gni", "//services/identity/public/cpp/typemaps.gni",
"//services/media_session/public/cpp/typemaps.gni",
"//services/network/public/cpp/typemaps.gni", "//services/network/public/cpp/typemaps.gni",
"//services/preferences/public/cpp/typemaps.gni", "//services/preferences/public/cpp/typemaps.gni",
"//services/proxy_resolver/public/cpp/typemaps.gni", "//services/proxy_resolver/public/cpp/typemaps.gni",
......
...@@ -55,6 +55,7 @@ test("services_unittests") { ...@@ -55,6 +55,7 @@ test("services_unittests") {
deps += [ deps += [
"//services/data_decoder/public/cpp/android:safe_json_java", "//services/data_decoder/public/cpp/android:safe_json_java",
"//services/device:java", "//services/device:java",
"//services/media_session/public/cpp/android:media_session_java",
# Some tests make network requests. # Some tests make network requests.
"//net/android:net_java", "//net/android:net_java",
......
include_rules = [
"+jni",
"+ui/gfx",
]
...@@ -6,15 +6,24 @@ component("cpp") { ...@@ -6,15 +6,24 @@ component("cpp") {
output_name = "media_session_cpp" output_name = "media_session_cpp"
sources = [ sources = [
"media_metadata.cc",
"media_metadata.h",
"switches.cc", "switches.cc",
"switches.h", "switches.h",
] ]
deps = [ deps = [
"//base", "//base",
"//ui/gfx/geometry",
"//url",
] ]
configs += [ "//build/config/compiler:wexit_time_destructors" ] 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" ] 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 @@ ...@@ -4,10 +4,7 @@
import("//mojo/public/tools/bindings/mojom.gni") import("//mojo/public/tools/bindings/mojom.gni")
mojom_component("mojom") { mojom("mojom") {
output_prefix = "media_session_public_mojom"
macro_prefix = "MEDIA_SESSION_PUBLIC_MOJOM"
sources = [ sources = [
"audio_focus.mojom", "audio_focus.mojom",
"constants.mojom", "constants.mojom",
...@@ -17,5 +14,15 @@ mojom_component("mojom") { ...@@ -17,5 +14,15 @@ mojom_component("mojom") {
public_deps = [ public_deps = [
"//mojo/public/mojom/base", "//mojo/public/mojom/base",
"//ui/gfx/geometry/mojo",
"//url/mojom:url_mojom_gurl",
] ]
# The blink variant of the Device Service mojom are depended on by the
# blink platform target. All blink variant mojoms use WTF types, which are
# part of the blink platform component. In order to avoid a dependency cycle,
# these targets must be part of that component.
export_class_attribute_blink = "BLINK_PLATFORM_EXPORT"
export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1"
export_header_blink = "third_party/blink/public/platform/web_common.h"
} }
...@@ -4,7 +4,10 @@ ...@@ -4,7 +4,10 @@
module media_session.mojom; module media_session.mojom;
import "mojo/public/mojom/base/string16.mojom";
import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/time.mojom";
import "ui/gfx/geometry/mojo/geometry.mojom";
import "url/mojom/url.mojom";
// Next MinVersion: 2 // Next MinVersion: 2
...@@ -25,6 +28,23 @@ enum MediaSessionAction { ...@@ -25,6 +28,23 @@ enum MediaSessionAction {
kSeekForward, kSeekForward,
}; };
// 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. // Contains state information about a MediaSession.
struct MediaSessionInfo { struct MediaSessionInfo {
[Extensible] [Extensible]
......
...@@ -262,6 +262,7 @@ jumbo_component("platform") { ...@@ -262,6 +262,7 @@ jumbo_component("platform") {
visibility = [ visibility = [
"//components/pdf/common:interfaces_blink", "//components/pdf/common:interfaces_blink",
"//services/device/public/mojom:mojom_blink", "//services/device/public/mojom:mojom_blink",
"//services/media_session/public/mojom:mojom_blink",
"//third_party/blink/*", "//third_party/blink/*",
"//url/mojom:url_mojom_origin_blink", "//url/mojom:url_mojom_origin_blink",
"//url/mojom:url_mojom_gurl_blink", "//url/mojom:url_mojom_gurl_blink",
......
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