connglli / ELEGANT

ELEGANT - a tool to Effectively LocatE fraGmentAtion-iNduced compaTibility issues.
MIT License
3 stars 0 forks source link

weekly report: 2017.08.10-2017.08.15 #2

Closed connglli closed 6 years ago

connglli commented 7 years ago

周报

2017.08.10 ~ 2017.08.15

Soot

安装和配置

本周的第一个任务就是对 Soot 进行了快速的了解和学习。虽然只是下一个 jar 包而已,但其间也是遇到了一个小坑,这里记录一下。

根据官方Wiki的讲解,由于 Soot 有自己的 classpath ,因此我们在使用命令行工具的时候需要手动添加 $CLASSPATH$JAVA_HOME来解决类似 java.lang.Object 无法加载的问题:

# 或者
java -cp soot-x.y.z.jar soot.Main -cp .:${JAVA_HOME}/jre/lib/rt.jar A
# 或者
java -cp soot-2.5.0.jar soot.Main -cp . -pp A

然而,即使这样也可能会遇到:

Exception in thread main java.lang.RuntimeException: Could not load classfile: java.lang.CharSequence

查询后发现是 java 版本的问题,在 java 8 下会报这样的错误,解决方案:

虽然是个小小的 jar 包,但也是历经一番辛苦才搞好。

调研与使用

看了文档后,了解到 Soot 是一个经常用来分析和优化 java/android 应用的工具,提供了诸如

等能力,同时提供了四种主要的中间代码表示形式:

  1. Jimple
  2. Shimple
  3. Baf
  4. Dava

详细的使用将在开发阶段进行,这不作为本周的重点。

Issues 的提取

按照上周计划,本打算根据 Lili 学姐论文中提到的数据收集和分析的方法自己进行 issue 的提取,但当打开 CSipSimple 项目对第一个关键词 device 进行搜索并欲进行整理和分析的时候,发现搜到的结果竟有 43 次 Commit 和 8 个 issue,考虑到还有14个关键词和4个项目,数量有点大而且不易仔细分析,于是便暂时先放弃了自己进行搜索和分析的想法,暂时先使用学姐给出的 191 个 issue 来优先进行 Model 的提取。可等开发完成后再回头考虑如何能好又快的进行 Issue 的提取。这里暂时先给自己留个坑出来以后填。

Model 的提取 - 1.1.1

根据学姐项目主页的数据表,对其中每一个 Issue 都进行了查找和分析,并初步(仅对原因进行了分析,还未进行进一步抽象与提取)得到了以下的 Model(限于时间,目前仅对 CSipSimple 进行了小部分分析,下周会继续):

备注:平台版本、级别、VERSION_CODE 对应关系见这里

# API Context
54 Intent.EXTRA_REMOTE_INTENT_TOKEN API level 5 支持
55 handlerThread.quit() API level 5 支持
56 arlarmManager.setExtract() API level 19 支持
57 System.WIFI_SLEEP_POLICY, Settings.System.WIFI_SLEEP_POLICY_DEFAULT API level 17 废弃
58 AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE API level 17 支持
59 Camera 相关 API API level 5/8/9+ 支持不同
60 notification.contentView.setVisibiliy(View.VISIBLE) API level 8 才可用
61 contentResolver.insert() 任何 API 下都可能发生异常
62 cv.put(Data.RAW_CONTACT_ID, callerInfo.personId); HTC desire S 需要 ID 才能成功保存 log
63 keyCharacterMap.getNumber(keyCode) 有些平板不支持,如 Xoom ...
64 preferencesWrapper.setPreferenceBooleanValue(SipConfigManager.INTEGRATE_WITH_CALLLOGS, true); ‘Go Gear Connect' 设备不允许存储 CALLLOGS
66 preferencesWrapper.setPreferenceBooleanValue(PreferencesWrapper.KEEP_AWAKE_IN_CALL) HTC desire 和 Nexus One 需要设置为 true
87 audioManager.setRouting API level 4 被废弃
127 MenuItem.SHOW_AS_ACTION_WITH_TEXT API level 11 支持
128 ApplicationInfo.FLAG_EXTERNAL_STORAGE API level 8 支持

疑问!!!

为什么 #61 是 Device-Specific 的?其代码修改如下(代码中未体现设备相关性):
@@ -26,7 +26,9 @@
  import android.content.Context;
  import android.content.Intent;
  import android.net.Uri;
 +import android.os.Build;
  import android.provider.CallLog;
 +import android.provider.ContactsContract.Data;

  import com.csipsimple.api.SipCallSession;
  import com.csipsimple.api.SipManager;
 @@ -95,6 +97,12 @@ public static ContentValues logValuesForCall(Context context, SipCallSession cal
            cv.put(CallLog.Calls.CACHED_NAME, callerInfo.name);
            cv.put(CallLog.Calls.CACHED_NUMBER_LABEL, callerInfo.numberLabel);
            cv.put(CallLog.Calls.CACHED_NUMBER_TYPE, callerInfo.numberType);
 +          
 +          if(Build.DEVICE.equalsIgnoreCase("saga")) {
 +              // For HTC desire S they need for some reason the personId
 +              // Thx Maximus for the tip
 +              cv.put(Data.RAW_CONTACT_ID, callerInfo.personId);
 +          }
        }

        return cv;
