Andorid11 暗码启动应用(一)
创始人
2024-01-21 18:17:33
0

通过拨号盘,输入暗码启动工程模式流程分析。

1.暗码启动应用流程

1.1拨号盘的显示

用工具抓到点击弹出拨号键盘的button的id是fab,点击之后启动DialpadFragment显示拨号盘

  • packages/apps/Dialer/java/com/android/dialer/main/impl/OldMainActivityPeer.java
 private void initLayout(Bundle savedInstanceState) {...FloatingActionButton fab = activity.findViewById(R.id.fab);fab.setOnClickListener(v -> {Logger.get(activity).logImpression(DialerImpression.Type.MAIN_CLICK_FAB_TO_OPEN_DIALPAD);searchController.showDialpad(true);if (callLogAdapterOnActionModeStateChangedListener.isEnabled) {LogUtil.i("OldMainActivityPeer.onFabClicked", "closing multiselect");callLogAdapterOnActionModeStateChangedListener.actionMode.finish();}});...}   
  • packages/apps/Dialer/java/com/android/dialer/main/impl/MainSearchController.java
 private void showDialpad(boolean animate, boolean fromNewIntent) {...// Show Dialpadif (dialpadFragment == null) {dialpadFragment = new DialpadFragment();dialpadFragment.setStartedFromNewIntent(fromNewIntent);transaction.add(R.id.dialpad_fragment_container, dialpadFragment, DIALPAD_FRAGMENT_TAG);searchFragment.setQuery("", CallInitiationType.Type.DIALPAD);} else {dialpadFragment.setStartedFromNewIntent(fromNewIntent);transaction.show(dialpadFragment);}transaction.commit();}
1.2 输入暗码后的逻辑处理
  • packages/apps/Dialer/java/com/android/dialer/dialpadview/DialpadFragment.java
/** Fragment that displays a twelve-key phone dialpad. */
public class DialpadFragment extends Fragmentimplements View.OnClickListener,View.OnLongClickListener,View.OnKeyListener,AdapterView.OnItemClickListener,TextWatcher,PopupMenu.OnMenuItemClickListener,DialpadKeyButton.OnPressedListener {

其继承了TextWatcher类,能够监听实现输入变化。

@Overridepublic void afterTextChanged(Editable input) {// When DTMF dialpad buttons are being pressed, we delay SpecialCharSequenceMgr sequence,// since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down"// behavior.if (!digitsFilledByIntent&& SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), digits)) {// A special sequence was entered, clear the digitsdigits.getText().clear();}

输入结束后,调用了SpecialCharSequenceMgr辅助类的handleChars方法,这里会对各种特殊的code进行区分处理

  • packages/apps/Dialer/java/com/android/dialer/dialpadview/SpecialCharSequenceMgr.java
public static boolean handleChars(Context context, String input, EditText textField) {// get rid of the separators so that the string gets parsed correctlyString dialString = PhoneNumberUtils.stripSeparators(input);if (handleDeviceIdDisplay(context, dialString)|| handleRegulatoryInfoDisplay(context, dialString)|| handlePinEntry(context, dialString)|| handleAdnEntry(context, dialString, textField)|| handleSecretCode(context, dialString)) {return true;}if (MotorolaUtils.handleSpecialCharSequence(context, input)) {return true;}return false;}// 以*#*#开头,#*#*结束的特殊code,发广播调起其他应用
static boolean handleSecretCode(Context context, String input) {// Secret code specific to OEMs should be handled first.if (TranssionUtils.isTranssionSecretCode(input)) {TranssionUtils.handleTranssionSecretCode(context, input);return true;}// Secret codes are accessed by dialing *#*##*#* or "*##"if (input.length() > 8 && input.startsWith("*#*#") && input.endsWith("#*#*")) {String secretCode = input.substring(4, input.length() - 4);TelephonyManagerCompat.handleSecretCode(context, secretCode);return true;}return false;}

然后又来到TelephonyManagerCompat的handleSecretCode方法

  • packages/apps/Dialer/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java
public static void handleSecretCode(Context context, String secretCode) {// Must use system service on O+ to avoid using broadcasts, which are not allowed on O+.if (BuildCompat.isAtLeastO()) {if (!TelecomUtil.isDefaultDialer(context)) {LogUtil.e("TelephonyManagerCompat.handleSecretCode","not default dialer, cannot send special code");return;}context.getSystemService(TelephonyManager.class).sendDialerSpecialCode(secretCode);} else {// System service call is not supported pre-O, so must use a broadcast for N-.Intent intent =new Intent(SECRET_CODE_ACTION, Uri.parse("android_secret_code://" + secretCode));context.sendBroadcast(intent);}}

这里会判断版本和是否是默认的通话应用,如果是低于O版本直接发送广播,如果是高于O版本,判断是否是默认通话应用,是的话走到TelephonyManager中。

  • frameworks/base/telephony/java/android/telephony/TelephonyManager.java
 public void sendDialerSpecialCode(String inputCode) {try {final ITelephony telephony = getITelephony();if (telephony == null) {if (!isSystemProcess()) {throw new RuntimeException("Telephony service unavailable");}return;}telephony.sendDialerSpecialCode(mContext.getOpPackageName(), inputCode);} catch (RemoteException ex) {// This could happen if binder process crashes.if (!isSystemProcess()) {ex.rethrowAsRuntimeException();}}}

PhoneInterfaceManager继承ITelephony.Stub

  • packages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.java
 @Overridepublic void sendDialerSpecialCode(String callingPackage, String inputCode) {final Phone defaultPhone = getDefaultPhone();mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);TelecomManager tm = defaultPhone.getContext().getSystemService(TelecomManager.class);String defaultDialer = tm.getDefaultDialerPackage();if (!TextUtils.equals(callingPackage, defaultDialer)) {TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mApp,getDefaultSubscription(), "sendDialerSpecialCode");}final long identity = Binder.clearCallingIdentity();try {defaultPhone.sendDialerSpecialCode(inputCode);} finally {Binder.restoreCallingIdentity(identity);}}
  • frameworks/opt/telephony/src/java/com/android/internal/telephony/Phone.java
public void sendDialerSpecialCode(String code) {if (!TextUtils.isEmpty(code)) {final BroadcastOptions options = BroadcastOptions.makeBasic();options.setBackgroundActivityStartsAllowed(true);Intent intent = new Intent(TelephonyIntents.SECRET_CODE_ACTION,Uri.parse("android_secret_code://" + code));intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);mContext.sendBroadcast(intent, null, options.toBundle());// {@link TelephonyManager.ACTION_SECRET_CODE} will replace {@link// TelephonyIntents#SECRET_CODE_ACTION} in the next Android version. Before// that both of these two actions will be broadcast.Intent secrectCodeIntent = new Intent(TelephonyManager.ACTION_SECRET_CODE,Uri.parse("android_secret_code://" + code));secrectCodeIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);mContext.sendBroadcast(secrectCodeIntent, null, options.toBundle());}}

走到Phone.java中,最终还是发送暗码广播。

接收示例:

  • vendor/mediatek/proprietary/packages/apps/EngineerMode/AndroidManifest.xml
          
  • vendor/mediatek/proprietary/packages/apps/EngineerMode/src/com/mediatek/engineermode/EngineerModeReceiver.java
public final class EngineerModeReceiver extends BroadcastReceiver {private static final String TAG = "EngineerModeReceiver";private static final String SECRET_CODE_ACTION= "android.provider.Telephony.SECRET_CODE";// process *#*#3646633#*#*private final Uri mEmUri = Uri.parse("android_secret_code://3646633");// process *#*#9527686#*#* mtklogprivate final Uri mMtklogUri1 = Uri.parse("android_secret_code://9527686");@Overridepublic void onReceive(Context context, Intent intent) {if (intent.getAction() == null) {Elog.e(TAG, "Null action");return;}if (intent.getAction().equals(SECRET_CODE_ACTION)) {Uri uri = intent.getData();Elog.i(TAG, "Receive secret code intent and uri is " + uri);if (uri.equals(mEmUri)) {Intent intentEm = new Intent(context, EngineerMode.class);intentEm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intentEm);} else if(uri.equals(mMtklogUri1)) {String packageName = "com.debug.loggerui";String className = "com.debug.loggerui.MainActivity";Intent intentEm = new Intent(Intent.ACTION_MAIN);intentEm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);ComponentName cn = new ComponentName(packageName, className);intentEm.setComponent(cn);context.startActivity(intentEm);}}}
}

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...