Automated API-Usage Update for Android Apps Mattia Fazzini Qi Xin - - PowerPoint PPT Presentation
Automated API-Usage Update for Android Apps Mattia Fazzini Qi Xin - - PowerPoint PPT Presentation
Automated API-Usage Update for Android Apps Mattia Fazzini Qi Xin Alessandro Orso Mobile Applications Platform Platform Tight Coupling Platforms Change Platforms Change Frequently Android Petit Four Cupcake Donut 1.1 Eclair Froyo
Mobile Applications
Platform
Platform
Tight Coupling
Platforms Change
Platforms Change Frequently
Android Eclair Ice Cream Marshmallow Donut Petit Four Cupcake Honeycomb Froyo Gingerbread Lollipop Jelly Bean KitKat Pie Nougat Oreo
1.1
App
Developer
Adaptive Maintenance
Platform
App
New Platform
Platform Fragmentation
Gingerbread Ice Cream Jelly Bean KitKat Lollipop Marshmallow Nougat Oreo
App C
Developer C
App B
Developer B
App A
Intuition
Developer A
App C
Developer C
App B
Developer B
App A
Intuition
Developer A
App C
Developer C
App B
Developer B
App A
Intuition
Developer A
API Updates
API-Usage Changes
public NetworkInfo[] getAllNetworkInfo()
public Network[] getAllNetworks()
New API Usage
public NetworkInfo getNetworkInfo(Network network) public NetworkInfo[] getAllNetworkInfo()
Old API Usage
API Updates
API-Usage Changes
public NetworkInfo[] getAllNetworkInfo()
public Network[] getAllNetworks()
New API Usage
public NetworkInfo getNetworkInfo(Network network) public NetworkInfo[] getAllNetworkInfo()
Old API Usage
API Updates
API-Usage Changes
public NetworkInfo[] getAllNetworkInfo()
public Network[] getAllNetworks()
New API Usage
public NetworkInfo getNetworkInfo(Network network) public NetworkInfo[] getAllNetworkInfo()
Old API Usage
API Updates
API-Usage Changes
public NetworkInfo[] getAllNetworkInfo()
public Network[] getAllNetworks()
New API Usage
public NetworkInfo getNetworkInfo(Network network) public NetworkInfo[] getAllNetworkInfo()
Old API Usage
Update Example
Update Example Before Update Example After
public boolean isConnected(Context cont) { ConnectivityManager cm = ...; NetworkInfo[] info = cm.getAllNetworkInfo(); for (int i = 0; i < info.length; i++) { if(info[i].isConnected()) { return true; } } Toast.makeText(R.s.noNet).show(); return false; } public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; if (VERSION.SDK_INT >= VERSION_CODES.M) { Network[] networks = cm.getAllNetworks(); for (Network mNetwork : networks) { NetworkInfo networkInfo = cm.getNetworkInfo(mNetwork); if(networkInfo.isConnected()) { Log.d(networkInfo.getTypeName()); return true; } } } else { NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(anInfo.isConnected()) { Log.d(anInfo.getTypeName()); return true; } } } Toast.makeText(cont.getString(...)).show(); return false; }
Update Example
Update Example Before Update Example After
public boolean isConnected(Context cont) { ConnectivityManager cm = ...; NetworkInfo[] info = cm.getAllNetworkInfo(); for (int i = 0; i < info.length; i++) { if(info[i].isConnected()) { return true; } } Toast.makeText(R.s.noNet).show(); return false; } public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; if (VERSION.SDK_INT >= VERSION_CODES.M) { Network[] networks = cm.getAllNetworks(); for (Network mNetwork : networks) { NetworkInfo networkInfo = cm.getNetworkInfo(mNetwork); if(networkInfo.isConnected()) { Log.d(networkInfo.getTypeName()); return true; } } } else { NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(anInfo.isConnected()) { Log.d(anInfo.getTypeName()); return true; } } } Toast.makeText(cont.getString(...)).show(); return false; }
Update Example After
public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; if (VERSION.SDK_INT >= VERSION_CODES.M) { Network[] networks = cm.getAllNetworks(); for (Network mNetwork : networks) { NetworkInfo networkInfo = cm.getNetworkInfo(mNetwork); if(networkInfo.isConnected()) { Log.d(networkInfo.getTypeName()); return true; } } } else { NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(anInfo.isConnected()) { Log.d(anInfo.getTypeName()); return true; } } } Toast.makeText(cont.getString(...)).show(); return false; }
Update Example
Update Example Before
public boolean isConnected(Context cont) { ConnectivityManager cm = ...; NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(info[i].isConnected()) { return true; } } Toast.makeText(R.s.noNet).show(); return false; }
public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; if (VERSION.SDK_INT >= VERSION_CODES.M) { Network[] networks = cm.getAllNetworks(); for (Network mNetwork : networks) { NetworkInfo networkInfo = cm.getNetworkInfo(mNetwork); if(networkInfo.isConnected()) { Log.d(networkInfo.getTypeName()); return true; } } } else { NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(anInfo.isConnected()) { Log.d(anInfo.getTypeName()); return true; } } } Toast.makeText(cont.getString(...)).show(); return false; }
Update Example After
Update Example
Update Example Before
public boolean isConnected(Context cont) { ConnectivityManager cm = ...; NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(info[i].isConnected()) { return true; } } Toast.makeText(R.s.noNet).show(); return false; }
APPEVOLVE Overview
Identify API usages requiring update in target app
Find update examples for identified API usages Abstract update examples into generic update patches and rank them Update and validate API usages in target app based on patches
APPEVOLVE Overview
Identify API usages requiring update in target app
Find update examples for identified API usages Abstract update examples into generic update patches and rank them Update and validate API usages in target app based on patches
APPEVOLVE Overview
Identify API usages requiring update in target app
Find update examples for identified API usages Abstract update examples into generic update patches and rank them Update and validate API usages in target app based on patches
Update Example Search
Code Hosting Infrastructure Keyword-Based Search
∀
∈
method signature New API Usage
Search Result
Code Base App1 Code Base App2 Code Base App3 Code Base App4
f1i−n f1i−1 f1i
f2j−1 f2j
f4k−1 f4k
method name, param types, declaring class
Update Example Search
Code Hosting Infrastructure Keyword-Based Search
∀
∈
method signature New API Usage
Search Result
Code Base App1 Code Base App2 Code Base App3 Code Base App4
f1i−n f1i−1 f1i
f2j−1 f2j
f4k−1 f4k
Search Result
Code Base App1 Code Base App2 Code Base App3 Code Base App4
f1i−n f1i−1 f1i
f2j−1 f2j
f4k−1 f4k
method name, param types, declaring class
Update Example Search
Code Hosting Infrastructure Keyword-Based Search
∀
∈
method signature New API Usage
Search Result
Code Base App1 Code Base App2 Code Base App3 Code Base App4
f1i−n f1i−1 f1i
f2j−1 f2j
f4k−1 f4k
Search Result
Code Base App1 Code Base App2 Code Base App3 Code Base App4
f1i−n f1i−1 f1i
f2j−1 f2j
f4k−1 f4k
method name, param types, declaring class
Update Example Search
public boolean isConnected(Context cont) { ConnectivityManager cm = ...; NetworkInfo[] info = cm.getAllNetworkInfo(); for (int i = 0; i < info.length; i++) { if(info[i].isConnected()) { return true; } } Toast.makeText(R.s.noNet).show(); return false; } public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; if (VERSION.SDK_INT >= VERSION_CODES.M) { Network[] networks = cm.getAllNetworks(); for (Network mNetwork : networks) { NetworkInfo networkInfo = cm.getNetworkInfo(mNetwork); if(networkInfo.isConnected()) { Log.d(networkInfo.getTypeName()); return true; } } } else { NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(anInfo.isConnected()) { Log.d(anInfo.getTypeName()); return true; } } } Toast.makeText(cont.getString(...)).show(); return false; }
( f1i−1)
Before Update
( f1i)
After Update
public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; + if (VERSION.SDK_INT >= VERSION_CODES.M) { + Network[] networks = cm.getAllNetworks(); + for (Network mNetwork : networks) { + NetworkInfo networkInfo = + cm.getNetworkInfo(mNetwork); + if(networkInfo.isConnected()) { + Log.d(networkInfo.getTypeName()); return true; } } + } else { + NetworkInfo[] info = cm.getAllNetworkInfo(); + for (NetworkInfo anInfo : info) { + if(anInfo.isConnected()) { + Log.d(anInfo.getTypeName()); + return true; + } } + } + Toast.makeText(cont.getString(...)).show(); return false; }
Update Example Search
Compute Differences
public boolean isConnected(Context cont) { ConnectivityManager cm = ...;
- NetworkInfo[] info = cm.getAllNetworkInfo();
- for (int i = 0; i < info.length; i++) {
- if(info[i].isConnected()) {
return true; } }
- Toast.makeText(R.s.noNet).show();
return false; }
( f1i−1)
Before Update
( f1i)
After Update
public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; + if (VERSION.SDK_INT >= VERSION_CODES.M) { + Network[] networks = cm.getAllNetworks(); + for (Network mNetwork : networks) { + NetworkInfo networkInfo = + cm.getNetworkInfo(mNetwork); + if(networkInfo.isConnected()) { + Log.d(networkInfo.getTypeName()); return true; } } + } else { + NetworkInfo[] info = cm.getAllNetworkInfo(); + for (NetworkInfo anInfo : info) { + if(anInfo.isConnected()) { + Log.d(anInfo.getTypeName()); + return true; + } } + } + Toast.makeText(cont.getString(...)).show(); return false; }
Update Example Search
Compute Differences
public boolean isConnected(Context cont) { ConnectivityManager cm = ...;
- NetworkInfo[] info = cm.getAllNetworkInfo();
- for (int i = 0; i < info.length; i++) {
- if(info[i].isConnected()) {
return true; } }
- Toast.makeText(R.s.noNet).show();
return false; }
( f1i−1)
Before Update
( f1i)
After Update Added check on platform version Added new API Usage Moved old API Usage
public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; + if (VERSION.SDK_INT >= VERSION_CODES.M) { + Network[] networks = cm.getAllNetworks(); + for (Network mNetwork : networks) { + NetworkInfo networkInfo = + cm.getNetworkInfo(mNetwork); + if(networkInfo.isConnected()) { + Log.d(networkInfo.getTypeName()); return true; } } + } else { + NetworkInfo[] info = cm.getAllNetworkInfo(); + for (NetworkInfo anInfo : info) { + if(anInfo.isConnected()) { + Log.d(anInfo.getTypeName()); + return true; + } } + } + Toast.makeText(cont.getString(...)).show(); return false; }
Update Example Search
Compute Differences
public boolean isConnected(Context cont) { ConnectivityManager cm = ...;
- NetworkInfo[] info = cm.getAllNetworkInfo();
- for (int i = 0; i < info.length; i++) {
- if(info[i].isConnected()) {
return true; } }
- Toast.makeText(R.s.noNet).show();
return false; }
( f1i−1)
Before Update
( f1i)
After Update Added check on platform version Added new API Usage Moved old API Usage Update Example
public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; + if (VERSION.SDK_INT >= VERSION_CODES.M) { + Network[] networks = cm.getAllNetworks(); + for (Network mNetwork : networks) { + NetworkInfo networkInfo = + cm.getNetworkInfo(mNetwork); + if(networkInfo.isConnected()) { + Log.d(networkInfo.getTypeName()); return true; } } + } else { + NetworkInfo[] info = cm.getAllNetworkInfo(); + for (NetworkInfo anInfo : info) { + if(anInfo.isConnected()) { + Log.d(anInfo.getTypeName()); + return true; + } } + } + Toast.makeText(cont.getString(...)).show(); return false; }
Update Example Search
Compute Differences
public boolean isConnected(Context cont) { ConnectivityManager cm = ...;
- NetworkInfo[] info = cm.getAllNetworkInfo();
- for (int i = 0; i < info.length; i++) {
- if(info[i].isConnected()) {
return true; } }
- Toast.makeText(R.s.noNet).show();
return false; }
( f1i−1)
Before Update
( f1i)
After Update Added check on platform version Added new API Usage Moved old API Usage Update Example Update Examples
Code Base App1 Code Base App2 Code Base App4 Code Base App3
APPEVOLVE Overview
Identify API usages requiring update in target app
Find update examples for identified API usages Abstract update examples into generic update patches and rank them Update and validate API usages in target app based on patches
Update Example Analysis
public boolean isConnected(Context cont) { ConnectivityManager cm = ...; NetworkInfo[] info = cm.getAllNetworkInfo(); for (int i = 0; i < info.length; i++) { if(info[i].isConnected()) { return true; } } Toast.makeText(R.s.noNet).show(); return false; } public boolean isConnected(Context cont) { ConnectivityManager cm = ... ; if (VERSION.SDK_INT >= VERSION_CODES.M) { Network[] networks = cm.getAllNetworks(); for (Network mNetwork : networks) { NetworkInfo networkInfo = cm.getNetworkInfo(mNetwork); if(networkInfo.isConnected()) { Log.d(networkInfo.getTypeName()); return true; } } } else { NetworkInfo[] info = cm.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(anInfo.isConnected()) { Log.d(anInfo.getTypeName()); return true; } } } Toast.makeText(cont.getString(...)).show(); return false; }
( f1i−1)
Update Example Before
( f1i)
Update Example After
Compute Update Patch
Update Example Analysis
( f1i−1)
Abstract Syntax Tree Before
( f1i)
Abstract Syntax Tree After
Compute Update Patch
Update Example Analysis
( f1i−1)
Abstract Syntax Tree Before
( f1i)
Abstract Syntax Tree After
Compute Update Patch
Edit Operations
INSERT(sn1, sn2, i) MOVE(sn1, sn2, i) UPDATE(sn1, sn2) DELETE(sn1)
Update Example Analysis
( f1i−1)
Abstract Syntax Tree Before
( f1i)
Abstract Syntax Tree After
Compute Update Patch
Raw Edit Script
INSERT if VERSION.SDK_INT>=VERSION_CODES.M UPDATE Toast.makeText(R.s.noNet).show() Toast.makeText(cont.getString(...)).show() INSERT Network[] networks=cm.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=cm.getAllNetworkInfo() INSERT NetworkInfo nI=cm.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Update Example Analysis
( f1i−1)
Abstract Syntax Tree Before
( f1i)
Abstract Syntax Tree After Unrelated Edits
INSERT if VERSION.SDK_INT>=VERSION_CODES.M UPDATE Toast.makeText(R.s.noNet).show() Toast.makeText(cont.getString(...)).show() INSERT Network[] networks=cm.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=cm.getAllNetworkInfo() INSERT NetworkInfo nI=cm.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Compute Update Patch
Update Example Analysis
( f1i−1)
Abstract Syntax Tree Before
( f1i)
Abstract Syntax Tree After Edit Script
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=cm.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=cm.getAllNetworkInfo() INSERT NetworkInfo nI=cm.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Dependency Analysis
Compute Update Patch
Update Example Analysis
( f1i−1)
Abstract Syntax Tree Before
( f1i)
Abstract Syntax Tree After Unneeded Edits
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=cm.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=cm.getAllNetworkInfo() INSERT NetworkInfo nI=cm.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Compute Update Patch
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=cm.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=cm.getAllNetworkInfo() INSERT NetworkInfo nI=cm.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Edit Script Update Example #1
Update Example Analysis
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=cMan.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=cMan.getAllNetworkInfo() INSERT NetworkInfo nI=cMan.getNetworkInfo(mNetwork) UPDATE if info[i].getState()==CONNECTED if nI.getState()==CONNECTED MOVERT if nI.getState()==CONNECTED INSERT for NetworkInfo anInfo:info INSERT if anInfo.getState()==CONNECTED INSERT return true DELETE for int j=0 j<info.length j++
Edit Script Update Example #2
Edit Script Abstraction #1
Update Example Analysis
Edit Script Abstraction #2
Find common core using Multiple Longest Common Subsequence (MLCS)
MLCS Solution Core Proximity Value
|MLC Solution| |Edit Script|
Core Proximity Value = 0.62 Core Proximity Value = 0.72
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=$V.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=$V.getAllNetworkInfo() INSERT NetworkInfo nI=$V.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Edit Script
Update Example Analysis
Core Proximity Value = 0.62
Context Variable Computation
Context Variables[($V,ConnectivityManager:cm)]
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=$V.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=$V.getAllNetworkInfo() INSERT NetworkInfo nI=$V.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Edit Script
Update Example Analysis
Core Proximity Value = 0.62
Generic Update Patch
Context Variables[($V,ConnectivityManager:cm)]
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=$V.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=$V.getAllNetworkInfo() INSERT NetworkInfo nI=$V.getNetworkInfo(mNetwork) UPDATE if info[i].isConnected() if nI.isConnected() MOVERT if nI.isConnected() INSERT Log.d(networkInfo.getTypeName()) INSERT for NetworkInfo anInfo:info INSERT if anInfo.isConnected() INSERT Log.d(anInfo.getTypeName()) INSERT return true DELETE for int i=0 i<info.length i++
Edit Script
Update Example Analysis
Core Proximity Value = 0.62
Generic Update Patch
Context Variables[($V,ConnectivityManager:cm)]
Generic Update Patches
1st 2nd 3rd
APPEVOLVE Overview
Identify API usages requiring update in target app
Find update examples for identified API usages Abstract update examples into generic update patches and rank them Update and validate API usages in target app based on patches
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=$V.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=$V.getAllNetworkInfo() INSERT NetworkInfo nI=$V.getNetworkInfo(mNetwork) UPDATE if info[i].getState()==CONNECTED if nI.getState()==CONNECTED MOVERT if nI.getState()==CONNECTED INSERT for NetworkInfo anInfo:info INSERT if anInfo.getState()==CONNECTED INSERT return true DELETE for int j=0 j<info.length j++
Core Proximity Value = 0.72 Context Variables[($V,ConnectivityManager:cMan)]
API-Usage Update
public boolean hasNetwork(Context context) { ConnectivityManager conn = ...; NetworkInfo[] netInfo = conn.getAllNetworkInfo(); for (int k = 0; k < netInfo; k++) { if (netInfo[k].getState() == NetworkInfo.State.CONNECTED) { return true; } } return false; }
Target App Code Generic Update Patch Edit Script
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=cMan.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=cMan.getAllNetworkInfo() INSERT NetworkInfo nI=cMan.getNetworkInfo(mNetwork) UPDATE if info[i].getState()==CONNECTED if nI.getState()==CONNECTED MOVERT if nI.getState()==CONNECTED INSERT for NetworkInfo anInfo:info INSERT if anInfo.getState()==CONNECTED INSERT return true DELETE for int j=0 j<info.length j++
Core Proximity Value = 0.72 Context Variables
API-Usage Update
public boolean hasNetwork(Context context) { ConnectivityManager conn = ...; NetworkInfo[] netInfo = conn.getAllNetworkInfo(); for (int k = 0; k < netInfo; k++) { if (netInfo[k].getState() == NetworkInfo.State.CONNECTED) { return true; } } return false; }
Target App Code Generic Update Patch Edit Script
[($V,ConnectivityManager:cMan)]
Analyze Variables in Scope
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=$V.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=$V.getAllNetworkInfo() INSERT NetworkInfo nI=$V.getNetworkInfo(mNetwork) UPDATE if info[i].getState()==CONNECTED if nI.getState()==CONNECTED MOVERT if nI.getState()==CONNECTED INSERT for NetworkInfo anInfo:info INSERT if anInfo.getState()==CONNECTED INSERT return true DELETE for int j=0 j<info.length j++
Core Proximity Value = 0.72 Context Variables
API-Usage Update
Abstract Syntax Tree Target App Generic Update Patch Edit Script
[($V,ConnectivityManager:cMan)] [($V,ConnectivityManager:conn)]
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=$V.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=$V.getAllNetworkInfo() INSERT NetworkInfo nI=$V.getNetworkInfo(mNetwork) UPDATE if info[i].getState()==CONNECTED if nI.getState()==CONNECTED MOVERT if nI.getState()==CONNECTED INSERT for NetworkInfo anInfo:info INSERT anInfo.getState()==CONNECTED INSERT return true DELETE for int j=0 j<info.length j++
Core Proximity Value = 0.72 Context Variables
API-Usage Update
Updated Abstract Syntax Tree Target App Generic Update Patch Edit Script
[($V,ConnectivityManager:cMan)] [($V,ConnectivityManager:conn)]
INSERT if VERSION.SDK_INT>=VERSION_CODES.M INSERT Network[] networks=$V.getAllNetworks() INSERT for Network mNetwork:networks MOVERT NetworkInfo[] info=$V.getAllNetworkInfo() INSERT NetworkInfo nI=$V.getNetworkInfo(mNetwork) UPDATE if info[i].getState()==CONNECTED if nI.getState()==CONNECTED MOVERT if nI.getState()==CONNECTED INSERT for NetworkInfo anInfo:info INSERT anInfo.getState()==CONNECTED INSERT return true DELETE for int j=0 j<info.length j++
Core Proximity Value = 0.72 Context Variables
API-Usage Update
Updated Target App Code Generic Update Patch Edit Script
[($V,ConnectivityManager:cMan)] [($V,ConnectivityManager:conn)] public boolean hasNetwork(Context context) { ConnectivityManager conn = ... ; if (VERSION.SDK_INT >= VERSION_CODES.M) { Network[] networks = conn.getAllNetworks(); for (Network mNetwork : networks) { NetworkInfo networkInfo = conn.getNetworkInfo(mNetwork); if(networkInfo.getState() == NetworkInfo.State.CONNECTED) { return true; } } } else { NetworkInfo[] info = conn.getAllNetworkInfo(); for (NetworkInfo anInfo : info) { if(anInfo.getState() == NetworkInfo.State.CONNECTED) { return true; } } } return false; }
API-Usage Update
New Platform
Differential Testing
Old Platform
API-Usage Update
New Platform
Differential Testing
Old Platform
Target App
API-Usage Update
New Platform
Differential Testing
Old Platform
Target App Updated Target App Updated Target App
Empirical Evaluation
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps? RQ2 (EFFICIENCY): What is the cost of running APPEVOLVE?
Research Questions
Empirical Evaluation
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps? RQ2 (EFFICIENCY): What is the cost of running APPEVOLVE?
Research Questions
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps?
Empirical Evaluation
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps? RQ2 (EFFICIENCY): What is the cost of running APPEVOLVE?
Research Questions
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps? RQ2 (EFFICIENCY): What is the cost of running APPEVOLVE?
Benchmarks and Setup
20 API Usages
addAction getAllNetworkInfo getCurrentHour getCurrentMinute setCurrentHour setCurrentMinute setTextAppearance addGpsStatusListener fromHtml release removeGpsStatusListener shouldOverrideUrlLoading startDrag abandonAudioFocus getDeviceId requestAudioFocus saveLayer setAudioStreamType vibrate(long) vibrate(long[],int) (41 occurrences)
Lollipop Marshmallow Nougat
15 Apps
BIPOLALARM CONVERSATIONS PARKENDD CLEAN SB OPENSUDOKU WIGLE WIFI FOOTGUY CALENDAR IE DIOLINUX SOLAR COMPASS SYMPHONY SYSLOG MUZEI NOTES ONETWO
Setup
- Ran technique on benchmarks
- Measured successful update and validation rate
- Measured execution time
Benchmarks and Setup
20 API Usages
addAction getAllNetworkInfo getCurrentHour getCurrentMinute setCurrentHour setCurrentMinute setTextAppearance addGpsStatusListener fromHtml release removeGpsStatusListener shouldOverrideUrlLoading startDrag abandonAudioFocus getDeviceId requestAudioFocus saveLayer setAudioStreamType vibrate(long) vibrate(long[],int) (41 occurrences)
Lollipop Marshmallow Nougat
15 Apps
BIPOLALARM CONVERSATIONS PARKENDD CLEAN SB OPENSUDOKU WIGLE WIFI FOOTGUY CALENDAR IE DIOLINUX SOLAR COMPASS SYMPHONY SYSLOG MUZEI NOTES ONETWO
20 API Usages
addAction getAllNetworkInfo getCurrentHour getCurrentMinute setCurrentHour setCurrentMinute setTextAppearance addGpsStatusListener fromHtml release removeGpsStatusListener shouldOverrideUrlLoading startDrag abandonAudioFocus getDeviceId requestAudioFocus saveLayer setAudioStreamType vibrate(long) vibrate(long[],int) (41 occurrences)
Setup
- Ran technique on benchmarks
- Measured successful update and validation rate
- Measured execution time
Benchmarks and Setup
20 API Usages
addAction getAllNetworkInfo getCurrentHour getCurrentMinute setCurrentHour setCurrentMinute setTextAppearance addGpsStatusListener fromHtml release removeGpsStatusListener shouldOverrideUrlLoading startDrag abandonAudioFocus getDeviceId requestAudioFocus saveLayer setAudioStreamType vibrate(long) vibrate(long[],int) (41 occurrences)
Lollipop Marshmallow Nougat
15 Apps
BIPOLALARM CONVERSATIONS PARKENDD CLEAN SB OPENSUDOKU WIGLE WIFI FOOTGUY CALENDAR IE DIOLINUX SOLAR COMPASS SYMPHONY SYSLOG MUZEI NOTES ONETWO
20 API Usages
addAction getAllNetworkInfo getCurrentHour getCurrentMinute setCurrentHour setCurrentMinute setTextAppearance addGpsStatusListener fromHtml release removeGpsStatusListener shouldOverrideUrlLoading startDrag abandonAudioFocus getDeviceId requestAudioFocus saveLayer setAudioStreamType vibrate(long) vibrate(long[],int) (41 occurrences)
Setup
- Ran technique on benchmarks
- Measured successful update and validation rate
- Measured execution time
Setup
- Ran technique on benchmarks
- Measured successful update and validation rate
- Measured execution time
Evaluation: Effectiveness
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps?
- In 19/20 cases, APPEVOLVE could find update examples
- In 14/19 cases, the number of relevant edits is lower than the number of AST edits
- In 11/19 cases, the core proximity value is different from its minimum and maximum
Details
APPEVOLVE is effective in automatically updating API usages.
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps?
- 37/41 (90%) successful update rate (for API-usage occurrences)
- 25/37 (68%) automatic validation rate (for API-usage occurrences)
Overall Effectivness
- 17/20 (85%) successful update rate (for API usages)
Evaluation: Effectiveness
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps?
- In 19/20 cases, APPEVOLVE could find update examples
- In 14/19 cases, the number of relevant edits is lower than the number of AST edits
- In 11/19 cases, the core proximity value is different from its minimum and maximum
Details
APPEVOLVE is effective in automatically updating API usages.
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps?
- 37/41 (90%) successful update rate (for API-usage occurrences)
- 25/37 (68%) automatic validation rate (for API-usage occurrences)
Overall Effectivness
- 17/20 (85%) successful update rate (for API usages)
- In 19/20 cases, APPEVOLVE could find update examples
- In 14/19 cases, the number of relevant edits is lower than the number of AST edits
- In 11/19 cases, the core proximity value is different from its minimum and maximum
Details
Evaluation: Effectiveness
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps?
- In 19/20 cases, APPEVOLVE could find update examples
- In 14/19 cases, the number of relevant edits is lower than the number of AST edits
- In 11/19 cases, the core proximity value is different from its minimum and maximum
Details
APPEVOLVE is effective in automatically updating API usages.
RQ1 (EFFECTIVENESS): Can APPEVOLVE update API usages in real-world apps?
- 37/41 (90%) successful update rate (for API-usage occurrences)
- 25/37 (68%) automatic validation rate (for API-usage occurrences)
Overall Effectivness
- 17/20 (85%) successful update rate (for API usages)
- In 19/20 cases, APPEVOLVE could find update examples
- In 14/19 cases, the number of relevant edits is lower than the number of AST edits
- In 11/19 cases, the core proximity value is different from its minimum and maximum
Details
APPEVOLVE is effective in automatically updating API usages.
Evaluation: Efficiency
RQ2 (EFFICIENCY): What is the cost of running APPEVOLVE?
API-Usage Analysis Update Examples Search Update Examples Analysis API-Usage Update 28s 10h27m 2s204ms 20s The cost of the update examples search phase dominates the cost of the other phases.
Average Execution Time
API-Usage Analysis Update Examples Search Update Examples Analysis API-Usage Update 28s 10h27m 2s204ms 20s The cost of the update examples search phase dominates the cost of the other phases.
Average Execution Time
Future Work
Handle updates that span across multiple methods Automatically compute API change specifications Improve validation through differential testing Investigate use of APPEVOLVE in other contexts (e.g., web apps)
Future Work
Handle updates that span across multiple methods Automatically compute API change specifications Improve validation through differential testing Investigate use of APPEVOLVE in other contexts (e.g., web apps) Handle updates that span across multiple methods
Future Work
Handle updates that span across multiple methods Automatically compute API change specifications Improve validation through differential testing Investigate use of APPEVOLVE in other contexts (e.g., web apps) Handle updates that span across multiple methods Automatically compute API change specifications
Future Work
Handle updates that span across multiple methods Automatically compute API change specifications Improve validation through differential testing Investigate use of APPEVOLVE in other contexts (e.g., web apps) Handle updates that span across multiple methods Automatically compute API change specifications Improve validation through differential testing
Future Work
Handle updates that span across multiple methods Automatically compute API change specifications Improve validation through differential testing Investigate use of APPEVOLVE in other contexts (e.g., web apps) Handle updates that span across multiple methods Automatically compute API change specifications Improve validation through differential testing Investigate use of APPEVOLVE in other contexts (e.g., web apps)
Summary
Summary
https://b.gatech.edu/2JKkpWV
Artifact
Related Work
Example Based Program Update
SYDIT, LASE, RASE, MEDITOR, REFAZER, ARES,…
Other Techniques
ICTAPIFINDER, CHANGEDISTILLING