// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef DEVICE_NFC_NFC_ADAPTER_H_ #define DEVICE_NFC_NFC_ADAPTER_H_ #include <map> #include <string> #include <vector> #include "base/callback.h" #include "base/memory/ref_counted.h" namespace device { class NfcPeer; class NfcTag; // NfcAdapter represents a local NFC adapter which may be used to interact with // NFC tags and remote NFC adapters on platforms that support NFC. Through // instances of this class, users can obtain important information such as if // and/or when an adapter is present, supported NFC technologies, and the // adapter's power and polling state. NfcAdapter instances can be used to power // up/down the NFC adapter and its Observer interface allows users to get // notified when new adapters are added/removed and when remote NFC tags and // devices were detected or lost. // // A system can contain more than one NFC adapter (e.g. external USB adapters) // but Chrome will have only one NfcAdapter instance. This instance will do // its best to represent all underlying adapters but will only allow // interacting with only one at a given time. If the currently represented // adapter is removed from the system, the NfcAdapter instance will update to // reflect the information from the next available adapter. class NfcAdapter : public base::RefCounted<NfcAdapter> { public: // Interface for observing changes from NFC adapters. class Observer { public: virtual ~Observer() {} // Called when the presence of the adapter |adapter| changes. When |present| // is true, this indicates that the adapter has now become present, while a // value of false indicates that the adapter is no longer available on the // current system. virtual void AdapterPresentChanged(NfcAdapter* adapter, bool present) {} // Called when the radio power state of the adapter |adapter| changes. If // |powered| is true, the adapter radio is turned on, otherwise it's turned // off. virtual void AdapterPoweredChanged(NfcAdapter* adapter, bool powered) {} // Called when the "polling" state of the adapter |adapter| changes. If // |polling| is true, the adapter is currently polling for remote tags and // devices. If false, the adapter isn't polling, either because a poll loop // was never started or because a connection with a tag or peer has been // established. virtual void AdapterPollingChanged(NfcAdapter* adapter, bool polling) {} // Called when an NFC tag |tag| has been found by the adapter |adapter|. // The observer can use this method to take further action on the tag object // |tag|, such as reading its records or writing to it. While |tag| will be // valid within the context of this call, its life-time cannot be guaranteed // once this call returns, as the object may get destroyed if the connection // with the tag is lost. Instead of caching the pointer directly, observers // should store the tag's assigned unique identifier instead, which can be // used to obtain a pointer to the tag, as long as it exists. virtual void TagFound(NfcAdapter* adapter, NfcTag* tag) {} // Called when the NFC tag |tag| is no longer known by the adapter // |adapter|. |tag| should not be cached. virtual void TagLost(NfcAdapter* adapter, NfcTag* tag) {} // Called when a remote NFC adapter |peer| has been detected, which is // available for peer-to-peer communication over NFC. The observer can use // this method to take further action on |peer| such as reading its records // or pushing NDEFs to it. While |peer| will be valid within the context of // this call, its life-time cannot be guaranteed once this call returns, as // the object may get destroyed if the connection with the peer is lost. // Instead of caching the pointer directly, observers should store the // peer's assigned unique identifier instead, which can be used to obtain a // pointer to the peer, as long as it exists. virtual void PeerFound(NfcAdapter* adaper, NfcPeer* peer) {} // Called when the remote NFC adapter |peer| is no longer known by the // adapter |adapter|. |peer| should not be cached. virtual void PeerLost(NfcAdapter* adapter, NfcPeer* peer) {} }; // The ErrorCallback is used by methods to asynchronously report errors. typedef base::Closure ErrorCallback; // Typedefs for lists of NFC peer and NFC tag objects. typedef std::vector<NfcPeer*> PeerList; typedef std::vector<NfcTag*> TagList; // Adds and removes observers for events on this NFC adapter. If monitoring // multiple adapters, check the |adapter| parameter of observer methods to // determine which adapter is issuing the event. virtual void AddObserver(Observer* observer) = 0; virtual void RemoveObserver(Observer* observer) = 0; // Indicates whether an underlying adapter is actually present on the // system. An adapter that was previously present can become no longer // present, for example, if all physical adapters that can back it up were // removed from the system. virtual bool IsPresent() const = 0; // Indicates whether the adapter radio is powered. virtual bool IsPowered() const = 0; // Indicates whether the adapter is polling for remote NFC tags and peers. virtual bool IsPolling() const = 0; // Indicates whether the NfcAdapter instance is initialized and ready to use. virtual bool IsInitialized() const = 0; // Requests a change to the adapter radio power. Setting |powered| to true // will turn on the radio and false will turn it off. On success, |callback| // will be invoked. On failure, |error_callback| will be invoked, which can // happen if the radio power is already in the requested state, or if the // underlying adapter is not present. virtual void SetPowered(bool powered, const base::Closure& callback, const ErrorCallback& error_callback) = 0; // Requests the adapter to begin its poll loop to start looking for remote // NFC tags and peers. On success, |callback| will be invoked. On failure, // |error_callback| will be invoked. This method can fail for various // reasons, including: // - The adapter radio is not powered. // - The adapter is already polling. // - The adapter is busy; it has already established a connection to a // remote tag or peer. // Bear in mind that this method may be called by multiple users of the same // adapter. virtual void StartPolling(const base::Closure& callback, const ErrorCallback& error_callback) = 0; // Requests the adapter to stop its current poll loop. On success, |callback| // will be invoked. On failure, |error_callback| will be invoked. This method // can fail if the adapter is not polling when this method was called. Bear // in mind that this method may be called by multiple users of the same // adapter and polling may not actually stop if other callers have called // StartPolling() in the mean time. virtual void StopPolling(const base::Closure& callback, const ErrorCallback& error_callback) = 0; // Returns a list containing all known peers in |peer_list|. If |peer_list| // was non-empty at the time of the call, it will be cleared. The contents of // |peer_list| at the end of this call are owned by the adapter. virtual void GetPeers(PeerList* peer_list) const; // Returns a list containing all known tags in |tag_list|. If |tag_list| was // non-empty at the time of the call, it will be cleared. The contents of // |tag_list| at the end of this call are owned by the adapter. virtual void GetTags(TagList* tag_list) const; // Returns a pointer to the peer with the given identifier |identifier| or // NULL if no such peer is known. If a non-NULL pointer is returned, the // instance that it points to is owned by this adapter. virtual NfcPeer* GetPeer(const std::string& identifier) const; // Returns a pointer to the tag with the given identifier |identifier| or // NULL if no such tag is known. If a non-NULL pointer is returned, the // instance that it points to is owned by this adapter. virtual NfcTag* GetTag(const std::string& identifier) const; protected: friend class base::RefCounted<NfcAdapter>; // The default constructor does nothing. The destructor deletes all known // NfcPeer and NfcTag instances. NfcAdapter(); virtual ~NfcAdapter(); // Peers and tags that have been found. The key is the unique identifier // assigned to the peer or tag and the value is a pointer to the // corresponding NfcPeer or NfcTag object, whose lifetime is managed by the // adapter instance. typedef std::map<const std::string, NfcPeer*> PeersMap; typedef std::map<const std::string, NfcTag*> TagsMap; // Set the given tag or peer for |identifier|. If a tag or peer for // |identifier| already exists, these methods won't do anything. void SetTag(const std::string& identifier, NfcTag* tag); void SetPeer(const std::string& identifier, NfcPeer* peer); // Removes the tag or peer for |identifier| and returns the removed object. // Returns NULL, if no tag or peer for |identifier| was found. NfcTag* RemoveTag(const std::string& identifier); NfcPeer* RemovePeer(const std::string& identifier); // Clear the peer and tag maps. These methods won't delete the tag and peer // objects, however after the call to these methods, the peers and tags won't // be returned via calls to GetPeers and GetTags. void ClearTags(); void ClearPeers(); private: // Peers and tags that are managed by this adapter. PeersMap peers_; TagsMap tags_; DISALLOW_COPY_AND_ASSIGN(NfcAdapter); }; } // namespace device #endif // DEVICE_NFC_NFC_ADAPTER_H_