Skip to content

Commit b091315

Browse files
authored
Merge pull request #353 from stefanie-koss/refactorLifecycleAnalyzing
Refactor lifecycle analyzing
2 parents f4343e9 + 7767d16 commit b091315

2 files changed

Lines changed: 82 additions & 75 deletions

File tree

soot-infoflow-android/src/soot/jimple/infoflow/android/callbacks/DefaultCallbackAnalyzer.java

Lines changed: 1 addition & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import java.io.IOException;
44
import java.util.ArrayList;
5-
import java.util.Collection;
6-
import java.util.Collections;
75
import java.util.HashSet;
86
import java.util.Iterator;
97
import java.util.List;
@@ -26,7 +24,6 @@
2624
import soot.jimple.infoflow.android.callbacks.filters.ICallbackFilter;
2725
import soot.jimple.infoflow.android.entryPointCreators.AndroidEntryPointConstants;
2826
import soot.jimple.infoflow.android.entryPointCreators.AndroidEntryPointUtils;
29-
import soot.jimple.infoflow.android.entryPointCreators.AndroidEntryPointUtils.ComponentType;
3027
import soot.jimple.infoflow.memory.IMemoryBoundedSolver;
3128
import soot.jimple.infoflow.memory.ISolverTerminationReason;
3229
import soot.jimple.infoflow.util.SystemClassHandler;
@@ -97,7 +94,7 @@ protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes")
9794
break;
9895

9996
List<MethodOrMethodContext> methods = new ArrayList<MethodOrMethodContext>(
100-
getLifecycleMethods(sc));
97+
entryPointUtils.getLifecycleMethods(sc));
10198

10299
// Check for callbacks registered in the code
103100
analyzeRechableMethods(sc, methods);
@@ -155,77 +152,6 @@ protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes")
155152
PackManager.v().getPack("wjtp").add(transform);
156153
}
157154

