package cm.android.framework.server; import android.content.Context; import android.content.pm.ProviderInfo; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.support.v4.app.BundleCompat; import cm.android.framework.client.core.Framework; import cm.android.framework.client.core.LogUtil; import cm.android.framework.client.ipc.ProviderCall; import cm.android.framework.component.BaseContentProvider; import cm.android.framework.interfaces.IServiceFetcher; import cm.android.framework.server.daemon.DaemonService; public final class ServerProvider extends BaseContentProvider { public static final String M_create = "@create"; public static final String M_destroy = "@destroy"; public static final String M_isActive = "@isActive"; public static final String M_getServiceFetcher = "@getServiceFetcher"; public static final String M_getBundle = "@getBundle"; public static final String M_putBundle = "@putBundle"; public static String AUTHORITIES = "framework.provider"; public static final String KEY_BINDER = "_framework_|_binder_"; private final ServiceFetcher mServiceFetcher = new ServiceFetcher(); private final BinderServerAgent binderServer = new BinderServerAgent(); public static void authorities(String authorities) { AUTHORITIES = authorities; } @Override public void attachInfo(Context context, ProviderInfo info) { super.attachInfo(context, info); } @Override public boolean onCreate() { LogUtil.getLogger().info("ServerProvider:onCreate:{},getContext():{}", this, getContext()); DaemonService.start(this, getContext()); synchronized (this) { binderServer.attach(Framework.SERVER_NAME); //TODO ggg 方案1:create时判断是否初始化 //TODO ggg 确保getContext().getApplicationContext()不为null binderServer.restore(getContext()); } return true; } // private void addService(String name, IBinder service) { // ServiceFetcherServer.get().addService(name, service); // } @Override public Bundle call(String method, String arg, Bundle extras) { LogUtil.getLogger().info("ServerProvider:isStartup = {},method = {},arg = {},extras = {}", Framework.get().isStartup(), method, arg, extras); synchronized (this) { if (M_create.equals(method)) { binderServer.create(getContext()); } else if (M_destroy.equals(method)) { binderServer.destroy(); } else if (M_isActive.equals(method)) { Bundle bundle = new Bundle(); bundle.putBoolean(KEY_BINDER, binderServer.isActive(getContext())); return bundle; } else if (M_getServiceFetcher.equals(method)) { //TODO 方案2:ggg 每次get前判断下是否初始化 // binderServer.restore(getContext()); Bundle bundle = new Bundle(); BundleCompat.putBinder(bundle, KEY_BINDER, mServiceFetcher); return bundle; } else if (M_getBundle.equals(method)) { Bundle bundle = new Bundle(); bundle.putBundle(KEY_BINDER, binderServer.getBundle(arg)); return bundle; } else if (M_putBundle.equals(method)) { binderServer.putBundle(arg, extras); } } return null; } private static class ServiceFetcher extends IServiceFetcher.Stub { @Override public IBinder getService(String name) throws RemoteException { if (name != null) { return ServiceFetcherServer.get().getService(name); } return null; } @Override public void addService(String name, IBinder service) throws RemoteException { if (name != null && service != null) { ServiceFetcherServer.get().addService(name, service); } } @Override public void removeService(String name) throws RemoteException { if (name != null) { ServiceFetcherServer.get().removeService(name); } } @Override public void clearService() throws RemoteException { ServiceFetcherServer.get().clearService(); } } public static class Proxy { private static Bundle invokeMethod(Context context, String method) { Bundle response = new ProviderCall.Builder(context, AUTHORITIES) .methodName(method) .call(); return response; } private static Bundle invokeMethod(Context context, String method, String arg, Bundle bundle) { Bundle response = new ProviderCall.Builder(context, AUTHORITIES) .methodName(method) .arg(arg) .addArg(bundle) .call(); return response; } public static void create(Context context) { invokeMethod(context, ServerProvider.M_create); } public static void destroy(Context context) { invokeMethod(context, ServerProvider.M_destroy); } public static Bundle isActive(Context context) { return invokeMethod(context, ServerProvider.M_isActive); } public static Bundle getServiceFetcher(Context context) { return invokeMethod(context, ServerProvider.M_getServiceFetcher); } public static Bundle getBundle(Context context, String key) { return invokeMethod(context, ServerProvider.M_getBundle, key, null); } public static Bundle putBundle(Context context, String key, Bundle bundle) { return invokeMethod(context, ServerProvider.M_putBundle, key, bundle); } } }