diff options
Diffstat (limited to 'third_party/sl4a/src/main/java/com/google/android/mobly/snippet/manager/SnippetManager.java')
-rw-r--r-- | third_party/sl4a/src/main/java/com/google/android/mobly/snippet/manager/SnippetManager.java | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/manager/SnippetManager.java b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/manager/SnippetManager.java index ff0aec3..66e33b3 100644 --- a/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/manager/SnippetManager.java +++ b/third_party/sl4a/src/main/java/com/google/android/mobly/snippet/manager/SnippetManager.java @@ -16,11 +16,17 @@ package com.google.android.mobly.snippet.manager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.os.Build; +import android.os.Bundle; import com.google.android.mobly.snippet.Snippet; +import com.google.android.mobly.snippet.event.EventSnippet; import com.google.android.mobly.snippet.rpc.MethodDescriptor; import com.google.android.mobly.snippet.rpc.RpcMinSdk; import com.google.android.mobly.snippet.rpc.RunOnUiThread; +import com.google.android.mobly.snippet.schedulerpc.ScheduleRpcSnippet; import com.google.android.mobly.snippet.util.Log; import com.google.android.mobly.snippet.util.MainThread; import com.google.android.mobly.snippet.util.SnippetLibException; @@ -30,18 +36,24 @@ import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.Callable; public class SnippetManager { + private static final String METADATA_TAG_NAME = "mobly-snippets"; private final Map<Class<? extends Snippet>, Snippet> mSnippets; /** A map of strings to known RPCs. */ private final Map<String, MethodDescriptor> mKnownRpcs; - public SnippetManager(Collection<Class<? extends Snippet>> classList) { + private static SnippetManager sInstance = null; + private boolean mShutdown = false; + + private SnippetManager(Collection<Class<? extends Snippet>> classList) { // Synchronized for multiple connections on the same session. Can't use ConcurrentHashMap // because we have to put in a value of 'null' before the class is constructed, but // ConcurrentHashMap does not allow null values. @@ -65,6 +77,25 @@ public class SnippetManager { mKnownRpcs = Collections.unmodifiableMap(knownRpcs); } + public static synchronized SnippetManager initSnippetManager(Context context) { + if (sInstance != null) { + throw new IllegalStateException("SnippetManager should not be re-initialized"); + } + Collection<Class<? extends Snippet>> classList = findSnippetClassesFromMetadata(context); + sInstance = new SnippetManager(classList); + return sInstance; + } + + public static SnippetManager getInstance() { + if (sInstance == null) { + throw new IllegalStateException("getInstance() called before init()"); + } + if (sInstance.isShutdown()) { + throw new IllegalStateException("shutdown() called before getInstance()"); + } + return sInstance; + } + public MethodDescriptor getMethodDescriptor(String methodName) { return mKnownRpcs.get(methodName); } @@ -114,6 +145,56 @@ public class SnippetManager { entry.getValue().shutdown(); } } + mSnippets.clear(); + mKnownRpcs.clear(); + mShutdown = true; + } + + public boolean isShutdown() { + return mShutdown; + } + + private static Set<Class<? extends Snippet>> findSnippetClassesFromMetadata(Context context) { + ApplicationInfo appInfo; + try { + appInfo = + context.getPackageManager() + .getApplicationInfo( + context.getPackageName(), PackageManager.GET_META_DATA); + } catch (PackageManager.NameNotFoundException e) { + throw new IllegalStateException( + "Failed to find ApplicationInfo with package name: " + + context.getPackageName()); + } + Bundle metadata = appInfo.metaData; + String snippets = metadata.getString(METADATA_TAG_NAME); + if (snippets == null) { + throw new IllegalStateException( + "AndroidManifest.xml does not contain a <metadata> tag with " + + "name=\"" + + METADATA_TAG_NAME + + "\""); + } + String[] snippetClassNames = snippets.split("\\s*,\\s*"); + Set<Class<? extends Snippet>> receiverSet = new HashSet<>(); + /** Add the event snippet class which is provided within the Snippet Lib. */ + receiverSet.add(EventSnippet.class); + /** Add the schedule RPC snippet class which is provided within the Snippet Lib. */ + receiverSet.add(ScheduleRpcSnippet.class); + for (String snippetClassName : snippetClassNames) { + try { + Log.i("Trying to load Snippet class: " + snippetClassName); + Class<?> snippetClass = Class.forName(snippetClassName); + receiverSet.add((Class<? extends Snippet>) snippetClass); + } catch (ClassNotFoundException e) { + Log.e("Failed to find class " + snippetClassName); + throw new RuntimeException(e); + } + } + if (receiverSet.isEmpty()) { + throw new IllegalStateException("Found no subclasses of Snippet."); + } + return receiverSet; } private Snippet get(Class<? extends Snippet> clazz) throws Exception { |