158-
/**
159-
* Gets all lifecycle methods in the given entry point class
160-
*
161-
* @param sc The class in which to look for lifecycle methods
162-
* @return The set of lifecycle methods in the given class
163-
*/
164-
private Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc) {
165-
return getLifecycleMethods(entryPointUtils.getComponentType(sc), sc);
166-
}
167-
168-
/**
169-
* Gets all lifecycle methods in the given entry point class
170-
*
171-
* @param componentType the component type
172-
* @param sc The class in which to look for lifecycle methods
173-
* @return The set of lifecycle methods in the given class
174-
*/
175-
public static Collection<? extends MethodOrMethodContext> getLifecycleMethods(ComponentType componentType,
176-
SootClass sc) {
177-
switch (componentType) {
178-
case Activity:
179-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getActivityLifecycleMethods());
180-
case Service:
181-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceLifecycleMethods());
182-
case Application:
183-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getApplicationLifecycleMethods());
184-
case BroadcastReceiver:
185-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getBroadcastLifecycleMethods());
186-
case Fragment:
187-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getFragmentLifecycleMethods());
188-
case ContentProvider:
189-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getContentproviderLifecycleMethods());
190-
case GCMBaseIntentService:
191-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMIntentServiceMethods());
192-
case GCMListenerService:
193-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMListenerServiceMethods());
194-
case ServiceConnection:
195-
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceConnectionMethods());
196-
case Plain:
197-
return Collections.emptySet();
198-
}
199-
return Collections.emptySet();
200-
}
201-
202-
/**
203-
* This method takes a lifecycle class and the list of lifecycle method
204-
* subsignatures. For each subsignature, it checks whether the given class or
205-
* one of its superclass overwrites the respective methods. All findings are
206-
* collected in a set and returned.
207-
*
208-
* @param sc The class in which to look for lifecycle method
209-
* implementations
210-
* @param methods The list of lifecycle method subsignatures for the type of
211-
* component that the given class corresponds to
212-
* @return The set of implemented lifecycle methods in the given class
213-
*/
214-
private static Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc, List<String> methods) {
215-
Set<MethodOrMethodContext> lifecycleMethods = new HashSet<>();
216-
SootClass currentClass = sc;
217-
while (currentClass != null) {
218-
for (String sig : methods) {
219-
SootMethod sm = currentClass.getMethodUnsafe(sig);
220-
if (sm != null)
221-
if (!SystemClassHandler.v().isClassInSystemPackage(sm.getDeclaringClass().getName()))
222-
lifecycleMethods.add(sm);
223-
}
224-
currentClass = currentClass.hasSuperclass() ? currentClass.getSuperclass() : null;
225-
}
226-
return lifecycleMethods;
227-
}
228-
229155
private void analyzeRechableMethods(SootClass lifecycleElement, List<MethodOrMethodContext> methods) {
230156
// Make sure to exclude all other edges in the callgraph except for the
231157
// edges start in the lifecycle methods we explicitly pass in

soot-infoflow-android/src/soot/jimple/infoflow/android/entryPointCreators/AndroidEntryPointUtils.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
package soot.jimple.infoflow.android.entryPointCreators;
22

3+
import java.util.Collection;
4+
import java.util.Collections;
35
import java.util.HashMap;
6+
import java.util.HashSet;
7+
import java.util.List;
48
import java.util.Map;
9+
import java.util.Set;
510

611
import org.slf4j.Logger;
712
import org.slf4j.LoggerFactory;
813

914
import soot.FastHierarchy;
15+
import soot.MethodOrMethodContext;
1016
import soot.Scene;
1117
import soot.SootClass;
1218
import soot.SootMethod;
19+
import soot.jimple.infoflow.util.SystemClassHandler;
1320

1421
/**
1522
* Class containing common utility methods for dealing with Android entry points
@@ -162,6 +169,9 @@ public boolean isEntryPointMethod(SootMethod method) {
162169
if (componentType == ComponentType.Service
163170
&& AndroidEntryPointConstants.getServiceLifecycleMethods().contains(subsignature))
164171
return true;
172+
if (componentType == ComponentType.Application
173+
&& AndroidEntryPointConstants.getApplicationLifecycleMethods().contains(subsignature))
174+
return true;
165175
if (componentType == ComponentType.Fragment
166176
&& AndroidEntryPointConstants.getFragmentLifecycleMethods().contains(subsignature))
167177
return true;
@@ -184,4 +194,75 @@ public boolean isEntryPointMethod(SootMethod method) {
184194
return false;
185195
}
186196

197+
/**
198+
* Gets all lifecycle methods in the given entry point class
199+
*
200+
* @param sc The class in which to look for lifecycle methods
201+
* @return The set of lifecycle methods in the given class
202+
*/
203+
public Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc) {
204+
return getLifecycleMethods(getComponentType(sc), sc);
205+
}
206+
207+
/**
208+
* Gets all lifecycle methods in the given entry point class
209+
*
210+
* @param componentType the component type
211+
* @param sc The class in which to look for lifecycle methods
212+
* @return The set of lifecycle methods in the given class
213+
*/
214+
public static Collection<? extends MethodOrMethodContext> getLifecycleMethods(ComponentType componentType,
215+
SootClass sc) {
216+
switch (componentType) {
217+
case Activity:
218+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getActivityLifecycleMethods());
219+
case Service:
220+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceLifecycleMethods());
221+
case Application:
222+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getApplicationLifecycleMethods());
223+
case BroadcastReceiver:
224+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getBroadcastLifecycleMethods());
225+
case Fragment:
226+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getFragmentLifecycleMethods());
227+
case ContentProvider:
228+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getContentproviderLifecycleMethods());
229+
case GCMBaseIntentService:
230+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMIntentServiceMethods());
231+
case GCMListenerService:
232+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getGCMListenerServiceMethods());
233+
case ServiceConnection:
234+
return getLifecycleMethods(sc, AndroidEntryPointConstants.getServiceConnectionMethods());
235+
case Plain:
236+
return Collections.emptySet();
237+
}
238+
return Collections.emptySet();
239+
}
240+
241+
/**
242+
* This method takes a lifecycle class and the list of lifecycle method
243+
* subsignatures. For each subsignature, it checks whether the given class or
244+
* one of its superclass overwrites the respective methods. All findings are
245+
* collected in a set and returned.
246+
*
247+
* @param sc The class in which to look for lifecycle method
248+
* implementations
249+
* @param methods The list of lifecycle method subsignatures for the type of
250+
* component that the given class corresponds to
251+
* @return The set of implemented lifecycle methods in the given class
252+
*/
253+
private static Collection<? extends MethodOrMethodContext> getLifecycleMethods(SootClass sc, List<String> methods) {
254+
Set<MethodOrMethodContext> lifecycleMethods = new HashSet<>();
255+
SootClass currentClass = sc;
256+
while (currentClass != null) {
257+
for (String sig : methods) {
258+
SootMethod sm = currentClass.getMethodUnsafe(sig);
259+
if (sm != null)
260+
if (!SystemClassHandler.v().isClassInSystemPackage(sm.getDeclaringClass().getName()))
261+
lifecycleMethods.add(sm);
262+
}
263+
currentClass = currentClass.hasSuperclass() ? currentClass.getSuperclass() : null;
264+
}
265+
return lifecycleMethods;
266+
}
267+
187268
}

0 commit comments

Comments
 (0)