mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-22 19:49:17 +01:00
Replace LogActivity with "Share Logs" + Add Timestamp to Logger
This commit is contained in:
parent
e511e158e3
commit
6854e07356
@ -36,5 +36,10 @@
|
||||
<option name="name" value="MavenLocal" />
|
||||
<option name="url" value="file:/$USER_HOME$/.m2/repository/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://google.bintray.com/flexbox-layout" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
@ -1,5 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DesignSurface">
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="app/src/main/res/layout/main_activity.xml" value="0.2028688524590164" />
|
||||
<entry key="app/src/main/res/layout/settings_activity.xml" value="0.22302631578947368" />
|
||||
<entry key="app/src/main/res/menu/toolbar_log.xml" value="0.11019736842105263" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="JavadocGenerationManager">
|
||||
<option name="OUTPUT_DIRECTORY" value="$PROJECT_DIR$/../LightSwitchEXTRA/JDoc" />
|
||||
@ -31,7 +40,7 @@
|
||||
</option>
|
||||
<option name="myNotNulls">
|
||||
<value>
|
||||
<list size="14">
|
||||
<list size="15">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
|
||||
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
|
||||
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
|
||||
@ -46,6 +55,7 @@
|
||||
<item index="11" class="java.lang.String" itemvalue="org.eclipse.jdt.annotation.NonNull" />
|
||||
<item index="12" class="java.lang.String" itemvalue="io.reactivex.annotations.NonNull" />
|
||||
<item index="13" class="java.lang.String" itemvalue="io.reactivex.rxjava3.annotations.NonNull" />
|
||||
<item index="14" class="java.lang.String" itemvalue="lombok.NonNull" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
|
@ -26,14 +26,6 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="emu.skyline.LogActivity"
|
||||
android:label="@string/log"
|
||||
android:parentActivityName="emu.skyline.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="emu.skyline.MainActivity" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name="emu.skyline.SettingsActivity"
|
||||
android:exported="true"
|
||||
@ -101,5 +93,15 @@
|
||||
tools:ignore="AppLinkUrlError" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="skyline.emu.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
||||
|
@ -11,14 +11,14 @@
|
||||
#include "kernel/types/KThread.h"
|
||||
|
||||
namespace skyline {
|
||||
Logger::Logger(const std::string &path, LogLevel configLevel) : configLevel(configLevel) {
|
||||
Logger::Logger(const std::string &path, LogLevel configLevel) : configLevel(configLevel), start(util::GetTimeNs() / constant::NsInMillisecond) {
|
||||
logFile.open(path, std::ios::trunc);
|
||||
UpdateTag();
|
||||
WriteHeader("Logging started");
|
||||
Write(LogLevel::Info, "Logging started");
|
||||
}
|
||||
|
||||
Logger::~Logger() {
|
||||
WriteHeader("Logging ended");
|
||||
Write(LogLevel::Info, "Logging ended");
|
||||
logFile.flush();
|
||||
}
|
||||
|
||||
@ -33,13 +33,6 @@ namespace skyline {
|
||||
logTag = std::string("emu-cpp-") + threadName;
|
||||
}
|
||||
|
||||
void Logger::WriteHeader(const std::string &str) {
|
||||
__android_log_write(ANDROID_LOG_INFO, "emu-cpp", str.c_str());
|
||||
|
||||
std::lock_guard guard(mutex);
|
||||
logFile << "\0360\035" << str << '\n';
|
||||
}
|
||||
|
||||
void Logger::Write(LogLevel level, const std::string &str) {
|
||||
constexpr std::array<char, 5> levelCharacter{'E', 'W', 'I', 'D', 'V'}; // The LogLevel as written out to a file
|
||||
constexpr std::array<int, 5> levelAlog{ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE}; // This corresponds to LogLevel and provides its equivalent for NDK Logging
|
||||
@ -50,7 +43,7 @@ namespace skyline {
|
||||
__android_log_write(levelAlog[static_cast<u8>(level)], logTag.c_str(), str.c_str());
|
||||
|
||||
std::lock_guard guard(mutex);
|
||||
logFile << "\0361\035" << levelCharacter[static_cast<u8>(level)] << '\035' << threadName << '\035' << str << '\n'; // We use RS (\036) and GS (\035) as our delimiters
|
||||
logFile << '\036' << levelCharacter[static_cast<u8>(level)] << '\035' << std::dec << (util::GetTimeNs() / constant::NsInMillisecond) - start << '\035' << threadName << '\035' << str << '\n'; // We use RS (\036) and GS (\035) as our delimiters
|
||||
}
|
||||
|
||||
DeviceState::DeviceState(kernel::OS *os, std::shared_ptr<JvmManager> jvmManager, std::shared_ptr<Settings> settings, std::shared_ptr<Logger> logger)
|
||||
|
@ -122,6 +122,7 @@ namespace skyline {
|
||||
namespace constant {
|
||||
// Time
|
||||
constexpr u64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second
|
||||
constexpr u64 NsInMillisecond{1000000}; //!< The amount of nanoseconds in a millisecond
|
||||
constexpr u64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
|
||||
}
|
||||
|
||||
@ -457,8 +458,9 @@ namespace skyline {
|
||||
*/
|
||||
class Logger {
|
||||
private:
|
||||
std::ofstream logFile; //!< An output stream to the log file
|
||||
std::mutex mutex; //!< Synchronizes all output I/O to ensure there are no races
|
||||
std::ofstream logFile; //!< An output stream to the log file
|
||||
u64 start; //!< A timestamp in milliseconds for when the logger was started, this is used as the base for all log timestamps
|
||||
|
||||
public:
|
||||
enum class LogLevel {
|
||||
@ -487,11 +489,6 @@ namespace skyline {
|
||||
*/
|
||||
static void UpdateTag();
|
||||
|
||||
/**
|
||||
* @brief Writes a header, should only be used for emulation starting and ending
|
||||
*/
|
||||
void WriteHeader(const std::string &str);
|
||||
|
||||
void Write(LogLevel level, const std::string &str);
|
||||
|
||||
/**
|
||||
|
@ -375,7 +375,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
is AxisGuestEvent -> {
|
||||
value = guestEvent.value(value)
|
||||
value = if (polarity) abs(value) else -abs(value)
|
||||
value = if (guestEvent.axis == AxisId.LX || guestEvent.axis == AxisId.RX) value else -value // TODO: Test this
|
||||
value = if (guestEvent.axis == AxisId.LX || guestEvent.axis == AxisId.RX) value else -value
|
||||
|
||||
setAxisValue(guestEvent.id, guestEvent.axis.ordinal, (value * Short.MAX_VALUE).toInt())
|
||||
}
|
||||
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
*/
|
||||
|
||||
package emu.skyline
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import emu.skyline.adapter.GenericAdapter
|
||||
import emu.skyline.adapter.HeaderViewItem
|
||||
import emu.skyline.adapter.LogViewItem
|
||||
import emu.skyline.databinding.LogActivityBinding
|
||||
import emu.skyline.utils.Settings
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.net.URL
|
||||
import javax.inject.Inject
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
|
||||
@AndroidEntryPoint
|
||||
class LogActivity : AppCompatActivity() {
|
||||
private val binding by lazy { LogActivityBinding.inflate(layoutInflater) }
|
||||
|
||||
/**
|
||||
* The log file is used to read log entries from or to clear all entries
|
||||
*/
|
||||
private lateinit var logFile : File
|
||||
|
||||
private val adapter = GenericAdapter()
|
||||
|
||||
@Inject
|
||||
lateinit var settings : Settings
|
||||
|
||||
override fun onCreate(savedInstanceState : Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(binding.root)
|
||||
|
||||
setSupportActionBar(binding.titlebar.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
||||
val compact = settings.logCompact
|
||||
val logLevel = settings.logLevel.toInt()
|
||||
val logLevels = resources.getStringArray(R.array.log_level)
|
||||
|
||||
binding.logList.adapter = adapter
|
||||
|
||||
if (!compact) binding.logList.addItemDecoration(DividerItemDecoration(this, RecyclerView.VERTICAL))
|
||||
|
||||
try {
|
||||
logFile = File(applicationContext.filesDir.canonicalPath + "/skyline.log")
|
||||
|
||||
adapter.setItems(logFile.readLines().mapNotNull { logLine ->
|
||||
try {
|
||||
val logMeta = logLine.split("|", limit = 3)
|
||||
|
||||
if (logMeta[0].startsWith("1")) {
|
||||
val level = logMeta[1].toInt()
|
||||
if (level > logLevel) return@mapNotNull null
|
||||
|
||||
return@mapNotNull LogViewItem(compact, "(" + logMeta[2] + ") " + logMeta[3].replace('\\', '\n'), logLevels[level])
|
||||
} else {
|
||||
return@mapNotNull HeaderViewItem(logMeta[1])
|
||||
}
|
||||
} catch (ignored : IndexOutOfBoundsException) {
|
||||
} catch (ignored : NumberFormatException) {
|
||||
}
|
||||
null
|
||||
})
|
||||
} catch (e : FileNotFoundException) {
|
||||
Log.w("Logger", "IO Error during access of log file: " + e.message)
|
||||
Toast.makeText(applicationContext, getString(R.string.file_missing), Toast.LENGTH_LONG).show()
|
||||
|
||||
finish()
|
||||
} catch (e : IOException) {
|
||||
Log.w("Logger", "IO Error during access of log file: " + e.message)
|
||||
Toast.makeText(applicationContext, getString(R.string.error) + ": ${e.localizedMessage}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This inflates the layout for the menu [R.menu.toolbar_log] and sets up searching the logs
|
||||
*/
|
||||
override fun onCreateOptionsMenu(menu : Menu) : Boolean {
|
||||
menuInflater.inflate(R.menu.toolbar_log, menu)
|
||||
|
||||
val searchView = menu.findItem(R.id.action_search_log).actionView as SearchView
|
||||
searchView.isSubmitButtonEnabled = false
|
||||
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query : String) : Boolean {
|
||||
searchView.isIconified = false
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onQueryTextChange(newText : String) : Boolean {
|
||||
adapter.filter.filter(newText)
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
/**
|
||||
* This handles menu selection for [R.id.action_clear] and [R.id.action_share_log]
|
||||
*/
|
||||
override fun onOptionsItemSelected(item : MenuItem) : Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.action_clear -> {
|
||||
try {
|
||||
logFile.writeText("")
|
||||
} catch (e : IOException) {
|
||||
Log.w("Logger", "IO Error while clearing the log file: " + e.message)
|
||||
Toast.makeText(applicationContext, getString(R.string.error) + ": ${e.localizedMessage}", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
Toast.makeText(applicationContext, getString(R.string.cleared), Toast.LENGTH_LONG).show()
|
||||
finish()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.action_share_log -> {
|
||||
uploadAndShareLog()
|
||||
true
|
||||
}
|
||||
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This uploads the logs and launches the [Intent.ACTION_SEND] intent
|
||||
*/
|
||||
private fun uploadAndShareLog() {
|
||||
Snackbar.make(findViewById(android.R.id.content), getString(R.string.upload_logs), Snackbar.LENGTH_SHORT).show()
|
||||
|
||||
val shareThread = Thread {
|
||||
var urlConnection : HttpsURLConnection? = null
|
||||
|
||||
try {
|
||||
val url = URL("https://hastebin.com/documents")
|
||||
|
||||
urlConnection = url.openConnection() as HttpsURLConnection
|
||||
urlConnection.requestMethod = "POST"
|
||||
urlConnection.setRequestProperty("Host", "hastebin.com")
|
||||
urlConnection.setRequestProperty("Content-Type", "application/json; charset=utf-8")
|
||||
urlConnection.setRequestProperty("Referer", "https://hastebin.com/")
|
||||
|
||||
urlConnection.outputStream.bufferedWriter().use {
|
||||
it.write(logFile.readText())
|
||||
it.flush()
|
||||
}
|
||||
|
||||
if (urlConnection.responseCode != 200) {
|
||||
Log.e("LogUpload", "HTTPS Status Code: " + urlConnection.responseCode)
|
||||
throw Exception()
|
||||
}
|
||||
|
||||
val bufferedReader = urlConnection.inputStream.bufferedReader()
|
||||
val key = JSONObject(bufferedReader.readText()).getString("key")
|
||||
bufferedReader.close()
|
||||
|
||||
val result = "https://hastebin.com/$key"
|
||||
val sharingIntent = Intent(Intent.ACTION_SEND).setType("text/plain").putExtra(Intent.EXTRA_TEXT, result)
|
||||
|
||||
startActivity(Intent.createChooser(sharingIntent, "Share log url with:"))
|
||||
} catch (e : Exception) {
|
||||
runOnUiThread { Snackbar.make(findViewById(android.R.id.content), getString(R.string.error) + ": ${e.localizedMessage}", Snackbar.LENGTH_LONG).show() }
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
urlConnection!!.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
shareThread.start()
|
||||
}
|
||||
|
||||
/**
|
||||
* This handles on calling [onBackPressed] when [KeyEvent.KEYCODE_BUTTON_B] is lifted
|
||||
*/
|
||||
override fun onKeyUp(keyCode : Int, event : KeyEvent?) : Boolean {
|
||||
if (keyCode == KeyEvent.KEYCODE_BUTTON_B) {
|
||||
onBackPressed()
|
||||
return true
|
||||
}
|
||||
|
||||
return super.onKeyUp(keyCode, event)
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.content.res.use
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.view.isInvisible
|
||||
@ -35,6 +36,7 @@ import emu.skyline.loader.AppEntry
|
||||
import emu.skyline.loader.LoaderResult
|
||||
import emu.skyline.loader.RomFormat
|
||||
import emu.skyline.utils.Settings
|
||||
import emu.skyline.utils.toFile
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
@ -120,7 +122,7 @@ class MainActivity : AppCompatActivity() {
|
||||
binding.swipeRefreshLayout.apply {
|
||||
setProgressBackgroundColorSchemeColor(obtainStyledAttributes(intArrayOf(R.attr.colorPrimary)).use { it.getColor(0, Color.BLACK) })
|
||||
setColorSchemeColors(obtainStyledAttributes(intArrayOf(R.attr.colorAccent)).use { it.getColor(0, Color.BLACK) })
|
||||
post { setDistanceToTriggerSync((binding.swipeRefreshLayout.height / 2.5f).roundToInt()) }
|
||||
post { setDistanceToTriggerSync(binding.swipeRefreshLayout.height / 3) }
|
||||
setOnRefreshListener { loadRoms(false) }
|
||||
}
|
||||
|
||||
@ -128,7 +130,17 @@ class MainActivity : AppCompatActivity() {
|
||||
loadRoms(!settings.refreshRequired)
|
||||
|
||||
binding.searchBar.apply {
|
||||
binding.logIcon.setOnClickListener { startActivity(Intent(context, LogActivity::class.java)) }
|
||||
binding.logIcon.setOnClickListener {
|
||||
val file = applicationContext.filesDir.resolve("skyline.log")
|
||||
if (file.length() != 0L) {
|
||||
val intent = Intent(Intent.ACTION_SEND)
|
||||
.setType("text/plain")
|
||||
.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(this@MainActivity, "skyline.emu.fileprovider", file))
|
||||
startActivity(Intent.createChooser(intent, getString(R.string.log_share_prompt)))
|
||||
} else {
|
||||
Snackbar.make(this@MainActivity.findViewById(android.R.id.content), getString(R.string.logs_not_found), Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
binding.settingsIcon.setOnClickListener { settingsCallback.launch(Intent(context, SettingsActivity::class.java)) }
|
||||
binding.refreshIcon.setOnClickListener { loadRoms(false) }
|
||||
addTextChangedListener(afterTextChanged = { editable ->
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
* Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
*/
|
||||
|
||||
package emu.skyline.adapter
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import emu.skyline.databinding.LogItemBinding
|
||||
import emu.skyline.databinding.LogItemCompactBinding
|
||||
|
||||
data class LogBindingFactory(private val compact : Boolean) : ViewBindingFactory {
|
||||
override fun createBinding(parent : ViewGroup) = if (compact) LogCompactBinding(parent) else LogBinding(parent)
|
||||
}
|
||||
|
||||
interface ILogBinding : ViewBinding {
|
||||
val binding : ViewBinding
|
||||
|
||||
override fun getRoot() = binding.root
|
||||
|
||||
val textTitle : TextView
|
||||
|
||||
val textSubTitle : TextView?
|
||||
}
|
||||
|
||||
class LogCompactBinding(parent : ViewGroup) : ILogBinding {
|
||||
override val binding = LogItemCompactBinding.inflate(parent.inflater(), parent, false)
|
||||
|
||||
override val textTitle = binding.textTitle
|
||||
|
||||
override val textSubTitle : Nothing? = null
|
||||
}
|
||||
|
||||
class LogBinding(parent : ViewGroup) : ILogBinding {
|
||||
override val binding = LogItemBinding.inflate(parent.inflater(), parent, false)
|
||||
|
||||
override val textTitle = binding.textTitle
|
||||
|
||||
override val textSubTitle = binding.textSubtitle
|
||||
}
|
||||
|
||||
data class LogViewItem(private val compact : Boolean, private val message : String, private val level : String) : GenericListItem<ILogBinding>() {
|
||||
override fun getViewBindingFactory() = LogBindingFactory(compact)
|
||||
|
||||
override fun bind(binding : ILogBinding, position : Int) {
|
||||
binding.textTitle.text = message
|
||||
binding.textSubTitle?.text = level
|
||||
|
||||
binding.root.setOnClickListener {
|
||||
it.context.getSystemService(ClipboardManager::class.java).setPrimaryClip(ClipData.newPlainText("Log Message", "$message ($level)"))
|
||||
Toast.makeText(it.context, "Copied to clipboard", Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".LogActivity">
|
||||
|
||||
<include
|
||||
android:id="@+id/titlebar"
|
||||
layout="@layout/titlebar" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/log_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fastScrollEnabled="true"
|
||||
android:focusedByDefault="true"
|
||||
android:transcriptMode="normal"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="15dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:textAppearance="?android:attr/textAppearanceListItem"
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_subtitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/text_title"
|
||||
android:layout_alignStart="@id/text_title"
|
||||
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
|
||||
android:textColor="@android:color/tertiary_text_light"
|
||||
android:textSize="12sp" />
|
||||
</RelativeLayout>
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="vertical"
|
||||
android:padding="1dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</RelativeLayout>
|
@ -53,7 +53,7 @@
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/log"
|
||||
android:contentDescription="@string/share_logs"
|
||||
android:padding="5dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/sub_text"
|
||||
app:layout_constraintEnd_toStartOf="@id/settings_icon"
|
||||
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_search_log"
|
||||
android:icon="@drawable/ic_search"
|
||||
android:title="@string/search"
|
||||
app:actionViewClass="androidx.appcompat.widget.SearchView"
|
||||
app:iconTint="?android:attr/textColorSecondary"
|
||||
app:showAsAction="ifRoom|withText" />
|
||||
<item
|
||||
android:id="@+id/action_share_log"
|
||||
android:icon="@drawable/ic_share"
|
||||
android:title="@string/share"
|
||||
app:iconTint="?android:attr/textColorSecondary"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_clear"
|
||||
android:icon="@drawable/ic_clear"
|
||||
android:title="@string/clear"
|
||||
app:iconTint="?android:attr/textColorSecondary"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
@ -5,8 +5,11 @@
|
||||
<string name="error">An error has occurred</string>
|
||||
<!-- Toolbar Main -->
|
||||
<string name="settings">Settings</string>
|
||||
<string name="log">Logger</string>
|
||||
<string name="share_logs">Share Logs</string>
|
||||
<string name="refresh">Refresh</string>
|
||||
<!-- Toolbar - Share Logs -->
|
||||
<string name="log_share_prompt">Share log file</string>
|
||||
<string name="logs_not_found">No logs were created during the last run</string>
|
||||
<!-- Main -->
|
||||
<string name="all">All</string>
|
||||
<string name="metadata_missing">Metadata Missing</string>
|
||||
@ -18,13 +21,6 @@
|
||||
<string name="invalid_file">Invalid file</string>
|
||||
<string name="missing_title_key">Missing title key</string>
|
||||
<string name="incomplete_prod_keys">Incomplete production keys</string>
|
||||
<!-- Toolbar Logger -->
|
||||
<string name="clear">Clear</string>
|
||||
<string name="share">Share</string>
|
||||
<!-- Logger -->
|
||||
<string name="file_missing">The log file was not found</string>
|
||||
<string name="upload_logs">The logs are being uploaded</string>
|
||||
<string name="cleared">The logs have been cleared</string>
|
||||
<!-- Settings - Emulator -->
|
||||
<string name="emulator">Emulator</string>
|
||||
<string name="search_location">Search Location</string>
|
||||
@ -56,8 +52,8 @@
|
||||
<!-- Settings - Display -->
|
||||
<string name="display">Display</string>
|
||||
<string name="force_triple_buffering">Force Triple Buffering</string>
|
||||
<string name="triple_buffering_enabled">Utilize at least 3 swapchain buffers (Higher FPS with higher input lag)</string>
|
||||
<string name="triple_buffering_disabled">Utilize at least 2 swapchain buffers (Lower FPS with lower input lag)</string>
|
||||
<string name="triple_buffering_enabled">Utilize at least three swapchain buffers (Higher FPS but more input lag)</string>
|
||||
<string name="triple_buffering_disabled">Utilize at least two swapchain buffers (Lower FPS but less input lag)</string>
|
||||
<string name="disable_frame_throttling">Disable Frame Throttling</string>
|
||||
<string name="disable_frame_throttling_enabled">Game is allowed to submit frames as fast as possible (Only for benchmarking)</string>
|
||||
<string name="disable_frame_throttling_disabled">Only allow the game to submit frames at the display refresh rate</string>
|
||||
|
4
app/src/main/res/xml/filepaths.xml
Normal file
4
app/src/main/res/xml/filepaths.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths>
|
||||
<files-path path="/" name="Skyline" />
|
||||
</paths>
|
Loading…
Reference in New Issue
Block a user