Class: Playwire::Android

Inherits:
Object
  • Object
show all
Defined in:
lib/playwire/android.rb

Constant Summary collapse

PWC =
Playwire::PWC::AndroidManifest

Instance Method Summary collapse

Instance Method Details

#is_playwire_sdk_installed(path, sdk) ⇒ Object



20
21
22
23
24
25
# File 'lib/playwire/android.rb', line 20

def is_playwire_sdk_installed(path, sdk)
    ### Look for Playwire SDK dependencies in the build.gradle
    build_gradle = File.read(path)
    matches = build_gradle.scan(/['"]#{sdk}:.+['"]/)
    return !matches.empty?
end

#load_config_and_set_gam_app_id(publisher_id, app_id, user_manifest_path = nil) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/playwire/android.rb', line 57

def load_config_and_set_gam_app_id(publisher_id, app_id, user_manifest_path=nil)
    ### Iterate over build.gradle files to check if contains Playwire SDK dependency
    gradle_files = seek_for_gradle_files()
    puts gradle_files
    is_total_dependency = gradle_files.filter { |path| is_playwire_sdk_installed(path, PWC::PWC_TOTAL_DEPENDENCY) }.length > 0
    puts "Total #{is_total_dependency}"
    is_coppa_dependency = gradle_files.filter { |path| is_playwire_sdk_installed(path, PWC::PWC_COPPA_DEPENDENCY) }.length > 0
    puts "COPPA #{is_coppa_dependency}"
    ### Return error if Playwire SDK dependency hasn't been found
    if !is_total_dependency && !is_coppa_dependency
        Playwire::Logger.error("No 'Playwire SDK' dependency found in the Podfile.")
        return
    end

    ### Use 'AndroidManifest.xml' provided by a pub or looking for 'AndroidManifest.xml' paths.
    manifest_paths = user_manifest_path.nil? ? seek_for_manifests() : validate_manifest_path_from_user(user_manifest_path)
    return unless manifest_paths

    ### Load config file with metadata provided by a pub or return error if the config file does't exist
    json = Playwire::Network.load_config(publisher_id, app_id)
    if json.nil?
        Playwire::Logger.error("No config file found for the publisher. Check the entered metadata or contact Playwire Account Manager to resolve this issue.")
        return
    end

    ### Extract 'gamAppId' or return error if the 'gamAppId' is omitted
    gam_app_id = json.dig('settings', 'gamAppId')
    if gam_app_id.nil?
        Playwire::Logger.error("No 'gamAppId' found for the publisher. Contact Playwire Account Manager to resolve this issue.")
        return
    end

    manifest_paths.each { |path|
        ### Open and modify the 'AndroidManifest.xml' file
        modify_android_manifest_file(path, gam_app_id, is_total_dependency)
    }

    Playwire::Logger.success("The 'AndroidManifest.xml' has been updated with 'gamAppId' = #{gam_app_id}.")
end

#modify_android_manifest_file(path, gam_app_id, is_total_dependency) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/playwire/android.rb', line 97

def modify_android_manifest_file(path, gam_app_id, is_total_dependency)
    ### Open and parse the 'AndroidManifest.xml' file
    document = parse_manifest_file(path)
    return unless document

    ### Get the namespace and <application> tags
    namespace = document.root.namespace_definitions.find { |namespace| namespace.prefix == PWC::PWC_NAMESPACE_PREFIX }
    application_nodes = document.xpath("//#{PWC::PWC_APPLICATION_ATTRIBUTE}")

    ### Verify that the manifest file contains 'android' namespace and <application> tags
    if namespace.nil? || application_nodes.empty?
        Playwire::Logger.error("Could not verify 'AndroidManifest.xml' in the project directory. Use --manifest option to define the 'AndroidManifest.xml' path manually.")
        return
    end

    ### Update or insert <meta-data> tags
    application_nodes.each { |application|
        (namespace.prefix, application, PWC::PWC_GAD_APP_ID_KEY, gam_app_id)
        (namespace.prefix, application, PWC::PWC_AD_MANAGER_APP_KEY, "true")
        if is_total_dependency
            set_activity_tag(namespace.prefix, application, PWC::PWC_AMAZON_AD_ACTIVITY_KEY)
            set_activity_tag(namespace.prefix, application, PWC::PWC_AMAZON_INTERSTITIAL_ACTIVITY_KEY)
        end
    }

    ### Update or insert <uses-permission> tags
    permissions = [
        PWC::PWC_PERMISSION_INTERNET_KEY,
        PWC::PWC_PERMISSION_NETWORK_STATE_KEY, 
        PWC::PWC_PERMISSION_WIFI_STATE_KEY, 
        PWC::PWC_PERMISSION_VIBRATE_KEY
    ]

    permissions.each { |permission|
        set_permission_tag(document, namespace.prefix, permission)
    }

    ### Save changes to the 'AndroidManifest.xml' file
    begin
        File.write(File.join(path), document.to_xml)            
    rescue
        Playwire::Logger.error("Could not write the 'AndroidManifest.xml' file at path #{path}.")
    end
end

#parse_manifest_file(path) ⇒ Object



142
143
144
145
146
147
148
149
150
# File 'lib/playwire/android.rb', line 142

def parse_manifest_file(path)
    begin
        manifest_file = File.join(path)
        return File.open(manifest_file) { |file| Nokogiri::XML(file) }
    rescue
        Playwire::Logger.error("Could not open and read the 'AndroidManifest.xml' file at path #{path}.")
        return nil
    end
end

#seek_for_gradle_filesObject



15
16
17
18
# File 'lib/playwire/android.rb', line 15

def seek_for_gradle_files
    ### Look for 'AndroidManifest.xml' paths
    return Dir.glob(File.join(Pathname.pwd, '**', '*')).filter { |file| file =~ /.+\/build\.gradle/ }.flatten
end

#seek_for_manifestsObject



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/playwire/android.rb', line 27

def seek_for_manifests
    ### Look for 'AndroidManifest.xml' paths
    manifests = Dir.glob(File.join(Pathname.pwd, '**', '*'))
        .filter { |file| file =~ /.+src.+\/AndroidManifest\.xml/ }.flatten
  
    ### Return error if 'AndroidManifest.xml' files haven't been found
    if manifests.empty?
      Playwire::Logger.error("No 'AndroidManifest.xml' found in the project directory. Use --manifest option to define the 'AndroidManifest.xml' path manually.")
      return nil
    end
    return manifests
end

#set_activity_tag(namespace_prefix, application_tag, key) ⇒ Object

Add Amazon-related activities



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/playwire/android.rb', line 175

def set_activity_tag(namespace_prefix, application_tag, key)
    name_attribute = "#{namespace_prefix}:name"

    ### Search for <activity> tag by name attribute
    activity_path = "//#{PWC::PWC_ACTIVITY_ATTRIBUTE}[@#{name_attribute}=\"#{key}\"]"
    nodes = application_tag.xpath(activity_path)
    
    ### Create a new <activity> tag with name attribute if it doesn't exist
    if nodes.empty?
        activity = Nokogiri::XML::Node.new PWC::PWC_ACTIVITY_ATTRIBUTE, application_tag.document
        activity[name_attribute] = key
        activity.parent = application_tag
        nodes << activity
    end
end

#set_metadata_tag(namespace_prefix, application_tag, key, value) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/playwire/android.rb', line 152

def (namespace_prefix, application_tag, key, value)
    name_attribute = "#{namespace_prefix}:name"
    value_attribute = "#{namespace_prefix}:value"

    ### Search for <meta-data> tag by name attribute
     = "//#{PWC::PWC_META_DATA_ATTRIBUTE}[@#{name_attribute}=\"#{key}\"]"
    nodes = application_tag.xpath()
    
    ### Create a new <meta-data> tag with name attribute if it doesn't exist
    if nodes.empty?
         = Nokogiri::XML::Node.new PWC::PWC_META_DATA_ATTRIBUTE, application_tag.document
        [name_attribute] = key
        .parent = application_tag
        nodes << 
    end

    ### Update the <meta-data> tag with value 
    nodes.each { |node|
        node[value_attribute] = value
    }
end

#set_permission_tag(document, namespace_prefix, key) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/playwire/android.rb', line 191

def set_permission_tag(document, namespace_prefix, key)
    name_attribute = "#{namespace_prefix}:name"

    ### Search for <uses-permission> tag by name attribute
    permission_path = "//#{PWC::PWC_USE_PERMISSION_ATTRIBUTE}[@#{name_attribute}=\"#{key}\"]"
    nodes = document.xpath(permission_path)
    
    ### Create a new <uses-permission> tag with name attribute if it doesn't exist
    if nodes.empty?
        permission = Nokogiri::XML::Node.new PWC::PWC_USE_PERMISSION_ATTRIBUTE, document
        permission[name_attribute] = key
        permission.parent = document.root
        nodes << permission
    end
end

#validate_manifest_path_from_user(manifest_path) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/playwire/android.rb', line 40

def validate_manifest_path_from_user(manifest_path)
    ### Converts any pathname to an absolute pathname.
    path = File.expand_path(manifest_path, __FILE__)
  
    ### Verify that file exists and the path doesn't point to directory. 
    isExist = File.exist?(path)
    isDirectory = File.directory?(path)
  
    ### Return error if the file doesn't meet condition.
    if !isExist || isDirectory
      Playwire::Logger.error("No a '.xml' file found at the path provided by '--manifest'. Check if the '.xml' file exists at the path.")
      return nil
    end
  
    return [path]
end