#128 代码为什么使用 0x00040000 而非 ApplicationInfo.FLAG_EXTERNAL_STORAGE 既然兼容 API level 8
public static boolean isInstalledOnSdCard(Context context) {
  // check for API level 8 and higher
  if (Compatibility.isCompatible(8)) {
    PackageManager pm = context.getPackageManager();
    try {
      PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
      ApplicationInfo ai = pi.applicationInfo;
      return (ai.flags & 0x00040000 /*ApplicationInfo.FLAG_EXTERNAL_STORAGE*/) == 0x00040000 /*ApplicationInfo.FLAG_EXTERNAL_STORAGE*/;
    } catch (NameNotFoundException e) {
      // ignore
    }
  }

  // check for API level 7 - check files dir
  try {
    String filesDir = context.getFilesDir().getAbsolutePath();
    if (filesDir.startsWith("/data/")) {
      return false;
    } else if (filesDir.contains(Environment.getExternalStorageDirectory().getPath())) {
      return true;
    }
  } catch (Throwable e) {
    // ignore
  }

  return false;
}

下周计划

  1. 完成剩余 Model 的分析与提取 (Model 的提取 1.1.2 ~ Model 的提取 1.1.x)
  2. 对提取到的 Model 进行下一步的分析,抽取共性并舍弃一些相互调用相关性比较强的特例(如保存Log需要多步并且只有HTC desire S系列才会出问题的例子)。(Model 的提取 1.2)
  3. 若上述两步骤完成,进入开发阶段,进行项目创建和框架搭建。

心声

  1. 本来时间规划并不是一件难事,但它难就难在阿里给了一个 一周开发+前后端联调+提测+20号上线 的项目,不过实习确实学到了挺多东西,也真正了解到了软件工程的整个开发阶段、中后台项目的前端解决方案以及一个日 PV 高达 2kw 的项目的前后端解决方案。
  2. FicFinder的实现也会继续合理安排时间进行,目前进度偏慢,希望后续能有时间和能力加速。
LiliWeiSE commented 7 years ago

First let me answer your questions:

  1. #128 is device-specific as it checks a device-specific context.

    if(Build.DEVICE.equalsIgnoreCase("saga")) {

    If you check the API guide you will find that this is an identifier for the device model.

  2. 0x00040000 is the value of FLAG_EXTERNAL_STORAGE

You may get many problems when using Soot. It seems to me that using the trunk is better for Android analysis. (But still, I seems to find some bugs of Soot when analysing apk files)

connglli commented 7 years ago

@frankFic

  1. sorry that I pasted wrong codes for #61, the right codes is as following:
@@ -43,11 +43,17 @@
      private static final String EXTRA_CALL_LOG_URI = "uri";
      // Provider name
      public static final String EXTRA_SIP_PROVIDER = "provider";
 +    private static final String THIS_FILE = "CallLogHelper";

    public static void addCallLog(Context context, ContentValues values, ContentValues extraValues) {
        ContentResolver contentResolver = context.getContentResolver();
 -      Uri result = contentResolver.insert(CallLog.Calls.CONTENT_URI, values);
 +      Uri result = null;
 +      try {
 +          result = contentResolver.insert(CallLog.Calls.CONTENT_URI, values);
 +      }catch(IllegalArgumentException e) {
 +          Log.w(THIS_FILE, "Cannot insert call log entry. Probably not a phone", e);
 +      }

        if(result != null) {
            // Announce that to other apps
  1. Yep, 0x00040000 is the value of FLAG_EXTERNAL_STORAGE , but I have no idea that, since FLAG_EXTERNAL_STORAGE is supported since API level 8, why the original codes use 0x00040000 the constant itself rather that the constant variable FLAG_EXTERNAL_STORAGE?
LiliWeiSE commented 7 years ago
  1. I see. I checked the revision. I categorized it as device-specific because of the commit log and the exception information. It indicated that "Protect call log helper from device that doesn't have call log db" which suggests an implicit context that the device does not have the call log database.

  2. 0x00040000 is exactly the same as FLAG_EXTERNAL_STORAGE so actually it is equivalent to use them. (I found sometimes compiler will directly replace FLAG_EXTERNAL_STORAGE with the constant value at compilation time) The FIC issue here is that on devices lower than API 8, even using the constant value, the app will still not work properly.

connglli commented 7 years ago

Alright, I see! Thanks!

LiliWeiSE commented 7 years ago

By the way, I may made mistakes when analyzing the data set. Feel free to point them out if you find any