parent
acd8620139
commit
6dfa9f7786
|
@ -23,9 +23,9 @@ jobs:
|
|||
|
||||
- name: Gradle
|
||||
working-directory: shell/android-studio
|
||||
run: ./gradlew assembleDreamcastDebug --parallel
|
||||
run: ./gradlew assembleDebug --parallel
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: flycast-debug.apk
|
||||
path: shell/android-studio/flycast/build/outputs/apk/dreamcast/debug/flycast-dreamcast-debug.apk
|
||||
path: shell/android-studio/flycast/build/outputs/apk/debug/flycast-debug.apk
|
||||
|
|
|
@ -22,14 +22,14 @@ install:
|
|||
script:
|
||||
- cd shell/android-studio
|
||||
- chmod +x gradlew
|
||||
- ./gradlew assembleDreamcastDebug --console=plain --parallel
|
||||
- ./gradlew assembleDebug --console=plain --parallel
|
||||
|
||||
before_deploy:
|
||||
- cd ../../
|
||||
- GIT_HASH=`git log --pretty=format:'%h' -n 1`
|
||||
- GIT_BUILD=`git describe --all --always`-$GIT_HASH
|
||||
- mkdir -p artifacts/$GIT_BUILD/
|
||||
- cp shell/android-studio/flycast/build/outputs/apk/dreamcast/debug/flycast-dreamcast-debug.apk artifacts/$GIT_BUILD/flycast-debug-$GIT_HASH.apk
|
||||
- cp shell/android-studio/flycast/build/outputs/apk/debug/flycast-debug.apk artifacts/$GIT_BUILD/flycast-debug-$GIT_HASH.apk
|
||||
|
||||
deploy:
|
||||
provider: s3
|
||||
|
|
|
@ -281,6 +281,12 @@ if(ASAN)
|
|||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address -static-libasan")
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
find_package(oboe REQUIRED CONFIG)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_OBOE)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE oboe::oboe)
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE
|
||||
core/deps/chdpsr/cdipsr.cpp
|
||||
core/deps/chdpsr/cdipsr.h)
|
||||
|
@ -710,6 +716,7 @@ target_sources(${PROJECT_NAME} PRIVATE
|
|||
core/oslib/audiobackend_directsound.cpp
|
||||
core/oslib/audiobackend_libao.cpp
|
||||
core/oslib/audiobackend_null.cpp
|
||||
core/oslib/audiobackend_oboe.cpp
|
||||
core/oslib/audiobackend_omx.cpp
|
||||
core/oslib/audiobackend_oss.cpp
|
||||
core/oslib/audiobackend_pulseaudio.cpp
|
||||
|
|
|
@ -26,66 +26,6 @@ static cResetEvent pushWait;
|
|||
|
||||
constexpr u32 SAMPLE_BYTES = SAMPLE_COUNT * 4;
|
||||
|
||||
class RingBuffer
|
||||
{
|
||||
std::vector<u8> buffer;
|
||||
std::atomic_int readCursor { 0 };
|
||||
std::atomic_int writeCursor { 0 };
|
||||
|
||||
u32 readSize() {
|
||||
return (writeCursor - readCursor + buffer.size()) % buffer.size();
|
||||
}
|
||||
u32 writeSize() {
|
||||
return (readCursor - writeCursor + buffer.size() - 1) % buffer.size();
|
||||
}
|
||||
|
||||
public:
|
||||
bool write(const u8 *data, u32 size)
|
||||
{
|
||||
if (size > writeSize())
|
||||
return false;
|
||||
u32 wc = writeCursor;
|
||||
u32 chunkSize = std::min<u32>(size, buffer.size() - wc);
|
||||
memcpy(&buffer[wc], data, chunkSize);
|
||||
wc = (wc + chunkSize) % buffer.size();
|
||||
size -= chunkSize;
|
||||
if (size > 0)
|
||||
{
|
||||
data += chunkSize;
|
||||
memcpy(&buffer[wc], data, size);
|
||||
wc = (wc + size) % buffer.size();
|
||||
}
|
||||
writeCursor = wc;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read(u8 *data, u32 size)
|
||||
{
|
||||
if (size > readSize())
|
||||
return false;
|
||||
u32 rc = readCursor;
|
||||
u32 chunkSize = std::min<u32>(size, buffer.size() - rc);
|
||||
memcpy(data, &buffer[rc], chunkSize);
|
||||
rc = (rc + chunkSize) % buffer.size();
|
||||
size -= chunkSize;
|
||||
if (size > 0)
|
||||
{
|
||||
data += chunkSize;
|
||||
memcpy(data, &buffer[rc], size);
|
||||
rc = (rc + size) % buffer.size();
|
||||
}
|
||||
readCursor = rc;
|
||||
return true;
|
||||
}
|
||||
|
||||
void setCapacity(size_t size)
|
||||
{
|
||||
std::fill(buffer.begin(), buffer.end(), 0);
|
||||
buffer.resize(size);
|
||||
readCursor = 0;
|
||||
writeCursor = 0;
|
||||
}
|
||||
};
|
||||
static RingBuffer ringBuffer;
|
||||
|
||||
static u32 notificationOffset(int index) {
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
Copyright 2021 flyinghead
|
||||
|
||||
This file is part of Flycast.
|
||||
|
||||
Flycast is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Flycast is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "audiostream.h"
|
||||
#ifdef USE_OBOE
|
||||
#include <oboe/Oboe.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include "stdclass.h"
|
||||
|
||||
static RingBuffer ringBuffer;
|
||||
static cResetEvent pushWait;
|
||||
|
||||
static std::shared_ptr<oboe::AudioStream> stream;
|
||||
static std::shared_ptr<oboe::AudioStream> recordStream;
|
||||
|
||||
class AudioCallback : public oboe::AudioStreamDataCallback
|
||||
{
|
||||
public:
|
||||
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames)
|
||||
{
|
||||
if (!ringBuffer.read((u8 *)audioData, numFrames * 4))
|
||||
// underrun
|
||||
memset(audioData, 0, numFrames * 4);
|
||||
else
|
||||
pushWait.Set();
|
||||
|
||||
return oboe::DataCallbackResult::Continue;
|
||||
}
|
||||
};
|
||||
static AudioCallback audioCallback;
|
||||
|
||||
static void audio_init()
|
||||
{
|
||||
// Actual capacity is size-1 to avoid overrun so add one buffer
|
||||
ringBuffer.setCapacity((config::AudioBufferSize + SAMPLE_COUNT) * 4);
|
||||
|
||||
oboe::AudioStreamBuilder builder;
|
||||
oboe::Result result = builder.setDirection(oboe::Direction::Output)
|
||||
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
|
||||
->setSharingMode(oboe::SharingMode::Exclusive)
|
||||
->setFormat(oboe::AudioFormat::I16)
|
||||
->setChannelCount(oboe::ChannelCount::Stereo)
|
||||
->setSampleRate(44100)
|
||||
->setFramesPerCallback(SAMPLE_COUNT)
|
||||
->setDataCallback(&audioCallback)
|
||||
->openStream(stream);
|
||||
if (result != oboe::Result::OK)
|
||||
{
|
||||
ERROR_LOG(AUDIO, "Oboe open stream failed: %s", oboe::convertToText(result));
|
||||
return;
|
||||
}
|
||||
stream->requestStart();
|
||||
NOTICE_LOG(AUDIO, "Oboe driver started. stream capacity: %d frames, frames/callback: %d, frames/burst: %d",
|
||||
stream->getBufferCapacityInFrames(), stream->getFramesPerCallback(), stream->getFramesPerBurst());
|
||||
}
|
||||
|
||||
static void audio_term()
|
||||
{
|
||||
NOTICE_LOG(AUDIO, "Oboe driver stopping");
|
||||
if (stream != nullptr)
|
||||
{
|
||||
stream->stop();
|
||||
stream->close();
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
static u32 audio_push(const void* frame, u32 samples, bool wait) {
|
||||
while (!ringBuffer.write((const u8 *)frame, samples * 4) && wait)
|
||||
pushWait.Wait();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void term_record()
|
||||
{
|
||||
if (recordStream != nullptr)
|
||||
{
|
||||
recordStream->stop();
|
||||
recordStream->close();
|
||||
recordStream.reset();
|
||||
}
|
||||
NOTICE_LOG(AUDIO, "Oboe recorder stopped");
|
||||
}
|
||||
|
||||
static bool init_record(u32 sampling_freq)
|
||||
{
|
||||
oboe::AudioStreamBuilder builder;
|
||||
oboe::Result result = builder.setDirection(oboe::Direction::Input)
|
||||
->setPerformanceMode(oboe::PerformanceMode::None)
|
||||
->setSharingMode(oboe::SharingMode::Exclusive)
|
||||
->setFormat(oboe::AudioFormat::I16)
|
||||
->setChannelCount(oboe::ChannelCount::Mono)
|
||||
->setSampleRate(sampling_freq)
|
||||
->openStream(recordStream);
|
||||
if (result != oboe::Result::OK)
|
||||
{
|
||||
ERROR_LOG(AUDIO, "Oboe open record stream failed: %s", oboe::convertToText(result));
|
||||
return false;
|
||||
}
|
||||
recordStream->requestStart();
|
||||
NOTICE_LOG(AUDIO, "Oboe recorder started. stream capacity: %d frames",
|
||||
stream->getBufferCapacityInFrames());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static u32 record(void *data, u32 samples)
|
||||
{
|
||||
oboe::ResultWithValue<int32_t> result = recordStream->read(data, samples, 0);
|
||||
return result.value();
|
||||
}
|
||||
|
||||
static audiobackend_t audiobackend_oboe = {
|
||||
"Oboe", // Slug
|
||||
"Automatic AAudio / OpenSL selection", // Name
|
||||
&audio_init,
|
||||
&audio_push,
|
||||
&audio_term,
|
||||
NULL,
|
||||
&init_record,
|
||||
&record,
|
||||
&term_record
|
||||
};
|
||||
|
||||
static bool oboebe = RegisterAudioBackend(&audiobackend_oboe);
|
||||
|
||||
#endif
|
|
@ -47,10 +47,10 @@ audiobackend_t* GetAudioBackend(const std::string& slug)
|
|||
{
|
||||
if (slug == "auto")
|
||||
{
|
||||
// Don't select the null driver
|
||||
// Don't select the null or OpenSL/Oboe drivers
|
||||
audiobackend_t *autoselection = nullptr;
|
||||
for (auto backend : *audiobackends)
|
||||
if (backend->slug != "null")
|
||||
if (backend->slug != "null" && backend->slug != "OpenSL" && backend->slug != "Oboe")
|
||||
{
|
||||
autoselection = backend;
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#pragma once
|
||||
#include "types.h"
|
||||
#include "cfg/option.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
|
||||
typedef std::vector<std::string> (*audio_option_callback_t)();
|
||||
enum audio_option_type
|
||||
|
@ -53,3 +56,64 @@ audiobackend_t* GetAudioBackend(int num);
|
|||
audiobackend_t* GetAudioBackend(const std::string& slug);
|
||||
|
||||
constexpr u32 SAMPLE_COUNT = 512; // push() is always called with that many frames
|
||||
|
||||
class RingBuffer
|
||||
{
|
||||
std::vector<u8> buffer;
|
||||
std::atomic_int readCursor { 0 };
|
||||
std::atomic_int writeCursor { 0 };
|
||||
|
||||
u32 readSize() {
|
||||
return (writeCursor - readCursor + buffer.size()) % buffer.size();
|
||||
}
|
||||
u32 writeSize() {
|
||||
return (readCursor - writeCursor + buffer.size() - 1) % buffer.size();
|
||||
}
|
||||
|
||||
public:
|
||||
bool write(const u8 *data, u32 size)
|
||||
{
|
||||
if (size > writeSize())
|
||||
return false;
|
||||
u32 wc = writeCursor;
|
||||
u32 chunkSize = std::min<u32>(size, buffer.size() - wc);
|
||||
memcpy(&buffer[wc], data, chunkSize);
|
||||
wc = (wc + chunkSize) % buffer.size();
|
||||
size -= chunkSize;
|
||||
if (size > 0)
|
||||
{
|
||||
data += chunkSize;
|
||||
memcpy(&buffer[wc], data, size);
|
||||
wc = (wc + size) % buffer.size();
|
||||
}
|
||||
writeCursor = wc;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read(u8 *data, u32 size)
|
||||
{
|
||||
if (size > readSize())
|
||||
return false;
|
||||
u32 rc = readCursor;
|
||||
u32 chunkSize = std::min<u32>(size, buffer.size() - rc);
|
||||
memcpy(data, &buffer[rc], chunkSize);
|
||||
rc = (rc + chunkSize) % buffer.size();
|
||||
size -= chunkSize;
|
||||
if (size > 0)
|
||||
{
|
||||
data += chunkSize;
|
||||
memcpy(data, &buffer[rc], size);
|
||||
rc = (rc + size) % buffer.size();
|
||||
}
|
||||
readCursor = rc;
|
||||
return true;
|
||||
}
|
||||
|
||||
void setCapacity(size_t size)
|
||||
{
|
||||
std::fill(buffer.begin(), buffer.end(), 0);
|
||||
buffer.resize(size);
|
||||
readCursor = 0;
|
||||
writeCursor = 0;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1398,8 +1398,9 @@ static void gui_display_settings()
|
|||
OptionCheckbox("Enable DSP", config::DSPEnabled,
|
||||
"Enable the Dreamcast Digital Sound Processor. Only recommended on fast platforms");
|
||||
#ifdef __ANDROID__
|
||||
OptionCheckbox("Automatic Latency", config::AutoLatency,
|
||||
"Automatically set audio latency. Recommended");
|
||||
if (config::AudioBackend.get() == "auto" || config::AudioBackend.get() == "android")
|
||||
OptionCheckbox("Automatic Latency", config::AutoLatency,
|
||||
"Automatically set audio latency. Recommended");
|
||||
#endif
|
||||
if (!config::AutoLatency)
|
||||
{
|
||||
|
|
|
@ -5,7 +5,7 @@ buildscript {
|
|||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.3'
|
||||
classpath 'com.android.tools.build:gradle:4.1.2'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ def getVersionName = { ->
|
|||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion '28.0.3'
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.flycast.emulator"
|
||||
|
@ -37,7 +36,7 @@ android {
|
|||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments '-DANDROID_ARM_MODE=arm'
|
||||
arguments "-DANDROID_STL=c++_shared", "-DANDROID_ARM_MODE=arm"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,13 +74,6 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
flavorDimensions "systemtype"
|
||||
productFlavors {
|
||||
dreamcast {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.10.2+'
|
||||
|
@ -92,13 +84,16 @@ android {
|
|||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
buildFeatures {
|
||||
prefab true
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
android.applicationVariants.all { v ->
|
||||
if (v.buildType.name == "release") {
|
||||
def hashtag = getVersionHash()
|
||||
v.outputs[0].outputFileName = "flycast-android-" + hashtag + ".apk"
|
||||
// def hashtag = getVersionHash()
|
||||
// v.outputs[0].outputFileName = "flycast-android-" + hashtag + ".apk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,4 +110,5 @@ dependencies {
|
|||
exclude module: 'junit'
|
||||
}
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation 'com.google.oboe:oboe:1.5.0'
|
||||
}
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.reicast.emulator"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<application android:name="com.reicast.emulator.Emulator">
|
||||
<activity
|
||||
android:name="com.reicast.emulator.NativeGLActivity"/>
|
||||
<activity-alias
|
||||
android:name="com.reicast.emulator.MainActivity"
|
||||
android:targetActivity="com.reicast.emulator.NativeGLActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.GDI"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.gdi"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.CHD"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.chd"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.CDI"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.cdi"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.CUE"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.cue"
|
||||
android:scheme="file" />
|
||||
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.LST"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.lst"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.BIN"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.bin"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.DAT"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.dat"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.ZIP"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.zip"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.7Z"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.7z"
|
||||
android:scheme="file" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
</application>
|
||||
</manifest>
|
|
@ -64,6 +64,104 @@
|
|||
<category android:name="tv.ouya.intent.category.GAME" />
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.GDI"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.gdi"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.CHD"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.chd"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.CDI"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.cdi"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.CUE"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.cue"
|
||||
android:scheme="file" />
|
||||
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.LST"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.lst"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.BIN"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.bin"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.DAT"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.dat"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.ZIP"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.zip"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.7Z"
|
||||
android:scheme="file" />
|
||||
<data
|
||||
android:host="*"
|
||||
android:mimeType="*/*"
|
||||
android:pathPattern=".*\\.7z"
|
||||
android:scheme="file" />
|
||||
</intent-filter>
|
||||
</activity-alias>
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#Mon Apr 02 06:06:44 EDT 2018
|
||||
#Wed Apr 07 11:28:33 CEST 2021
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
|
||||
|
|
Loading…
Reference in New Issue