class DeviceDetector
Constants
- VERSION
Attributes
client_hint[R]
user_agent[R]
Public Class Methods
cache()
click to toggle source
# File lib/device_detector.rb, line 218 def cache @cache ||= MemoryCache.new(config.to_hash) end
config()
click to toggle source
# File lib/device_detector.rb, line 214 def config @config ||= Configuration.new end
configure() { |config| ... }
click to toggle source
# File lib/device_detector.rb, line 222 def configure @config = Configuration.new yield(config) end
new(user_agent, headers = nil)
click to toggle source
# File lib/device_detector.rb, line 23 def initialize(user_agent, headers = nil) @client_hint = ClientHint.new(headers) utf8_user_agent = encode_user_agent_if_needed(user_agent) @user_agent = build_user_agent(utf8_user_agent) end
Public Instance Methods
bot?()
click to toggle source
# File lib/device_detector.rb, line 195 def bot? bot.bot? end
bot_name()
click to toggle source
# File lib/device_detector.rb, line 199 def bot_name bot.name end
build_user_agent(user_agent)
click to toggle source
# File lib/device_detector.rb, line 30 def build_user_agent(user_agent) return user_agent if client_hint.model.nil? regex = build_regex('Android 10[.\d]*; K(?: Build/|[;)])') return user_agent unless user_agent =~ regex version = client_hint.os_version || '10' user_agent.gsub(/(Android 10[.\d]*; K)/, "Android #{version}; #{client_hint.model}") end
device_brand()
click to toggle source
# File lib/device_detector.rb, line 84 def device_brand return if fake_ua? # Assume all devices running iOS / Mac OS are from Apple brand = device.brand brand = 'Apple' if brand.nil? && DeviceDetector::OS::APPLE_OS_NAMES.include?(os_name) brand end
device_name()
click to toggle source
# File lib/device_detector.rb, line 78 def device_name return if fake_ua? device.name || client_hint.model || fix_for_x_music end
device_type()
click to toggle source
# File lib/device_detector.rb, line 94 def device_type t = device.type t = nil if fake_ua? # Chrome on Android passes the device type based on the keyword 'Mobile' # If it is present the device should be a smartphone, otherwise it's a tablet # See https://developer.chrome.com/multidevice/user-agent#chrome_for_android_user_agent # Note: We do not check for browser (family) here, as there might be mobile apps using Chrome, # that won't have a detected browser, but can still be detected. So we check the useragent for # Chrome instead. if t.nil? && os_family == 'Android' && user_agent =~ build_regex('Chrome\/[\.0-9]*') t = user_agent =~ build_regex('(?:Mobile|eliboM)') ? 'smartphone' : 'tablet' end # Some UA contain the fragment 'Pad/APad', so we assume those devices as tablets t = 'tablet' if t == 'smartphone' && user_agent =~ build_regex('Pad\/APad') # Some UA contain the fragment 'Android; Tablet;' or 'Opera Tablet', so we assume those devices # as tablets t = 'tablet' if t.nil? && (android_tablet_fragment? || opera_tablet?) # Some user agents simply contain the fragment 'Android; Mobile;', so we assume those devices # as smartphones t = 'smartphone' if t.nil? && android_mobile_fragment? # Some UA contains the 'Android; Mobile VR;' fragment t = 'wearable' if t.nil? && android_vr_fragment? # Android up to 3.0 was designed for smartphones only. But as 3.0, # which was tablet only, was published too late, there were a # bunch of tablets running with 2.x With 4.0 the two trees were # merged and it is for smartphones and tablets # # So were are expecting that all devices running Android < 2 are # smartphones Devices running Android 3.X are tablets. Device type # of Android 2.X and 4.X+ are unknown if t.nil? && os_name == 'Android' && os.full_version && !os.full_version.empty? full_version = Gem::Version.new(os.full_version) if full_version < VersionExtractor::MAJOR_VERSION_2 t = 'smartphone' elsif full_version >= VersionExtractor::MAJOR_VERSION_3 && \ full_version < VersionExtractor::MAJOR_VERSION_4 t = 'tablet' end end # All detected feature phones running android are more likely a smartphone t = 'smartphone' if t == 'feature phone' && os_family == 'Android' # All unknown devices under running Java ME are more likely a features phones t = 'feature phone' if t.nil? && os_name == 'Java ME' # According to http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx # Internet Explorer 10 introduces the "Touch" UA string token. If this token is present at the # end of the UA string, the computer has touch capability, and is running Windows 8 (or later). # This UA string will be transmitted on a touch-enabled system running Windows 8 (RT) # # As most touch enabled devices are tablets and only a smaller part are desktops/notebooks we # assume that all Windows 8 touch devices are tablets. if t.nil? && touch_enabled? && (os_name == 'Windows RT' || (os_name == 'Windows' && os_full_version && Gem::Version.new(os_full_version) >= VersionExtractor::MAJOR_VERSION_8)) t = 'tablet' end # All devices running Opera TV Store are assumed to be a tv t = 'tv' if opera_tv_store? # All devices that contain Andr0id in string are assumed to be a tv if user_agent =~ build_regex('Andr0id|(?:Android(?: UHD)?|Google) TV|\(lite\) TV|BRAVIA') t = 'tv' end # All devices running Tizen TV or SmartTV are assumed to be a tv t = 'tv' if t.nil? && tizen_samsung_tv? # Devices running those clients are assumed to be a TV t = 'tv' if ['Kylo', 'Espial TV Browser', 'LUJO TV Browser', 'LogicUI TV Browser', 'Open TV Browser', 'Seraphic Sraf', 'Opera Devices', 'Crow Browser', 'Vewd Browser', 'TiviMate', 'Quick Search TV', 'QJY TV Browser', 'TV Bro'].include?(name) # All devices containing TV fragment are assumed to be a tv t = 'tv' if t.nil? && user_agent =~ build_regex('\(TV;') has_desktop = t != 'desktop' && desktop_string? && desktop_fragment? t = 'desktop' if has_desktop # set device type to desktop for all devices running a desktop os that were not detected as # another device type return t if t || !desktop? 'desktop' end
encode_user_agent_if_needed(user_agent)
click to toggle source
# File lib/device_detector.rb, line 41 def encode_user_agent_if_needed(user_agent) return if user_agent.nil? return user_agent if user_agent.encoding.name == 'UTF-8' user_agent.encode('utf-8', 'binary', undef: :replace) end
full_version()
click to toggle source
# File lib/device_detector.rb, line 54 def full_version client_hint.full_version || client.full_version end
known?()
click to toggle source
# File lib/device_detector.rb, line 191 def known? client.known? end
name()
click to toggle source
# File lib/device_detector.rb, line 48 def name return client.name if mobile_fix? client_hint.browser_name || client.name end
os_family()
click to toggle source
# File lib/device_detector.rb, line 58 def os_family return 'GNU/Linux' if linux_fix? client_hint.os_family || os.family || client_hint.platform end
os_full_version()
click to toggle source
# File lib/device_detector.rb, line 70 def os_full_version return if skip_os_version? return os.full_version if pico_os_fix? return fire_os_version if fire_os_fix? client_hint.os_version || os.full_version end
os_name()
click to toggle source
# File lib/device_detector.rb, line 64 def os_name return 'GNU/Linux' if linux_fix? client_hint.os_name || os.name || client_hint.platform end
Private Instance Methods
android_mobile_fragment?()
click to toggle source
# File lib/device_detector.rb, line 293 def android_mobile_fragment? user_agent =~ build_regex('Android( [\.0-9]+)?; Mobile;|.*\-mobile$') end
android_tablet_fragment?()
click to toggle source
# File lib/device_detector.rb, line 289 def android_tablet_fragment? user_agent =~ build_regex('Android( [\.0-9]+)?; Tablet;|Tablet(?! PC)|.*\-tablet$') end
android_vr_fragment?()
click to toggle source
# File lib/device_detector.rb, line 297 def android_vr_fragment? user_agent =~ build_regex('Android( [\.0-9]+)?; Mobile VR;| VR ') end
bot()
click to toggle source
# File lib/device_detector.rb, line 230 def bot @bot ||= Bot.new(user_agent) end
build_regex(src)
click to toggle source
# File lib/device_detector.rb, line 339 def build_regex(src) Regexp.new('(?:^|[^A-Z0-9\_\-])(?:' + src + ')', Regexp::IGNORECASE) end
client()
click to toggle source
# File lib/device_detector.rb, line 234 def client @client ||= Client.new(user_agent) end
desktop?()
click to toggle source
# File lib/device_detector.rb, line 330 def desktop? return false if os_name.nil? || os_name == '' || os_name == 'UNK' # Check for browsers available for mobile devices only return false if uses_mobile_browser? DeviceDetector::OS::DESKTOP_OSS.include?(os_family) end
desktop_fragment?()
click to toggle source
# File lib/device_detector.rb, line 301 def desktop_fragment? user_agent =~ build_regex('Desktop(?: (x(?:32|64)|WOW64))?;') end
desktop_string?()
click to toggle source
This is a workaround until we support detecting mobile only browsers
# File lib/device_detector.rb, line 326 def desktop_string? user_agent =~ /Desktop/ end
device()
click to toggle source
# File lib/device_detector.rb, line 238 def device @device ||= Device.new(user_agent) end
fake_ua?()
click to toggle source
# File lib/device_detector.rb, line 247 def fake_ua? device.brand == 'Apple' && !DeviceDetector::OS::APPLE_OS_NAMES.include?(os_name) end
fire_os_fix?()
click to toggle source
# File lib/device_detector.rb, line 273 def fire_os_fix? !client_hint.platform.nil? && os.name == 'Fire OS' end
fire_os_version()
click to toggle source
# File lib/device_detector.rb, line 277 def fire_os_version DeviceDetector::OS .mapped_os_version(client_hint.os_version, DeviceDetector::OS::FIRE_OS_VERSION_MAPPING) end
fix_for_x_music()
click to toggle source
Related to issue mentionned in device.rb#1562
# File lib/device_detector.rb, line 264 def fix_for_x_music user_agent&.include?('X-music Ⅲ') ? 'X-Music III' : nil end
linux_fix?()
click to toggle source
# File lib/device_detector.rb, line 257 def linux_fix? client_hint.platform == 'Linux' && %w[iOS Android].include?(os.name) && %w[?0 0].include?(client_hint.mobile) end
mobile_fix?()
click to toggle source
github.com/matomo-org/device-detector/blob/be1c9ef486c247dc4886668da5ed0b1c49d90ba8/Parser/Client/Browser.php#L772 Fix mobile browser names e.g. Chrome => Chrome Mobile
# File lib/device_detector.rb, line 253 def mobile_fix? client.name == "#{client_hint.browser_name} Mobile" end
opera_tablet?()
click to toggle source
# File lib/device_detector.rb, line 313 def opera_tablet? user_agent =~ build_regex('Opera Tablet') end
opera_tv_store?()
click to toggle source
# File lib/device_detector.rb, line 309 def opera_tv_store? user_agent =~ build_regex('Opera TV Store|OMI/') end
os()
click to toggle source
# File lib/device_detector.rb, line 242 def os @os ||= OS.new(user_agent) end
pico_os_fix?()
click to toggle source
# File lib/device_detector.rb, line 268 def pico_os_fix? client_hint.os_name == 'Pico OS' end
skip_os_version?()
click to toggle source
# File lib/device_detector.rb, line 283 def skip_os_version? !client_hint.os_family.nil? && client_hint.os_version.nil? && client_hint.os_family != os.family end
tizen_samsung_tv?()
click to toggle source
# File lib/device_detector.rb, line 317 def tizen_samsung_tv? user_agent =~ build_regex('SmartTV|Tizen.+ TV .+$') end
touch_enabled?()
click to toggle source
# File lib/device_detector.rb, line 305 def touch_enabled? user_agent =~ build_regex('Touch') end
uses_mobile_browser?()
click to toggle source
# File lib/device_detector.rb, line 321 def uses_mobile_browser? client.browser? && client.mobile_only_browser? end