[Android] add runtime flag to determine if HCPP is supported. (#163004)
Developers will need to _conditionally_ use HCPP (or the framework will need to handle it automatically). This requires the ability to query at runtime whether HCPP mode is enabled + supported. Add a message channel to do so, and add the usage of this to the android_engine_test. Does not yet add any automatic selection. --------- Co-authored-by: Matan Lurey <matanlurey@users.noreply.github.com>
This commit is contained in:
parent
5e37c966c0
commit
9438fd4471
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:android_driver_extensions/extension.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
@ -14,7 +16,14 @@ import '../src/allow_list_devices.dart';
|
||||
|
||||
void main() async {
|
||||
ensureAndroidDevice();
|
||||
enableFlutterDriverExtension(commands: <CommandExtension>[nativeDriverCommands]);
|
||||
enableFlutterDriverExtension(
|
||||
handler: (String? command) async {
|
||||
return json.encode(<String, Object?>{
|
||||
'supported': await HybridAndroidViewController.checkIfSupported(),
|
||||
});
|
||||
},
|
||||
commands: <CommandExtension>[nativeDriverCommands],
|
||||
);
|
||||
|
||||
// Run on full screen.
|
||||
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:android_driver_extensions/native_driver.dart';
|
||||
import 'package:android_driver_extensions/skia_gold.dart';
|
||||
import 'package:flutter_driver/flutter_driver.dart';
|
||||
@ -43,6 +45,13 @@ void main() async {
|
||||
await flutterDriver.close();
|
||||
});
|
||||
|
||||
test('verify that HCPP is supported and enabled', () async {
|
||||
final Map<String, Object?> response =
|
||||
json.decode(await flutterDriver.requestData('')) as Map<String, Object?>;
|
||||
|
||||
expect(response['supported'], true);
|
||||
}, timeout: Timeout.none);
|
||||
|
||||
test('should screenshot an HCPP platform view', () async {
|
||||
await expectLater(
|
||||
nativeDriver.screenshot(),
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "flutter/fml/cpu_affinity.h"
|
||||
#include "flutter/fml/logging.h"
|
||||
#include "flutter/fml/make_copyable.h"
|
||||
@ -261,8 +262,6 @@ std::unique_ptr<AndroidShellHolder> AndroidShellHolder::Spawn(
|
||||
return std::make_unique<Rasterizer>(shell);
|
||||
};
|
||||
|
||||
// TODO(xster): could be worth tracing this to investigate whether
|
||||
// the IsolateConfiguration could be cached somewhere.
|
||||
auto config = BuildRunConfiguration(entrypoint, libraryUrl, entrypoint_args);
|
||||
if (!config) {
|
||||
// If the RunConfiguration was null, the kernel blob wasn't readable.
|
||||
@ -358,4 +357,8 @@ void AndroidShellHolder::UpdateDisplayMetrics() {
|
||||
shell_->OnDisplayUpdates(std::move(displays));
|
||||
}
|
||||
|
||||
bool AndroidShellHolder::IsSurfaceControlEnabled() {
|
||||
return GetPlatformView()->IsSurfaceControlEnabled();
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
@ -93,6 +93,8 @@ class AndroidShellHolder {
|
||||
|
||||
fml::WeakPtr<PlatformViewAndroid> GetPlatformView();
|
||||
|
||||
bool IsSurfaceControlEnabled();
|
||||
|
||||
Rasterizer::Screenshot Screenshot(Rasterizer::ScreenshotType type,
|
||||
bool base64_encode);
|
||||
|
||||
|
@ -365,6 +365,7 @@ public class FlutterEngine implements ViewUtils.DisplayUpdater {
|
||||
|
||||
PlatformViewsController2 platformViewsController2 = new PlatformViewsController2();
|
||||
platformViewsController2.setRegistry(platformViewsController.getRegistry());
|
||||
platformViewsController2.setFlutterJNI(flutterJNI);
|
||||
|
||||
flutterJNI.addEngineLifecycleListener(engineLifecycleListener);
|
||||
flutterJNI.setPlatformViewsController(platformViewsController);
|
||||
|
@ -1624,4 +1624,11 @@ public class FlutterJNI {
|
||||
}
|
||||
|
||||
private native boolean nativeShouldDisableAHB();
|
||||
|
||||
/** Whether the SurfaceControl swapchain required for hcpp is enabled and active. */
|
||||
public boolean IsSurfaceControlEnabled() {
|
||||
return nativeIsSurfaceControlEnabled(nativeShellHolderId);
|
||||
}
|
||||
|
||||
private native boolean nativeIsSurfaceControlEnabled(long nativeShellHolderId);
|
||||
}
|
||||
|
@ -79,6 +79,9 @@ public class PlatformViewsChannel2 {
|
||||
case "clearFocus":
|
||||
clearFocus(call, result);
|
||||
break;
|
||||
case "isSurfaceControlEnabled":
|
||||
isSurfaceControlEnabled(call, result);
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
@ -171,6 +174,11 @@ public class PlatformViewsChannel2 {
|
||||
result.error("error", detailedExceptionString(exception), null);
|
||||
}
|
||||
}
|
||||
|
||||
private void isSurfaceControlEnabled(
|
||||
@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
result.success(handler.isSurfaceControlEnabled());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -213,6 +221,9 @@ public class PlatformViewsChannel2 {
|
||||
|
||||
/** Clears the focus from the platform view with a give id if it is currently focused. */
|
||||
void clearFocus(int viewId);
|
||||
|
||||
/** Whether the SurfaceControl swapchain is enabled. */
|
||||
boolean isSurfaceControlEnabled();
|
||||
}
|
||||
|
||||
/** Request sent from Flutter to create a new platform view. */
|
||||
|
@ -27,6 +27,7 @@ import io.flutter.Log;
|
||||
import io.flutter.embedding.android.AndroidTouchProcessor;
|
||||
import io.flutter.embedding.android.FlutterView;
|
||||
import io.flutter.embedding.android.MotionEventTracker;
|
||||
import io.flutter.embedding.engine.FlutterJNI;
|
||||
import io.flutter.embedding.engine.FlutterOverlaySurface;
|
||||
import io.flutter.embedding.engine.dart.DartExecutor;
|
||||
import io.flutter.embedding.engine.mutatorsstack.*;
|
||||
@ -50,6 +51,7 @@ public class PlatformViewsController2 implements PlatformViewsAccessibilityDeleg
|
||||
private AndroidTouchProcessor androidTouchProcessor;
|
||||
private Context context;
|
||||
private FlutterView flutterView;
|
||||
private FlutterJNI flutterJNI = null;
|
||||
|
||||
@Nullable private TextInputPlugin textInputPlugin;
|
||||
|
||||
@ -77,6 +79,11 @@ public class PlatformViewsController2 implements PlatformViewsAccessibilityDeleg
|
||||
this.registry = (PlatformViewRegistryImpl) registry;
|
||||
}
|
||||
|
||||
/** Whether the SurfaceControl swapchain mode is enabled. */
|
||||
public void setFlutterJNI(FlutterJNI flutterJNI) {
|
||||
this.flutterJNI = flutterJNI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesVirtualDisplay(int id) {
|
||||
return false;
|
||||
@ -679,5 +686,13 @@ public class PlatformViewsController2 implements PlatformViewsAccessibilityDeleg
|
||||
}
|
||||
embeddedView.clearFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSurfaceControlEnabled() {
|
||||
if (flutterJNI == null) {
|
||||
return false;
|
||||
}
|
||||
return flutterJNI.IsSurfaceControlEnabled();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import androidx.annotation.Keep;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
// TODO(mattcarroll): re-evalute docs in this class and add nullability annotations.
|
||||
/**
|
||||
* Registry of backend textures used with a single {@link io.flutter.embedding.android.FlutterView}
|
||||
* instance. Entries may be embedded into the Flutter view using the <a
|
||||
|
@ -498,4 +498,9 @@ double PlatformViewAndroid::GetScaledFontSize(double unscaled_font_size,
|
||||
return jni_facade_->FlutterViewGetScaledFontSize(unscaled_font_size,
|
||||
configuration_id);
|
||||
}
|
||||
|
||||
bool PlatformViewAndroid::IsSurfaceControlEnabled() const {
|
||||
return android_use_new_platform_view_;
|
||||
}
|
||||
|
||||
} // namespace flutter
|
||||
|
@ -119,6 +119,9 @@ class PlatformViewAndroid final : public PlatformView {
|
||||
return platform_message_handler_;
|
||||
}
|
||||
|
||||
/// @brief Whether the SurfaceControl based swapchain is enabled and active.
|
||||
bool IsSurfaceControlEnabled() const;
|
||||
|
||||
private:
|
||||
const std::shared_ptr<PlatformViewAndroidJNI> jni_facade_;
|
||||
std::shared_ptr<AndroidContext> android_context_;
|
||||
|
@ -383,6 +383,12 @@ static void UpdateDisplayMetrics(JNIEnv* env,
|
||||
ANDROID_SHELL_HOLDER->UpdateDisplayMetrics();
|
||||
}
|
||||
|
||||
static bool IsSurfaceControlEnabled(JNIEnv* env,
|
||||
jobject jcaller,
|
||||
jlong shell_holder) {
|
||||
return ANDROID_SHELL_HOLDER->IsSurfaceControlEnabled();
|
||||
}
|
||||
|
||||
static jobject GetBitmap(JNIEnv* env, jobject jcaller, jlong shell_holder) {
|
||||
auto screenshot = ANDROID_SHELL_HOLDER->Screenshot(
|
||||
Rasterizer::ScreenshotType::UncompressedImage, false);
|
||||
@ -873,6 +879,11 @@ bool RegisterApi(JNIEnv* env) {
|
||||
.signature = "()Z",
|
||||
.fnPtr = reinterpret_cast<void*>(
|
||||
&impeller::android::ShadowRealm::ShouldDisableAHB),
|
||||
},
|
||||
{
|
||||
.name = "nativeIsSurfaceControlEnabled",
|
||||
.signature = "(J)Z",
|
||||
.fnPtr = reinterpret_cast<void*>(&IsSurfaceControlEnabled),
|
||||
}};
|
||||
|
||||
if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
|
||||
|
@ -1157,6 +1157,11 @@ class HybridAndroidViewController extends AndroidViewController {
|
||||
|
||||
final _AndroidViewControllerInternals _internals = _Hybrid2AndroidViewControllerInternals();
|
||||
|
||||
/// Perform a runtime check to determine if HCPP mode is supported on the
|
||||
/// current device.
|
||||
static Future<bool> checkIfSupported() =>
|
||||
_Hybrid2AndroidViewControllerInternals.checkIfSurfaceControlEnabled();
|
||||
|
||||
@override
|
||||
bool get _createRequiresSize => false;
|
||||
|
||||
@ -1440,7 +1445,18 @@ class _HybridAndroidViewControllerInternals extends _AndroidViewControllerIntern
|
||||
}
|
||||
}
|
||||
|
||||
// The HCPP platform view controller.
|
||||
//
|
||||
// This is only supported via an opt in on Impeller Android.
|
||||
class _Hybrid2AndroidViewControllerInternals extends _AndroidViewControllerInternals {
|
||||
// Determine if HCPP can be used.
|
||||
static Future<bool> checkIfSurfaceControlEnabled() async {
|
||||
return (await SystemChannels.platform_views_2.invokeMethod<bool>(
|
||||
'isSurfaceControlEnabled',
|
||||
<String, Object?>{},
|
||||
))!;
|
||||
}
|
||||
|
||||
@override
|
||||
int get textureId {
|
||||
throw UnimplementedError('Not supported for hybrid composition.');
|
||||
|
Loading…
x
Reference in New Issue
Block a user