mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-03-06 00:29:34 +00:00
Route Android logging to native side and timestamp logs
This commit is contained in:
parent
46b74f65fa
commit
310825e2cc
@ -30,6 +30,7 @@ import android.widget.Toast;
|
||||
|
||||
import org.deadc0de.apple2ix.basic.BuildConfig;
|
||||
import org.deadc0de.apple2ix.basic.R;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@ -96,6 +97,8 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
|
||||
private static native void nativeReboot(int resetState);
|
||||
|
||||
private static native void nativeLogMessage(String jsonStr);
|
||||
|
||||
public final static boolean isNativeBarfed() {
|
||||
return sNativeBarfed;
|
||||
}
|
||||
@ -118,7 +121,7 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
}
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Log.e(TAG, "onCreate()");
|
||||
logMessage(LogType.ERROR, TAG, "onCreate()");
|
||||
|
||||
// placeholder view on initial launch
|
||||
if (mView == null) {
|
||||
@ -127,14 +130,14 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
|
||||
Apple2CrashHandler.getInstance().initializeAndSetCustomExceptionHandler(this);
|
||||
if (sNativeBarfed) {
|
||||
Log.e(TAG, "NATIVE BARFED...", sNativeBarfedThrowable);
|
||||
logMessage(LogType.ERROR, TAG, "NATIVE BARFED : " + sNativeBarfedThrowable.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
int sampleRate = DevicePropertyCalculator.getRecommendedSampleRate(this);
|
||||
int monoBufferSize = DevicePropertyCalculator.getRecommendedBufferSize(this, /*isStereo:*/false);
|
||||
int stereoBufferSize = DevicePropertyCalculator.getRecommendedBufferSize(this, /*isStereo:*/true);
|
||||
Log.d(TAG, "Device sampleRate:" + sampleRate + " mono bufferSize:" + monoBufferSize + " stereo bufferSize:" + stereoBufferSize);
|
||||
logMessage(LogType.DEBUG, TAG, "Device sampleRate:" + sampleRate + " mono bufferSize:" + monoBufferSize + " stereo bufferSize:" + stereoBufferSize);
|
||||
|
||||
String dataDir = Apple2Utils.getDataDir(this);
|
||||
nativeOnCreate(dataDir, sampleRate, monoBufferSize, stereoBufferSize);
|
||||
@ -185,7 +188,7 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
Apple2Utils.exposeAPKAssets(Apple2Activity.this);
|
||||
if (externalStoragePermission) {
|
||||
Apple2Utils.exposeAPKAssetsToExternal(Apple2Activity.this);
|
||||
Log.d(TAG, "Finished first time copying #1...");
|
||||
logMessage(LogType.DEBUG, TAG, "Finished first time copying #1...");
|
||||
|
||||
if (!(boolean)Apple2Preferences.getJSONPref(Apple2Preferences.PREF_DOMAIN_INTERFACE, Apple2Preferences.PREF_RELEASE_NOTES, false)) {
|
||||
Runnable myRunnable = new Runnable() {
|
||||
@ -232,7 +235,7 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
// perform migration(s) and assets exposure now
|
||||
Apple2Utils.migrateToExternalStorage(Apple2Activity.this);
|
||||
Apple2Utils.exposeAPKAssetsToExternal(Apple2Activity.this);
|
||||
Log.d(TAG, "Finished first time copying #2...");
|
||||
logMessage(LogType.DEBUG, TAG, "Finished first time copying #2...");
|
||||
} // else ... we keep nagging on app startup ...
|
||||
} else {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
@ -253,7 +256,7 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
break;
|
||||
}
|
||||
|
||||
Log.d(TAG, "onResume()");
|
||||
logMessage(LogType.DEBUG, TAG, "onResume()");
|
||||
showSplashScreen(/*dismissable:*/true);
|
||||
if (!mSwitchingToPortrait.get()) {
|
||||
Apple2CrashHandler.getInstance().checkForCrashes(this); // NOTE : needs to be called again to clean-up
|
||||
@ -320,10 +323,10 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
if (isEmulationPaused()) {
|
||||
Apple2Preferences.save(this);
|
||||
} else {
|
||||
Log.d(TAG, "Letting native save preferences...");
|
||||
logMessage(LogType.DEBUG, TAG, "Letting native save preferences...");
|
||||
}
|
||||
|
||||
Log.d(TAG, "onPause()");
|
||||
logMessage(LogType.DEBUG, TAG, "onPause()");
|
||||
if (mView != null) {
|
||||
mView.onPause();
|
||||
}
|
||||
@ -415,7 +418,7 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
} catch (InterruptedIOException e) {
|
||||
/* EINTR, EAGAIN */
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "OOPS could not load release_notes.txt!", e);
|
||||
logMessage(LogType.ERROR, TAG, "OOPS could not load release_notes.txt : " + e.getMessage());
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
@ -620,4 +623,30 @@ public class Apple2Activity extends AppCompatActivity implements Apple2DiskChoos
|
||||
}
|
||||
}.run();
|
||||
}
|
||||
|
||||
public enum LogType {
|
||||
// Constants match
|
||||
VERBOSE(2),
|
||||
DEBUG(3),
|
||||
INFO(4),
|
||||
WARN(5),
|
||||
ERROR(6);
|
||||
private int type;
|
||||
|
||||
LogType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public static void logMessage(LogType type, String tag, String mesg) {
|
||||
JSONObject map = new JSONObject();
|
||||
try {
|
||||
map.put("type", type.type);
|
||||
map.put("tag", tag);
|
||||
map.put("mesg", mesg);
|
||||
nativeLogMessage(map.toString());
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "OOPS: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,24 +221,24 @@ public class Apple2CrashHandler {
|
||||
|
||||
// here we assume that the crash data was previously sent via email ... if not then we lost it =P
|
||||
|
||||
Log.d(TAG, "Cleaning up crash data ...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Cleaning up crash data ...");
|
||||
int idx = 0;
|
||||
File[] nativeCrashes = _nativeCrashFiles(activity);
|
||||
for (File crash : nativeCrashes) {
|
||||
|
||||
if (!crash.delete()) {
|
||||
Log.d(TAG, "Could not unlink crash : " + crash);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Could not unlink crash : " + crash);
|
||||
}
|
||||
|
||||
File processed = new File(_dumpPath2ProcessedPath(crash.getAbsolutePath()));
|
||||
if (!processed.delete()) {
|
||||
Log.d(TAG, "Could not unlink processed : " + processed);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Could not unlink processed : " + processed);
|
||||
}
|
||||
}
|
||||
|
||||
File javaCrashFile = _javaCrashFile(activity);
|
||||
if (!javaCrashFile.delete()) {
|
||||
Log.d(TAG, "Could not unlink java crash : " + javaCrashFile);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Could not unlink java crash : " + javaCrashFile);
|
||||
}
|
||||
|
||||
// remove previous log file
|
||||
@ -339,7 +339,7 @@ public class Apple2CrashHandler {
|
||||
for (File crash : nativeCrashes) {
|
||||
|
||||
String crashPath = crash.getAbsolutePath();
|
||||
Log.d(TAG, "Processing crash : " + crashPath);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Processing crash : " + crashPath);
|
||||
|
||||
String processedPath = _dumpPath2ProcessedPath(crashPath);
|
||||
try {
|
||||
@ -350,7 +350,7 @@ public class Apple2CrashHandler {
|
||||
|
||||
StringBuilder crashData = new StringBuilder();
|
||||
if (!Apple2Utils.readEntireFile(new File(processedPath), crashData)) {
|
||||
Log.e(TAG, "Error processing crash : " + crashPath);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Error processing crash : " + crashPath);
|
||||
}
|
||||
allCrashData.append(">>>>>>> NATIVE CRASH [").append(crashPath).append("]\n");
|
||||
allCrashData.append(crashData);
|
||||
@ -410,9 +410,9 @@ public class Apple2CrashHandler {
|
||||
StringBuilder javaCrashData = new StringBuilder();
|
||||
File javaCrashFile = _javaCrashFile(activity);
|
||||
if (javaCrashFile.exists()) {
|
||||
Log.d(TAG, "Reading java crashes file");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Reading java crashes file");
|
||||
if (!Apple2Utils.readEntireFile(javaCrashFile, javaCrashData)) {
|
||||
Log.e(TAG, "Error processing java crash : " + javaCrashFileName);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Error processing java crash : " + javaCrashFileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ public class Apple2CrashHandler {
|
||||
try {
|
||||
obj = new JSONObject(jsonData.toString());
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error reading preferences : " + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Error reading preferences : " + e);
|
||||
}
|
||||
if (obj != null) {
|
||||
summary.append("PREFS:\n");
|
||||
@ -511,7 +511,7 @@ public class Apple2CrashHandler {
|
||||
} catch (InterruptedIOException ie) {
|
||||
/* EINTR, EAGAIN ... */
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Exception attempting to write data : " + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Exception attempting to write data : " + e);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -564,7 +564,7 @@ public class Apple2CrashHandler {
|
||||
} else {
|
||||
allCrashFile = new File(Apple2Utils.getDataDir(activity), "apple2ix_crash.txt");
|
||||
}
|
||||
Log.d(TAG, "Writing all crashes to temp file : " + allCrashFile.getAbsolutePath());
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Writing all crashes to temp file : " + allCrashFile.getAbsolutePath());
|
||||
return allCrashFile;
|
||||
}
|
||||
|
||||
@ -588,14 +588,14 @@ public class Apple2CrashHandler {
|
||||
File allCrashFile = _getCrashFile(activity);
|
||||
Apple2Utils.writeFile(allCrashData, allCrashFile);
|
||||
if (!allCrashFile.setReadable(true, /*ownerOnly:*/false)) {
|
||||
Log.d(TAG, "Oops, could not set file data readable!");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Oops, could not set file data readable!");
|
||||
}
|
||||
|
||||
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(allCrashFile));
|
||||
|
||||
Log.d(TAG, "STARTING CHOOSER FOR EMAIL ...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "STARTING CHOOSER FOR EMAIL ...");
|
||||
activity.startActivity(Intent.createChooser(emailIntent, "Send email"));
|
||||
Log.d(TAG, "AFTER START ACTIVITY ...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "AFTER START ACTIVITY ...");
|
||||
}
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@ public class Apple2DiskChooserActivity extends AppCompatActivity {
|
||||
resolver.takePersistableUriPermission(uri, (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
|
||||
pfd = resolver.openFileDescriptor(uri, "rw");
|
||||
} catch (Throwable t) {
|
||||
Log.e(TAG, "OOPS, could not get appropriate access to URI ( " + uri + " ) : " + t);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS, could not get appropriate access to URI ( " + uri + " ) : " + t);
|
||||
}
|
||||
|
||||
return pfd;
|
||||
@ -83,7 +83,7 @@ public class Apple2DiskChooserActivity extends AppCompatActivity {
|
||||
fileName = returnCursor.getString(nameIndex);
|
||||
|
||||
} catch (Throwable t) {
|
||||
Log.e(TAG, "OOPS, could not get filename from URI ( " + uri + " ) : " + t);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS, could not get filename from URI ( " + uri + " ) : " + t);
|
||||
}
|
||||
|
||||
return fileName;
|
||||
@ -118,7 +118,7 @@ public class Apple2DiskChooserActivity extends AppCompatActivity {
|
||||
|
||||
boolean ran = b.getBoolean("ran");
|
||||
if (ran) {
|
||||
Log.e(TAG, "OOPS, already ran...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS, already ran...");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
@ -139,7 +139,7 @@ public class Apple2DiskChooserActivity extends AppCompatActivity {
|
||||
startActivityForResult(pickIntent, EDIT_REQUEST_CODE);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
Log.e(TAG, "OOPS : " + t);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS : " + t);
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
||||
try {
|
||||
diskArgs.pfd.close();
|
||||
} catch (IOException ioe) {
|
||||
Log.e(TAG, "Error attempting to close PFD : " + ioe);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Error attempting to close PFD : " + ioe);
|
||||
}
|
||||
}
|
||||
diskArgs.pfd = null;
|
||||
@ -381,7 +381,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
||||
}
|
||||
|
||||
} catch (Throwable t) {
|
||||
Log.d(TAG, "OOPS: " + t);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "OOPS: " + t);
|
||||
}
|
||||
}
|
||||
|
||||
@ -739,7 +739,7 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
|
||||
if (isDirectory[position]) {
|
||||
Log.d(TAG, "Descending to path : " + filePaths[position]);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Descending to path : " + filePaths[position]);
|
||||
if (parentIsRootPath && !new File(filePaths[position]).isAbsolute()) {
|
||||
pushPathStack(parentDisksDir + File.separator + filePaths[position]);
|
||||
} else {
|
||||
|
@ -108,7 +108,7 @@ public class Apple2JoystickCalibration implements Apple2MenuView {
|
||||
joystickPollerThread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(TAG, "Starting joystick poll thread...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.INFO, TAG, "Starting joystick poll thread...");
|
||||
try {
|
||||
while (true) {
|
||||
long cxy = nativePollJoystick();
|
||||
@ -139,7 +139,7 @@ public class Apple2JoystickCalibration implements Apple2MenuView {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.i(TAG, "Stopping joystick poll thread...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.INFO, TAG, "Stopping joystick poll thread...");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -216,7 +216,7 @@ public class Apple2KeyboardSettingsMenu extends Apple2AbstractMenu {
|
||||
File keyboardDir = new File(Apple2Utils.getDataDir(activity) + File.separator + "keyboards");
|
||||
files = keyboardDir.listFiles(kbdJsonFilter);
|
||||
if (files == null) {
|
||||
Log.e(TAG, "OOPS, could not read keyboard data directory");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS, could not read keyboard data directory");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public class Apple2KeypadChooser implements Apple2MenuView {
|
||||
}
|
||||
|
||||
String asciiStr = asciiRepresentation(mActivity, ascii);
|
||||
Log.d(TAG, "ascii:'" + asciiStr + "' scancode:" + scancode);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "ascii:'" + asciiStr + "' scancode:" + scancode);
|
||||
if (ascii == ' ') {
|
||||
ascii = Apple2KeyboardSettingsMenu.ICONTEXT_VISUAL_SPACE;
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ public class Apple2MainMenu {
|
||||
mainMenuView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Log.d(TAG, "position:" + position + " tapped...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "position:" + position + " tapped...");
|
||||
SETTINGS setting = SETTINGS.values()[position];
|
||||
setting.handleSelection(Apple2MainMenu.this);
|
||||
}
|
||||
@ -337,12 +337,12 @@ public class Apple2MainMenu {
|
||||
try {
|
||||
diskArgs.pfd.close(); // at this point diskArgs.pfd !null
|
||||
} catch (IOException ioe) {
|
||||
Log.e(TAG, "Error attempting to close PFD : " + ioe);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Error attempting to close PFD : " + ioe);
|
||||
}
|
||||
diskArgs.pfd = null;
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "OOPS: " + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS: " + e);
|
||||
}
|
||||
|
||||
return restored;
|
||||
@ -386,7 +386,7 @@ public class Apple2MainMenu {
|
||||
|
||||
pfds[i] = Apple2DiskChooserActivity.openFileDescriptorFromUri(activity, uri);
|
||||
if (pfds[i] == null) {
|
||||
Log.e(TAG, "Did not find URI for drive #" + i + " specified in " + SAVE_FILE + " file : " + diskPath);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Did not find URI for drive #" + i + " specified in " + SAVE_FILE + " file : " + diskPath);
|
||||
} else {
|
||||
int fd = pfds[i].getFd();
|
||||
map.put(fdKeys[i], fd);
|
||||
@ -394,7 +394,7 @@ public class Apple2MainMenu {
|
||||
} else {
|
||||
boolean exists = new File(diskPath).exists();
|
||||
if (!exists) {
|
||||
Log.e(TAG, "Did not find path for drive #" + i + " specified in " + SAVE_FILE + " file : " + diskPath);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Did not find path for drive #" + i + " specified in " + SAVE_FILE + " file : " + diskPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -407,7 +407,7 @@ public class Apple2MainMenu {
|
||||
pfds[i].close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
Log.e(TAG, "Error attempting to close PFD #" + i + " : " + ioe);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Error attempting to close PFD #" + i + " : " + ioe);
|
||||
}
|
||||
}
|
||||
map = new JSONObject(jsonString);
|
||||
|
@ -103,7 +103,7 @@ public class Apple2Preferences {
|
||||
key = menu.getPrefKey();
|
||||
val = map.get(key);
|
||||
} catch (JSONException e) {
|
||||
Log.d(TAG, "Did not find value for domain:" + menu.getPrefDefault() + " key:" + key);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Did not find value for domain:" + menu.getPrefDefault() + " key:" + key);
|
||||
}
|
||||
if (val == null && key != null) {
|
||||
val = menu.getPrefDefault();
|
||||
@ -123,7 +123,7 @@ public class Apple2Preferences {
|
||||
map = _prefDomain(domain);
|
||||
val = map.get(key);
|
||||
} catch (JSONException e) {
|
||||
Log.d(TAG, "Did not find value for domain:" + domain + " key:" + key);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Did not find value for domain:" + domain + " key:" + key);
|
||||
}
|
||||
if (val == null) {
|
||||
val = defaultVal;
|
||||
@ -143,17 +143,17 @@ public class Apple2Preferences {
|
||||
try {
|
||||
return (float) obj;
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "could not cast object as float");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "could not cast object as float");
|
||||
}
|
||||
try {
|
||||
return (float) ((double) obj);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "could not cast object as double");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "could not cast object as double");
|
||||
}
|
||||
try {
|
||||
return (float) ((int) obj);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "could not cast object as int");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "could not cast object as int");
|
||||
}
|
||||
return (float) ((long) obj);
|
||||
}
|
||||
@ -165,17 +165,17 @@ public class Apple2Preferences {
|
||||
try {
|
||||
return (int) obj;
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "could not cast object as int");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "could not cast object as int");
|
||||
}
|
||||
try {
|
||||
return (int) ((long) obj);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "could not cast object as long");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "could not cast object as long");
|
||||
}
|
||||
try {
|
||||
return (int) ((float) obj);
|
||||
} catch (ClassCastException e) {
|
||||
Log.d(TAG, "could not cast object as float");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "could not cast object as float");
|
||||
}
|
||||
return (int) ((double) obj);
|
||||
}
|
||||
@ -249,7 +249,7 @@ public class Apple2Preferences {
|
||||
|
||||
jsonArray = (JSONArray) getJSONPref(PREF_DOMAIN_JOYSTICK, "kpAxisRosetteChars", null);
|
||||
if (jsonArray == null || jsonArray.length() != Apple2KeypadSettingsMenu.ROSETTE_SIZE) {
|
||||
Log.e(TAG, "Oops, kpAxisRosetteChars is not expected length");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Oops, kpAxisRosetteChars is not expected length");
|
||||
} else {
|
||||
for (int i = 0; i < Apple2KeypadSettingsMenu.ROSETTE_SIZE; i++) {
|
||||
Apple2KeypadSettingsMenu.KeyTuple tuple = axisRosette.get(i);
|
||||
@ -259,7 +259,7 @@ public class Apple2Preferences {
|
||||
|
||||
jsonArray = (JSONArray) getJSONPref(PREF_DOMAIN_JOYSTICK, "kpAxisRosetteScancodes", null);
|
||||
if (jsonArray == null || jsonArray.length() != Apple2KeypadSettingsMenu.ROSETTE_SIZE) {
|
||||
Log.e(TAG, "Oops, kpAxisRosetteScancodes is not expected length");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Oops, kpAxisRosetteScancodes is not expected length");
|
||||
} else {
|
||||
for (int i = 0; i < Apple2KeypadSettingsMenu.ROSETTE_SIZE; i++) {
|
||||
Apple2KeypadSettingsMenu.KeyTuple tuple = axisRosette.get(i);
|
||||
@ -333,7 +333,7 @@ public class Apple2Preferences {
|
||||
|
||||
StringBuilder jsonString = new StringBuilder();
|
||||
if (!Apple2Utils.readEntireFile(prefsFile, jsonString)) {
|
||||
Log.d(TAG, "Oops, could not read JSON file : " + prefsFile);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Oops, could not read JSON file : " + prefsFile);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -359,7 +359,7 @@ public class Apple2Preferences {
|
||||
try {
|
||||
jsonString = sSettings.toString(2);
|
||||
} catch (JSONException e) {
|
||||
Log.w(TAG, "Error attempting to pretty-print JSON : " + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.WARN, TAG, "Error attempting to pretty-print JSON : " + e);
|
||||
ex = e;
|
||||
jsonString = sSettings.toString();
|
||||
}
|
||||
|
@ -425,7 +425,7 @@ public class Apple2SettingsMenu extends Apple2AbstractMenu {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.d(TAG, "About to NPE : " + str[0].length());
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "About to NPE : " + str[0].length());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public class Apple2Utils {
|
||||
} catch (InterruptedIOException ie) {
|
||||
/* EINTR, EAGAIN ... */
|
||||
} catch (IOException e) {
|
||||
Log.d(TAG, "Error reading file at path : " + file.toString());
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Error reading file at path : " + file.toString());
|
||||
}
|
||||
|
||||
try {
|
||||
@ -89,7 +89,7 @@ public class Apple2Utils {
|
||||
} catch (InterruptedIOException ie) {
|
||||
/* EINTR, EAGAIN ... */
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Exception attempting to write data : " + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Exception attempting to write data : " + e);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -182,7 +182,7 @@ public class Apple2Utils {
|
||||
if (!externalDir.exists()) {
|
||||
boolean made = externalDir.mkdirs();
|
||||
if (!made) {
|
||||
Log.d(TAG, "WARNING: could not make directory : " + sExternalFilesDir);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "WARNING: could not make directory : " + sExternalFilesDir);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -218,7 +218,7 @@ public class Apple2Utils {
|
||||
PackageInfo pi = pm.getPackageInfo(activity.getPackageName(), 0);
|
||||
sDataDir = pi.applicationInfo.dataDir;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "" + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "" + e);
|
||||
if (sDataDir == null) {
|
||||
sDataDir = "/data/local/tmp";
|
||||
}
|
||||
@ -285,7 +285,7 @@ public class Apple2Utils {
|
||||
recursivelyDelete(new File(new File(sDataDir, "disks").getAbsolutePath(), "logo"));
|
||||
recursivelyDelete(new File(new File(sDataDir, "disks").getAbsolutePath(), "miscgame"));
|
||||
|
||||
Log.d(TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
|
||||
|
||||
getExternalStorageDirectory(activity);
|
||||
recursivelyCopyAPKAssets(activity, /*from APK directory:*/"disks", /*to location:*/new File(sDataDir, "disks").getAbsolutePath(), true);
|
||||
@ -321,7 +321,7 @@ public class Apple2Utils {
|
||||
}
|
||||
}
|
||||
if (!file.delete()) {
|
||||
Log.d(TAG, "Failed to delete file: " + file);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "Failed to delete file: " + file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,7 +338,7 @@ public class Apple2Utils {
|
||||
} catch (InterruptedIOException e) {
|
||||
/* EINTR, EAGAIN ... */
|
||||
} catch (IOException e) {
|
||||
Log.d(TAG, "OOPS exception attempting to list APK files at : " + srcFileOrDir + " : " + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "OOPS exception attempting to list APK files at : " + srcFileOrDir + " : " + e);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -350,7 +350,7 @@ public class Apple2Utils {
|
||||
} while (attempts < maxAttempts);
|
||||
|
||||
if (files == null) {
|
||||
Log.d(TAG, "OOPS, could not list APK assets at : " + srcFileOrDir);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "OOPS, could not list APK assets at : " + srcFileOrDir);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -359,7 +359,7 @@ public class Apple2Utils {
|
||||
File dstPath = new File(dstFileOrDir);
|
||||
if (!dstPath.mkdirs()) {
|
||||
if (!dstPath.exists()) {
|
||||
Log.d(TAG, "OOPS, could not mkdirs on " + dstPath);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "OOPS, could not mkdirs on " + dstPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -387,7 +387,7 @@ public class Apple2Utils {
|
||||
} catch (InterruptedIOException e) {
|
||||
/* EINTR, EAGAIN */
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Failed to copy asset file: " + srcFileOrDir, e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "Failed to copy asset file: " + srcFileOrDir + " : " + e.getMessage());
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
@ -462,7 +462,7 @@ public class Apple2Utils {
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "OOPS : {e}");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS : {e}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,7 +478,7 @@ public class Apple2Utils {
|
||||
} catch (InterruptedIOException e) {
|
||||
// EINTR, EAGAIN ...
|
||||
} catch (IOException e) {
|
||||
Log.d(TAG, "OOPS exception attempting to copy emulator state file : " + e);
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.DEBUG, TAG, "OOPS exception attempting to copy emulator state file : " + e);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -136,7 +136,7 @@ class Apple2View extends GLSurfaceView implements InputManagerCompat.InputDevice
|
||||
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
||||
|
||||
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
|
||||
Log.w(TAG, "creating OpenGL ES 2.0 context");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.WARN, TAG, "creating OpenGL ES 2.0 context");
|
||||
checkEglError("Before eglCreateContext", egl);
|
||||
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE};
|
||||
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
|
||||
@ -152,7 +152,7 @@ class Apple2View extends GLSurfaceView implements InputManagerCompat.InputDevice
|
||||
private static void checkEglError(String prompt, EGL10 egl) {
|
||||
int error;
|
||||
while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
|
||||
Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, String.format("%s: EGL error: 0x%x", prompt, error));
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,9 +204,9 @@ class Apple2View extends GLSurfaceView implements InputManagerCompat.InputDevice
|
||||
// Now return the "best" one
|
||||
EGLConfig best = chooseConfig(egl, display, configs);
|
||||
if (best == null) {
|
||||
Log.e(TAG, "OOPS! Did not pick an EGLConfig. What device are you using?! Android will now crash this app...");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.ERROR, TAG, "OOPS! Did not pick an EGLConfig. What device are you using?! Android will now crash this app...");
|
||||
} else {
|
||||
Log.w(TAG, "Using EGL CONFIG : ");
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.WARN, TAG, "Using EGL CONFIG : ");
|
||||
printConfig(egl, display, best);
|
||||
}
|
||||
return best;
|
||||
@ -245,9 +245,9 @@ class Apple2View extends GLSurfaceView implements InputManagerCompat.InputDevice
|
||||
|
||||
private void printConfigs(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
|
||||
int numConfigs = configs.length;
|
||||
Log.w(TAG, String.format("%d configurations", numConfigs));
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.WARN, TAG, String.format("%d configurations", numConfigs));
|
||||
for (int i = 0; i < numConfigs; i++) {
|
||||
Log.w(TAG, String.format("Configuration %d:\n", i));
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.WARN, TAG, String.format("Configuration %d:\n", i));
|
||||
printConfig(egl, display, configs[i]);
|
||||
}
|
||||
}
|
||||
@ -328,9 +328,9 @@ class Apple2View extends GLSurfaceView implements InputManagerCompat.InputDevice
|
||||
int attribute = attributes[i];
|
||||
String name = names[i];
|
||||
if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
|
||||
Log.w(TAG, String.format(" %s: %d\n", name, value[0]));
|
||||
Apple2Activity.logMessage(Apple2Activity.LogType.WARN, TAG, String.format(" %s: %d\n", name, value[0]));
|
||||
} else {
|
||||
// Log.w(TAG, String.format(" %s: failed\n", name));
|
||||
// Apple2Activity.logMessage(Apple2Activity.LogType.WARN, TAG, String.format(" %s: failed\n", name));
|
||||
while (egl.eglGetError() != EGL10.EGL_SUCCESS) ;
|
||||
}
|
||||
}
|
||||
|
@ -627,3 +627,37 @@ jlong Java_org_deadc0de_apple2ix_Apple2JoystickCalibration_nativePollJoystick(JN
|
||||
return cxy;
|
||||
}
|
||||
|
||||
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeLogMessage(JNIEnv *env, jclass cls, jstring jJsonString) {
|
||||
#if TESTING
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
const char *jsonString = (*env)->GetStringUTFChars(env, jJsonString, NULL);
|
||||
|
||||
JSON_ref jsonData = NULL;
|
||||
bool ret = json_createFromString(jsonString, &jsonData);
|
||||
assert(ret > 0);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, jJsonString, jsonString); jsonString = NULL;
|
||||
|
||||
long type = LOG_TYPE_INFO;
|
||||
json_mapParseLongValue(jsonData, "type", &type, 10);
|
||||
|
||||
char *tag = NULL;
|
||||
json_mapCopyStringValue(jsonData, "tag", &tag);
|
||||
|
||||
char *mesg = NULL;
|
||||
json_mapCopyStringValue(jsonData, "mesg", &mesg);
|
||||
|
||||
log_taggedOutputString((log_type_t)type, tag, mesg);
|
||||
|
||||
if (tag) {
|
||||
FREE(tag);
|
||||
}
|
||||
if (mesg) {
|
||||
FREE(mesg);
|
||||
}
|
||||
|
||||
json_destroy(&jsonData);
|
||||
}
|
||||
|
||||
|
@ -95,14 +95,25 @@ void log_init(void) {
|
||||
}
|
||||
|
||||
void log_outputString(const char * const str) {
|
||||
log_taggedOutputString(LOG_TYPE_INFO, NULL, str);
|
||||
}
|
||||
|
||||
void log_taggedOutputString(log_type_t type, const char * const tag, const char * const str) {
|
||||
if (UNLIKELY(!str)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(NDEBUG)
|
||||
// TODO : make logging level dynamic+configurable ...
|
||||
if (type <= LOG_TYPE_DEBUG) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DO_STDERR_LOGGING
|
||||
{
|
||||
#if defined(__ANDROID__) && !defined(NDEBUG)
|
||||
__android_log_print(ANDROID_LOG_ERROR, "apple2ix", "%s", str);
|
||||
__android_log_print(type, tag ? tag : "apple2ix", "%s", str);
|
||||
#else
|
||||
fprintf(stderr, "%s\n", str);
|
||||
#endif
|
||||
@ -113,14 +124,31 @@ void log_outputString(const char * const str) {
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate timestamp ...
|
||||
char timestamp[32];
|
||||
{
|
||||
time_t secs = time(NULL);
|
||||
struct tm timeinfo = { 0 };
|
||||
struct tm *t = gmtime_r(&secs, &timeinfo);
|
||||
assert(t != NULL);
|
||||
size_t count = strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &timeinfo);
|
||||
assert(count == 19);
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
ASPRINTF(&buf, "%s %s %s", timestamp, tag ? tag : "-", str);
|
||||
if (UNLIKELY(!buf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
|
||||
size_t expected_bytescount = strlen(str);
|
||||
size_t expected_bytescount = strlen(buf);
|
||||
size_t bytescount = 0;
|
||||
|
||||
do {
|
||||
ssize_t byteswritten = 0;
|
||||
TEMP_FAILURE_RETRY(byteswritten = write(logFd, str+bytescount, expected_bytescount-bytescount));
|
||||
TEMP_FAILURE_RETRY(byteswritten = write(logFd, buf+bytescount, expected_bytescount-bytescount));
|
||||
if (UNLIKELY(byteswritten <= 0)) {
|
||||
break; // OOPS !
|
||||
}
|
||||
@ -139,6 +167,8 @@ void log_outputString(const char * const str) {
|
||||
}
|
||||
} while (1);
|
||||
|
||||
FREE(buf);
|
||||
|
||||
if (UNLIKELY(bytescount != expected_bytescount)) {
|
||||
// logging is b0rked, shut it down ...
|
||||
_log_stopLogging();
|
||||
|
@ -16,6 +16,15 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// NOTE: These match Android settings
|
||||
typedef enum log_type_t {
|
||||
LOG_TYPE_VERBOSE = 2,
|
||||
LOG_TYPE_DEBUG,
|
||||
LOG_TYPE_INFO,
|
||||
LOG_TYPE_WARN,
|
||||
LOG_TYPE_ERROR,
|
||||
} log_type_t;
|
||||
|
||||
#if VIDEO_OPENGL
|
||||
extern GLenum safeGLGetError(void);
|
||||
#else
|
||||
@ -29,6 +38,9 @@ void log_init(void);
|
||||
// print a string to the log file. Terminating '\n' is added.
|
||||
void log_outputString(const char * const str);
|
||||
|
||||
// print a tag + string to the log file. Terminating '\n' is added.
|
||||
void log_taggedOutputString(log_type_t type, const char * const tag, const char * const str);
|
||||
|
||||
#define _MYFILE_ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
|
||||
|
||||
#define _SIMPLE_LOG(...) \
|
||||
|
Loading…
x
Reference in New Issue
Block a user