Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
appinventor-sources
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
appinventor-sources
Commits
c503528d
Unverified
Commit
c503528d
authored
Jul 01, 2020
by
Shreyash Saitwal
Committed by
GitHub
Jun 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement annotations for Services and Content Providers (#2217)
parent
1843bdd6
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
952 additions
and
12 deletions
+952
-12
appinventor/buildserver/src/com/google/appinventor/buildserver/Compiler.java
...rver/src/com/google/appinventor/buildserver/Compiler.java
+65
-3
appinventor/components/src/com/google/appinventor/components/annotations/UsesContentProviders.java
...inventor/components/annotations/UsesContentProviders.java
+33
-0
appinventor/components/src/com/google/appinventor/components/annotations/UsesServices.java
...ogle/appinventor/components/annotations/UsesServices.java
+33
-0
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/GrantUriPermissionElement.java
...nnotations/androidmanifest/GrantUriPermissionElement.java
+78
-0
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/PathPermissionElement.java
...ts/annotations/androidmanifest/PathPermissionElement.java
+91
-0
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/ProviderElement.java
...mponents/annotations/androidmanifest/ProviderElement.java
+262
-0
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/ServiceElement.java
...omponents/annotations/androidmanifest/ServiceElement.java
+194
-0
appinventor/components/src/com/google/appinventor/components/common/ComponentDescriptorConstants.java
...entor/components/common/ComponentDescriptorConstants.java
+2
-0
appinventor/components/src/com/google/appinventor/components/scripts/ComponentDescriptorGenerator.java
...ntor/components/scripts/ComponentDescriptorGenerator.java
+15
-1
appinventor/components/src/com/google/appinventor/components/scripts/ComponentListGenerator.java
...ppinventor/components/scripts/ComponentListGenerator.java
+11
-3
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
...le/appinventor/components/scripts/ComponentProcessor.java
+168
-5
No files found.
appinventor/buildserver/src/com/google/appinventor/buildserver/Compiler.java
View file @
c503528d
...
...
@@ -170,6 +170,10 @@ public final class Compiler {
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
broadcastReceiversNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
servicesNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
contentProvidersNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
libsNeeded
=
new
ConcurrentHashMap
<
String
,
Set
<
String
>>();
private
final
ConcurrentMap
<
String
,
Set
<
String
>>
nativeLibsNeeded
=
...
...
@@ -420,6 +424,18 @@ public final class Compiler {
return
broadcastReceiversNeeded
;
}
// Just used for testing
@VisibleForTesting
Map
<
String
,
Set
<
String
>>
getServices
()
{
return
servicesNeeded
;
}
// Just used for testing
@VisibleForTesting
Map
<
String
,
Set
<
String
>>
getContentProviders
()
{
return
contentProvidersNeeded
;
}
// Just used for testing
@VisibleForTesting
Map
<
String
,
Set
<
String
>>
getActivities
()
{
...
...
@@ -600,6 +616,46 @@ public final class Compiler {
mergeConditionals
(
conditionals
.
get
(
ComponentDescriptorConstants
.
BROADCAST_RECEIVERS_TARGET
),
broadcastReceiversNeeded
);
}
/*
* Generate a set of conditionally included services needed by this project.
*/
@VisibleForTesting
void
generateServices
()
{
try
{
loadJsonInfo
(
servicesNeeded
,
ComponentDescriptorConstants
.
SERVICES_TARGET
);
}
catch
(
IOException
e
)
{
// This is fatal.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Services"
));
}
catch
(
JSONException
e
)
{
// This is fatal, but shouldn't actually ever happen.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Services"
));
}
mergeConditionals
(
conditionals
.
get
(
ComponentDescriptorConstants
.
SERVICES_TARGET
),
servicesNeeded
);
}
/*
* Generate a set of conditionally included content providers needed by this project.
*/
@VisibleForTesting
void
generateContentProviders
()
{
try
{
loadJsonInfo
(
contentProvidersNeeded
,
ComponentDescriptorConstants
.
CONTENT_PROVIDERS_TARGET
);
}
catch
(
IOException
e
)
{
// This is fatal.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Content Providers"
));
}
catch
(
JSONException
e
)
{
// This is fatal, but shouldn't actually ever happen.
e
.
printStackTrace
();
userErrors
.
print
(
String
.
format
(
ERROR_IN_STAGE
,
"Content Providers"
));
}
mergeConditionals
(
conditionals
.
get
(
ComponentDescriptorConstants
.
CONTENT_PROVIDERS_TARGET
),
contentProvidersNeeded
);
}
/*
* TODO(Will): Remove this method once the deprecated @SimpleBroadcastReceiver
* annotation is removed. This should remain for the time being so
...
...
@@ -1119,10 +1175,13 @@ public final class Compiler {
subelements
.
addAll
(
activitiesNeeded
.
entrySet
());
subelements
.
addAll
(
metadataNeeded
.
entrySet
());
subelements
.
addAll
(
broadcastReceiversNeeded
.
entrySet
());
subelements
.
addAll
(
servicesNeeded
.
entrySet
());
subelements
.
addAll
(
contentProvidersNeeded
.
entrySet
());
// If any component needs to register additional activities or
// broadcast receivers, insert them into the manifest here.
// If any component needs to register additional activities,
// broadcast receivers, services or content providers, insert
// them into the manifest here.
if
(!
subelements
.
isEmpty
())
{
for
(
Map
.
Entry
<
String
,
Set
<
String
>>
componentSubElSetPair
:
subelements
)
{
Set
<
String
>
subelementSet
=
componentSubElSetPair
.
getValue
();
...
...
@@ -1234,6 +1293,8 @@ public final class Compiler {
compiler
.
generateMetadata
();
compiler
.
generateActivityMetadata
();
compiler
.
generateBroadcastReceivers
();
compiler
.
generateServices
();
compiler
.
generateContentProviders
();
compiler
.
generateLibNames
();
compiler
.
generateNativeLibNames
();
compiler
.
generatePermissions
();
...
...
@@ -2514,7 +2575,8 @@ public final class Compiler {
* @param type The name of the type being processed
* @param targetInfo Name of the annotation target being processed (e.g.,
* permissions). Any of: PERMISSIONS_TARGET,
* BROADCAST_RECEIVERS_TARGET
* BROADCAST_RECEIVERS_TARGET, SERVICES_TARGET,
* CONTENT_PROVIDERS_TARGET
*/
private
void
processConditionalInfo
(
JSONObject
compJson
,
String
type
,
String
targetInfo
)
{
// Strip off the package name since SCM and BKY use unqualified names
...
...
appinventor/components/src/com/google/appinventor/components/annotations/UsesContentProviders.java
0 → 100644
View file @
c503528d
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package
com.google.appinventor.components.annotations
;
import
com.google.appinventor.components.annotations.androidmanifest.ProviderElement
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Annotation to indicate any content providers used by
* a component so that corresponding <provider> elements can be
* created in AndroidManifest.xml.
*
* @author https://github.com/ShreyashSaitwal (Shreyash Saitwal)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
TYPE
,
ElementType
.
METHOD
})
public
@interface
UsesContentProviders
{
/**
* An array containing each {@link ProviderElement}
* that is required by the component.
*
* @return the array containing the relevant providers
*/
ProviderElement
[]
providers
();
}
appinventor/components/src/com/google/appinventor/components/annotations/UsesServices.java
0 → 100644
View file @
c503528d
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package
com.google.appinventor.components.annotations
;
import
com.google.appinventor.components.annotations.androidmanifest.ServiceElement
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Annotation to indicate any services used by
* a component so that corresponding <service> elements can be
* created in AndroidManifest.xml.
*
* @author https://github.com/ShreyashSaitwal (Shreyash Saitwal)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
TYPE
,
ElementType
.
METHOD
})
public
@interface
UsesServices
{
/**
* An array containing each {@link ServiceElement}
* that is required by the component.
*
* @return the array containing the relevant services
*/
ServiceElement
[]
services
();
}
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/GrantUriPermissionElement.java
0 → 100644
View file @
c503528d
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package
com.google.appinventor.components.annotations.androidmanifest
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Specifies the subsets of app data that the parent content provider has permission to access.
* Data subsets are indicated by the path part of a content: URI. (The authority part of the URI
* identifies the content provider.) Granting permission is a way of enabling clients of the <provider>
* that don't normally have permission to access its data to overcome that restriction on a one-time
* basis.
*
* If a content provider's grantUriPermissions attribute is "true", permission can be granted for
* any the data under the provider's purview. However, if that attribute is "false", permission can
* be granted only to data subsets that are specified by this element. A provider can contain any
* number of <grant-uri-permission> elements. Each one can specify only one path (only one of the
* three possible attributes).
*
* Note: Most of this documentation is adapted from the Android framework specification
* linked below. That documentation is licensed under the
* {@link <a href="https://creativecommons.org/licenses/by/2.5/">
* Creative Commons Attribution license v2.5
* </a>}.
*
* See {@link <a href="https://developer.android.com/guide/topics/manifest/grant-uri-permission-element">
* https://developer.android.com/guide/topics/manifest/grant-uri-permission-element
* </a>}.
*
* @author https://github.com/ShreyashSaitwal (Shreyash Saitwal)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
GrantUriPermissionElement
{
/**
* A complete URI path for a subset of content provider data. Permission can be granted only
* to the particular data identified by this path. When used to provide search suggestion
* content, it must be appended with "/search_suggest_query".
*
* @return the grant uri permission path attribute
*/
String
path
()
default
""
;
/**
* The initial part of a URI path for a subset of content provider data. Permission can be
* granted to all data subsets with paths that share this initial part.
*
* @return the grant uri permission pathPrefix attribute
*/
String
pathPrefix
()
default
""
;
/**
* A path identifying the data subset or subsets that permission can be granted for. The path
* attribute specifies a complete path; permission can be granted only to the particular data
* subset identified by that path. The pathPrefix attribute specifies the initial part of a path;
* permission can be granted to all data subsets with paths that share that initial part. The
* pathPattern attribute specifies a complete path, but one that can contain the following wildcards:
* - An asterisk ('*') matches a sequence of 0 to many occurrences of the immediately preceding
* character.
* - A period followed by an asterisk (".*") matches any sequence of 0 to many characters.
* Because '\' is used as an escape character when the string is read from XML (before it is parsed
* as a pattern), you will need to double-escape: For example, a literal '*' would be written as "\\*"
* and a literal '\' would be written as "\\\\". This is basically the same as what you would need to
* write if constructing the string in Java code.
*
* @return the grant uri permission pathPattern attribute respectively
*/
String
pathPattern
()
default
""
;
}
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/PathPermissionElement.java
0 → 100644
View file @
c503528d
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package
com.google.appinventor.components.annotations.androidmanifest
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Defines the path and required permissions for a specific subset of data within a
* <provider>. This element can be specified multiple times to supply multiple paths.
*
* Note: Most of this documentation is adapted from the Android framework specification
* linked below. That documentation is licensed under the
* {@link <a href="https://creativecommons.org/licenses/by/2.5/">
* Creative Commons Attribution license v2.5
* </a>}.
*
* See {@link <a href="https://developer.android.com/guide/topics/manifest/path-permission-element">
* https://developer.android.com/guide/topics/manifest/path-permission-element
* </a>}.
*
* @author https://github.com/ShreyashSaitwal (Shreyash Saitwal)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
PathPermissionElement
{
/**
* A complete URI path for a subset of content provider data. Permission can be granted only
* to the particular data identified by this path. When used to provide search suggestion
* content, it must be appended with "/search_suggest_query".
*
* @return the path permission path attribute
*/
String
path
()
default
""
;
/**
* The initial part of a URI path for a subset of content provider data. Permission can be
* granted to all data subsets with paths that share this initial part.
*
* @return the path permission pathPrefix attribute
*/
String
pathPrefix
()
default
""
;
/**
* A complete URI path for a subset of content provider data, but one that can use the following
* wildcards:
* - An asterisk ('*'). This matches a sequence of 0 to many occurrences of the immediately
* preceding character.
* - A period followed by an asterisk (".*"). This matches any sequence of 0 or more characters.
*
* Because '\' is used as an escape character when the string is read from XML (before it is parsed
* as a pattern), you will need to double-escape. For example, a literal '*' would be written as "\\*"
* and a literal '\' would be written as "\\". This is basically the same as what you would need to
* write if constructing the string in Java code.
*
* @return the path permission pathPattern attribute
*/
String
pathPattern
()
default
""
;
/**
* The name of a permission that clients must have in order to read or write the content provider's
* data. This attribute is a convenient way of setting a single permission for both reading and
* writing. However, the {@link #readPermission()} and {@link #writePermission()} attributes take
* precedence over this one.
*
* @return the path permission permission attribute
*/
String
permission
()
default
""
;
/**
* A permission that clients must have in order to query the content provider.
*
* @return the path permission readPermission attribute
*/
String
readPermission
()
default
""
;
/**
* A permission that clients must have in order to make changes to the data controlled by the
* content provider.
*
* @return the path permission writePermission attribute
*/
String
writePermission
()
default
""
;
}
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/ProviderElement.java
0 → 100644
View file @
c503528d
This diff is collapsed.
Click to expand it.
appinventor/components/src/com/google/appinventor/components/annotations/androidmanifest/ServiceElement.java
0 → 100644
View file @
c503528d
// -*- mode: java; c-basic-offset: 2; -*-
// Copyright 2020 MIT, All rights reserved
// Released under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0
package
com.google.appinventor.components.annotations.androidmanifest
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* Annotation to describe a <service> element required by a component so that
* it can be added to AndroidManifest.xml. <service> elements indicate that
* a component is a service. <service> element attributes that are not
* set explicitly default to "" or {} and are ignored when the element is created
* in the manifest.
*
* Note: Most of this documentation is adapted from the Android framework specification
* linked below. That documentation is licensed under the
* {@link <a href="https://creativecommons.org/licenses/by/2.5/">
* Creative Commons Attribution license v2.5
* </a>}.
*
* See {@link <a href="https://developer.android.com/guide/topics/manifest/service-element">
* https://developer.android.com/guide/topics/manifest/service-element
* </a>}.
*
* @author https://github.com/ShreyashSaitwal (Shreyash Saitwal)
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
public
@interface
ServiceElement
{
/**
* An array containing any intent filters used by this <service> element.
*
* @return an array containing the <intent-filter> subelements for this
* <service> element
*/
IntentFilterElement
[]
intentFilters
()
default
{};
/**
* An array containing any meta data used by this <service> element.
*
* @return an array containing the <meta-data> subelements for this
* <service> element
*/
MetaDataElement
[]
metaDataElements
()
default
{};
/**
* The name of the class that implements the service. This should
* be a fully qualified class name (such as, "com.example.project.RoomService").
* However, as a shorthand, if the first character of the name is
* a period (for example, ".RoomService"), it is appended to the
* package name of the application.
*
* @return the Service class name
*/
String
name
();
/**
* If set to true, this service will run under a special process that
* is isolated from the rest of the system and has no permissions
* of its own. The only communication with it is through the Service
* API (binding and starting).
*
* @return the service isolatedProcess attribute
*/
String
isolatedProcess
()
default
""
;
/**
* Specify that the service is a foreground service that satisfies a
* particular use case. For example, a foreground service type of
* "location" indicates that an app is getting the device's current
* location, usually to continue a user-initiated action related to
* device location.
* You can assign multiple foreground service types to a particular service.
*
* @return the service foregroundServiceType attribute
*/
String
foregroundServiceType
()
default
""
;
/**
* A string that describes the service to users. The label should be
* set as a reference to a string resource, so that it can be localized
* like other strings in the user interface.
*
* @return the service desciption attribute
*/
String
description
()
default
""
;
/**
* Whether or not the service is direct-boot aware; that is, whether or
* not it can run before the user unlocks the device.
*
* @return the service directBootAware attribute
*/
String
directBootAware
()
default
""
;
/**
* Whether or not the service can be instantiated by the system — "true"
* if it can be, and "false" if not. The default value is "true".
* The <application> element has its own enabled attribute that applies
* to all application components, including services. The <application>
* and <service> attributes must both be "true" (as they both are by default)
* for the service to be enabled. If either is "false", the service is
* disabled; it cannot be instantiated.
*
* @return the service enabled attribute
*/
String
enabled
()
default
""
;
/**
* Whether or not components of other applications can invoke the service
* or interact with it — "true" if they can, and "false" if not. When the
* value is "false", only components of the same application or applications
* with the same user ID can start the service or bind to it.
*
* The default value depends on whether the service contains intent filters.
* The absence of any filters means that it can be invoked only by specifying
* its exact class name. This implies that the service is intended only for
* application-internal use (since others would not know the class name). So
* in this case, the default value is "false". On the other hand, the presence
* of at least one filter implies that the service is intended for external use,
* so the default value is "true".
* This attribute is not the only way to limit the exposure of a service to other
* applications. You can also use a permission to limit the external entities that
* can interact with the service.
*
* @return the service exported attribute
*/
String
exported
()
default
""
;
/**
* An icon representing the service. This attribute must be set as
* a reference to a drawable resource containing the image definition. If it is
* not set, the icon specified for the application as a whole is used instead.
*
* The service's icon — whether set here or by the <application>
* element — is also the default icon for all the service's intent filters
* (see the {@link IntentFilterElement#icon()} attribute).
*
* @return the service icon attribute
*/
String
icon
()
default
""
;
/**
* A name for the service that can be displayed to users. If this attribute
* is not set, the label set for the application as a whole is used instead.
*
* The service's label — whether set here or by the <application> element —
* is also the default label for all the service's intent filters.
*
* @return the service label attribute
*/
String
label
()
default
""
;
/**
* The name of a permission that an entity must have in order to launch the
* service or bind to it. If a caller of startService(), bindService(), or
* stopService(), has not been granted this permission, the method will not
* work and the Intent object will not be delivered to the service.
*
* If this attribute is not set, the permission set by the <application>
* element's permission attribute applies to the service. If neither attribute
* is set, the service is not protected by a permission.
*
* @return the service permission attribute
*/
String
permission
()
default
""
;
/**
* The name of the process in which the service should run. Normally,
* all components of an application run in the default process created for the
* application. For our purposes, those components are services and
* activities. It has the same name as the application package. Each component
* can override the default with its own process attribute, allowing you to
* spread your application across multiple processes.
*
* If the name assigned to this attribute begins with a colon (':'), a new
* process, private to the application, is created when it's needed and the
* service runs in that process. If the process name begins with
* a lowercase character, the service will run in a global process of that
* name, provided that it has permission to do so. This allows components
* ( services and activities) in different applications to share
* a process, reducing resource usage.
*
* @return the service process attribute
*/
String
process
()
default
""
;
}
appinventor/components/src/com/google/appinventor/components/common/ComponentDescriptorConstants.java
View file @
c503528d
...
...
@@ -26,6 +26,8 @@ public final class ComponentDescriptorConstants {
public
static
final
String
NATIVE_TARGET
=
"native"
;
public
static
final
String
PERMISSIONS_TARGET
=
"permissions"
;
public
static
final
String
BROADCAST_RECEIVERS_TARGET
=
"broadcastReceivers"
;
public
static
final
String
SERVICES_TARGET
=
"services"
;
public
static
final
String
CONTENT_PROVIDERS_TARGET
=
"contentProviders"
;
public
static
final
String
ANDROIDMINSDK_TARGET
=
"androidMinSdk"
;
public
static
final
String
CONDITIONALS_TARGET
=
"conditionals"
;
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentDescriptorGenerator.java
View file @
c503528d
...
...
@@ -213,7 +213,9 @@ public final class ComponentDescriptorGenerator extends ComponentProcessor {
*/
private
void
outputConditionalAnnotations
(
ComponentInfo
component
,
StringBuilder
sb
)
{
if
(
component
.
conditionalPermissions
.
size
()
+
component
.
conditionalBroadcastReceivers
.
size
()
==
0
)
{
component
.
conditionalBroadcastReceivers
.
size
()
+
component
.
conditionalServices
.
size
()
+
component
.
conditionalContentProviders
.
size
()
==
0
)
{
return
;
}
sb
.
append
(
",\n \"conditionals\":{\n "
);
...
...
@@ -229,6 +231,18 @@ public final class ComponentDescriptorGenerator extends ComponentProcessor {
outputMultimap
(
sb
,
" "
,
component
.
conditionalBroadcastReceivers
);
first
=
false
;
}
if
(
component
.
conditionalServices
.
size
()
>
0
)
{
if
(!
first
)
sb
.
append
(
",\n "
);
sb
.
append
(
"\"services\": "
);
outputMultimap
(
sb
,
" "
,
component
.
conditionalServices
);
first
=
false
;
}
if
(
component
.
conditionalContentProviders
.
size
()
>
0
)
{
if
(!
first
)
sb
.
append
(
",\n "
);
sb
.
append
(
"\"contentProviders\": "
);
outputMultimap
(
sb
,
" "
,
component
.
conditionalContentProviders
);
first
=
false
;
}
// Add other annotations here as needed
sb
.
append
(
"\n }"
);
}
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentListGenerator.java
View file @
c503528d
...
...
@@ -18,8 +18,8 @@ import javax.tools.Diagnostic;
import
javax.tools.FileObject
;
/**
* Tool to generate a list of the simple component types, permissions, libraries, activities
*
and Broadcast Receiv
ers (build info) required for each component.
* Tool to generate a list of the simple component types, permissions, libraries, activities
,
*
Broadcast Receivers, Services and Content Provid
ers (build info) required for each component.
*
* @author lizlooney@google.com (Liz Looney)
*/
...
...
@@ -85,6 +85,8 @@ public final class ComponentListGenerator extends ComponentProcessor {
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ACTIVITY_METADATA_TARGET
,
component
.
activityMetadata
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
ANDROIDMINSDK_TARGET
,
Collections
.
singleton
(
Integer
.
toString
(
component
.
getAndroidMinSdk
())));
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
BROADCAST_RECEIVERS_TARGET
,
component
.
broadcastReceivers
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
SERVICES_TARGET
,
component
.
services
);
appendComponentInfo
(
sb
,
ComponentDescriptorConstants
.
CONTENT_PROVIDERS_TARGET
,
component
.
contentProviders
);
appendConditionalComponentInfo
(
component
,
sb
);
// TODO(Will): Remove the following call once the deprecated
// @SimpleBroadcastReceiver annotation is removed. It should
...
...
@@ -103,7 +105,9 @@ public final class ComponentListGenerator extends ComponentProcessor {
*/
private
static
void
appendConditionalComponentInfo
(
ComponentInfo
component
,
StringBuilder
sb
)
{
if
(
component
.
conditionalPermissions
.
size
()
+
component
.
conditionalBroadcastReceivers
.
size
()
==
0
)
{
component
.
conditionalBroadcastReceivers
.
size
()
+
component
.
conditionalServices
.
size
()
+
component
.
conditionalContentProviders
.
size
()
==
0
)
{
return
;
}
sb
.
append
(
", \""
+
ComponentDescriptorConstants
.
CONDITIONALS_TARGET
+
"\": { "
);
...
...
@@ -111,6 +115,10 @@ public final class ComponentListGenerator extends ComponentProcessor {
appendMap
(
sb
,
component
.
conditionalPermissions
);
sb
.
append
(
", \""
+
ComponentDescriptorConstants
.
BROADCAST_RECEIVERS_TARGET
+
"\": "
);
appendMap
(
sb
,
component
.
conditionalBroadcastReceivers
);
sb
.
append
(
", \""
+
ComponentDescriptorConstants
.
SERVICES_TARGET
+
"\": "
);
appendMap
(
sb
,
component
.
conditionalServices
);
sb
.
append
(
", \""
+
ComponentDescriptorConstants
.
CONTENT_PROVIDERS_TARGET
+
"\": "
);
appendMap
(
sb
,
component
.
conditionalContentProviders
);
sb
.
append
(
"}"
);
}
...
...
appinventor/components/src/com/google/appinventor/components/scripts/ComponentProcessor.java
View file @
c503528d
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment