mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-02-16 18:40:46 +00:00
Compare commits
339 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8f1f9325e | ||
|
|
658940d3fb | ||
|
|
51b4ca401e | ||
|
|
10e4ca4ef3 | ||
|
|
2bcc2bdfe5 | ||
|
|
6462b580bb | ||
|
|
b83d91c944 | ||
|
|
07f842bc9e | ||
|
|
3913e845fa | ||
|
|
09f0913974 | ||
|
|
aa9ca35115 | ||
|
|
010dfdf834 | ||
|
|
150fac9c09 | ||
|
|
ec3aef13d8 | ||
|
|
2b56005bd2 | ||
|
|
9bc893b6ad | ||
|
|
3feb92e788 | ||
|
|
1265952814 | ||
|
|
f5ad5d97db | ||
|
|
5ac0939731 | ||
|
|
b653694860 | ||
|
|
49051a5095 | ||
|
|
7734de6465 | ||
|
|
edac646434 | ||
|
|
51c7665fdc | ||
|
|
37545821fc | ||
|
|
8a1ed0f146 | ||
|
|
7a0228fb81 | ||
|
|
3aecf9e031 | ||
|
|
c2d4d221af | ||
|
|
53f89fbe22 | ||
|
|
eb5f7ef7af | ||
|
|
e2fc76d21d | ||
|
|
1754103175 | ||
|
|
dacd00708f | ||
|
|
a73129243c | ||
|
|
54a6aa9081 | ||
|
|
0fbb53c606 | ||
|
|
eb2e79977d | ||
|
|
b70a47f5e5 | ||
|
|
9d5ff72548 | ||
|
|
6b972b56a5 | ||
|
|
a80d30baf7 | ||
|
|
b9280e9a8e | ||
|
|
c6640d201c | ||
|
|
795fdc3605 | ||
|
|
05311da33d | ||
|
|
2e442cb1d1 | ||
|
|
fe322590cc | ||
|
|
6cf9b25c04 | ||
|
|
417babb3d4 | ||
|
|
bdaaa6f0c7 | ||
|
|
7e92dd7fe4 | ||
|
|
50601e24ed | ||
|
|
bfc3116661 | ||
|
|
264b6e54f2 | ||
|
|
1ed7ecc82f | ||
|
|
19b8032d06 | ||
|
|
1e254ea8f4 | ||
|
|
babfc99c35 | ||
|
|
5c802555a2 | ||
|
|
fbc41c9a4e | ||
|
|
1eca461cb1 | ||
|
|
ebd327c7a6 | ||
|
|
602febe876 | ||
|
|
84fcd3ae6a | ||
|
|
84296c6e1c | ||
|
|
6012e0ea8c | ||
|
|
9c76defad0 | ||
|
|
ffd6fab35c | ||
|
|
296f97f7ca | ||
|
|
9cbef34f29 | ||
|
|
7a65136d29 | ||
|
|
acaebea846 | ||
|
|
ce850ac12f | ||
|
|
a93422d3ed | ||
|
|
b2e605838e | ||
|
|
2e14002442 | ||
|
|
c743949df5 | ||
|
|
f207a3f6d1 | ||
|
|
d6211605a1 | ||
|
|
b16676b54a | ||
|
|
dc9bfe5189 | ||
|
|
80620ed4c6 | ||
|
|
76bd0ab696 | ||
|
|
e0914df58a | ||
|
|
20039a422e | ||
|
|
22b9c9ca68 | ||
|
|
0c546e35ec | ||
|
|
b70370ac09 | ||
|
|
aa10bb7dc5 | ||
|
|
c6100a9be1 | ||
|
|
529a2f7bf8 | ||
|
|
9ec7e916c5 | ||
|
|
982b36cf98 | ||
|
|
a73eab5e92 | ||
|
|
a8479ccb5f | ||
|
|
f55e4e0e01 | ||
|
|
d08c32ce04 | ||
|
|
1d599c5e60 | ||
|
|
e888ae59e4 | ||
|
|
951d544894 | ||
|
|
49898b34e1 | ||
|
|
3854a6a42e | ||
|
|
d4da5bc281 | ||
|
|
04954f5242 | ||
|
|
9fc5496526 | ||
|
|
e363d24b1c | ||
|
|
801f4027a2 | ||
|
|
c0dc344f76 | ||
|
|
b5b3d81f00 | ||
|
|
8dd8dbc1d1 | ||
|
|
8f31aa59a8 | ||
|
|
5b581b6c0f | ||
|
|
297ac64fde | ||
|
|
d4490f0e17 | ||
|
|
d04e7a3231 | ||
|
|
5b456aba27 | ||
|
|
0c065dcc1f | ||
|
|
531f73329d | ||
|
|
d6ba72032d | ||
|
|
bfdc7a2609 | ||
|
|
031abf03da | ||
|
|
6aac8e6be6 | ||
|
|
8ff93d21c3 | ||
|
|
6df3d0bc44 | ||
|
|
0b18e8fdb4 | ||
|
|
19d8ae0f78 | ||
|
|
d7ffb5dddc | ||
|
|
2859b73dfe | ||
|
|
6f9021a5e6 | ||
|
|
3bfeaefdbd | ||
|
|
db1eace975 | ||
|
|
cab0fa176e | ||
|
|
2f9ae107a2 | ||
|
|
18c93abcb3 | ||
|
|
bd64dfb661 | ||
|
|
82619063ee | ||
|
|
5dbf18d66e | ||
|
|
6a34ff2728 | ||
|
|
f7c7487756 | ||
|
|
f966cb4ca0 | ||
|
|
549563a3d2 | ||
|
|
c5f2a3f8fe | ||
|
|
81a3bbd5e8 | ||
|
|
1509a2a799 | ||
|
|
fc547b734f | ||
|
|
b3700b5a19 | ||
|
|
2b29682095 | ||
|
|
286094ee33 | ||
|
|
c7a061d24e | ||
|
|
4bdc2e0aba | ||
|
|
e69061082b | ||
|
|
1da2ec3cb1 | ||
|
|
8ffc3b80b2 | ||
|
|
08f8b6cb8e | ||
|
|
fb09c9692c | ||
|
|
4901b0c78f | ||
|
|
0a2117241f | ||
|
|
f352cfd15b | ||
|
|
ac7c5c1064 | ||
|
|
077cb2103d | ||
|
|
cdeda011a4 | ||
|
|
894c146988 | ||
|
|
61cc9e151f | ||
|
|
cfe4c9ff21 | ||
|
|
d4bd29b320 | ||
|
|
7f2f2056c3 | ||
|
|
4dd3b2cfb7 | ||
|
|
2e62ad0f00 | ||
|
|
41ef292b82 | ||
|
|
aa60671c88 | ||
|
|
f1ccba39e8 | ||
|
|
226e580a30 | ||
|
|
6f8e719200 | ||
|
|
c127af1e05 | ||
|
|
648904cc69 | ||
|
|
dc85ddb3f9 | ||
|
|
23a7d8555f | ||
|
|
bc9e250d34 | ||
|
|
2203186527 | ||
|
|
53d3d9ecb8 | ||
|
|
de549f67a1 | ||
|
|
755c41481a | ||
|
|
aebc2126bc | ||
|
|
f43547fb31 | ||
|
|
398e4df7cf | ||
|
|
ff68efc3f5 | ||
|
|
8ba2f51bda | ||
|
|
87b79b278b | ||
|
|
121e3ea9be | ||
|
|
ec6ed79ee1 | ||
|
|
ca125826a7 | ||
|
|
dd0aecf108 | ||
|
|
ef5cb2f0cd | ||
|
|
e5a7bb40e9 | ||
|
|
bfdda48fee | ||
|
|
ebea1bb5c1 | ||
|
|
14bc1552fc | ||
|
|
a5b80d3944 | ||
|
|
75d0eedc2b | ||
|
|
29ac7028fa | ||
|
|
8a63b61495 | ||
|
|
eb9e6443e2 | ||
|
|
362c466a16 | ||
|
|
5dac42646b | ||
|
|
c25faf6426 | ||
|
|
81df1245b4 | ||
|
|
2bf4d92185 | ||
|
|
ae6073fe80 | ||
|
|
d0463da2a1 | ||
|
|
c0f8001627 | ||
|
|
f39bf61b04 | ||
|
|
9c8237dab0 | ||
|
|
b88251fa79 | ||
|
|
208855917e | ||
|
|
34bdf450e9 | ||
|
|
998fa1f4e9 | ||
|
|
5c80f7d58c | ||
|
|
7552181e24 | ||
|
|
4b2e26050e | ||
|
|
530b48de71 | ||
|
|
f4721901f8 | ||
|
|
8b692269c1 | ||
|
|
079eca7b4d | ||
|
|
fee40cdbe2 | ||
|
|
66920bb4cb | ||
|
|
fdbf810aa2 | ||
|
|
08bfc1de4a | ||
|
|
76149328fe | ||
|
|
285f33f3f1 | ||
|
|
b17c1b7588 | ||
|
|
5b25c90db8 | ||
|
|
931a0a5168 | ||
|
|
f6a46438bd | ||
|
|
4a60ec1755 | ||
|
|
ec222413dd | ||
|
|
5a28239813 | ||
|
|
da45cba2ff | ||
|
|
54bc34496a | ||
|
|
294910ac84 | ||
|
|
71d2c6a5d5 | ||
|
|
79bf17fe24 | ||
|
|
31f66031bc | ||
|
|
d3f2284791 | ||
|
|
ec647608c4 | ||
|
|
597582ddd8 | ||
|
|
c6d9889182 | ||
|
|
7c58234174 | ||
|
|
ae9282b0af | ||
|
|
310ba646fc | ||
|
|
d479908939 | ||
|
|
5cd5d68d22 | ||
|
|
3e0bf25acb | ||
|
|
f3d277c94a | ||
|
|
04545ecbb0 | ||
|
|
5350651d6f | ||
|
|
f2e2e28419 | ||
|
|
b9031785ac | ||
|
|
91a72474a1 | ||
|
|
b6e7c425c6 | ||
|
|
834ace4566 | ||
|
|
54af70005d | ||
|
|
f2bf168925 | ||
|
|
27ffbd8dec | ||
|
|
eaa82592fe | ||
|
|
73784585a8 | ||
|
|
262d562dd9 | ||
|
|
ab4f904dc9 | ||
|
|
fc4fdd5ee2 | ||
|
|
41c5b62b1a | ||
|
|
239cb0435c | ||
|
|
c6ccc7a6e2 | ||
|
|
6cedb9019c | ||
|
|
8bc64f0438 | ||
|
|
89e6e39e58 | ||
|
|
645761f677 | ||
|
|
0fc60f7855 | ||
|
|
ce38460d87 | ||
|
|
de8e759d3a | ||
|
|
06f6134538 | ||
|
|
ac352b3a23 | ||
|
|
9b8e65e552 | ||
|
|
35999a05f0 | ||
|
|
86ee30e9b4 | ||
|
|
a81c4a1e23 | ||
|
|
394ce458a0 | ||
|
|
f187e57899 | ||
|
|
a15335872d | ||
|
|
beb77b4dab | ||
|
|
aa80d8cd0a | ||
|
|
77d197f14e | ||
|
|
f98fbb778c | ||
|
|
c46a0106f2 | ||
|
|
cbf3db0be0 | ||
|
|
21f3710083 | ||
|
|
8ac5768f4f | ||
|
|
2458b9305c | ||
|
|
a8909ea2a5 | ||
|
|
ac7c35c6c2 | ||
|
|
e4631b5a85 | ||
|
|
e1c50b5dc5 | ||
|
|
c6c5a5cd12 | ||
|
|
bd4854a607 | ||
|
|
cd0181e6f4 | ||
|
|
287b1d2b4d | ||
|
|
10c61bb0a7 | ||
|
|
92215ac34f | ||
|
|
f64d50d8c8 | ||
|
|
b74e0ce48f | ||
|
|
27cb0029a8 | ||
|
|
ce6f193f06 | ||
|
|
a862ffdde4 | ||
|
|
3f1cd8a118 | ||
|
|
bb4b5838e3 | ||
|
|
ea98d64184 | ||
|
|
98f3c56da5 | ||
|
|
20b7619380 | ||
|
|
7b1c3f05c7 | ||
|
|
9166998442 | ||
|
|
e1f6b577bf | ||
|
|
ba0d08b2a6 | ||
|
|
e79c12a038 | ||
|
|
2ca5182a28 | ||
|
|
205e627209 | ||
|
|
425d4f3f63 | ||
|
|
d69843e122 | ||
|
|
d2586d3b59 | ||
|
|
edab84c89b | ||
|
|
dd08754f1f | ||
|
|
2cdfe85091 | ||
|
|
a11acef36f | ||
|
|
1e34dbf616 | ||
|
|
b3d4763ef6 | ||
|
|
fe630e9383 | ||
|
|
826a20785f | ||
|
|
75932d7621 | ||
|
|
62d095af4f | ||
|
|
1594735aa0 |
@@ -3,7 +3,7 @@
|
||||
[](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master)
|
||||
[](https://hosted.weblate.org/projects/moonlight/moonlight-android/)
|
||||
|
||||
[Moonlight for Android](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
|
||||
[Moonlight for Android](https://moonlight-stream.org) is an open source client for NVIDIA GameStream, as used by the NVIDIA Shield.
|
||||
|
||||
Moonlight for Android will allow you to stream your full collection of games from your Windows PC to your Android device,
|
||||
whether in your own home or over the internet.
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
ndkVersion "22.1.7171670"
|
||||
ndkVersion "23.2.8568313"
|
||||
|
||||
compileSdkVersion 30
|
||||
compileSdk 33
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
minSdk 16
|
||||
targetSdk 33
|
||||
|
||||
versionName "9.9.1"
|
||||
versionCode = 261
|
||||
versionName "10.8.1"
|
||||
versionCode = 288
|
||||
|
||||
// Generate native debug symbols to allow Google Play to symbolicate our native crashes
|
||||
ndk.debugSymbolLevel = 'FULL'
|
||||
}
|
||||
|
||||
flavorDimensions "root"
|
||||
flavorDimensions.add("root")
|
||||
|
||||
productFlavors {
|
||||
root {
|
||||
// Android O has native mouse capture, so don't show the rooted
|
||||
// version to devices running O on the Play Store.
|
||||
maxSdkVersion 25
|
||||
maxSdk 25
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
@@ -29,6 +32,7 @@ android {
|
||||
|
||||
applicationId "com.limelight.root"
|
||||
dimension "root"
|
||||
buildConfigField "boolean", "ROOT_BUILD", "true"
|
||||
}
|
||||
|
||||
nonRoot {
|
||||
@@ -40,12 +44,13 @@ android {
|
||||
|
||||
applicationId "com.limelight"
|
||||
dimension "root"
|
||||
buildConfigField "boolean", "ROOT_BUILD", "false"
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
lint {
|
||||
disable 'MissingTranslation'
|
||||
lintConfig file("lint.xml")
|
||||
lintConfig file('lint.xml')
|
||||
}
|
||||
|
||||
bundle {
|
||||
@@ -55,7 +60,7 @@ android {
|
||||
enableSplit = false
|
||||
}
|
||||
density {
|
||||
// FIXME: This should not be neccessary but we get
|
||||
// FIXME: This should not be necessary but we get
|
||||
// weird crashes due to missing drawable resources
|
||||
// when this split is enabled.
|
||||
enableSplit = false
|
||||
@@ -65,6 +70,8 @@ android {
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
resValue "string", "app_label", "Moonlight (Debug)"
|
||||
resValue "string", "app_label_root", "Moonlight (Root Debug)"
|
||||
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
@@ -101,6 +108,8 @@ android {
|
||||
//
|
||||
// TL;DR: Leave the following line alone!
|
||||
applicationIdSuffix ".unofficial"
|
||||
resValue "string", "app_label", "Moonlight"
|
||||
resValue "string", "app_label_root", "Moonlight (Root)"
|
||||
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
@@ -115,10 +124,11 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.66'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk15on:1.66'
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
|
||||
implementation 'org.jcodec:jcodec:0.2.3'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.12'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
|
||||
implementation 'com.squareup.okio:okio:1.17.5'
|
||||
implementation 'org.jmdns:jmdns:3.5.5'
|
||||
implementation 'org.jmdns:jmdns:3.5.7'
|
||||
implementation 'com.github.cgutman:ShieldControllerExtensions:1.0'
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_label" translatable="false">Moonlight (Debug)</string>
|
||||
<string name="app_label_root" translatable="false">Moonlight (Root Debug)</string>
|
||||
|
||||
</resources>
|
||||
@@ -35,6 +35,7 @@
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:dataExtractionRules="@xml/backup_rules_s"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:isGame="true"
|
||||
android:banner="@drawable/atv_banner"
|
||||
@@ -43,22 +44,31 @@
|
||||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:installLocation="auto"
|
||||
android:gwpAsanMode="always"
|
||||
android:localeConfig="@xml/locales_config"
|
||||
android:enableOnBackInvokedCallback="false"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<provider
|
||||
android:name=".PosterContentProvider"
|
||||
android:authorities="poster.${applicationId}"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
</provider>
|
||||
|
||||
<!-- Samsung multi-window support -->
|
||||
<uses-library
|
||||
android:name="com.sec.android.app.multiwindow"
|
||||
android:required="false" />
|
||||
|
||||
<meta-data
|
||||
android:name="com.sec.android.support.multiwindow"
|
||||
android:value="true" />
|
||||
|
||||
<!-- Disable Game Mode downscaling since it can break our UI dialogs and doesn't benefit
|
||||
performance much for us since we don't use GL/Vulkan for rendering anyway -->
|
||||
<meta-data
|
||||
android:name="com.android.graphics.intervention.wm.allowDownscale"
|
||||
android:value="false"/>
|
||||
|
||||
<!-- Samsung DeX support requires explicit placement of android:resizeableActivity="true"
|
||||
in each activity even though it is implied by targeting API 24+ -->
|
||||
|
||||
@@ -98,6 +108,7 @@
|
||||
<activity
|
||||
android:name=".preferences.StreamSettings"
|
||||
android:resizeableActivity="true"
|
||||
android:configChanges="mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
|
||||
android:label="Streaming Settings">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
@@ -107,16 +118,15 @@
|
||||
android:name=".preferences.AddComputerManually"
|
||||
android:resizeableActivity="true"
|
||||
android:windowSoftInputMode="stateVisible"
|
||||
android:configChanges="mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
|
||||
android:label="Add Computer Manually">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.limelight.PcView" />
|
||||
</activity>
|
||||
<!-- This will fall back to sensorLandscape at runtime on Android 4.2 and below -->
|
||||
<activity
|
||||
android:name=".Game"
|
||||
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
|
||||
android:screenOrientation="userLandscape"
|
||||
android:noHistory="true"
|
||||
android:supportsPictureInPicture="true"
|
||||
android:resizeableActivity="true"
|
||||
|
||||
@@ -293,6 +293,11 @@ public class AppView extends Activity implements AdapterFragmentCallbacks {
|
||||
|
||||
setContentView(R.layout.activity_app_view);
|
||||
|
||||
// Allow floating expanded PiP overlays while browsing apps
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
setShouldDockBigOverlays(false);
|
||||
}
|
||||
|
||||
UiHelper.notifyNewRootView(this);
|
||||
|
||||
showHiddenApps = getIntent().getBooleanExtra(SHOW_HIDDEN_APPS_EXTRA, false);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,9 +2,12 @@ package com.limelight;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.window.OnBackInvokedCallback;
|
||||
import android.window.OnBackInvokedDispatcher;
|
||||
|
||||
import com.limelight.utils.SpinnerDialog;
|
||||
|
||||
@@ -13,10 +16,26 @@ public class HelpActivity extends Activity {
|
||||
private SpinnerDialog loadingDialog;
|
||||
private WebView webView;
|
||||
|
||||
private boolean backCallbackRegistered;
|
||||
private OnBackInvokedCallback onBackInvokedCallback;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
onBackInvokedCallback = new OnBackInvokedCallback() {
|
||||
@Override
|
||||
public void onBackInvoked() {
|
||||
// We should always be able to go back because we unregister our callback
|
||||
// when we can't go back. Nonetheless, we will still check anyway.
|
||||
if (webView.canGoBack()) {
|
||||
webView.goBack();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
webView = new WebView(this);
|
||||
setContentView(webView);
|
||||
|
||||
@@ -39,6 +58,8 @@ public class HelpActivity extends Activity {
|
||||
getResources().getString(R.string.help_loading_title),
|
||||
getResources().getString(R.string.help_loading_msg), false);
|
||||
}
|
||||
|
||||
refreshBackDispatchState();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,6 +68,8 @@ public class HelpActivity extends Activity {
|
||||
loadingDialog.dismiss();
|
||||
loadingDialog = null;
|
||||
}
|
||||
|
||||
refreshBackDispatchState();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,7 +82,33 @@ public class HelpActivity extends Activity {
|
||||
webView.loadUrl(getIntent().getData().toString());
|
||||
}
|
||||
|
||||
private void refreshBackDispatchState() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (webView.canGoBack() && !backCallbackRegistered) {
|
||||
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
|
||||
OnBackInvokedDispatcher.PRIORITY_DEFAULT, onBackInvokedCallback);
|
||||
backCallbackRegistered = true;
|
||||
}
|
||||
else if (!webView.canGoBack() && backCallbackRegistered) {
|
||||
getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(onBackInvokedCallback);
|
||||
backCallbackRegistered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (backCallbackRegistered) {
|
||||
getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(onBackInvokedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
// NOTE: This will NOT be called on Android 13+ with android:enableOnBackInvokedCallback="true"
|
||||
public void onBackPressed() {
|
||||
// Back goes back through the WebView history
|
||||
// until no more history remains
|
||||
|
||||
@@ -124,6 +124,11 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
|
||||
UiHelper.notifyNewRootView(this);
|
||||
|
||||
// Allow floating expanded PiP overlays while browsing PCs
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
setShouldDockBigOverlays(false);
|
||||
}
|
||||
|
||||
// Set default preferences if we've never been run
|
||||
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
|
||||
|
||||
@@ -155,6 +160,13 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
}
|
||||
});
|
||||
|
||||
// Amazon review didn't like the help button because the wiki was not entirely
|
||||
// navigable via the Fire TV remote (though the relevant parts were). Let's hide
|
||||
// it on Fire TV.
|
||||
if (getPackageManager().hasSystemFeature("amazon.hardware.fire_tv")) {
|
||||
helpButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.pcFragmentContainer, new AdapterFragment())
|
||||
.commitAllowingStateLoss();
|
||||
@@ -367,8 +379,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
}
|
||||
|
||||
private void doPair(final ComputerDetails computer) {
|
||||
if (computer.state == ComputerDetails.State.OFFLINE ||
|
||||
ServerHelper.getCurrentAddressFromComputer(computer) == null) {
|
||||
if (computer.state == ComputerDetails.State.OFFLINE || computer.activeAddress == null) {
|
||||
Toast.makeText(PcView.this, getResources().getString(R.string.pair_pc_offline), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
@@ -505,8 +516,7 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
}
|
||||
|
||||
private void doUnpair(final ComputerDetails computer) {
|
||||
if (computer.state == ComputerDetails.State.OFFLINE ||
|
||||
ServerHelper.getCurrentAddressFromComputer(computer) == null) {
|
||||
if (computer.state == ComputerDetails.State.OFFLINE || computer.activeAddress == null) {
|
||||
Toast.makeText(PcView.this, getResources().getString(R.string.error_pc_offline), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13,11 +13,13 @@ import com.limelight.computers.ComputerManagerService;
|
||||
import com.limelight.nvstream.http.ComputerDetails;
|
||||
import com.limelight.nvstream.http.NvApp;
|
||||
import com.limelight.nvstream.http.PairingManager;
|
||||
import com.limelight.nvstream.wol.WakeOnLanSender;
|
||||
import com.limelight.utils.Dialog;
|
||||
import com.limelight.utils.ServerHelper;
|
||||
import com.limelight.utils.SpinnerDialog;
|
||||
import com.limelight.utils.UiHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -26,6 +28,7 @@ public class ShortcutTrampoline extends Activity {
|
||||
private NvApp app;
|
||||
private ArrayList<Intent> intentStack = new ArrayList<>();
|
||||
|
||||
private int wakeHostTries = 10;
|
||||
private ComputerDetails computer;
|
||||
private SpinnerDialog blockingLoadSpinner;
|
||||
|
||||
@@ -79,6 +82,23 @@ public class ShortcutTrampoline extends Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to wake the target PC if it's offline (up to some retry limit)
|
||||
if (details.state == ComputerDetails.State.OFFLINE && details.macAddress != null && --wakeHostTries >= 0) {
|
||||
try {
|
||||
// Make a best effort attempt to wake the target PC
|
||||
WakeOnLanSender.sendWolPacket(computer);
|
||||
|
||||
// If we sent at least one WoL packet, reset the computer state
|
||||
// to force ComputerManager to poll it again.
|
||||
managerBinder.invalidateStateForComputer(computer.uuid);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
// If we got an exception, we couldn't send a single WoL packet,
|
||||
// so fallthrough into the offline error path.
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (details.state != ComputerDetails.State.UNKNOWN) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -8,16 +8,6 @@ import com.limelight.nvstream.av.audio.AudioRenderer;
|
||||
import com.limelight.nvstream.http.LimelightCryptoProvider;
|
||||
|
||||
public class PlatformBinding {
|
||||
public static String getDeviceName() {
|
||||
String deviceName = android.os.Build.MODEL;
|
||||
deviceName = deviceName.replace(" ", "");
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
public static AudioRenderer getAudioRenderer() {
|
||||
return new AndroidAudioRenderer();
|
||||
}
|
||||
|
||||
public static LimelightCryptoProvider getCryptoProvider(Context c) {
|
||||
return new AndroidCryptoProvider(c);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.limelight.binding.audio;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioTrack;
|
||||
import android.media.audiofx.AudioEffect;
|
||||
import android.os.Build;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
@@ -12,8 +15,16 @@ import com.limelight.nvstream.jni.MoonBridge;
|
||||
|
||||
public class AndroidAudioRenderer implements AudioRenderer {
|
||||
|
||||
private final Context context;
|
||||
private final boolean enableAudioFx;
|
||||
|
||||
private AudioTrack track;
|
||||
|
||||
public AndroidAudioRenderer(Context context, boolean enableAudioFx) {
|
||||
this.context = context;
|
||||
this.enableAudioFx = enableAudioFx;
|
||||
}
|
||||
|
||||
private AudioTrack createAudioTrack(int channelConfig, int sampleRate, int bufferSize, boolean lowLatency) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
||||
return new AudioTrack(AudioManager.STREAM_MUSIC,
|
||||
@@ -161,6 +172,12 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip low latency options when using audio effects, since low latency mode
|
||||
// precludes the use of the audio effect pipeline (as of Android 13).
|
||||
if (enableAudioFx && lowLatency) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
track = createAudioTrack(channelConfig, sampleRate, bufferSize, lowLatency);
|
||||
track.play();
|
||||
@@ -203,10 +220,27 @@ public class AndroidAudioRenderer implements AudioRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {}
|
||||
public void start() {
|
||||
if (enableAudioFx) {
|
||||
// Open an audio effect control session to allow equalizers to apply audio effects
|
||||
Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
|
||||
i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, track.getAudioSessionId());
|
||||
i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName());
|
||||
i.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_GAME);
|
||||
context.sendBroadcast(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {}
|
||||
public void stop() {
|
||||
if (enableAudioFx) {
|
||||
// Close our audio effect control session when we're stopping
|
||||
Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
|
||||
i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, track.getAudioSessionId());
|
||||
i.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName());
|
||||
context.sendBroadcast(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.limelight.binding.input;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputManager;
|
||||
@@ -7,9 +8,11 @@ import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.media.AudioAttributes;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.os.CombinedVibration;
|
||||
import android.os.VibrationAttributes;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.os.VibratorManager;
|
||||
import android.util.SparseArray;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputEvent;
|
||||
@@ -28,6 +31,8 @@ import com.limelight.preferences.PreferenceConfiguration;
|
||||
import com.limelight.ui.GameGestures;
|
||||
import com.limelight.utils.Vector2d;
|
||||
|
||||
import org.cgutman.shieldcontrollerextensions.SceManager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
@@ -43,9 +48,6 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
private static final int EMULATING_SPECIAL = 0x1;
|
||||
private static final int EMULATING_SELECT = 0x2;
|
||||
|
||||
private static final int EMULATED_SPECIAL_UP_DELAY_MS = 100;
|
||||
private static final int EMULATED_SELECT_UP_DELAY_MS = 30;
|
||||
|
||||
private final Vector2d inputVector = new Vector2d();
|
||||
|
||||
private final SparseArray<InputDeviceContext> inputDeviceContexts = new SparseArray<>();
|
||||
@@ -57,6 +59,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
private final InputDeviceContext defaultContext = new InputDeviceContext();
|
||||
private final GameGestures gestures;
|
||||
private final Vibrator deviceVibrator;
|
||||
private final SceManager sceManager;
|
||||
private boolean hasGameController;
|
||||
|
||||
private final PreferenceConfiguration prefConfig;
|
||||
@@ -69,9 +72,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
this.prefConfig = prefConfig;
|
||||
this.deviceVibrator = (Vibrator) activityContext.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
|
||||
// HACK: For now we're hardcoding a 7% deadzone. Some deadzone
|
||||
// is required for controller batching support to work.
|
||||
int deadzonePercentage = 7;
|
||||
this.sceManager = new SceManager(activityContext);
|
||||
this.sceManager.start();
|
||||
|
||||
int deadzonePercentage = prefConfig.deadzonePercentage;
|
||||
|
||||
int[] ids = InputDevice.getDeviceIds();
|
||||
for (int id : ids) {
|
||||
@@ -155,11 +159,36 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
}
|
||||
|
||||
// This can happen when gaining/losing input focus with some devices.
|
||||
// Input devices that have a trackpad may gain/lose AXIS_RELATIVE_X/Y.
|
||||
@Override
|
||||
public void onInputDeviceChanged(int deviceId) {
|
||||
// Remove and re-add
|
||||
onInputDeviceRemoved(deviceId);
|
||||
onInputDeviceAdded(deviceId);
|
||||
InputDevice device = InputDevice.getDevice(deviceId);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have a context for this device, we don't need to update anything
|
||||
InputDeviceContext existingContext = inputDeviceContexts.get(deviceId);
|
||||
if (existingContext == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LimeLog.info("Device changed: "+existingContext.name+" ("+deviceId+")");
|
||||
|
||||
// Don't release the controller number, because we will carry it over if it is present.
|
||||
// We also want to make sure the change is invisible to the host PC to avoid an add/remove
|
||||
// cycle for the gamepad which may break some games.
|
||||
existingContext.destroy();
|
||||
|
||||
InputDeviceContext newContext = createInputDeviceContextForDevice(device);
|
||||
|
||||
// Copy over existing controller number state
|
||||
newContext.assignedControllerNumber = existingContext.assignedControllerNumber;
|
||||
newContext.reservedControllerNumber = existingContext.reservedControllerNumber;
|
||||
newContext.controllerNumber = existingContext.controllerNumber;
|
||||
|
||||
inputDeviceContexts.put(deviceId, newContext);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
@@ -173,6 +202,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
deviceContext.destroy();
|
||||
}
|
||||
|
||||
sceManager.stop();
|
||||
deviceVibrator.cancel();
|
||||
}
|
||||
|
||||
@@ -478,6 +508,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
LimeLog.info(dev.toString());
|
||||
|
||||
context.inputDevice = dev;
|
||||
context.name = devName;
|
||||
context.id = dev.getId();
|
||||
context.external = isExternal(dev);
|
||||
@@ -487,7 +518,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.productId = dev.getProductId();
|
||||
}
|
||||
|
||||
if (dev.getVibrator().hasVibrator()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && hasDualAmplitudeControlledRumbleVibrators(dev.getVibratorManager())) {
|
||||
context.vibratorManager = dev.getVibratorManager();
|
||||
}
|
||||
else if (dev.getVibrator().hasVibrator()) {
|
||||
context.vibrator = dev.getVibrator();
|
||||
}
|
||||
|
||||
@@ -672,9 +706,6 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
// SHIELD controllers will use small stick deadzones
|
||||
else if (devName.contains("SHIELD") || devName.contains("NVIDIA Controller")) {
|
||||
context.leftStickDeadzoneRadius = 0.07f;
|
||||
context.rightStickDeadzoneRadius = 0.07f;
|
||||
|
||||
// The big Nvidia button on the Shield controllers acts like a Search button. It
|
||||
// summons the Google Assistant on the Shield TV. On my Pixel 4, it seems to do
|
||||
// nothing, so we can hijack it to act like a mode button.
|
||||
@@ -1283,7 +1314,64 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
}
|
||||
|
||||
private void rumbleVibrator(Vibrator vibrator, short lowFreqMotor, short highFreqMotor) {
|
||||
@TargetApi(31)
|
||||
private boolean hasDualAmplitudeControlledRumbleVibrators(VibratorManager vm) {
|
||||
int[] vibratorIds = vm.getVibratorIds();
|
||||
|
||||
// There must be exactly 2 vibrators on this device
|
||||
if (vibratorIds.length != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Both vibrators must have amplitude control
|
||||
for (int vid : vibratorIds) {
|
||||
if (!vm.getVibrator(vid).hasAmplitudeControl()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This must only be called if hasDualAmplitudeControlledRumbleVibrators() is true!
|
||||
@TargetApi(31)
|
||||
private void rumbleDualVibrators(VibratorManager vm, short lowFreqMotor, short highFreqMotor) {
|
||||
// Normalize motor values to 0-255 amplitudes for VibrationManager
|
||||
highFreqMotor = (short)((highFreqMotor >> 8) & 0xFF);
|
||||
lowFreqMotor = (short)((lowFreqMotor >> 8) & 0xFF);
|
||||
|
||||
// If they're both zero, we can just call cancel().
|
||||
if (lowFreqMotor == 0 && highFreqMotor == 0) {
|
||||
vm.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// There's no documentation that states that vibrators for FF_RUMBLE input devices will
|
||||
// always be enumerated in this order, but it seems consistent between Xbox Series X (USB),
|
||||
// PS3 (USB), and PS4 (USB+BT) controllers on Android 12 Beta 3.
|
||||
int[] vibratorIds = vm.getVibratorIds();
|
||||
int[] vibratorAmplitudes = new int[] { highFreqMotor, lowFreqMotor };
|
||||
|
||||
CombinedVibration.ParallelCombination combo = CombinedVibration.startParallel();
|
||||
|
||||
for (int i = 0; i < vibratorIds.length; i++) {
|
||||
// It's illegal to create a VibrationEffect with an amplitude of 0.
|
||||
// Simply excluding that vibrator from our ParallelCombination will turn it off.
|
||||
if (vibratorAmplitudes[i] != 0) {
|
||||
combo.addVibrator(vibratorIds[i], VibrationEffect.createOneShot(60000, vibratorAmplitudes[i]));
|
||||
}
|
||||
}
|
||||
|
||||
VibrationAttributes.Builder vibrationAttributes = new VibrationAttributes.Builder();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
vibrationAttributes.setUsage(VibrationAttributes.USAGE_MEDIA);
|
||||
}
|
||||
|
||||
vm.vibrate(combo.combine(), vibrationAttributes.build());
|
||||
}
|
||||
|
||||
private void rumbleSingleVibrator(Vibrator vibrator, short lowFreqMotor, short highFreqMotor) {
|
||||
// Since we can only use a single amplitude value, compute the desired amplitude
|
||||
// by taking 80% of the big motor and 33% of the small motor, then capping to 255.
|
||||
// NB: This value is now 0-255 as required by VibrationEffect.
|
||||
@@ -1305,10 +1393,18 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (vibrator.hasAmplitudeControl()) {
|
||||
VibrationEffect effect = VibrationEffect.createOneShot(60000, simulatedAmplitude);
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_GAME)
|
||||
.build();
|
||||
vibrator.vibrate(effect, audioAttributes);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
VibrationAttributes vibrationAttributes = new VibrationAttributes.Builder()
|
||||
.setUsage(VibrationAttributes.USAGE_MEDIA)
|
||||
.build();
|
||||
vibrator.vibrate(effect, vibrationAttributes);
|
||||
}
|
||||
else {
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_GAME)
|
||||
.build();
|
||||
vibrator.vibrate(effect, audioAttributes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1318,7 +1414,13 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
long pwmPeriod = 20;
|
||||
long onTime = (long)((simulatedAmplitude / 255.0) * pwmPeriod);
|
||||
long offTime = pwmPeriod - onTime;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
VibrationAttributes vibrationAttributes = new VibrationAttributes.Builder()
|
||||
.setUsage(VibrationAttributes.USAGE_MEDIA)
|
||||
.build();
|
||||
vibrator.vibrate(VibrationEffect.createWaveform(new long[]{0, onTime, offTime}, 0), vibrationAttributes);
|
||||
}
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_GAME)
|
||||
.build();
|
||||
@@ -1339,9 +1441,19 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
if (deviceContext.controllerNumber == controllerNumber) {
|
||||
foundMatchingDevice = true;
|
||||
|
||||
if (deviceContext.vibrator != null) {
|
||||
// Prefer the documented Android 12 rumble API which can handle dual vibrators on PS/Xbox controllers
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && deviceContext.vibratorManager != null) {
|
||||
vibrated = true;
|
||||
rumbleVibrator(deviceContext.vibrator, lowFreqMotor, highFreqMotor);
|
||||
rumbleDualVibrators(deviceContext.vibratorManager, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
// On Shield devices, we can use their special API to rumble Shield controllers
|
||||
else if (sceManager.rumble(deviceContext.inputDevice, lowFreqMotor, highFreqMotor)) {
|
||||
vibrated = true;
|
||||
}
|
||||
// If all else fails, we have to try the old Vibrator API
|
||||
else if (deviceContext.vibrator != null) {
|
||||
vibrated = true;
|
||||
rumbleSingleVibrator(deviceContext.vibrator, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1361,12 +1473,12 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
// controls that triggered the rumble. Vibrate the device if
|
||||
// the user has requested that behavior.
|
||||
if (!foundMatchingDevice && prefConfig.onscreenController && !prefConfig.onlyL3R3 && prefConfig.vibrateOsc) {
|
||||
rumbleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
rumbleSingleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
else if (foundMatchingDevice && !vibrated && prefConfig.vibrateFallbackToDevice) {
|
||||
// We found a device to vibrate but it didn't have rumble support. The user
|
||||
// has requested us to vibrate the device in this case.
|
||||
rumbleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
rumbleSingleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1390,13 +1502,21 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
// If the button hasn't been down long enough, sleep for a bit before sending the up event
|
||||
// This allows "instant" button presses (like OUYA's virtual menu button) to work. This
|
||||
// path should not be triggered during normal usage.
|
||||
if (SystemClock.uptimeMillis() - event.getDownTime() < ControllerHandler.MINIMUM_BUTTON_DOWN_TIME_MS)
|
||||
int buttonDownTime = (int)(event.getEventTime() - event.getDownTime());
|
||||
if (buttonDownTime < ControllerHandler.MINIMUM_BUTTON_DOWN_TIME_MS)
|
||||
{
|
||||
// Since our sleep time is so short (10 ms), it shouldn't cause a problem doing this in the
|
||||
// UI thread.
|
||||
// Since our sleep time is so short (<= 25 ms), it shouldn't cause a problem doing this
|
||||
// in the UI thread.
|
||||
try {
|
||||
Thread.sleep(ControllerHandler.MINIMUM_BUTTON_DOWN_TIME_MS);
|
||||
} catch (InterruptedException ignored) {}
|
||||
Thread.sleep(ControllerHandler.MINIMUM_BUTTON_DOWN_TIME_MS - buttonDownTime);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
// InterruptedException clears the thread's interrupt status. Since we can't
|
||||
// handle that here, we will re-interrupt the thread to set the interrupt
|
||||
// status back to true.
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
switch (keyCode) {
|
||||
@@ -1409,7 +1529,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
// Make sure it's real by checking that the key is actually down before taking
|
||||
// any action.
|
||||
if ((context.inputMap & ControllerPacket.PLAY_FLAG) != 0 &&
|
||||
SystemClock.uptimeMillis() - context.startDownTime > ControllerHandler.START_DOWN_TIME_MOUSE_MODE_MS &&
|
||||
event.getEventTime() - context.startDownTime > ControllerHandler.START_DOWN_TIME_MOUSE_MODE_MS &&
|
||||
prefConfig.mouseEmulation) {
|
||||
toggleMouseEmulation(context);
|
||||
}
|
||||
@@ -1462,11 +1582,11 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_L1:
|
||||
context.inputMap &= ~ControllerPacket.LB_FLAG;
|
||||
context.lastLbUpTime = SystemClock.uptimeMillis();
|
||||
context.lastLbUpTime = event.getEventTime();
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_R1:
|
||||
context.inputMap &= ~ControllerPacket.RB_FLAG;
|
||||
context.lastRbUpTime = SystemClock.uptimeMillis();
|
||||
context.lastRbUpTime = event.getEventTime();
|
||||
break;
|
||||
case KeyEvent.KEYCODE_BUTTON_THUMBL:
|
||||
context.inputMap &= ~ControllerPacket.LS_CLK_FLAG;
|
||||
@@ -1502,10 +1622,6 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.inputMap &= ~ControllerPacket.BACK_FLAG;
|
||||
|
||||
context.emulatingButtonFlags &= ~ControllerHandler.EMULATING_SELECT;
|
||||
|
||||
try {
|
||||
Thread.sleep(EMULATED_SELECT_UP_DELAY_MS);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1520,10 +1636,6 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.inputMap &= ~ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||
|
||||
context.emulatingButtonFlags &= ~ControllerHandler.EMULATING_SPECIAL;
|
||||
|
||||
try {
|
||||
Thread.sleep(EMULATED_SPECIAL_UP_DELAY_MS);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1561,7 +1673,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
case KeyEvent.KEYCODE_BUTTON_START:
|
||||
case KeyEvent.KEYCODE_MENU:
|
||||
if (event.getRepeatCount() == 0) {
|
||||
context.startDownTime = SystemClock.uptimeMillis();
|
||||
context.startDownTime = event.getEventTime();
|
||||
}
|
||||
context.inputMap |= ControllerPacket.PLAY_FLAG;
|
||||
break;
|
||||
@@ -1652,7 +1764,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
if (!context.hasSelect) {
|
||||
if (context.inputMap == (ControllerPacket.PLAY_FLAG | ControllerPacket.LB_FLAG) ||
|
||||
(context.inputMap == ControllerPacket.PLAY_FLAG &&
|
||||
SystemClock.uptimeMillis() - context.lastLbUpTime <= MAXIMUM_BUMPER_UP_DELAY_MS))
|
||||
event.getEventTime() - context.lastLbUpTime <= MAXIMUM_BUMPER_UP_DELAY_MS))
|
||||
{
|
||||
context.inputMap &= ~(ControllerPacket.PLAY_FLAG | ControllerPacket.LB_FLAG);
|
||||
context.inputMap |= ControllerPacket.BACK_FLAG;
|
||||
@@ -1675,7 +1787,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
else {
|
||||
if (context.inputMap == (ControllerPacket.PLAY_FLAG | ControllerPacket.RB_FLAG) ||
|
||||
(context.inputMap == ControllerPacket.PLAY_FLAG &&
|
||||
SystemClock.uptimeMillis() - context.lastRbUpTime <= MAXIMUM_BUMPER_UP_DELAY_MS))
|
||||
event.getEventTime() - context.lastRbUpTime <= MAXIMUM_BUMPER_UP_DELAY_MS))
|
||||
{
|
||||
context.inputMap &= ~(ControllerPacket.PLAY_FLAG | ControllerPacket.RB_FLAG);
|
||||
context.inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||
@@ -1803,7 +1915,9 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
|
||||
class InputDeviceContext extends GenericControllerContext {
|
||||
public String name;
|
||||
public VibratorManager vibratorManager;
|
||||
public Vibrator vibrator;
|
||||
public InputDevice inputDevice;
|
||||
|
||||
public int leftStickXAxis = -1;
|
||||
public int leftStickYAxis = -1;
|
||||
@@ -1849,7 +1963,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
|
||||
if (vibrator != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && vibratorManager != null) {
|
||||
vibratorManager.cancel();
|
||||
}
|
||||
else if (vibrator != null) {
|
||||
vibrator.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
package com.limelight.binding.input;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.os.Build;
|
||||
import android.util.SparseArray;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Class to translate a Android key code into the codes GFE is expecting
|
||||
* @author Diego Waxemberg
|
||||
* @author Cameron Gutman
|
||||
*/
|
||||
public class KeyboardTranslator {
|
||||
public class KeyboardTranslator implements InputManager.InputDeviceListener {
|
||||
|
||||
/**
|
||||
* GFE's prefix for every key code
|
||||
@@ -48,6 +55,55 @@ public class KeyboardTranslator {
|
||||
public static final int VK_QUOTE = 222;
|
||||
public static final int VK_PAUSE = 19;
|
||||
|
||||
private static class KeyboardMapping {
|
||||
private final InputDevice device;
|
||||
private final int[] deviceKeyCodeToQwertyKeyCode;
|
||||
|
||||
@TargetApi(33)
|
||||
public KeyboardMapping(InputDevice device) {
|
||||
int maxKeyCode = KeyEvent.getMaxKeyCode();
|
||||
|
||||
this.device = device;
|
||||
this.deviceKeyCodeToQwertyKeyCode = new int[maxKeyCode + 1];
|
||||
|
||||
// Any unmatched keycodes are treated as unknown
|
||||
Arrays.fill(deviceKeyCodeToQwertyKeyCode, KeyEvent.KEYCODE_UNKNOWN);
|
||||
|
||||
for (int i = 0; i <= maxKeyCode; i++) {
|
||||
int deviceKeyCode = device.getKeyCodeForKeyLocation(i);
|
||||
if (deviceKeyCode != KeyEvent.KEYCODE_UNKNOWN) {
|
||||
deviceKeyCodeToQwertyKeyCode[deviceKeyCode] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(33)
|
||||
public int getDeviceKeyCodeForQwertyKeyCode(int qwertyKeyCode) {
|
||||
return device.getKeyCodeForKeyLocation(qwertyKeyCode);
|
||||
}
|
||||
|
||||
public int getQwertyKeyCodeForDeviceKeyCode(int deviceKeyCode) {
|
||||
if (deviceKeyCode > KeyEvent.getMaxKeyCode()) {
|
||||
return KeyEvent.KEYCODE_UNKNOWN;
|
||||
}
|
||||
|
||||
return deviceKeyCodeToQwertyKeyCode[deviceKeyCode];
|
||||
}
|
||||
}
|
||||
|
||||
private final SparseArray<KeyboardMapping> keyboardMappings = new SparseArray<>();
|
||||
|
||||
public KeyboardTranslator() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
for (int deviceId : InputDevice.getDeviceIds()) {
|
||||
InputDevice device = InputDevice.getDevice(deviceId);
|
||||
if (device != null && device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
|
||||
keyboardMappings.set(deviceId, new KeyboardMapping(device));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean needsShift(int keycode) {
|
||||
switch (keycode)
|
||||
{
|
||||
@@ -65,10 +121,24 @@ public class KeyboardTranslator {
|
||||
/**
|
||||
* Translates the given keycode and returns the GFE keycode
|
||||
* @param keycode the code to be translated
|
||||
* @param deviceId InputDevice.getId() or -1 if unknown
|
||||
* @return a GFE keycode for the given keycode
|
||||
*/
|
||||
public static short translate(int keycode) {
|
||||
public short translate(int keycode, int deviceId) {
|
||||
int translated;
|
||||
|
||||
// If a device ID was provided, look up the keyboard mapping
|
||||
if (deviceId >= 0) {
|
||||
KeyboardMapping mapping = keyboardMappings.get(deviceId);
|
||||
if (mapping != null) {
|
||||
// Try to map this device-specific keycode onto a QWERTY layout.
|
||||
// GFE assumes incoming keycodes are from a QWERTY keyboard.
|
||||
int qwertyKeyCode = mapping.getQwertyKeyCodeForDeviceKeyCode(keycode);
|
||||
if (qwertyKeyCode != KeyEvent.KEYCODE_UNKNOWN) {
|
||||
keycode = qwertyKeyCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is a poor man's mapping between Android key codes
|
||||
// and Windows VK_* codes. For all defined VK_ codes, see:
|
||||
@@ -294,4 +364,30 @@ public class KeyboardTranslator {
|
||||
return (short) ((KEY_PREFIX << 8) | translated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceAdded(int index) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
InputDevice device = InputDevice.getDevice(index);
|
||||
if (device != null && device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
|
||||
keyboardMappings.put(index, new KeyboardMapping(device));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceRemoved(int index) {
|
||||
keyboardMappings.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceChanged(int index) {
|
||||
keyboardMappings.remove(index);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
InputDevice device = InputDevice.getDevice(index);
|
||||
if (device != null && device.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC) {
|
||||
keyboardMappings.set(index, new KeyboardMapping(device));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ package com.limelight.binding.input.capture;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -12,11 +14,13 @@ import android.view.View;
|
||||
// pointer icon hiding behavior over our stream view just in case pointer capture
|
||||
// is unavailable on this system (ex: DeX, ChromeOS)
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptureProvider {
|
||||
public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptureProvider implements InputManager.InputDeviceListener {
|
||||
private InputManager inputManager;
|
||||
private View targetView;
|
||||
|
||||
public AndroidNativePointerCaptureProvider(Activity activity, View targetView) {
|
||||
super(activity, targetView);
|
||||
this.inputManager = activity.getSystemService(InputManager.class);
|
||||
this.targetView = targetView;
|
||||
}
|
||||
|
||||
@@ -24,25 +28,85 @@ public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptu
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||
}
|
||||
|
||||
// We only capture the pointer if we have a compatible InputDevice
|
||||
// present. This is a workaround for an Android 12 regression causing
|
||||
// incorrect mouse input when using the SPen.
|
||||
// https://github.com/moonlight-stream/moonlight-android/issues/1030
|
||||
private boolean hasCaptureCompatibleInputDevice() {
|
||||
for (int id : InputDevice.getDeviceIds()) {
|
||||
InputDevice device = InputDevice.getDevice(id);
|
||||
if (device == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip touchscreens when considering compatible capture devices.
|
||||
// Samsung devices on Android 12 will report a sec_touchpad device
|
||||
// with SOURCE_TOUCHSCREEN, SOURCE_KEYBOARD, and SOURCE_MOUSE.
|
||||
// Upon enabling pointer capture, that device will switch to
|
||||
// SOURCE_KEYBOARD and SOURCE_TOUCHPAD.
|
||||
if (device.supportsSource(InputDevice.SOURCE_TOUCHSCREEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (device.supportsSource(InputDevice.SOURCE_MOUSE) ||
|
||||
device.supportsSource(InputDevice.SOURCE_MOUSE_RELATIVE) ||
|
||||
device.supportsSource(InputDevice.SOURCE_TOUCHPAD)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableCapture() {
|
||||
super.enableCapture();
|
||||
targetView.requestPointerCapture();
|
||||
|
||||
// Listen for device events to enable/disable capture
|
||||
inputManager.registerInputDeviceListener(this, null);
|
||||
|
||||
// Capture now if we have a capture-capable device
|
||||
if (hasCaptureCompatibleInputDevice()) {
|
||||
targetView.requestPointerCapture();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableCapture() {
|
||||
super.disableCapture();
|
||||
inputManager.unregisterInputDeviceListener(this);
|
||||
targetView.releasePointerCapture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean focusActive) {
|
||||
if (!focusActive || !isCapturing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Recapture the pointer if focus was regained. On Android Q,
|
||||
// we have to delay a bit before requesting capture because otherwise
|
||||
// we'll hit the "requestPointerCapture called for a window that has no focus"
|
||||
// error and it will not actually capture the cursor.
|
||||
Handler h = new Handler();
|
||||
h.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (hasCaptureCompatibleInputDevice()) {
|
||||
targetView.requestPointerCapture();
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eventHasRelativeMouseAxes(MotionEvent event) {
|
||||
// SOURCE_MOUSE_RELATIVE is how SOURCE_MOUSE appears when our view has pointer capture.
|
||||
// SOURCE_TOUCHPAD will have relative axes populated iff our view has pointer capture.
|
||||
// See https://developer.android.com/reference/android/view/View#requestPointerCapture()
|
||||
return event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE ||
|
||||
(event.getSource() == InputDevice.SOURCE_TOUCHPAD && targetView.hasPointerCapture());
|
||||
int eventSource = event.getSource();
|
||||
return (eventSource == InputDevice.SOURCE_MOUSE_RELATIVE && event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) ||
|
||||
(eventSource == InputDevice.SOURCE_TOUCHPAD && targetView.hasPointerCapture());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,4 +130,31 @@ public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptu
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceAdded(int deviceId) {
|
||||
// Check if we've added a capture-compatible device
|
||||
if (!targetView.hasPointerCapture() && hasCaptureCompatibleInputDevice()) {
|
||||
targetView.requestPointerCapture();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceRemoved(int deviceId) {
|
||||
// Check if the capture-compatible device was removed
|
||||
if (targetView.hasPointerCapture() && !hasCaptureCompatibleInputDevice()) {
|
||||
targetView.releasePointerCapture();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceChanged(int deviceId) {
|
||||
// Emulating a remove+add should be sufficient for our purposes.
|
||||
//
|
||||
// Note: This callback must be handled carefully because it can happen as a result of
|
||||
// calling requestPointerCapture(). This can cause trackpad devices to gain SOURCE_MOUSE_RELATIVE
|
||||
// and re-enter this callback.
|
||||
onInputDeviceRemoved(deviceId);
|
||||
onInputDeviceAdded(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.limelight.binding.input.capture;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.limelight.BuildConfig;
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.LimelightBuildProps;
|
||||
import com.limelight.R;
|
||||
import com.limelight.binding.input.evdev.EvdevCaptureProviderShim;
|
||||
import com.limelight.binding.input.evdev.EvdevListener;
|
||||
@@ -16,7 +16,7 @@ public class InputCaptureManager {
|
||||
}
|
||||
// LineageOS implemented broken NVIDIA capture extensions, so avoid using them on root builds.
|
||||
// See https://github.com/LineageOS/android_frameworks_base/commit/d304f478a023430f4712dbdc3ee69d9ad02cebd3
|
||||
else if (!LimelightBuildProps.ROOT_BUILD && ShieldCaptureProvider.isCaptureProviderSupported()) {
|
||||
else if (!BuildConfig.ROOT_BUILD && ShieldCaptureProvider.isCaptureProviderSupported()) {
|
||||
LimeLog.info("Using NVIDIA mouse capture extension");
|
||||
return new ShieldCaptureProvider(activity);
|
||||
}
|
||||
|
||||
@@ -33,4 +33,6 @@ public abstract class InputCaptureProvider {
|
||||
public float getRelativeAxisY(MotionEvent event) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void onWindowFocusChanged(boolean focusActive) {}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@ import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbDeviceConnection;
|
||||
import android.hardware.usb.UsbEndpoint;
|
||||
import android.hardware.usb.UsbInterface;
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.binding.video.MediaCodecHelper;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
@@ -37,7 +37,9 @@ public abstract class AbstractXboxController extends AbstractController {
|
||||
// around when we call notifyDeviceAdded(), we won't be able to claim
|
||||
// the controller number used by the original InputDevice.
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {}
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Report that we're added _before_ reporting input
|
||||
notifyDeviceAdded();
|
||||
@@ -56,7 +58,7 @@ public abstract class AbstractXboxController extends AbstractController {
|
||||
|
||||
do {
|
||||
// Read the next input state packet
|
||||
long lastMillis = MediaCodecHelper.getMonotonicMillis();
|
||||
long lastMillis = SystemClock.uptimeMillis();
|
||||
res = connection.bulkTransfer(inEndpt, buffer, buffer.length, 3000);
|
||||
|
||||
// If we get a zero length response, treat it as an error
|
||||
@@ -64,7 +66,7 @@ public abstract class AbstractXboxController extends AbstractController {
|
||||
res = -1;
|
||||
}
|
||||
|
||||
if (res == -1 && MediaCodecHelper.getMonotonicMillis() - lastMillis < 1000) {
|
||||
if (res == -1 && SystemClock.uptimeMillis() - lastMillis < 1000) {
|
||||
LimeLog.warning("Detected device I/O error");
|
||||
AbstractXboxController.this.stop();
|
||||
break;
|
||||
|
||||
@@ -29,6 +29,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
|
||||
private UsbManager usbManager;
|
||||
private PreferenceConfiguration prefConfig;
|
||||
private boolean started;
|
||||
|
||||
private final UsbEventReceiver receiver = new UsbEventReceiver();
|
||||
private final UsbDriverBinder binder = new UsbDriverBinder();
|
||||
@@ -36,6 +37,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
private final ArrayList<AbstractController> controllers = new ArrayList<>();
|
||||
|
||||
private UsbDriverListener listener;
|
||||
private UsbDriverStateListener stateListener;
|
||||
private int nextDeviceId;
|
||||
|
||||
@Override
|
||||
@@ -93,6 +95,11 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
else if (action.equals(ACTION_USB_PERMISSION)) {
|
||||
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
|
||||
|
||||
// Permission dialog is now closed
|
||||
if (stateListener != null) {
|
||||
stateListener.onUsbPermissionPromptCompleted();
|
||||
}
|
||||
|
||||
// If we got this far, we've already found we're able to handle this device
|
||||
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
|
||||
handleUsbDeviceState(device);
|
||||
@@ -112,6 +119,18 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setStateListener(UsbDriverStateListener stateListener) {
|
||||
UsbDriverService.this.stateListener = stateListener;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
UsbDriverService.this.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
UsbDriverService.this.stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleUsbDeviceState(UsbDevice device) {
|
||||
@@ -121,15 +140,29 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
if (!usbManager.hasPermission(device)) {
|
||||
// Let's ask for permission
|
||||
try {
|
||||
// Tell the state listener that we're about to display a permission dialog
|
||||
if (stateListener != null) {
|
||||
stateListener.onUsbPermissionPromptStarting();
|
||||
}
|
||||
|
||||
int intentFlags = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
// This PendingIntent must be mutable to allow the framework to populate EXTRA_DEVICE and EXTRA_PERMISSION_GRANTED.
|
||||
intentFlags |= PendingIntent.FLAG_MUTABLE;
|
||||
}
|
||||
|
||||
// This function is not documented as throwing any exceptions (denying access
|
||||
// is indicated by calling the PendingIntent with a false result). However,
|
||||
// Samsung Knox has some policies which block this request, but rather than
|
||||
// just returning a false result or returning 0 enumerated devices,
|
||||
// they throw an undocumented SecurityException from this call, crashing
|
||||
// the whole app. :(
|
||||
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), 0));
|
||||
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), intentFlags));
|
||||
} catch (SecurityException e) {
|
||||
Toast.makeText(this, this.getText(R.string.error_usb_prohibited), Toast.LENGTH_LONG).show();
|
||||
if (stateListener != null) {
|
||||
stateListener.onUsbPermissionPromptCompleted();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -220,16 +253,23 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
((!isRecognizedInputDevice(device) || claimAllAvailable) && Xbox360Controller.canClaimDevice(device));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
this.usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
||||
this.prefConfig = PreferenceConfiguration.readPreferences(this);
|
||||
private void start() {
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
|
||||
started = true;
|
||||
|
||||
// Register for USB attach broadcasts and permission completions
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
|
||||
filter.addAction(ACTION_USB_PERMISSION);
|
||||
registerReceiver(receiver, filter);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
registerReceiver(receiver, filter, RECEIVER_NOT_EXPORTED);
|
||||
}
|
||||
else {
|
||||
registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
// Enumerate existing devices
|
||||
for (UsbDevice dev : usbManager.getDeviceList().values()) {
|
||||
@@ -240,14 +280,16 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
private void stop() {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
|
||||
started = false;
|
||||
|
||||
// Stop the attachment receiver
|
||||
unregisterReceiver(receiver);
|
||||
|
||||
// Remove listeners
|
||||
listener = null;
|
||||
|
||||
// Stop all controllers
|
||||
while (controllers.size() > 0) {
|
||||
// Stop and remove the controller
|
||||
@@ -255,8 +297,28 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
this.usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
|
||||
this.prefConfig = PreferenceConfiguration.readPreferences(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
stop();
|
||||
|
||||
// Remove listeners
|
||||
listener = null;
|
||||
stateListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return binder;
|
||||
}
|
||||
|
||||
public interface UsbDriverStateListener {
|
||||
void onUsbPermissionPromptStarting();
|
||||
void onUsbPermissionPromptCompleted();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package com.limelight.binding.input.evdev;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import com.limelight.LimelightBuildProps;
|
||||
import com.limelight.BuildConfig;
|
||||
import com.limelight.binding.input.capture.InputCaptureProvider;
|
||||
|
||||
public class EvdevCaptureProviderShim {
|
||||
public static boolean isCaptureProviderSupported() {
|
||||
return LimelightBuildProps.ROOT_BUILD;
|
||||
return BuildConfig.ROOT_BUILD;
|
||||
}
|
||||
|
||||
// We need to construct our capture provider using reflection because it isn't included in non-root builds
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.limelight.binding.input.touch;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
|
||||
import com.limelight.nvstream.NvConnection;
|
||||
@@ -23,13 +24,20 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
private boolean confirmedTap;
|
||||
private Timer longPressTimer;
|
||||
private Timer tapDownTimer;
|
||||
private float accumulatedScrollDelta;
|
||||
|
||||
private final NvConnection conn;
|
||||
private final int actionIndex;
|
||||
private final View targetView;
|
||||
private final Handler handler;
|
||||
|
||||
private static final int SCROLL_SPEED_DIVISOR = 20;
|
||||
private final Runnable leftButtonUpRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT);
|
||||
}
|
||||
};
|
||||
|
||||
private static final int SCROLL_SPEED_FACTOR = 3;
|
||||
|
||||
private static final int LONG_PRESS_TIME_THRESHOLD = 650;
|
||||
private static final int LONG_PRESS_DISTANCE_THRESHOLD = 30;
|
||||
@@ -45,6 +53,7 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
this.conn = conn;
|
||||
this.actionIndex = actionIndex;
|
||||
this.targetView = view;
|
||||
this.handler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,7 +63,7 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDownEvent(int eventX, int eventY, boolean isNewFinger)
|
||||
public boolean touchDownEvent(int eventX, int eventY, long eventTime, boolean isNewFinger)
|
||||
{
|
||||
if (!isNewFinger) {
|
||||
// We don't handle finger transitions for absolute mode
|
||||
@@ -63,9 +72,8 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
|
||||
lastTouchLocationX = lastTouchDownX = eventX;
|
||||
lastTouchLocationY = lastTouchDownY = eventY;
|
||||
lastTouchDownTime = SystemClock.uptimeMillis();
|
||||
lastTouchDownTime = eventTime;
|
||||
cancelled = confirmedTap = confirmedLongPress = false;
|
||||
accumulatedScrollDelta = 0;
|
||||
|
||||
if (actionIndex == 0) {
|
||||
// Start the timers
|
||||
@@ -92,7 +100,7 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void touchUpEvent(int eventX, int eventY)
|
||||
public void touchUpEvent(int eventX, int eventY, long eventTime)
|
||||
{
|
||||
if (cancelled) {
|
||||
return;
|
||||
@@ -115,17 +123,17 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
// deadzone time. We'll need to send the touch down and up events now at the
|
||||
// original touch down position.
|
||||
tapConfirmed();
|
||||
try {
|
||||
// FIXME: Sleeping on the main thread sucks
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException ignored) {}
|
||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT);
|
||||
|
||||
// Release the left mouse button in 100ms to allow for apps that use polling
|
||||
// to detect mouse button presses.
|
||||
handler.removeCallbacks(leftButtonUpRunnable);
|
||||
handler.postDelayed(leftButtonUpRunnable, 100);
|
||||
}
|
||||
}
|
||||
|
||||
lastTouchLocationX = lastTouchUpX = eventX;
|
||||
lastTouchLocationY = lastTouchUpY = eventY;
|
||||
lastTouchUpTime = SystemClock.uptimeMillis();
|
||||
lastTouchUpTime = eventTime;
|
||||
}
|
||||
|
||||
private synchronized void startLongPressTimer() {
|
||||
@@ -209,7 +217,7 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchMoveEvent(int eventX, int eventY)
|
||||
public boolean touchMoveEvent(int eventX, int eventY, long eventTime)
|
||||
{
|
||||
if (cancelled) {
|
||||
return true;
|
||||
@@ -228,11 +236,7 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
}
|
||||
}
|
||||
else if (actionIndex == 1) {
|
||||
accumulatedScrollDelta += (eventY - lastTouchLocationY) / (float)SCROLL_SPEED_DIVISOR;
|
||||
if ((short)accumulatedScrollDelta != 0) {
|
||||
conn.sendMouseHighResScroll((short)accumulatedScrollDelta);
|
||||
accumulatedScrollDelta -= (short)accumulatedScrollDelta;
|
||||
}
|
||||
conn.sendMouseHighResScroll((short)((eventY - lastTouchLocationY) * SCROLL_SPEED_FACTOR));
|
||||
}
|
||||
|
||||
lastTouchLocationX = eventX;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.limelight.binding.input.touch;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
|
||||
import com.limelight.nvstream.NvConnection;
|
||||
import com.limelight.nvstream.input.MouseButtonPacket;
|
||||
import com.limelight.preferences.PreferenceConfiguration;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
@@ -30,22 +32,61 @@ public class RelativeTouchContext implements TouchContext {
|
||||
private final int referenceWidth;
|
||||
private final int referenceHeight;
|
||||
private final View targetView;
|
||||
private final PreferenceConfiguration prefConfig;
|
||||
private final Handler handler;
|
||||
|
||||
// Indexed by MouseButtonPacket.BUTTON_XXX - 1
|
||||
private final Runnable[] buttonUpRunnables = new Runnable[] {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT);
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_MIDDLE);
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_RIGHT);
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_X1);
|
||||
}
|
||||
},
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
conn.sendMouseButtonUp(MouseButtonPacket.BUTTON_X2);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private static final int TAP_MOVEMENT_THRESHOLD = 20;
|
||||
private static final int TAP_DISTANCE_THRESHOLD = 25;
|
||||
private static final int TAP_TIME_THRESHOLD = 250;
|
||||
private static final int DRAG_TIME_THRESHOLD = 650;
|
||||
|
||||
private static final int SCROLL_SPEED_DIVISOR = 20;
|
||||
private static final int SCROLL_SPEED_FACTOR = 5;
|
||||
|
||||
public RelativeTouchContext(NvConnection conn, int actionIndex,
|
||||
int referenceWidth, int referenceHeight, View view)
|
||||
int referenceWidth, int referenceHeight,
|
||||
View view, PreferenceConfiguration prefConfig)
|
||||
{
|
||||
this.conn = conn;
|
||||
this.actionIndex = actionIndex;
|
||||
this.referenceWidth = referenceWidth;
|
||||
this.referenceHeight = referenceHeight;
|
||||
this.targetView = view;
|
||||
this.prefConfig = prefConfig;
|
||||
this.handler = new Handler(Looper.getMainLooper());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +103,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
yDelta <= TAP_MOVEMENT_THRESHOLD;
|
||||
}
|
||||
|
||||
private boolean isTap()
|
||||
private boolean isTap(long eventTime)
|
||||
{
|
||||
if (confirmedDrag || confirmedMove || confirmedScroll) {
|
||||
return false;
|
||||
@@ -75,7 +116,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
return false;
|
||||
}
|
||||
|
||||
long timeDelta = SystemClock.uptimeMillis() - originalTouchTime;
|
||||
long timeDelta = eventTime - originalTouchTime;
|
||||
return isWithinTapBounds(lastTouchX, lastTouchY) && timeDelta <= TAP_TIME_THRESHOLD;
|
||||
}
|
||||
|
||||
@@ -90,7 +131,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchDownEvent(int eventX, int eventY, boolean isNewFinger)
|
||||
public boolean touchDownEvent(int eventX, int eventY, long eventTime, boolean isNewFinger)
|
||||
{
|
||||
// Get the view dimensions to scale inputs on this touch
|
||||
xFactor = referenceWidth / (double)targetView.getWidth();
|
||||
@@ -101,7 +142,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
|
||||
if (isNewFinger) {
|
||||
maxPointerCountInGesture = pointerCount;
|
||||
originalTouchTime = SystemClock.uptimeMillis();
|
||||
originalTouchTime = eventTime;
|
||||
cancelled = confirmedDrag = confirmedMove = confirmedScroll = false;
|
||||
distanceMoved = 0;
|
||||
|
||||
@@ -115,7 +156,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void touchUpEvent(int eventX, int eventY)
|
||||
public void touchUpEvent(int eventX, int eventY, long eventTime)
|
||||
{
|
||||
if (cancelled) {
|
||||
return;
|
||||
@@ -130,19 +171,16 @@ public class RelativeTouchContext implements TouchContext {
|
||||
// Raise the button after a drag
|
||||
conn.sendMouseButtonUp(buttonIndex);
|
||||
}
|
||||
else if (isTap())
|
||||
else if (isTap(eventTime))
|
||||
{
|
||||
// Lower the mouse button
|
||||
conn.sendMouseButtonDown(buttonIndex);
|
||||
|
||||
// We need to sleep a bit here because some games
|
||||
// do input detection by polling
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
|
||||
// Raise the mouse button
|
||||
conn.sendMouseButtonUp(buttonIndex);
|
||||
// Release the mouse button in 100ms to allow for apps that use polling
|
||||
// to detect mouse button presses.
|
||||
Runnable buttonUpRunnable = buttonUpRunnables[buttonIndex - 1];
|
||||
handler.removeCallbacks(buttonUpRunnable);
|
||||
handler.postDelayed(buttonUpRunnable, 100);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,6 +198,11 @@ public class RelativeTouchContext implements TouchContext {
|
||||
return;
|
||||
}
|
||||
|
||||
// The drag should only be processed for the primary finger
|
||||
if (actionIndex != maxPointerCountInGesture - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if someone cancelled us
|
||||
if (dragTimer == null) {
|
||||
return;
|
||||
@@ -213,7 +256,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean touchMoveEvent(int eventX, int eventY)
|
||||
public boolean touchMoveEvent(int eventX, int eventY, long eventTime)
|
||||
{
|
||||
if (cancelled) {
|
||||
return true;
|
||||
@@ -243,12 +286,19 @@ public class RelativeTouchContext implements TouchContext {
|
||||
|
||||
if (pointerCount == 2) {
|
||||
if (confirmedScroll) {
|
||||
deltaY /= SCROLL_SPEED_DIVISOR;
|
||||
|
||||
conn.sendMouseHighResScroll((short) deltaY);
|
||||
conn.sendMouseHighResScroll((short)(deltaY * SCROLL_SPEED_FACTOR));
|
||||
}
|
||||
} else {
|
||||
conn.sendMouseMove((short) deltaX, (short) deltaY);
|
||||
if (prefConfig.absoluteMouseMode) {
|
||||
conn.sendMouseMoveAsMousePosition(
|
||||
(short) deltaX,
|
||||
(short) deltaY,
|
||||
(short) targetView.getWidth(),
|
||||
(short) targetView.getHeight());
|
||||
}
|
||||
else {
|
||||
conn.sendMouseMove((short) deltaX, (short) deltaY);
|
||||
}
|
||||
}
|
||||
|
||||
// If the scaling factor ended up rounding deltas to zero, wait until they are
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.limelight.binding.input.touch;
|
||||
public interface TouchContext {
|
||||
int getActionIndex();
|
||||
void setPointerCount(int pointerCount);
|
||||
boolean touchDownEvent(int eventX, int eventY, boolean isNewFinger);
|
||||
boolean touchMoveEvent(int eventX, int eventY);
|
||||
void touchUpEvent(int eventX, int eventY);
|
||||
boolean touchDownEvent(int eventX, int eventY, long eventTime, boolean isNewFinger);
|
||||
boolean touchMoveEvent(int eventX, int eventY, long eventTime);
|
||||
void touchUpEvent(int eventX, int eventY, long eventTime);
|
||||
void cancelTouch();
|
||||
boolean isCancelled();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.os.SystemClock;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -254,7 +253,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePosition() {
|
||||
private void updatePosition(long eventTime) {
|
||||
// get 100% way
|
||||
float complete = radius_complete - radius_analog_stick;
|
||||
|
||||
@@ -271,7 +270,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
// We also release the deadzone if the user keeps the stick pressed for a bit to allow
|
||||
// them to make precise movements.
|
||||
stick_state = (stick_state == STICK_STATE.MOVED_ACTIVE ||
|
||||
SystemClock.uptimeMillis() - timeLastClick > timeoutDeadzone ||
|
||||
eventTime - timeLastClick > timeoutDeadzone ||
|
||||
movement_radius > radius_dead_zone) ?
|
||||
STICK_STATE.MOVED_ACTIVE : STICK_STATE.MOVED_IN_DEAD_ZONE;
|
||||
|
||||
@@ -312,7 +311,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
stick_state = STICK_STATE.MOVED_IN_DEAD_ZONE;
|
||||
// check for double click
|
||||
if (lastClickState == CLICK_STATE.SINGLE &&
|
||||
timeLastClick + timeoutDoubleClick > SystemClock.uptimeMillis()) {
|
||||
event.getEventTime() - timeLastClick <= timeoutDoubleClick) {
|
||||
click_state = CLICK_STATE.DOUBLE;
|
||||
notifyOnDoubleClick();
|
||||
} else {
|
||||
@@ -320,7 +319,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
notifyOnClick();
|
||||
}
|
||||
// reset last click timestamp
|
||||
timeLastClick = SystemClock.uptimeMillis();
|
||||
timeLastClick = event.getEventTime();
|
||||
// set item pressed and update
|
||||
setPressed(true);
|
||||
break;
|
||||
@@ -335,7 +334,7 @@ public class AnalogStick extends VirtualControllerElement {
|
||||
|
||||
if (isPressed()) {
|
||||
// when is pressed calculate new positions (will trigger movement if necessary)
|
||||
updatePosition();
|
||||
updatePosition(event.getEventTime());
|
||||
} else {
|
||||
stick_state = STICK_STATE.NO_MOVEMENT;
|
||||
notifyOnRevoke();
|
||||
|
||||
@@ -9,12 +9,11 @@ import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.R;
|
||||
import com.limelight.binding.input.ControllerHandler;
|
||||
import com.limelight.nvstream.NvConnection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -40,11 +39,10 @@ public class VirtualController {
|
||||
|
||||
private static final boolean _PRINT_DEBUG_INFORMATION = false;
|
||||
|
||||
private ControllerHandler controllerHandler;
|
||||
private Context context = null;
|
||||
private final ControllerHandler controllerHandler;
|
||||
private final Context context;
|
||||
|
||||
private FrameLayout frame_layout = null;
|
||||
private RelativeLayout relative_layout = null;
|
||||
|
||||
private Timer retransmitTimer;
|
||||
|
||||
@@ -60,10 +58,6 @@ public class VirtualController {
|
||||
this.frame_layout = layout;
|
||||
this.context = context;
|
||||
|
||||
relative_layout = new RelativeLayout(context);
|
||||
|
||||
frame_layout.addView(relative_layout);
|
||||
|
||||
buttonConfigure = new Button(context);
|
||||
buttonConfigure.setAlpha(0.25f);
|
||||
buttonConfigure.setFocusable(false);
|
||||
@@ -87,7 +81,7 @@ public class VirtualController {
|
||||
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
|
||||
relative_layout.invalidate();
|
||||
buttonConfigure.invalidate();
|
||||
|
||||
for (VirtualControllerElement element : elements) {
|
||||
element.invalidate();
|
||||
@@ -99,11 +93,20 @@ public class VirtualController {
|
||||
|
||||
public void hide() {
|
||||
retransmitTimer.cancel();
|
||||
relative_layout.setVisibility(View.INVISIBLE);
|
||||
|
||||
for (VirtualControllerElement element : elements) {
|
||||
element.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
buttonConfigure.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
relative_layout.setVisibility(View.VISIBLE);
|
||||
for (VirtualControllerElement element : elements) {
|
||||
element.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
buttonConfigure.setVisibility(View.VISIBLE);
|
||||
|
||||
// HACK: GFE sometimes discards gamepad packets when they are received
|
||||
// very shortly after another. This can be critical if an axis zeroing packet
|
||||
@@ -120,9 +123,11 @@ public class VirtualController {
|
||||
|
||||
public void removeElements() {
|
||||
for (VirtualControllerElement element : elements) {
|
||||
relative_layout.removeView(element);
|
||||
frame_layout.removeView(element);
|
||||
}
|
||||
elements.clear();
|
||||
|
||||
frame_layout.removeView(buttonConfigure);
|
||||
}
|
||||
|
||||
public void setOpacity(int opacity) {
|
||||
@@ -134,10 +139,10 @@ public class VirtualController {
|
||||
|
||||
public void addElement(VirtualControllerElement element, int x, int y, int width, int height) {
|
||||
elements.add(element);
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height);
|
||||
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(width, height);
|
||||
layoutParams.setMargins(x, y, 0, 0);
|
||||
|
||||
relative_layout.addView(element, layoutParams);
|
||||
frame_layout.addView(element, layoutParams);
|
||||
}
|
||||
|
||||
public List<VirtualControllerElement> getElements() {
|
||||
@@ -146,23 +151,20 @@ public class VirtualController {
|
||||
|
||||
private static final void _DBG(String text) {
|
||||
if (_PRINT_DEBUG_INFORMATION) {
|
||||
System.out.println("VirtualController: " + text);
|
||||
LimeLog.info("VirtualController: " + text);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshLayout() {
|
||||
relative_layout.removeAllViews();
|
||||
removeElements();
|
||||
|
||||
DisplayMetrics screen = context.getResources().getDisplayMetrics();
|
||||
|
||||
int buttonSize = (int)(screen.heightPixels*0.06f);
|
||||
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(buttonSize, buttonSize);
|
||||
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
|
||||
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(buttonSize, buttonSize);
|
||||
params.leftMargin = 15;
|
||||
params.topMargin = 15;
|
||||
relative_layout.addView(buttonConfigure, params);
|
||||
frame_layout.addView(buttonConfigure, params);
|
||||
|
||||
// Start with the default layout
|
||||
VirtualControllerConfigurationLoader.createDefaultLayout(this, context);
|
||||
|
||||
@@ -12,7 +12,7 @@ import android.graphics.Paint;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -72,7 +72,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
int newPos_x = (int) getX() + x - pressed_x;
|
||||
int newPos_y = (int) getY() + y - pressed_y;
|
||||
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
layoutParams.leftMargin = newPos_x > 0 ? newPos_x : 0;
|
||||
layoutParams.topMargin = newPos_y > 0 ? newPos_y : 0;
|
||||
@@ -83,7 +83,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
}
|
||||
|
||||
protected void resizeElement(int pressed_x, int pressed_y, int width, int height) {
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
int newHeight = height + (startSize_y - pressed_y);
|
||||
int newWidth = width + (startSize_x - pressed_x);
|
||||
@@ -316,7 +316,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
public JSONObject getConfiguration() throws JSONException {
|
||||
JSONObject configuration = new JSONObject();
|
||||
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
configuration.put("LEFT", layoutParams.leftMargin);
|
||||
configuration.put("TOP", layoutParams.topMargin);
|
||||
@@ -327,7 +327,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
}
|
||||
|
||||
public void loadConfiguration(JSONObject configuration) throws JSONException {
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
layoutParams.leftMargin = configuration.getInt("LEFT");
|
||||
layoutParams.topMargin = configuration.getInt("TOP");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@ import android.media.MediaFormat;
|
||||
import android.os.Build;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.preferences.PreferenceConfiguration;
|
||||
|
||||
public class MediaCodecHelper {
|
||||
|
||||
@@ -37,11 +38,11 @@ public class MediaCodecHelper {
|
||||
private static final List<String> whitelistedHevcDecoders;
|
||||
private static final List<String> refFrameInvalidationAvcPrefixes;
|
||||
private static final List<String> refFrameInvalidationHevcPrefixes;
|
||||
private static final List<String> blacklisted49FpsDecoderPrefixes;
|
||||
private static final List<String> blacklisted59FpsDecoderPrefixes;
|
||||
private static final List<String> useFourSlicesPrefixes;
|
||||
private static final List<String> qualcommDecoderPrefixes;
|
||||
private static final List<String> kirinDecoderPrefixes;
|
||||
private static final List<String> exynosDecoderPrefixes;
|
||||
private static final List<String> amlogicDecoderPrefixes;
|
||||
|
||||
public static final boolean IS_EMULATOR = Build.HARDWARE.equals("ranchu") || Build.HARDWARE.equals("cheets");
|
||||
|
||||
@@ -118,7 +119,7 @@ public class MediaCodecHelper {
|
||||
// if adaptive playback was enabled so let's avoid it to be safe.
|
||||
blacklistedAdaptivePlaybackPrefixes.add("omx.intel");
|
||||
// The MediaTek decoder crashes at 1080p when adaptive playback is enabled
|
||||
// on some Android TV devices with H.265 only.
|
||||
// on some Android TV devices with HEVC only.
|
||||
blacklistedAdaptivePlaybackPrefixes.add("omx.mtk");
|
||||
|
||||
constrainedHighProfilePrefixes = new LinkedList<>();
|
||||
@@ -136,24 +137,26 @@ public class MediaCodecHelper {
|
||||
// Exynos seems to be the only HEVC decoder that works reliably
|
||||
whitelistedHevcDecoders.add("omx.exynos");
|
||||
|
||||
// On Darcy (Shield 2017), HEVC runs fine with no fixups required.
|
||||
// For some reason, other X1 implementations require bitstream fixups.
|
||||
if (Build.DEVICE.equalsIgnoreCase("darcy")) {
|
||||
// On Darcy (Shield 2017), HEVC runs fine with no fixups required. For some reason,
|
||||
// other X1 implementations require bitstream fixups. However, since numReferenceFrames
|
||||
// has been supported in GFE since late 2017, we'll go ahead and enable HEVC for all
|
||||
// device models.
|
||||
//
|
||||
// NVIDIA does partial HEVC acceleration on the Shield Tablet. I don't know
|
||||
// whether the performance is good enough to use for streaming, but they're
|
||||
// using the same omx.nvidia.h265.decode name as the Shield TV which has a
|
||||
// fully accelerated HEVC pipeline. AFAIK, the only K1 devices with this
|
||||
// partially accelerated HEVC decoder are the Shield Tablet and Xiaomi MiPad,
|
||||
// so I'll check for those here.
|
||||
//
|
||||
// In case there are some that I missed, I will also exclude pre-Oreo OSes since
|
||||
// only Shield ATV got an Oreo update and any newer Tegra devices will not ship
|
||||
// with an old OS like Nougat.
|
||||
if (!Build.DEVICE.equalsIgnoreCase("shieldtablet") &&
|
||||
!Build.DEVICE.equalsIgnoreCase("mocha") &&
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
whitelistedHevcDecoders.add("omx.nvidia");
|
||||
}
|
||||
else {
|
||||
// TODO: This needs a similar fixup to the Tegra 3 otherwise it buffers 16 frames
|
||||
}
|
||||
|
||||
// Older Sony ATVs (SVP-DTV15) have broken MediaTek codecs (decoder hangs after rendering the first frame).
|
||||
// I know the Fire TV 2 and 3 works, so I'll whitelist Amazon devices which seem to actually be tested.
|
||||
if (Build.MANUFACTURER.equalsIgnoreCase("Amazon")) {
|
||||
whitelistedHevcDecoders.add("omx.mtk");
|
||||
|
||||
// This broke at some point on the Fire TV 3 and now the decoder
|
||||
// never produces any output frames.
|
||||
//whitelistedHevcDecoders.add("omx.amlogic");
|
||||
}
|
||||
|
||||
// Plot twist: On newer Sony devices (BRAVIA_ATV2, BRAVIA_ATV3_4K, BRAVIA_UR1_4K) the H.264 decoder crashes
|
||||
// on several configurations (> 60 FPS and 1440p) that work with HEVC, so we'll whitelist those devices for HEVC.
|
||||
@@ -163,11 +166,23 @@ public class MediaCodecHelper {
|
||||
|
||||
// Amlogic requires 1 reference frame for HEVC to avoid hanging. Since it's been years
|
||||
// since GFE added support for maxNumReferenceFrames, we'll just enable all Amlogic SoCs
|
||||
// running Android 9 or later. HEVC is much lower latency than H.264 on Sabrina (S905X2).
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
// running Android 9 or later.
|
||||
//
|
||||
// NB: We don't do this on Sabrina (GCWGTV) because H.264 is lower latency when we use
|
||||
// vendor.low-latency.enable. We will still use HEVC if decoderCanMeetPerformancePointWithHevcAndNotAvc()
|
||||
// determines it's the only way to meet the performance requirements.
|
||||
//
|
||||
// FIXME: Should we do this for all Amlogic S905X SoCs?
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !Build.DEVICE.equalsIgnoreCase("sabrina")) {
|
||||
whitelistedHevcDecoders.add("omx.amlogic");
|
||||
}
|
||||
|
||||
// Realtek SoCs are used inside many Android TV devices and can only do 4K60 with HEVC.
|
||||
// We'll enable those HEVC decoders by default and see if anything breaks.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
whitelistedHevcDecoders.add("omx.realtek");
|
||||
}
|
||||
|
||||
// These theoretically have good HEVC decoding capabilities (potentially better than
|
||||
// their AVC decoders), but haven't been tested enough
|
||||
//whitelistedHevcDecoders.add("omx.rk");
|
||||
@@ -188,21 +203,15 @@ public class MediaCodecHelper {
|
||||
}
|
||||
|
||||
static {
|
||||
blacklisted49FpsDecoderPrefixes = new LinkedList<>();
|
||||
blacklisted59FpsDecoderPrefixes = new LinkedList<>();
|
||||
useFourSlicesPrefixes = new LinkedList<>();
|
||||
|
||||
// We see a bunch of crashes on MediaTek Android TVs running
|
||||
// at 49 FPS (PAL 50 Hz - 1). Blacklist this frame rate for
|
||||
// these devices and hope they fix it in Pie.
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
||||
blacklisted49FpsDecoderPrefixes.add("omx.mtk");
|
||||
// Software decoders will use 4 slices per frame to allow for slice multithreading
|
||||
useFourSlicesPrefixes.add("omx.google");
|
||||
useFourSlicesPrefixes.add("AVCDecoder");
|
||||
useFourSlicesPrefixes.add("omx.ffmpeg");
|
||||
useFourSlicesPrefixes.add("c2.android");
|
||||
|
||||
// 59 FPS also seems to crash on the Sony Bravia TV ATV3 model.
|
||||
// Blacklist that frame rate on these devices too.
|
||||
if (Build.DEVICE.startsWith("BRAVIA_ATV3")) {
|
||||
blacklisted59FpsDecoderPrefixes.add("omx.mtk");
|
||||
}
|
||||
}
|
||||
// Old Qualcomm decoders are detected at runtime
|
||||
}
|
||||
|
||||
static {
|
||||
@@ -216,12 +225,21 @@ public class MediaCodecHelper {
|
||||
kirinDecoderPrefixes = new LinkedList<>();
|
||||
|
||||
kirinDecoderPrefixes.add("omx.hisi");
|
||||
kirinDecoderPrefixes.add("c2.hisi"); // Unconfirmed
|
||||
}
|
||||
|
||||
static {
|
||||
exynosDecoderPrefixes = new LinkedList<>();
|
||||
|
||||
exynosDecoderPrefixes.add("omx.exynos");
|
||||
exynosDecoderPrefixes.add("c2.exynos");
|
||||
}
|
||||
|
||||
static {
|
||||
amlogicDecoderPrefixes = new LinkedList<>();
|
||||
|
||||
amlogicDecoderPrefixes.add("omx.amlogic");
|
||||
amlogicDecoderPrefixes.add("c2.amlogic"); // Unconfirmed
|
||||
}
|
||||
|
||||
private static boolean isPowerVR(String glRenderer) {
|
||||
@@ -282,6 +300,19 @@ public class MediaCodecHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
// Older Sony ATVs (SVP-DTV15) have broken MediaTek codecs (decoder hangs after rendering the first frame).
|
||||
// I know the Fire TV 2 and 3 works, so I'll whitelist Amazon devices which seem to actually be tested.
|
||||
// We still have to check Build.MANUFACTURER to catch Amazon Fire tablets.
|
||||
if (context.getPackageManager().hasSystemFeature("amazon.hardware.fire_tv") ||
|
||||
Build.MANUFACTURER.equalsIgnoreCase("Amazon")) {
|
||||
whitelistedHevcDecoders.add("omx.mtk");
|
||||
|
||||
// This requires setting vdec-lowlatency on the Fire TV 3, otherwise the decoder
|
||||
// never produces any output frames. See comment above for details on why we only
|
||||
// do this for Fire TV devices.
|
||||
whitelistedHevcDecoders.add("omx.amlogic");
|
||||
}
|
||||
|
||||
ActivityManager activityManager =
|
||||
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
ConfigurationInfo configInfo = activityManager.getDeviceConfigurationInfo();
|
||||
@@ -327,6 +358,9 @@ public class MediaCodecHelper {
|
||||
}
|
||||
else {
|
||||
blacklistedDecoderPrefixes.add("OMX.qcom.video.decoder.hevc");
|
||||
|
||||
// These older decoders need 4 slices per frame for best performance
|
||||
useFourSlicesPrefixes.add("omx.qcom");
|
||||
}
|
||||
|
||||
// Older MediaTek SoCs have issues with HEVC rendering but the newer chips with
|
||||
@@ -366,10 +400,6 @@ public class MediaCodecHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long getMonotonicMillis() {
|
||||
return System.nanoTime() / 1000000L;
|
||||
}
|
||||
|
||||
private static boolean decoderSupportsAndroidRLowLatency(MediaCodecInfo decoderInfo, String mimeType) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
try {
|
||||
@@ -401,41 +431,117 @@ public class MediaCodecHelper {
|
||||
!isAdreno620;
|
||||
}
|
||||
|
||||
public static void setDecoderLowLatencyOptions(MediaFormat videoFormat, MediaCodecInfo decoderInfo, String mimeType) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && decoderSupportsAndroidRLowLatency(decoderInfo, mimeType)) {
|
||||
videoFormat.setInteger(MediaFormat.KEY_LOW_LATENCY, 1);
|
||||
public static boolean setDecoderLowLatencyOptions(MediaFormat videoFormat, MediaCodecInfo decoderInfo, int tryNumber) {
|
||||
// Options here should be tried in the order of most to least risky. The decoder will use
|
||||
// the first MediaFormat that doesn't fail in configure().
|
||||
|
||||
boolean setNewOption = false;
|
||||
|
||||
if (tryNumber < 1) {
|
||||
// Official Android 11+ low latency option (KEY_LOW_LATENCY).
|
||||
videoFormat.setInteger("low-latency", 1);
|
||||
setNewOption = true;
|
||||
|
||||
// If this decoder officially supports FEATURE_LowLatency, we will just use that alone
|
||||
// for try 0. Otherwise, we'll include it as best effort with other options.
|
||||
if (decoderSupportsAndroidRLowLatency(decoderInfo, videoFormat.getString(MediaFormat.KEY_MIME))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// MediaCodec supports vendor-defined format keys using the "vendor.<extension name>.<parameter name>" syntax.
|
||||
// These allow access to functionality that is not exposed through documented MediaFormat.KEY_* values.
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/common/inc/vidc_vendor_extensions.h;l=67
|
||||
|
||||
if (tryNumber < 2 &&
|
||||
(!Build.MANUFACTURER.equalsIgnoreCase("xiaomi") || Build.VERSION.SDK_INT > Build.VERSION_CODES.M)) {
|
||||
// MediaTek decoders don't use vendor-defined keys for low latency mode. Instead, they have a modified
|
||||
// version of AOSP's ACodec.cpp which supports the "vdec-lowlatency" option. This option is passed down
|
||||
// to the decoder as OMX.MTK.index.param.video.LowLatencyDecode.
|
||||
//
|
||||
// MediaCodec vendor extension support was introduced in Android 8.0:
|
||||
// https://cs.android.com/android/_/android/platform/frameworks/av/+/01c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Try vendor-specific low latency options
|
||||
if (isDecoderInList(qualcommDecoderPrefixes, decoderInfo.getName())) {
|
||||
// Examples of Qualcomm's vendor extensions for Snapdragon 845:
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/vdec/src/omx_vdec_extensions.hpp
|
||||
// https://cs.android.com/android/_/android/platform/hardware/qcom/sm8150/media/+/0621ceb1c1b19564999db8293574a0e12952ff6c
|
||||
videoFormat.setInteger("vendor.qti-ext-dec-low-latency.enable", 1);
|
||||
// This option is also plumbed for Amazon Amlogic-based devices like the Fire TV 3. Not only does it
|
||||
// reduce latency on Amlogic, it fixes the HEVC bug that causes the decoder to not output any frames.
|
||||
// Unfortunately, it does the exact opposite for the Xiaomi MITV4-ANSM0, breaking it in the way that
|
||||
// Fire TV was broken prior to vdec-lowlatency :(
|
||||
//
|
||||
// On Fire TV 3, vdec-lowlatency is translated to OMX.amazon.fireos.index.video.lowLatencyDecode.
|
||||
//
|
||||
// https://github.com/yuan1617/Framwork/blob/master/frameworks/av/media/libstagefright/ACodec.cpp
|
||||
// https://github.com/iykex/vendor_mediatek_proprietary_hardware/blob/master/libomx/video/MtkOmxVdecEx/MtkOmxVdecEx.h
|
||||
videoFormat.setInteger("vdec-lowlatency", 1);
|
||||
setNewOption = true;
|
||||
}
|
||||
|
||||
// MediaCodec supports vendor-defined format keys using the "vendor.<extension name>.<parameter name>" syntax.
|
||||
// These allow access to functionality that is not exposed through documented MediaFormat.KEY_* values.
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/common/inc/vidc_vendor_extensions.h;l=67
|
||||
//
|
||||
// MediaCodec vendor extension support was introduced in Android 8.0:
|
||||
// https://cs.android.com/android/_/android/platform/frameworks/av/+/01c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Try vendor-specific low latency options
|
||||
if (isDecoderInList(qualcommDecoderPrefixes, decoderInfo.getName())) {
|
||||
// Examples of Qualcomm's vendor extensions for Snapdragon 845:
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/vdec/src/omx_vdec_extensions.hpp
|
||||
// https://cs.android.com/android/_/android/platform/hardware/qcom/sm8150/media/+/0621ceb1c1b19564999db8293574a0e12952ff6c
|
||||
//
|
||||
// We will first try both, then try vendor.qti-ext-dec-low-latency.enable alone if that fails
|
||||
if (tryNumber < 3) {
|
||||
videoFormat.setInteger("vendor.qti-ext-dec-picture-order.enable", 1);
|
||||
setNewOption = true;
|
||||
}
|
||||
else if (isDecoderInList(kirinDecoderPrefixes, decoderInfo.getName())) {
|
||||
if (tryNumber < 4) {
|
||||
videoFormat.setInteger("vendor.qti-ext-dec-low-latency.enable", 1);
|
||||
setNewOption = true;
|
||||
}
|
||||
}
|
||||
else if (isDecoderInList(kirinDecoderPrefixes, decoderInfo.getName())) {
|
||||
if (tryNumber < 3) {
|
||||
// Kirin low latency options
|
||||
// https://developer.huawei.com/consumer/cn/forum/topic/0202325564295980115
|
||||
videoFormat.setInteger("vendor.hisi-ext-low-latency-video-dec.video-scene-for-low-latency-req", 1);
|
||||
videoFormat.setInteger("vendor.hisi-ext-low-latency-video-dec.video-scene-for-low-latency-rdy", -1);
|
||||
setNewOption = true;
|
||||
}
|
||||
else if (isDecoderInList(exynosDecoderPrefixes, decoderInfo.getName())) {
|
||||
}
|
||||
else if (isDecoderInList(exynosDecoderPrefixes, decoderInfo.getName())) {
|
||||
if (tryNumber < 3) {
|
||||
// Exynos low latency option for H.264 decoder
|
||||
videoFormat.setInteger("vendor.rtc-ext-dec-low-latency.enable", 1);
|
||||
setNewOption = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (MediaCodecHelper.decoderSupportsMaxOperatingRate(decoderInfo.getName())) {
|
||||
videoFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, Short.MAX_VALUE);
|
||||
else if (isDecoderInList(amlogicDecoderPrefixes, decoderInfo.getName())) {
|
||||
if (tryNumber < 3) {
|
||||
// Amlogic low latency vendor extension
|
||||
// https://github.com/codewalkerster/android_vendor_amlogic_common_prebuilt_libstagefrighthw/commit/41fefc4e035c476d58491324a5fe7666bfc2989e
|
||||
videoFormat.setInteger("vendor.low-latency.enable", 1);
|
||||
setNewOption = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: We should probably integrate this into the try system
|
||||
if (MediaCodecHelper.decoderSupportsMaxOperatingRate(decoderInfo.getName())) {
|
||||
videoFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, Short.MAX_VALUE);
|
||||
}
|
||||
|
||||
return setNewOption;
|
||||
}
|
||||
|
||||
public static boolean decoderSupportsFusedIdrFrame(MediaCodecInfo decoderInfo, String mimeType) {
|
||||
// If adaptive playback is supported, we can submit new CSD together with a keyframe
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
try {
|
||||
if (decoderInfo.getCapabilitiesForType(mimeType).
|
||||
isFeatureSupported(CodecCapabilities.FEATURE_AdaptivePlayback))
|
||||
{
|
||||
LimeLog.info("Decoder supports fused IDR frames (FEATURE_AdaptivePlayback)");
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Tolerate buggy codecs
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean decoderSupportsAdaptivePlayback(MediaCodecInfo decoderInfo, String mimeType) {
|
||||
@@ -479,15 +585,14 @@ public class MediaCodecHelper {
|
||||
return isDecoderInList(baselineProfileHackPrefixes, decoderName);
|
||||
}
|
||||
|
||||
public static boolean decoderBlacklistedForFrameRate(String decoderName, int fps) {
|
||||
if (fps == 49) {
|
||||
return isDecoderInList(blacklisted49FpsDecoderPrefixes, decoderName);
|
||||
}
|
||||
else if (fps == 59) {
|
||||
return isDecoderInList(blacklisted59FpsDecoderPrefixes, decoderName);
|
||||
public static byte getDecoderOptimalSlicesPerFrame(String decoderName) {
|
||||
if (isDecoderInList(useFourSlicesPrefixes, decoderName)) {
|
||||
// 4 slices per frame reduces decoding latency on older Qualcomm devices
|
||||
return 4;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
// 1 slice per frame produces the optimal encoding efficiency
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,21 +615,7 @@ public class MediaCodecHelper {
|
||||
return isDecoderInList(refFrameInvalidationHevcPrefixes, decoderName);
|
||||
}
|
||||
|
||||
public static boolean decoderIsWhitelistedForHevc(String decoderName, boolean meteredData) {
|
||||
// TODO: Shield Tablet K1/LTE?
|
||||
//
|
||||
// NVIDIA does partial HEVC acceleration on the Shield Tablet. I don't know
|
||||
// whether the performance is good enough to use for streaming, but they're
|
||||
// using the same omx.nvidia.h265.decode name as the Shield TV which has a
|
||||
// fully accelerated HEVC pipeline. AFAIK, the only K1 device with this
|
||||
// partially accelerated HEVC decoder is the Shield Tablet, so I'll
|
||||
// check for it here.
|
||||
//
|
||||
// TODO: Temporarily disabled with NVIDIA HEVC support
|
||||
/*if (Build.DEVICE.equalsIgnoreCase("shieldtablet")) {
|
||||
return false;
|
||||
}*/
|
||||
|
||||
public static boolean decoderIsWhitelistedForHevc(String decoderName, boolean meteredData, PreferenceConfiguration prefs) {
|
||||
// Google didn't have official support for HEVC (or more importantly, a CTS test) until
|
||||
// Lollipop. I've seen some MediaTek devices on 4.4 crash when attempting to use HEVC,
|
||||
// so I'm restricting HEVC usage to Lollipop and higher.
|
||||
@@ -545,9 +636,10 @@ public class MediaCodecHelper {
|
||||
// Some devices have HEVC decoders that we prefer not to use
|
||||
// typically because it can't support reference frame invalidation.
|
||||
// However, we will use it for HDR and for streaming over mobile networks
|
||||
// since it works fine otherwise.
|
||||
// since it works fine otherwise. We will also use it for 4K because RFI
|
||||
// is currently disabled due to issues with video corruption.
|
||||
if (isDecoderInList(deprioritizedHevcDecoders, decoderName)) {
|
||||
if (meteredData) {
|
||||
if (meteredData || (prefs.width == 3840 && prefs.height == 2160)) {
|
||||
LimeLog.info("Selected deprioritized decoder");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
@@ -49,8 +47,7 @@ public class ComputerManagerService extends Service {
|
||||
private static final int APPLIST_POLLING_PERIOD_MS = 30000;
|
||||
private static final int APPLIST_FAILED_POLLING_RETRY_MS = 2000;
|
||||
private static final int MDNS_QUERY_PERIOD_MS = 1000;
|
||||
private static final int FAST_POLL_TIMEOUT = 1000;
|
||||
private static final int OFFLINE_POLL_TRIES = 5;
|
||||
private static final int OFFLINE_POLL_TRIES = 3;
|
||||
private static final int INITIAL_POLL_TRIES = 2;
|
||||
private static final int EMPTY_LIST_THRESHOLD = 3;
|
||||
private static final int POLL_DATA_TTL_MS = 30000;
|
||||
@@ -232,7 +229,13 @@ public class ComputerManagerService extends Service {
|
||||
// Wait for the bind notification
|
||||
discoveryServiceConnection.wait(1000);
|
||||
}
|
||||
} catch (InterruptedException ignored) {
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
// InterruptedException clears the thread's interrupt status. Since we can't
|
||||
// handle that here, we will re-interrupt the thread to set the interrupt
|
||||
// status back to true.
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,11 +244,18 @@ public class ComputerManagerService extends Service {
|
||||
while (activePolls.get() != 0) {
|
||||
try {
|
||||
Thread.sleep(250);
|
||||
} catch (InterruptedException ignored) {}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
// InterruptedException clears the thread's interrupt status. Since we can't
|
||||
// handle that here, we will re-interrupt the thread to set the interrupt
|
||||
// status back to true.
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addComputerBlocking(ComputerDetails fakeDetails) {
|
||||
public boolean addComputerBlocking(ComputerDetails fakeDetails) throws InterruptedException {
|
||||
return ComputerManagerService.this.addComputerBlocking(fakeDetails);
|
||||
}
|
||||
|
||||
@@ -399,9 +409,18 @@ public class ComputerManagerService extends Service {
|
||||
details.ipv6Address = computer.getIpv6Address().getHostAddress();
|
||||
}
|
||||
|
||||
// Kick off a serverinfo poll on this machine
|
||||
if (!addComputerBlocking(details)) {
|
||||
LimeLog.warning("Auto-discovered PC failed to respond: "+details);
|
||||
try {
|
||||
// Kick off a blocking serverinfo poll on this machine
|
||||
if (!addComputerBlocking(details)) {
|
||||
LimeLog.warning("Auto-discovered PC failed to respond: "+details);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
// InterruptedException clears the thread's interrupt status. Since we can't
|
||||
// handle that here, we will re-interrupt the thread to set the interrupt
|
||||
// status back to true.
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,28 +468,25 @@ public class ComputerManagerService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addComputerBlocking(ComputerDetails fakeDetails) {
|
||||
public boolean addComputerBlocking(ComputerDetails fakeDetails) throws InterruptedException {
|
||||
// Block while we try to fill the details
|
||||
try {
|
||||
// We cannot use runPoll() here because it will attempt to persist the state of the machine
|
||||
// in the database, which would be bad because we don't have our pinned cert loaded yet.
|
||||
if (pollComputer(fakeDetails)) {
|
||||
// See if we have record of this PC to pull its pinned cert
|
||||
synchronized (pollingTuples) {
|
||||
for (PollingTuple tuple : pollingTuples) {
|
||||
if (tuple.computer.uuid.equals(fakeDetails.uuid)) {
|
||||
fakeDetails.serverCert = tuple.computer.serverCert;
|
||||
break;
|
||||
}
|
||||
|
||||
// We cannot use runPoll() here because it will attempt to persist the state of the machine
|
||||
// in the database, which would be bad because we don't have our pinned cert loaded yet.
|
||||
if (pollComputer(fakeDetails)) {
|
||||
// See if we have record of this PC to pull its pinned cert
|
||||
synchronized (pollingTuples) {
|
||||
for (PollingTuple tuple : pollingTuples) {
|
||||
if (tuple.computer.uuid.equals(fakeDetails.uuid)) {
|
||||
fakeDetails.serverCert = tuple.computer.serverCert;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Poll again, possibly with the pinned cert, to get accurate pairing information.
|
||||
// This will insert the host into the database too.
|
||||
runPoll(fakeDetails, true, 0);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
return false;
|
||||
|
||||
// Poll again, possibly with the pinned cert, to get accurate pairing information.
|
||||
// This will insert the host into the database too.
|
||||
runPoll(fakeDetails, true, 0);
|
||||
}
|
||||
|
||||
// If the machine is reachable, it was successful
|
||||
@@ -528,11 +544,6 @@ public class ComputerManagerService extends Service {
|
||||
}
|
||||
|
||||
private ComputerDetails tryPollIp(ComputerDetails details, String address) {
|
||||
// Fast poll this address first to determine if we can connect at the TCP layer
|
||||
if (!fastPollIp(address)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
NvHTTP http = new NvHTTP(address, idManager.getUniqueId(), details.serverCert,
|
||||
PlatformBinding.getCryptoProvider(ComputerManagerService.this));
|
||||
@@ -551,146 +562,140 @@ public class ComputerManagerService extends Service {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set the new active address
|
||||
newDetails.activeAddress = address;
|
||||
|
||||
return newDetails;
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
} catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Just try to establish a TCP connection to speculatively detect a running
|
||||
// GFE server
|
||||
private boolean fastPollIp(String address) {
|
||||
if (address == null) {
|
||||
// Don't bother if our address is null
|
||||
return false;
|
||||
private static class ParallelPollTuple {
|
||||
public String address;
|
||||
public ComputerDetails existingDetails;
|
||||
|
||||
public boolean complete;
|
||||
public Thread pollingThread;
|
||||
public ComputerDetails returnedDetails;
|
||||
|
||||
public ParallelPollTuple(String address, ComputerDetails existingDetails) {
|
||||
this.address = address;
|
||||
this.existingDetails = existingDetails;
|
||||
}
|
||||
|
||||
Socket s = new Socket();
|
||||
try {
|
||||
s.connect(new InetSocketAddress(address, NvHTTP.HTTPS_PORT), FAST_POLL_TIMEOUT);
|
||||
s.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
public void interrupt() {
|
||||
if (pollingThread != null) {
|
||||
pollingThread.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startFastPollThread(final String address, final boolean[] info) {
|
||||
Thread t = new Thread() {
|
||||
private void startParallelPollThread(ParallelPollTuple tuple, HashSet<String> uniqueAddresses) {
|
||||
// Don't bother starting a polling thread for an address that doesn't exist
|
||||
// or if the address has already been polled with an earlier tuple
|
||||
if (tuple.address == null || !uniqueAddresses.add(tuple.address)) {
|
||||
tuple.complete = true;
|
||||
tuple.returnedDetails = null;
|
||||
return;
|
||||
}
|
||||
|
||||
tuple.pollingThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean pollRes = fastPollIp(address);
|
||||
ComputerDetails details = tryPollIp(tuple.existingDetails, tuple.address);
|
||||
|
||||
synchronized (info) {
|
||||
info[0] = true; // Done
|
||||
info[1] = pollRes; // Polling result
|
||||
synchronized (tuple) {
|
||||
tuple.complete = true; // Done
|
||||
tuple.returnedDetails = details; // Polling result
|
||||
|
||||
info.notify();
|
||||
tuple.notify();
|
||||
}
|
||||
}
|
||||
};
|
||||
t.setName("Fast Poll - "+address);
|
||||
t.start();
|
||||
tuple.pollingThread.setName("Parallel Poll - "+tuple.address+" - "+tuple.existingDetails.name);
|
||||
tuple.pollingThread.start();
|
||||
}
|
||||
|
||||
private String fastPollPc(final String localAddress, final String remoteAddress, final String manualAddress, final String ipv6Address) throws InterruptedException {
|
||||
final boolean[] remoteInfo = new boolean[2];
|
||||
final boolean[] localInfo = new boolean[2];
|
||||
final boolean[] manualInfo = new boolean[2];
|
||||
final boolean[] ipv6Info = new boolean[2];
|
||||
private ComputerDetails parallelPollPc(ComputerDetails details) throws InterruptedException {
|
||||
ParallelPollTuple localInfo = new ParallelPollTuple(details.localAddress, details);
|
||||
ParallelPollTuple manualInfo = new ParallelPollTuple(details.manualAddress, details);
|
||||
ParallelPollTuple remoteInfo = new ParallelPollTuple(details.remoteAddress, details);
|
||||
ParallelPollTuple ipv6Info = new ParallelPollTuple(details.ipv6Address, details);
|
||||
|
||||
startFastPollThread(localAddress, localInfo);
|
||||
startFastPollThread(remoteAddress, remoteInfo);
|
||||
startFastPollThread(manualAddress, manualInfo);
|
||||
startFastPollThread(ipv6Address, ipv6Info);
|
||||
// These must be started in order of precedence for the deduplication algorithm
|
||||
// to result in the correct behavior.
|
||||
HashSet<String> uniqueAddresses = new HashSet<>();
|
||||
startParallelPollThread(localInfo, uniqueAddresses);
|
||||
startParallelPollThread(manualInfo, uniqueAddresses);
|
||||
startParallelPollThread(remoteInfo, uniqueAddresses);
|
||||
startParallelPollThread(ipv6Info, uniqueAddresses);
|
||||
|
||||
// Check local first
|
||||
synchronized (localInfo) {
|
||||
while (!localInfo[0]) {
|
||||
localInfo.wait(500);
|
||||
try {
|
||||
// Check local first
|
||||
synchronized (localInfo) {
|
||||
while (!localInfo.complete) {
|
||||
localInfo.wait();
|
||||
}
|
||||
|
||||
if (localInfo.returnedDetails != null) {
|
||||
localInfo.returnedDetails.activeAddress = localInfo.address;
|
||||
return localInfo.returnedDetails;
|
||||
}
|
||||
}
|
||||
|
||||
if (localInfo[1]) {
|
||||
return localAddress;
|
||||
}
|
||||
}
|
||||
// Now manual
|
||||
synchronized (manualInfo) {
|
||||
while (!manualInfo.complete) {
|
||||
manualInfo.wait();
|
||||
}
|
||||
|
||||
// Now manual
|
||||
synchronized (manualInfo) {
|
||||
while (!manualInfo[0]) {
|
||||
manualInfo.wait(500);
|
||||
if (manualInfo.returnedDetails != null) {
|
||||
manualInfo.returnedDetails.activeAddress = manualInfo.address;
|
||||
return manualInfo.returnedDetails;
|
||||
}
|
||||
}
|
||||
|
||||
if (manualInfo[1]) {
|
||||
return manualAddress;
|
||||
}
|
||||
}
|
||||
// Now remote IPv4
|
||||
synchronized (remoteInfo) {
|
||||
while (!remoteInfo.complete) {
|
||||
remoteInfo.wait();
|
||||
}
|
||||
|
||||
// Now remote IPv4
|
||||
synchronized (remoteInfo) {
|
||||
while (!remoteInfo[0]) {
|
||||
remoteInfo.wait(500);
|
||||
if (remoteInfo.returnedDetails != null) {
|
||||
remoteInfo.returnedDetails.activeAddress = remoteInfo.address;
|
||||
return remoteInfo.returnedDetails;
|
||||
}
|
||||
}
|
||||
|
||||
if (remoteInfo[1]) {
|
||||
return remoteAddress;
|
||||
}
|
||||
}
|
||||
// Now global IPv6
|
||||
synchronized (ipv6Info) {
|
||||
while (!ipv6Info.complete) {
|
||||
ipv6Info.wait();
|
||||
}
|
||||
|
||||
// Now global IPv6
|
||||
synchronized (ipv6Info) {
|
||||
while (!ipv6Info[0]) {
|
||||
ipv6Info.wait(500);
|
||||
}
|
||||
|
||||
if (ipv6Info[1]) {
|
||||
return ipv6Address;
|
||||
if (ipv6Info.returnedDetails != null) {
|
||||
ipv6Info.returnedDetails.activeAddress = ipv6Info.address;
|
||||
return ipv6Info.returnedDetails;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Stop any further polling if we've found a working address or we've been
|
||||
// interrupted by an attempt to stop polling.
|
||||
localInfo.interrupt();
|
||||
manualInfo.interrupt();
|
||||
remoteInfo.interrupt();
|
||||
ipv6Info.interrupt();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean pollComputer(ComputerDetails details) throws InterruptedException {
|
||||
ComputerDetails polledDetails;
|
||||
|
||||
// Do a TCP-level connection to the HTTP server to see if it's listening.
|
||||
// Do not write this address to details.activeAddress because:
|
||||
// a) it's only a candidate and may be wrong (multiple PCs behind a single router)
|
||||
// b) if it's null, it will be unexpectedly nulling the activeAddress of a possibly online PC
|
||||
LimeLog.info("Starting fast poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress+", "+details.ipv6Address+")");
|
||||
String candidateAddress = fastPollPc(details.localAddress, details.remoteAddress, details.manualAddress, details.ipv6Address);
|
||||
LimeLog.info("Fast poll for "+details.name+" returned candidate address: "+candidateAddress);
|
||||
|
||||
// If no connection could be established to either IP address, there's nothing we can do
|
||||
if (candidateAddress == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try using the active address from fast-poll
|
||||
polledDetails = tryPollIp(details, candidateAddress);
|
||||
if (polledDetails == null) {
|
||||
// If that failed, try all unique addresses except what we've
|
||||
// already tried
|
||||
HashSet<String> uniqueAddresses = new HashSet<>();
|
||||
uniqueAddresses.add(details.localAddress);
|
||||
uniqueAddresses.add(details.manualAddress);
|
||||
uniqueAddresses.add(details.remoteAddress);
|
||||
uniqueAddresses.add(details.ipv6Address);
|
||||
for (String addr : uniqueAddresses) {
|
||||
if (addr == null || addr.equals(candidateAddress)) {
|
||||
continue;
|
||||
}
|
||||
polledDetails = tryPollIp(details, addr);
|
||||
if (polledDetails != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Poll all addresses in parallel to speed up the process
|
||||
LimeLog.info("Starting parallel poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress+", "+details.ipv6Address+")");
|
||||
ComputerDetails polledDetails = parallelPollPc(details);
|
||||
LimeLog.info("Parallel poll for "+details.name+" returned address: "+details.activeAddress);
|
||||
|
||||
if (polledDetails != null) {
|
||||
details.update(polledDetails);
|
||||
|
||||
@@ -128,6 +128,13 @@ public class CachedAppAssetLoader {
|
||||
try {
|
||||
Thread.sleep((int) (1000 + (Math.random() * 500)));
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
// InterruptedException clears the thread's interrupt status. Since we can't
|
||||
// handle that here, we will re-interrupt the thread to set the interrupt
|
||||
// status back to true.
|
||||
Thread.currentThread().interrupt();
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ public class ConnectionContext {
|
||||
// This is the version quad from the appversion tag of /serverinfo
|
||||
public String serverAppVersion;
|
||||
public String serverGfeVersion;
|
||||
|
||||
// This is the sessionUrl0 tag from /resume and /launch
|
||||
public String rtspSessionUrl;
|
||||
|
||||
public int negotiatedWidth, negotiatedHeight;
|
||||
public boolean negotiatedHdr;
|
||||
|
||||
@@ -7,6 +7,8 @@ import java.nio.ByteBuffer;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import javax.crypto.KeyGenerator;
|
||||
@@ -33,12 +35,20 @@ public class NvConnection {
|
||||
private ConnectionContext context;
|
||||
private static Semaphore connectionAllowed = new Semaphore(1);
|
||||
private final boolean isMonkey;
|
||||
|
||||
public NvConnection(String host, String uniqueId, StreamConfiguration config, LimelightCryptoProvider cryptoProvider, X509Certificate serverCert)
|
||||
private final boolean batchMouseInput;
|
||||
|
||||
private static final int MOUSE_BATCH_PERIOD_MS = 5;
|
||||
private Timer mouseInputTimer;
|
||||
private final Object mouseInputLock = new Object();
|
||||
private short relMouseX, relMouseY, relMouseWidth, relMouseHeight;
|
||||
private short absMouseX, absMouseY, absMouseWidth, absMouseHeight;
|
||||
|
||||
public NvConnection(String host, String uniqueId, StreamConfiguration config, LimelightCryptoProvider cryptoProvider, X509Certificate serverCert, boolean batchMouseInput)
|
||||
{
|
||||
this.host = host;
|
||||
this.cryptoProvider = cryptoProvider;
|
||||
this.uniqueId = uniqueId;
|
||||
this.batchMouseInput = batchMouseInput;
|
||||
|
||||
this.context = new ConnectionContext();
|
||||
this.context.streamConfig = config;
|
||||
@@ -70,6 +80,11 @@ public class NvConnection {
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
// Stop sending additional input
|
||||
if (mouseInputTimer != null) {
|
||||
mouseInputTimer.cancel();
|
||||
}
|
||||
|
||||
// Interrupt any pending connection. This is thread-safe.
|
||||
MoonBridge.interruptConnection();
|
||||
|
||||
@@ -83,6 +98,24 @@ public class NvConnection {
|
||||
// Now a pending connection can be processed
|
||||
connectionAllowed.release();
|
||||
}
|
||||
|
||||
private void flushMousePosition() {
|
||||
synchronized (mouseInputLock) {
|
||||
if (relMouseX != 0 || relMouseY != 0) {
|
||||
if (relMouseWidth != 0 || relMouseHeight != 0) {
|
||||
MoonBridge.sendMouseMoveAsMousePosition(relMouseX, relMouseY, relMouseWidth, relMouseHeight);
|
||||
}
|
||||
else {
|
||||
MoonBridge.sendMouseMove(relMouseX, relMouseY);
|
||||
}
|
||||
relMouseX = relMouseY = relMouseWidth = relMouseHeight = 0;
|
||||
}
|
||||
if (absMouseX != 0 || absMouseY != 0 || absMouseWidth != 0 || absMouseHeight != 0) {
|
||||
MoonBridge.sendMousePosition(absMouseX, absMouseY, absMouseWidth, absMouseHeight);
|
||||
absMouseX = absMouseY = absMouseWidth = absMouseHeight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean startApp() throws XmlPullParserException, IOException
|
||||
{
|
||||
@@ -122,7 +155,7 @@ public class NvConnection {
|
||||
}
|
||||
else if ((context.streamConfig.getWidth() > 4096 || context.streamConfig.getHeight() > 4096) &&
|
||||
!context.streamConfig.getHevcSupported()) {
|
||||
context.connListener.displayMessage("Your streaming device must support H.265 to stream at resolutions above 4K.");
|
||||
context.connListener.displayMessage("Your streaming device must support HEVC to stream at resolutions above 4K.");
|
||||
return false;
|
||||
}
|
||||
else if (context.streamConfig.getHeight() >= 2160 && !h.supports4K(serverInfo)) {
|
||||
@@ -275,7 +308,7 @@ public class NvConnection {
|
||||
synchronized (MoonBridge.class) {
|
||||
MoonBridge.setupBridge(videoDecoderRenderer, audioRenderer, connectionListener);
|
||||
int ret = MoonBridge.startConnection(context.serverAddress,
|
||||
context.serverAppVersion, context.serverGfeVersion,
|
||||
context.serverAppVersion, context.serverGfeVersion, context.rtspSessionUrl,
|
||||
context.negotiatedWidth, context.negotiatedHeight,
|
||||
context.streamConfig.getRefreshRate(), context.streamConfig.getBitrate(),
|
||||
context.streamConfig.getMaxPacketSize(),
|
||||
@@ -292,6 +325,21 @@ public class NvConnection {
|
||||
// to stop the connection themselves. We need to release their
|
||||
// semaphore count for them.
|
||||
connectionAllowed.release();
|
||||
return;
|
||||
}
|
||||
|
||||
if (batchMouseInput) {
|
||||
// High polling rate mice can cause GeForce Experience's input queue to get backed up,
|
||||
// causing massive input latency. We counter this by limiting our mouse events to 200 Hz
|
||||
// which appears to avoid triggering the issue on all known configurations.
|
||||
mouseInputTimer = new Timer("MouseInput", true);
|
||||
mouseInputTimer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Flush the mouse position every 5 ms
|
||||
flushMousePosition();
|
||||
}
|
||||
}, MOUSE_BATCH_PERIOD_MS, MOUSE_BATCH_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -301,20 +349,65 @@ public class NvConnection {
|
||||
public void sendMouseMove(final short deltaX, final short deltaY)
|
||||
{
|
||||
if (!isMonkey) {
|
||||
MoonBridge.sendMouseMove(deltaX, deltaY);
|
||||
synchronized (mouseInputLock) {
|
||||
relMouseX += deltaX;
|
||||
relMouseY += deltaY;
|
||||
|
||||
// Reset these to ensure we don't send this as a position update
|
||||
relMouseWidth = 0;
|
||||
relMouseHeight = 0;
|
||||
}
|
||||
|
||||
if (!batchMouseInput) {
|
||||
flushMousePosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMousePosition(short x, short y, short referenceWidth, short referenceHeight)
|
||||
{
|
||||
if (!isMonkey) {
|
||||
MoonBridge.sendMousePosition(x, y, referenceWidth, referenceHeight);
|
||||
synchronized (mouseInputLock) {
|
||||
absMouseX = x;
|
||||
absMouseY = y;
|
||||
absMouseWidth = referenceWidth;
|
||||
absMouseHeight = referenceHeight;
|
||||
}
|
||||
|
||||
if (!batchMouseInput) {
|
||||
flushMousePosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void sendMouseMoveAsMousePosition(short deltaX, short deltaY, short referenceWidth, short referenceHeight)
|
||||
{
|
||||
if (!isMonkey) {
|
||||
synchronized (mouseInputLock) {
|
||||
// Only accumulate the delta if the reference size is the same
|
||||
if (relMouseWidth == referenceWidth && relMouseHeight == referenceHeight) {
|
||||
relMouseX += deltaX;
|
||||
relMouseY += deltaY;
|
||||
}
|
||||
else {
|
||||
relMouseX = deltaX;
|
||||
relMouseY = deltaY;
|
||||
}
|
||||
|
||||
relMouseWidth = referenceWidth;
|
||||
relMouseHeight = referenceHeight;
|
||||
}
|
||||
|
||||
if (!batchMouseInput) {
|
||||
flushMousePosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMouseButtonDown(final byte mouseButton)
|
||||
{
|
||||
if (!isMonkey) {
|
||||
flushMousePosition();
|
||||
MoonBridge.sendMouseButton(MouseButtonPacket.PRESS_EVENT, mouseButton);
|
||||
}
|
||||
}
|
||||
@@ -322,6 +415,7 @@ public class NvConnection {
|
||||
public void sendMouseButtonUp(final byte mouseButton)
|
||||
{
|
||||
if (!isMonkey) {
|
||||
flushMousePosition();
|
||||
MoonBridge.sendMouseButton(MouseButtonPacket.RELEASE_EVENT, mouseButton);
|
||||
}
|
||||
}
|
||||
@@ -357,16 +451,24 @@ public class NvConnection {
|
||||
|
||||
public void sendMouseScroll(final byte scrollClicks) {
|
||||
if (!isMonkey) {
|
||||
flushMousePosition();
|
||||
MoonBridge.sendMouseScroll(scrollClicks);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMouseHighResScroll(final short scrollAmount) {
|
||||
if (!isMonkey) {
|
||||
flushMousePosition();
|
||||
MoonBridge.sendMouseHighResScroll(scrollAmount);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendUtf8Text(final String text) {
|
||||
if (!isMonkey) {
|
||||
MoonBridge.sendUtf8Text(text);
|
||||
}
|
||||
}
|
||||
|
||||
public static String findExternalAddressForMdns(String stunHostname, int stunPort) {
|
||||
return MoonBridge.findExternalAddressIP4(stunHostname, stunPort);
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@ public interface NvConnectionListener {
|
||||
void displayTransientMessage(String message);
|
||||
|
||||
void rumble(short controllerNumber, short lowFreqMotor, short highFreqMotor);
|
||||
|
||||
void setHdrMode(boolean enabled);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,11 @@ public abstract class VideoDecoderRenderer {
|
||||
// This is called once for each frame-start NALU. This means it will be called several times
|
||||
// for an IDR frame which contains several parameter sets and the I-frame data.
|
||||
public abstract int submitDecodeUnit(byte[] decodeUnitData, int decodeUnitLength, int decodeUnitType,
|
||||
int frameNumber, long receiveTimeMs, long enqueueTimeMs);
|
||||
int frameNumber, int frameType, long receiveTimeMs, long enqueueTimeMs);
|
||||
|
||||
public abstract void cleanup();
|
||||
|
||||
public abstract int getCapabilities();
|
||||
|
||||
public abstract void setHdrMode(boolean enabled);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class NvApp {
|
||||
public String toString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("Name: ").append(appName).append("\n");
|
||||
str.append("HDR: ").append(hdrSupported ? "Yes" : "No").append("\n");
|
||||
str.append("HDR Supported: ").append(hdrSupported ? "Yes" : "Unknown").append("\n");
|
||||
str.append("ID: ").append(appId).append("\n");
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
@@ -9,10 +9,8 @@ import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.Socket;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
@@ -53,6 +51,7 @@ import com.limelight.nvstream.ConnectionContext;
|
||||
import com.limelight.nvstream.http.PairingManager.PairState;
|
||||
|
||||
import okhttp3.ConnectionPool;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
@@ -71,8 +70,8 @@ public class NvHTTP {
|
||||
// Print URL and content to logcat on debug builds
|
||||
private static boolean verbose = BuildConfig.DEBUG;
|
||||
|
||||
public String baseUrlHttps;
|
||||
public String baseUrlHttp;
|
||||
private HttpUrl baseUrlHttps;
|
||||
private HttpUrl baseUrlHttp;
|
||||
|
||||
private OkHttpClient httpClient;
|
||||
private OkHttpClient httpClientWithReadTimeout;
|
||||
@@ -173,6 +172,7 @@ public class NvHTTP {
|
||||
.hostnameVerifier(hv)
|
||||
.readTimeout(0, TimeUnit.MILLISECONDS)
|
||||
.connectTimeout(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.proxy(Proxy.NO_PROXY)
|
||||
.build();
|
||||
|
||||
httpClientWithReadTimeout = httpClient.newBuilder()
|
||||
@@ -190,22 +190,26 @@ public class NvHTTP {
|
||||
initializeHttpState(cryptoProvider);
|
||||
|
||||
try {
|
||||
// The URI constructor takes care of escaping IPv6 literals
|
||||
this.baseUrlHttps = new URI("https", null, address, HTTPS_PORT, null, null, null).toString();
|
||||
this.baseUrlHttp = new URI("http", null, address, HTTP_PORT, null, null, null).toString();
|
||||
} catch (URISyntaxException e) {
|
||||
// Encapsulate URISyntaxException into IOException for callers to handle more easily
|
||||
this.baseUrlHttp = new HttpUrl.Builder()
|
||||
.scheme("http")
|
||||
.host(address)
|
||||
.port(HTTP_PORT)
|
||||
.build();
|
||||
|
||||
this.baseUrlHttps = new HttpUrl.Builder()
|
||||
.scheme("https")
|
||||
.host(address)
|
||||
.port(HTTPS_PORT)
|
||||
.build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Encapsulate IllegalArgumentException into IOException for callers to handle more easily
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
this.pm = new PairingManager(this, cryptoProvider);
|
||||
}
|
||||
|
||||
String buildUniqueIdUuidString() {
|
||||
return "uniqueid="+uniqueId+"&uuid="+UUID.randomUUID();
|
||||
}
|
||||
|
||||
static String getXmlString(Reader r, String tagname) throws XmlPullParserException, IOException {
|
||||
|
||||
static String getXmlString(Reader r, String tagname, boolean throwIfMissing) throws XmlPullParserException, IOException {
|
||||
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
XmlPullParser xpp = factory.newPullParser();
|
||||
@@ -234,11 +238,19 @@ public class NvHTTP {
|
||||
eventType = xpp.next();
|
||||
}
|
||||
|
||||
if (throwIfMissing) {
|
||||
// We throw an XmlPullParserException here for ease of handling in all the various callers.
|
||||
// We could also throw an IOException, but some callers expect those in cases where the
|
||||
// host may not be reachable. We want to distinguish unreachable hosts vs. hosts that
|
||||
// are returning garbage XML to us, so we use XmlPullParserException instead.
|
||||
throw new XmlPullParserException("Missing mandatory field in host response: "+tagname);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static String getXmlString(String str, String tagname) throws XmlPullParserException, IOException {
|
||||
return getXmlString(new StringReader(str), tagname);
|
||||
static String getXmlString(String str, String tagname, boolean throwIfMissing) throws XmlPullParserException, IOException {
|
||||
return getXmlString(new StringReader(str), tagname, throwIfMissing);
|
||||
}
|
||||
|
||||
private static void verifyResponseStatus(XmlPullParser xpp) throws GfeHttpResponseException {
|
||||
@@ -272,7 +284,7 @@ public class NvHTTP {
|
||||
if (serverCert != null) {
|
||||
try {
|
||||
try {
|
||||
resp = openHttpConnectionToString(baseUrlHttps + "/serverinfo?"+buildUniqueIdUuidString(), true);
|
||||
resp = openHttpConnectionToString(baseUrlHttps, "serverinfo", true);
|
||||
} catch (SSLHandshakeException e) {
|
||||
// Detect if we failed due to a server cert mismatch
|
||||
if (e.getCause() instanceof CertificateException) {
|
||||
@@ -292,7 +304,7 @@ public class NvHTTP {
|
||||
catch (GfeHttpResponseException e) {
|
||||
if (e.getErrorCode() == 401) {
|
||||
// Cert validation error - fall back to HTTP
|
||||
return openHttpConnectionToString(baseUrlHttp + "/serverinfo", true);
|
||||
return openHttpConnectionToString(baseUrlHttp, "serverinfo", true);
|
||||
}
|
||||
|
||||
// If it's not a cert validation error, throw it
|
||||
@@ -303,7 +315,7 @@ public class NvHTTP {
|
||||
}
|
||||
else {
|
||||
// No pinned cert, so use HTTP
|
||||
return openHttpConnectionToString(baseUrlHttp + "/serverinfo", true);
|
||||
return openHttpConnectionToString(baseUrlHttp , "serverinfo", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,21 +323,21 @@ public class NvHTTP {
|
||||
ComputerDetails details = new ComputerDetails();
|
||||
String serverInfo = getServerInfo();
|
||||
|
||||
details.name = getXmlString(serverInfo, "hostname");
|
||||
details.name = getXmlString(serverInfo, "hostname", false);
|
||||
if (details.name == null || details.name.isEmpty()) {
|
||||
details.name = "UNKNOWN";
|
||||
}
|
||||
|
||||
details.uuid = getXmlString(serverInfo, "uniqueid");
|
||||
details.macAddress = getXmlString(serverInfo, "mac");
|
||||
details.localAddress = getXmlString(serverInfo, "LocalIP");
|
||||
// UUID is mandatory to determine which machine is responding
|
||||
details.uuid = getXmlString(serverInfo, "uniqueid", true);
|
||||
|
||||
// This may be null, but that's okay
|
||||
details.remoteAddress = getXmlString(serverInfo, "ExternalIP");
|
||||
details.macAddress = getXmlString(serverInfo, "mac", false);
|
||||
details.localAddress = getXmlString(serverInfo, "LocalIP", false);
|
||||
|
||||
// This is missing on on recent GFE versions
|
||||
details.remoteAddress = getXmlString(serverInfo, "ExternalIP", false);
|
||||
|
||||
// This has some extra logic to always report unpaired if the pinned cert isn't there
|
||||
details.pairState = getPairState(serverInfo);
|
||||
|
||||
details.runningGameId = getCurrentGame(serverInfo);
|
||||
|
||||
// We could reach it so it's online
|
||||
@@ -357,12 +369,26 @@ public class NvHTTP {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpUrl getCompleteUrl(HttpUrl baseUrl, String path, String query) {
|
||||
return baseUrl.newBuilder()
|
||||
.addPathSegment(path)
|
||||
.query(query)
|
||||
.addQueryParameter("uniqueid", uniqueId)
|
||||
.addQueryParameter("uuid", UUID.randomUUID().toString())
|
||||
.build();
|
||||
}
|
||||
|
||||
private ResponseBody openHttpConnection(HttpUrl baseUrl, String path, boolean enableReadTimeout) throws IOException {
|
||||
return openHttpConnection(baseUrl, path, null, enableReadTimeout);
|
||||
}
|
||||
|
||||
// Read timeout should be enabled for any HTTP query that requires no outside action
|
||||
// on the GFE server. Examples of queries that DO require outside action are launch, resume, and quit.
|
||||
// The initial pair query does require outside action (user entering a PIN) but subsequent pairing
|
||||
// queries do not.
|
||||
private ResponseBody openHttpConnection(String url, boolean enableReadTimeout) throws IOException {
|
||||
Request request = new Request.Builder().url(url).get().build();
|
||||
private ResponseBody openHttpConnection(HttpUrl baseUrl, String path, String query, boolean enableReadTimeout) throws IOException {
|
||||
HttpUrl completeUrl = getCompleteUrl(baseUrl, path, query);
|
||||
Request request = new Request.Builder().url(completeUrl).get().build();
|
||||
Response response;
|
||||
|
||||
if (enableReadTimeout) {
|
||||
@@ -384,30 +410,31 @@ public class NvHTTP {
|
||||
}
|
||||
|
||||
if (response.code() == 404) {
|
||||
throw new FileNotFoundException(url);
|
||||
throw new FileNotFoundException(completeUrl.toString());
|
||||
}
|
||||
else {
|
||||
throw new GfeHttpResponseException(response.code(), response.message());
|
||||
}
|
||||
}
|
||||
|
||||
String openHttpConnectionToString(String url, boolean enableReadTimeout) throws IOException {
|
||||
try {
|
||||
if (verbose) {
|
||||
LimeLog.info("Requesting URL: "+url);
|
||||
}
|
||||
|
||||
ResponseBody resp = openHttpConnection(url, enableReadTimeout);
|
||||
private String openHttpConnectionToString(HttpUrl baseUrl, String path, boolean enableReadTimeout) throws IOException {
|
||||
return openHttpConnectionToString(baseUrl, path, null, enableReadTimeout);
|
||||
}
|
||||
|
||||
private String openHttpConnectionToString(HttpUrl baseUrl, String path, String query, boolean enableReadTimeout) throws IOException {
|
||||
try {
|
||||
ResponseBody resp = openHttpConnection(baseUrl, path, query, enableReadTimeout);
|
||||
String respString = resp.string();
|
||||
resp.close();
|
||||
|
||||
if (verbose) {
|
||||
LimeLog.info(url+" -> "+respString);
|
||||
if (verbose && !path.equals("serverinfo")) {
|
||||
LimeLog.info(getCompleteUrl(baseUrl, path, query)+" -> "+respString);
|
||||
}
|
||||
|
||||
return respString;
|
||||
} catch (IOException e) {
|
||||
if (verbose) {
|
||||
if (verbose && !path.equals("serverinfo")) {
|
||||
LimeLog.warning(getCompleteUrl(baseUrl, path, query)+" -> "+e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -416,7 +443,8 @@ public class NvHTTP {
|
||||
}
|
||||
|
||||
public String getServerVersion(String serverInfo) throws XmlPullParserException, IOException {
|
||||
return getXmlString(serverInfo, "appversion");
|
||||
// appversion is present in all supported GFE versions
|
||||
return getXmlString(serverInfo, "appversion", true);
|
||||
}
|
||||
|
||||
public PairingManager.PairState getPairState() throws IOException, XmlPullParserException {
|
||||
@@ -424,15 +452,14 @@ public class NvHTTP {
|
||||
}
|
||||
|
||||
public PairingManager.PairState getPairState(String serverInfo) throws IOException, XmlPullParserException {
|
||||
if (!NvHTTP.getXmlString(serverInfo, "PairStatus").equals("1")) {
|
||||
return PairState.NOT_PAIRED;
|
||||
}
|
||||
|
||||
return PairState.PAIRED;
|
||||
// appversion is present in all supported GFE versions
|
||||
return NvHTTP.getXmlString(serverInfo, "PairStatus", true).equals("1") ?
|
||||
PairState.PAIRED : PairState.NOT_PAIRED;
|
||||
}
|
||||
|
||||
public long getMaxLumaPixelsH264(String serverInfo) throws XmlPullParserException, IOException {
|
||||
String str = getXmlString(serverInfo, "MaxLumaPixelsH264");
|
||||
// MaxLumaPixelsH264 wasn't present on old GFE versions
|
||||
String str = getXmlString(serverInfo, "MaxLumaPixelsH264", false);
|
||||
if (str != null) {
|
||||
return Long.parseLong(str);
|
||||
} else {
|
||||
@@ -441,7 +468,8 @@ public class NvHTTP {
|
||||
}
|
||||
|
||||
public long getMaxLumaPixelsHEVC(String serverInfo) throws XmlPullParserException, IOException {
|
||||
String str = getXmlString(serverInfo, "MaxLumaPixelsHEVC");
|
||||
// MaxLumaPixelsHEVC wasn't present on old GFE versions
|
||||
String str = getXmlString(serverInfo, "MaxLumaPixelsHEVC", false);
|
||||
if (str != null) {
|
||||
return Long.parseLong(str);
|
||||
} else {
|
||||
@@ -458,7 +486,8 @@ public class NvHTTP {
|
||||
// Bit 10: HEVC Main10 4:4:4
|
||||
// Bit 11: ???
|
||||
public long getServerCodecModeSupport(String serverInfo) throws XmlPullParserException, IOException {
|
||||
String str = getXmlString(serverInfo, "ServerCodecModeSupport");
|
||||
// ServerCodecModeSupport wasn't present on old GFE versions
|
||||
String str = getXmlString(serverInfo, "ServerCodecModeSupport", false);
|
||||
if (str != null) {
|
||||
return Long.parseLong(str);
|
||||
} else {
|
||||
@@ -467,16 +496,18 @@ public class NvHTTP {
|
||||
}
|
||||
|
||||
public String getGpuType(String serverInfo) throws XmlPullParserException, IOException {
|
||||
return getXmlString(serverInfo, "gputype");
|
||||
// ServerCodecModeSupport wasn't present on old GFE versions
|
||||
return getXmlString(serverInfo, "gputype", false);
|
||||
}
|
||||
|
||||
public String getGfeVersion(String serverInfo) throws XmlPullParserException, IOException {
|
||||
return getXmlString(serverInfo, "GfeVersion");
|
||||
// ServerCodecModeSupport wasn't present on old GFE versions
|
||||
return getXmlString(serverInfo, "GfeVersion", false);
|
||||
}
|
||||
|
||||
public boolean supports4K(String serverInfo) throws XmlPullParserException, IOException {
|
||||
// Only allow 4K on GFE 3.x
|
||||
String gfeVersionStr = getXmlString(serverInfo, "GfeVersion");
|
||||
// Only allow 4K on GFE 3.x. GfeVersion wasn't present on very old versions of GFE.
|
||||
String gfeVersionStr = getXmlString(serverInfo, "GfeVersion", false);
|
||||
if (gfeVersionStr == null || gfeVersionStr.startsWith("2.")) {
|
||||
return false;
|
||||
}
|
||||
@@ -488,10 +519,8 @@ public class NvHTTP {
|
||||
// GFE 2.8 started keeping currentgame set to the last game played. As a result, it no longer
|
||||
// has the semantics that its name would indicate. To contain the effects of this change as much
|
||||
// as possible, we'll force the current game to zero if the server isn't in a streaming session.
|
||||
String serverState = getXmlString(serverInfo, "state");
|
||||
if (serverState != null && serverState.endsWith("_SERVER_BUSY")) {
|
||||
String game = getXmlString(serverInfo, "currentgame");
|
||||
return Integer.parseInt(game);
|
||||
if (getXmlString(serverInfo, "state", true).endsWith("_SERVER_BUSY")) {
|
||||
return Integer.parseInt(getXmlString(serverInfo, "currentgame", true));
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
@@ -588,8 +617,8 @@ public class NvHTTP {
|
||||
return appList;
|
||||
}
|
||||
|
||||
public String getAppListRaw() throws MalformedURLException, IOException {
|
||||
return openHttpConnectionToString(baseUrlHttps + "/applist?"+buildUniqueIdUuidString(), true);
|
||||
public String getAppListRaw() throws IOException {
|
||||
return openHttpConnectionToString(baseUrlHttps, "applist", true);
|
||||
}
|
||||
|
||||
public LinkedList<NvApp> getAppList() throws GfeHttpResponseException, IOException, XmlPullParserException {
|
||||
@@ -598,20 +627,31 @@ public class NvHTTP {
|
||||
return getAppListByReader(new StringReader(getAppListRaw()));
|
||||
}
|
||||
else {
|
||||
ResponseBody resp = openHttpConnection(baseUrlHttps + "/applist?" + buildUniqueIdUuidString(), true);
|
||||
ResponseBody resp = openHttpConnection(baseUrlHttps, "applist", true);
|
||||
LinkedList<NvApp> appList = getAppListByReader(new InputStreamReader(resp.byteStream()));
|
||||
resp.close();
|
||||
return appList;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String executePairingCommand(String additionalArguments, boolean enableReadTimeout) throws GfeHttpResponseException, IOException {
|
||||
return openHttpConnectionToString(baseUrlHttp, "pair",
|
||||
"devicename=roth&updateState=1&" + additionalArguments,
|
||||
enableReadTimeout);
|
||||
}
|
||||
|
||||
String executePairingChallenge() throws GfeHttpResponseException, IOException {
|
||||
return openHttpConnectionToString(baseUrlHttps, "pair",
|
||||
"devicename=roth&updateState=1&phrase=pairchallenge",
|
||||
true);
|
||||
}
|
||||
|
||||
public void unpair() throws IOException {
|
||||
openHttpConnectionToString(baseUrlHttp + "/unpair?"+buildUniqueIdUuidString(), true);
|
||||
openHttpConnectionToString(baseUrlHttp, "unpair", true);
|
||||
}
|
||||
|
||||
public InputStream getBoxArt(NvApp app) throws IOException {
|
||||
ResponseBody resp = openHttpConnection(baseUrlHttps + "/appasset?"+ buildUniqueIdUuidString() +
|
||||
"&appid=" + app.getAppId() + "&AssetType=2&AssetIdx=0", true);
|
||||
ResponseBody resp = openHttpConnection(baseUrlHttps, "appasset", "appid=" + app.getAppId() + "&AssetType=2&AssetIdx=0", true);
|
||||
return resp.byteStream();
|
||||
}
|
||||
|
||||
@@ -666,9 +706,8 @@ public class NvHTTP {
|
||||
enableSops = false;
|
||||
}
|
||||
|
||||
String xmlStr = openHttpConnectionToString(baseUrlHttps +
|
||||
"/launch?" + buildUniqueIdUuidString() +
|
||||
"&appid=" + appId +
|
||||
String xmlStr = openHttpConnectionToString(baseUrlHttps, "launch",
|
||||
"appid=" + appId +
|
||||
"&mode=" + context.negotiatedWidth + "x" + context.negotiatedHeight + "x" + fps +
|
||||
"&additionalStates=1&sops=" + (enableSops ? 1 : 0) +
|
||||
"&rikey="+bytesToHex(context.riKey.getEncoded()) +
|
||||
@@ -679,24 +718,35 @@ public class NvHTTP {
|
||||
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&remoteControllersBitmap=" + context.streamConfig.getAttachedGamepadMask() : "") +
|
||||
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&gcmap=" + context.streamConfig.getAttachedGamepadMask() : ""),
|
||||
false);
|
||||
String gameSession = getXmlString(xmlStr, "gamesession");
|
||||
return gameSession != null && !gameSession.equals("0");
|
||||
if (!getXmlString(xmlStr, "gamesession", true).equals("0")) {
|
||||
// sessionUrl0 will be missing for older GFE versions
|
||||
context.rtspSessionUrl = getXmlString(xmlStr, "sessionUrl0", false);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean resumeApp(ConnectionContext context) throws IOException, XmlPullParserException {
|
||||
String xmlStr = openHttpConnectionToString(baseUrlHttps + "/resume?" + buildUniqueIdUuidString() +
|
||||
"&rikey="+bytesToHex(context.riKey.getEncoded()) +
|
||||
String xmlStr = openHttpConnectionToString(baseUrlHttps, "resume",
|
||||
"rikey="+bytesToHex(context.riKey.getEncoded()) +
|
||||
"&rikeyid="+context.riKeyId +
|
||||
"&surroundAudioInfo=" + context.streamConfig.getAudioConfiguration().getSurroundAudioInfo(),
|
||||
false);
|
||||
String resume = getXmlString(xmlStr, "resume");
|
||||
return Integer.parseInt(resume) != 0;
|
||||
if (!getXmlString(xmlStr, "resume", true).equals("0")) {
|
||||
// sessionUrl0 will be missing for older GFE versions
|
||||
context.rtspSessionUrl = getXmlString(xmlStr, "sessionUrl0", false);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean quitApp() throws IOException, XmlPullParserException {
|
||||
String xmlStr = openHttpConnectionToString(baseUrlHttps + "/cancel?" + buildUniqueIdUuidString(), false);
|
||||
String cancel = getXmlString(xmlStr, "cancel");
|
||||
if (Integer.parseInt(cancel) == 0) {
|
||||
String xmlStr = openHttpConnectionToString(baseUrlHttps, "cancel", false);
|
||||
if (getXmlString(xmlStr, "cancel", true).equals("0")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.limelight.nvstream.http;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import org.bouncycastle.crypto.BlockCipher;
|
||||
import org.bouncycastle.crypto.engines.AESLightEngine;
|
||||
import org.bouncycastle.crypto.params.KeyParameter;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
@@ -21,7 +21,6 @@ public class PairingManager {
|
||||
|
||||
private PrivateKey pk;
|
||||
private X509Certificate cert;
|
||||
private SecretKey aesKey;
|
||||
private byte[] pemCertBytes;
|
||||
|
||||
private X509Certificate serverCert;
|
||||
@@ -68,7 +67,8 @@ public class PairingManager {
|
||||
|
||||
private X509Certificate extractPlainCert(String text) throws XmlPullParserException, IOException
|
||||
{
|
||||
String certText = NvHTTP.getXmlString(text, "plaincert");
|
||||
// Plaincert may be null if another client is already trying to pair
|
||||
String certText = NvHTTP.getXmlString(text, "plaincert", false);
|
||||
if (certText != null) {
|
||||
byte[] certBytes = hexToBytes(certText);
|
||||
|
||||
@@ -124,43 +124,35 @@ public class PairingManager {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] decryptAes(byte[] encryptedData, SecretKey secretKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
|
||||
|
||||
int blockRoundedSize = ((encryptedData.length + 15) / 16) * 16;
|
||||
byte[] blockRoundedEncrypted = Arrays.copyOf(encryptedData, blockRoundedSize);
|
||||
byte[] fullDecrypted = new byte[blockRoundedSize];
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKey);
|
||||
cipher.doFinal(blockRoundedEncrypted, 0,
|
||||
blockRoundedSize, fullDecrypted);
|
||||
return fullDecrypted;
|
||||
} catch (GeneralSecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
private static byte[] performBlockCipher(BlockCipher blockCipher, byte[] input) {
|
||||
int blockSize = blockCipher.getBlockSize();
|
||||
int blockRoundedSize = (input.length + (blockSize - 1)) & ~(blockSize - 1);
|
||||
|
||||
byte[] blockRoundedInputData = Arrays.copyOf(input, blockRoundedSize);
|
||||
byte[] blockRoundedOutputData = new byte[blockRoundedSize];
|
||||
|
||||
for (int offset = 0; offset < blockRoundedSize; offset += blockSize) {
|
||||
blockCipher.processBlock(blockRoundedInputData, offset, blockRoundedOutputData, offset);
|
||||
}
|
||||
|
||||
return blockRoundedOutputData;
|
||||
}
|
||||
|
||||
private static byte[] encryptAes(byte[] data, SecretKey secretKey) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
|
||||
|
||||
int blockRoundedSize = ((data.length + 15) / 16) * 16;
|
||||
byte[] blockRoundedData = Arrays.copyOf(data, blockRoundedSize);
|
||||
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
|
||||
return cipher.doFinal(blockRoundedData);
|
||||
} catch (GeneralSecurityException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
private static byte[] decryptAes(byte[] encryptedData, byte[] aesKey) {
|
||||
BlockCipher aesEngine = new AESLightEngine();
|
||||
aesEngine.init(false, new KeyParameter(aesKey));
|
||||
return performBlockCipher(aesEngine, encryptedData);
|
||||
}
|
||||
|
||||
private static SecretKey generateAesKey(PairingHashAlgorithm hashAlgo, byte[] keyData) {
|
||||
byte[] aesTruncated = Arrays.copyOf(hashAlgo.hashData(keyData), 16);
|
||||
return new SecretKeySpec(aesTruncated, "AES");
|
||||
private static byte[] encryptAes(byte[] plaintextData, byte[] aesKey) {
|
||||
BlockCipher aesEngine = new AESLightEngine();
|
||||
aesEngine.init(true, new KeyParameter(aesKey));
|
||||
return performBlockCipher(aesEngine, plaintextData);
|
||||
}
|
||||
|
||||
private static byte[] generateAesKey(PairingHashAlgorithm hashAlgo, byte[] keyData) {
|
||||
return Arrays.copyOf(hashAlgo.hashData(keyData), 16);
|
||||
}
|
||||
|
||||
private static byte[] concatBytes(byte[] a, byte[] b) {
|
||||
@@ -199,16 +191,14 @@ public class PairingManager {
|
||||
byte[] salt = generateRandomBytes(16);
|
||||
|
||||
// Combine the salt and pin, then create an AES key from them
|
||||
byte[] saltAndPin = saltPin(salt, pin);
|
||||
aesKey = generateAesKey(hashAlgo, saltAndPin);
|
||||
byte[] aesKey = generateAesKey(hashAlgo, saltPin(salt, pin));
|
||||
|
||||
// Send the salt and get the server cert. This doesn't have a read timeout
|
||||
// because the user must enter the PIN before the server responds
|
||||
String getCert = http.openHttpConnectionToString(http.baseUrlHttp +
|
||||
"/pair?"+http.buildUniqueIdUuidString()+"&devicename=roth&updateState=1&phrase=getservercert&salt="+
|
||||
String getCert = http.executePairingCommand("phrase=getservercert&salt="+
|
||||
bytesToHex(salt)+"&clientcert="+bytesToHex(pemCertBytes),
|
||||
false);
|
||||
if (!NvHTTP.getXmlString(getCert, "paired").equals("1")) {
|
||||
if (!NvHTTP.getXmlString(getCert, "paired", true).equals("1")) {
|
||||
return PairState.FAILED;
|
||||
}
|
||||
|
||||
@@ -217,7 +207,7 @@ public class PairingManager {
|
||||
if (serverCert == null) {
|
||||
// Attempting to pair while another device is pairing will cause GFE
|
||||
// to give an empty cert in the response.
|
||||
http.openHttpConnectionToString(http.baseUrlHttp + "/unpair?"+http.buildUniqueIdUuidString(), true);
|
||||
http.unpair();
|
||||
return PairState.ALREADY_IN_PROGRESS;
|
||||
}
|
||||
|
||||
@@ -229,16 +219,14 @@ public class PairingManager {
|
||||
byte[] encryptedChallenge = encryptAes(randomChallenge, aesKey);
|
||||
|
||||
// Send the encrypted challenge to the server
|
||||
String challengeResp = http.openHttpConnectionToString(http.baseUrlHttp +
|
||||
"/pair?"+http.buildUniqueIdUuidString()+"&devicename=roth&updateState=1&clientchallenge="+bytesToHex(encryptedChallenge),
|
||||
true);
|
||||
if (!NvHTTP.getXmlString(challengeResp, "paired").equals("1")) {
|
||||
http.openHttpConnectionToString(http.baseUrlHttp + "/unpair?"+http.buildUniqueIdUuidString(), true);
|
||||
String challengeResp = http.executePairingCommand("clientchallenge="+bytesToHex(encryptedChallenge), true);
|
||||
if (!NvHTTP.getXmlString(challengeResp, "paired", true).equals("1")) {
|
||||
http.unpair();
|
||||
return PairState.FAILED;
|
||||
}
|
||||
|
||||
// Decode the server's response and subsequent challenge
|
||||
byte[] encServerChallengeResponse = hexToBytes(NvHTTP.getXmlString(challengeResp, "challengeresponse"));
|
||||
byte[] encServerChallengeResponse = hexToBytes(NvHTTP.getXmlString(challengeResp, "challengeresponse", true));
|
||||
byte[] decServerChallengeResponse = decryptAes(encServerChallengeResponse, aesKey);
|
||||
|
||||
byte[] serverResponse = Arrays.copyOfRange(decServerChallengeResponse, 0, hashAlgo.getHashLength());
|
||||
@@ -248,23 +236,21 @@ public class PairingManager {
|
||||
byte[] clientSecret = generateRandomBytes(16);
|
||||
byte[] challengeRespHash = hashAlgo.hashData(concatBytes(concatBytes(serverChallenge, cert.getSignature()), clientSecret));
|
||||
byte[] challengeRespEncrypted = encryptAes(challengeRespHash, aesKey);
|
||||
String secretResp = http.openHttpConnectionToString(http.baseUrlHttp +
|
||||
"/pair?"+http.buildUniqueIdUuidString()+"&devicename=roth&updateState=1&serverchallengeresp="+bytesToHex(challengeRespEncrypted),
|
||||
true);
|
||||
if (!NvHTTP.getXmlString(secretResp, "paired").equals("1")) {
|
||||
http.openHttpConnectionToString(http.baseUrlHttp + "/unpair?"+http.buildUniqueIdUuidString(), true);
|
||||
String secretResp = http.executePairingCommand("serverchallengeresp="+bytesToHex(challengeRespEncrypted), true);
|
||||
if (!NvHTTP.getXmlString(secretResp, "paired", true).equals("1")) {
|
||||
http.unpair();
|
||||
return PairState.FAILED;
|
||||
}
|
||||
|
||||
// Get the server's signed secret
|
||||
byte[] serverSecretResp = hexToBytes(NvHTTP.getXmlString(secretResp, "pairingsecret"));
|
||||
byte[] serverSecretResp = hexToBytes(NvHTTP.getXmlString(secretResp, "pairingsecret", true));
|
||||
byte[] serverSecret = Arrays.copyOfRange(serverSecretResp, 0, 16);
|
||||
byte[] serverSignature = Arrays.copyOfRange(serverSecretResp, 16, 272);
|
||||
|
||||
// Ensure the authenticity of the data
|
||||
if (!verifySignature(serverSecret, serverSignature, serverCert)) {
|
||||
// Cancel the pairing process
|
||||
http.openHttpConnectionToString(http.baseUrlHttp + "/unpair?"+http.buildUniqueIdUuidString(), true);
|
||||
http.unpair();
|
||||
|
||||
// Looks like a MITM
|
||||
return PairState.FAILED;
|
||||
@@ -274,7 +260,7 @@ public class PairingManager {
|
||||
byte[] serverChallengeRespHash = hashAlgo.hashData(concatBytes(concatBytes(randomChallenge, serverCert.getSignature()), serverSecret));
|
||||
if (!Arrays.equals(serverChallengeRespHash, serverResponse)) {
|
||||
// Cancel the pairing process
|
||||
http.openHttpConnectionToString(http.baseUrlHttp + "/unpair?"+http.buildUniqueIdUuidString(), true);
|
||||
http.unpair();
|
||||
|
||||
// Probably got the wrong PIN
|
||||
return PairState.PIN_WRONG;
|
||||
@@ -282,19 +268,16 @@ public class PairingManager {
|
||||
|
||||
// Send the server our signed secret
|
||||
byte[] clientPairingSecret = concatBytes(clientSecret, signData(clientSecret, pk));
|
||||
String clientSecretResp = http.openHttpConnectionToString(http.baseUrlHttp +
|
||||
"/pair?"+http.buildUniqueIdUuidString()+"&devicename=roth&updateState=1&clientpairingsecret="+bytesToHex(clientPairingSecret),
|
||||
true);
|
||||
if (!NvHTTP.getXmlString(clientSecretResp, "paired").equals("1")) {
|
||||
http.openHttpConnectionToString(http.baseUrlHttp + "/unpair?"+http.buildUniqueIdUuidString(), true);
|
||||
String clientSecretResp = http.executePairingCommand("clientpairingsecret="+bytesToHex(clientPairingSecret), true);
|
||||
if (!NvHTTP.getXmlString(clientSecretResp, "paired", true).equals("1")) {
|
||||
http.unpair();
|
||||
return PairState.FAILED;
|
||||
}
|
||||
|
||||
// Do the initial challenge (seems neccessary for us to show as paired)
|
||||
String pairChallenge = http.openHttpConnectionToString(http.baseUrlHttps +
|
||||
"/pair?"+http.buildUniqueIdUuidString()+"&devicename=roth&updateState=1&phrase=pairchallenge", true);
|
||||
if (!NvHTTP.getXmlString(pairChallenge, "paired").equals("1")) {
|
||||
http.openHttpConnectionToString(http.baseUrlHttp + "/unpair?"+http.buildUniqueIdUuidString(), true);
|
||||
// Do the initial challenge (seems necessary for us to show as paired)
|
||||
String pairChallenge = http.executePairingChallenge();
|
||||
if (!NvHTTP.getXmlString(pairChallenge, "paired", true).equals("1")) {
|
||||
http.unpair();
|
||||
return PairState.FAILED;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ public class MoonBridge {
|
||||
public static final int BUFFER_TYPE_PPS = 2;
|
||||
public static final int BUFFER_TYPE_VPS = 3;
|
||||
|
||||
public static final int FRAME_TYPE_PFRAME = 0;
|
||||
public static final int FRAME_TYPE_IDR = 1;
|
||||
|
||||
public static final int CAPABILITY_DIRECT_SUBMIT = 1;
|
||||
public static final int CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC = 2;
|
||||
public static final int CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC = 4;
|
||||
@@ -153,12 +156,12 @@ public class MoonBridge {
|
||||
}
|
||||
}
|
||||
|
||||
public static int bridgeDrSubmitDecodeUnit(byte[] decodeUnitData, int decodeUnitLength,
|
||||
int decodeUnitType, int frameNumber,
|
||||
public static int bridgeDrSubmitDecodeUnit(byte[] decodeUnitData, int decodeUnitLength, int decodeUnitType,
|
||||
int frameNumber, int frameType,
|
||||
long receiveTimeMs, long enqueueTimeMs) {
|
||||
if (videoRenderer != null) {
|
||||
return videoRenderer.submitDecodeUnit(decodeUnitData, decodeUnitLength,
|
||||
decodeUnitType, frameNumber, receiveTimeMs, enqueueTimeMs);
|
||||
decodeUnitType, frameNumber, frameType, receiveTimeMs, enqueueTimeMs);
|
||||
}
|
||||
else {
|
||||
return DR_OK;
|
||||
@@ -240,6 +243,12 @@ public class MoonBridge {
|
||||
}
|
||||
}
|
||||
|
||||
public static void bridgeClSetHdrMode(boolean enabled) {
|
||||
if (connectionListener != null) {
|
||||
connectionListener.setHdrMode(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupBridge(VideoDecoderRenderer videoRenderer, AudioRenderer audioRenderer, NvConnectionListener connectionListener) {
|
||||
MoonBridge.videoRenderer = videoRenderer;
|
||||
MoonBridge.audioRenderer = audioRenderer;
|
||||
@@ -253,6 +262,7 @@ public class MoonBridge {
|
||||
}
|
||||
|
||||
public static native int startConnection(String address, String appVersion, String gfeVersion,
|
||||
String rtspSessionUrl,
|
||||
int width, int height, int fps,
|
||||
int bitrate, int packetSize, int streamingRemotely,
|
||||
int audioConfiguration, boolean supportsHevc,
|
||||
@@ -271,6 +281,8 @@ public class MoonBridge {
|
||||
|
||||
public static native void sendMousePosition(short x, short y, short referenceWidth, short referenceHeight);
|
||||
|
||||
public static native void sendMouseMoveAsMousePosition(short deltaX, short deltaY, short referenceWidth, short referenceHeight);
|
||||
|
||||
public static native void sendMouseButton(byte buttonEvent, byte mouseButton);
|
||||
|
||||
public static native void sendMultiControllerInput(short controllerNumber,
|
||||
@@ -290,6 +302,8 @@ public class MoonBridge {
|
||||
|
||||
public static native void sendMouseHighResScroll(short scrollAmount);
|
||||
|
||||
public static native void sendUtf8Text(String text);
|
||||
|
||||
public static native String getStageName(int stage);
|
||||
|
||||
public static native String findExternalAddressIP4(String stunHostName, int stunPort);
|
||||
@@ -306,5 +320,8 @@ public class MoonBridge {
|
||||
|
||||
public static native String stringifyPortFlags(int portFlags, String separator);
|
||||
|
||||
// The RTT is in the top 32 bits, and the RTT variance is in the bottom 32 bits
|
||||
public static native long getEstimatedRttInfo();
|
||||
|
||||
public static native void init();
|
||||
}
|
||||
|
||||
@@ -88,15 +88,15 @@ public class AddComputerManually extends Activity {
|
||||
|
||||
// Couldn't find a matching interface
|
||||
return true;
|
||||
} catch (SocketException e) {
|
||||
} catch (Exception e) {
|
||||
// Catch all exceptions because some broken Android devices
|
||||
// will throw an NPE from inside getNetworkInterfaces().
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void doAddPc(String host) {
|
||||
private void doAddPc(String host) throws InterruptedException {
|
||||
boolean wrongSiteLocal = false;
|
||||
boolean success;
|
||||
int portTestResult;
|
||||
@@ -108,12 +108,18 @@ public class AddComputerManually extends Activity {
|
||||
ComputerDetails details = new ComputerDetails();
|
||||
details.manualAddress = host;
|
||||
success = managerBinder.addComputerBlocking(details);
|
||||
} catch (InterruptedException e) {
|
||||
// Propagate the InterruptedException to the caller for proper handling
|
||||
dialog.dismiss();
|
||||
throw e;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// This can be thrown from OkHttp if the host fails to canonicalize to a valid name.
|
||||
// https://github.com/square/okhttp/blob/okhttp_27/okhttp/src/main/java/com/squareup/okhttp/HttpUrl.java#L705
|
||||
e.printStackTrace();
|
||||
success = false;
|
||||
}
|
||||
|
||||
// Keep the SpinnerDialog open while testing connectivity
|
||||
if (!success){
|
||||
wrongSiteLocal = isWrongSubnetSiteLocalAddress(host);
|
||||
}
|
||||
@@ -162,15 +168,12 @@ public class AddComputerManually extends Activity {
|
||||
@Override
|
||||
public void run() {
|
||||
while (!isInterrupted()) {
|
||||
String computer;
|
||||
|
||||
try {
|
||||
computer = computersToAdd.take();
|
||||
String computer = computersToAdd.take();
|
||||
doAddPc(computer);
|
||||
} catch (InterruptedException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
doAddPc(computer);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -184,7 +187,14 @@ public class AddComputerManually extends Activity {
|
||||
|
||||
try {
|
||||
addThread.join();
|
||||
} catch (InterruptedException ignored) {}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
// InterruptedException clears the thread's interrupt status. Since we can't
|
||||
// handle that here, we will re-interrupt the thread to set the interrupt
|
||||
// status back to true.
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
addThread = null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.limelight.preferences;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.preference.ListPreference;
|
||||
import android.provider.Settings;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
public class LanguagePreference extends ListPreference {
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public LanguagePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public LanguagePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public LanguagePreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public LanguagePreference(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
try {
|
||||
// Launch the Android native app locale settings page
|
||||
Intent intent = new Intent(Settings.ACTION_APP_LOCALE_SETTINGS);
|
||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||
intent.setData(Uri.parse("package:" + getContext().getPackageName()));
|
||||
getContext().startActivity(intent, null);
|
||||
return;
|
||||
} catch (ActivityNotFoundException e) {
|
||||
// App locale settings should be present on all Android 13 devices,
|
||||
// but if not, we'll launch the old language chooser.
|
||||
}
|
||||
}
|
||||
|
||||
// If we don't have native app locale settings, launch the normal dialog
|
||||
super.onClick();
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.Display;
|
||||
|
||||
import com.limelight.nvstream.jni.MoonBridge;
|
||||
|
||||
@@ -30,7 +31,7 @@ public class PreferenceConfiguration {
|
||||
private static final String VIDEO_FORMAT_PREF_STRING = "video_format";
|
||||
private static final String ONSCREEN_CONTROLLER_PREF_STRING = "checkbox_show_onscreen_controls";
|
||||
private static final String ONLY_L3_R3_PREF_STRING = "checkbox_only_show_L3R3";
|
||||
private static final String DISABLE_FRAME_DROP_PREF_STRING = "checkbox_disable_frame_drop";
|
||||
private static final String LEGACY_DISABLE_FRAME_DROP_PREF_STRING = "checkbox_disable_frame_drop";
|
||||
private static final String ENABLE_HDR_PREF_STRING = "checkbox_enable_hdr";
|
||||
private static final String ENABLE_PIP_PREF_STRING = "checkbox_enable_pip";
|
||||
private static final String ENABLE_PERF_OVERLAY_STRING = "checkbox_enable_perf_overlay";
|
||||
@@ -43,6 +44,10 @@ public class PreferenceConfiguration {
|
||||
private static final String FLIP_FACE_BUTTONS_PREF_STRING = "checkbox_flip_face_buttons";
|
||||
private static final String TOUCHSCREEN_TRACKPAD_PREF_STRING = "checkbox_touchscreen_trackpad";
|
||||
private static final String LATENCY_TOAST_PREF_STRING = "checkbox_enable_post_stream_toast";
|
||||
private static final String FRAME_PACING_PREF_STRING = "frame_pacing";
|
||||
private static final String ABSOLUTE_MOUSE_MODE_PREF_STRING = "checkbox_absolute_mouse_mode";
|
||||
private static final String ENABLE_AUDIO_FX_PREF_STRING = "checkbox_enable_audiofx";
|
||||
private static final String REDUCE_REFRESH_RATE_PREF_STRING = "checkbox_reduce_refresh_rate";
|
||||
|
||||
static final String DEFAULT_RESOLUTION = "1280x720";
|
||||
static final String DEFAULT_FPS = "60";
|
||||
@@ -50,7 +55,7 @@ public class PreferenceConfiguration {
|
||||
private static final boolean DEFAULT_SOPS = true;
|
||||
private static final boolean DEFAULT_DISABLE_TOASTS = false;
|
||||
private static final boolean DEFAULT_HOST_AUDIO = false;
|
||||
private static final int DEFAULT_DEADZONE = 15;
|
||||
private static final int DEFAULT_DEADZONE = 7;
|
||||
private static final int DEFAULT_OPACITY = 90;
|
||||
public static final String DEFAULT_LANGUAGE = "default";
|
||||
private static final boolean DEFAULT_MULTI_CONTROLLER = true;
|
||||
@@ -58,7 +63,6 @@ public class PreferenceConfiguration {
|
||||
private static final String DEFAULT_VIDEO_FORMAT = "auto";
|
||||
private static final boolean ONSCREEN_CONTROLLER_DEFAULT = false;
|
||||
private static final boolean ONLY_L3_R3_DEFAULT = false;
|
||||
private static final boolean DEFAULT_DISABLE_FRAME_DROP = false;
|
||||
private static final boolean DEFAULT_ENABLE_HDR = false;
|
||||
private static final boolean DEFAULT_ENABLE_PIP = false;
|
||||
private static final boolean DEFAULT_ENABLE_PERF_OVERLAY = false;
|
||||
@@ -72,11 +76,20 @@ public class PreferenceConfiguration {
|
||||
private static final boolean DEFAULT_TOUCHSCREEN_TRACKPAD = true;
|
||||
private static final String DEFAULT_AUDIO_CONFIG = "2"; // Stereo
|
||||
private static final boolean DEFAULT_LATENCY_TOAST = false;
|
||||
private static final String DEFAULT_FRAME_PACING = "latency";
|
||||
private static final boolean DEFAULT_ABSOLUTE_MOUSE_MODE = false;
|
||||
private static final boolean DEFAULT_ENABLE_AUDIO_FX = false;
|
||||
private static final boolean DEFAULT_REDUCE_REFRESH_RATE = false;
|
||||
|
||||
public static final int FORCE_H265_ON = -1;
|
||||
public static final int AUTOSELECT_H265 = 0;
|
||||
public static final int FORCE_H265_OFF = 1;
|
||||
|
||||
public static final int FRAME_PACING_MIN_LATENCY = 0;
|
||||
public static final int FRAME_PACING_BALANCED = 1;
|
||||
public static final int FRAME_PACING_CAP_FPS = 2;
|
||||
public static final int FRAME_PACING_MAX_SMOOTHNESS = 3;
|
||||
|
||||
public static final String RES_360P = "640x360";
|
||||
public static final String RES_480P = "854x480";
|
||||
public static final String RES_720P = "1280x720";
|
||||
@@ -95,7 +108,6 @@ public class PreferenceConfiguration {
|
||||
public boolean smallIconMode, multiController, usbDriver, flipFaceButtons;
|
||||
public boolean onscreenController;
|
||||
public boolean onlyL3R3;
|
||||
public boolean disableFrameDrop;
|
||||
public boolean enableHdr;
|
||||
public boolean enablePip;
|
||||
public boolean enablePerfOverlay;
|
||||
@@ -108,6 +120,10 @@ public class PreferenceConfiguration {
|
||||
public boolean vibrateFallbackToDevice;
|
||||
public boolean touchscreenTrackpad;
|
||||
public MoonBridge.AudioConfiguration audioConfiguration;
|
||||
public int framePacing;
|
||||
public boolean absoluteMouseMode;
|
||||
public boolean enableAudioFx;
|
||||
public boolean reduceRefreshRate;
|
||||
|
||||
public static boolean isNativeResolution(int width, int height) {
|
||||
// It's not a native resolution if it matches an existing resolution option
|
||||
@@ -133,6 +149,31 @@ public class PreferenceConfiguration {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we have a screen that has semi-square dimensions, we may want to change our behavior
|
||||
// to allow any orientation and vertical+horizontal resolutions.
|
||||
public static boolean isSquarishScreen(int width, int height) {
|
||||
float longDim = Math.max(width, height);
|
||||
float shortDim = Math.min(width, height);
|
||||
|
||||
// We just put the arbitrary cutoff for a square-ish screen at 1.3
|
||||
return longDim / shortDim < 1.3f;
|
||||
}
|
||||
|
||||
public static boolean isSquarishScreen(Display display) {
|
||||
int width, height;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
width = display.getMode().getPhysicalWidth();
|
||||
height = display.getMode().getPhysicalHeight();
|
||||
}
|
||||
else {
|
||||
width = display.getWidth();
|
||||
height = display.getHeight();
|
||||
}
|
||||
|
||||
return isSquarishScreen(width, height);
|
||||
}
|
||||
|
||||
private static String convertFromLegacyResolutionString(String resString) {
|
||||
if (resString.equalsIgnoreCase("360p")) {
|
||||
return RES_360P;
|
||||
@@ -264,6 +305,37 @@ public class PreferenceConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private static int getFramePacingValue(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
// Migrate legacy never drop frames option to the new location
|
||||
if (prefs.contains(LEGACY_DISABLE_FRAME_DROP_PREF_STRING)) {
|
||||
boolean legacyNeverDropFrames = prefs.getBoolean(LEGACY_DISABLE_FRAME_DROP_PREF_STRING, false);
|
||||
prefs.edit()
|
||||
.remove(LEGACY_DISABLE_FRAME_DROP_PREF_STRING)
|
||||
.putString(FRAME_PACING_PREF_STRING, legacyNeverDropFrames ? "balanced" : "latency")
|
||||
.apply();
|
||||
}
|
||||
|
||||
String str = prefs.getString(FRAME_PACING_PREF_STRING, DEFAULT_FRAME_PACING);
|
||||
if (str.equals("latency")) {
|
||||
return FRAME_PACING_MIN_LATENCY;
|
||||
}
|
||||
else if (str.equals("balanced")) {
|
||||
return FRAME_PACING_BALANCED;
|
||||
}
|
||||
else if (str.equals("cap-fps")) {
|
||||
return FRAME_PACING_CAP_FPS;
|
||||
}
|
||||
else if (str.equals("smoothness")) {
|
||||
return FRAME_PACING_MAX_SMOOTHNESS;
|
||||
}
|
||||
else {
|
||||
// Should never get here
|
||||
return FRAME_PACING_MIN_LATENCY;
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetStreamingSettings(Context context) {
|
||||
// We consider resolution, FPS, bitrate, HDR, and video format as "streaming settings" here
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
@@ -279,6 +351,19 @@ public class PreferenceConfiguration {
|
||||
.apply();
|
||||
}
|
||||
|
||||
public static void completeLanguagePreferenceMigration(Context context) {
|
||||
// Put our language option back to default which tells us that we've already migrated it
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
prefs.edit().putString(LANGUAGE_PREF_STRING, DEFAULT_LANGUAGE).apply();
|
||||
}
|
||||
|
||||
public static boolean isShieldAtvFirmwareWithBrokenHdr() {
|
||||
// This particular Shield TV firmware crashes when using HDR
|
||||
// https://www.nvidia.com/en-us/geforce/forums/notifications/comment/155192/
|
||||
return Build.MANUFACTURER.equalsIgnoreCase("NVIDIA") &&
|
||||
Build.FINGERPRINT.contains("PPR1.180610.011/4079208_2235.1395");
|
||||
}
|
||||
|
||||
public static PreferenceConfiguration readPreferences(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
PreferenceConfiguration config = new PreferenceConfiguration();
|
||||
@@ -387,6 +472,7 @@ public class PreferenceConfiguration {
|
||||
}
|
||||
|
||||
config.videoFormat = getVideoFormatValue(context);
|
||||
config.framePacing = getFramePacingValue(context);
|
||||
|
||||
config.deadzonePercentage = prefs.getInt(DEADZONE_PREF_STRING, DEFAULT_DEADZONE);
|
||||
|
||||
@@ -404,8 +490,7 @@ public class PreferenceConfiguration {
|
||||
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
|
||||
config.onscreenController = prefs.getBoolean(ONSCREEN_CONTROLLER_PREF_STRING, ONSCREEN_CONTROLLER_DEFAULT);
|
||||
config.onlyL3R3 = prefs.getBoolean(ONLY_L3_R3_PREF_STRING, ONLY_L3_R3_DEFAULT);
|
||||
config.disableFrameDrop = prefs.getBoolean(DISABLE_FRAME_DROP_PREF_STRING, DEFAULT_DISABLE_FRAME_DROP);
|
||||
config.enableHdr = prefs.getBoolean(ENABLE_HDR_PREF_STRING, DEFAULT_ENABLE_HDR);
|
||||
config.enableHdr = prefs.getBoolean(ENABLE_HDR_PREF_STRING, DEFAULT_ENABLE_HDR) && !isShieldAtvFirmwareWithBrokenHdr();
|
||||
config.enablePip = prefs.getBoolean(ENABLE_PIP_PREF_STRING, DEFAULT_ENABLE_PIP);
|
||||
config.enablePerfOverlay = prefs.getBoolean(ENABLE_PERF_OVERLAY_STRING, DEFAULT_ENABLE_PERF_OVERLAY);
|
||||
config.bindAllUsb = prefs.getBoolean(BIND_ALL_USB_STRING, DEFAULT_BIND_ALL_USB);
|
||||
@@ -417,6 +502,9 @@ public class PreferenceConfiguration {
|
||||
config.flipFaceButtons = prefs.getBoolean(FLIP_FACE_BUTTONS_PREF_STRING, DEFAULT_FLIP_FACE_BUTTONS);
|
||||
config.touchscreenTrackpad = prefs.getBoolean(TOUCHSCREEN_TRACKPAD_PREF_STRING, DEFAULT_TOUCHSCREEN_TRACKPAD);
|
||||
config.enableLatencyToast = prefs.getBoolean(LATENCY_TOAST_PREF_STRING, DEFAULT_LATENCY_TOAST);
|
||||
config.absoluteMouseMode = prefs.getBoolean(ABSOLUTE_MOUSE_MODE_PREF_STRING, DEFAULT_ABSOLUTE_MOUSE_MODE);
|
||||
config.enableAudioFx = prefs.getBoolean(ENABLE_AUDIO_FX_PREF_STRING, DEFAULT_ENABLE_AUDIO_FX);
|
||||
config.reduceRefreshRate = prefs.getBoolean(REDUCE_REFRESH_RATE_PREF_STRING, DEFAULT_REDUCE_REFRESH_RATE);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -3,23 +3,29 @@ package com.limelight.preferences;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.app.Activity;
|
||||
import android.os.Handler;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Range;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.PcView;
|
||||
@@ -28,15 +34,24 @@ import com.limelight.binding.video.MediaCodecHelper;
|
||||
import com.limelight.utils.Dialog;
|
||||
import com.limelight.utils.UiHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class StreamSettings extends Activity {
|
||||
private PreferenceConfiguration previousPrefs;
|
||||
private int previousDisplayPixelCount;
|
||||
|
||||
// HACK for Android 9
|
||||
static DisplayCutout displayCutoutP;
|
||||
|
||||
void reloadSettings() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
Display.Mode mode = getWindowManager().getDefaultDisplay().getMode();
|
||||
previousDisplayPixelCount = mode.getPhysicalWidth() * mode.getPhysicalHeight();
|
||||
}
|
||||
getFragmentManager().beginTransaction().replace(
|
||||
R.id.stream_settings, new SettingsFragment()
|
||||
).commit();
|
||||
).commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,22 +63,61 @@ public class StreamSettings extends Activity {
|
||||
UiHelper.setLocale(this);
|
||||
|
||||
setContentView(R.layout.activity_stream_settings);
|
||||
reloadSettings();
|
||||
|
||||
UiHelper.notifyNewRootView(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
// We have to use this hack on Android 9 because we don't have Display.getCutout()
|
||||
// which was added in Android 10.
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
|
||||
// Insets can be null when the activity is recreated on screen rotation
|
||||
// https://stackoverflow.com/questions/61241255/windowinsets-getdisplaycutout-is-null-everywhere-except-within-onattachedtowindo
|
||||
WindowInsets insets = getWindow().getDecorView().getRootWindowInsets();
|
||||
if (insets != null) {
|
||||
displayCutoutP = insets.getDisplayCutout();
|
||||
}
|
||||
}
|
||||
|
||||
reloadSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
Display.Mode mode = getWindowManager().getDefaultDisplay().getMode();
|
||||
|
||||
// If the display's physical pixel count has changed, we consider that it's a new display
|
||||
// and we should reload our settings (which include display-dependent values).
|
||||
//
|
||||
// NB: We aren't using displayId here because that stays the same (DEFAULT_DISPLAY) when
|
||||
// switching between screens on a foldable device.
|
||||
if (mode.getPhysicalWidth() * mode.getPhysicalHeight() != previousDisplayPixelCount) {
|
||||
reloadSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// NOTE: This will NOT be called on Android 13+ with android:enableOnBackInvokedCallback="true"
|
||||
public void onBackPressed() {
|
||||
finish();
|
||||
|
||||
// Check for changes that require a UI reload to take effect
|
||||
PreferenceConfiguration newPrefs = PreferenceConfiguration.readPreferences(this);
|
||||
if (!newPrefs.language.equals(previousPrefs.language)) {
|
||||
// Restart the PC view to apply UI changes
|
||||
Intent intent = new Intent(this, PcView.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent, null);
|
||||
// Language changes are handled via configuration changes in Android 13+,
|
||||
// so manual activity relaunching is no longer required.
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
|
||||
PreferenceConfiguration newPrefs = PreferenceConfiguration.readPreferences(this);
|
||||
if (!newPrefs.language.equals(previousPrefs.language)) {
|
||||
// Restart the PC view to apply UI changes
|
||||
Intent intent = new Intent(this, PcView.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivity(intent, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,10 +130,29 @@ public class StreamSettings extends Activity {
|
||||
pref.setValue(value);
|
||||
}
|
||||
|
||||
private void addNativeResolutionEntry(int nativeWidth, int nativeHeight) {
|
||||
private void addNativeResolutionEntry(int nativeWidth, int nativeHeight, boolean insetsRemoved, boolean portrait) {
|
||||
ListPreference pref = (ListPreference) findPreference(PreferenceConfiguration.RESOLUTION_PREF_STRING);
|
||||
|
||||
String newName = getResources().getString(R.string.resolution_prefix_native) + " ("+nativeWidth+"x"+nativeHeight+")";
|
||||
String newName;
|
||||
|
||||
if (insetsRemoved) {
|
||||
newName = getResources().getString(R.string.resolution_prefix_native_fullscreen);
|
||||
}
|
||||
else {
|
||||
newName = getResources().getString(R.string.resolution_prefix_native);
|
||||
}
|
||||
|
||||
if (PreferenceConfiguration.isSquarishScreen(nativeWidth, nativeHeight)) {
|
||||
if (portrait) {
|
||||
newName += " " + getResources().getString(R.string.resolution_prefix_native_portrait);
|
||||
}
|
||||
else {
|
||||
newName += " " + getResources().getString(R.string.resolution_prefix_native_landscape);
|
||||
}
|
||||
}
|
||||
|
||||
newName += " ("+nativeWidth+"x"+nativeHeight+")";
|
||||
|
||||
String newValue = nativeWidth+"x"+nativeHeight;
|
||||
|
||||
CharSequence[] values = pref.getEntryValues();
|
||||
@@ -107,6 +180,13 @@ public class StreamSettings extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
private void addNativeResolutionEntries(int nativeWidth, int nativeHeight, boolean insetsRemoved) {
|
||||
if (PreferenceConfiguration.isSquarishScreen(nativeWidth, nativeHeight)) {
|
||||
addNativeResolutionEntry(nativeHeight, nativeWidth, insetsRemoved, true);
|
||||
}
|
||||
addNativeResolutionEntry(nativeWidth, nativeHeight, insetsRemoved, false);
|
||||
}
|
||||
|
||||
private void removeValue(String preferenceKey, String value, Runnable onMatched) {
|
||||
int matchingCount = 0;
|
||||
|
||||
@@ -173,7 +253,7 @@ public class StreamSettings extends Activity {
|
||||
|
||||
// hide on-screen controls category on non touch screen devices
|
||||
if (!getActivity().getPackageManager().
|
||||
hasSystemFeature("android.hardware.touchscreen")) {
|
||||
hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
|
||||
{
|
||||
PreferenceCategory category =
|
||||
(PreferenceCategory) findPreference("category_onscreen_controls");
|
||||
@@ -187,6 +267,15 @@ public class StreamSettings extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
// Hide remote desktop mouse mode on pre-Oreo (which doesn't have pointer capture)
|
||||
// and NVIDIA SHIELD devices (which support raw mouse input in pointer capture mode)
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O ||
|
||||
getActivity().getPackageManager().hasSystemFeature("com.nvidia.feature.shield")) {
|
||||
PreferenceCategory category =
|
||||
(PreferenceCategory) findPreference("category_input_settings");
|
||||
category.removePreference(findPreference("checkbox_absolute_mouse_mode"));
|
||||
}
|
||||
|
||||
// Remove PiP mode on devices pre-Oreo, where the feature is not available (some low RAM devices),
|
||||
// and on Fire OS where it violates the Amazon App Store guidelines for some reason.
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O ||
|
||||
@@ -197,6 +286,13 @@ public class StreamSettings extends Activity {
|
||||
category.removePreference(findPreference("checkbox_enable_pip"));
|
||||
}
|
||||
|
||||
// Fire TV apps are not allowed to use WebViews or browsers, so hide the Help category
|
||||
/*if (getActivity().getPackageManager().hasSystemFeature("amazon.hardware.fire_tv")) {
|
||||
PreferenceCategory category =
|
||||
(PreferenceCategory) findPreference("category_help");
|
||||
screen.removePreference(category);
|
||||
}*/
|
||||
|
||||
// Remove the vibration options if the device can't vibrate
|
||||
if (!((Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE)).hasVibrator()) {
|
||||
PreferenceCategory category =
|
||||
@@ -218,6 +314,38 @@ public class StreamSettings extends Activity {
|
||||
|
||||
int maxSupportedResW = 0;
|
||||
|
||||
// Add a native resolution with any insets included for users that don't want content
|
||||
// behind the notch of their display
|
||||
boolean hasInsets = false;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
DisplayCutout cutout;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
// Use the much nicer Display.getCutout() API on Android 10+
|
||||
cutout = display.getCutout();
|
||||
}
|
||||
else {
|
||||
// Android 9 only
|
||||
cutout = displayCutoutP;
|
||||
}
|
||||
|
||||
if (cutout != null) {
|
||||
int widthInsets = cutout.getSafeInsetLeft() + cutout.getSafeInsetRight();
|
||||
int heightInsets = cutout.getSafeInsetBottom() + cutout.getSafeInsetTop();
|
||||
|
||||
if (widthInsets != 0 || heightInsets != 0) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
display.getRealMetrics(metrics);
|
||||
|
||||
int width = Math.max(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
|
||||
int height = Math.min(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
|
||||
|
||||
addNativeResolutionEntries(width, height, false);
|
||||
hasInsets = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Always allow resolutions that are smaller or equal to the active
|
||||
// display resolution because decoders can report total non-sense to us.
|
||||
// For example, a p201 device reports:
|
||||
@@ -233,7 +361,12 @@ public class StreamSettings extends Activity {
|
||||
int width = Math.max(candidate.getPhysicalWidth(), candidate.getPhysicalHeight());
|
||||
int height = Math.min(candidate.getPhysicalWidth(), candidate.getPhysicalHeight());
|
||||
|
||||
addNativeResolutionEntry(width, height);
|
||||
// Some TVs report strange values here, so let's avoid native resolutions on a TV
|
||||
// unless they report greater than 4K resolutions.
|
||||
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION) ||
|
||||
(width > 3840 || height > 2160)) {
|
||||
addNativeResolutionEntries(width, height, hasInsets);
|
||||
}
|
||||
|
||||
if ((width >= 3840 || height >= 2160) && maxSupportedResW < 3840) {
|
||||
maxSupportedResW = 3840;
|
||||
@@ -334,11 +467,29 @@ public class StreamSettings extends Activity {
|
||||
// Never remove 720p
|
||||
}
|
||||
}
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
// On Android 4.2 and later, we can get the true metrics via the
|
||||
// getRealMetrics() function (unlike the lies that getWidth() and getHeight()
|
||||
// tell to us).
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
|
||||
int width = Math.max(metrics.widthPixels, metrics.heightPixels);
|
||||
int height = Math.min(metrics.widthPixels, metrics.heightPixels);
|
||||
addNativeResolutionEntries(width, height, false);
|
||||
}
|
||||
else {
|
||||
// On Android 4.1, we have to resort to reflection to invoke hidden APIs
|
||||
// to get the real screen dimensions.
|
||||
Display display = getActivity().getWindowManager().getDefaultDisplay();
|
||||
int width = Math.max(display.getWidth(), display.getHeight());
|
||||
int height = Math.min(display.getWidth(), display.getHeight());
|
||||
addNativeResolutionEntry(width, height);
|
||||
try {
|
||||
Method getRawHeightFunc = Display.class.getMethod("getRawHeight");
|
||||
Method getRawWidthFunc = Display.class.getMethod("getRawWidth");
|
||||
int width = (Integer) getRawWidthFunc.invoke(display);
|
||||
int height = (Integer) getRawHeightFunc.invoke(display);
|
||||
addNativeResolutionEntries(Math.max(width, height), Math.min(width, height), false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!PreferenceConfiguration.readPreferences(this.getActivity()).unlockFps) {
|
||||
@@ -439,6 +590,15 @@ public class StreamSettings extends Activity {
|
||||
(PreferenceCategory) findPreference("category_advanced_settings");
|
||||
category.removePreference(findPreference("checkbox_enable_hdr"));
|
||||
}
|
||||
else if (PreferenceConfiguration.isShieldAtvFirmwareWithBrokenHdr()) {
|
||||
LimeLog.info("Disabling HDR toggle on old broken SHIELD TV firmware");
|
||||
PreferenceCategory category =
|
||||
(PreferenceCategory) findPreference("category_advanced_settings");
|
||||
CheckBoxPreference hdrPref = (CheckBoxPreference) category.findPreference("checkbox_enable_hdr");
|
||||
hdrPref.setEnabled(false);
|
||||
hdrPref.setChecked(false);
|
||||
hdrPref.setSummary("Update the firmware on your NVIDIA SHIELD Android TV to enable HDR");
|
||||
}
|
||||
}
|
||||
|
||||
// Add a listener to the FPS and resolution preference
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.limelight.preferences;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.limelight.utils.HelpLauncher;
|
||||
|
||||
public class WebLauncherPreference extends Preference {
|
||||
private String url;
|
||||
|
||||
public WebLauncherPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initialize(attrs);
|
||||
}
|
||||
|
||||
public WebLauncherPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialize(attrs);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public WebLauncherPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
initialize(attrs);
|
||||
}
|
||||
|
||||
private void initialize(AttributeSet attrs) {
|
||||
if (attrs == null) {
|
||||
throw new IllegalStateException("WebLauncherPreference must have attributes!");
|
||||
}
|
||||
|
||||
url = attrs.getAttributeValue(null, "url");
|
||||
if (url == null) {
|
||||
throw new IllegalStateException("WebLauncherPreference must have 'url' attribute!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
HelpLauncher.launchUrl(getContext(), url);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
package com.limelight.ui;
|
||||
|
||||
public interface GameGestures {
|
||||
void showKeyboard();
|
||||
void toggleKeyboard();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.net.Uri;
|
||||
import com.limelight.HelpActivity;
|
||||
|
||||
public class HelpLauncher {
|
||||
private static void launchUrl(Context context, String url) {
|
||||
public static void launchUrl(Context context, String url) {
|
||||
// Try to launch the default browser
|
||||
try {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
|
||||
@@ -27,7 +27,10 @@ import java.security.cert.CertificateEncodingException;
|
||||
public class ServerHelper {
|
||||
public static final String CONNECTION_TEST_SERVER = "android.conntest.moonlight-stream.org";
|
||||
|
||||
public static String getCurrentAddressFromComputer(ComputerDetails computer) {
|
||||
public static String getCurrentAddressFromComputer(ComputerDetails computer) throws IOException {
|
||||
if (computer.activeAddress == null) {
|
||||
throw new IOException("No active address for "+computer.name);
|
||||
}
|
||||
return computer.activeAddress;
|
||||
}
|
||||
|
||||
@@ -53,7 +56,7 @@ public class ServerHelper {
|
||||
public static Intent createStartIntent(Activity parent, NvApp app, ComputerDetails computer,
|
||||
ComputerManagerService.ComputerManagerBinder managerBinder) {
|
||||
Intent intent = new Intent(parent, Game.class);
|
||||
intent.putExtra(Game.EXTRA_HOST, getCurrentAddressFromComputer(computer));
|
||||
intent.putExtra(Game.EXTRA_HOST, computer.activeAddress);
|
||||
intent.putExtra(Game.EXTRA_APP_NAME, app.getAppName());
|
||||
intent.putExtra(Game.EXTRA_APP_ID, app.getAppId());
|
||||
intent.putExtra(Game.EXTRA_APP_HDR, app.isHdrSupported());
|
||||
@@ -72,8 +75,7 @@ public class ServerHelper {
|
||||
|
||||
public static void doStart(Activity parent, NvApp app, ComputerDetails computer,
|
||||
ComputerManagerService.ComputerManagerBinder managerBinder) {
|
||||
if (computer.state == ComputerDetails.State.OFFLINE ||
|
||||
ServerHelper.getCurrentAddressFromComputer(computer) == null) {
|
||||
if (computer.state == ComputerDetails.State.OFFLINE || computer.activeAddress == null) {
|
||||
Toast.makeText(parent, parent.getResources().getString(R.string.pair_pc_offline), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ShortcutHelper {
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
private void reapShortcutsForDynamicAdd() {
|
||||
List<ShortcutInfo> dynamicShortcuts = sm.getDynamicShortcuts();
|
||||
while (dynamicShortcuts.size() >= sm.getMaxShortcutCountPerActivity()) {
|
||||
while (!dynamicShortcuts.isEmpty() && dynamicShortcuts.size() >= sm.getMaxShortcutCountPerActivity()) {
|
||||
ShortcutInfo maxRankShortcut = dynamicShortcuts.get(0);
|
||||
for (ShortcutInfo scut : dynamicShortcuts) {
|
||||
if (maxRankShortcut.getRank() < scut.getRank()) {
|
||||
@@ -118,8 +118,16 @@ public class ShortcutHelper {
|
||||
// To avoid a random carousel of shortcuts popping in and out based on polling status,
|
||||
// we only add shortcuts if it's not at the limit or the user made a conscious action
|
||||
// to interact with this PC.
|
||||
if (forceAdd || sm.getDynamicShortcuts().size() < sm.getMaxShortcutCountPerActivity()) {
|
||||
|
||||
if (forceAdd) {
|
||||
// This should free an entry for us to add one below
|
||||
reapShortcutsForDynamicAdd();
|
||||
}
|
||||
|
||||
// We still need to check the maximum shortcut count even after reaping,
|
||||
// because there's a possibility that it could be zero.
|
||||
if (sm.getDynamicShortcuts().size() < sm.getMaxShortcutCountPerActivity()) {
|
||||
// Add a shortcut if there is room
|
||||
sm.addDynamicShortcuts(Collections.singletonList(sinfo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package com.limelight.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.GameManager;
|
||||
import android.app.GameState;
|
||||
import android.app.LocaleManager;
|
||||
import android.app.UiModeManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
@@ -9,10 +12,12 @@ import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Insets;
|
||||
import android.os.Build;
|
||||
import android.os.LocaleList;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.limelight.Game;
|
||||
import com.limelight.R;
|
||||
import com.limelight.nvstream.http.ComputerDetails;
|
||||
import com.limelight.preferences.PreferenceConfiguration;
|
||||
@@ -24,25 +29,66 @@ public class UiHelper {
|
||||
private static final int TV_VERTICAL_PADDING_DP = 15;
|
||||
private static final int TV_HORIZONTAL_PADDING_DP = 15;
|
||||
|
||||
private static void setGameModeStatus(Context context, boolean streaming, boolean loading, boolean interruptible) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
GameManager gameManager = context.getSystemService(GameManager.class);
|
||||
|
||||
if (streaming) {
|
||||
gameManager.setGameState(new GameState(loading, interruptible ? GameState.MODE_GAMEPLAY_INTERRUPTIBLE : GameState.MODE_GAMEPLAY_UNINTERRUPTIBLE));
|
||||
}
|
||||
else {
|
||||
gameManager.setGameState(new GameState(loading, GameState.MODE_NONE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyStreamConnecting(Context context) {
|
||||
setGameModeStatus(context, true, true, true);
|
||||
}
|
||||
|
||||
public static void notifyStreamConnected(Context context) {
|
||||
setGameModeStatus(context, true, false, false);
|
||||
}
|
||||
|
||||
public static void notifyStreamEnteringPiP(Context context) {
|
||||
setGameModeStatus(context, true, false, true);
|
||||
}
|
||||
|
||||
public static void notifyStreamExitingPiP(Context context) {
|
||||
setGameModeStatus(context, true, false, false);
|
||||
}
|
||||
|
||||
public static void notifyStreamEnded(Context context) {
|
||||
setGameModeStatus(context, false, false, false);
|
||||
}
|
||||
|
||||
public static void setLocale(Activity activity)
|
||||
{
|
||||
String locale = PreferenceConfiguration.readPreferences(activity).language;
|
||||
if (!locale.equals(PreferenceConfiguration.DEFAULT_LANGUAGE)) {
|
||||
Configuration config = new Configuration(activity.getResources().getConfiguration());
|
||||
|
||||
// Some locales include both language and country which must be separated
|
||||
// before calling the Locale constructor.
|
||||
if (locale.contains("-"))
|
||||
{
|
||||
config.locale = new Locale(locale.substring(0, locale.indexOf('-')),
|
||||
locale.substring(locale.indexOf('-') + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
config.locale = new Locale(locale);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
// On Android 13, migrate this non-default language setting into the OS native API
|
||||
LocaleManager localeManager = activity.getSystemService(LocaleManager.class);
|
||||
localeManager.setApplicationLocales(LocaleList.forLanguageTags(locale));
|
||||
PreferenceConfiguration.completeLanguagePreferenceMigration(activity);
|
||||
}
|
||||
else {
|
||||
Configuration config = new Configuration(activity.getResources().getConfiguration());
|
||||
|
||||
activity.getResources().updateConfiguration(config, activity.getResources().getDisplayMetrics());
|
||||
// Some locales include both language and country which must be separated
|
||||
// before calling the Locale constructor.
|
||||
if (locale.contains("-"))
|
||||
{
|
||||
config.locale = new Locale(locale.substring(0, locale.indexOf('-')),
|
||||
locale.substring(locale.indexOf('-') + 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
config.locale = new Locale(locale);
|
||||
}
|
||||
|
||||
activity.getResources().updateConfiguration(config, activity.getResources().getDisplayMetrics());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +114,9 @@ public class UiHelper {
|
||||
View rootView = activity.findViewById(android.R.id.content);
|
||||
UiModeManager modeMgr = (UiModeManager) activity.getSystemService(Context.UI_MODE_SERVICE);
|
||||
|
||||
// Set GameState.MODE_NONE initially for all activities
|
||||
setGameModeStatus(activity, false, false, false);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
// Allow this non-streaming activity to layout under notches.
|
||||
//
|
||||
|
||||
@@ -20,8 +20,8 @@ LOCAL_SRC_FILES := moonlight-common-c/src/AudioStream.c \
|
||||
moonlight-common-c/src/Platform.c \
|
||||
moonlight-common-c/src/PlatformCrypto.c \
|
||||
moonlight-common-c/src/PlatformSockets.c \
|
||||
moonlight-common-c/src/RtpFecQueue.c \
|
||||
moonlight-common-c/src/RtpReorderQueue.c \
|
||||
moonlight-common-c/src/RtpAudioQueue.c \
|
||||
moonlight-common-c/src/RtpVideoQueue.c \
|
||||
moonlight-common-c/src/RtspConnection.c \
|
||||
moonlight-common-c/src/RtspParser.c \
|
||||
moonlight-common-c/src/SdpGenerator.c \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
|
||||
PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
|
||||
OUTPUT_DIR=~/openssl
|
||||
|
||||
BASE_ARGS="no-shared no-ssl3 no-stdio no-engine no-hw"
|
||||
|
||||
@@ -32,6 +32,7 @@ static jmethodID BridgeClConnectionStartedMethod;
|
||||
static jmethodID BridgeClConnectionTerminatedMethod;
|
||||
static jmethodID BridgeClRumbleMethod;
|
||||
static jmethodID BridgeClConnectionStatusUpdateMethod;
|
||||
static jmethodID BridgeClSetHdrModeMethod;
|
||||
static jbyteArray DecodedFrameBuffer;
|
||||
static jshortArray DecodedAudioBuffer;
|
||||
|
||||
@@ -79,7 +80,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_init(JNIEnv *env, jclass clazz) {
|
||||
BridgeDrStartMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrStart", "()V");
|
||||
BridgeDrStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrStop", "()V");
|
||||
BridgeDrCleanupMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrCleanup", "()V");
|
||||
BridgeDrSubmitDecodeUnitMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrSubmitDecodeUnit", "([BIIIJJ)I");
|
||||
BridgeDrSubmitDecodeUnitMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeDrSubmitDecodeUnit", "([BIIIIJJ)I");
|
||||
BridgeArInitMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArInit", "(III)I");
|
||||
BridgeArStartMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArStart", "()V");
|
||||
BridgeArStopMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeArStop", "()V");
|
||||
@@ -92,6 +93,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_init(JNIEnv *env, jclass clazz) {
|
||||
BridgeClConnectionTerminatedMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClConnectionTerminated", "(I)V");
|
||||
BridgeClRumbleMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClRumble", "(SSS)V");
|
||||
BridgeClConnectionStatusUpdateMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClConnectionStatusUpdate", "(I)V");
|
||||
BridgeClSetHdrModeMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClSetHdrMode", "(Z)V");
|
||||
}
|
||||
|
||||
int BridgeDrSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags) {
|
||||
@@ -157,8 +159,8 @@ int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
||||
|
||||
ret = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSubmitDecodeUnitMethod,
|
||||
DecodedFrameBuffer, currentEntry->length, currentEntry->bufferType,
|
||||
decodeUnit->frameNumber, (jlong)decodeUnit->receiveTimeMs,
|
||||
(jlong)decodeUnit->enqueueTimeMs);
|
||||
decodeUnit->frameNumber, decodeUnit->frameType,
|
||||
(jlong)decodeUnit->receiveTimeMs, (jlong)decodeUnit->enqueueTimeMs);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// We will crash here
|
||||
(*JVM)->DetachCurrentThread(JVM);
|
||||
@@ -178,7 +180,7 @@ int BridgeDrSubmitDecodeUnit(PDECODE_UNIT decodeUnit) {
|
||||
|
||||
ret = (*env)->CallStaticIntMethod(env, GlobalBridgeClass, BridgeDrSubmitDecodeUnitMethod,
|
||||
DecodedFrameBuffer, offset, BUFFER_TYPE_PICDATA,
|
||||
decodeUnit->frameNumber,
|
||||
decodeUnit->frameNumber, decodeUnit->frameType,
|
||||
(jlong)decodeUnit->receiveTimeMs, (jlong)decodeUnit->enqueueTimeMs);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// We will crash here
|
||||
@@ -326,6 +328,16 @@ void BridgeClConnectionStatusUpdate(int connectionStatus) {
|
||||
}
|
||||
}
|
||||
|
||||
void BridgeClSetHdrMode(bool enabled) {
|
||||
JNIEnv* env = GetThreadEnv();
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClSetHdrModeMethod, enabled);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// We will crash here
|
||||
(*JVM)->DetachCurrentThread(JVM);
|
||||
}
|
||||
}
|
||||
|
||||
void BridgeClLogMessage(const char* format, ...) {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
@@ -359,11 +371,13 @@ static CONNECTION_LISTENER_CALLBACKS BridgeConnListenerCallbacks = {
|
||||
.logMessage = BridgeClLogMessage,
|
||||
.rumble = BridgeClRumble,
|
||||
.connectionStatusUpdate = BridgeClConnectionStatusUpdate,
|
||||
.setHdrMode = BridgeClSetHdrMode,
|
||||
};
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass clazz,
|
||||
jstring address, jstring appVersion, jstring gfeVersion,
|
||||
jstring rtspSessionUrl,
|
||||
jint width, jint height, jint fps,
|
||||
jint bitrate, jint packetSize, jint streamingRemotely,
|
||||
jint audioConfiguration, jboolean supportsHevc,
|
||||
@@ -377,6 +391,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass c
|
||||
.address = (*env)->GetStringUTFChars(env, address, 0),
|
||||
.serverInfoAppVersion = (*env)->GetStringUTFChars(env, appVersion, 0),
|
||||
.serverInfoGfeVersion = gfeVersion ? (*env)->GetStringUTFChars(env, gfeVersion, 0) : NULL,
|
||||
.rtspSessionUrl = rtspSessionUrl ? (*env)->GetStringUTFChars(env, rtspSessionUrl, 0) : NULL,
|
||||
};
|
||||
STREAM_CONFIGURATION streamConfig = {
|
||||
.width = width,
|
||||
@@ -416,6 +431,9 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass c
|
||||
if (gfeVersion != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, gfeVersion, serverInfo.serverInfoGfeVersion);
|
||||
}
|
||||
if (rtspSessionUrl != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, rtspSessionUrl, serverInfo.rtspSessionUrl);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
Submodule app/src/main/jni/moonlight-core/moonlight-common-c updated: 65047ac0e2...50603ac16e
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
592
app/src/main/jni/moonlight-core/openssl/include/openssl/cmp.h
Normal file
592
app/src/main/jni/moonlight-core/openssl/include/openssl/cmp.h
Normal file
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* WARNING: do not edit!
|
||||
* Generated by Makefile from include/openssl/cmp.h.in
|
||||
*
|
||||
* Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef OPENSSL_CMP_H
|
||||
# define OPENSSL_CMP_H
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
# ifndef OPENSSL_NO_CMP
|
||||
|
||||
# include <openssl/crmf.h>
|
||||
# include <openssl/cmperr.h>
|
||||
# include <openssl/cmp_util.h>
|
||||
# include <openssl/http.h>
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
# include <openssl/types.h>
|
||||
# include <openssl/safestack.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/x509v3.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# define OSSL_CMP_PVNO 2
|
||||
|
||||
/*-
|
||||
* PKIFailureInfo ::= BIT STRING {
|
||||
* -- since we can fail in more than one way!
|
||||
* -- More codes may be added in the future if/when required.
|
||||
* badAlg (0),
|
||||
* -- unrecognized or unsupported Algorithm Identifier
|
||||
* badMessageCheck (1),
|
||||
* -- integrity check failed (e.g., signature did not verify)
|
||||
* badRequest (2),
|
||||
* -- transaction not permitted or supported
|
||||
* badTime (3),
|
||||
* -- messageTime was not sufficiently close to the system time,
|
||||
* -- as defined by local policy
|
||||
* badCertId (4),
|
||||
* -- no certificate could be found matching the provided criteria
|
||||
* badDataFormat (5),
|
||||
* -- the data submitted has the wrong format
|
||||
* wrongAuthority (6),
|
||||
* -- the authority indicated in the request is different from the
|
||||
* -- one creating the response token
|
||||
* incorrectData (7),
|
||||
* -- the requester's data is incorrect (for notary services)
|
||||
* missingTimeStamp (8),
|
||||
* -- when the timestamp is missing but should be there
|
||||
* -- (by policy)
|
||||
* badPOP (9),
|
||||
* -- the proof-of-possession failed
|
||||
* certRevoked (10),
|
||||
* -- the certificate has already been revoked
|
||||
* certConfirmed (11),
|
||||
* -- the certificate has already been confirmed
|
||||
* wrongIntegrity (12),
|
||||
* -- invalid integrity, password based instead of signature or
|
||||
* -- vice versa
|
||||
* badRecipientNonce (13),
|
||||
* -- invalid recipient nonce, either missing or wrong value
|
||||
* timeNotAvailable (14),
|
||||
* -- the TSA's time source is not available
|
||||
* unacceptedPolicy (15),
|
||||
* -- the requested TSA policy is not supported by the TSA.
|
||||
* unacceptedExtension (16),
|
||||
* -- the requested extension is not supported by the TSA.
|
||||
* addInfoNotAvailable (17),
|
||||
* -- the additional information requested could not be
|
||||
* -- understood or is not available
|
||||
* badSenderNonce (18),
|
||||
* -- invalid sender nonce, either missing or wrong size
|
||||
* badCertTemplate (19),
|
||||
* -- invalid cert. template or missing mandatory information
|
||||
* signerNotTrusted (20),
|
||||
* -- signer of the message unknown or not trusted
|
||||
* transactionIdInUse (21),
|
||||
* -- the transaction identifier is already in use
|
||||
* unsupportedVersion (22),
|
||||
* -- the version of the message is not supported
|
||||
* notAuthorized (23),
|
||||
* -- the sender was not authorized to make the preceding
|
||||
* -- request or perform the preceding action
|
||||
* systemUnavail (24),
|
||||
* -- the request cannot be handled due to system unavailability
|
||||
* systemFailure (25),
|
||||
* -- the request cannot be handled due to system failure
|
||||
* duplicateCertReq (26)
|
||||
* -- certificate cannot be issued because a duplicate
|
||||
* -- certificate already exists
|
||||
* }
|
||||
*/
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badAlg 0
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badMessageCheck 1
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badRequest 2
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badTime 3
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badCertId 4
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badDataFormat 5
|
||||
# define OSSL_CMP_PKIFAILUREINFO_wrongAuthority 6
|
||||
# define OSSL_CMP_PKIFAILUREINFO_incorrectData 7
|
||||
# define OSSL_CMP_PKIFAILUREINFO_missingTimeStamp 8
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badPOP 9
|
||||
# define OSSL_CMP_PKIFAILUREINFO_certRevoked 10
|
||||
# define OSSL_CMP_PKIFAILUREINFO_certConfirmed 11
|
||||
# define OSSL_CMP_PKIFAILUREINFO_wrongIntegrity 12
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badRecipientNonce 13
|
||||
# define OSSL_CMP_PKIFAILUREINFO_timeNotAvailable 14
|
||||
# define OSSL_CMP_PKIFAILUREINFO_unacceptedPolicy 15
|
||||
# define OSSL_CMP_PKIFAILUREINFO_unacceptedExtension 16
|
||||
# define OSSL_CMP_PKIFAILUREINFO_addInfoNotAvailable 17
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badSenderNonce 18
|
||||
# define OSSL_CMP_PKIFAILUREINFO_badCertTemplate 19
|
||||
# define OSSL_CMP_PKIFAILUREINFO_signerNotTrusted 20
|
||||
# define OSSL_CMP_PKIFAILUREINFO_transactionIdInUse 21
|
||||
# define OSSL_CMP_PKIFAILUREINFO_unsupportedVersion 22
|
||||
# define OSSL_CMP_PKIFAILUREINFO_notAuthorized 23
|
||||
# define OSSL_CMP_PKIFAILUREINFO_systemUnavail 24
|
||||
# define OSSL_CMP_PKIFAILUREINFO_systemFailure 25
|
||||
# define OSSL_CMP_PKIFAILUREINFO_duplicateCertReq 26
|
||||
# define OSSL_CMP_PKIFAILUREINFO_MAX 26
|
||||
# define OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN \
|
||||
((1 << (OSSL_CMP_PKIFAILUREINFO_MAX + 1)) - 1)
|
||||
# if OSSL_CMP_PKIFAILUREINFO_MAX_BIT_PATTERN > INT_MAX
|
||||
# error CMP_PKIFAILUREINFO_MAX bit pattern does not fit in type int
|
||||
# endif
|
||||
|
||||
typedef ASN1_BIT_STRING OSSL_CMP_PKIFAILUREINFO;
|
||||
|
||||
# define OSSL_CMP_CTX_FAILINFO_badAlg (1 << 0)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badMessageCheck (1 << 1)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badRequest (1 << 2)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badTime (1 << 3)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badCertId (1 << 4)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badDataFormat (1 << 5)
|
||||
# define OSSL_CMP_CTX_FAILINFO_wrongAuthority (1 << 6)
|
||||
# define OSSL_CMP_CTX_FAILINFO_incorrectData (1 << 7)
|
||||
# define OSSL_CMP_CTX_FAILINFO_missingTimeStamp (1 << 8)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badPOP (1 << 9)
|
||||
# define OSSL_CMP_CTX_FAILINFO_certRevoked (1 << 10)
|
||||
# define OSSL_CMP_CTX_FAILINFO_certConfirmed (1 << 11)
|
||||
# define OSSL_CMP_CTX_FAILINFO_wrongIntegrity (1 << 12)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badRecipientNonce (1 << 13)
|
||||
# define OSSL_CMP_CTX_FAILINFO_timeNotAvailable (1 << 14)
|
||||
# define OSSL_CMP_CTX_FAILINFO_unacceptedPolicy (1 << 15)
|
||||
# define OSSL_CMP_CTX_FAILINFO_unacceptedExtension (1 << 16)
|
||||
# define OSSL_CMP_CTX_FAILINFO_addInfoNotAvailable (1 << 17)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badSenderNonce (1 << 18)
|
||||
# define OSSL_CMP_CTX_FAILINFO_badCertTemplate (1 << 19)
|
||||
# define OSSL_CMP_CTX_FAILINFO_signerNotTrusted (1 << 20)
|
||||
# define OSSL_CMP_CTX_FAILINFO_transactionIdInUse (1 << 21)
|
||||
# define OSSL_CMP_CTX_FAILINFO_unsupportedVersion (1 << 22)
|
||||
# define OSSL_CMP_CTX_FAILINFO_notAuthorized (1 << 23)
|
||||
# define OSSL_CMP_CTX_FAILINFO_systemUnavail (1 << 24)
|
||||
# define OSSL_CMP_CTX_FAILINFO_systemFailure (1 << 25)
|
||||
# define OSSL_CMP_CTX_FAILINFO_duplicateCertReq (1 << 26)
|
||||
|
||||
/*-
|
||||
* PKIStatus ::= INTEGER {
|
||||
* accepted (0),
|
||||
* -- you got exactly what you asked for
|
||||
* grantedWithMods (1),
|
||||
* -- you got something like what you asked for; the
|
||||
* -- requester is responsible for ascertaining the differences
|
||||
* rejection (2),
|
||||
* -- you don't get it, more information elsewhere in the message
|
||||
* waiting (3),
|
||||
* -- the request body part has not yet been processed; expect to
|
||||
* -- hear more later (note: proper handling of this status
|
||||
* -- response MAY use the polling req/rep PKIMessages specified
|
||||
* -- in Section 5.3.22; alternatively, polling in the underlying
|
||||
* -- transport layer MAY have some utility in this regard)
|
||||
* revocationWarning (4),
|
||||
* -- this message contains a warning that a revocation is
|
||||
* -- imminent
|
||||
* revocationNotification (5),
|
||||
* -- notification that a revocation has occurred
|
||||
* keyUpdateWarning (6)
|
||||
* -- update already done for the oldCertId specified in
|
||||
* -- CertReqMsg
|
||||
* }
|
||||
*/
|
||||
# define OSSL_CMP_PKISTATUS_accepted 0
|
||||
# define OSSL_CMP_PKISTATUS_grantedWithMods 1
|
||||
# define OSSL_CMP_PKISTATUS_rejection 2
|
||||
# define OSSL_CMP_PKISTATUS_waiting 3
|
||||
# define OSSL_CMP_PKISTATUS_revocationWarning 4
|
||||
# define OSSL_CMP_PKISTATUS_revocationNotification 5
|
||||
# define OSSL_CMP_PKISTATUS_keyUpdateWarning 6
|
||||
|
||||
typedef ASN1_INTEGER OSSL_CMP_PKISTATUS;
|
||||
DECLARE_ASN1_ITEM(OSSL_CMP_PKISTATUS)
|
||||
|
||||
# define OSSL_CMP_CERTORENCCERT_CERTIFICATE 0
|
||||
# define OSSL_CMP_CERTORENCCERT_ENCRYPTEDCERT 1
|
||||
|
||||
/* data type declarations */
|
||||
typedef struct ossl_cmp_ctx_st OSSL_CMP_CTX;
|
||||
typedef struct ossl_cmp_pkiheader_st OSSL_CMP_PKIHEADER;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKIHEADER)
|
||||
typedef struct ossl_cmp_msg_st OSSL_CMP_MSG;
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_MSG)
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS(OSSL_CMP_MSG, OSSL_CMP_MSG, OSSL_CMP_MSG)
|
||||
typedef struct ossl_cmp_certstatus_st OSSL_CMP_CERTSTATUS;
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CERTSTATUS, OSSL_CMP_CERTSTATUS, OSSL_CMP_CERTSTATUS)
|
||||
#define sk_OSSL_CMP_CERTSTATUS_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_value(sk, idx) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk), (idx)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_new(cmp) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CERTSTATUS_compfunc_type(cmp)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_new_null() ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_new_null())
|
||||
#define sk_OSSL_CMP_CERTSTATUS_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CERTSTATUS_compfunc_type(cmp), (n)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), (n))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_delete(sk, i) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), (i)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_delete_ptr(sk, ptr) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_pop(sk) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_shift(sk) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk),ossl_check_OSSL_CMP_CERTSTATUS_freefunc_type(freefunc))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr), (idx))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_set(sk, idx, ptr) ((OSSL_CMP_CERTSTATUS *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), (idx), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_type(ptr), pnum)
|
||||
#define sk_OSSL_CMP_CERTSTATUS_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_dup(sk) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CERTSTATUS) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CERTSTATUS_freefunc_type(freefunc)))
|
||||
#define sk_OSSL_CMP_CERTSTATUS_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CERTSTATUS_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CERTSTATUS_sk_type(sk), ossl_check_OSSL_CMP_CERTSTATUS_compfunc_type(cmp)))
|
||||
|
||||
typedef struct ossl_cmp_itav_st OSSL_CMP_ITAV;
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_ITAV)
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_ITAV, OSSL_CMP_ITAV, OSSL_CMP_ITAV)
|
||||
#define sk_OSSL_CMP_ITAV_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk))
|
||||
#define sk_OSSL_CMP_ITAV_value(sk, idx) ((OSSL_CMP_ITAV *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), (idx)))
|
||||
#define sk_OSSL_CMP_ITAV_new(cmp) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp)))
|
||||
#define sk_OSSL_CMP_ITAV_new_null() ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_null())
|
||||
#define sk_OSSL_CMP_ITAV_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp), (n)))
|
||||
#define sk_OSSL_CMP_ITAV_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (n))
|
||||
#define sk_OSSL_CMP_ITAV_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk))
|
||||
#define sk_OSSL_CMP_ITAV_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_ITAV_sk_type(sk))
|
||||
#define sk_OSSL_CMP_ITAV_delete(sk, i) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (i)))
|
||||
#define sk_OSSL_CMP_ITAV_delete_ptr(sk, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr)))
|
||||
#define sk_OSSL_CMP_ITAV_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr))
|
||||
#define sk_OSSL_CMP_ITAV_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr))
|
||||
#define sk_OSSL_CMP_ITAV_pop(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_ITAV_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_ITAV_shift(sk) ((OSSL_CMP_ITAV *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_ITAV_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_ITAV_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_ITAV_sk_type(sk),ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc))
|
||||
#define sk_OSSL_CMP_ITAV_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr), (idx))
|
||||
#define sk_OSSL_CMP_ITAV_set(sk, idx, ptr) ((OSSL_CMP_ITAV *)OPENSSL_sk_set(ossl_check_OSSL_CMP_ITAV_sk_type(sk), (idx), ossl_check_OSSL_CMP_ITAV_type(ptr)))
|
||||
#define sk_OSSL_CMP_ITAV_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr))
|
||||
#define sk_OSSL_CMP_ITAV_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr))
|
||||
#define sk_OSSL_CMP_ITAV_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_type(ptr), pnum)
|
||||
#define sk_OSSL_CMP_ITAV_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_ITAV_sk_type(sk))
|
||||
#define sk_OSSL_CMP_ITAV_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk))
|
||||
#define sk_OSSL_CMP_ITAV_dup(sk) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_ITAV_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_ITAV) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_ITAV_freefunc_type(freefunc)))
|
||||
#define sk_OSSL_CMP_ITAV_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_ITAV_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_ITAV_sk_type(sk), ossl_check_OSSL_CMP_ITAV_compfunc_type(cmp)))
|
||||
|
||||
typedef struct ossl_cmp_revrepcontent_st OSSL_CMP_REVREPCONTENT;
|
||||
typedef struct ossl_cmp_pkisi_st OSSL_CMP_PKISI;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CMP_PKISI)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CMP_PKISI)
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_PKISI, OSSL_CMP_PKISI, OSSL_CMP_PKISI)
|
||||
#define sk_OSSL_CMP_PKISI_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk))
|
||||
#define sk_OSSL_CMP_PKISI_value(sk, idx) ((OSSL_CMP_PKISI *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk), (idx)))
|
||||
#define sk_OSSL_CMP_PKISI_new(cmp) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_PKISI_compfunc_type(cmp)))
|
||||
#define sk_OSSL_CMP_PKISI_new_null() ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_new_null())
|
||||
#define sk_OSSL_CMP_PKISI_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_PKISI_compfunc_type(cmp), (n)))
|
||||
#define sk_OSSL_CMP_PKISI_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_PKISI_sk_type(sk), (n))
|
||||
#define sk_OSSL_CMP_PKISI_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_PKISI_sk_type(sk))
|
||||
#define sk_OSSL_CMP_PKISI_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_PKISI_sk_type(sk))
|
||||
#define sk_OSSL_CMP_PKISI_delete(sk, i) ((OSSL_CMP_PKISI *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_PKISI_sk_type(sk), (i)))
|
||||
#define sk_OSSL_CMP_PKISI_delete_ptr(sk, ptr) ((OSSL_CMP_PKISI *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr)))
|
||||
#define sk_OSSL_CMP_PKISI_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr))
|
||||
#define sk_OSSL_CMP_PKISI_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr))
|
||||
#define sk_OSSL_CMP_PKISI_pop(sk) ((OSSL_CMP_PKISI *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_PKISI_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_PKISI_shift(sk) ((OSSL_CMP_PKISI *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_PKISI_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_PKISI_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_PKISI_sk_type(sk),ossl_check_OSSL_CMP_PKISI_freefunc_type(freefunc))
|
||||
#define sk_OSSL_CMP_PKISI_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr), (idx))
|
||||
#define sk_OSSL_CMP_PKISI_set(sk, idx, ptr) ((OSSL_CMP_PKISI *)OPENSSL_sk_set(ossl_check_OSSL_CMP_PKISI_sk_type(sk), (idx), ossl_check_OSSL_CMP_PKISI_type(ptr)))
|
||||
#define sk_OSSL_CMP_PKISI_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr))
|
||||
#define sk_OSSL_CMP_PKISI_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr))
|
||||
#define sk_OSSL_CMP_PKISI_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_type(ptr), pnum)
|
||||
#define sk_OSSL_CMP_PKISI_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_PKISI_sk_type(sk))
|
||||
#define sk_OSSL_CMP_PKISI_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk))
|
||||
#define sk_OSSL_CMP_PKISI_dup(sk) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_PKISI_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_PKISI) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_PKISI_freefunc_type(freefunc)))
|
||||
#define sk_OSSL_CMP_PKISI_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_PKISI_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_PKISI_sk_type(sk), ossl_check_OSSL_CMP_PKISI_compfunc_type(cmp)))
|
||||
|
||||
typedef struct ossl_cmp_certrepmessage_st OSSL_CMP_CERTREPMESSAGE;
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CERTREPMESSAGE, OSSL_CMP_CERTREPMESSAGE, OSSL_CMP_CERTREPMESSAGE)
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_value(sk, idx) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (idx)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_new(cmp) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CERTREPMESSAGE_compfunc_type(cmp)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_new_null() ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_new_null())
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CERTREPMESSAGE_compfunc_type(cmp), (n)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (n))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_delete(sk, i) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (i)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_delete_ptr(sk, ptr) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_pop(sk) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_shift(sk) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk),ossl_check_OSSL_CMP_CERTREPMESSAGE_freefunc_type(freefunc))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr), (idx))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_set(sk, idx, ptr) ((OSSL_CMP_CERTREPMESSAGE *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), (idx), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_type(ptr), pnum)
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_dup(sk) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CERTREPMESSAGE) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CERTREPMESSAGE_freefunc_type(freefunc)))
|
||||
#define sk_OSSL_CMP_CERTREPMESSAGE_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CERTREPMESSAGE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CERTREPMESSAGE_sk_type(sk), ossl_check_OSSL_CMP_CERTREPMESSAGE_compfunc_type(cmp)))
|
||||
|
||||
typedef struct ossl_cmp_pollrep_st OSSL_CMP_POLLREP;
|
||||
typedef STACK_OF(OSSL_CMP_POLLREP) OSSL_CMP_POLLREPCONTENT;
|
||||
typedef struct ossl_cmp_certresponse_st OSSL_CMP_CERTRESPONSE;
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CMP_CERTRESPONSE, OSSL_CMP_CERTRESPONSE, OSSL_CMP_CERTRESPONSE)
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_value(sk, idx) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_value(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk), (idx)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_new(cmp) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_new(ossl_check_OSSL_CMP_CERTRESPONSE_compfunc_type(cmp)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_new_null() ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_new_null())
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_new_reserve(cmp, n) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CMP_CERTRESPONSE_compfunc_type(cmp), (n)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), (n))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_delete(sk, i) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_delete(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), (i)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_delete_ptr(sk, ptr) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_pop(sk) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_pop(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_shift(sk) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_shift(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk),ossl_check_OSSL_CMP_CERTRESPONSE_freefunc_type(freefunc))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr), (idx))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_set(sk, idx, ptr) ((OSSL_CMP_CERTRESPONSE *)OPENSSL_sk_set(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), (idx), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_type(ptr), pnum)
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_dup(sk) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CMP_CERTRESPONSE) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_copyfunc_type(copyfunc), ossl_check_OSSL_CMP_CERTRESPONSE_freefunc_type(freefunc)))
|
||||
#define sk_OSSL_CMP_CERTRESPONSE_set_cmp_func(sk, cmp) ((sk_OSSL_CMP_CERTRESPONSE_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CMP_CERTRESPONSE_sk_type(sk), ossl_check_OSSL_CMP_CERTRESPONSE_compfunc_type(cmp)))
|
||||
|
||||
typedef STACK_OF(ASN1_UTF8STRING) OSSL_CMP_PKIFREETEXT;
|
||||
|
||||
/*
|
||||
* function DECLARATIONS
|
||||
*/
|
||||
|
||||
/* from cmp_asn.c */
|
||||
OSSL_CMP_ITAV *OSSL_CMP_ITAV_create(ASN1_OBJECT *type, ASN1_TYPE *value);
|
||||
void OSSL_CMP_ITAV_set0(OSSL_CMP_ITAV *itav, ASN1_OBJECT *type,
|
||||
ASN1_TYPE *value);
|
||||
ASN1_OBJECT *OSSL_CMP_ITAV_get0_type(const OSSL_CMP_ITAV *itav);
|
||||
ASN1_TYPE *OSSL_CMP_ITAV_get0_value(const OSSL_CMP_ITAV *itav);
|
||||
int OSSL_CMP_ITAV_push0_stack_item(STACK_OF(OSSL_CMP_ITAV) **itav_sk_p,
|
||||
OSSL_CMP_ITAV *itav);
|
||||
void OSSL_CMP_ITAV_free(OSSL_CMP_ITAV *itav);
|
||||
void OSSL_CMP_MSG_free(OSSL_CMP_MSG *msg);
|
||||
|
||||
/* from cmp_ctx.c */
|
||||
OSSL_CMP_CTX *OSSL_CMP_CTX_new(OSSL_LIB_CTX *libctx, const char *propq);
|
||||
void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx);
|
||||
int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx);
|
||||
/* CMP general options: */
|
||||
# define OSSL_CMP_OPT_LOG_VERBOSITY 0
|
||||
/* CMP transfer options: */
|
||||
# define OSSL_CMP_OPT_KEEP_ALIVE 10
|
||||
# define OSSL_CMP_OPT_MSG_TIMEOUT 11
|
||||
# define OSSL_CMP_OPT_TOTAL_TIMEOUT 12
|
||||
/* CMP request options: */
|
||||
# define OSSL_CMP_OPT_VALIDITY_DAYS 20
|
||||
# define OSSL_CMP_OPT_SUBJECTALTNAME_NODEFAULT 21
|
||||
# define OSSL_CMP_OPT_SUBJECTALTNAME_CRITICAL 22
|
||||
# define OSSL_CMP_OPT_POLICIES_CRITICAL 23
|
||||
# define OSSL_CMP_OPT_POPO_METHOD 24
|
||||
# define OSSL_CMP_OPT_IMPLICIT_CONFIRM 25
|
||||
# define OSSL_CMP_OPT_DISABLE_CONFIRM 26
|
||||
# define OSSL_CMP_OPT_REVOCATION_REASON 27
|
||||
/* CMP protection options: */
|
||||
# define OSSL_CMP_OPT_UNPROTECTED_SEND 30
|
||||
# define OSSL_CMP_OPT_UNPROTECTED_ERRORS 31
|
||||
# define OSSL_CMP_OPT_OWF_ALGNID 32
|
||||
# define OSSL_CMP_OPT_MAC_ALGNID 33
|
||||
# define OSSL_CMP_OPT_DIGEST_ALGNID 34
|
||||
# define OSSL_CMP_OPT_IGNORE_KEYUSAGE 35
|
||||
# define OSSL_CMP_OPT_PERMIT_TA_IN_EXTRACERTS_FOR_IR 36
|
||||
int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val);
|
||||
int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt);
|
||||
/* CMP-specific callback for logging and outputting the error queue: */
|
||||
int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb);
|
||||
# define OSSL_CMP_CTX_set_log_verbosity(ctx, level) \
|
||||
OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_LOG_VERBOSITY, level)
|
||||
void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx);
|
||||
/* message transfer: */
|
||||
int OSSL_CMP_CTX_set1_serverPath(OSSL_CMP_CTX *ctx, const char *path);
|
||||
int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address);
|
||||
int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port);
|
||||
int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name);
|
||||
int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names);
|
||||
int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb);
|
||||
int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg);
|
||||
void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx);
|
||||
typedef OSSL_CMP_MSG *(*OSSL_CMP_transfer_cb_t) (OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req);
|
||||
int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb);
|
||||
int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg);
|
||||
void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx);
|
||||
/* server authentication: */
|
||||
int OSSL_CMP_CTX_set1_srvCert(OSSL_CMP_CTX *ctx, X509 *cert);
|
||||
int OSSL_CMP_CTX_set1_expected_sender(OSSL_CMP_CTX *ctx, const X509_NAME *name);
|
||||
int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store);
|
||||
X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx);
|
||||
int OSSL_CMP_CTX_set1_untrusted(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs);
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted(const OSSL_CMP_CTX *ctx);
|
||||
/* client authentication: */
|
||||
int OSSL_CMP_CTX_set1_cert(OSSL_CMP_CTX *ctx, X509 *cert);
|
||||
int OSSL_CMP_CTX_build_cert_chain(OSSL_CMP_CTX *ctx, X509_STORE *own_trusted,
|
||||
STACK_OF(X509) *candidates);
|
||||
int OSSL_CMP_CTX_set1_pkey(OSSL_CMP_CTX *ctx, EVP_PKEY *pkey);
|
||||
int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx,
|
||||
const unsigned char *ref, int len);
|
||||
int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec,
|
||||
const int len);
|
||||
/* CMP message header and extra certificates: */
|
||||
int OSSL_CMP_CTX_set1_recipient(OSSL_CMP_CTX *ctx, const X509_NAME *name);
|
||||
int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav);
|
||||
int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx,
|
||||
STACK_OF(X509) *extraCertsOut);
|
||||
/* certificate template: */
|
||||
int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey);
|
||||
EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv);
|
||||
int OSSL_CMP_CTX_set1_issuer(OSSL_CMP_CTX *ctx, const X509_NAME *name);
|
||||
int OSSL_CMP_CTX_set1_subjectName(OSSL_CMP_CTX *ctx, const X509_NAME *name);
|
||||
int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx,
|
||||
const GENERAL_NAME *name);
|
||||
int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts);
|
||||
int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx);
|
||||
int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo);
|
||||
int OSSL_CMP_CTX_set1_oldCert(OSSL_CMP_CTX *ctx, X509 *cert);
|
||||
int OSSL_CMP_CTX_set1_p10CSR(OSSL_CMP_CTX *ctx, const X509_REQ *csr);
|
||||
/* misc body contents: */
|
||||
int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav);
|
||||
/* certificate confirmation: */
|
||||
typedef int (*OSSL_CMP_certConf_cb_t) (OSSL_CMP_CTX *ctx, X509 *cert,
|
||||
int fail_info, const char **txt);
|
||||
int OSSL_CMP_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info,
|
||||
const char **text);
|
||||
int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb);
|
||||
int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg);
|
||||
void *OSSL_CMP_CTX_get_certConf_cb_arg(const OSSL_CMP_CTX *ctx);
|
||||
/* result fetching: */
|
||||
int OSSL_CMP_CTX_get_status(const OSSL_CMP_CTX *ctx);
|
||||
OSSL_CMP_PKIFREETEXT *OSSL_CMP_CTX_get0_statusString(const OSSL_CMP_CTX *ctx);
|
||||
int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx);
|
||||
# define OSSL_CMP_PKISI_BUFLEN 1024
|
||||
X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx);
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get1_newChain(const OSSL_CMP_CTX *ctx);
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx);
|
||||
STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx);
|
||||
int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *id);
|
||||
int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx,
|
||||
const ASN1_OCTET_STRING *nonce);
|
||||
|
||||
/* from cmp_status.c */
|
||||
char *OSSL_CMP_CTX_snprint_PKIStatus(const OSSL_CMP_CTX *ctx, char *buf,
|
||||
size_t bufsize);
|
||||
char *OSSL_CMP_snprint_PKIStatusInfo(const OSSL_CMP_PKISI *statusInfo,
|
||||
char *buf, size_t bufsize);
|
||||
OSSL_CMP_PKISI *
|
||||
OSSL_CMP_STATUSINFO_new(int status, int fail_info, const char *text);
|
||||
|
||||
/* from cmp_hdr.c */
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const
|
||||
OSSL_CMP_PKIHEADER *hdr);
|
||||
ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_recipNonce(const OSSL_CMP_PKIHEADER *hdr);
|
||||
|
||||
/* from cmp_msg.c */
|
||||
OSSL_CMP_PKIHEADER *OSSL_CMP_MSG_get0_header(const OSSL_CMP_MSG *msg);
|
||||
int OSSL_CMP_MSG_get_bodytype(const OSSL_CMP_MSG *msg);
|
||||
int OSSL_CMP_MSG_update_transactionID(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg);
|
||||
OSSL_CRMF_MSG *OSSL_CMP_CTX_setup_CRM(OSSL_CMP_CTX *ctx, int for_KUR, int rid);
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_read(const char *file, OSSL_LIB_CTX *libctx,
|
||||
const char *propq);
|
||||
int OSSL_CMP_MSG_write(const char *file, const OSSL_CMP_MSG *msg);
|
||||
OSSL_CMP_MSG *d2i_OSSL_CMP_MSG_bio(BIO *bio, OSSL_CMP_MSG **msg);
|
||||
int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg);
|
||||
|
||||
/* from cmp_vfy.c */
|
||||
int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg);
|
||||
int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx,
|
||||
X509_STORE *trusted_store, X509 *cert);
|
||||
|
||||
/* from cmp_http.c */
|
||||
OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx,
|
||||
const OSSL_CMP_MSG *req);
|
||||
|
||||
/* from cmp_server.c */
|
||||
typedef struct ossl_cmp_srv_ctx_st OSSL_CMP_SRV_CTX;
|
||||
OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req);
|
||||
OSSL_CMP_MSG * OSSL_CMP_CTX_server_perform(OSSL_CMP_CTX *client_ctx,
|
||||
const OSSL_CMP_MSG *req);
|
||||
OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq);
|
||||
void OSSL_CMP_SRV_CTX_free(OSSL_CMP_SRV_CTX *srv_ctx);
|
||||
typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_cert_request_cb_t)
|
||||
(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req, int certReqId,
|
||||
const OSSL_CRMF_MSG *crm, const X509_REQ *p10cr,
|
||||
X509 **certOut, STACK_OF(X509) **chainOut, STACK_OF(X509) **caPubs);
|
||||
typedef OSSL_CMP_PKISI *(*OSSL_CMP_SRV_rr_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req,
|
||||
const X509_NAME *issuer,
|
||||
const ASN1_INTEGER *serial);
|
||||
typedef int (*OSSL_CMP_SRV_genm_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req,
|
||||
const STACK_OF(OSSL_CMP_ITAV) *in,
|
||||
STACK_OF(OSSL_CMP_ITAV) **out);
|
||||
typedef void (*OSSL_CMP_SRV_error_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req,
|
||||
const OSSL_CMP_PKISI *statusInfo,
|
||||
const ASN1_INTEGER *errorCode,
|
||||
const OSSL_CMP_PKIFREETEXT *errDetails);
|
||||
typedef int (*OSSL_CMP_SRV_certConf_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req,
|
||||
int certReqId,
|
||||
const ASN1_OCTET_STRING *certHash,
|
||||
const OSSL_CMP_PKISI *si);
|
||||
typedef int (*OSSL_CMP_SRV_pollReq_cb_t)(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
const OSSL_CMP_MSG *req, int certReqId,
|
||||
OSSL_CMP_MSG **certReq,
|
||||
int64_t *check_after);
|
||||
int OSSL_CMP_SRV_CTX_init(OSSL_CMP_SRV_CTX *srv_ctx, void *custom_ctx,
|
||||
OSSL_CMP_SRV_cert_request_cb_t process_cert_request,
|
||||
OSSL_CMP_SRV_rr_cb_t process_rr,
|
||||
OSSL_CMP_SRV_genm_cb_t process_genm,
|
||||
OSSL_CMP_SRV_error_cb_t process_error,
|
||||
OSSL_CMP_SRV_certConf_cb_t process_certConf,
|
||||
OSSL_CMP_SRV_pollReq_cb_t process_pollReq);
|
||||
OSSL_CMP_CTX *OSSL_CMP_SRV_CTX_get0_cmp_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
|
||||
void *OSSL_CMP_SRV_CTX_get0_custom_ctx(const OSSL_CMP_SRV_CTX *srv_ctx);
|
||||
int OSSL_CMP_SRV_CTX_set_send_unprotected_errors(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
int val);
|
||||
int OSSL_CMP_SRV_CTX_set_accept_unprotected(OSSL_CMP_SRV_CTX *srv_ctx, int val);
|
||||
int OSSL_CMP_SRV_CTX_set_accept_raverified(OSSL_CMP_SRV_CTX *srv_ctx, int val);
|
||||
int OSSL_CMP_SRV_CTX_set_grant_implicit_confirm(OSSL_CMP_SRV_CTX *srv_ctx,
|
||||
int val);
|
||||
|
||||
/* from cmp_client.c */
|
||||
X509 *OSSL_CMP_exec_certreq(OSSL_CMP_CTX *ctx, int req_type,
|
||||
const OSSL_CRMF_MSG *crm);
|
||||
# define OSSL_CMP_IR 0
|
||||
# define OSSL_CMP_CR 2
|
||||
# define OSSL_CMP_P10CR 4
|
||||
# define OSSL_CMP_KUR 7
|
||||
# define OSSL_CMP_exec_IR_ses(ctx) \
|
||||
OSSL_CMP_exec_certreq(ctx, OSSL_CMP_IR, NULL)
|
||||
# define OSSL_CMP_exec_CR_ses(ctx) \
|
||||
OSSL_CMP_exec_certreq(ctx, OSSL_CMP_CR, NULL)
|
||||
# define OSSL_CMP_exec_P10CR_ses(ctx) \
|
||||
OSSL_CMP_exec_certreq(ctx, OSSL_CMP_P10CR, NULL)
|
||||
# define OSSL_CMP_exec_KUR_ses(ctx) \
|
||||
OSSL_CMP_exec_certreq(ctx, OSSL_CMP_KUR, NULL)
|
||||
int OSSL_CMP_try_certreq(OSSL_CMP_CTX *ctx, int req_type,
|
||||
const OSSL_CRMF_MSG *crm, int *checkAfter);
|
||||
int OSSL_CMP_exec_RR_ses(OSSL_CMP_CTX *ctx);
|
||||
STACK_OF(OSSL_CMP_ITAV) *OSSL_CMP_exec_GENM_ses(OSSL_CMP_CTX *ctx);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
# endif /* !defined(OPENSSL_NO_CMP) */
|
||||
#endif /* !defined(OPENSSL_CMP_H) */
|
||||
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* WARNING: do not edit!
|
||||
* Generated by Makefile from include/openssl/configuration.h.in
|
||||
*
|
||||
* Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_CONFIGURATION_H
|
||||
# define OPENSSL_CONFIGURATION_H
|
||||
# pragma once
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# ifdef OPENSSL_ALGORITHM_DEFINES
|
||||
# error OPENSSL_ALGORITHM_DEFINES no longer supported
|
||||
# endif
|
||||
|
||||
/*
|
||||
* OpenSSL was configured with the following options:
|
||||
*/
|
||||
|
||||
# define OPENSSL_CONFIGURED_API 30000
|
||||
# ifndef OPENSSL_RAND_SEED_OS
|
||||
# define OPENSSL_RAND_SEED_OS
|
||||
# endif
|
||||
# ifndef OPENSSL_THREADS
|
||||
# define OPENSSL_THREADS
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_ACVP_TESTS
|
||||
# define OPENSSL_NO_ACVP_TESTS
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_AFALGENG
|
||||
# define OPENSSL_NO_AFALGENG
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_ASAN
|
||||
# define OPENSSL_NO_ASAN
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_CAPIENG
|
||||
# define OPENSSL_NO_CAPIENG
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_CRYPTO_MDEBUG
|
||||
# define OPENSSL_NO_CRYPTO_MDEBUG
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
|
||||
# define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_DEPRECATED
|
||||
# define OPENSSL_NO_DEPRECATED
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_DEVCRYPTOENG
|
||||
# define OPENSSL_NO_DEVCRYPTOENG
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
# define OPENSSL_NO_EC_NISTP_64_GCC_128
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_EGD
|
||||
# define OPENSSL_NO_EGD
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
# define OPENSSL_NO_ENGINE
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_EXTERNAL_TESTS
|
||||
# define OPENSSL_NO_EXTERNAL_TESTS
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_FIPS_SECURITYCHECKS
|
||||
# define OPENSSL_NO_FIPS_SECURITYCHECKS
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_FUZZ_AFL
|
||||
# define OPENSSL_NO_FUZZ_AFL
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_FUZZ_LIBFUZZER
|
||||
# define OPENSSL_NO_FUZZ_LIBFUZZER
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_KTLS
|
||||
# define OPENSSL_NO_KTLS
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_LOADERENG
|
||||
# define OPENSSL_NO_LOADERENG
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_MD2
|
||||
# define OPENSSL_NO_MD2
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_MSAN
|
||||
# define OPENSSL_NO_MSAN
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_PADLOCKENG
|
||||
# define OPENSSL_NO_PADLOCKENG
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_RC5
|
||||
# define OPENSSL_NO_RC5
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_SCTP
|
||||
# define OPENSSL_NO_SCTP
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_SRP
|
||||
# define OPENSSL_NO_SRP
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_SSL3
|
||||
# define OPENSSL_NO_SSL3
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_SSL3_METHOD
|
||||
# define OPENSSL_NO_SSL3_METHOD
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_TESTS
|
||||
# define OPENSSL_NO_TESTS
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_TRACE
|
||||
# define OPENSSL_NO_TRACE
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_UBSAN
|
||||
# define OPENSSL_NO_UBSAN
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_UNIT_TEST
|
||||
# define OPENSSL_NO_UNIT_TEST
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_UPLINK
|
||||
# define OPENSSL_NO_UPLINK
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
|
||||
# define OPENSSL_NO_WEAK_SSL_CIPHERS
|
||||
# endif
|
||||
# ifndef OPENSSL_NO_DYNAMIC_ENGINE
|
||||
# define OPENSSL_NO_DYNAMIC_ENGINE
|
||||
# endif
|
||||
|
||||
|
||||
/* Generate 80386 code? */
|
||||
# undef I386_ONLY
|
||||
|
||||
/*
|
||||
* The following are cipher-specific, but are part of the public API.
|
||||
*/
|
||||
# if !defined(OPENSSL_SYS_UEFI)
|
||||
# undef BN_LLONG
|
||||
/* Only one for the following should be defined */
|
||||
# define SIXTY_FOUR_BIT_LONG
|
||||
# undef SIXTY_FOUR_BIT
|
||||
# undef THIRTY_TWO_BIT
|
||||
# endif
|
||||
|
||||
# define RC4_INT unsigned int
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* OPENSSL_CONFIGURATION_H */
|
||||
227
app/src/main/jni/moonlight-core/openssl/include/openssl/crmf.h
Normal file
227
app/src/main/jni/moonlight-core/openssl/include/openssl/crmf.h
Normal file
@@ -0,0 +1,227 @@
|
||||
/*-
|
||||
* WARNING: do not edit!
|
||||
* Generated by Makefile from include/openssl/crmf.h.in
|
||||
*
|
||||
* Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright Nokia 2007-2019
|
||||
* Copyright Siemens AG 2015-2019
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*
|
||||
* CRMF (RFC 4211) implementation by M. Peylo, M. Viljanen, and D. von Oheimb.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef OPENSSL_CRMF_H
|
||||
# define OPENSSL_CRMF_H
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_CRMF
|
||||
# include <openssl/opensslv.h>
|
||||
# include <openssl/safestack.h>
|
||||
# include <openssl/crmferr.h>
|
||||
# include <openssl/x509v3.h> /* for GENERAL_NAME etc. */
|
||||
|
||||
/* explicit #includes not strictly needed since implied by the above: */
|
||||
# include <openssl/types.h>
|
||||
# include <openssl/x509.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# define OSSL_CRMF_POPOPRIVKEY_THISMESSAGE 0
|
||||
# define OSSL_CRMF_POPOPRIVKEY_SUBSEQUENTMESSAGE 1
|
||||
# define OSSL_CRMF_POPOPRIVKEY_DHMAC 2
|
||||
# define OSSL_CRMF_POPOPRIVKEY_AGREEMAC 3
|
||||
# define OSSL_CRMF_POPOPRIVKEY_ENCRYPTEDKEY 4
|
||||
|
||||
# define OSSL_CRMF_SUBSEQUENTMESSAGE_ENCRCERT 0
|
||||
# define OSSL_CRMF_SUBSEQUENTMESSAGE_CHALLENGERESP 1
|
||||
|
||||
typedef struct ossl_crmf_encryptedvalue_st OSSL_CRMF_ENCRYPTEDVALUE;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_ENCRYPTEDVALUE)
|
||||
typedef struct ossl_crmf_msg_st OSSL_CRMF_MSG;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSG)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_MSG)
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CRMF_MSG, OSSL_CRMF_MSG, OSSL_CRMF_MSG)
|
||||
#define sk_OSSL_CRMF_MSG_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_MSG_value(sk, idx) ((OSSL_CRMF_MSG *)OPENSSL_sk_value(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk), (idx)))
|
||||
#define sk_OSSL_CRMF_MSG_new(cmp) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_new(ossl_check_OSSL_CRMF_MSG_compfunc_type(cmp)))
|
||||
#define sk_OSSL_CRMF_MSG_new_null() ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_new_null())
|
||||
#define sk_OSSL_CRMF_MSG_new_reserve(cmp, n) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CRMF_MSG_compfunc_type(cmp), (n)))
|
||||
#define sk_OSSL_CRMF_MSG_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CRMF_MSG_sk_type(sk), (n))
|
||||
#define sk_OSSL_CRMF_MSG_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CRMF_MSG_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_MSG_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CRMF_MSG_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_MSG_delete(sk, i) ((OSSL_CRMF_MSG *)OPENSSL_sk_delete(ossl_check_OSSL_CRMF_MSG_sk_type(sk), (i)))
|
||||
#define sk_OSSL_CRMF_MSG_delete_ptr(sk, ptr) ((OSSL_CRMF_MSG *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr)))
|
||||
#define sk_OSSL_CRMF_MSG_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr))
|
||||
#define sk_OSSL_CRMF_MSG_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr))
|
||||
#define sk_OSSL_CRMF_MSG_pop(sk) ((OSSL_CRMF_MSG *)OPENSSL_sk_pop(ossl_check_OSSL_CRMF_MSG_sk_type(sk)))
|
||||
#define sk_OSSL_CRMF_MSG_shift(sk) ((OSSL_CRMF_MSG *)OPENSSL_sk_shift(ossl_check_OSSL_CRMF_MSG_sk_type(sk)))
|
||||
#define sk_OSSL_CRMF_MSG_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CRMF_MSG_sk_type(sk),ossl_check_OSSL_CRMF_MSG_freefunc_type(freefunc))
|
||||
#define sk_OSSL_CRMF_MSG_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr), (idx))
|
||||
#define sk_OSSL_CRMF_MSG_set(sk, idx, ptr) ((OSSL_CRMF_MSG *)OPENSSL_sk_set(ossl_check_OSSL_CRMF_MSG_sk_type(sk), (idx), ossl_check_OSSL_CRMF_MSG_type(ptr)))
|
||||
#define sk_OSSL_CRMF_MSG_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr))
|
||||
#define sk_OSSL_CRMF_MSG_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr))
|
||||
#define sk_OSSL_CRMF_MSG_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_type(ptr), pnum)
|
||||
#define sk_OSSL_CRMF_MSG_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CRMF_MSG_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_MSG_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_MSG_dup(sk) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk)))
|
||||
#define sk_OSSL_CRMF_MSG_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CRMF_MSG) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_copyfunc_type(copyfunc), ossl_check_OSSL_CRMF_MSG_freefunc_type(freefunc)))
|
||||
#define sk_OSSL_CRMF_MSG_set_cmp_func(sk, cmp) ((sk_OSSL_CRMF_MSG_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CRMF_MSG_sk_type(sk), ossl_check_OSSL_CRMF_MSG_compfunc_type(cmp)))
|
||||
|
||||
typedef struct ossl_crmf_attributetypeandvalue_st OSSL_CRMF_ATTRIBUTETYPEANDVALUE;
|
||||
typedef struct ossl_crmf_pbmparameter_st OSSL_CRMF_PBMPARAMETER;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PBMPARAMETER)
|
||||
typedef struct ossl_crmf_poposigningkey_st OSSL_CRMF_POPOSIGNINGKEY;
|
||||
typedef struct ossl_crmf_certrequest_st OSSL_CRMF_CERTREQUEST;
|
||||
typedef struct ossl_crmf_certid_st OSSL_CRMF_CERTID;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTID)
|
||||
DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID)
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(OSSL_CRMF_CERTID, OSSL_CRMF_CERTID, OSSL_CRMF_CERTID)
|
||||
#define sk_OSSL_CRMF_CERTID_num(sk) OPENSSL_sk_num(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_CERTID_value(sk, idx) ((OSSL_CRMF_CERTID *)OPENSSL_sk_value(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk), (idx)))
|
||||
#define sk_OSSL_CRMF_CERTID_new(cmp) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_new(ossl_check_OSSL_CRMF_CERTID_compfunc_type(cmp)))
|
||||
#define sk_OSSL_CRMF_CERTID_new_null() ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_new_null())
|
||||
#define sk_OSSL_CRMF_CERTID_new_reserve(cmp, n) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_new_reserve(ossl_check_OSSL_CRMF_CERTID_compfunc_type(cmp), (n)))
|
||||
#define sk_OSSL_CRMF_CERTID_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), (n))
|
||||
#define sk_OSSL_CRMF_CERTID_free(sk) OPENSSL_sk_free(ossl_check_OSSL_CRMF_CERTID_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_CERTID_zero(sk) OPENSSL_sk_zero(ossl_check_OSSL_CRMF_CERTID_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_CERTID_delete(sk, i) ((OSSL_CRMF_CERTID *)OPENSSL_sk_delete(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), (i)))
|
||||
#define sk_OSSL_CRMF_CERTID_delete_ptr(sk, ptr) ((OSSL_CRMF_CERTID *)OPENSSL_sk_delete_ptr(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr)))
|
||||
#define sk_OSSL_CRMF_CERTID_push(sk, ptr) OPENSSL_sk_push(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr))
|
||||
#define sk_OSSL_CRMF_CERTID_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr))
|
||||
#define sk_OSSL_CRMF_CERTID_pop(sk) ((OSSL_CRMF_CERTID *)OPENSSL_sk_pop(ossl_check_OSSL_CRMF_CERTID_sk_type(sk)))
|
||||
#define sk_OSSL_CRMF_CERTID_shift(sk) ((OSSL_CRMF_CERTID *)OPENSSL_sk_shift(ossl_check_OSSL_CRMF_CERTID_sk_type(sk)))
|
||||
#define sk_OSSL_CRMF_CERTID_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_OSSL_CRMF_CERTID_sk_type(sk),ossl_check_OSSL_CRMF_CERTID_freefunc_type(freefunc))
|
||||
#define sk_OSSL_CRMF_CERTID_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr), (idx))
|
||||
#define sk_OSSL_CRMF_CERTID_set(sk, idx, ptr) ((OSSL_CRMF_CERTID *)OPENSSL_sk_set(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), (idx), ossl_check_OSSL_CRMF_CERTID_type(ptr)))
|
||||
#define sk_OSSL_CRMF_CERTID_find(sk, ptr) OPENSSL_sk_find(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr))
|
||||
#define sk_OSSL_CRMF_CERTID_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr))
|
||||
#define sk_OSSL_CRMF_CERTID_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_type(ptr), pnum)
|
||||
#define sk_OSSL_CRMF_CERTID_sort(sk) OPENSSL_sk_sort(ossl_check_OSSL_CRMF_CERTID_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_CERTID_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk))
|
||||
#define sk_OSSL_CRMF_CERTID_dup(sk) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_dup(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk)))
|
||||
#define sk_OSSL_CRMF_CERTID_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(OSSL_CRMF_CERTID) *)OPENSSL_sk_deep_copy(ossl_check_const_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_copyfunc_type(copyfunc), ossl_check_OSSL_CRMF_CERTID_freefunc_type(freefunc)))
|
||||
#define sk_OSSL_CRMF_CERTID_set_cmp_func(sk, cmp) ((sk_OSSL_CRMF_CERTID_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_OSSL_CRMF_CERTID_sk_type(sk), ossl_check_OSSL_CRMF_CERTID_compfunc_type(cmp)))
|
||||
|
||||
|
||||
typedef struct ossl_crmf_pkipublicationinfo_st OSSL_CRMF_PKIPUBLICATIONINFO;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_PKIPUBLICATIONINFO)
|
||||
typedef struct ossl_crmf_singlepubinfo_st OSSL_CRMF_SINGLEPUBINFO;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_SINGLEPUBINFO)
|
||||
typedef struct ossl_crmf_certtemplate_st OSSL_CRMF_CERTTEMPLATE;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTTEMPLATE)
|
||||
typedef STACK_OF(OSSL_CRMF_MSG) OSSL_CRMF_MSGS;
|
||||
DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_MSGS)
|
||||
|
||||
typedef struct ossl_crmf_optionalvalidity_st OSSL_CRMF_OPTIONALVALIDITY;
|
||||
|
||||
/* crmf_pbm.c */
|
||||
OSSL_CRMF_PBMPARAMETER *OSSL_CRMF_pbmp_new(OSSL_LIB_CTX *libctx, size_t slen,
|
||||
int owfnid, size_t itercnt,
|
||||
int macnid);
|
||||
int OSSL_CRMF_pbm_new(OSSL_LIB_CTX *libctx, const char *propq,
|
||||
const OSSL_CRMF_PBMPARAMETER *pbmp,
|
||||
const unsigned char *msg, size_t msglen,
|
||||
const unsigned char *sec, size_t seclen,
|
||||
unsigned char **mac, size_t *maclen);
|
||||
|
||||
/* crmf_lib.c */
|
||||
int OSSL_CRMF_MSG_set1_regCtrl_regToken(OSSL_CRMF_MSG *msg,
|
||||
const ASN1_UTF8STRING *tok);
|
||||
ASN1_UTF8STRING
|
||||
*OSSL_CRMF_MSG_get0_regCtrl_regToken(const OSSL_CRMF_MSG *msg);
|
||||
int OSSL_CRMF_MSG_set1_regCtrl_authenticator(OSSL_CRMF_MSG *msg,
|
||||
const ASN1_UTF8STRING *auth);
|
||||
ASN1_UTF8STRING
|
||||
*OSSL_CRMF_MSG_get0_regCtrl_authenticator(const OSSL_CRMF_MSG *msg);
|
||||
int
|
||||
OSSL_CRMF_MSG_PKIPublicationInfo_push0_SinglePubInfo(OSSL_CRMF_PKIPUBLICATIONINFO *pi,
|
||||
OSSL_CRMF_SINGLEPUBINFO *spi);
|
||||
# define OSSL_CRMF_PUB_METHOD_DONTCARE 0
|
||||
# define OSSL_CRMF_PUB_METHOD_X500 1
|
||||
# define OSSL_CRMF_PUB_METHOD_WEB 2
|
||||
# define OSSL_CRMF_PUB_METHOD_LDAP 3
|
||||
int OSSL_CRMF_MSG_set0_SinglePubInfo(OSSL_CRMF_SINGLEPUBINFO *spi,
|
||||
int method, GENERAL_NAME *nm);
|
||||
# define OSSL_CRMF_PUB_ACTION_DONTPUBLISH 0
|
||||
# define OSSL_CRMF_PUB_ACTION_PLEASEPUBLISH 1
|
||||
int OSSL_CRMF_MSG_set_PKIPublicationInfo_action(OSSL_CRMF_PKIPUBLICATIONINFO *pi,
|
||||
int action);
|
||||
int OSSL_CRMF_MSG_set1_regCtrl_pkiPublicationInfo(OSSL_CRMF_MSG *msg,
|
||||
const OSSL_CRMF_PKIPUBLICATIONINFO *pi);
|
||||
OSSL_CRMF_PKIPUBLICATIONINFO
|
||||
*OSSL_CRMF_MSG_get0_regCtrl_pkiPublicationInfo(const OSSL_CRMF_MSG *msg);
|
||||
int OSSL_CRMF_MSG_set1_regCtrl_protocolEncrKey(OSSL_CRMF_MSG *msg,
|
||||
const X509_PUBKEY *pubkey);
|
||||
X509_PUBKEY
|
||||
*OSSL_CRMF_MSG_get0_regCtrl_protocolEncrKey(const OSSL_CRMF_MSG *msg);
|
||||
int OSSL_CRMF_MSG_set1_regCtrl_oldCertID(OSSL_CRMF_MSG *msg,
|
||||
const OSSL_CRMF_CERTID *cid);
|
||||
OSSL_CRMF_CERTID
|
||||
*OSSL_CRMF_MSG_get0_regCtrl_oldCertID(const OSSL_CRMF_MSG *msg);
|
||||
OSSL_CRMF_CERTID *OSSL_CRMF_CERTID_gen(const X509_NAME *issuer,
|
||||
const ASN1_INTEGER *serial);
|
||||
|
||||
int OSSL_CRMF_MSG_set1_regInfo_utf8Pairs(OSSL_CRMF_MSG *msg,
|
||||
const ASN1_UTF8STRING *utf8pairs);
|
||||
ASN1_UTF8STRING
|
||||
*OSSL_CRMF_MSG_get0_regInfo_utf8Pairs(const OSSL_CRMF_MSG *msg);
|
||||
int OSSL_CRMF_MSG_set1_regInfo_certReq(OSSL_CRMF_MSG *msg,
|
||||
const OSSL_CRMF_CERTREQUEST *cr);
|
||||
OSSL_CRMF_CERTREQUEST
|
||||
*OSSL_CRMF_MSG_get0_regInfo_certReq(const OSSL_CRMF_MSG *msg);
|
||||
|
||||
int OSSL_CRMF_MSG_set0_validity(OSSL_CRMF_MSG *crm,
|
||||
ASN1_TIME *notBefore, ASN1_TIME *notAfter);
|
||||
int OSSL_CRMF_MSG_set_certReqId(OSSL_CRMF_MSG *crm, int rid);
|
||||
int OSSL_CRMF_MSG_get_certReqId(const OSSL_CRMF_MSG *crm);
|
||||
int OSSL_CRMF_MSG_set0_extensions(OSSL_CRMF_MSG *crm, X509_EXTENSIONS *exts);
|
||||
|
||||
int OSSL_CRMF_MSG_push0_extension(OSSL_CRMF_MSG *crm, X509_EXTENSION *ext);
|
||||
# define OSSL_CRMF_POPO_NONE -1
|
||||
# define OSSL_CRMF_POPO_RAVERIFIED 0
|
||||
# define OSSL_CRMF_POPO_SIGNATURE 1
|
||||
# define OSSL_CRMF_POPO_KEYENC 2
|
||||
# define OSSL_CRMF_POPO_KEYAGREE 3
|
||||
int OSSL_CRMF_MSG_create_popo(int meth, OSSL_CRMF_MSG *crm,
|
||||
EVP_PKEY *pkey, const EVP_MD *digest,
|
||||
OSSL_LIB_CTX *libctx, const char *propq);
|
||||
int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs,
|
||||
int rid, int acceptRAVerified,
|
||||
OSSL_LIB_CTX *libctx, const char *propq);
|
||||
OSSL_CRMF_CERTTEMPLATE *OSSL_CRMF_MSG_get0_tmpl(const OSSL_CRMF_MSG *crm);
|
||||
const ASN1_INTEGER
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_serialNumber(const OSSL_CRMF_CERTTEMPLATE *tmpl);
|
||||
const X509_NAME
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_subject(const OSSL_CRMF_CERTTEMPLATE *tmpl);
|
||||
const X509_NAME
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_issuer(const OSSL_CRMF_CERTTEMPLATE *tmpl);
|
||||
X509_EXTENSIONS
|
||||
*OSSL_CRMF_CERTTEMPLATE_get0_extensions(const OSSL_CRMF_CERTTEMPLATE *tmpl);
|
||||
const X509_NAME
|
||||
*OSSL_CRMF_CERTID_get0_issuer(const OSSL_CRMF_CERTID *cid);
|
||||
const ASN1_INTEGER
|
||||
*OSSL_CRMF_CERTID_get0_serialNumber(const OSSL_CRMF_CERTID *cid);
|
||||
int OSSL_CRMF_CERTTEMPLATE_fill(OSSL_CRMF_CERTTEMPLATE *tmpl,
|
||||
EVP_PKEY *pubkey,
|
||||
const X509_NAME *subject,
|
||||
const X509_NAME *issuer,
|
||||
const ASN1_INTEGER *serial);
|
||||
X509
|
||||
*OSSL_CRMF_ENCRYPTEDVALUE_get1_encCert(const OSSL_CRMF_ENCRYPTEDVALUE *ecert,
|
||||
OSSL_LIB_CTX *libctx, const char *propq,
|
||||
EVP_PKEY *pkey);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
# endif /* !defined(OPENSSL_NO_CRMF) */
|
||||
#endif /* !defined(OPENSSL_CRMF_H) */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -279,7 +279,8 @@ typedef unsigned __int64 uint64_t;
|
||||
# define ossl_inline inline
|
||||
# endif
|
||||
|
||||
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
|
||||
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && \
|
||||
!defined(__cplusplus)
|
||||
# define ossl_noreturn _Noreturn
|
||||
# elif defined(__GNUC__) && __GNUC__ >= 2
|
||||
# define ossl_noreturn __attribute__((noreturn))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -793,12 +793,15 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1,
|
||||
EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
|
||||
int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
|
||||
|
||||
# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
|
||||
# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
|
||||
# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
|
||||
(char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
|
||||
# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
|
||||
(unsigned char *)(x))
|
||||
# define d2i_ECPKParameters_bio(bp,x) \
|
||||
ASN1_d2i_bio_of(EC_GROUP, NULL, d2i_ECPKParameters, bp, x)
|
||||
# define i2d_ECPKParameters_bio(bp,x) \
|
||||
ASN1_i2d_bio_of_const(EC_GROUP, i2d_ECPKParameters, bp, x)
|
||||
# define d2i_ECPKParameters_fp(fp,x) \
|
||||
(EC_GROUP *)ASN1_d2i_fp(NULL, (d2i_of_void *)d2i_ECPKParameters, (fp), \
|
||||
(void **)(x))
|
||||
# define i2d_ECPKParameters_fp(fp,x) \
|
||||
ASN1_i2d_fp((i2d_of_void *)i2d_ECPKParameters, (fp), (void *)(x))
|
||||
|
||||
int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
|
||||
# ifndef OPENSSL_NO_STDIO
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -722,6 +722,7 @@ typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id,
|
||||
CRYPTO_set_mem_functions(fns->mem_fns.malloc_fn, \
|
||||
fns->mem_fns.realloc_fn, \
|
||||
fns->mem_fns.free_fn); \
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_NO_ATEXIT, NULL); \
|
||||
skip_cbs: \
|
||||
if (!fn(e, id)) return 0; \
|
||||
return 1; }
|
||||
|
||||
128
app/src/main/jni/moonlight-core/openssl/include/openssl/ess.h
Normal file
128
app/src/main/jni/moonlight-core/openssl/include/openssl/ess.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* WARNING: do not edit!
|
||||
* Generated by Makefile from include/openssl/ess.h.in
|
||||
*
|
||||
* Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef OPENSSL_ESS_H
|
||||
# define OPENSSL_ESS_H
|
||||
# pragma once
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# include <openssl/safestack.h>
|
||||
# include <openssl/x509.h>
|
||||
# include <openssl/esserr.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
|
||||
typedef struct ESS_issuer_serial ESS_ISSUER_SERIAL;
|
||||
typedef struct ESS_cert_id ESS_CERT_ID;
|
||||
typedef struct ESS_signing_cert ESS_SIGNING_CERT;
|
||||
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(ESS_CERT_ID, ESS_CERT_ID, ESS_CERT_ID)
|
||||
#define sk_ESS_CERT_ID_num(sk) OPENSSL_sk_num(ossl_check_const_ESS_CERT_ID_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_value(sk, idx) ((ESS_CERT_ID *)OPENSSL_sk_value(ossl_check_const_ESS_CERT_ID_sk_type(sk), (idx)))
|
||||
#define sk_ESS_CERT_ID_new(cmp) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_new(ossl_check_ESS_CERT_ID_compfunc_type(cmp)))
|
||||
#define sk_ESS_CERT_ID_new_null() ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_new_null())
|
||||
#define sk_ESS_CERT_ID_new_reserve(cmp, n) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_new_reserve(ossl_check_ESS_CERT_ID_compfunc_type(cmp), (n)))
|
||||
#define sk_ESS_CERT_ID_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ESS_CERT_ID_sk_type(sk), (n))
|
||||
#define sk_ESS_CERT_ID_free(sk) OPENSSL_sk_free(ossl_check_ESS_CERT_ID_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_zero(sk) OPENSSL_sk_zero(ossl_check_ESS_CERT_ID_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_delete(sk, i) ((ESS_CERT_ID *)OPENSSL_sk_delete(ossl_check_ESS_CERT_ID_sk_type(sk), (i)))
|
||||
#define sk_ESS_CERT_ID_delete_ptr(sk, ptr) ((ESS_CERT_ID *)OPENSSL_sk_delete_ptr(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr)))
|
||||
#define sk_ESS_CERT_ID_push(sk, ptr) OPENSSL_sk_push(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr))
|
||||
#define sk_ESS_CERT_ID_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr))
|
||||
#define sk_ESS_CERT_ID_pop(sk) ((ESS_CERT_ID *)OPENSSL_sk_pop(ossl_check_ESS_CERT_ID_sk_type(sk)))
|
||||
#define sk_ESS_CERT_ID_shift(sk) ((ESS_CERT_ID *)OPENSSL_sk_shift(ossl_check_ESS_CERT_ID_sk_type(sk)))
|
||||
#define sk_ESS_CERT_ID_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ESS_CERT_ID_sk_type(sk),ossl_check_ESS_CERT_ID_freefunc_type(freefunc))
|
||||
#define sk_ESS_CERT_ID_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr), (idx))
|
||||
#define sk_ESS_CERT_ID_set(sk, idx, ptr) ((ESS_CERT_ID *)OPENSSL_sk_set(ossl_check_ESS_CERT_ID_sk_type(sk), (idx), ossl_check_ESS_CERT_ID_type(ptr)))
|
||||
#define sk_ESS_CERT_ID_find(sk, ptr) OPENSSL_sk_find(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr))
|
||||
#define sk_ESS_CERT_ID_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr))
|
||||
#define sk_ESS_CERT_ID_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_type(ptr), pnum)
|
||||
#define sk_ESS_CERT_ID_sort(sk) OPENSSL_sk_sort(ossl_check_ESS_CERT_ID_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ESS_CERT_ID_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_dup(sk) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_dup(ossl_check_const_ESS_CERT_ID_sk_type(sk)))
|
||||
#define sk_ESS_CERT_ID_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ESS_CERT_ID) *)OPENSSL_sk_deep_copy(ossl_check_const_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_copyfunc_type(copyfunc), ossl_check_ESS_CERT_ID_freefunc_type(freefunc)))
|
||||
#define sk_ESS_CERT_ID_set_cmp_func(sk, cmp) ((sk_ESS_CERT_ID_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ESS_CERT_ID_sk_type(sk), ossl_check_ESS_CERT_ID_compfunc_type(cmp)))
|
||||
|
||||
|
||||
|
||||
typedef struct ESS_signing_cert_v2_st ESS_SIGNING_CERT_V2;
|
||||
typedef struct ESS_cert_id_v2_st ESS_CERT_ID_V2;
|
||||
|
||||
SKM_DEFINE_STACK_OF_INTERNAL(ESS_CERT_ID_V2, ESS_CERT_ID_V2, ESS_CERT_ID_V2)
|
||||
#define sk_ESS_CERT_ID_V2_num(sk) OPENSSL_sk_num(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_V2_value(sk, idx) ((ESS_CERT_ID_V2 *)OPENSSL_sk_value(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk), (idx)))
|
||||
#define sk_ESS_CERT_ID_V2_new(cmp) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_new(ossl_check_ESS_CERT_ID_V2_compfunc_type(cmp)))
|
||||
#define sk_ESS_CERT_ID_V2_new_null() ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_new_null())
|
||||
#define sk_ESS_CERT_ID_V2_new_reserve(cmp, n) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_new_reserve(ossl_check_ESS_CERT_ID_V2_compfunc_type(cmp), (n)))
|
||||
#define sk_ESS_CERT_ID_V2_reserve(sk, n) OPENSSL_sk_reserve(ossl_check_ESS_CERT_ID_V2_sk_type(sk), (n))
|
||||
#define sk_ESS_CERT_ID_V2_free(sk) OPENSSL_sk_free(ossl_check_ESS_CERT_ID_V2_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_V2_zero(sk) OPENSSL_sk_zero(ossl_check_ESS_CERT_ID_V2_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_V2_delete(sk, i) ((ESS_CERT_ID_V2 *)OPENSSL_sk_delete(ossl_check_ESS_CERT_ID_V2_sk_type(sk), (i)))
|
||||
#define sk_ESS_CERT_ID_V2_delete_ptr(sk, ptr) ((ESS_CERT_ID_V2 *)OPENSSL_sk_delete_ptr(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr)))
|
||||
#define sk_ESS_CERT_ID_V2_push(sk, ptr) OPENSSL_sk_push(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr))
|
||||
#define sk_ESS_CERT_ID_V2_unshift(sk, ptr) OPENSSL_sk_unshift(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr))
|
||||
#define sk_ESS_CERT_ID_V2_pop(sk) ((ESS_CERT_ID_V2 *)OPENSSL_sk_pop(ossl_check_ESS_CERT_ID_V2_sk_type(sk)))
|
||||
#define sk_ESS_CERT_ID_V2_shift(sk) ((ESS_CERT_ID_V2 *)OPENSSL_sk_shift(ossl_check_ESS_CERT_ID_V2_sk_type(sk)))
|
||||
#define sk_ESS_CERT_ID_V2_pop_free(sk, freefunc) OPENSSL_sk_pop_free(ossl_check_ESS_CERT_ID_V2_sk_type(sk),ossl_check_ESS_CERT_ID_V2_freefunc_type(freefunc))
|
||||
#define sk_ESS_CERT_ID_V2_insert(sk, ptr, idx) OPENSSL_sk_insert(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr), (idx))
|
||||
#define sk_ESS_CERT_ID_V2_set(sk, idx, ptr) ((ESS_CERT_ID_V2 *)OPENSSL_sk_set(ossl_check_ESS_CERT_ID_V2_sk_type(sk), (idx), ossl_check_ESS_CERT_ID_V2_type(ptr)))
|
||||
#define sk_ESS_CERT_ID_V2_find(sk, ptr) OPENSSL_sk_find(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr))
|
||||
#define sk_ESS_CERT_ID_V2_find_ex(sk, ptr) OPENSSL_sk_find_ex(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr))
|
||||
#define sk_ESS_CERT_ID_V2_find_all(sk, ptr, pnum) OPENSSL_sk_find_all(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_type(ptr), pnum)
|
||||
#define sk_ESS_CERT_ID_V2_sort(sk) OPENSSL_sk_sort(ossl_check_ESS_CERT_ID_V2_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_V2_is_sorted(sk) OPENSSL_sk_is_sorted(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk))
|
||||
#define sk_ESS_CERT_ID_V2_dup(sk) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_dup(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk)))
|
||||
#define sk_ESS_CERT_ID_V2_deep_copy(sk, copyfunc, freefunc) ((STACK_OF(ESS_CERT_ID_V2) *)OPENSSL_sk_deep_copy(ossl_check_const_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_copyfunc_type(copyfunc), ossl_check_ESS_CERT_ID_V2_freefunc_type(freefunc)))
|
||||
#define sk_ESS_CERT_ID_V2_set_cmp_func(sk, cmp) ((sk_ESS_CERT_ID_V2_compfunc)OPENSSL_sk_set_cmp_func(ossl_check_ESS_CERT_ID_V2_sk_type(sk), ossl_check_ESS_CERT_ID_V2_compfunc_type(cmp)))
|
||||
|
||||
|
||||
DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_ISSUER_SERIAL)
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_ISSUER_SERIAL, ESS_ISSUER_SERIAL)
|
||||
DECLARE_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL)
|
||||
|
||||
DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_CERT_ID)
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_CERT_ID, ESS_CERT_ID)
|
||||
DECLARE_ASN1_DUP_FUNCTION(ESS_CERT_ID)
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(ESS_SIGNING_CERT)
|
||||
DECLARE_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT)
|
||||
|
||||
DECLARE_ASN1_ALLOC_FUNCTIONS(ESS_CERT_ID_V2)
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS_only(ESS_CERT_ID_V2, ESS_CERT_ID_V2)
|
||||
DECLARE_ASN1_DUP_FUNCTION(ESS_CERT_ID_V2)
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(ESS_SIGNING_CERT_V2)
|
||||
DECLARE_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2)
|
||||
|
||||
ESS_SIGNING_CERT *OSSL_ESS_signing_cert_new_init(const X509 *signcert,
|
||||
const STACK_OF(X509) *certs,
|
||||
int set_issuer_serial);
|
||||
ESS_SIGNING_CERT_V2 *OSSL_ESS_signing_cert_v2_new_init(const EVP_MD *hash_alg,
|
||||
const X509 *signcert,
|
||||
const
|
||||
STACK_OF(X509) *certs,
|
||||
int set_issuer_serial);
|
||||
int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss,
|
||||
const ESS_SIGNING_CERT_V2 *ssv2,
|
||||
const STACK_OF(X509) *chain,
|
||||
int require_signing_cert);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* WARNING: do not edit!
|
||||
* Generated by Makefile from include/openssl/fipskey.h.in
|
||||
*
|
||||
* Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_FIPSKEY_H
|
||||
# define OPENSSL_FIPSKEY_H
|
||||
# pragma once
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
/*
|
||||
* The FIPS validation HMAC key, usable as an array initializer.
|
||||
*/
|
||||
#define FIPS_KEY_ELEMENTS \
|
||||
0xf4, 0x55, 0x66, 0x50, 0xac, 0x31, 0xd3, 0x54, 0x61, 0x61, 0x0b, 0xac, 0x4e, 0xd8, 0x1b, 0x1a, 0x18, 0x1b, 0x2d, 0x8a, 0x43, 0xea, 0x28, 0x54, 0xcb, 0xae, 0x22, 0xca, 0x74, 0x56, 0x08, 0x13
|
||||
|
||||
/*
|
||||
* The FIPS validation key, as a string.
|
||||
*/
|
||||
#define FIPS_KEY_STRING "f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813"
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@@ -2,7 +2,7 @@
|
||||
* WARNING: do not edit!
|
||||
* Generated by crypto/objects/objects.pl
|
||||
*
|
||||
* Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -39,8 +39,8 @@ extern "C" {
|
||||
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
|
||||
* major minor fix final patch/beta)
|
||||
*/
|
||||
# define OPENSSL_VERSION_NUMBER 0x101010bfL
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1k 25 Mar 2021"
|
||||
# define OPENSSL_VERSION_NUMBER 0x1010111fL
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1q 5 Jul 2022"
|
||||
|
||||
/*-
|
||||
* The macros below are to be used for shared library (.so, .dll, ...)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
@@ -1305,6 +1305,8 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
# define SSL_CTRL_GET_MAX_PROTO_VERSION 131
|
||||
# define SSL_CTRL_GET_SIGNATURE_NID 132
|
||||
# define SSL_CTRL_GET_TMP_KEY 133
|
||||
# define SSL_CTRL_GET_VERIFY_CERT_STORE 137
|
||||
# define SSL_CTRL_GET_CHAIN_CERT_STORE 138
|
||||
# define SSL_CERT_SET_FIRST 1
|
||||
# define SSL_CERT_SET_NEXT 2
|
||||
# define SSL_CERT_SET_SERVER 3
|
||||
@@ -1360,10 +1362,14 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_CTX_set1_verify_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st))
|
||||
# define SSL_CTX_get0_verify_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_GET_VERIFY_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_CTX_set0_chain_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_CTX_set1_chain_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
|
||||
# define SSL_CTX_get0_chain_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_set0_chain(s,sk) \
|
||||
SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk))
|
||||
# define SSL_set1_chain(s,sk) \
|
||||
@@ -1386,10 +1392,14 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_set1_verify_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)(st))
|
||||
#define SSL_get0_verify_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_GET_VERIFY_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_set0_chain_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_set1_chain_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
|
||||
#define SSL_get0_chain_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_get1_groups(s, glist) \
|
||||
SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist))
|
||||
# define SSL_CTX_set1_groups(ctx, glist, glistlen) \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -70,6 +70,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_F_FINAL_EMS 486
|
||||
# define SSL_F_FINAL_KEY_SHARE 503
|
||||
# define SSL_F_FINAL_MAXFRAGMENTLEN 557
|
||||
# define SSL_F_FINAL_PSK 639
|
||||
# define SSL_F_FINAL_RENEGOTIATE 483
|
||||
# define SSL_F_FINAL_SERVER_NAME 558
|
||||
# define SSL_F_FINAL_SIG_ALGS 497
|
||||
@@ -592,6 +593,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381
|
||||
# define SSL_R_MISSING_FATAL 256
|
||||
# define SSL_R_MISSING_PARAMETERS 290
|
||||
# define SSL_R_MISSING_PSK_KEX_MODES_EXTENSION 310
|
||||
# define SSL_R_MISSING_RSA_CERTIFICATE 168
|
||||
# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169
|
||||
# define SSL_R_MISSING_RSA_SIGNING_CERT 170
|
||||
@@ -633,6 +635,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_R_NO_VERIFY_COOKIE_CALLBACK 403
|
||||
# define SSL_R_NULL_SSL_CTX 195
|
||||
# define SSL_R_NULL_SSL_METHOD_PASSED 196
|
||||
# define SSL_R_OCSP_CALLBACK_FAILURE 294
|
||||
# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197
|
||||
# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
|
||||
# define SSL_R_OVERFLOW_ERROR 237
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -38,6 +38,7 @@ int ERR_load_X509V3_strings(void);
|
||||
# define X509V3_F_I2S_ASN1_IA5STRING 149
|
||||
# define X509V3_F_I2S_ASN1_INTEGER 120
|
||||
# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138
|
||||
# define X509V3_F_I2V_AUTHORITY_KEYID 173
|
||||
# define X509V3_F_LEVEL_ADD_NODE 168
|
||||
# define X509V3_F_NOTICE_SECTION 132
|
||||
# define X509V3_F_NREF_NOS 133
|
||||
@@ -78,6 +79,7 @@ int ERR_load_X509V3_strings(void);
|
||||
# define X509V3_F_V2I_TLS_FEATURE 165
|
||||
# define X509V3_F_V3_GENERIC_EXTENSION 116
|
||||
# define X509V3_F_X509V3_ADD1_I2D 140
|
||||
# define X509V3_F_X509V3_ADD_LEN_VALUE 174
|
||||
# define X509V3_F_X509V3_ADD_VALUE 105
|
||||
# define X509V3_F_X509V3_EXT_ADD 104
|
||||
# define X509V3_F_X509V3_EXT_ADD_ALIAS 106
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,6 +4,7 @@
|
||||
#include <android/log.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_sendMouseMove(JNIEnv *env, jclass clazz, jshort deltaX, jshort deltaY) {
|
||||
@@ -16,6 +17,12 @@ Java_com_limelight_nvstream_jni_MoonBridge_sendMousePosition(JNIEnv *env, jclass
|
||||
LiSendMousePositionEvent(x, y, referenceWidth, referenceHeight);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_sendMouseMoveAsMousePosition(JNIEnv *env, jclass clazz,
|
||||
jshort deltaX, jshort deltaY, jshort referenceWidth, jshort referenceHeight) {
|
||||
LiSendMouseMoveAsMousePositionEvent(deltaX, deltaY, referenceWidth, referenceHeight);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_sendMouseButton(JNIEnv *env, jclass clazz, jbyte buttonEvent, jbyte mouseButton) {
|
||||
LiSendMouseButtonEvent(buttonEvent, mouseButton);
|
||||
@@ -54,6 +61,13 @@ Java_com_limelight_nvstream_jni_MoonBridge_sendMouseHighResScroll(JNIEnv *env, j
|
||||
LiSendHighResScrollEvent(scrollAmount);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_sendUtf8Text(JNIEnv *env, jclass clazz, jstring text) {
|
||||
const char* utf8Text = (*env)->GetStringUTFChars(env, text, NULL);
|
||||
LiSendUtf8TextEvent(utf8Text, strlen(utf8Text));
|
||||
(*env)->ReleaseStringUTFChars(env, text, utf8Text);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_stopConnection(JNIEnv *env, jclass clazz) {
|
||||
LiStopConnection();
|
||||
@@ -134,4 +148,15 @@ Java_com_limelight_nvstream_jni_MoonBridge_stringifyPortFlags(JNIEnv *env, jclas
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, separator, separatorStr);
|
||||
return (*env)->NewStringUTF(env, outputBuffer);
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_getEstimatedRttInfo(JNIEnv *env, jclass clazz) {
|
||||
uint32_t rtt, variance;
|
||||
|
||||
if (!LiGetEstimatedRttInfo(&rtt, &variance)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ((uint64_t)rtt << 32U) | variance;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="256dp"
|
||||
android:height="256dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="256dp"
|
||||
android:height="256dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v-2h4L11,7h2v4h4v2z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="512dp"
|
||||
android:height="512dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="512dp"
|
||||
android:height="512dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M21,2L3,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h7v2L8,20v2h8v-2h-2v-2h7c1.1,0 2,-0.9 2,-2L23,4c0,-1.1 -0.9,-2 -2,-2zM21,16L3,16L3,4h18v12z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M21,2L3,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h7v2L8,20v2h8v-2h-2v-2h7c1.1,0 2,-0.9 2,-2L23,4c0,-1.1 -0.9,-2 -2,-2zM21,16L3,16L3,4h18v12z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="256dp"
|
||||
android:height="256dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="256dp"
|
||||
android:height="256dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<vector android:height="128dp" android:width="128dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="128dp"
|
||||
android:height="128dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,16.5v-9l6,4.5 -6,4.5z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM9.5,16.5v-9l7,4.5L9.5,16.5z" />
|
||||
</vector>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="256dp"
|
||||
android:height="256dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
android:width="256dp"
|
||||
android:height="256dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"
|
||||
android:fillColor="#FFFFFF"/>
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z" />
|
||||
</vector>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
android:text="@string/title_add_pc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:preferKeepClear="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:layout_alignParentTop="true"/>
|
||||
@@ -29,6 +30,7 @@
|
||||
android:layout_alignParentStart="true"
|
||||
android:ems="10"
|
||||
android:singleLine="true"
|
||||
android:preferKeepClear="true"
|
||||
android:inputType="textNoSuggestions"
|
||||
android:hint="@string/ip_hint" >
|
||||
|
||||
@@ -43,6 +45,7 @@
|
||||
android:layout_below="@+id/manuallyAddPcText"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:preferKeepClear="true"
|
||||
android:text="@android:string/ok"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
android:gravity="center"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:preferKeepClear="true"
|
||||
android:textSize="28sp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -21,6 +21,7 @@
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:gravity="left"
|
||||
android:background="#80000000"
|
||||
android:preferKeepClear="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
@@ -34,6 +35,7 @@
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:gravity="right"
|
||||
android:background="#80000000"
|
||||
android:preferKeepClear="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</merge>
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:src="@drawable/ic_settings"
|
||||
android:preferKeepClear="true"
|
||||
style="?android:attr/borderlessButtonStyle"/>
|
||||
|
||||
<ImageButton
|
||||
@@ -69,6 +70,7 @@
|
||||
android:layout_toRightOf="@+id/settingsButton"
|
||||
android:layout_toEndOf="@+id/settingsButton"
|
||||
android:src="@drawable/ic_help"
|
||||
android:preferKeepClear="true"
|
||||
style="?android:attr/borderlessButtonStyle"/>
|
||||
|
||||
<ImageButton
|
||||
@@ -81,6 +83,7 @@
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:src="@drawable/ic_add"
|
||||
android:preferKeepClear="true"
|
||||
style="?android:attr/borderlessButtonStyle"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||
</adaptive-icon>
|
||||
@@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_pc_scut_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_pc_scut_foreground"/>
|
||||
<monochrome android:drawable="@mipmap/ic_pc_scut_foreground"/>
|
||||
</adaptive-icon>
|
||||
2
app/src/main/res/values-cs/strings.xml
Normal file
2
app/src/main/res/values-cs/strings.xml
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="decoder_names">
|
||||
<item>Decoder automatisch auswählen</item>
|
||||
<item>Software Decodierung erzwingen</item>
|
||||
<item>Hardware Decodierung erzwingen</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="video_format_names">
|
||||
<item>Verwende H.265 so fern stabile Unterstützung vorhanden ist</item>
|
||||
<item>Immer H.265 verwenden (könnte Crashes verursachen)</item>
|
||||
<item>Nie H.265 verwenden</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -1,7 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_label" translatable="false">Moonlight</string>
|
||||
<string name="app_label_root" translatable="false">Moonlight (Root)</string>
|
||||
<!-- Shortcut strings -->
|
||||
<string name="scut_deleted_pc">Host gelöscht</string>
|
||||
<string name="scut_not_paired">Host nicht gekoppelt</string>
|
||||
@@ -94,14 +92,11 @@
|
||||
<string name="slow_connection_msg">Langsame Verbindung zum Host
|
||||
\nReduziere die Bitrate</string>
|
||||
<string name="poor_connection_msg">Sehr langsame Verbindung zum Host</string>
|
||||
<string name="perf_overlay_text">Videodimensionen: %1$s
|
||||
\nDecoder: %2$s
|
||||
\nGeschätzte Host Bildwiederholrate: %3$.2f FPS
|
||||
\nBildwiederholrate der Netzwerkübertragung: %4$.2f FPS
|
||||
\nWiedergabe-Bildwiederholungsrate: %5$.2f FPS
|
||||
\nWegen Netzwerkübertragung ausgelassene Frames: %6$.2f%%
|
||||
\nDurchschnittliche Übertragungsdauer: %7$.2f ms
|
||||
\nDurchschnittliche Dekodierungszeit: %8$.2f ms</string>
|
||||
<string name="perf_overlay_decoder">Decoder: %1$s</string>
|
||||
<string name="perf_overlay_incomingfps">Bildwiederholrate der Netzwerkübertragung: %1$.2f FPS</string>
|
||||
<string name="perf_overlay_renderingfps">Wiedergabe-Bildwiederholungsrate: %1$.2f FPS</string>
|
||||
<string name="perf_overlay_netdrops">Wegen Netzwerkübertragung ausgelassene Frames: %1$.2f%%</string>
|
||||
<string name="perf_overlay_dectime">Durchschnittliche Dekodierungszeit: %1$.2f ms</string>
|
||||
<!-- AppList activity -->
|
||||
<string name="applist_connect_msg">Verbinde mit Host…</string>
|
||||
<string name="applist_menu_resume">Sitzung wiederherstellen</string>
|
||||
@@ -137,7 +132,7 @@
|
||||
<string name="summary_fps_list">Erhöhen für einen gleichmäßigeren Video-Stream. Verringern um auf langsameren Geräten eine bessere Performance zu erzielen.</string>
|
||||
<string name="title_seekbar_bitrate">Video Bitrate</string>
|
||||
<string name="summary_seekbar_bitrate">Erhöhen für einen schärferen Video-Stream. Verringern um auf langsameren Geräten eine bessere Performance zu erzielen.</string>
|
||||
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
|
||||
<string name="suffix_seekbar_bitrate_mbps">Mbit/s</string>
|
||||
<string name="title_checkbox_stretch_video">Video auf Vollbildschirm strecken</string>
|
||||
<string name="category_audio_settings">Audio Einstellungen</string>
|
||||
<string name="title_audio_config_list">Surround Sound Konfiguration </string>
|
||||
@@ -196,8 +191,8 @@
|
||||
<string name="title_checkbox_disable_warnings">Warnhinweise deaktivieren</string>
|
||||
<string name="summary_checkbox_disable_warnings">On-Screen Warnmeldungen während des Streaming deaktivieren</string>
|
||||
<string name="summary_disable_frame_drop">Kann das Mikro-Ruckeln auf einigen Geräten reduzieren, allerdings erhöht dies gleichzeitig die Latenz</string>
|
||||
<string name="title_video_format">H265 Einstellungen ändern</string>
|
||||
<string name="summary_video_format">H265 verringert die Video-Bandbreitenanforderung, funktioniert allerdings nur auf sehr neuen Geräten</string>
|
||||
<string name="title_video_format">HEVC Einstellungen ändern</string>
|
||||
<string name="summary_video_format">HEVC verringert die Video-Bandbreitenanforderung, funktioniert allerdings nur auf sehr neuen Geräten</string>
|
||||
<string name="title_enable_hdr">HDR aktivieren (experimentell)</string>
|
||||
<string name="summary_enable_hdr">HDR-Streaming sofern dies von der Host-GPU unterstützt wird. HDR erfordert eine GPU der GTX 1000 Serie oder neuer.</string>
|
||||
<string name="title_enable_perf_overlay">Performance Overlay aktivieren</string>
|
||||
@@ -222,4 +217,46 @@
|
||||
<string name="pcview_menu_header_unknown">Aktualisiere</string>
|
||||
<string name="pcview_menu_header_offline">Offline</string>
|
||||
<string name="pcview_menu_header_online">Online</string>
|
||||
<!-- Array strings -->
|
||||
<string name="videoformat_hevcauto">Automatisch</string>
|
||||
<string name="videoformat_hevcalways">Immer HEVC verwenden (könnte Crashes verursachen)</string>
|
||||
<string name="videoformat_hevcnever">Nie HEVC verwenden</string>
|
||||
<string name="title_frame_pacing">Video Frame-Pacing</string>
|
||||
<string name="summary_frame_pacing">Lege fest, wie die Videolatenz und die flüssige Wiedergabe ausgeglichen werden sollen</string>
|
||||
<string name="resolution_prefix_native_fullscreen">Natives Vollbild</string>
|
||||
<string name="pacing_latency">Bevorzuge niedrigste Latenz</string>
|
||||
<string name="pacing_balanced">Ausgeglichen</string>
|
||||
<string name="pacing_smoothness">Bevorzuge flüssige Bildwiedergabe (kann die Latenzzeit deutlich erhöhen)</string>
|
||||
<string name="perf_overlay_streamdetails">Video Stream: %1$s %2$.2f FPS</string>
|
||||
<string name="resolution_360p">360p</string>
|
||||
<string name="resolution_1080p">1080p</string>
|
||||
<string name="resolution_1440p">1440p</string>
|
||||
<string name="resolution_4k">4K</string>
|
||||
<string name="audioconf_stereo">Stereo</string>
|
||||
<string name="audioconf_51surround">5.1 Surround Sound</string>
|
||||
<string name="audioconf_71surround">7.1 Surround Sound</string>
|
||||
<string name="perf_overlay_netlatency">Durchschnittliche Netzwerklatenz: %1$d ms (Abweichung: %2$d ms)</string>
|
||||
<string name="fps_30">30 FPS</string>
|
||||
<string name="resolution_480p">480p</string>
|
||||
<string name="fps_120">120 FPS</string>
|
||||
<string name="resolution_720p">720p</string>
|
||||
<string name="fps_60">60 FPS</string>
|
||||
<string name="fps_90">90 FPS</string>
|
||||
<string name="summary_troubleshooting">Tipps zur Diagnose und Behebung häufiger Streaming-Probleme anzeigen</string>
|
||||
<string name="pacing_balanced_alt">Ausbalanciert mit FPS-Limit</string>
|
||||
<string name="summary_checkbox_absolute_mouse_mode">Dies kann die Mausbeschleunigung für die Fernsteuerung natürlicher gestalten, ist aber mit vielen Spielen nicht kompatibel.</string>
|
||||
<string name="title_troubleshooting">Anleitung zur Fehlersuche</string>
|
||||
<string name="title_privacy_policy">Datenschutzbestimmungen</string>
|
||||
<string name="title_checkbox_enable_audiofx">Unterstützung des System-Equalizer aktivieren</string>
|
||||
<string name="summary_setup_guide">Zeige Anweisungen zum Einrichten Ihres Gaming-PCs für das Streaming an</string>
|
||||
<string name="title_checkbox_absolute_mouse_mode">Modus für ferngesteuerte Maus</string>
|
||||
<string name="category_help">Hilfe</string>
|
||||
<string name="title_setup_guide">Einstellungsanleitung</string>
|
||||
<string name="summary_privacy_policy">Moonlight\'s Datenschutzbestimmungen anzeigen</string>
|
||||
<string name="summary_seekbar_deadzone">Hinweis: Einige Spiele können eine größere Controller-Totzone erzwingen als die, die in Moonlight konfiguriert ist.</string>
|
||||
<string name="summary_checkbox_enable_audiofx">Ermöglicht das Funktionieren von Audioeffekten beim Streaming, kann aber die Audio-Latenz erhöhen</string>
|
||||
<string name="resolution_prefix_native_portrait">(Portrait)</string>
|
||||
<string name="title_checkbox_reduce_refresh_rate">Aktualisierungsrate verringern erlauben</string>
|
||||
<string name="summary_checkbox_reduce_refresh_rate">Durch das Verringern der Display Aktualisierungsrate, kann, auf Kosten der Video-Latenz, der Akkuverbrauch reduziert werden</string>
|
||||
<string name="resolution_prefix_native_landscape">(Landscape)</string>
|
||||
</resources>
|
||||
208
app/src/main/res/values-el/strings.xml
Normal file
208
app/src/main/res/values-el/strings.xml
Normal file
@@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="unable_to_pin_shortcut">Η τρέχουσα εφαρμογή εκκίνησης δεν επιτρέπει τη δημιουργία καρφιτσωμένων συντομεύσεων.</string>
|
||||
<string name="pcview_menu_delete_pc">Διαγραφή υπολογιστή</string>
|
||||
<string name="nettest_text_success">Το δίκτυό σας δεν φαίνεται να μπλοκάρει το Moonlight. Αν εξακολουθείτε να έχετε πρόβλημα σύνδεσης, ελέγξτε τις ρυθμίσεις του τείχους προστασίας του υπολογιστή σας.
|
||||
\n
|
||||
\nΕάν προσπαθείτε να κάνετε streaming μέσω του Διαδικτύου, εγκαταστήστε το Moonlight Internet Hosting Tool στον υπολογιστή σας και εκτελέστε το συμπεριλαμβανόμενο Internet Streaming Tester για να ελέγξετε τη σύνδεση του υπολογιστή σας στο Διαδίκτυο.</string>
|
||||
<string name="error_manager_not_running">Η υπηρεσία ComputerManager δεν εκτελείται. Περιμένετε μερικά δευτερόλεπτα ή επανεκκινήστε την εφαρμογή.</string>
|
||||
<string name="message_decoding_error">Το Moonlight κατέρρευσε λόγω ασυμβατότητας με τον αποκωδικοποιητή βίντεο αυτής της συσκευής. Βεβαιωθείτε ότι το GeForce Experience έχει ενημερωθεί στην τελευταία έκδοση στον υπολογιστή σας. Δοκιμάστε να προσαρμόσετε τις ρυθμίσεις ροής, εάν οι καταρρεύσεις συνεχίζονται.</string>
|
||||
<string name="help_loading_title">Πρόγραμμα προβολής βοήθειας</string>
|
||||
<string name="help_loading_msg">Φόρτωση σελίδας βοήθειας…</string>
|
||||
<string name="pcview_menu_header_online">Σε σύνδεση</string>
|
||||
<string name="pcview_menu_header_unknown">Ανανέωση</string>
|
||||
<string name="pcview_menu_app_list">Προβολή όλων των εφαρμογών</string>
|
||||
<string name="pcview_menu_pair_pc">Σύζευξη με υπολογιστή</string>
|
||||
<string name="pcview_menu_unpair_pc">Κατάργηση ζεύξης</string>
|
||||
<string name="pcview_menu_send_wol">Αποστολή αιτήματος Wake-On-LAN</string>
|
||||
<string name="nettest_title_waiting">Δοκιμή σύνδεσης δικτύου</string>
|
||||
<string name="nettest_title_done">Ολοκληρώθηκε η δοκιμή δικτύου</string>
|
||||
<string name="nettest_text_inconclusive">Η δοκιμή δικτύου δεν μπορούσε να πραγματοποιηθεί επειδή κανένας από τους διακομιστές δοκιμής σύνδεσης της Moonlight δεν ήταν προσβάσιμος. Ελέγξτε τη σύνδεσή σας στο Internet ή δοκιμάστε ξανά αργότερα.</string>
|
||||
<string name="nettest_text_blocked">Η τρέχουσα σύνδεση δικτύου της συσκευής σας εμποδίζει το Moonlight. Η ροή μέσω του Internet ενδέχεται να μην λειτουργεί ενώ είστε συνδεδεμένοι σε αυτό το δίκτυο.</string>
|
||||
<string name="pairing">Σύζευξη…</string>
|
||||
<string name="pair_pc_offline">Ο υπολογιστής είναι εκτός σύνδεσης</string>
|
||||
<string name="pair_pc_ingame">Ο υπολογιστής βρίσκεται αυτή τη στιγμή σε παιχνίδι. Πρέπει να κλείσετε το παιχνίδι πριν κάνετε σύζευξη.</string>
|
||||
<string name="pair_pairing_title">Σύζευξη</string>
|
||||
<string name="pair_pairing_msg">Εισαγάγετε τον ακόλουθο κωδικό PIN στον υπολογιστή προορισμού:</string>
|
||||
<string name="pair_incorrect_pin">Λανθασμένο PIN</string>
|
||||
<string name="pair_already_in_progress">Η σύζευξη βρίσκεται ήδη σε εξέλιξη</string>
|
||||
<string name="wol_pc_online">Ο υπολογιστής είναι συνδεδεμένος</string>
|
||||
<string name="wol_waking_pc">Αφύπνιση υπολογιστή…</string>
|
||||
<string name="wol_waking_msg">Μπορεί να χρειαστούν μερικά δευτερόλεπτα για να αφυπνισθεί ο υπολογιστής σας. Αν δεν το κάνει, βεβαιωθείτε ότι έχει ρυθμιστεί σωστά για Wake-On-LAN.</string>
|
||||
<string name="scut_invalid_app_id">Η παρεχόμενη εφαρμογή δεν είναι έγκυρη</string>
|
||||
<string name="scut_invalid_uuid">Ο παρεχόμενος υπολογιστής δεν είναι έγκυρος</string>
|
||||
<string name="pcview_menu_details">Προβολή λεπτομερειών</string>
|
||||
<string name="nettest_text_failure">Η τρέχουσα σύνδεση δικτύου της συσκευής σας φαίνεται να εμποδίζει το Moonlight. Η ροή μέσω του Internet ενδέχεται να μην λειτουργεί ενώ είστε συνδεδεμένοι σε αυτό το δίκτυο.
|
||||
\n
|
||||
\nΟι ακόλουθες θύρες δικτύου αποκλείστηκαν:
|
||||
\n</string>
|
||||
<string name="perf_overlay_netlatency">Μέσος λανθάνων χρόνος δικτύου: %1$d MS (διακύμανση: %2$d ms)</string>
|
||||
<string name="applist_menu_hide_app">Απόκρυψη εφαρμογής</string>
|
||||
<string name="applist_refresh_title">Λίστα εφαρμογών</string>
|
||||
<string name="applist_refresh_error_title">Σφάλμα</string>
|
||||
<string name="applist_refresh_error_msg">Απέτυχε η λήψη λίστας εφαρμογών</string>
|
||||
<string name="applist_quit_fail">Αποτυχία διακοπής</string>
|
||||
<string name="applist_quit_confirmation">Είστε σίγουροι ότι θέλετε να τερματίσετε την τρέχουσα εφαρμογή; Όλα τα μη αποθηκευμένα δεδομένα θα χαθούν.</string>
|
||||
<string name="dialog_text_reset_osc">Είστε βέβαιοι ότι θέλετε να διαγράψετε την αποθηκευμένη διάταξη στοιχείων ελέγχου στην οθόνη;</string>
|
||||
<string name="title_enable_perf_overlay">Εμφάνιση στατιστικών στοιχείων απόδοσης κατά τη ροή</string>
|
||||
<string name="unpair_error">Η συσκευή δεν είχε συζευξηθεί</string>
|
||||
<string name="error_pc_offline">Ο υπολογιστής είναι εκτός σύνδεσης</string>
|
||||
<string name="error_unknown_host">Αποτυχία επίλυσης ονόματος κεντρικού υπολογιστή</string>
|
||||
<string name="title_decoding_error">Ο αποκωδικοποιητής βίντεο κατέρρευσε</string>
|
||||
<string name="title_decoding_reset">Επαναφορά ρυθμίσεων βίντεο</string>
|
||||
<string name="message_decoding_reset">Ο αποκωδικοποιητής βίντεο της συσκευής σας συνεχίζει να κολλάει στις επιλεγμένες ρυθμίσεις ροής. Οι ρυθμίσεις ροής σας επαναφέρθηκαν στις προεπιλογές.</string>
|
||||
<string name="error_usb_prohibited">Η πρόσβαση μέσω USB απαγορεύεται από το διαχειριστή της συσκευής σας. Ελέγξτε τις ρυθμίσεις Knox ή MDM.</string>
|
||||
<string name="no_video_received_error">Δεν ελήφθη βίντεο από τον κεντρικό υπολογιστή.</string>
|
||||
<string name="no_frame_received_error">Η σύνδεσή σας στο δίκτυο δεν αποδίδει καλά. Μειώστε το bitrate ή δοκιμάστε μια ταχύτερη σύνδεση.</string>
|
||||
<string name="check_ports_msg">Ελέγξτε το τείχος προστασίας και τους κανόνες προώθησης θυρών για τις θύρες:</string>
|
||||
<string name="conn_establishing_title">Δημιουργία σύνδεσης</string>
|
||||
<string name="conn_establishing_msg">Έναρξη σύνδεσης</string>
|
||||
<string name="conn_metered">Προειδοποίηση: Η ενεργή σύνδεσή σας στο δίκτυο έχει όριο δεδομένων!</string>
|
||||
<string name="conn_client_latency">Μέσος χρόνος αποκωδικοποίησης πλαισίων:</string>
|
||||
<string name="conn_client_latency_hw">Λανθάνων χρόνος αποκωδικοποιητή υλικού:</string>
|
||||
<string name="conn_hardware_latency">Μέση καθυστέρηση αποκωδικοποίησης υλικού:</string>
|
||||
<string name="conn_starting">Εκκίνηση</string>
|
||||
<string name="conn_terminated_msg">Η σύνδεση τερματίστηκε</string>
|
||||
<string name="ip_hint">Διεύθυνση IP του υπολογιστή GeForce</string>
|
||||
<string name="yes">Ναί</string>
|
||||
<string name="perf_overlay_streamdetails">Ροή βίντεο: %1$s %2$.2f FPS</string>
|
||||
<string name="perf_overlay_decoder">Αποκωδικοποιητής: %1$s</string>
|
||||
<string name="perf_overlay_incomingfps">Ρυθμός εισερχόμενων καρέ από το δίκτυο: %1$.2f FPS</string>
|
||||
<string name="applist_menu_cancel">Ακύρωση</string>
|
||||
<string name="applist_menu_tv_channel">Προσθήκη στο κανάλι</string>
|
||||
<string name="applist_refresh_msg">Ανανέωση εφαρμογών…</string>
|
||||
<string name="addpc_success">Ο υπολογιστής προστέθηκε με επιτυχία</string>
|
||||
<string name="addpc_unknown_host">Αδυναμία επίλυσης διεύθυνσης υπολογιστή. Βεβαιωθείτε ότι δεν κάνατε τυπογραφικό λάθος στη διεύθυνση.</string>
|
||||
<string name="title_fps_list">Ρυθμός καρέ βίντεο</string>
|
||||
<string name="summary_fps_list">Αύξηση για πιο ομαλή ροή βίντεο. Μειώστε για καλύτερες επιδόσεις σε συσκευές χαμηλότερων προδιαγραφών.</string>
|
||||
<string name="title_seekbar_bitrate">Ρυθμός bit βίντεο</string>
|
||||
<string name="summary_seekbar_bitrate">Αυξήστε για καλύτερη ποιότητα εικόνας. Μείωση για τη βελτίωση των επιδόσεων σε πιο αργές συνδέσεις.</string>
|
||||
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
|
||||
<string name="title_checkbox_stretch_video">Επέκταση βίντεο σε πλήρη οθόνη</string>
|
||||
<string name="resolution_prefix_native">Εγγενής</string>
|
||||
<string name="resolution_prefix_native_fullscreen">Εγγενής πλήρης οθόνη</string>
|
||||
<string name="category_audio_settings">Ρυθμίσεις ήχου</string>
|
||||
<string name="title_audio_config_list">Ρύθμιση παραμέτρων ήχου surround</string>
|
||||
<string name="summary_checkbox_vibrate_fallback">Δονεί τη συσκευή σας για να μιμηθεί το rumble αν το gamepad σας δεν το υποστηρίζει</string>
|
||||
<string name="suffix_seekbar_deadzone">%</string>
|
||||
<string name="title_checkbox_xb1_driver">Πρόγραμμα οδήγησης για Xbox 360/One USB gamepad</string>
|
||||
<string name="summary_checkbox_xb1_driver">Ενεργοποιεί ένα ενσωματωμένο πρόγραμμα οδήγησης USB για συσκευές χωρίς εγγενή υποστήριξη χειριστηρίου Xbox</string>
|
||||
<string name="title_checkbox_usb_bind_all">Παράκαμψη εγγενούς υποστήριξης του Xbox gamepad</string>
|
||||
<string name="summary_checkbox_usb_bind_all">Χρησιμοποιήστε το πρόγραμμα οδήγησης USB του Moonlight για όλα τα υποστηριζόμενα gamepad, ακόμα και αν υπάρχει υποστήριξη εγγενούς ελεγκτή Xbox</string>
|
||||
<string name="title_checkbox_mouse_emulation">Εξομοίωση ποντικιού μέσω gamepad</string>
|
||||
<string name="title_checkbox_mouse_nav_buttons">Ενεργοποίηση κουμπιών ποντικιού πίσω και εμπρός</string>
|
||||
<string name="summary_checkbox_mouse_nav_buttons">Η ενεργοποίηση αυτής της επιλογής μπορεί να διακόψει το δεξί κλικ σε ορισμένες συσκευές με σφάλματα</string>
|
||||
<string name="title_checkbox_flip_face_buttons">Αναστροφή κουμπιών πρόσωψης</string>
|
||||
<string name="summary_checkbox_flip_face_buttons">Αλλάζει τα κουμπιά πρόσοψης A/B και X/Y για τα gamepad και τα χειριστήρια στην οθόνη</string>
|
||||
<string name="summary_checkbox_show_onscreen_controls">Εμφάνιση επικάλυψης εικονικού ελεγκτή στην οθόνη αφής</string>
|
||||
<string name="title_checkbox_vibrate_osc">Ενεργοποίηση δόνησης</string>
|
||||
<string name="title_only_l3r3">Εμφάνιση μόνο των L3 και R3</string>
|
||||
<string name="summary_only_l3r3">Απόκρυψη όλων των εικονικών κουμπιών εκτός των L3 και R3</string>
|
||||
<string name="dialog_title_reset_osc">Επαναφορά διάταξης</string>
|
||||
<string name="toast_reset_osc_success">Επαναφορά των στοιχείων ελέγχου στην οθόνη στις προεπιλογές</string>
|
||||
<string name="title_osc_opacity">Αλλαγή της αδιαφάνειας των στοιχείων ελέγχου στην οθόνη</string>
|
||||
<string name="summary_osc_opacity">Κάντε τα στοιχεία ελέγχου στην οθόνη περισσότερο/λιγότερο διαφανή</string>
|
||||
<string name="suffix_osc_opacity">%</string>
|
||||
<string name="category_ui_settings">Ρυθμίσεις διεπαφής χρήστη</string>
|
||||
<string name="title_checkbox_enable_pip">Ενεργοποίηση της λειτουργίας παρατηρητή εικόνας μέσα σε εικόνα</string>
|
||||
<string name="summary_checkbox_enable_pip">Επιτρέπει την προβολή της ροής (αλλά όχι τον έλεγχο) κατά την εκτέλεση πολλαπλών εργασιών</string>
|
||||
<string name="title_language_list">Γλώσσα</string>
|
||||
<string name="summary_language_list">Γλώσσα που χρησιμοποιείται για το Moonlight</string>
|
||||
<string name="title_checkbox_small_icon_mode">Χρησιμοποιήστε μικρά κουτιά</string>
|
||||
<string name="scut_not_paired">Ο υπολογιστής δεν έχει συζευχθεί</string>
|
||||
<string name="pcview_menu_header_offline">Εκτός σύνδεσης</string>
|
||||
<string name="pcview_menu_test_network">Δοκιμή σύνδεσης δικτύου</string>
|
||||
<string name="nettest_text_waiting">Το Moonlight δοκιμάζει τη σύνδεση δικτύου σας για να καθορίσει εάν το NVIDIA GameStream είναι αποκλεισμένο.
|
||||
\n
|
||||
\nΑυτό μπορεί να πάρει μερικά δευτερόλεπτα…</string>
|
||||
<string name="pair_fail">Η σύζευξη απέτυχε</string>
|
||||
<string name="wol_no_mac">Δεν είναι δυνατή η αφύπνιση του υπολογιστή επειδή το GFE δεν έστειλε διεύθυνση MAC</string>
|
||||
<string name="wol_fail">Απέτυχε η αποστολή πακέτων Wake-On-LAN</string>
|
||||
<string name="unpairing">Κατάργηση σύζευξης…</string>
|
||||
<string name="unpair_success">Καταργήθηκε η σύζευξη με επιτυχία</string>
|
||||
<string name="unpair_fail">Αποτυχία κατάργησης σύζευξης</string>
|
||||
<string name="summary_checkbox_small_icon_mode">Το μικρότερο box art στο πλέγμα εφαρμογών επιτρέπει σε περισσότερες εφαρμογές να είναι ορατές στην οθόνη</string>
|
||||
<string name="category_host_settings">Ρυθμίσεις κεντρικού υπολογιστή</string>
|
||||
<string name="title_checkbox_host_audio">Αναπαραγωγή ήχου στον υπολογιστή</string>
|
||||
<string name="summary_checkbox_host_audio">Αναπαραγωγή ήχου από τον υπολογιστή και αυτή τη συσκευή</string>
|
||||
<string name="title_checkbox_disable_warnings">Απενεργοποίηση προειδοποιητικών μηνυμάτων</string>
|
||||
<string name="summary_checkbox_disable_warnings">Απενεργοποίηση των προειδοποιητικών μηνυμάτων σύνδεσης στην οθόνη κατά τη ροή</string>
|
||||
<string name="summary_disable_frame_drop">Μπορεί να μειώσει το micro-stuttering σε ορισμένες συσκευές, αλλά μπορεί να αυξήσει την καθυστέρηση</string>
|
||||
<string name="title_enable_hdr">Ενεργοποίηση HDR (πειραματικό)</string>
|
||||
<string name="summary_enable_hdr">Μεταδώστε HDR όταν το παιχνίδι και η GPU του υπολογιστή το υποστηρίζουν. Το HDR απαιτεί GPU της σειράς GTX 1000 ή νεότερη.</string>
|
||||
<string name="summary_enable_perf_overlay">Εμφάνιση πληροφοριών απόδοσης ροής σε πραγματικό χρόνο κατά τη ροή</string>
|
||||
<string name="summary_enable_post_stream_toast">Εμφάνιση ενός μηνύματος πληροφοριών καθυστέρησης μετά το τέλος της ροής</string>
|
||||
<string name="scut_deleted_pc">Ο υπολογιστής διαγράφηκε</string>
|
||||
<string name="scut_pc_not_found">Ο υπολογιστής δεν βρέθηκε</string>
|
||||
<string name="early_termination_error">Κάτι πήγε στραβά στον κεντρικό υπολογιστή σας κατά την εκκίνηση της ροής.
|
||||
\n
|
||||
\nΒεβαιωθείτε ότι δεν έχετε ανοιχτό περιεχόμενο που προστατεύεται από DRM στον κεντρικό υπολογιστή σας. Μπορείτε επίσης να δοκιμάσετε να κάνετε επανεκκίνηση του κεντρικού υπολογιστή σας.
|
||||
\n
|
||||
\nΑν το πρόβλημα παραμένει, δοκιμάστε να επανεγκαταστήσετε τα προγράμματα οδήγησης της κάρτας γραφικών και το GeForce Experience.</string>
|
||||
<string name="conn_terminated_title">Η σύνδεση τερματίστηκε</string>
|
||||
<string name="help">Βοήθεια</string>
|
||||
<string name="perf_overlay_netdrops">Πλαίσια που απορρίπτονται από τη σύνδεση δικτύου σας: %1$.2f%%</string>
|
||||
<string name="applist_quit_app">Εγκατάλειψη</string>
|
||||
<string name="msg_add_pc">Σύνδεση στον υπολογιστή…</string>
|
||||
<string name="error_404">Το GFE επέστρεψε ένα σφάλμα HTTP 404. Βεβαιωθείτε ότι ο υπολογιστής σας χρησιμοποιεί μια υποστηριζόμενη κάρτα γραφικών. Η χρήση λογισμικού απομακρυσμένης επιφάνειας εργασίας μπορεί επίσης να προκαλέσει αυτό το σφάλμα. Δοκιμάστε την επανεκκίνηση του υπολογιστή σας ή την επανεγκατάσταση του GFE.</string>
|
||||
<string name="video_decoder_init_failed">Απέτυχε η προετοιμασία του αποκωδικοποιητή βίντεο. Η συσκευή σας ενδέχεται να μην υποστηρίζει την επιλεγμένη ανάλυση ή ρυθμό καρέ.</string>
|
||||
<string name="perf_overlay_dectime">Μέσος χρόνος αποκωδικοποίησης: %1$.2f ms</string>
|
||||
<string name="title_add_pc">Προσθήκη υπολογιστή χειροκίνητα</string>
|
||||
<string name="lost_connection">Χάθηκε η σύνδεση με τον υπολογιστή</string>
|
||||
<string name="title_details">Λεπτομέρειες</string>
|
||||
<string name="applist_menu_resume">Συνέχιση περιόδου λειτουργίας</string>
|
||||
<string name="applist_menu_quit">Έξοδος από τη συνεδρία</string>
|
||||
<string name="addpc_wrong_sitelocal">Αυτή η διεύθυνση δεν φαίνεται σωστή. Πρέπει να χρησιμοποιείτε τη δημόσια διεύθυνση IP του δρομολογητή σας για ροή μέσω του Διαδικτύου.</string>
|
||||
<string name="conn_error_title">Σφάλμα σύνδεσης</string>
|
||||
<string name="conn_error_msg">Απέτυχε η εκκίνηση</string>
|
||||
<string name="searching_pc">Αναζήτηση για υπολογιστές με GameStream σε λειτουργία...
|
||||
\n
|
||||
\n Βεβαιωθείτε ότι το GameStream είναι ενεργοποιημένο στις ρυθμίσεις GeForce Experience SHIELD.</string>
|
||||
<string name="no">Οχι</string>
|
||||
<string name="delete_pc_msg">Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτόν τον υπολογιστή;</string>
|
||||
<string name="slow_connection_msg">Αργή σύνδεση με υπολογιστή
|
||||
\nΜειώστε το bitrate σας</string>
|
||||
<string name="poor_connection_msg">Κακή σύνδεση με τον υπολογιστή</string>
|
||||
<string name="applist_connect_msg">Σύνδεση σε υπολογιστή…</string>
|
||||
<string name="applist_menu_quit_and_start">Τερματισμός τρέχοντος παιχνιδιού και έναρξη</string>
|
||||
<string name="summary_checkbox_touchscreen_trackpad">Εάν είναι ενεργοποιημένη, η οθόνη αφής λειτουργεί σαν trackpad. Εάν είναι απενεργοποιημένη, η οθόνη αφής ελέγχει απευθείας τον κέρσορα του ποντικιού.</string>
|
||||
<string name="title_checkbox_multi_controller">Αυτόματη ανίχνευση παρουσίας gamepad</string>
|
||||
<string name="applist_menu_details">Προβολή λεπτομερειών</string>
|
||||
<string name="applist_quit_success">Επιτυχής έξοδος</string>
|
||||
<string name="applist_menu_scut">Δημιουργία συντόμευσης</string>
|
||||
<string name="applist_details_id">Αναγνωριστικό εφαρμογής:</string>
|
||||
<string name="addpc_fail">Αδυναμία σύνδεσης με τον καθορισμένο υπολογιστή. Βεβαιωθείτε ότι οι απαιτούμενες θύρες επιτρέπονται μέσω του τείχους προστασίας.</string>
|
||||
<string name="addpc_enter_ip">Πρέπει να εισαγάγετε μια διεύθυνση IP</string>
|
||||
<string name="title_resolution_list">Ανάλυση βίντεο</string>
|
||||
<string name="summary_audio_config_list">Ενεργοποίηση ήχου surround 5.1 ή 7.1 για συστήματα οικιακού κινηματογράφου</string>
|
||||
<string name="category_input_settings">Ρυθμίσεις εισόδου</string>
|
||||
<string name="title_checkbox_touchscreen_trackpad">Χρήση της οθόνης αφής ως trackpad</string>
|
||||
<string name="summary_checkbox_multi_controller">Η απενεργοποίηση αυτής της επιλογής αναγκάζει ένα gamepad να είναι πάντα παρόν</string>
|
||||
<string name="category_basic_settings">Βασικές ρυθμίσεις</string>
|
||||
<string name="summary_resolution_list">Αυξήστε για να βελτιώσετε την ευκρίνεια της εικόνας. Μειώστε για καλύτερη απόδοση σε συσκευές χαμηλότερων επιδόσεων και σε πιο αργά δίκτυα.</string>
|
||||
<string name="title_native_res_dialog">Προειδοποίηση εγγενούς ανάλυσης</string>
|
||||
<string name="text_native_res_dialog">Οι λειτουργίες εγγενούς ανάλυσης δεν υποστηρίζονται επίσημα από το GeForce Experience, επομένως δεν θα ορίσει το ίδιο την ανάλυση της οθόνης υποδοχής σας. Θα πρέπει να τη ρυθμίσετε χειροκίνητα κατά τη διάρκεια του παιχνιδιού.
|
||||
\n
|
||||
\nΕάν επιλέξετε να δημιουργήσετε μια προσαρμοσμένη ανάλυση στον Πίνακα Ελέγχου της NVIDIA για να ταιριάζει με την ανάλυση της συσκευής σας, βεβαιωθείτε ότι έχετε διαβάσει και κατανοήσει την προειδοποίηση της NVIDIA σχετικά με πιθανή βλάβη της οθόνης, αστάθεια του υπολογιστή και άλλα πιθανά προβλήματα.
|
||||
\n
|
||||
\nΔεν είμαστε υπεύθυνοι για τυχόν προβλήματα που προκύπτουν από τη δημιουργία προσαρμοσμένης ανάλυσης στον υπολογιστή σας.
|
||||
\n
|
||||
\nΤέλος, η συσκευή ή ο κεντρικός υπολογιστής σας ενδέχεται να μην υποστηρίζει ροή σε εγγενή ανάλυση. Εάν δεν λειτουργεί στη συσκευή σας, δυστυχώς δεν είστε τυχεροί.</string>
|
||||
<string name="title_checkbox_vibrate_fallback">Μιμηθείτε την υποστήριξη rumble με δόνηση</string>
|
||||
<string name="title_seekbar_deadzone">Ρύθμιση της νεκρής ζώνης του αναλογικού μοχλού</string>
|
||||
<string name="summary_checkbox_mouse_emulation">Με παρατεταμένο πάτημα του κουμπιού Έναρξη θα αλλάξει το gamepad σε λειτουργία ποντικιού</string>
|
||||
<string name="category_on_screen_controls_settings">Ρυθμίσεις στοιχείων ελέγχου στην οθόνη</string>
|
||||
<string name="summary_reset_osc">Επαναφέρει όλα τα στοιχεία ελέγχου στην οθόνη στο προεπιλεγμένο μέγεθος και τη θέση τους</string>
|
||||
<string name="title_unlock_fps">Ξεκλειδώστε όλους τους πιθανούς ρυθμούς καρέ</string>
|
||||
<string name="title_checkbox_show_onscreen_controls">Εμφάνιση στοιχείων ελέγχου στην οθόνη</string>
|
||||
<string name="summary_checkbox_vibrate_osc">Δονεί τη συσκευή σας για να μιμηθεί το rumble για τα χειριστήρια στην οθόνη</string>
|
||||
<string name="title_reset_osc">Εκκαθάριση αποθηκευμένης διάταξης στοιχείων ελέγχου στην οθόνη</string>
|
||||
<string name="dialog_title_osc_opacity">Αλλαγή αδιαφάνειας</string>
|
||||
<string name="title_checkbox_enable_sops">Βελτιστοποίηση ρυθμίσεων παιχνιδιού</string>
|
||||
<string name="summary_checkbox_enable_sops">Επιτρέψτε στη GFE να τροποποιήσει τις ρυθμίσεις του παιχνιδιού για βέλτιστη ροή</string>
|
||||
<string name="category_advanced_settings">Προηγμένες ρυθμίσεις</string>
|
||||
<string name="summary_unlock_fps">Η ροή στα 90 ή 120 FPS μπορεί να μειώσει τον λανθάνοντα χρόνο σε συσκευές υψηλών προδιαγραφών, αλλά μπορεί να προκαλέσει καθυστέρηση ή αστάθεια σε συσκευές που δεν μπορούν να την υποστηρίξουν</string>
|
||||
<string name="title_video_format">Αλλαγή ρυθμίσεων HEVC</string>
|
||||
<string name="title_enable_post_stream_toast">Εμφάνιση μηνύματος λανθάνοντος χρόνου μετά τη ροή</string>
|
||||
<string name="summary_video_format">Το HEVC μειώνει τις απαιτήσεις εύρους ζώνης βίντεο, αλλά απαιτεί μια νεότερη συσκευή</string>
|
||||
</resources>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="decoder_names">
|
||||
<item>Automático</item>
|
||||
<item>Forzar decodificación por software</item>
|
||||
<item>Forzar decodificación por hardware</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="video_format_names">
|
||||
<item>Usar H.265 solo si es estable</item>
|
||||
<item>Siempre usar H.265 (puede fallar)</item>
|
||||
<item>Nunca usar H.265</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -1,13 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- PC view menu entries -->
|
||||
<string name="pcview_menu_app_list">Ver lista de juegos</string>
|
||||
<string name="pcview_menu_pair_pc">Emparejar con PC</string>
|
||||
<string name="pcview_menu_unpair_pc">Desemparejar</string>
|
||||
<string name="pcview_menu_send_wol">Enviar petición Wake-On-LAN</string>
|
||||
<string name="pcview_menu_delete_pc">Eliminar PC</string>
|
||||
|
||||
<!-- Pair messages -->
|
||||
<string name="pairing">Emparejando…</string>
|
||||
<string name="pair_pc_offline">El ordenador está apagado</string>
|
||||
@@ -16,7 +14,6 @@
|
||||
<string name="pair_pairing_msg">Por favor, introduce el siguiente PIN en el PC destino:</string>
|
||||
<string name="pair_incorrect_pin">PIN incorrecto</string>
|
||||
<string name="pair_fail">Fallo al emparejar</string>
|
||||
|
||||
<!-- WOL messages -->
|
||||
<string name="wol_pc_online">Ordenador encendido</string>
|
||||
<string name="wol_no_mac">Imposible iniciar PC porque GFE no ha enviado una dirección MAC</string>
|
||||
@@ -25,13 +22,11 @@
|
||||
Si no se inicia asegúrate que está configurado correctamente para Wake-On-LAN.
|
||||
</string>
|
||||
<string name="wol_fail">Fallo al enviar paquetes Wake-On-LAN</string>
|
||||
|
||||
<!-- Unpair messages -->
|
||||
<string name="unpairing">Desemparejando…</string>
|
||||
<string name="unpair_success">Desemparejado con éxito</string>
|
||||
<string name="unpair_fail">Error al desemparejar</string>
|
||||
<string name="unpair_error">El dispositivo no estaba emparejado</string>
|
||||
|
||||
<!-- Errors -->
|
||||
<string name="error_pc_offline">El ordenador está apagado</string>
|
||||
<string name="error_manager_not_running">El servicio "ComputerManager" no está en ejecución. Por favor, espera unos segundos o reinicia la aplicación.</string>
|
||||
@@ -39,7 +34,6 @@
|
||||
<string name="error_404">GFE ha devuelto un error HTTP 404. Asegúrate que el PC tiene una GPU soportada.
|
||||
Usar software de Escritorio Remoto puede causar este error. Intenta reiniciar el equipo o reinstalar GFE.
|
||||
</string>
|
||||
|
||||
<!-- Start application messages -->
|
||||
<string name="conn_establishing_title">Estableciendo conexión</string>
|
||||
<string name="conn_establishing_msg">Iniciando conexión</string>
|
||||
@@ -52,14 +46,14 @@
|
||||
<string name="conn_error_msg">Fallo al iniciar</string>
|
||||
<string name="conn_terminated_title">Conexión finalizada</string>
|
||||
<string name="conn_terminated_msg">La conexión ha finalizando</string>
|
||||
|
||||
<!-- General strings -->
|
||||
<string name="ip_hint">Dirección IP del PC con GeForce</string>
|
||||
<string name="searching_pc">Buscando por PCs con GeForce Experience ejecutándose…</string>
|
||||
<string name="searching_pc">Buscando por PCs con GameStream ejecutándose...
|
||||
\n
|
||||
\nVerifica que GameStream esté activado en las opciones de SHIELD dentro de GeForce Experience.</string>
|
||||
<string name="yes">Si</string>
|
||||
<string name="no">No</string>
|
||||
<string name="lost_connection">Conexión perdida</string>
|
||||
|
||||
<!-- AppList activity -->
|
||||
<string name="applist_menu_resume">Reanudar sesión</string>
|
||||
<string name="applist_menu_quit">Cerrar sesión</string>
|
||||
@@ -73,7 +67,6 @@
|
||||
<string name="applist_quit_success">Cerrado satisfactoriamente</string>
|
||||
<string name="applist_quit_fail">Error al cerrar</string>
|
||||
<string name="applist_quit_confirmation">¿Estás seguro que deseas quitar la aplicación en ejecución? Todo dato sin salvar se perderá.</string>
|
||||
|
||||
<!-- Add computer manually activity -->
|
||||
<string name="title_add_pc">Añadir PC manualmente</string>
|
||||
<string name="msg_add_pc">Conectando al PC…</string>
|
||||
@@ -81,46 +74,186 @@
|
||||
<string name="addpc_success">Ordenador añadido satisfactoriamente</string>
|
||||
<string name="addpc_unknown_host">Imposible resolver la dirección del PC. Asegúrate que no hay ningún error en la dirección.</string>
|
||||
<string name="addpc_enter_ip">Debes introducir una dirección IP</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<string name="category_basic_settings">Configuración básica</string>
|
||||
<string name="title_resolution_list">Seleccionar resolución y FPS</string>
|
||||
<string name="summary_resolution_list">Establecer unos valores demasiado altos puede causar lag o cierres inesperados</string>
|
||||
<string name="summary_resolution_list">Establecer unos valores demasiado altos puede causar retraso o cierres inesperados.</string>
|
||||
<string name="title_seekbar_bitrate">Seleccionar bitrate de vídeo</string>
|
||||
<string name="summary_seekbar_bitrate">Usa bitrate bajo para reducir "parpadeo". Incrementa el bitrate para mayor calidad de imagen.</string>
|
||||
<string name="title_checkbox_stretch_video">Ajustar vídeo a pantalla completa</string>
|
||||
<string name="title_checkbox_disable_warnings">Desactivar mensajes de advertencia</string>
|
||||
<string name="summary_checkbox_disable_warnings">Desactivar mensajes de advertencia en pantalla durante la transmisión</string>
|
||||
|
||||
<string name="category_audio_settings">Configuración de audio</string>
|
||||
|
||||
<string name="title_checkbox_multi_controller">Soporte para múltiples mandos</string>
|
||||
<string name="summary_checkbox_multi_controller">Si no está marcado, todos los mandos aparecen como uno solo</string>
|
||||
<string name="title_seekbar_deadzone">Ajustar zona muerta del stick analógico</string>
|
||||
<string name="suffix_seekbar_deadzone">%</string>
|
||||
<string name="title_checkbox_xb1_driver">Driver para mando Xbox 360/One</string>
|
||||
<string name="summary_checkbox_xb1_driver">Activa el driver USB incluido para dispositivos sin soporte nativo para mandos de Xbox.</string>
|
||||
|
||||
<string name="summary_checkbox_xb1_driver">Activa el driver USB incluido para dispositivos sin soporte nativo para mandos de Xbox</string>
|
||||
<string name="category_on_screen_controls_settings">Configuración de controles en pantalla</string>
|
||||
<string name="title_checkbox_show_onscreen_controls">Mostrar controles en pantalla</string>
|
||||
<string name="summary_checkbox_show_onscreen_controls">Muestra controles virtuales superpuestos en la pantalla táctil</string>
|
||||
<string name="title_only_l3r3">Solo muestra L3 y R3</string>
|
||||
<string name="summary_only_l3r3">Ocultar todo excepto L3 y R3</string>
|
||||
|
||||
<string name="category_ui_settings">Configuración de la interfaz</string>
|
||||
<string name="title_language_list">Idioma</string>
|
||||
<string name="summary_language_list">Idioma a usar por Moonlight</string>
|
||||
<string name="title_checkbox_small_icon_mode">Usar iconos pequeños</string>
|
||||
<string name="summary_checkbox_small_icon_mode">Usar iconos pequeños en las entradas de cuadrículas para permitir más entradas en la pantalla</string>
|
||||
|
||||
<string name="category_host_settings">Configuración de servidor</string>
|
||||
<string name="title_checkbox_enable_sops">Optimizar configuración del juego</string>
|
||||
<string name="summary_checkbox_enable_sops">Permitir que GFE modifique la configuración del juego para una transmisión óptima</string>
|
||||
<string name="title_checkbox_host_audio">Reproducir audio en PC</string>
|
||||
<string name="summary_checkbox_host_audio">Reproducir audio en el ordenador y en este dispositivo</string>
|
||||
|
||||
<string name="category_advanced_settings">Configuración avanzada</string>
|
||||
<string name="title_video_format">Cambiar configuración H.265</string>
|
||||
<string name="summary_video_format">H.265 reduce el ancho de banda de vídeo, pero requiere un dispositivo bastante actual.</string>
|
||||
|
||||
</resources>
|
||||
<string name="title_video_format">Cambiar configuración HEVC</string>
|
||||
<string name="summary_video_format">HEVC reduce el ancho de banda de vídeo, pero requiere un dispositivo reciente</string>
|
||||
<!-- Array strings -->
|
||||
<string name="videoformat_hevcauto">Usar HEVC sólo si es estable</string>
|
||||
<string name="videoformat_hevcalways">Siempre usar HEVC (puede fallar)</string>
|
||||
<string name="videoformat_hevcnever">Nunca usar HEVC</string>
|
||||
<string name="nettest_title_done">Prueba de Red Completada</string>
|
||||
<string name="scut_not_paired">PC no emparejado</string>
|
||||
<string name="scut_invalid_uuid">El PC proporcionado no es válido</string>
|
||||
<string name="scut_invalid_app_id">La App proporcionada no es válida</string>
|
||||
<string name="help_loading_title">Visor de ayuda</string>
|
||||
<string name="pcview_menu_header_online">En línea</string>
|
||||
<string name="pcview_menu_header_unknown">Actualizando</string>
|
||||
<string name="pcview_menu_test_network">Probar Conexión de Red</string>
|
||||
<string name="pcview_menu_details">Ver Detalles</string>
|
||||
<string name="nettest_title_waiting">Probando Conexión de Red</string>
|
||||
<string name="nettest_text_waiting">Moonlight esta probando tu conexión de red para determinar si NVIDIA GameStream esta bloqueado.
|
||||
\n
|
||||
\nEsto puede tomar algunos segundos …</string>
|
||||
<string name="nettest_text_inconclusive">La prueba de red no pudo ejecutarse debido a que no se pudo alcanzar ningún servidor de prueba de conexión de Moonlight. Revisa tu conexión a internet o prueba nuevamente mas tarde.</string>
|
||||
<string name="nettest_text_failure">La actual conexión de red de tu dispositivo parece estar bloqueando Moonlight. La Transmisión mediante Internet puede no funcionar mientras estes conectado a esta red.
|
||||
\n
|
||||
\nSe han bloqueado los siguientes puertos de red:
|
||||
\n</string>
|
||||
<string name="title_decoding_error">Falló el Decodificador de Video</string>
|
||||
<string name="scut_deleted_pc">PC eliminado</string>
|
||||
<string name="scut_pc_not_found">PC no encontrado</string>
|
||||
<string name="help_loading_msg">Cargando página de ayuda…</string>
|
||||
<string name="pcview_menu_header_offline">Fuera de línea</string>
|
||||
<string name="nettest_text_success">Tu red parece no estar bloqueando Moonlight. Si aun tienes problemas de conexión, comprueba la configuración del firewall de tu PC.
|
||||
\n
|
||||
\nSi estas intentado transmitir mediante Internet, instala en tu pc la Moonlight Internet Hosting Tool y ejecuta el Internet Streaming Tester incluido para comprobar la conexión de tu PC a internet.</string>
|
||||
<string name="nettest_text_blocked">La conexión de red actual de tu dispositivo esta bloqueando Moonlight. La Transmisión mediante Internet puede no funcionar mientras estés conectado a esta red.</string>
|
||||
<string name="pair_already_in_progress">Emparejamiento ya en progreso</string>
|
||||
<string name="resolution_prefix_native_fullscreen">Pantalla Completa Nativa</string>
|
||||
<string name="title_audio_config_list">Configuración de Sonido Envolvente</string>
|
||||
<string name="title_decoding_reset">Reiniciar Opciones de Video</string>
|
||||
<string name="no_video_received_error">No se recibe video desde el equipo anfitrión.</string>
|
||||
<string name="applist_details_id">ID de Aplicación:</string>
|
||||
<string name="title_checkbox_mouse_emulation">Emulación de ratón usando el mando</string>
|
||||
<string name="pacing_latency">Preferir la menor latencia posible</string>
|
||||
<string name="pacing_balanced">Equilibrado</string>
|
||||
<string name="pacing_smoothness">Preferir mayor fluidez de video (puede incrementar significativamente la latencia)</string>
|
||||
<string name="perf_overlay_decoder">Decodificador: %1$s</string>
|
||||
<string name="perf_overlay_incomingfps">Tasa de cuadros obtenida de la red: %1$.2f FPS</string>
|
||||
<string name="perf_overlay_renderingfps">Tasa de Cuadros Renderizada: %1$.2f FPS</string>
|
||||
<string name="perf_overlay_netdrops">Cuadros perdidos por tu conexión de internet: %1$.2f%%</string>
|
||||
<string name="perf_overlay_netlatency">Latencia promedio de red:%1$d ms (variación: %2$d ms)</string>
|
||||
<string name="perf_overlay_dectime">Tiempo promedio de descodificado: %1$.2f ms</string>
|
||||
<string name="perf_overlay_streamdetails">Transmisión video: %1$s %2$.2f FPS</string>
|
||||
<string name="title_fps_list">Tasa de cuadros en el video</string>
|
||||
<string name="summary_fps_list">Incrementar para una experiencia mas fluida en la transmisión. Disminuir para una mejoría en el rendimiento en dispositivos de gama de entrada.</string>
|
||||
<string name="summary_reset_osc">Reiniciar toda la configuración a las predeterminadas de tamaño y posición para los controles en pantalla</string>
|
||||
<string name="summary_troubleshooting">Mostrar consejos para diagnosticar y corregir errores comunes respecto a la transmisión</string>
|
||||
<string name="title_privacy_policy">Política de Privacidad</string>
|
||||
<string name="resolution_360p">360p</string>
|
||||
<string name="resolution_1440p">1440p</string>
|
||||
<string name="resolution_4k">4K</string>
|
||||
<string name="suffix_osc_opacity">%</string>
|
||||
<string name="title_checkbox_enable_pip">Actividad modo Pantalla-en-Pantalla para observador</string>
|
||||
<string name="resolution_720p">720p</string>
|
||||
<string name="fps_120">120 FPS</string>
|
||||
<string name="audioconf_71surround">7.1 Sonido Envolvente</string>
|
||||
<string name="title_troubleshooting">Guía de Solución de Errores</string>
|
||||
<string name="resolution_1080p">1080p</string>
|
||||
<string name="summary_frame_pacing">Especificar como balancear la latencia de video y la fluidez</string>
|
||||
<string name="pacing_balanced_alt">Equilibrado con limitador de FPS (Cuadros por Segundo)</string>
|
||||
<string name="audioconf_51surround">5.1 Sonido Envolvente</string>
|
||||
<string name="audioconf_stereo">Estéreo</string>
|
||||
<string name="check_ports_msg">Revisa la configuración de tu firewall, así como, las reglas de redireccionamiento para él(los) puerto(s):</string>
|
||||
<string name="error_usb_prohibited">El acceso a USB está restringido en tu dispositivo por el administrador. Revisar tus ajustes en MDM o Knox.</string>
|
||||
<string name="message_decoding_error">Moonlight se ha cerrado debido a una incompatibilidad con el decodificador de vídeo de este dispositivo. Asegúrate de que GeForce Experience está actualizado a la última versión en tu PC. Intenta ajustar la configuración de streaming si los bloqueos continúan.</string>
|
||||
<string name="message_decoding_reset">La decodificación de video de tu equipo sigue fallando con las opciones elegidas. Las opciones de la transmisión han sido revertidas a las predeterminadas.</string>
|
||||
<string name="video_decoder_init_failed">El descodificador de video no pudo ser iniciado. Tu dispositivo puede no soportar la resolución elegida o la tasa de cuadros por segundo.</string>
|
||||
<string name="no_frame_received_error">La conexión de internet no está teniendo un buen desempeño. Reduce la tasa de bits de video o prueba en una conexión de mayor velocidad.</string>
|
||||
<string name="unable_to_pin_shortcut">Tu lanzador predeterminado no permite la creación de accesos directos anclados.</string>
|
||||
<string name="early_termination_error">Algo ha salido mal en el PC anfitrión cuando se inicio la transmisión.
|
||||
\n
|
||||
\nVerifica que no tengas ningún contenido protegido por DRM abierto en el equipo. También prueba reiniciando el equipo anfitrión.
|
||||
\n
|
||||
\nSi el problema persiste, intenta reinstalar los controladores de la tarjeta de video (GPU) además de GeForce Experience.</string>
|
||||
<string name="title_details">Detalles</string>
|
||||
<string name="poor_connection_msg">Conexión pobre al PC</string>
|
||||
<string name="applist_menu_details">Ver Detalles</string>
|
||||
<string name="applist_menu_scut">Crear Acceso Directo</string>
|
||||
<string name="applist_menu_tv_channel">Agregar al Canal</string>
|
||||
<string name="applist_menu_hide_app">Esconder Aplicación</string>
|
||||
<string name="applist_connect_msg">Conectando al Equipo…</string>
|
||||
<string name="summary_checkbox_mouse_nav_buttons">Activar esta opción puede desconfigurar la función de clic derecho en algunos dispositivos inestables</string>
|
||||
<string name="text_native_res_dialog">Modos de resolución nativa no son oficialmente soportados por GeForce Experience, así que no se no se aplicarán por su cuenta en la pantalla del equipo anfitrión. Vas a necesitar ajustarlos manualmente en el juego.
|
||||
\n
|
||||
\nSi eliges crear una resolución personalizada en el Panel de Control de Nvidia para ajustarse a la resolución de tu dispositivo, por favor considera haber leído y entendido la advertencia de NVIDIA respectivo a cualquier daño posible a tu monitor, inestabilidad del equipo, y otros problemas potencialmente posibles.
|
||||
\n
|
||||
\nNo somos responsables de cualquier problema por haber creador una resolución personalizada en tu PC.
|
||||
\n
|
||||
\nFinalmente, tu dispositivo o tu Pc anfitrión, podrían no soportar la transmisión a resolución nativa. Si no funciona en tu equipo, puede que solo no tengas suerte de momento.</string>
|
||||
<string name="resolution_prefix_native">Nativo</string>
|
||||
<string name="summary_audio_config_list">Activar sonido envolvente de 5.1 o 7.1 canales para sistemas de teatro en casa</string>
|
||||
<string name="title_checkbox_vibrate_fallback">Emular la vibración del mando con vibración del equipo</string>
|
||||
<string name="summary_checkbox_enable_audiofx">Permitir funcionar efectos de sonido durante la transmisión, pero podría incrementar la latencia del sonido</string>
|
||||
<string name="summary_checkbox_usb_bind_all">Usar el controlador de USB de Moonlight para todos los mandos soportados, incluso si el control de Xbox se encuentra presente</string>
|
||||
<string name="summary_checkbox_mouse_emulation">Presionar por un periodo largo el botón de inicio hará cambiar el mando a modo de ratón</string>
|
||||
<string name="title_checkbox_mouse_nav_buttons">Activar los botones atrás y adelante del ratón</string>
|
||||
<string name="title_unlock_fps">Desbloquear todas las opciones de tasa de cuadros disponibles</string>
|
||||
<string name="summary_unlock_fps">Transmitir a 90 o 120 FPS puede reducir latencia en dispositivos de gama alta pero puede causar retrasos en dispositivos que no lo soporten</string>
|
||||
<string name="title_enable_perf_overlay">Mostrar estadísticas de rendimiento mientras la transmisión está activa</string>
|
||||
<string name="summary_enable_post_stream_toast">Mostrar un mensaje sobre la información de latencia cuando la transmisión termine</string>
|
||||
<string name="help">Ayuda</string>
|
||||
<string name="delete_pc_msg">¿Estás seguro de eliminar este PC\?</string>
|
||||
<string name="slow_connection_msg">Conexión lenta al PC
|
||||
\nReduce la tasa de bits</string>
|
||||
<string name="addpc_wrong_sitelocal">La dirección no luce correcta. Debes usar la dirección IP Pública de tu Rúter para la transmisión por Internet.</string>
|
||||
<string name="title_native_res_dialog">Advertencia Resolución Nativa</string>
|
||||
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
|
||||
<string name="category_input_settings">Opciones de Entrada</string>
|
||||
<string name="title_checkbox_touchscreen_trackpad">Usa la pantalla táctil como panel táctil</string>
|
||||
<string name="summary_checkbox_touchscreen_trackpad">Si está activo, la pantalla táctil funcionará como panel táctil. Si está desactivado, la pantalla táctil directamente controlará el cursor del ratón.</string>
|
||||
<string name="summary_seekbar_deadzone">Nota: Algunos juegos pueden forzar una zona muerta mayor a la que Moonlight esta configurada a usar.</string>
|
||||
<string name="title_checkbox_flip_face_buttons">Invertir botones frontales</string>
|
||||
<string name="summary_checkbox_absolute_mouse_mode">Esto puede hacer que la aceleración de mouse se comporte mas natural para uso de escritorio remoto, pero es incompatible con muchos juegos.</string>
|
||||
<string name="title_checkbox_enable_audiofx">Activar el soporte para ecualizador de sistema</string>
|
||||
<string name="summary_checkbox_vibrate_fallback">Vibrar el dispositivo para emular el retumbe si tu mando de control no lo soporta</string>
|
||||
<string name="title_checkbox_usb_bind_all">Sobrescribir el soporte nativo del control de Xbox</string>
|
||||
<string name="summary_checkbox_flip_face_buttons">Invertir botones frontales A/B y X/Y para los mandos y los botones sobre la pantalla</string>
|
||||
<string name="title_checkbox_absolute_mouse_mode">Modo de ratón para escritorio remoto</string>
|
||||
<string name="title_checkbox_vibrate_osc">Activar vibración</string>
|
||||
<string name="summary_checkbox_vibrate_osc">Hacer vibrar tu dispositivo para emular la vibración del juego para los controles en pantalla</string>
|
||||
<string name="title_reset_osc">Borrar la configuración guardada de la plantilla para el control en pantalla</string>
|
||||
<string name="dialog_title_reset_osc">Reiniciar a Plantilla Predeterminada</string>
|
||||
<string name="dialog_text_reset_osc">¿Estás seguro de que quieres eliminar tus configuraciones guardadas para las plantillas de los controles en pantalla\?</string>
|
||||
<string name="toast_reset_osc_success">Establecer Controles en Pantalla en modo Predeterminado</string>
|
||||
<string name="title_osc_opacity">Cambiar la transparencia de los controles en pantalla</string>
|
||||
<string name="summary_osc_opacity">Hacer los controles en pantalla más/menos transparentes</string>
|
||||
<string name="dialog_title_osc_opacity">Cambiar opacidad</string>
|
||||
<string name="summary_checkbox_enable_pip">Permite que la transmisión sea vista (pero no controlable) mientras se usa la multitarea</string>
|
||||
<string name="title_disable_frame_drop">Nunca disminuir cuadros</string>
|
||||
<string name="summary_disable_frame_drop">Puede reducir micro-tartamudeos (Stuttering) en algunos dispositivos , pero puede incrementar latencia</string>
|
||||
<string name="title_enable_hdr">Activar HDR (Alto Rango Dinámico / Experimental)</string>
|
||||
<string name="summary_enable_hdr">Transmitir HDR (Alto Rango Dinámico) cuando el juego, el PC y la Tarjeta de Video (GPU) lo soporten. HDR requiere de una Tarjeta de Video de la serie GTX 1000 o superior.</string>
|
||||
<string name="summary_enable_perf_overlay">Mostrar en tiempo real la información del desempeño de la transmisión mientras está activa la misma</string>
|
||||
<string name="title_enable_post_stream_toast">Mostrar mensajes sobre latencia mientras se transmite</string>
|
||||
<string name="category_help">Ayuda</string>
|
||||
<string name="title_setup_guide">Guía para la Configuración</string>
|
||||
<string name="summary_setup_guide">Mostrar instrucciones para como configurar tu PC para juegos para la transmisión</string>
|
||||
<string name="summary_privacy_policy">Mostrar la política de privacidad de Moonlight</string>
|
||||
<string name="resolution_480p">480p</string>
|
||||
<string name="fps_30">30 FPS</string>
|
||||
<string name="fps_60">60 FPS</string>
|
||||
<string name="fps_90">90 FPS</string>
|
||||
<string name="title_frame_pacing">Ritmo de cuadros por segundo en video</string>
|
||||
</resources>
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="fps_names">
|
||||
<item>30 IPS</item>
|
||||
<item>60 IPS</item>
|
||||
<item>90 IPS</item>
|
||||
<item>120 IPS</item>
|
||||
</string-array>
|
||||
<string-array name="audio_config_names">
|
||||
<item>Stéréo</item>
|
||||
<item>Son surround 5.1</item>
|
||||
<item>Son surround 7.1</item>
|
||||
</string-array>
|
||||
<string-array name="decoder_names">
|
||||
<item>Sélection automatique du décodeur</item>
|
||||
<item>Contraindre le décodage logiciel</item>
|
||||
<item>Contraindre le décodage matériel</item>
|
||||
</string-array>
|
||||
<string-array name="video_format_names">
|
||||
<item>Utiliser H.265 uniquement s\'il est stable</item>
|
||||
<item>Utilisez toujours H.265 (mais il peut planter)</item>
|
||||
<item>N\'utilisez jamais H.265</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -88,14 +88,11 @@
|
||||
<string name="delete_pc_msg">Êtes-vous sûr de vouloir supprimer ce PC \?</string>
|
||||
<string name="slow_connection_msg">Connexion lente au PC\nRéduisez votre débit</string>
|
||||
<string name="poor_connection_msg">Mauvaise connexion au PC</string>
|
||||
<string name="perf_overlay_text">Dimensions vidéo : %1$s
|
||||
\nDécodeur : %2$s
|
||||
\nEstimation de la fréquence d\'images de l\'ordinateur hôte : %3$.2f FPS
|
||||
\nFréquence d\'images entrantes du réseau : %4$.2f FPS
|
||||
\nFréquence d\'images de rendu : %5$.2f FPS
|
||||
\nImages perdues par votre connexion réseau : %6$.2f%%
|
||||
\nTemps moyen de réception : %7$.2f ms
|
||||
\nTemps moyen de décodage : %8$.2f ms</string>
|
||||
<string name="perf_overlay_decoder">Décodeur : %1$s</string>
|
||||
<string name="perf_overlay_incomingfps">Fréquence d\'images entrantes du réseau : %1$.2f FPS</string>
|
||||
<string name="perf_overlay_renderingfps">Fréquence d\'images de rendu : %1$.2f FPS</string>
|
||||
<string name="perf_overlay_netdrops">Images perdues par votre connexion réseau : %1$.2f%%</string>
|
||||
<string name="perf_overlay_dectime">Temps moyen de décodage : %1$.2f ms</string>
|
||||
<!-- AppList activity -->
|
||||
<string name="applist_connect_msg">Connexion au PC…</string>
|
||||
<string name="applist_menu_resume">Reprise de la session</string>
|
||||
@@ -188,8 +185,8 @@
|
||||
<string name="summary_checkbox_disable_warnings">Désactiver les messages d\'avertissement de connexion à l\'écran pendant la diffusion</string>
|
||||
<string name="title_disable_frame_drop">Ne jamais laisser tomber les frames</string>
|
||||
<string name="summary_disable_frame_drop">Peut réduire les micro-saccades sur certains appareils, mais peut augmenter la latence</string>
|
||||
<string name="title_video_format">Modifier les paramètres H.265</string>
|
||||
<string name="summary_video_format">H.265 réduit les besoins en bande passante vidéo mais nécessite un périphérique très récent</string>
|
||||
<string name="title_video_format">Modifier les paramètres HEVC</string>
|
||||
<string name="summary_video_format">HEVC réduit les besoins en bande passante vidéo mais nécessite un périphérique très récent</string>
|
||||
<string name="title_enable_hdr">Activer le HDR (expérimental)</string>
|
||||
<string name="summary_enable_hdr">Diffuser du HDR lorsque le jeu et le processeur graphique du PC le prennent en charge. HDR nécessite un GPU série GTX 1000 ou une version ultérieure.</string>
|
||||
<string name="title_enable_perf_overlay">Activer la superposition de performance</string>
|
||||
@@ -220,4 +217,40 @@
|
||||
\n
|
||||
\nSi le problème persiste, essayez de réinstaller les pilotes de votre GPU ainsi que GeForce Experience.</string>
|
||||
<string name="no_frame_received_error">Votre connexion ne fonctionne pas bien. Baissez votre paramètres de débit ou utilisez une connexion plus rapide.</string>
|
||||
<string name="resolution_prefix_native_fullscreen">Plein-écran natif</string>
|
||||
<string name="perf_overlay_netlatency">Latence réseau moyenne : %1$d ms (variance : %2$d ms)</string>
|
||||
<string name="perf_overlay_streamdetails">Stream vidéo : %1$s %2$.2f FPS</string>
|
||||
<!-- Array strings -->
|
||||
<string name="fps_30">30 IPS</string>
|
||||
<string name="fps_60">60 IPS</string>
|
||||
<string name="fps_90">90 IPS</string>
|
||||
<string name="fps_120">120 IPS</string>
|
||||
<string name="audioconf_stereo">Stéréo</string>
|
||||
<string name="audioconf_51surround">Son surround 5.1</string>
|
||||
<string name="audioconf_71surround">Son surround 7.1</string>
|
||||
<string name="videoformat_hevcauto">Automatique</string>
|
||||
<string name="videoformat_hevcalways">Utilisez toujours HEVC (mais il peut planter)</string>
|
||||
<string name="videoformat_hevcnever">N\'utilisez jamais HEVC</string>
|
||||
<string name="title_frame_pacing">Frame-pacing vidéo</string>
|
||||
<string name="summary_frame_pacing">Spécifiez comment équilibrer latence et fluidité de la vidéo</string>
|
||||
<string name="pacing_latency">Préférer une latence plus faible</string>
|
||||
<string name="pacing_balanced">Équilibré</string>
|
||||
<string name="resolution_720p">720p</string>
|
||||
<string name="pacing_smoothness">Préférer la qualité vidéo (risque d\'augmenter la latence)</string>
|
||||
<string name="resolution_360p">360p</string>
|
||||
<string name="resolution_480p">480p</string>
|
||||
<string name="resolution_1440p">1440p</string>
|
||||
<string name="resolution_1080p">1080p</string>
|
||||
<string name="resolution_4k">4K</string>
|
||||
<string name="category_help">Aide</string>
|
||||
<string name="title_setup_guide">Guide de configuration</string>
|
||||
<string name="title_troubleshooting">Guide de dépannage</string>
|
||||
<string name="title_privacy_policy">Politique de confidentialité</string>
|
||||
<string name="summary_privacy_policy">Voir la politique de confidentialité de Moonlight</string>
|
||||
<string name="summary_setup_guide">Afficher les instructions sur la façon de configurer votre PC de jeu pour le streaming</string>
|
||||
<string name="summary_troubleshooting">Afficher des conseils pour diagnostiquer et résoudre les problèmes de streaming courants</string>
|
||||
<string name="pacing_balanced_alt">Équilibré avec limite FPS</string>
|
||||
<string name="title_checkbox_absolute_mouse_mode">Mode souris pour bureau à distance</string>
|
||||
<string name="summary_seekbar_deadzone">Remarque : Certains jeux peuvent imposer une zone morte plus grande que celle que Moonlight est configuré pour utiliser.</string>
|
||||
<string name="summary_checkbox_absolute_mouse_mode">Cela peut rendre l\'accélération de la souris plus naturelle pour l\'utilisation du bureau à distance, mais elle est incompatible avec de nombreux jeux.</string>
|
||||
</resources>
|
||||
210
app/src/main/res/values-hu/strings.xml
Normal file
210
app/src/main/res/values-hu/strings.xml
Normal file
@@ -0,0 +1,210 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="summary_enable_post_stream_toast">Késleltetési információs üzenet megjelenítése az adatfolyam vége után</string>
|
||||
<string name="title_enable_post_stream_toast">A késleltetési üzenet megjelenítése streaming után</string>
|
||||
<string name="summary_enable_perf_overlay">Valós idejű adatfolyam-adat megjelenítése streaming közben</string>
|
||||
<string name="title_enable_perf_overlay">Teljesítmény statisztikák megjelenítése közvetítés közben</string>
|
||||
<string name="summary_enable_hdr">Streaming HDR, amikor a játék és a PC GPU támogatja. A HDR-hez GTX 1000 sorozatú vagy újabb verzió szükséges.</string>
|
||||
<string name="title_enable_hdr">HDR engedélyezése (kísérleti)</string>
|
||||
<string name="summary_video_format">A HEVC csökkenti a video sávszélesség követelményeit, de újabb eszközt igényel</string>
|
||||
<string name="title_video_format">Módosítsa a HEVC beállításait</string>
|
||||
<string name="summary_disable_frame_drop">Csökkentheti a mikrodadogást egyes eszközökön, de növelheti a késést</string>
|
||||
<string name="title_disable_frame_drop">Soha ne ejtse le a kereteket</string>
|
||||
<string name="summary_checkbox_disable_warnings">Streaming közben tiltsa le a képernyőn megjelenő csatlakozási figyelmeztető üzeneteket</string>
|
||||
<string name="title_checkbox_disable_warnings">Tiltsa le a figyelmeztető üzeneteket</string>
|
||||
<string name="summary_unlock_fps">A 90 vagy 120 FPS sebességgel történő streaming csökkentheti a csúcskategóriás eszközök késését, de késést vagy instabilitást okozhat azokon az eszközökön, amelyek ezt nem támogatják</string>
|
||||
<string name="title_unlock_fps">Oldja fel az összes lehetséges képsebességet</string>
|
||||
<string name="category_advanced_settings">További beállítások</string>
|
||||
<string name="summary_checkbox_host_audio">Hang lejátszása a számítógépről és az eszközről</string>
|
||||
<string name="title_checkbox_host_audio">Hang lejátszása PC-n</string>
|
||||
<string name="summary_checkbox_enable_sops">Engedje meg, hogy a GFE módosítsa a játék beállításait az optimális streaming érdekében</string>
|
||||
<string name="title_checkbox_enable_sops">Optimalizálja a játék beállításait</string>
|
||||
<string name="category_host_settings">Gazdabeállítások</string>
|
||||
<string name="summary_checkbox_small_icon_mode">Az alkalmazásrács kisebbik rajza lehetővé teszi, hogy több alkalmazás is látható legyen a képernyőn</string>
|
||||
<string name="title_checkbox_small_icon_mode">Használjon kis dobozos rajzokat</string>
|
||||
<string name="summary_language_list">A Moonlight-hoz használt nyelv</string>
|
||||
<string name="title_language_list">Nyelv</string>
|
||||
<string name="summary_checkbox_enable_pip">Lehetővé teszi az adatfolyam megtekintését (de nem vezérlését) multitasking közben</string>
|
||||
<string name="title_checkbox_enable_pip">Engedélyezze a Kép a képben megfigyelő módot</string>
|
||||
<string name="category_ui_settings">Felhasználói felület beállításai</string>
|
||||
<string name="suffix_osc_opacity">%</string>
|
||||
<string name="dialog_title_osc_opacity">Opacitás módosítása</string>
|
||||
<string name="summary_osc_opacity">Tegye többé-kevésbé átláthatóvá a képernyőn megjelenő vezérlőket</string>
|
||||
<string name="title_osc_opacity">A képernyőn megjelenő vezérlők átlátszatlanságának módosítása</string>
|
||||
<string name="toast_reset_osc_success">A képernyőn megjelenő vezérlők visszaállnak az alapértelmezettre</string>
|
||||
<string name="dialog_text_reset_osc">Biztosan törli a képernyőn tárolt vezérlők mentett elrendezését\?</string>
|
||||
<string name="dialog_title_reset_osc">Reset Layout</string>
|
||||
<string name="summary_reset_osc">Visszaállítja az összes képernyőn megjelenő vezérlőt az alapértelmezett méretre és helyzetre</string>
|
||||
<string name="title_reset_osc">A képernyőn lévő mentett vezérlők elrendezésének törlése</string>
|
||||
<string name="summary_only_l3r3">Az összes virtuális gombot elrejti az L3 és R3 kivételével</string>
|
||||
<string name="title_only_l3r3">Csak az L3-at és az R3-at mutatják</string>
|
||||
<string name="summary_checkbox_vibrate_osc">Rezeg a készülék, hogy utánozza a képernyőn megjelenő vezérlők zúgását</string>
|
||||
<string name="title_checkbox_vibrate_osc">Rezgés engedélyezése</string>
|
||||
<string name="summary_checkbox_show_onscreen_controls">A virtuális vezérlő fedvényének megjelenítése az érintőképernyőn</string>
|
||||
<string name="title_checkbox_show_onscreen_controls">A képernyőn megjelenő vezérlők megjelenítése</string>
|
||||
<string name="category_on_screen_controls_settings">A képernyőn megjelenő vezérlők beállításai</string>
|
||||
<string name="summary_checkbox_flip_face_buttons">Átkapcsolja az A / B és X / Y arcgombokat a játékvezérlőkhöz és a képernyőn megjelenő vezérlőkhöz</string>
|
||||
<string name="title_checkbox_flip_face_buttons">Flip face gombok</string>
|
||||
<string name="summary_checkbox_mouse_nav_buttons">Ennek az opciónak az engedélyezése megszakíthatja a jobb egérgombbal való kattintást néhány hibás eszközön</string>
|
||||
<string name="title_checkbox_mouse_nav_buttons">Engedélyezze az előre és hátra gombokat</string>
|
||||
<string name="summary_checkbox_mouse_emulation">A Start gomb hosszan tartó megnyomásával egér üzemmódba kapcsol a játéktábla</string>
|
||||
<string name="title_checkbox_mouse_emulation">Egér emuláció a játékvezérlőn keresztül</string>
|
||||
<string name="summary_checkbox_usb_bind_all">Használja a Moonlight USB-illesztőprogramját az összes támogatott játékvezérlőhöz, még akkor is, ha natív Xbox vezérlő támogatás van jelen</string>
|
||||
<string name="title_checkbox_usb_bind_all">Az natív Xbox játéktámogatás felülbírálása</string>
|
||||
<string name="summary_checkbox_xb1_driver">Beépített USB-illesztőprogramot engedélyez natív Xbox vezérlő támogatás nélküli eszközökhöz</string>
|
||||
<string name="title_checkbox_xb1_driver">Xbox 360 / One USB játékvezérlő</string>
|
||||
<string name="suffix_seekbar_deadzone">%</string>
|
||||
<string name="title_seekbar_deadzone">Állítsa be az analóg bot holtzónáját</string>
|
||||
<string name="summary_checkbox_vibrate_fallback">Rezeg a készülék, hogy utánozza a dübörgést, ha a gamepad nem támogatja</string>
|
||||
<string name="title_checkbox_vibrate_fallback">A dübörgés támogatását rezgéssel utánozzuk</string>
|
||||
<string name="summary_checkbox_multi_controller">Ennek az opciónak a bejelölése arra kényszeríti a játéktáblát, hogy mindig jelen legyen</string>
|
||||
<string name="title_checkbox_multi_controller">Automatikus gamepad jelenlét-észlelés</string>
|
||||
<string name="summary_checkbox_touchscreen_trackpad">Ha engedélyezve van, az érintőképernyő úgy működik, mint egy trackpad. Ha le van tiltva, az érintőképernyő közvetlenül vezérli az egér kurzort.</string>
|
||||
<string name="title_checkbox_touchscreen_trackpad">Használja az érintőképernyőt trackpadként</string>
|
||||
<string name="category_input_settings">Bemeneti beállítások</string>
|
||||
<string name="summary_audio_config_list">Engedélyezze az 5.1 vagy 7.1 térhatású hangot házimozi rendszerekhez</string>
|
||||
<string name="title_audio_config_list">Térhatású hang konfigurációja</string>
|
||||
<string name="resolution_prefix_native">Natív</string>
|
||||
<string name="category_audio_settings">Hangbeállítások</string>
|
||||
<string name="title_checkbox_stretch_video">Nyújtsa a videót teljes képernyősre</string>
|
||||
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
|
||||
<string name="summary_seekbar_bitrate">Növelje a jobb képminőség érdekében. Csökkenjen a lassabb kapcsolatok teljesítményének javítása érdekében.</string>
|
||||
<string name="title_seekbar_bitrate">Videó bitráta</string>
|
||||
<string name="summary_fps_list">Növelje a gördülékenyebb videofolyamot. Csökkenjen a jobb teljesítmény érdekében az alsó kategóriás eszközökön.</string>
|
||||
<string name="title_fps_list">Videó képkockasebessége</string>
|
||||
<string name="text_native_res_dialog">A natív felbontási módokat a GeForce Experience hivatalosan nem támogatja, így maga nem állítja be a gazdagép kijelzőjének felbontását. A játék során manuálisan kell beállítania.
|
||||
\n
|
||||
\nHa úgy dönt, hogy az NVIDIA vezérlőpultján egyedi felbontást hoz létre, hogy megfeleljen az eszköz felbontásának, kérjük, olvassa el és értette az NVIDIA figyelmeztetéseit a monitor esetleges károsodásával, a számítógép instabilitásával és más lehetséges problémákkal kapcsolatban.
|
||||
\n
|
||||
\nNem vagyunk felelősek a PC-n egyedi felbontás létrehozásából eredő problémákért.
|
||||
\n
|
||||
\nVégül előfordulhat, hogy az eszköz vagy a fogadó PC nem támogatja a natív felbontású adatfolyamot. Ha a készülékén nem működik, sajnos csak nincs szerencséje.</string>
|
||||
<string name="title_native_res_dialog">Natív felbontás figyelmeztetés</string>
|
||||
<string name="summary_resolution_list">Növelje a kép tisztaságának növelése érdekében. Csökkenjen a jobb teljesítmény érdekében az alsó kategóriás eszközökön és a lassabb hálózatokon.</string>
|
||||
<string name="title_resolution_list">Videó felbontás</string>
|
||||
<string name="category_basic_settings">Alapbeállítások</string>
|
||||
<string name="addpc_wrong_sitelocal">Ez a cím nem tűnik megfelelőnek. Az interneten történő streaminghez az PCnyilvános IP-címét kell használnia.</string>
|
||||
<string name="addpc_enter_ip">Meg kell adnia egy IP-címet</string>
|
||||
<string name="addpc_unknown_host">Nem sikerült feloldani a PC-címet. Győződjön meg arról, hogy nem hibázott a címben.</string>
|
||||
<string name="addpc_success">A számítógép sikeresen hozzáadva</string>
|
||||
<string name="addpc_fail">Nem sikerült csatlakozni a megadott számítógéphez. Győződjön meg arról, hogy a szükséges portok engedélyezve vannak a tűzfalon keresztül.</string>
|
||||
<string name="msg_add_pc">Csatlakozás a számítógéphez…</string>
|
||||
<string name="title_add_pc">Számítógép hozzáadása manuálisan</string>
|
||||
<string name="applist_details_id">Alkalmazásazonosító:</string>
|
||||
<string name="applist_quit_confirmation">Biztosan kilép a futó alkalmazásból\? Minden nem mentett adat elvész.</string>
|
||||
<string name="applist_quit_fail">Nem sikerült kilépni</string>
|
||||
<string name="applist_quit_success">Sikeresen kiléptél</string>
|
||||
<string name="applist_quit_app">Kilépés</string>
|
||||
<string name="applist_refresh_error_msg">Nem sikerült betölteni az alkalmazások listáját</string>
|
||||
<string name="applist_refresh_error_title">Hiba</string>
|
||||
<string name="applist_refresh_msg">Alkalmazás lista frissítése…</string>
|
||||
<string name="applist_refresh_title">Alkalmazás lista</string>
|
||||
<string name="applist_menu_quit">Kilépés a játékból</string>
|
||||
<string name="applist_menu_resume">Visszalépés a játékba</string>
|
||||
<string name="applist_menu_hide_app">Alkalmazás elrejtése</string>
|
||||
<string name="applist_menu_tv_channel">Hozzáadás a csatornához</string>
|
||||
<string name="applist_menu_scut">Parancsikon létrehozása</string>
|
||||
<string name="applist_menu_details">Részletek megtekintése</string>
|
||||
<string name="applist_menu_cancel">Mégse</string>
|
||||
<string name="applist_menu_quit_and_start">Lépjen ki az aktuális játékból és indítsa el</string>
|
||||
<string name="applist_connect_msg">Csatlakozás a számítógéphez…</string>
|
||||
<string name="perf_overlay_dectime">Átlagos dekódolási idő:%1$.2f ms</string>
|
||||
<string name="perf_overlay_netlatency">Átlagos hálózati késés:%1$d ms (szórás:%2$d ms)</string>
|
||||
<string name="perf_overlay_netdrops">A hálózati kapcsolat miatt elesett keretek:%1$.2f%%</string>
|
||||
<string name="perf_overlay_renderingfps">Képkockasebesség megjelenítése:%1$.2f FPS</string>
|
||||
<string name="perf_overlay_incomingfps">Bejövő képkockasebesség a hálózatról:%1$.2f FPS</string>
|
||||
<string name="perf_overlay_decoder">Dekóder:%1$s</string>
|
||||
<string name="perf_overlay_streamdetails">Videófolyam:%1$s %2$.2f FPS</string>
|
||||
<string name="poor_connection_msg">Gyenge kapcsolat a PC-vel</string>
|
||||
<string name="slow_connection_msg">Lassú kapcsolat a PC-vel
|
||||
\nCsökkentse a bitrátát</string>
|
||||
<string name="delete_pc_msg">Biztosan törli ezt a számítógépet\?</string>
|
||||
<string name="help">Segítség</string>
|
||||
<string name="title_details">Részletek</string>
|
||||
<string name="lost_connection">Megszakadt a kapcsolat a PC-vel</string>
|
||||
<string name="no">Nem</string>
|
||||
<string name="yes">Igen</string>
|
||||
<string name="searching_pc">PC-k keresése futó GameStream segítségével ...
|
||||
\n
|
||||
\n Győződjön meg arról, hogy a GameStream engedélyezve van a GeForce Experience SHIELD beállításaiban.</string>
|
||||
<string name="ip_hint">A GeForce PC IP-címe</string>
|
||||
<string name="conn_terminated_msg">A kapcsolat megszakadt</string>
|
||||
<string name="conn_terminated_title">A kapcsolat megszűnt</string>
|
||||
<string name="conn_error_msg">Nem sikerült elindítani</string>
|
||||
<string name="conn_client_latency_hw">hardveres dekóder késleltetése:</string>
|
||||
<string name="conn_client_latency">Átlagos keret dekódolási késés:</string>
|
||||
<string name="conn_metered">Figyelem: Az aktív hálózati kapcsolatod mérésre került!</string>
|
||||
<string name="conn_establishing_msg">Kapcsolódás</string>
|
||||
<string name="conn_establishing_title">Kapcsolat létesítése</string>
|
||||
<string name="check_ports_msg">Ellenőrizze a tűzfal és a port-továbbítási szabályokat a port(ok)ra vonatkozóan:</string>
|
||||
<string name="early_termination_error">Valami nem sikerült a fogadó PC-n az adatfolyam indításakor.
|
||||
\n
|
||||
\nGyőződjön meg arról, hogy a fogadó PC-n nincs megnyitva DRM-védett tartalom. Megpróbálhatja újraindítani a gazdagépet is.
|
||||
\n
|
||||
\nHa a probléma továbbra is fennáll, próbálja meg újratelepíteni a GPU illesztőprogramokat és a GeForce Experience szoftvert.</string>
|
||||
<string name="no_frame_received_error">A hálózati kapcsolat nem működik megfelelően. Csökkentse a videó bitráta beállítását, vagy próbálkozzon gyorsabb kapcsolattal.</string>
|
||||
<string name="no_video_received_error">Nem kapott videót a gazdagéptől.</string>
|
||||
<string name="video_decoder_init_failed">A videó dekóder inicializálása nem sikerült. Előfordulhat, hogy készüléke nem támogatja a kiválasztott felbontást vagy képkockasebességet.</string>
|
||||
<string name="unable_to_pin_shortcut">A jelenlegi program nem teszi lehetővé rögzített parancsikonok létrehozását.</string>
|
||||
<string name="error_usb_prohibited">Az USB-hozzáférést az eszköz rendszergazdája tiltja. Ellenőrizze a Knox vagy az MDM beállításait.</string>
|
||||
<string name="message_decoding_reset">Az eszköz videodekóderje továbbra is összeomlik a kiválasztott adatfolyam-beállításoknál. A streaming beállításait visszaállította az alapértelmezettre.</string>
|
||||
<string name="title_decoding_reset">Videó Beállítások Alapra</string>
|
||||
<string name="message_decoding_error">A Moonlight összeomlott, mert inkompatibilis volt az eszköz videó dekóderével. Győződjön meg arról, hogy a GeForce Experience frissítve van a számítógép legújabb verziójára. Próbálja meg módosítani a streaming beállításokat, ha az összeomlások továbbra is fennállnak.</string>
|
||||
<string name="title_decoding_error">A videó dekóder összeomlott</string>
|
||||
<string name="error_404">A GFE HTTP 404 hibát adott vissza. Győződjön meg arról, hogy a számítógépen támogatott GPU fut. A távoli asztali szoftver használata szintén ezt a hibát okozhatja. Próbálja újraindítani a gépet, vagy telepítse újra a GFE-t.</string>
|
||||
<string name="conn_error_title">Csatlakozási hiba</string>
|
||||
<string name="conn_starting">Indítás</string>
|
||||
<string name="conn_hardware_latency">Átlagos hardver dekódolási késés:</string>
|
||||
<string name="error_unknown_host">Nem sikerült feloldani a gazdagépet</string>
|
||||
<string name="error_manager_not_running">A ComputerManager szolgáltatás nem fut. Várjon néhány másodpercet, vagy indítsa újra az alkalmazást.</string>
|
||||
<string name="error_pc_offline">A számítógép nem elérhető</string>
|
||||
<string name="unpair_error">Az eszköz nincs párosítva</string>
|
||||
<string name="unpair_fail">A párosítás megszüntetése nem sikerült</string>
|
||||
<string name="unpair_success">Párosítás megszüntetve</string>
|
||||
<string name="unpairing">Párosítás megszüntetése…</string>
|
||||
<string name="wol_fail">Nem sikerült elküldeni a Wake-On-LAN csomagokat</string>
|
||||
<string name="wol_waking_msg">Néhány másodpercbe telhet, mire a számítógép felébred. Ha nem, ellenőrizze, hogy megfelelően van-e konfigurálva a Wake-On-LAN számára.</string>
|
||||
<string name="wol_waking_pc">PC elindítása…</string>
|
||||
<string name="wol_no_mac">Nem lehet elindítani a PC-t, mert a GFE nem küldött MAC-címet</string>
|
||||
<string name="wol_pc_online">A számítógép elérhető</string>
|
||||
<string name="pair_already_in_progress">A párosítás már folyamatban van</string>
|
||||
<string name="pairing">Párosítás…</string>
|
||||
<string name="pair_pairing_title">Párosítás</string>
|
||||
<string name="pair_fail">Párosítás nem sikerült</string>
|
||||
<string name="pair_incorrect_pin">Hibás PIN</string>
|
||||
<string name="pair_pairing_msg">Kérjük, adja meg a következő PIN-kódot a cél PC-n:</string>
|
||||
<string name="pair_pc_ingame">A számítógép jelenleg játékban van. A párosítás előtt be kell zárni a játékot.</string>
|
||||
<string name="pair_pc_offline">A számítógép nem elérhető</string>
|
||||
<string name="nettest_text_blocked">Az eszköz jelenlegi hálózati kapcsolata blokkolja a Moonlight-ot. Előfordulhat, hogy az interneten keresztüli streaming nem működik, ha csatlakozik ehhez a hálózathoz.</string>
|
||||
<string name="nettest_text_failure">Úgy tűnik, hogy eszközének jelenlegi hálózati kapcsolata blokkolja a Moonlight-ot. Előfordulhat, hogy az interneten keresztüli streaming nem működik, ha csatlakozik ehhez a hálózathoz.
|
||||
\n
|
||||
\nA következő hálózati portokat blokkolták:
|
||||
\n</string>
|
||||
<string name="nettest_text_inconclusive">A hálózati tesztet nem sikerült elvégezni, mert a Moonlight egyik kapcsolat tesztelő szervere sem volt elérhető. Ellenőrizze az internetkapcsolatot, vagy próbálkozzon újra később.</string>
|
||||
<string name="nettest_text_success">Úgy tűnik, hogy a hálózata nem blokkolja a Moonlight-ot. Ha továbbra is problémái vannak a csatlakozással, ellenőrizze a számítógép tűzfalának beállításait.
|
||||
\n
|
||||
\nHa az interneten keresztül kíván közvetíteni, telepítse a Moonlight Internet Hosting Tool alkalmazást a számítógépére, és futtassa a mellékelt Internet Streaming Tester szoftvert a számítógép internetkapcsolatának ellenőrzéséhez.</string>
|
||||
<string name="nettest_title_done">Hálózati kapcsolat teszt kész</string>
|
||||
<string name="nettest_text_waiting">A Moonlight a hálózati kapcsolatot teszteli annak megállapítására, hogy az NVIDIA GameStream blokkolva van-e.
|
||||
\n
|
||||
\nEz eltarthat néhány másodpercig …</string>
|
||||
<string name="pcview_menu_test_network">Hálózati kapcsolat teszt</string>
|
||||
<string name="nettest_title_waiting">Hálózati kapcsolat ellenőrzése</string>
|
||||
<string name="pcview_menu_details">Részletek megtekintése</string>
|
||||
<string name="pcview_menu_delete_pc">PC törlése</string>
|
||||
<string name="pcview_menu_send_wol">Wake-On-LAN kérés küldése</string>
|
||||
<string name="pcview_menu_unpair_pc">Lecsatlakoztat</string>
|
||||
<string name="pcview_menu_pair_pc">PC csatlakoztatása</string>
|
||||
<string name="pcview_menu_app_list">Összes alkalmazás megtekintése</string>
|
||||
<string name="pcview_menu_header_unknown">Újratöltés</string>
|
||||
<string name="pcview_menu_header_offline">Nem elérhető</string>
|
||||
<string name="pcview_menu_header_online">Elérhető</string>
|
||||
<string name="help_loading_msg">Segítségek betöltés alatt…</string>
|
||||
<string name="help_loading_title">Segítség megtekintő</string>
|
||||
<string name="scut_invalid_app_id">A kiválasztott App nem érvényes</string>
|
||||
<string name="scut_invalid_uuid">A kiválasztott PC nem érvényes</string>
|
||||
<string name="scut_pc_not_found">Pc nem található</string>
|
||||
<string name="scut_not_paired">PC nincs csatlakoztatva</string>
|
||||
<string name="scut_deleted_pc">PC eltávolítva</string>
|
||||
<string name="resolution_prefix_native_fullscreen">Natív teljes képernyős</string>
|
||||
</resources>
|
||||
96
app/src/main/res/values-in/strings.xml
Normal file
96
app/src/main/res/values-in/strings.xml
Normal file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="scut_not_paired">Komputer tidak terpasang</string>
|
||||
<string name="scut_pc_not_found">Komputer tidak ditemukan</string>
|
||||
<string name="scut_invalid_uuid">Komputer yang diberikan tidak valid</string>
|
||||
<string name="help_loading_title">Lihat bantuan</string>
|
||||
<string name="help_loading_msg">Memuat laman bantuan…</string>
|
||||
<string name="pcview_menu_header_online">Tersedia</string>
|
||||
<string name="pcview_menu_header_offline">Tidak tersedia</string>
|
||||
<string name="pcview_menu_header_unknown">Memuat ulang</string>
|
||||
<string name="pcview_menu_app_list">Lihat semua aplikasi</string>
|
||||
<string name="pcview_menu_pair_pc">Pasangkan dengan komputer</string>
|
||||
<string name="pcview_menu_unpair_pc">Batalkan pemasangan</string>
|
||||
<string name="pcview_menu_send_wol">Kirim permintaan Wake-On-LAN</string>
|
||||
<string name="pcview_menu_delete_pc">Hapus komputer</string>
|
||||
<string name="nettest_title_waiting">Menguji koneksi jaringan</string>
|
||||
<string name="nettest_text_waiting">Moonlight sedang menguji koneksi jaringan untuk mencari tahu apakah NVIDIA GameStream diblokir.
|
||||
\n
|
||||
\nIni mungkin membutuhkan beberapa saat…</string>
|
||||
<string name="nettest_text_inconclusive">Uji koneksi jaringan tidak dapat dilakukan karena tidak ada server pengujian Moonlight yang bisa dijangkau. Cek koneksi Internet Anda atau coba lagi nanti.</string>
|
||||
<string name="nettest_text_failure">Koneksi jaringan perangkat anda sepertinya memblokir Moonlight. Streaming lewat Internet mungkin tidak bekerja ketika terhubung dengan jaringan ini.
|
||||
\n
|
||||
\nPort-port ini telah diblokir:
|
||||
\n</string>
|
||||
<string name="nettest_text_blocked">Koneksi jaringan perangkat anda memblokir Moonlight. Streaming lewat Internet mungkin tidak bekerja ketika terhubung dengan jaringan ini.</string>
|
||||
<string name="pair_pc_offline">Komputer tidak tersedia</string>
|
||||
<string name="pair_pairing_title">Memasang</string>
|
||||
<string name="pair_pairing_msg">Mohon isi PIN ini di komputer target:</string>
|
||||
<string name="pair_incorrect_pin">PIN salah</string>
|
||||
<string name="pair_fail">Pemasangan gagal</string>
|
||||
<string name="pair_already_in_progress">Pemasangan sedang berlangsung</string>
|
||||
<string name="wol_pc_online">Komputer tersedia</string>
|
||||
<string name="wol_no_mac">Tidak bisa membangunkan komputer karena GFE tidak mengirimkan alamat MAC</string>
|
||||
<string name="wol_waking_pc">Membangunkan komputer…</string>
|
||||
<string name="wol_waking_msg">Membangunkan komputer mungkin akan membutuhkan beberapa saat. Jika tidak bisa, pastikan konfigurasi Wake-On-LAN sudah benar.</string>
|
||||
<string name="unpairing">Memutuskan pemasangan…</string>
|
||||
<string name="unpair_success">Pemutusan pemasangan berhasil</string>
|
||||
<string name="unpair_fail">Gagal memutuskan pemasangan</string>
|
||||
<string name="error_pc_offline">Komputer tidak tersedia</string>
|
||||
<string name="title_decoding_error">Dekoder video berhenti bekerja</string>
|
||||
<string name="message_decoding_error">Moonlight telah berhenti bekerja dikarenakan inkompatibilitas dengan dekoder video perangkat ini. Pastikan GeForce Experience sudah diperbarui ke versi terkini pada komputer Anda. Coba ganti pengaturan stream jika masih berlanjut.</string>
|
||||
<string name="title_decoding_reset">Pengaturan video dipulihkan</string>
|
||||
<string name="message_decoding_reset">Dekoder video perangkat Anda terus-menerus berhenti pada pengaturan stream yang dipilih. Pengaturan stream Anda telah dipulihkan ke bawaan.</string>
|
||||
<string name="error_usb_prohibited">Akses USB dilarang oleh Administrator perangkat Anda. Cek pengaturan Knox atau MDM Anda.</string>
|
||||
<string name="no_video_received_error">Tidak ada video yang diterima dari host.</string>
|
||||
<string name="no_frame_received_error">Kinerja koneksi jaringan anda tidak baik. Kurangi pengaturan bitrate video Anda atau coba koneksi yang lebih cepat.</string>
|
||||
<string name="check_ports_msg">Cek pengaturan firewall dan port forwarding untuk port-port ini:</string>
|
||||
<string name="conn_establishing_title">Membangun koneksi</string>
|
||||
<string name="conn_establishing_msg">Memulai koneksi</string>
|
||||
<string name="conn_metered">Peringatan: Koneksi aktif Anda terbatas!</string>
|
||||
<string name="conn_client_latency">Rata-rata latensi dekoding bingkai:</string>
|
||||
<string name="conn_client_latency_hw">Latensi dekoder perangkat keras:</string>
|
||||
<string name="conn_hardware_latency">Rata-rata latensi dekoder perangkat keras:</string>
|
||||
<string name="conn_starting">Memulai</string>
|
||||
<string name="conn_error_title">Koneksi eror</string>
|
||||
<string name="conn_error_msg">Gagal untuk memulai</string>
|
||||
<string name="conn_terminated_title">Koneksi dihentikan</string>
|
||||
<string name="conn_terminated_msg">Koneksi telah terhenti</string>
|
||||
<string name="ip_hint">Alamat IP komputer GeForce</string>
|
||||
<string name="searching_pc">Mencari komputer yang menjalankan GameStream...
|
||||
\n
|
||||
\nPastikan GameStream diaktifkan pada pengaturan SHIELD GeForce Experience.</string>
|
||||
<string name="yes">Ya</string>
|
||||
<string name="no">Tidak</string>
|
||||
<string name="lost_connection">Koneksi dengan komputer hilang</string>
|
||||
<string name="title_details">Rincian</string>
|
||||
<string name="delete_pc_msg">Apakah Anda yakin ingin menghapus komputer ini\?</string>
|
||||
<string name="slow_connection_msg">Koneksi terhadap komputer lambat
|
||||
\nKurangi bitrate anda</string>
|
||||
<string name="poor_connection_msg">Koneksi dengan komputer buruk</string>
|
||||
<string name="perf_overlay_streamdetails">Stream video: %1$s %2$.2f FPS</string>
|
||||
<string name="perf_overlay_decoder">Dekoder: %1$s</string>
|
||||
<string name="perf_overlay_incomingfps">Kecepatan bingkai masuk dari jaringan: %1$.2f FPS</string>
|
||||
<string name="scut_deleted_pc">Komputer dihapus</string>
|
||||
<string name="scut_invalid_app_id">Aplikasi yang diberikan tidak valid</string>
|
||||
<string name="pcview_menu_test_network">Uji koneksi jaringan</string>
|
||||
<string name="pcview_menu_details">Lihat rincian</string>
|
||||
<string name="nettest_title_done">Uji jaringan selesai</string>
|
||||
<string name="pairing">Memasang…</string>
|
||||
<string name="nettest_text_success">Jaringan Anda sepertinya tidak memblokir Moonlight. Jika Anda masih mengalami masalah menghubungkan, cek pengaturan firewall komputer Anda.
|
||||
\n
|
||||
\nJika anda mencoba stream lewat internet, install Moonlight Internet Hosting Tool pada komputer anda dan jalankan Internet Streaming Tester untuk mengecek koneksi Internet komputer Anda.</string>
|
||||
<string name="pair_pc_ingame">Komputer sedang ada di game. Anda harus menutupnya terlebih dahulu.</string>
|
||||
<string name="wol_fail">Gagal mengirim paket Wake-On-LAN</string>
|
||||
<string name="unpair_error">Perangkat tidak terpasang</string>
|
||||
<string name="error_manager_not_running">ComputerManager tidak berjalan. Mohon tunggu beberapa saat atau mulai ulang aplikasi.</string>
|
||||
<string name="error_404">GFE memberikan eror HTTP 404. Pastikan komputer anda menggunakan kartu grafis yang didukung. Penggunaan aplikasi remote desktop juga dapat menyebabakan eror ini. Coba mulai ulang perangkat Anda atau install ulang GFE.</string>
|
||||
<string name="unable_to_pin_shortcut">Peluncur Anda tidak memperbolehkan pembuatan shortcut yang disematkan.</string>
|
||||
<string name="video_decoder_init_failed">Gagal memulai dekoder video. Perangkat Anda mungkin tidak mendukung resolusi atau kecepatan bingkai yang dipilih.</string>
|
||||
<string name="early_termination_error">Ada yang salah dengan komputer host anda ketika memulai stream.
|
||||
\n
|
||||
\nPastikan tidak ada konten yang dilindungi DRM yang terbuka di komputer host Anda. Coba mulai ulang komputer host.
|
||||
\n
|
||||
\nJika masalah berkelanjutan, coba install ulang GeForce Experience dan driver video grafis Anda.</string>
|
||||
<string name="help">Bantuan</string>
|
||||
</resources>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="decoder_names">
|
||||
<item>Scegli decoder automaticamente</item>
|
||||
<item>Forza decoder software</item>
|
||||
<item>Forza decoder hardware</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -3,18 +3,15 @@
|
||||
<!-- Shortcut strings -->
|
||||
<string name="scut_deleted_pc">PC eliminato</string>
|
||||
<string name="scut_not_paired">PC non accoppiato</string>
|
||||
|
||||
<!-- Help strings -->
|
||||
<string name="help_loading_title">Visualizza assistenza</string>
|
||||
<string name="help_loading_msg">Caricamento pagina di assistenza…</string>
|
||||
|
||||
<!-- PC view menu entries -->
|
||||
<string name="pcview_menu_app_list">Lista applicazioni</string>
|
||||
<string name="pcview_menu_app_list">Vedi Tutte le Applicazioni</string>
|
||||
<string name="pcview_menu_pair_pc">Accoppia PC</string>
|
||||
<string name="pcview_menu_unpair_pc">Disaccoppia PC</string>
|
||||
<string name="pcview_menu_send_wol">Invia richiesta Wake-On-LAN</string>
|
||||
<string name="pcview_menu_delete_pc">Rimuovi PC</string>
|
||||
|
||||
<!-- Pair messages -->
|
||||
<string name="pairing">Accoppiamento…</string>
|
||||
<string name="pair_pc_offline">Il PC è offline</string>
|
||||
@@ -24,7 +21,6 @@
|
||||
<string name="pair_incorrect_pin">PIN non corretto</string>
|
||||
<string name="pair_fail">Accoppiamento fallito</string>
|
||||
<string name="pair_already_in_progress">Accoppiamento già in corso</string>
|
||||
|
||||
<!-- WOL messages -->
|
||||
<string name="wol_pc_online">PC già avviato</string>
|
||||
<string name="wol_no_mac">Impossibile risvegliare il PC perché GFE non ha inviato nessun indirizzo MAC</string>
|
||||
@@ -33,13 +29,11 @@
|
||||
Se non succede niente, assicurati che l\'opzione Wake-On-LAN sia configurata correttamente.
|
||||
</string>
|
||||
<string name="wol_fail">Invio pacchetti Wake-On-LAN fallito</string>
|
||||
|
||||
<!-- Unpair messages -->
|
||||
<string name="unpairing">Disaccoppiamento…</string>
|
||||
<string name="unpair_success">Disaccoppiato con successo</string>
|
||||
<string name="unpair_fail">Disaccoppiamento fallito</string>
|
||||
<string name="unpair_error">PC non accoppiato</string>
|
||||
|
||||
<!-- Errors -->
|
||||
<string name="error_pc_offline">PC offline</string>
|
||||
<string name="error_manager_not_running">Il servizio ComputerManager non è avviato. Attendi qualche secondo o riavvia l\'applicazione.</string>
|
||||
@@ -52,7 +46,6 @@
|
||||
<string name="title_decoding_reset">Ripristino impostazioni video</string>
|
||||
<string name="message_decoding_reset">Il decodificatore video del dispositivo continua a funzionare in modo anomalo con le impostazioni di streaming selezionate. Le impostazioni di streaming sono state ripristinate ai valori predefiniti.</string>
|
||||
<string name="error_usb_prohibited">L\'accesso USB è vietato dall\'amministratore del dispositivo. Verifica le impostazioni Knox o MDM.</string>
|
||||
|
||||
<!-- Start application messages -->
|
||||
<string name="conn_establishing_title">Connessione in corso</string>
|
||||
<string name="conn_establishing_msg">Avvio connessione</string>
|
||||
@@ -60,12 +53,11 @@
|
||||
<string name="conn_client_latency">Latenza decodifica fotogrammi media:</string>
|
||||
<string name="conn_client_latency_hw">latenza decodificatore hardware:</string>
|
||||
<string name="conn_hardware_latency">Latenza decodificatore hardware media:</string>
|
||||
<string name="conn_starting">Avvio in corso…</string>
|
||||
<string name="conn_starting">Avvio in corso</string>
|
||||
<string name="conn_error_title">Errore connessione</string>
|
||||
<string name="conn_error_msg">Avvio fallito</string>
|
||||
<string name="conn_terminated_title">Connessione interrotta</string>
|
||||
<string name="conn_terminated_msg">La connessione è stata interrotta</string>
|
||||
|
||||
<!-- General strings -->
|
||||
<string name="ip_hint">Indirizzo IP del PC</string>
|
||||
<string name="searching_pc">Ricerca di PC con GameStream avviato…\n\n
|
||||
@@ -74,7 +66,6 @@
|
||||
<string name="no">No</string>
|
||||
<string name="lost_connection">Connessione con il PC persa</string>
|
||||
<string name="help">Assistenza</string>
|
||||
|
||||
<!-- AppList activity -->
|
||||
<string name="applist_connect_msg">Connessione al PC in corso…</string>
|
||||
<string name="applist_menu_resume">Riprendi sessione</string>
|
||||
@@ -85,11 +76,10 @@
|
||||
<string name="applist_refresh_msg">Aggiornamento lista in corso…</string>
|
||||
<string name="applist_refresh_error_title">Errore</string>
|
||||
<string name="applist_refresh_error_msg">Ricezione lista applicazioni fallita</string>
|
||||
<string name="applist_quit_app">Chiusura in corso…</string>
|
||||
<string name="applist_quit_app">Chiusura in corso</string>
|
||||
<string name="applist_quit_success">Sessione chiusa con successo</string>
|
||||
<string name="applist_quit_fail">Chiusura sessione fallita</string>
|
||||
<string name="applist_quit_confirmation">Sei sicuro di voler chiudere l\'applicazione avviata? Tutti i dati non salvati saranno persi.</string>
|
||||
|
||||
<!-- Add computer manually activity -->
|
||||
<string name="title_add_pc">Aggiungi PC manualmente</string>
|
||||
<string name="msg_add_pc">Connessione al PC in corso…</string>
|
||||
@@ -98,21 +88,18 @@
|
||||
<string name="addpc_unknown_host">Impossibile risovere l\'indirizzo del PC. Assicurati di aver scritto correttamente l\'indirizzo.</string>
|
||||
<string name="addpc_enter_ip">Devi inserire un indirizzo IP</string>
|
||||
<string name="addpc_wrong_sitelocal">Quell\'indirizzo non sembra corretto. È necessario utilizzare l\'indirizzo IP pubblico del router per lo streaming su Internet.</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<string name="category_basic_settings">Impostazioni generali</string>
|
||||
<string name="title_resolution_list">Risoluzione e FPS</string>
|
||||
<string name="summary_resolution_list">Valori troppo elevati possono causare lag o crash</string>
|
||||
<string name="summary_resolution_list">Aumentare per migliorare la nitidezza dell\'immagine. Diminuire per aumentare le prestazioni su dispositivi di fascia più bassa e reti più lente.</string>
|
||||
<string name="title_seekbar_bitrate">Velocità di trasmissione video</string>
|
||||
<string name="summary_seekbar_bitrate">Abbassa la velocità di trasmissione per ridurre lo stuttering; alzala per migliorare la qualità dell\'immagine</string>
|
||||
<string name="summary_seekbar_bitrate">Aumentare per migliorare la qualità dell\'immagine. Diminuire per aumentare le prestazioni su reti più lente.</string>
|
||||
<string name="title_checkbox_stretch_video">Forza video a schermo intero</string>
|
||||
<string name="title_checkbox_disable_warnings">Disabilita messaggi di warning</string>
|
||||
<string name="summary_checkbox_disable_warnings">Disabilita i messaggi di warning sullo schermo durante lo streaming</string>
|
||||
<string name="title_checkbox_enable_pip">Abilita modalità spettatore Picture-in-Picture</string>
|
||||
<string name="summary_checkbox_enable_pip">Permette di osservare (ma non di controllare) la stream in multitasking</string>
|
||||
|
||||
<string name="category_audio_settings">Impostazioni audio</string>
|
||||
|
||||
<string name="title_checkbox_multi_controller">Supporto a più controller</string>
|
||||
<string name="summary_checkbox_multi_controller">Quando disabilitato, tutti i controller appaiono come uno solo</string>
|
||||
<string name="title_seekbar_deadzone">Regola i punti morti degli stick analogici</string>
|
||||
@@ -123,7 +110,6 @@
|
||||
<string name="summary_checkbox_usb_bind_all">Forza i driver USB di Moonlight di assumere il controllo su tutti i controller Xbox supportati</string>
|
||||
<string name="title_checkbox_mouse_emulation">Emulazione del mouse tramite controller</string>
|
||||
<string name="summary_checkbox_mouse_emulation">Tenendo premuto il pulsante Start, il controller passerà alla modalità mouse</string>
|
||||
|
||||
<string name="category_on_screen_controls_settings">Impostazioni dei controlli a schermo</string>
|
||||
<string name="title_checkbox_show_onscreen_controls">Mostra controlli a schermo</string>
|
||||
<string name="summary_checkbox_show_onscreen_controls">Mostra l\'overlay virtuale del controller su schermo</string>
|
||||
@@ -134,26 +120,138 @@
|
||||
<string name="dialog_title_reset_osc">Ripristino del layout</string>
|
||||
<string name="dialog_text_reset_osc">Sei sicuro di voler ripristinare ai valori predefiniti i layout dei controlli a schermo?</string>
|
||||
<string name="toast_reset_osc_success">I controlli a schermo sono stati ripristinati</string>
|
||||
|
||||
<string name="category_ui_settings">Impostazioni dell\'interfaccia</string>
|
||||
<string name="title_language_list">Lingua</string>
|
||||
<string name="summary_language_list">Lingua da usare in Moonlight</string>
|
||||
<string name="title_checkbox_small_icon_mode">Usa icone piccole</string>
|
||||
<string name="summary_checkbox_small_icon_mode">Usa icone piccole nella griglia per avere più oggetti a schermo</string>
|
||||
|
||||
<string name="category_host_settings">Impostazioni del PC host</string>
|
||||
<string name="title_checkbox_enable_sops">Ottimizza le impostazioni dei giochi</string>
|
||||
<string name="summary_checkbox_enable_sops">Permetti a GFE di modificare le impostazioni dei giochi per uno streaming ottimale</string>
|
||||
<string name="title_checkbox_host_audio">Riproduci audio sul PC</string>
|
||||
<string name="summary_checkbox_host_audio">Riproduce l\'audio sul PC e su questo dispositivo</string>
|
||||
|
||||
<string name="category_advanced_settings">Impostazioni avanzate</string>
|
||||
<string name="title_disable_frame_drop">Non saltare i fotogrammi</string>
|
||||
<string name="summary_disable_frame_drop">Potrebbe ridurre il micro-stuttering su alcuni dispositivi, ma può aumentare la latenza</string>
|
||||
<string name="title_video_format">Modifica impostazioni H.265</string>
|
||||
<string name="summary_video_format">H.265 riduce i requisiti di larghezza di banda video ma richiede un dispositivo molto recente</string>
|
||||
<string name="title_video_format">Modifica impostazioni HEVC</string>
|
||||
<string name="summary_video_format">HEVC riduce i requisiti di larghezza di banda video ma richiede un dispositivo molto recente</string>
|
||||
<string name="title_enable_hdr">Abilita HDR (sperimentale)</string>
|
||||
<string name="summary_enable_hdr">Utilizza l\'HDR quando il gioco e la scheda video del PC lo supportano. L\'HDR richiede una scheda video serie GTX 1000 o sucessive.</string>
|
||||
<string name="suffix_osc_opacity">%</string>
|
||||
|
||||
</resources>
|
||||
<string name="pcview_menu_header_online">Online</string>
|
||||
<string name="scut_pc_not_found">PC non trovato</string>
|
||||
<string name="scut_invalid_uuid">Il PC indicato non è valido</string>
|
||||
<string name="scut_invalid_app_id">L\'App indicata non è valida</string>
|
||||
<string name="pcview_menu_header_offline">Offline</string>
|
||||
<string name="pcview_menu_header_unknown">Aggiornando</string>
|
||||
<string name="pcview_menu_details">Mostra Dettagli</string>
|
||||
<string name="pcview_menu_test_network">Controlla la Connessione di Rete</string>
|
||||
<string name="title_details">Dettagli</string>
|
||||
<string name="delete_pc_msg">Sei sicuro di voler rimuovere questo PC\?</string>
|
||||
<string name="slow_connection_msg">Connessione lenta al PC
|
||||
\nRidurre il bitrate</string>
|
||||
<string name="poor_connection_msg">Connessione al PC di bassa qualità</string>
|
||||
<string name="applist_menu_hide_app">Nascondi App</string>
|
||||
<string name="applist_menu_scut">Crea Collegamento</string>
|
||||
<string name="applist_menu_tv_channel">Aggiungi al Canale</string>
|
||||
<string name="applist_menu_details">Mostra Dettagli</string>
|
||||
<string name="summary_fps_list">Aumentare per uno streaming video più fluido. Diminuire per prestazioni migliori su dispositivi di fascia più bassa.</string>
|
||||
<string name="applist_details_id">ID Applicazione:</string>
|
||||
<string name="perf_overlay_decoder">Decoder: %1$s</string>
|
||||
<string name="perf_overlay_dectime">Tempo medio di decodifica: %1$.2f ms</string>
|
||||
<string name="perf_overlay_streamdetails">Flusso video: %1$s %2$.2f FPS</string>
|
||||
<string name="nettest_title_waiting">Prova della Connessione di Rete</string>
|
||||
<string name="nettest_text_waiting">Moonlight sta testando la tua connessione di rete per controllare se NVIDIA GameStream sia bloccato.
|
||||
\n
|
||||
\nPotrebbero volerci alcuni secondi…</string>
|
||||
<string name="nettest_title_done">Test della Rete Completato</string>
|
||||
<string name="nettest_text_inconclusive">Il test della rete non è stato effettuato perché nessuno dei server per il test della connessione di Moonlight era raggiungibile. Controlla la tua connessione ad Internet o riprova più tardi.</string>
|
||||
<string name="nettest_text_success">La tua rete non sembra bloccare Moonlight. Se hai ancora problemi di connessione, controlla le impostazioni del firewall del PC.
|
||||
\n
|
||||
\nSe stai cercando di trasmettere via Internet, installa il Moonlight Internet Hosting Tool sul tuo PC ed avvia il Test per la trasmissione via Internet incluso per controllare la connessione ad Internet del tuo PC.</string>
|
||||
<string name="title_checkbox_vibrate_osc">Abilita vibrazione</string>
|
||||
<string name="title_audio_config_list">Configurazione suono surround</string>
|
||||
<string name="title_checkbox_touchscreen_trackpad">Usa lo schermo touch come un trackpad</string>
|
||||
<string name="summary_audio_config_list">Abilita il sourround 5.1 o 7.1 per sistemi home-theater</string>
|
||||
<string name="title_fps_list">Frame rate video</string>
|
||||
<string name="summary_checkbox_touchscreen_trackpad">Se abilitato, lo schermo touch si comporta come un trackpad. Se disabilitato, lo schermo touch controlla direttamente il cursore del mouse.</string>
|
||||
<string name="title_checkbox_vibrate_fallback">Emula il supporto per la vibrazione</string>
|
||||
<string name="title_checkbox_mouse_nav_buttons">Abilita i bottoni avanti e indietro del mouse</string>
|
||||
<string name="title_osc_opacity">Cambia l\'opavità dei controlli a schermo</string>
|
||||
<string name="title_unlock_fps">Sblocca tutti i frame rate possibili</string>
|
||||
<string name="pacing_balanced">Bilanciato</string>
|
||||
<string name="pacing_latency">Preferisci ritardi minori</string>
|
||||
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
|
||||
<string name="resolution_prefix_native">Nativo</string>
|
||||
<string name="no_video_received_error">Nessun video ricevuto dal PC sorgente.</string>
|
||||
<string name="resolution_prefix_native_fullscreen">Schermo intero nativo</string>
|
||||
<string name="category_input_settings">Impostazioni di input</string>
|
||||
<string name="title_native_res_dialog">Avviso Risoluzione Nativa</string>
|
||||
<string name="dialog_title_osc_opacity">Cambia opacità</string>
|
||||
<string name="pacing_smoothness">Preferisci video più fluido (potrebbe aumentare significativamente il ritardo)</string>
|
||||
<string name="summary_osc_opacity">Rende i controlli a schermo più/meno trasparenti</string>
|
||||
<string name="summary_checkbox_mouse_nav_buttons">Abilitare questa opzione può far smettere di funzionare il click destro su alcuni dispositivi</string>
|
||||
<string name="title_checkbox_flip_face_buttons">Inverti i bottoni frontali</string>
|
||||
<string name="summary_checkbox_flip_face_buttons">Inverte i bottoni A/B e X/Y sui controller e sui controlli a schermo</string>
|
||||
<string name="summary_checkbox_vibrate_fallback">Fa vibrare il tuo dispositivo per emulare la vibrazione del controller se questo non la supporta</string>
|
||||
<string name="summary_checkbox_vibrate_osc">Fa vibrare il tuo dispositivo per emulare la vibrazione con i controlli a schermo</string>
|
||||
<string name="resolution_360p">360p</string>
|
||||
<string name="resolution_480p">480p</string>
|
||||
<string name="resolution_720p">720p</string>
|
||||
<string name="resolution_1080p">1080p</string>
|
||||
<string name="resolution_1440p">1440p</string>
|
||||
<string name="resolution_4k">4K</string>
|
||||
<string name="fps_30">30 FPS</string>
|
||||
<string name="fps_60">60 FPS</string>
|
||||
<string name="fps_90">90 FPS</string>
|
||||
<string name="fps_120">120 FPS</string>
|
||||
<string name="audioconf_stereo">Stereo</string>
|
||||
<string name="audioconf_51surround">Surround 5.1</string>
|
||||
<string name="audioconf_71surround">Surround 7.1</string>
|
||||
<string name="videoformat_hevcauto">Automatico</string>
|
||||
<string name="videoformat_hevcalways">Usa sempre HEVC (potrebbe essere instabile)</string>
|
||||
<string name="videoformat_hevcnever">Non usare mai HEVC</string>
|
||||
<string name="title_frame_pacing">Bilanciamento frame video</string>
|
||||
<string name="summary_frame_pacing">Specifica come bilanciare il ritardo video e la fluidità</string>
|
||||
<string name="summary_enable_perf_overlay">Mostra informazioni real time sulla trasmissione</string>
|
||||
<string name="nettest_text_failure">Sembra che l\'attuale connessione di rete del tuo dispositivo stia bloccando Moonlight. Trasmettere via Internet potrebbe non funzionare mentre sei connesso a questa rete.
|
||||
\n
|
||||
\nQueste porte di rete sono bloccate:
|
||||
\n</string>
|
||||
<string name="nettest_text_blocked">L\'attuale connessione di rete del tuo dispositivo sta bloccando Moonlight. Trasmettere via Internet potrebbe non funzionare mentre sei connesso a questa rete.</string>
|
||||
<string name="unable_to_pin_shortcut">Il tuo launcher non permette la creazione di scorciatoie appuntate.</string>
|
||||
<string name="video_decoder_init_failed">Il decoder video non è riuscito ad inizializzarsi. Il tuo dispositivo potrebbe non supportare la risoluzione o il frame rate selezionati.</string>
|
||||
<string name="check_ports_msg">Controlla il tuo firewall e le regole di inoltro delle seguenti porte:</string>
|
||||
<string name="title_enable_perf_overlay">Mostra le statistiche delle performance durante la trasmissione</string>
|
||||
<string name="title_enable_post_stream_toast">Mostra un messaggio sulla latenza dopo la trasmissione</string>
|
||||
<string name="no_frame_received_error">La tua connessione di rete non sta funzionando bene. Riduci il bitrate video o prova ad usare una connessione più veloce.</string>
|
||||
<string name="early_termination_error">Qualcosa è andato storto sul PC sorgente mentre la trasmissione veniva avviata.
|
||||
\n
|
||||
\nAssicurati di non avere nessun contenuto protetto da DRM aperto sul PC sorgente. Puoi anche provare a spengere e riaccendere il PC sorgente.
|
||||
\n
|
||||
\nSe il problema persiste, prova a installare di nuovo i driver della scheda video e GeForce Experience.</string>
|
||||
<string name="summary_unlock_fps">Trasmettere a 90 o 120 FPS potrebbe ridurre il ritardo su dispositivi di fascia alta, ma può provocare ritardi i instabilità sui dispositivi che non lo supportano</string>
|
||||
<string name="summary_enable_post_stream_toast">Molstra un messaggio con informazioni sulla latenza dopo che la trasmissione è conclusa</string>
|
||||
<string name="text_native_res_dialog">Le impostazioni di risoluzione nativa non sono ufficialmente supportate da GeForce Experience, quindi non cambierà automaticamente la risoluzione del monitor del computer sorgente. Dovrai cambiarla manualmente all\'interno del gioco.
|
||||
\n
|
||||
\nSe scegli di create una risoluzione personalizzata nel Pannello di Controllo NVIDIA per copiare la risoluzione del tuo dispositivo, assicurati di aver letto e capito il messaggio di attenzione di NVIDIA a proposito dei possibili danni al monitor, all\'instabilità del PC e altri potenziali problemi.
|
||||
\n
|
||||
\nNon saremo responsabili per qualsiasi problema risultante dalla creazione di una risoluzione personalizzata sul tuo PC.
|
||||
\n
|
||||
\nInfine, il tuo dispositivo o PC sorgente potrebbero non supportare la trasmissione alla risoluzione nativa. Se ciò non funzionasse sul tuo dispositivo, sfortunatamente non ci sono altre soluzioni.</string>
|
||||
<string name="perf_overlay_incomingfps">Frame rate in ingresso dalla rete: %1$.2f FPS</string>
|
||||
<string name="perf_overlay_renderingfps">Frame rate renderizzato: %1$.2f FPS</string>
|
||||
<string name="perf_overlay_netdrops">Frame scartati dalla tua connessione di rete: %1$.2f%%</string>
|
||||
<string name="perf_overlay_netlatency">Latenza media della rete: %1$d ms (varianza: %2$d ms)</string>
|
||||
<string name="category_help">Aiuto</string>
|
||||
<string name="title_setup_guide">Guida configurazione</string>
|
||||
<string name="pacing_balanced_alt">Bilanciato con il limite FPS</string>
|
||||
<string name="summary_seekbar_deadzone">Nota: Alcuni giochi possono imporre una deadzone più grande di quella che Moonlight è configurato per utilizzare.</string>
|
||||
<string name="title_checkbox_absolute_mouse_mode">Modalità mouse desktop remoto</string>
|
||||
<string name="summary_checkbox_absolute_mouse_mode">Questo può rendere l\'accelerazione del mouse più naturale per l\'utilizzo del desktop remoto, ma è incompatibile con molti giochi.</string>
|
||||
<string name="summary_setup_guide">Visualizza le istruzioni su come configurare il tuo PC da gaming per lo streaming</string>
|
||||
<string name="title_troubleshooting">Guida alla risoluzione dei problemi</string>
|
||||
<string name="title_privacy_policy">Informativa sulla privacy</string>
|
||||
<string name="summary_troubleshooting">Visualizza i suggerimenti per la diagnosi e la risoluzione dei problemi di streaming più comuni</string>
|
||||
<string name="summary_privacy_policy">Visualizza l\'informativa sulla privacy di Moonlight</string>
|
||||
</resources>
|
||||
@@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string-array name="decoder_names">
|
||||
<item>デコーダを自動選択</item>
|
||||
<item>ソフトウェアデコードを強制</item>
|
||||
<item>ハードウェアデコードを強制</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="video_format_names">
|
||||
<item>安定している場合にH.265を有効化</item>
|
||||
<item>H.265を強制的に有効化(クラッシュする可能性があります)</item>
|
||||
<item>H.265を無効化</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -114,8 +114,8 @@
|
||||
<string name="summary_checkbox_host_audio">音声をコンピュータとこのデバイスの両方で再生します</string>
|
||||
|
||||
<string name="category_advanced_settings">高度な設定</string>
|
||||
<string name="title_video_format">H.265</string>
|
||||
<string name="summary_video_format">H.265は動画に必要な帯域幅を圧縮します。この機能にはなるべく新しいデバイスが必要です</string>
|
||||
<string name="title_video_format">HEVC</string>
|
||||
<string name="summary_video_format">HEVCは動画に必要な帯域幅を圧縮します。この機能にはなるべく新しいデバイスが必要です</string>
|
||||
<string name="suffix_osc_opacity">%</string>
|
||||
<string name="dialog_title_osc_opacity">透過率</string>
|
||||
<string name="title_osc_opacity">透過率</string>
|
||||
@@ -130,4 +130,8 @@
|
||||
<string name="title_checkbox_vibrate_osc">振動</string>
|
||||
<string name="summary_checkbox_vibrate_osc">コントローラの振動を真似します</string>
|
||||
|
||||
<!-- Array strings -->
|
||||
<string name="videoformat_hevcauto">安定している場合にHEVCを有効化</string>
|
||||
<string name="videoformat_hevcalways">HEVCを強制的に有効化(クラッシュする可能性があります)</string>
|
||||
<string name="videoformat_hevcnever">HEVCを無効化</string>
|
||||
</resources>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user