I have one very unusual case when calling an Android hidden API over reflection freezes the calling thread eternally. I cannot debug the underlying code as it is a code from Android itself normally not visible. I tried running the code in an asynctask, in a normal thread but nor asynctask.cancel nor thread.interrupt kills the thread, the thread stays visible, I can see it while debugging. Is it really not possible to run a code encapsulated and kill it completely eventually? This problems occurs only on Android O and only on some devices, that's why I need to test-run it to see if it works on the current device and be able to activate a feature according to that. The code below, I don't really see a solution for this:
Thread endCallThread;
Runnable myRunnable;
private void checkFeatureSupport(final Context context) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
myRunnable = new Runnable() {
@Override
public void run() {
doInBackgroundWrapper();
if (getActivity() != null) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//handleResult();
}
});
}
}
};
endCallThread = new Thread(myRunnable, "endCallThread");
endCallThread.start();
new CountDownTimer(3000, 3000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
Log.e("TESTAUTOMATION", "endCall did not finished in 3 seconds");
// stop async task if not in progress
if (endCallThread.isAlive()) {
try {
endCallThread.interrupt();
endCallThread = null;
myRunnable = null;
System.gc();
Log.e("TESTAUTOMATION", "endCallThread interrupted");
} catch (Exception ex) {
Log.e("TESTAUTOMATION", "endCallThread interrupted exception");
}
//handleResult();
}
}
}.start();
} else {
mEndCallSupported = true;
}
}
}
private void doInBackgroundWrapper() {
try {
if (getContext() == null) {
return;
}
final TelephonyManager telMan = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
if (telMan == null) {
return;
}
final Class<?> classTemp = Class.forName(telMan.getClass().getName());
final Method methodTemp = classTemp.getDeclaredMethod("getITelephony");
methodTemp.setAccessible(true);
ITelephony telephonyService = (ITelephony) methodTemp.invoke(telMan);
// If this call does not return a security exception we say the call principally works.
Log.d("TESTAUTOMATION", "endCall before");
// This call endCall may freeze depending on device, mostly seen on Nexus 5x with Android 8&8.1
telephonyService.endCall();
Log.d("TESTAUTOMATION", "endCall after");
mSupported = true;
} catch (Exception ex) {
ex.printStackTrace();
mSupported = false;
}
}
To reproduce this the device should better no have a SIM inserted.