├── IQcNvItems.java ├── IQcRilHook.java ├── ISemcRilHook.java ├── README.md └── closedsourceshim ├── QcNvItems.java ├── QcRilHook.java └── SemcRilHook.java /IQcNvItems.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 Joey Hewitt 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package net.scintill.qcrilhook; 24 | 25 | import java.io.IOException; 26 | import java.security.InvalidParameterException; 27 | 28 | public interface IQcNvItems { 29 | 30 | //public void enableAutoAnswer(short rings) throws IOException, InvalidParameterException; 31 | 32 | //public void disableAutoAnswer() throws IOException; 33 | 34 | public static class AutoAnswer { 35 | public boolean enable; 36 | public short rings; 37 | } 38 | 39 | public AutoAnswer getAutoAnswer() throws IOException; 40 | 41 | // ideally this is more of a helper, but for now, I'll just export it 42 | // http://forum.xda-developers.com/showthread.php?t=1954029 43 | public byte[] readNv(int itemId) throws IOException; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /IQcRilHook.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 Joey Hewitt 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package net.scintill.qcrilhook; 24 | 25 | import android.os.AsyncResult; 26 | 27 | import java.io.IOException; 28 | 29 | public interface IQcRilHook { 30 | 31 | public void setFieldTestMode(int sub, byte ratType, int enable) throws IOException; 32 | 33 | public String[] getAvailableConfigs(String device) throws IOException; 34 | 35 | //public String getConfig(); 36 | 37 | //public boolean goDormant(String interfaceName); 38 | 39 | //public boolean setCdmaSubSrcWithSpc(int cdmaSubscription, String spc); 40 | 41 | //public boolean setConfig(String config); 42 | 43 | //public boolean avoidCurCdmaNwk(); 44 | 45 | //public boolean clearCdmaAvoidanceList(); 46 | 47 | //public byte[] getCdmaAvoidanceList(); 48 | 49 | //public boolean informShutDown(int sub); 50 | 51 | //public boolean performIncrManualScan(int sub); 52 | 53 | //public boolean setBuiltInPLMNList(byte[] payload, int sub); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /ISemcRilHook.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 Joey Hewitt 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package net.scintill.qcrilhook; 24 | 25 | import java.io.IOException; 26 | 27 | public interface ISemcRilHook extends IQcRilHook { 28 | 29 | enum FtmNetworkType { 30 | GSM 31 | }; 32 | 33 | public byte[] getCipherIndicator() throws IOException; 34 | 35 | public byte[] getActiveBand() throws IOException; 36 | 37 | public byte[] getSpeechCodec() throws IOException; 38 | 39 | public byte[] registerForFtmLiveUpdate(FtmNetworkType type) throws IOException; 40 | 41 | public byte[] unregisterForFtmLiveUpdate(FtmNetworkType type) throws IOException; 42 | 43 | public long readNvSemc(int itemId) throws IOException; 44 | 45 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # qcrilhook 2 | 3 | Tinkering with the qcrilhook functions available on modern Qualcomm-based Android phones. These are implemented through Java libraries in /system/framework, that communicate with a Intent endpoint living in the com.android.phone process, which sends a RIL_REQUEST_OEM_HOOK_RAW to the native RIL code. 4 | 5 | So far, I've implemented a wrapper around a few methods in the closed-source and undocumented Java libraries. Unfortunately there is not much exciting that really works (yet?) I'm not sure if I'm doing something wrong, need to enable a debug flag somehow, need engineering-mode binaries, etc. 6 | 7 | TODO Do some more testing with qcril_log_adb_on = 1 in the RIL .so (it's a 1-byte debug flag exported in libril-qc-qmi-1.so's symbol table, which causes extra output to the logcat log) 8 | 9 | ## Dependencies 10 | 11 | You'll need some variant of the following, depending on your exact usage: 12 | 13 | ```xml 14 | 15 | 16 | 17 | ``` 18 | 19 | These refer to libraries that are installed in /system/framework, so the compiled app requires a ROM that includes them (such as many shipped ROMs for Qualcomm devices -- AOSP etc. probably won't have these libraries.) 20 | 21 | ## Generic Qualcomm Features 22 | 23 | * Query "auto answer" configuration from NV memory ("generic failure" from RIL on my device) 24 | * Query arbitrary NV items ("generic failure") 25 | * Enable a "field test" mode. Works, but the format of the response packets is currently unknown. They can be seen in the radio log (adb logcat -b radio). I believe there's an Intent you can listen for to receive the packets into the app, but I haven't implemented it since I can't do much with the responses. 26 | * Get available "configurations" (?) ("not supported" or something similar on my device) 27 | 28 | ## SEMC (Sony) Features 29 | 30 | * Cipher indicator ("generic failure") 31 | * Get active bands - generic byte array, unknown meaning, but could probably be reversed from the service menu app (dial `*#*#7378423#*#*` on Sony Xperia Z1 Compact) 32 | * Get speech codecs - same as above 33 | * Sony-specific field test mode - similar situation as the generic Qualcomm field test. I see an intent "semc.intent.action.ACTION_UNSOL_SEMC_FIELD_TEST_MODE" with extra "payload" (byte[]), but have not implemented reception. 34 | * Sony-specific NV reading - doesn't work on my device 35 | 36 | ## License 37 | 38 | The MIT License (MIT) 39 | 40 | Copyright (c) 2015 Joey Hewitt 41 | 42 | Permission is hereby granted, free of charge, to any person obtaining a copy 43 | of this software and associated documentation files (the "Software"), to deal 44 | in the Software without restriction, including without limitation the rights 45 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 46 | copies of the Software, and to permit persons to whom the Software is 47 | furnished to do so, subject to the following conditions: 48 | 49 | The above copyright notice and this permission notice shall be included in 50 | all copies or substantial portions of the Software. 51 | 52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 54 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 56 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 57 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 58 | THE SOFTWARE. 59 | -------------------------------------------------------------------------------- /closedsourceshim/QcNvItems.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 Joey Hewitt 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package net.scintill.qcrilhook.closedsourceshim; 24 | 25 | import android.content.Context; 26 | 27 | import net.scintill.qcrilhook.IQcNvItems; 28 | 29 | import java.io.IOException; 30 | import java.lang.reflect.InvocationTargetException; 31 | import java.lang.reflect.Method; 32 | 33 | public class QcNvItems implements IQcNvItems { 34 | 35 | protected Object mQcNvItems; 36 | 37 | public QcNvItems(QcRilHook rilHook) { 38 | try { 39 | mQcNvItems = Class.forName("com.qualcomm.qcnvitems.QcNvItems") 40 | .getConstructor(Context.class).newInstance(rilHook.mCtx); 41 | } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) { 42 | throw new RuntimeException(e); 43 | } 44 | } 45 | 46 | @Override 47 | public AutoAnswer getAutoAnswer() throws IOException { 48 | try { 49 | Object o = mQcNvItems.getClass().getMethod("getAutoAnswerStatus").invoke(mQcNvItems); 50 | AutoAnswer aa = new AutoAnswer(); 51 | aa.enable = (Boolean)o.getClass().getMethod("isEnabled").invoke(o); 52 | aa.rings = (Short)o.getClass().getMethod("getRings").invoke(o); 53 | return aa; 54 | } catch (IllegalAccessException | NoSuchMethodException e) { 55 | throw new RuntimeException(e); 56 | } catch (InvocationTargetException e) { 57 | if (e.getTargetException() instanceof IOException) { 58 | throw (IOException)e.getTargetException(); 59 | } 60 | 61 | // no other exceptions expected 62 | throw new RuntimeException(e); 63 | } 64 | } 65 | 66 | @Override 67 | public byte[] readNv(int itemId) throws IOException { 68 | try { 69 | Method m = mQcNvItems.getClass().getDeclaredMethod("doNvRead", int.class); 70 | m.setAccessible(true); 71 | return (byte[])m.invoke(mQcNvItems, itemId); 72 | } catch (IllegalAccessException | NoSuchMethodException e) { 73 | throw new RuntimeException(e); 74 | } catch (InvocationTargetException e) { 75 | if (e.getTargetException() instanceof IOException) { 76 | throw (IOException)e.getTargetException(); 77 | } 78 | 79 | // no other exceptions expected 80 | throw new RuntimeException(e); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /closedsourceshim/QcRilHook.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 Joey Hewitt 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package net.scintill.qcrilhook.closedsourceshim; 24 | 25 | import android.content.Context; 26 | 27 | import net.scintill.qcrilhook.IQcRilHook; 28 | 29 | import java.io.IOException; 30 | import java.lang.reflect.InvocationTargetException; 31 | 32 | public class QcRilHook implements IQcRilHook { 33 | 34 | /*package*/ Object mQcRilHook; 35 | /*package*/ Context mCtx; 36 | 37 | public QcRilHook(Context ctx) { 38 | try { 39 | mQcRilHook = Class.forName("com.qualcomm.qcrilhook.QcRilHook") 40 | .getConstructor(Context.class).newInstance(ctx); 41 | mCtx = ctx; 42 | } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) { 43 | throw new RuntimeException(e); 44 | } 45 | } 46 | 47 | @Override 48 | public void setFieldTestMode(int sub, byte ratType, int enable) throws IOException { 49 | try { 50 | boolean b = (Boolean)mQcRilHook.getClass().getMethod("qcRilSetFieldTestMode", int.class, byte.class, int.class).invoke(mQcRilHook, sub, ratType, enable); 51 | if (!b) { 52 | throw new IOException(); 53 | } 54 | } catch (IllegalAccessException | NoSuchMethodException e) { 55 | throw new RuntimeException(e); 56 | } catch (InvocationTargetException e) { 57 | // no exceptions expected 58 | throw new RuntimeException(e); 59 | } 60 | } 61 | 62 | @Override 63 | public String[] getAvailableConfigs(String device) throws IOException { 64 | try { 65 | String[] configs = (String[])mQcRilHook.getClass().getMethod("qcRilGetAvailableConfigs", String.class).invoke(mQcRilHook, device); 66 | if (configs == null) { 67 | throw new IOException(); 68 | } 69 | return configs; 70 | } catch (IllegalAccessException | NoSuchMethodException e) { 71 | throw new RuntimeException(e); 72 | } catch (InvocationTargetException e) { 73 | // no exceptions expected 74 | throw new RuntimeException(e); 75 | } 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /closedsourceshim/SemcRilHook.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015 Joey Hewitt 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | 23 | package net.scintill.qcrilhook.closedsourceshim; 24 | 25 | import android.content.Context; 26 | 27 | import net.scintill.qcrilhook.ISemcRilHook; 28 | 29 | import java.io.IOException; 30 | import java.lang.reflect.InvocationTargetException; 31 | 32 | public class SemcRilHook extends QcRilHook implements ISemcRilHook { 33 | 34 | protected Object mSemcRilExtConfigInfo; 35 | protected Object mSemcRilExtFtm; 36 | protected Object mSemcRilExtNvItem; 37 | 38 | public SemcRilHook(Context ctx) { 39 | super(ctx); 40 | 41 | try { 42 | mSemcRilExtConfigInfo = Class.forName("com.sonyericsson.android.semcrilextension.SemcRilExtConfigInfo") 43 | .getConstructor(Context.class, Class.forName("com.qualcomm.qcrilhook.IQcSemcServiceConnected")) 44 | .newInstance(ctx, null); 45 | mSemcRilExtFtm = Class.forName("com.sonyericsson.android.semcrilextension.SemcRilExtFTM") 46 | .getConstructor(Context.class, Class.forName("com.qualcomm.qcrilhook.IQcSemcServiceConnected")) 47 | .newInstance(ctx, null); 48 | mSemcRilExtNvItem = Class.forName("com.sonyericsson.android.semcrilextension.SemcRilExtNvItem") 49 | .getConstructor(Context.class, Class.forName("com.qualcomm.qcrilhook.IQcSemcServiceConnected")) 50 | .newInstance(ctx, null); 51 | } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) { 52 | throw new RuntimeException(e); 53 | } 54 | } 55 | 56 | @Override 57 | public byte[] getCipherIndicator() throws IOException { 58 | return getConfigInfoByteArray("getCipherIndicator"); 59 | } 60 | 61 | @Override 62 | public byte[] getActiveBand() throws IOException { 63 | return getConfigInfoByteArray("getActiveBand"); 64 | } 65 | 66 | @Override 67 | public byte[] getSpeechCodec() throws IOException { 68 | return getConfigInfoByteArray("getSpeechCodec"); 69 | } 70 | 71 | @Override 72 | public byte[] registerForFtmLiveUpdate(FtmNetworkType type) throws IOException { 73 | try { 74 | return (byte[])mSemcRilExtFtm.getClass().getMethod("RegisterforFTMLiveUpdate", String.class) 75 | .invoke(mSemcRilExtFtm, type.toString()); 76 | } catch (IllegalAccessException | NoSuchMethodException e) { 77 | throw new RuntimeException(e); 78 | } catch (InvocationTargetException e) { 79 | if (e.getTargetException() instanceof IOException) { 80 | throw (IOException)e.getTargetException(); 81 | } 82 | // no other expected exceptions 83 | throw new RuntimeException(e); 84 | } 85 | } 86 | 87 | @Override 88 | public byte[] unregisterForFtmLiveUpdate(FtmNetworkType type) throws IOException { 89 | try { 90 | return (byte[])mSemcRilExtFtm.getClass().getMethod("UnRegisterforFTMLiveUpdate", String.class) 91 | .invoke(mSemcRilExtFtm, type.toString()); 92 | } catch (IllegalAccessException | NoSuchMethodException e) { 93 | throw new RuntimeException(e); 94 | } catch (InvocationTargetException e) { 95 | if (e.getTargetException() instanceof IOException) { 96 | throw (IOException)e.getTargetException(); 97 | } 98 | // no other expected exceptions 99 | throw new RuntimeException(e); 100 | } 101 | } 102 | 103 | @Override 104 | public long readNvSemc(int itemId) throws IOException { 105 | try { 106 | return (Long)mSemcRilExtNvItem.getClass().getMethod("getNvItem", int.class).invoke(mSemcRilExtNvItem, itemId); 107 | } catch (IllegalAccessException | NoSuchMethodException e) { 108 | throw new RuntimeException(e); 109 | } catch (InvocationTargetException e) { 110 | if (e.getTargetException() instanceof IOException) { 111 | throw (IOException) e.getTargetException(); 112 | } 113 | // no other expected exceptions 114 | throw new RuntimeException(e); 115 | } 116 | } 117 | 118 | protected byte[] getConfigInfoByteArray(String getterName) throws IOException { 119 | try { 120 | return (byte[])mSemcRilExtConfigInfo.getClass().getMethod(getterName).invoke(mSemcRilExtConfigInfo); 121 | } catch (IllegalAccessException | NoSuchMethodException e) { 122 | throw new RuntimeException(e); 123 | } catch (InvocationTargetException e) { 124 | if (e.getTargetException() instanceof IOException) { 125 | throw (IOException)e.getTargetException(); 126 | } 127 | // no other expected exceptions 128 | throw new RuntimeException(e); 129 | } 130 | } 131 | } 132 | --------------------------------------------------------------------------------