Skip to content

Commit

Permalink
finish fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
levinli303 committed Apr 23, 2020
1 parent bfd0449 commit 0b50844
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 9 deletions.
18 changes: 10 additions & 8 deletions app/src/main/java/space/celestia/mobilecelestia/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,12 @@ class MainActivity : AppCompatActivity(),
override fun celestiaLoadingFailed() {
AppStatusReporter.shared().updateStatus("Loading Celestia failed...")
if (customDataDirPath != null || customConfigFilePath != null) {
// Fallback to default
setConfigFilePath(null)
setDataDirectoryPath(null)
runOnUiThread {
removeCelestiaFragment()
showAlert(CelestiaString("Error loading data, fallback to original configuration.", "")) {
// Fallback to default
setConfigFilePath(null)
setDataDirectoryPath(null)
loadLibrarySuccess()
}
}
Expand All @@ -218,7 +218,7 @@ class MainActivity : AppCompatActivity(),

private fun removeCelestiaFragment() {
supportFragmentManager.findFragmentById(R.id.celestia_fragment_container)?.let {
supportFragmentManager.beginTransaction().remove(it).commitAllowingStateLoss()
supportFragmentManager.beginTransaction().hide(it).remove(it).commitAllowingStateLoss()
}
}

Expand Down Expand Up @@ -780,17 +780,19 @@ class MainActivity : AppCompatActivity(),

private fun setConfigFilePath(path: String?) {
preferenceManager[PreferenceManager.PredefinedKey.ConfigFilePath] = path
customConfigFilePath = null
customConfigFilePath = path
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val uri = data?.data
if (uri == null) { return }
val uri = data?.data ?: return
if (requestCode == CONFIG_FILE_REQUEST) {
val path = RealPathUtils.getRealPath(this, uri)
setConfigFilePath(path)
reloadSettings()
} else if (requestCode == DATA_DIR_REQUEST) {
val docUri = DocumentsContract.buildDocumentUriUsingTree(uri, DocumentsContract.getDocumentId(uri))
val path = RealPathUtils.getRealPath(this, DocumentsContract.buildDocumentUriUsingTree(uri, DocumentsContract.getTreeDocumentId(uri)))
setDataDirectoryPath(path)
reloadSettings()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class CelestiaFragment: Fragment(), GLSurfaceView.Renderer, CelestiaControlView.
private var addonToLoad: String? = null
private val core by lazy { CelestiaAppCore.shared() }

private var loadSuccess = false

interface Listener {
fun celestiaFragmentDidRequestActionMenu()
}
Expand Down Expand Up @@ -150,6 +152,8 @@ class CelestiaFragment: Fragment(), GLSurfaceView.Renderer, CelestiaControlView.

glView?.isReady = true

loadSuccess = true

Log.d(TAG, "Ready to display")
AppStatusReporter.shared().celestiaLoadResult(true)
}
Expand All @@ -169,12 +173,16 @@ class CelestiaFragment: Fragment(), GLSurfaceView.Renderer, CelestiaControlView.
}

override fun onSurfaceChanged(p0: GL10?, p1: Int, p2: Int) {
if (!loadSuccess) { return }

glViewSize = Size(p1, p2)
Log.d(TAG, "Resize to $p1 x $p2")
core.resize(p1, p2)
}

override fun onDrawFrame(p0: GL10?) {
if (!loadSuccess) { return }

core.draw()
core.tick()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ class SettingsDataLocationRecyclerViewAdapter(

override fun bindVH(holder: RecyclerView.ViewHolder, item: RecyclerViewItem) {
if (item is DataLocationItem && holder is CommonTextViewHolder) {
val core = CelestiaAppCore.shared()
holder.title.text = item.title
holder.detail.visibility = View.VISIBLE
holder.detail.text = item.subtitle
Expand Down
197 changes: 197 additions & 0 deletions app/src/main/java/space/celestia/mobilecelestia/utils/RealPathUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/*
* RealPathUtils.kt
*
* Copyright (C) 2001-2020, the Celestia Development Team
*
* This program 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.
*/

package space.celestia.mobilecelestia.utils

import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import space.celestia.mobilecelestia.BuildConfig
import java.io.File

object RealPathUtils {
fun getRealPath(
context: Context,
fileUri: Uri
): String? {
return getRealPathFromURIAboveAPI19(context, fileUri)
}

@SuppressLint("NewApi")
private fun getRealPathFromURIAboveAPI19(
context: Context,
uri: Uri
): String? {
// DocumentProvider
when {
DocumentsContract.isDocumentUri(context, uri) -> {
// ExternalStorageProvider
when {
isExternalStorageDocument(uri) -> {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":").toTypedArray()
val type = split[0]

// This is for checking Main Memory
return if ("primary".equals(type, ignoreCase = true)) {
if (split.size > 1) {
getExternalStorageDirectory(context) + "/" + split[1]
} else {
getExternalStorageDirectory(context) + "/"
}
// This is for checking SD Card
} else {
"storage" + "/" + docId.replace(":", "/")
}
}
isDownloadsDocument(uri) -> {
val fileName = getFilePath(context, uri)
if (fileName != null) {
return getExternalStorageDirectory(context) + "/Download/" + fileName
}
val id = DocumentsContract.getDocumentId(uri)
val contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"),
java.lang.Long.valueOf(id)
)
return getDataColumn(context, contentUri, null, null)
}
isMediaDocument(uri) -> {
val docId = DocumentsContract.getDocumentId(uri)
val split = docId.split(":").toTypedArray()
val type = split[0]
var contentUri: Uri? = null
when (type) {
"image" -> {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
"video" -> {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
}
"audio" -> {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
}
val selection = "_id=?"
val selectionArgs = arrayOf(
split[1]
)
return getDataColumn(context, contentUri, selection, selectionArgs)
}
}
}
"content".equals(uri.scheme, ignoreCase = true) -> {
// Return the remote address
return if (isGooglePhotosUri(uri)) uri.lastPathSegment else getDataColumn(
context,
uri,
null,
null
)
}
"file".equals(uri.scheme, ignoreCase = true) -> {
return uri.path
}
}
return null
}

private fun getExternalStorageDirectory(context: Context): String {
val rootPath = context.getExternalFilesDir(null)?.absolutePath ?: return ""
val extra = "/Android/data/" + BuildConfig.APPLICATION_ID + File.separator + "files"
return rootPath.replace(extra, "")
}

private fun getDataColumn(
context: Context, uri: Uri?, selection: String?,
selectionArgs: Array<String>?
): String? {
var cursor: Cursor? = null
val column = "_data"
val projection = arrayOf(
column
)
try {
cursor = context.contentResolver.query(
uri!!, projection, selection, selectionArgs,
null
)
if (cursor != null && cursor.moveToFirst()) {
val index: Int = cursor.getColumnIndexOrThrow(column)
return cursor.getString(index)
}
} finally {
cursor?.close()
}
return null
}


private fun getFilePath(
context: Context,
uri: Uri
): String? {
var cursor: Cursor? = null
val projection = arrayOf(
MediaStore.MediaColumns.DISPLAY_NAME
)
try {
cursor = context.contentResolver.query(
uri, projection, null, null,
null
)
if (cursor != null && cursor.moveToFirst()) {
val index: Int = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)
return cursor.getString(index)
}
} finally {
cursor?.close()
}
return null
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
private fun isExternalStorageDocument(uri: Uri): Boolean {
return "com.android.externalstorage.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
private fun isDownloadsDocument(uri: Uri): Boolean {
return "com.android.providers.downloads.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private fun isMediaDocument(uri: Uri): Boolean {
return "com.android.providers.media.documents" == uri.authority
}

/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
private fun isGooglePhotosUri(uri: Uri): Boolean {
return "com.google.android.apps.photos.content" == uri.authority
}
}

0 comments on commit 0b50844

Please sign in to comment.