| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.googlecode.android_scripting.trigger; |
| |
| import com.google.common.collect.Maps; |
| import com.googlecode.android_scripting.facade.FacadeConfiguration; |
| import com.googlecode.android_scripting.facade.FacadeManager; |
| import com.googlecode.android_scripting.rpc.MethodDescriptor; |
| import com.googlecode.android_scripting.trigger.TriggerRepository.TriggerRepositoryObserver; |
| |
| import java.util.Map; |
| |
| import org.json.JSONArray; |
| |
| /** |
| * A {@link TriggerRepositoryObserver} that starts and stops the monitoring of events depending on |
| * whether or not triggers for the event exist. |
| * |
| */ |
| public class EventGenerationControllingObserver implements TriggerRepositoryObserver { |
| private final FacadeManager mFacadeManager; |
| private final Map<String, MethodDescriptor> mStartEventGeneratingMethodDescriptors; |
| private final Map<String, MethodDescriptor> mStopEventGeneratingMethodDescriptors; |
| private final Map<String, Integer> mEventTriggerRefCounts = Maps.newHashMap(); |
| |
| /** |
| * Creates a new StartEventMonitoringObserver for the given trigger repository. |
| * |
| * @param facadeManager |
| * @param triggerRepository |
| */ |
| public EventGenerationControllingObserver(FacadeManager facadeManager) { |
| mFacadeManager = facadeManager; |
| mStartEventGeneratingMethodDescriptors = |
| FacadeConfiguration.collectStartEventMethodDescriptors(); |
| mStopEventGeneratingMethodDescriptors = FacadeConfiguration.collectStopEventMethodDescriptors(); |
| } |
| |
| private synchronized int incrementAndGetRefCount(String eventName) { |
| int refCount = |
| (mEventTriggerRefCounts.containsKey(eventName)) ? mEventTriggerRefCounts.get(eventName) : 0; |
| refCount++; |
| mEventTriggerRefCounts.put(eventName, refCount); |
| return refCount; |
| } |
| |
| private synchronized int decrementAndGetRefCount(String eventName) { |
| int refCount = |
| (mEventTriggerRefCounts.containsKey(eventName)) ? mEventTriggerRefCounts.get(eventName) : 0; |
| refCount--; |
| mEventTriggerRefCounts.put(eventName, refCount); |
| return refCount; |
| } |
| |
| @Override |
| public synchronized void onPut(Trigger trigger) { |
| // If we're not already monitoring the events corresponding to this trigger, do so. |
| if (incrementAndGetRefCount(trigger.getEventName()) == 1) { |
| startMonitoring(trigger.getEventName()); |
| } |
| } |
| |
| @Override |
| public synchronized void onRemove(Trigger trigger) { |
| // If there are no more triggers listening to this event, then we need to stop monitoring. |
| if (decrementAndGetRefCount(trigger.getEventName()) == 1) { |
| stopMonitoring(trigger.getEventName()); |
| } |
| } |
| |
| private void startMonitoring(String eventName) { |
| MethodDescriptor startEventGeneratingMethod = |
| mStartEventGeneratingMethodDescriptors.get(eventName); |
| try { |
| startEventGeneratingMethod.invoke(mFacadeManager, new JSONArray()); |
| } catch (Throwable t) { |
| throw new RuntimeException(t); |
| } |
| } |
| |
| private void stopMonitoring(String eventName) { |
| MethodDescriptor stopEventGeneratingMethod = |
| mStopEventGeneratingMethodDescriptors.get(eventName); |
| try { |
| stopEventGeneratingMethod.invoke(mFacadeManager, new JSONArray()); |
| } catch (Throwable t) { |
| throw new RuntimeException(t); |
| } |
| } |
| } |