void Process::ProcessImpl::stopService(const sp<Intent>& intent, const sp<IRemoteCallback>& callback) { sp<Service> service; sp<Bundle> result = new Bundle(); { AutoLock autoLock(mProcess->mLock); service = mProcess->mServices->get(intent->getComponent()); } if (service != nullptr) { service->onDestroy(); result->putBoolean("result", true); sp<Context> context = service->getBaseContext(); context->cleanup(); { AutoLock autoLock(mProcess->mLock); mProcess->mServices->remove(intent->getComponent()); mProcess->mCondition->signalAll(); } } else { result->putBoolean("result", false); } if (callback != nullptr) { callback->sendResult(result); } }
void Process::ProcessImpl::createService(const sp<Intent>& intent, const sp<IRemoteCallback>& callback) { sp<Service> service = nullptr; sp<Bundle> result = new Bundle(); sp<String> componentName = String::format("%s::%s", intent->getComponent()->getPackageName()->c_str(), intent->getComponent()->getClassName()->c_str()); if (intent->getBooleanExtra("systemService", false)) { sp<Class<Service>> clazz = Class<Service>::forName(componentName); service = clazz->newInstance(); } else { if (mProcess->mPackageManager == nullptr) { mProcess->mPackageManager = binder::PackageManager::Stub::asInterface(ServiceManager::getSystemService(Context::PACKAGE_MANAGER)); Assert::assertNotNull("System failure", mProcess->mPackageManager); } sp<ResolveInfo> resolveInfo = nullptr; sp<ServiceInfo> serviceInfo = nullptr; try { resolveInfo = mProcess->mPackageManager->resolveService(intent, 0); } catch (const RemoteException& e) { Assert::fail("System failure"); } if (resolveInfo != nullptr && resolveInfo->serviceInfo != nullptr) { serviceInfo = resolveInfo->serviceInfo; if (serviceInfo->isEnabled()) { sp<Class<Service>> clazz = Class<Service>::forName(componentName); service = clazz->newInstance(); } else { Log::e(Process::TAG, "Service not enabled %s", intent->getComponent()->toShortString()->c_str()); } } else { Log::e(Process::TAG, "Unknown service %s", intent->getComponent()->toShortString()->c_str()); } } if (service != nullptr) { service->attach(new ContextImpl(mProcess->mMainThread, intent->getComponent()), binder::Process::Stub::asInterface(this), intent->getComponent()->getClassName()); service->onCreate(); result->putBoolean("result", true); { AutoLock autoLock(mProcess->mLock); mProcess->mServices->put(intent->getComponent(), service); } } else { Log::e(Process::TAG, "Cannot find and instantiate class %s", componentName->c_str()); result->putBoolean("result", false); } callback->sendResult(result); }
void Process::ProcessImpl::startService(const sp<Intent>& intent, int32_t flags, int32_t startId, const sp<IRemoteCallback>& callback) { sp<Service> service; sp<Bundle> result = new Bundle(); { AutoLock autoLock(mProcess->mLock); service = mProcess->mServices->get(intent->getComponent()); } if (service != nullptr) { service->onStartCommand(intent, flags, startId); result->putBoolean("result", true); } else { result->putBoolean("result", false); } callback->sendResult(result); }
void Process::ProcessImpl::bindService(const sp<Intent>& intent, const sp<ServiceConnection>& conn, int32_t flags, const sp<IRemoteCallback>& callback) { sp<Service> service; sp<Bundle> result = new Bundle(); { AutoLock autoLock(mProcess->mLock); service = mProcess->mServices->get(intent->getComponent()); } if (service != nullptr) { sp<IBinder> binder = service->onBind(intent); result->putBoolean("result", true); result->putBinder("binder", binder); } else { result->putBoolean("result", false); } callback->sendResult(result); }
void Process::ProcessImpl::unbindService(const sp<Intent>& intent, const sp<IRemoteCallback>& callback) { sp<Service> service; sp<Bundle> result = new Bundle(); { AutoLock autoLock(mProcess->mLock); service = mProcess->mServices->get(intent->getComponent()); } if (service != nullptr) { service->onUnbind(intent); result->putBoolean("result", true); } else { result->putBoolean("result", false); } if (callback != nullptr) { callback->sendResult(result); } }
void ContextImpl::cleanup() { auto itr = mServiceConnections->iterator(); while (itr.hasNext()) { auto entry = itr.next(); sp<ServiceConnection> conn = entry.getKey(); sp<Intent> service = entry.getValue(); itr.remove(); mServiceManager->unbindService(service, conn); Log::w(TAG, "Service %s is leaking a ServiceConnection to %s", mComponent->toString()->c_str(), service->getComponent()->toString()->c_str()); } }