Skip to content

Commit

Permalink
New build target cobalt_shell_apk
Browse files Browse the repository at this point in the history
This new target generate CobaltShell.apk that has `dev.cobalt.coat`
as its package name, and include most of Cobalt's java code.

App starts from CobaltActivity now. CobaltActivity inherits from
ContentShellActivity now instead of GameActivity.

Remember to put treat_warnings_as_errors = false in gn args since
Chromium treats java warnings as errors and we have many.

There are many TODOs left in this CL and this is only to be served
as a prototype to unblock SbPlayer and JS injection.
  • Loading branch information
johnxwork committed Oct 24, 2024
1 parent 4572bcd commit c0db810
Show file tree
Hide file tree
Showing 97 changed files with 622 additions and 448 deletions.
2 changes: 1 addition & 1 deletion build/android/gyp/util/resource_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
'anim', 'animator', 'array', 'attr', 'bool', 'color', 'dimen', 'drawable',
'font', 'fraction', 'id', 'integer', 'interpolator', 'layout', 'macro',
'menu', 'mipmap', 'plurals', 'raw', 'string', 'style', 'styleable',
'transition', 'xml'
'transition', 'xml', 'overlayable'
}

AAPT_IGNORE_PATTERN = ':'.join([
Expand Down
2 changes: 2 additions & 0 deletions cobalt/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ group("gn_all") {
deps = [ "//starboard($starboard_toolchain)" ]
if (!is_android) {
deps += [ ":cobalt" ]
} else {
deps += [ "android:cobalt_shell_apk" ]
}
}

Expand Down
153 changes: 153 additions & 0 deletions cobalt/android/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//third_party/icu/config.gni")

cobalt_shell_manifest =
"$target_gen_dir/cobalt_shell_test_manifest/AndroidManifest.xml"

android_resources("cobalt_shell_java_resources") {
testonly = true
sources = [
"apk/app/src/main/res/values/overlayable.xml",
"apk/app/src/main/res/values/styles.xml",
"apk/app/src/main/res/values/ids.xml",
"apk/app/src/main/res/values/colors.xml",
"apk/app/src/main/res/values/strings.xml",
"apk/app/src/main/res/values/rro_variables.xml",
"apk/app/src/main/res/layout/coat_error_dialog.xml",
"apk/app/src/app/res/mipmap-mdpi/ic_app.png",
"apk/app/src/app/res/mipmap-xhdpi/ic_app.png",
"apk/app/src/app/res/mipmap-hdpi/ic_app.png",
"apk/app/src/app/res/values/strings.xml",
"apk/app/src/app/res/drawable-xhdpi/app_banner.png",
"apk/app/src/app/res/mipmap-xxhdpi/ic_app.png",
]
#TODO(b/375037287): use Widget.Leanback.ErrorMessageStyle
#deps = [
# "//third_party/androidx:androidx_leanback_leanback_java",
#]
}

jinja_template("cobalt_shell_manifest") {
testonly = true
input = "apk/app/src/app/AndroidManifest.xml.jinja2"
output = cobalt_shell_manifest
variables = [ "manifest_package=dev.cobalt.coat" ]
}


android_library("cobalt_shell_apk_java") {
testonly = true
resources_package = "dev.cobalt.coat"
deps = [
"//base:base_java",
"//content/shell/android:content_shell_apk_java",
":cobalt_shell_java_resources",
"//third_party/androidx:androidx_annotation_annotation_java",
"//ui/android:ui_no_recycler_view_java",
]
sources = [
"apk/app/src/main/java/dev/cobalt/coat/VolumeStateReceiver.java",
"apk/app/src/app/java/dev/cobalt/app/CobaltApplication.java",
"apk/app/src/app/java/dev/cobalt/app/MainActivity.java",
"apk/app/src/main/java/dev/cobalt/coat/ArtworkDownloader.java",
"apk/app/src/main/java/dev/cobalt/coat/ArtworkDownloaderDefault.java",
"apk/app/src/main/java/dev/cobalt/coat/ArtworkLoader.java",
"apk/app/src/main/java/dev/cobalt/coat/CaptionSettings.java",
"apk/app/src/main/java/dev/cobalt/coat/CobaltActivity.java",
"apk/app/src/main/java/dev/cobalt/coat/CobaltHttpHelper.java",
# "apk/app/src/main/java/dev/cobalt/coat/CobaltMediaSession.java",
"apk/app/src/main/java/dev/cobalt/coat/CobaltService.java",
"apk/app/src/main/java/dev/cobalt/coat/CobaltSystemConfigChangeReceiver.java",
"apk/app/src/main/java/dev/cobalt/coat/CobaltTextToSpeechHelper.java",
"apk/app/src/main/java/dev/cobalt/coat/CrashContextUpdateHandler.java",
"apk/app/src/main/java/dev/cobalt/coat/ErrorDialog.java",
"apk/app/src/main/java/dev/cobalt/coat/MediaImage.java",
"apk/app/src/main/java/dev/cobalt/coat/NetworkStatus.java",
"apk/app/src/main/java/dev/cobalt/coat/NullCobaltFactory.java",
"apk/app/src/main/java/dev/cobalt/coat/PlatformError.java",
"apk/app/src/main/java/dev/cobalt/coat/ResourceOverlay.java",
# "apk/app/src/main/java/dev/cobalt/coat/AdvertisingId.java",
"apk/app/src/main/java/dev/cobalt/coat/StarboardBridge.java",
"apk/app/src/main/java/dev/cobalt/libraries/services/clientloginfo/ClientLogInfo.java",
"apk/app/src/main/java/dev/cobalt/libraries/services/clientloginfo/ClientLogInfoModule.java",
# "apk/app/src/main/java/dev/cobalt/media/AudioOutputManager.java",
"apk/app/src/main/java/dev/cobalt/media/AudioTrackBridge.java",
"apk/app/src/main/java/dev/cobalt/media/Log.java",
"apk/app/src/main/java/dev/cobalt/media/MediaCodecBridge.java",
"apk/app/src/main/java/dev/cobalt/media/MediaCodecStatus.java",
"apk/app/src/main/java/dev/cobalt/media/MediaCodecBridgeBuilder.java",
"apk/app/src/main/java/dev/cobalt/media/MediaCodecCapabilitiesLogger.java",
"apk/app/src/main/java/dev/cobalt/media/MediaCodecUtil.java",
"apk/app/src/main/java/dev/cobalt/media/MediaDrmBridge.java",
"apk/app/src/main/java/dev/cobalt/media/MediaFormatBuilder.java",
"apk/app/src/main/java/dev/cobalt/media/VideoFrameReleaseTimeHelper.java",
"apk/app/src/main/java/dev/cobalt/media/VideoSurfaceTexture.java",
"apk/app/src/main/java/dev/cobalt/media/VideoSurfaceView.java",
"apk/app/src/main/java/dev/cobalt/media/VideoDecoderCache.java",
# "apk/app/src/main/java/dev/cobalt/storage/CobaltStorageLoader.java",
# "apk/app/src/main/java/dev/cobalt/storage/StorageProto.java",
"apk/app/src/main/java/dev/cobalt/util/DisplayUtil.java",
"apk/app/src/main/java/dev/cobalt/util/Holder.java",
"apk/app/src/main/java/dev/cobalt/util/IsEmulator.java",
"apk/app/src/main/java/dev/cobalt/util/SynchronizedHolder.java",
"apk/app/src/main/java/dev/cobalt/util/Log.java",
"apk/app/src/main/java/dev/cobalt/util/SystemPropertiesHelper.java",
"apk/app/src/main/java/dev/cobalt/util/UsedByNative.java",
]
}

android_assets("cobalt_shell_assets") {
testonly = true
sources = [
"apk/app/src/app/assets/test/not_empty.txt",
"apk/app/src/app/assets/web/cobalt_blue_splash_screen.html",
"apk/app/src/app/assets/web/link_android_splash_screen.html",
"apk/app/src/app/assets/web/cobalt_blue_splash_screen.css",
"apk/app/src/app/assets/web/cobalt_logo_1024.png",
"apk/app/src/app/assets/not_empty.txt",
]
disable_compression = true
}

template("content_shell_apk_tmpl") {
_target_type = invoker.target_type
target(_target_type, target_name) {
forward_variables_from(invoker, "*")
testonly = true
if (!defined(deps)) {
deps = []
}
deps += [
"//content/shell/android:content_shell_apk_java",
"//content/shell/android:content_shell_assets",
"//content/shell/android:content_shell_java",
"//base:base_java_test_support",
"//components/crash/android:java",
"//components/crash/core/app:chrome_crashpad_handler_named_as_so",
"//components/metrics:metrics_java",
"//content/public/android:content_java",
"//content/public/test/android:android_test_message_pump_support_java",
"//media/capture/video/android:capture_java",
"//net/android:net_java",
"//services/shape_detection:shape_detection_java",
"//third_party/mesa_headers",
"//ui/android:ui_java",
]
loadable_modules = [ "$root_out_dir/libchrome_crashpad_handler.so" ]
}
}

content_shell_apk_tmpl("cobalt_shell_apk") {
target_type = "android_apk"
apk_name = "CobaltShell"
android_manifest = cobalt_shell_manifest
android_manifest_dep = ":cobalt_shell_manifest"
deps = [
":cobalt_shell_apk_java",
":cobalt_shell_assets",
":cobalt_shell_java_resources",
]
shared_libraries = [ "//content/shell/android:libcontent_shell_content_view" ]
command_line_flags_file = "content-shell-command-line"
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
126 changes: 126 additions & 0 deletions cobalt/android/apk/app/src/app/AndroidManifest.xml.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 The Cobalt Authors. All Rights Reserved.
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.
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="{{ manifest_package }}">

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- This is needed when targeting API 28+ to use foreground services -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />

<!-- https://iabtechlab.com/OTT-IFA, AdvertisingIdClient.Info.getId() -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

{% block extra_uses_permissions %}
{% endblock %}

<application android:name="dev.cobalt.app.CobaltApplication"
android:icon="@mipmap/app_icon"
android:zygotePreloadName="org.chromium.content_public.app.ZygotePreload"
android:label="{% block application_label %}Cobalt Shell{% endblock %}">
<activity android:name="dev.cobalt.app.MainActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|uiMode"
android:windowSoftInputMode="adjustResize"
android:hardwareAccelerated="true"
android:exported="true">
<meta-data android:name="cobalt.APP_URL" android:value="https://www.youtube.com/tv"/>
<meta-data android:name="cobalt.EVERGREEN_LITE" android:value="false"/>
<meta-data android:name="android.app.lib_name" android:value="cobalt"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="youtube.com"/>
<data android:host="www.youtube.com"/>
<data android:host="m.youtube.com"/>
<data android:host="youtu.be"/>
<data android:pathPattern=".*"/>
</intent-filter>
</activity>
<!-- The following service entries exist in order to allow us to
start more than one sandboxed process. -->

<!-- NOTE: If you change the values of "android:process" for any of the below services,
you also need to update kHelperProcessExecutableName in chrome_constants.cc. -->
{% set num_sandboxed_services = 40 %}
<meta-data android:name="org.chromium.content.browser.NUM_SANDBOXED_SERVICES"
android:value="{{ num_sandboxed_services }}"/>
{% for i in range(num_sandboxed_services) %}
<service android:name="org.chromium.content.app.SandboxedProcessService{{ i }}"
android:process=":sandboxed_process{{ i }}"
{% if (i == 0) %}
android:useAppZygote="true"
{% endif %}
android:isolatedProcess="true"
android:exported="false" />
{% endfor %}

{% set num_privileged_services = 5 %}
<meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES"
android:value="{{ num_privileged_services }}"/>
{% for i in range(num_privileged_services) %}
<service android:name="org.chromium.content.app.PrivilegedProcessService{{ i }}"
android:process=":privileged_process{{ i }}"
android:isolatedProcess="false"
android:exported="false" />
{% endfor %}
<meta-data android:name="org.chromium.content.browser.SMART_CLIP_PROVIDER"
android:value="org.chromium.content.browser.SmartClipProvider" />

<service android:name="org.chromium.content_shell_apk.ChildProcessLauncherTestHelperService"
android:process=":ChildProcessLauncherHelper" />

<!-- The following entries are for ChildProcessLauncherTest. They should eventually be moved
to base. -->
{% set num_test_services = 2 %}
<meta-data android:name="org.chromium.content.browser.NUM_TEST_SERVICES"
android:value="{{ num_test_services }}"/>
{% for i in range(num_test_services) %}
<service android:name="org.chromium.content_shell_apk.TestChildProcessService{{ i }}"
android:process=":test_child_service_process{{ i }}"
android:isolatedProcess="true"
android:exported="false" />
{% endfor %}
{% block extra_application_definitions_for_test %}
{% endblock %}

</application>
{% block extra_root_definitions %}
{% endblock %}
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
package dev.cobalt.app;

import android.app.Application;
import android.content.Context;
import dev.cobalt.coat.StarboardBridge;

import org.chromium.content_shell_apk.ContentShellApplication;

/** Android Application hosting the Starboard application. */
public class CobaltApplication extends Application implements StarboardBridge.HostApplication {
public class CobaltApplication extends ContentShellApplication implements StarboardBridge.HostApplication {
StarboardBridge starboardBridge;

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import android.os.Looper;
import android.util.Pair;
import android.util.Size;
import androidx.annotation.NonNull;
import dev.cobalt.util.DisplayUtil;
import java.util.Locale;

Expand All @@ -31,9 +30,9 @@ public interface Callback {
void onArtworkLoaded(Bitmap bitmap);
}

@NonNull private volatile String requestedArtworkUrl = "";
@NonNull private volatile String currentArtworkUrl = "";
private volatile Bitmap currentArtwork = null;
private volatile String requestedArtworkUrl = "";
private volatile String currentArtworkUrl = "";
private volatile Bitmap currentArtwork;

private final Handler handler = new Handler(Looper.getMainLooper());
private final ArtworkDownloader artworkDownloader;
Expand All @@ -48,7 +47,7 @@ public ArtworkLoader(Callback callback, ArtworkDownloader artworkDownloader) {
* Returns a cached image if available. If not cached, returns null and starts downloading it in
* the background, and then when ready the callback will be called with the image.
*/
public synchronized Bitmap getOrLoadArtwork(MediaImage[] artwork) {
public Bitmap getOrLoadArtwork(MediaImage[] artwork) {
MediaImage image = getBestFitImage(artwork, DisplayUtil.getDisplaySize());
String url = (image == null) ? "" : image.src;

Expand Down
Loading

0 comments on commit c0db810

Please sign in to comment.