22 展讯Sprd设置-电池-识别输入法应用

1. 目的

输入法应用属于可识别类型且核心应用,不能进行拦截和kill

2. 展讯输入法判断

2.1 判断逻辑块

    //handle inputmethod
    if (isLaunchingIMEApp(intent, targetApp, targetUid, callerApp, reason)) {
        return true;
    }

2.2 判断是否为输入法

    private boolean isLaunchingIMEApp(Intent intent, String targetApp, int targetUid,
            String callerApp, String reason) {

        //handle inputmethod
        // 是否满足以下条件
        // 1. caller 为系统发起
        // 2. 启动类型为bind-services
        // 3. action为输入法类型
        if ("android".equals(callerApp)
            && REASON_BIND_SERVICE.equals(reason)
            && intent != null && "android.view.InputMethod".equals(intent.getAction())) {

            // 判断为输入法应用
            if (targetApp != null) { // a input method
                // 如果未保存到当前可用输入法,则存入mEnabledInputMethodAppList列表中
                int index = mEnabledInputMethodAppList.indexOf(targetApp);
                if (index < 0) {
                    mEnabledInputMethodAppList.add(targetApp);

                    // 多用户模式下,保存输入法信息到对应列表中
                    int userId = UserHandle.getUserId(targetUid);
                    mAppStateInfoCollector.updateAppInputMethodState(targetApp, true, userId);
                    mAppStateInfoCollector.setDefaultInputMethodApp(targetApp, userId);
                }
            }
            return true;
        }

        // allow to start input Method
        // 是否满足下面条件
        // 1. 启动类型为bind-services
        // 2. caller 为系统发起
        // 3. 该进程属于输入法列表
        if (REASON_BIND_SERVICE.equals(reason) && "android".equals(callerApp) && isInputMethodApp(targetApp)) {
            if (DEBUG) Slog.d(TAG, "isLaunchingIMEApp: "+targetApp
                + ", callingPackage = "+callerApp+", reason = "+reason +" allow for input method");
            return true;
        }

        return false;
    }
    
    // input method app
    private boolean isInputMethodApp(String pkgName) {
        int index = mEnabledInputMethodAppList.indexOf(pkgName);
        if (index >= 0) {
            return true;
        }
        return false;
    }

2.3 AppStateInfoCollector.updateAppInputMethodState

更新对应进程状态中,应用状态mIsEnabledInputMethod为输入法应用

    // update the Input Method identify state of this app
    public void updateAppInputMethodState(String pkgName, boolean isInputMethod, int userId) {
        ArrayMap<String, AppState> mAppStateInfoList = getAppStateInfoList(userId);
        int index = mAppStateInfoList.indexOfKey(pkgName);
        if (index >= 0) {
            AppState appState = mAppStateInfoList.valueAt(index);
            appState.mIsEnabledInputMethod = isInputMethod;
        }
    }

2.4 AppStateInfoCollector.setDefaultInputMethodApp

更新为默认输入法

    // update the Input Method identify state of this app
    public void setDefaultInputMethodApp(String pkgName, int userId) {
        ArrayMap<String, AppState> mAppStateInfoList = getAppStateInfoList(userId);
        String mDefaultIMEAppName =  mDefaultIMEAppNameForUsers.get(userId);

        // 新值与默认输入法一致,则不需要重复更新
        if (mDefaultIMEAppName != null
            && mDefaultIMEAppName.equals(pkgName)) {
            return;
        }

        // 旧的默认输入法更新状态
        // clear orignal
        if (mDefaultIMEAppName != null) {
            int index = mAppStateInfoList.indexOfKey(mDefaultIMEAppName);
            if (index >= 0) {
                AppState appState = mAppStateInfoList.valueAt(index);
                appState.mIsDefaultInputMethod = false;
            }
        }

        // set new
        // 新值设置为默认输入法即当前使用的输入法
        int index = mAppStateInfoList.indexOfKey(pkgName);
        if (index >= 0) {
            AppState appState = mAppStateInfoList.valueAt(index);
            appState.mIsDefaultInputMethod = true;
        }

        mDefaultIMEAppName = pkgName;
        mDefaultIMEAppNameForUsers.put(userId, mDefaultIMEAppName);
    }

2.5 APPstate创建中会进行判断是否为输入法

    // check if is input method
    retVal.mIsEnabledInputMethod = isEnabledIMEApp(packageName);
        
    // if this app is a input Method
    private boolean isEnabledIMEApp(String pkgName){
        if (pkgName == null) return false;
        IInputMethodManager service = IInputMethodManager.Stub.asInterface(
            ServiceManager.getService(Context.INPUT_METHOD_SERVICE));
        List<InputMethodInfo> inputMethods;
        try {
            inputMethods = service.getEnabledInputMethodList();
        } catch (RemoteException e) {
            return false;
        }
        if (inputMethods == null || inputMethods.size() == 0) return false;
        for (InputMethodInfo info : inputMethods){
            if (info == null || info.getPackageName() == null) continue;
            if (info.getPackageName().equals(pkgName)) return true;
        }
        return false;
    }    

3. 应用上层的输入法判断

3.1 判断是否为默认输入法,或者正在使用的当前输入法

    public static String getInputPackage(Context mContext) {
        String result = null;
        String input = Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
        if (input == null || input.equals("") || !input.contains("/")) {
            // frameworks/base/packages/SettingsProvider/res/values/defaults.xml, default_input_method
        } else {
            result = input.substring(0, input.indexOf('/'));
        }
        Log.d(TAG, "getInputPackage = " + result);
        return result;
    }

3.2 根据AndroidManifest进行判断是否为输入法

    public static boolean isInputMethodApp(Context context, String packageName) {
        PackageManager pm = context.getPackageManager();
        boolean isInputMethodApp = false;
        try {
            PackageInfo pkgInfo = pm.getPackageInfo(packageName, PackageManager.GET_SERVICES);
            ServiceInfo[] sInfo = pkgInfo.services;
            if (sInfo != null) {
                for (int i = 0; i < sInfo.length; i++) {
                    ServiceInfo serviceInfo = sInfo[i];
                    if (serviceInfo.permission != null && serviceInfo.permission.equals("android.permission.BIND_INPUT_METHOD")) {
                        isInputMethodApp = true;
                        break;
                    }
                }
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return isInputMethodApp;
    }

3.3 根据 InputMethodManager 进行获取输入法列表

    public static ArrayList<String> getInputMethodAppList(Context context) {
        ArrayList<String> list = new ArrayList<String>();
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

        List<InputMethodInfo> methodList = imm.getInputMethodList();
        List<String> mInputMethodBlackList = getInputMethodBlackList(context);

        if (methodList != null) {
            for (InputMethodInfo mi : methodList) {
                String inputMethodPackageName = mi.getPackageName();

                if (!mInputMethodBlackList.contains(inputMethodPackageName)) {
                    list.add(inputMethodPackageName);
                }

            }
        }
        Log.d(TAG, "getInputMethodAppList = " + list.toString());
        return list;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值