mirror of
https://github.com/YTVanced/VancedMicroG
synced 2024-11-27 13:43:00 +00:00
Merge branch 'master' of https://github.com/microg/android_packages_apps_GmsCore
Conflicts: build.gradle play-services-base-core/src/main/java/org/microg/gms/common/ForegroundServiceContext.java play-services-cast/src/main/java/com/google/android/gms/cast/Cast.java play-services-cast/src/main/java/com/google/android/gms/cast/CastRemoteDisplay.java play-services-cast/src/main/java/org/microg/gms/cast/CastApiClientBuilder.java play-services-cast/src/main/java/org/microg/gms/cast/CastClientImpl.java play-services-cast/src/main/java/org/microg/gms/cast/CastRemoteDisplayApiClientBuilder.java play-services-core/build.gradle play-services-core/microg-ui-tools/src/main/res/drawable/self_check.xml play-services-core/src/main/AndroidManifest.xml play-services-core/src/main/java/org/microg/gms/checkin/CheckinManager.java play-services-core/src/main/java/org/microg/gms/checkin/CheckinService.java play-services-core/src/main/java/org/microg/gms/snet/SafetyNetClientServiceImpl.java play-services-core/src/main/java/org/microg/gms/ui/CheckinFragment.java play-services-core/src/main/java/org/microg/gms/ui/GcmAppFragment.java play-services-core/src/main/java/org/microg/gms/ui/GcmFragment.java play-services-core/src/main/java/org/microg/gms/ui/SettingsActivity.java play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendDetailsActivity.java play-services-core/src/main/java/org/microg/gms/ui/UnifiedBackendListActivity.java play-services-core/src/main/res/drawable/dots_horizontal.xml play-services-core/src/main/res/drawable/ic_certificate.xml play-services-core/src/main/res/values/strings.xml play-services-core/src/main/res/xml/preferences_safetynet.xml play-services-core/src/main/res/xml/preferences_start.xml play-services-gcm/build.gradle play-services-gcm/src/main/java/com/google/android/gms/gcm/GcmReceiver.java play-services-iid/build.gradle play-services-iid/src/main/java/com/google/android/gms/iid/InstanceIDListenerService.java play-services-location-api/build.gradle play-services-location/build.gradle play-services-location/src/main/java/com/google/android/gms/location/ActivityRecognition.java play-services-location/src/main/java/com/google/android/gms/location/FusedLocationProviderApi.java play-services-location/src/main/java/com/google/android/gms/location/GeofencingApi.java play-services-location/src/main/java/com/google/android/gms/location/LocationServices.java play-services-location/src/main/java/com/google/android/gms/location/SettingsApi.java play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionApiClientBuilder.java play-services-location/src/main/java/org/microg/gms/location/ActivityRecognitionClientImpl.java play-services-location/src/main/java/org/microg/gms/location/FusedLocationProviderApiImpl.java play-services-location/src/main/java/org/microg/gms/location/GeofencingApiImpl.java play-services-location/src/main/java/org/microg/gms/location/GoogleLocationManagerClient.java play-services-location/src/main/java/org/microg/gms/location/LocationClientImpl.java play-services-location/src/main/java/org/microg/gms/location/LocationServicesApiClientBuilder.java play-services-wearable-api/build.gradle play-services-wearable/src/main/java/com/google/android/gms/wearable/Wearable.java play-services-wearable/src/main/java/org/microg/gms/wearable/WearableApiClientBuilder.java play-services-wearable/src/main/java/org/microg/gms/wearable/WearableClientImpl.java settings.gradle
This commit is contained in:
commit
a15efbb4c0
161 changed files with 5297 additions and 574 deletions
208
LICENSES/Apache-2.0.txt
Normal file
208
LICENSES/Apache-2.0.txt
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
Apache License
|
||||||
|
|
||||||
|
Version 2.0, January 2004
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
|
||||||
|
AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction, and distribution
|
||||||
|
as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||||
|
owner that is granting the License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||||
|
that control, are controlled by, or are under common control with that entity.
|
||||||
|
For the purposes of this definition, "control" means (i) the power, direct
|
||||||
|
or indirect, to cause the direction or management of such entity, whether
|
||||||
|
by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
|
||||||
|
of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
|
||||||
|
granted by this License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications, including
|
||||||
|
but not limited to software source code, documentation source, and configuration
|
||||||
|
files.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical transformation
|
||||||
|
or translation of a Source form, including but not limited to compiled object
|
||||||
|
code, generated documentation, and conversions to other media types.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or Object form,
|
||||||
|
made available under the License, as indicated by a copyright notice that
|
||||||
|
is included in or attached to the work (an example is provided in the Appendix
|
||||||
|
below).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object form,
|
||||||
|
that is based on (or derived from) the Work and for which the editorial revisions,
|
||||||
|
annotations, elaborations, or other modifications represent, as a whole, an
|
||||||
|
original work of authorship. For the purposes of this License, Derivative
|
||||||
|
Works shall not include works that remain separable from, or merely link (or
|
||||||
|
bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including the original version
|
||||||
|
of the Work and any modifications or additions to that Work or Derivative
|
||||||
|
Works thereof, that is intentionally submitted to Licensor for inclusion in
|
||||||
|
the Work by the copyright owner or by an individual or Legal Entity authorized
|
||||||
|
to submit on behalf of the copyright owner. For the purposes of this definition,
|
||||||
|
"submitted" means any form of electronic, verbal, or written communication
|
||||||
|
sent to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems, and
|
||||||
|
issue tracking systems that are managed by, or on behalf of, the Licensor
|
||||||
|
for the purpose of discussing and improving the Work, but excluding communication
|
||||||
|
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||||
|
owner as "Not a Contribution."
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||||
|
of whom a Contribution has been received by Licensor and subsequently incorporated
|
||||||
|
within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of this
|
||||||
|
License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
|
||||||
|
Derivative Works of, publicly display, publicly perform, sublicense, and distribute
|
||||||
|
the Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of this License,
|
||||||
|
each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||||
|
no-charge, royalty-free, irrevocable (except as stated in this section) patent
|
||||||
|
license to make, have made, use, offer to sell, sell, import, and otherwise
|
||||||
|
transfer the Work, where such license applies only to those patent claims
|
||||||
|
licensable by such Contributor that are necessarily infringed by their Contribution(s)
|
||||||
|
alone or by combination of their Contribution(s) with the Work to which such
|
||||||
|
Contribution(s) was submitted. If You institute patent litigation against
|
||||||
|
any entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||||
|
that the Work or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses granted to You
|
||||||
|
under this License for that Work shall terminate as of the date such litigation
|
||||||
|
is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the Work or
|
||||||
|
Derivative Works thereof in any medium, with or without modifications, and
|
||||||
|
in Source or Object form, provided that You meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or Derivative Works a copy
|
||||||
|
of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices stating that
|
||||||
|
You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works that You distribute,
|
||||||
|
all copyright, patent, trademark, and attribution notices from the Source
|
||||||
|
form of the Work, excluding those notices that do not pertain to any part
|
||||||
|
of the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its distribution,
|
||||||
|
then any Derivative Works that You distribute must include a readable copy
|
||||||
|
of the attribution notices contained within such NOTICE file, excluding those
|
||||||
|
notices that do not pertain to any part of the Derivative Works, in at least
|
||||||
|
one of the following places: within a NOTICE text file distributed as part
|
||||||
|
of the Derivative Works; within the Source form or documentation, if provided
|
||||||
|
along with the Derivative Works; or, within a display generated by the Derivative
|
||||||
|
Works, if and wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and do not modify the
|
||||||
|
License. You may add Your own attribution notices within Derivative Works
|
||||||
|
that You distribute, alongside or as an addendum to the NOTICE text from the
|
||||||
|
Work, provided that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and may provide
|
||||||
|
additional or different license terms and conditions for use, reproduction,
|
||||||
|
or distribution of Your modifications, or for any such Derivative Works as
|
||||||
|
a whole, provided Your use, reproduction, and distribution of the Work otherwise
|
||||||
|
complies with the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise, any
|
||||||
|
Contribution intentionally submitted for inclusion in the Work by You to the
|
||||||
|
Licensor shall be under the terms and conditions of this License, without
|
||||||
|
any additional terms or conditions. Notwithstanding the above, nothing herein
|
||||||
|
shall supersede or modify the terms of any separate license agreement you
|
||||||
|
may have executed with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade names,
|
||||||
|
trademarks, service marks, or product names of the Licensor, except as required
|
||||||
|
for reasonable and customary use in describing the origin of the Work and
|
||||||
|
reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or agreed to
|
||||||
|
in writing, Licensor provides the Work (and each Contributor provides its
|
||||||
|
Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied, including, without limitation, any warranties
|
||||||
|
or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
|
||||||
|
of using or redistributing the Work and assume any risks associated with Your
|
||||||
|
exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory, whether
|
||||||
|
in tort (including negligence), contract, or otherwise, unless required by
|
||||||
|
applicable law (such as deliberate and grossly negligent acts) or agreed to
|
||||||
|
in writing, shall any Contributor be liable to You for damages, including
|
||||||
|
any direct, indirect, special, incidental, or consequential damages of any
|
||||||
|
character arising as a result of this License or out of the use or inability
|
||||||
|
to use the Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all other commercial
|
||||||
|
damages or losses), even if such Contributor has been advised of the possibility
|
||||||
|
of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing the Work
|
||||||
|
or Derivative Works thereof, You may choose to offer, and charge a fee for,
|
||||||
|
acceptance of support, warranty, indemnity, or other liability obligations
|
||||||
|
and/or rights consistent with this License. However, in accepting such obligations,
|
||||||
|
You may act only on Your own behalf and on Your sole responsibility, not on
|
||||||
|
behalf of any other Contributor, and only if You agree to indemnify, defend,
|
||||||
|
and hold each Contributor harmless for any liability incurred by, or claims
|
||||||
|
asserted against, such Contributor by reason of your accepting any such warranty
|
||||||
|
or additional liability. END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following boilerplate
|
||||||
|
notice, with the fields enclosed by brackets "[]" replaced with your own identifying
|
||||||
|
information. (Don't include the brackets!) The text should be enclosed in
|
||||||
|
the appropriate comment syntax for the file format. We also recommend that
|
||||||
|
a file or class name and description of purpose be included on the same "printed
|
||||||
|
page" as the copyright notice for easier identification within third-party
|
||||||
|
archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
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.
|
324
LICENSES/CC-BY-4.0.txt
Normal file
324
LICENSES/CC-BY-4.0.txt
Normal file
|
@ -0,0 +1,324 @@
|
||||||
|
Creative Commons Attribution 4.0 International Creative Commons Corporation
|
||||||
|
("Creative Commons") is not a law firm and does not provide legal services
|
||||||
|
or legal advice. Distribution of Creative Commons public licenses does not
|
||||||
|
create a lawyer-client or other relationship. Creative Commons makes its licenses
|
||||||
|
and related information available on an "as-is" basis. Creative Commons gives
|
||||||
|
no warranties regarding its licenses, any material licensed under their terms
|
||||||
|
and conditions, or any related information. Creative Commons disclaims all
|
||||||
|
liability for damages resulting from their use to the fullest extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and conditions
|
||||||
|
that creators and other rights holders may use to share original works of
|
||||||
|
authorship and other material subject to copyright and certain other rights
|
||||||
|
specified in the public license below. The following considerations are for
|
||||||
|
informational purposes only, are not exhaustive, and do not form part of our
|
||||||
|
licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are intended for use by
|
||||||
|
those authorized to give the public permission to use material in ways otherwise
|
||||||
|
restricted by copyright and certain other rights. Our licenses are irrevocable.
|
||||||
|
Licensors should read and understand the terms and conditions of the license
|
||||||
|
they choose before applying it. Licensors should also secure all rights necessary
|
||||||
|
before applying our licenses so that the public can reuse the material as
|
||||||
|
expected. Licensors should clearly mark any material not subject to the license.
|
||||||
|
This includes other CC-licensed material, or material used under an exception
|
||||||
|
or limitation to copyright. More considerations for licensors : wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public licenses, a licensor
|
||||||
|
grants the public permission to use the licensed material under specified
|
||||||
|
terms and conditions. If the licensor's permission is not necessary for any
|
||||||
|
reason–for example, because of any applicable exception or limitation to copyright–then
|
||||||
|
that use is not regulated by the license. Our licenses grant only permissions
|
||||||
|
under copyright and certain other rights that a licensor has authority to
|
||||||
|
grant. Use of the licensed material may still be restricted for other reasons,
|
||||||
|
including because others have copyright or other rights in the material. A
|
||||||
|
licensor may make special requests, such as asking that all changes be marked
|
||||||
|
or described. Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More considerations for the public
|
||||||
|
: wiki.creativecommons.org/Considerations_for_licensees Creative Commons Attribution
|
||||||
|
4.0 International Public License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree to
|
||||||
|
be bound by the terms and conditions of this Creative Commons Attribution
|
||||||
|
4.0 International Public License ("Public License"). To the extent this Public
|
||||||
|
License may be interpreted as a contract, You are granted the Licensed Rights
|
||||||
|
in consideration of Your acceptance of these terms and conditions, and the
|
||||||
|
Licensor grants You such rights in consideration of benefits the Licensor
|
||||||
|
receives from making the Licensed Material available under these terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
Section 1 – Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar Rights
|
||||||
|
that is derived from or based upon the Licensed Material and in which the
|
||||||
|
Licensed Material is translated, altered, arranged, transformed, or otherwise
|
||||||
|
modified in a manner requiring permission under the Copyright and Similar
|
||||||
|
Rights held by the Licensor. For purposes of this Public License, where the
|
||||||
|
Licensed Material is a musical work, performance, or sound recording, Adapted
|
||||||
|
Material is always produced where the Licensed Material is synched in timed
|
||||||
|
relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright and Similar
|
||||||
|
Rights in Your contributions to Adapted Material in accordance with the terms
|
||||||
|
and conditions of this Public License.
|
||||||
|
|
||||||
|
c. Copyright and Similar Rights means copyright and/or similar rights closely
|
||||||
|
related to copyright including, without limitation, performance, broadcast,
|
||||||
|
sound recording, and Sui Generis Database Rights, without regard to how the
|
||||||
|
rights are labeled or categorized. For purposes of this Public License, the
|
||||||
|
rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
|
||||||
|
|
||||||
|
d. Effective Technological Measures means those measures that, in the absence
|
||||||
|
of proper authority, may not be circumvented under laws fulfilling obligations
|
||||||
|
under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996,
|
||||||
|
and/or similar international agreements.
|
||||||
|
|
||||||
|
e. Exceptions and Limitations means fair use, fair dealing, and/or any other
|
||||||
|
exception or limitation to Copyright and Similar Rights that applies to Your
|
||||||
|
use of the Licensed Material.
|
||||||
|
|
||||||
|
f. Licensed Material means the artistic or literary work, database, or other
|
||||||
|
material to which the Licensor applied this Public License.
|
||||||
|
|
||||||
|
g. Licensed Rights means the rights granted to You subject to the terms and
|
||||||
|
conditions of this Public License, which are limited to all Copyright and
|
||||||
|
Similar Rights that apply to Your use of the Licensed Material and that the
|
||||||
|
Licensor has authority to license.
|
||||||
|
|
||||||
|
h. Licensor means the individual(s) or entity(ies) granting rights under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
i. Share means to provide material to the public by any means or process that
|
||||||
|
requires permission under the Licensed Rights, such as reproduction, public
|
||||||
|
display, public performance, distribution, dissemination, communication, or
|
||||||
|
importation, and to make material available to the public including in ways
|
||||||
|
that members of the public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
j. Sui Generis Database Rights means rights other than copyright resulting
|
||||||
|
from Directive 96/9/EC of the European Parliament and of the Council of 11
|
||||||
|
March 1996 on the legal protection of databases, as amended and/or succeeded,
|
||||||
|
as well as other essentially equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
k. You means the individual or entity exercising the Licensed Rights under
|
||||||
|
this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
Section 2 – Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License, the Licensor
|
||||||
|
hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive,
|
||||||
|
irrevocable license to exercise the Licensed Rights in the Licensed Material
|
||||||
|
to:
|
||||||
|
|
||||||
|
A. reproduce and Share the Licensed Material, in whole or in part; and
|
||||||
|
|
||||||
|
B. produce, reproduce, and Share Adapted Material.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions
|
||||||
|
and Limitations apply to Your use, this Public License does not apply, and
|
||||||
|
You do not need to comply with its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section 6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The Licensor authorizes
|
||||||
|
You to exercise the Licensed Rights in all media and formats whether now known
|
||||||
|
or hereafter created, and to make technical modifications necessary to do
|
||||||
|
so. The Licensor waives and/or agrees not to assert any right or authority
|
||||||
|
to forbid You from making technical modifications necessary to exercise the
|
||||||
|
Licensed Rights, including technical modifications necessary to circumvent
|
||||||
|
Effective Technological Measures. For purposes of this Public License, simply
|
||||||
|
making modifications authorized by this Section 2(a)(4) never produces Adapted
|
||||||
|
Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed
|
||||||
|
Material automatically receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
B. No downstream restrictions. You may not offer or impose any additional
|
||||||
|
or different terms or conditions on, or apply any Effective Technological
|
||||||
|
Measures to, the Licensed Material if doing so restricts exercise of the Licensed
|
||||||
|
Rights by any recipient of the Licensed Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or may be construed
|
||||||
|
as permission to assert or imply that You are, or that Your use of the Licensed
|
||||||
|
Material is, connected with, or sponsored, endorsed, or granted official status
|
||||||
|
by, the Licensor or others designated to receive attribution as provided in
|
||||||
|
Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not licensed under this
|
||||||
|
Public License, nor are publicity, privacy, and/or other similar personality
|
||||||
|
rights; however, to the extent possible, the Licensor waives and/or agrees
|
||||||
|
not to assert any such rights held by the Licensor to the limited extent necessary
|
||||||
|
to allow You to exercise the Licensed Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to collect royalties
|
||||||
|
from You for the exercise of the Licensed Rights, whether directly or through
|
||||||
|
a collecting society under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly reserves any right
|
||||||
|
to collect such royalties.
|
||||||
|
|
||||||
|
Section 3 – License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the following
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified form), You must:
|
||||||
|
|
||||||
|
A. retain the following if it is supplied by the Licensor with the Licensed
|
||||||
|
Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed Material and any others
|
||||||
|
designated to receive attribution, in any reasonable manner requested by the
|
||||||
|
Licensor (including by pseudonym if designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
|
||||||
|
|
||||||
|
B. indicate if You modified the Licensed Material and retain an indication
|
||||||
|
of any previous modifications; and
|
||||||
|
|
||||||
|
C. indicate the Licensed Material is licensed under this Public License, and
|
||||||
|
include the text of, or the URI or hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner
|
||||||
|
based on the medium, means, and context in which You Share the Licensed Material.
|
||||||
|
For example, it may be reasonable to satisfy the conditions by providing a
|
||||||
|
URI or hyperlink to a resource that includes the required information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the information required
|
||||||
|
by Section 3(a)(1)(A) to the extent reasonably practicable.
|
||||||
|
|
||||||
|
4. If You Share Adapted Material You produce, the Adapter's License You apply
|
||||||
|
must not prevent recipients of the Adapted Material from complying with this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
Section 4 – Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that apply to
|
||||||
|
Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract,
|
||||||
|
reuse, reproduce, and Share all or a substantial portion of the contents of
|
||||||
|
the database;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database contents in
|
||||||
|
a database in which You have Sui Generis Database Rights, then the database
|
||||||
|
in which You have Sui Generis Database Rights (but not its individual contents)
|
||||||
|
is Adapted Material; and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share all or
|
||||||
|
a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not replace
|
||||||
|
Your obligations under this Public License where the Licensed Rights include
|
||||||
|
other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. Unless otherwise separately undertaken by the Licensor, to the extent possible,
|
||||||
|
the Licensor offers the Licensed Material as-is and as-available, and makes
|
||||||
|
no representations or warranties of any kind concerning the Licensed Material,
|
||||||
|
whether express, implied, statutory, or other. This includes, without limitation,
|
||||||
|
warranties of title, merchantability, fitness for a particular purpose, non-infringement,
|
||||||
|
absence of latent or other defects, accuracy, or the presence or absence of
|
||||||
|
errors, whether or not known or discoverable. Where disclaimers of warranties
|
||||||
|
are not allowed in full or in part, this disclaimer may not apply to You.
|
||||||
|
|
||||||
|
b. To the extent possible, in no event will the Licensor be liable to You
|
||||||
|
on any legal theory (including, without limitation, negligence) or otherwise
|
||||||
|
for any direct, special, indirect, incidental, consequential, punitive, exemplary,
|
||||||
|
or other losses, costs, expenses, or damages arising out of this Public License
|
||||||
|
or use of the Licensed Material, even if the Licensor has been advised of
|
||||||
|
the possibility of such losses, costs, expenses, or damages. Where a limitation
|
||||||
|
of liability is not allowed in full or in part, this limitation may not apply
|
||||||
|
to You.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided above
|
||||||
|
shall be interpreted in a manner that, to the extent possible, most closely
|
||||||
|
approximates an absolute disclaimer and waiver of all liability.
|
||||||
|
|
||||||
|
Section 6 – Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and Similar Rights
|
||||||
|
licensed here. However, if You fail to comply with this Public License, then
|
||||||
|
Your rights under this Public License terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under Section
|
||||||
|
6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided it is cured
|
||||||
|
within 30 days of Your discovery of the violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, this Section 6(b) does not affect any right
|
||||||
|
the Licensor may have to seek remedies for Your violations of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
d. For the avoidance of doubt, the Licensor may also offer the Licensed Material
|
||||||
|
under separate terms or conditions or stop distributing the Licensed Material
|
||||||
|
at any time; however, doing so will not terminate this Public License.
|
||||||
|
|
||||||
|
e. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
||||||
|
|
||||||
|
Section 7 – Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different terms or
|
||||||
|
conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the Licensed
|
||||||
|
Material not stated herein are separate from and independent of the terms
|
||||||
|
and conditions of this Public License.
|
||||||
|
|
||||||
|
Section 8 – Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and shall not
|
||||||
|
be interpreted to, reduce, limit, restrict, or impose conditions on any use
|
||||||
|
of the Licensed Material that could lawfully be made without permission under
|
||||||
|
this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is deemed
|
||||||
|
unenforceable, it shall be automatically reformed to the minimum extent necessary
|
||||||
|
to make it enforceable. If the provision cannot be reformed, it shall be severed
|
||||||
|
from this Public License without affecting the enforceability of the remaining
|
||||||
|
terms and conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no failure
|
||||||
|
to comply consented to unless expressly agreed to by the Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted as a limitation
|
||||||
|
upon, or waiver of, any privileges and immunities that apply to the Licensor
|
||||||
|
or You, including from the legal processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public licenses. Notwithstanding, Creative
|
||||||
|
Commons may elect to apply one of its public licenses to material it publishes
|
||||||
|
and in those instances will be considered the "Licensor." The text of the
|
||||||
|
Creative Commons public licenses is dedicated to the public domain under the
|
||||||
|
CC0 Public Domain Dedication. Except for the limited purpose of indicating
|
||||||
|
that material is shared under a Creative Commons public license or as otherwise
|
||||||
|
permitted by the Creative Commons policies published at creativecommons.org/policies,
|
||||||
|
Creative Commons does not authorize the use of the trademark "Creative Commons"
|
||||||
|
or any other trademark or logo of Creative Commons without its prior written
|
||||||
|
consent including, without limitation, in connection with any unauthorized
|
||||||
|
modifications to any of its public licenses or any other arrangements, understandings,
|
||||||
|
or agreements concerning use of licensed material. For the avoidance of doubt,
|
||||||
|
this paragraph does not form part of the public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
49
firebase-dynamic-links-api/build.gradle
Normal file
49
firebase-dynamic-links-api/build.gradle
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
String getMyVersionName() {
|
||||||
|
def stdout = new ByteArrayOutputStream()
|
||||||
|
if (rootProject.file("gradlew").exists())
|
||||||
|
exec { commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout }
|
||||||
|
else // automatic build system, don't tag dirty
|
||||||
|
exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout }
|
||||||
|
return stdout.toString().trim().substring(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
group = 'org.microg'
|
||||||
|
version = getMyVersionName()
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion androidCompileSdk()
|
||||||
|
buildToolsVersion "$androidBuildVersionTools"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
versionName getMyVersionName()
|
||||||
|
minSdkVersion androidMinSdk()
|
||||||
|
targetSdkVersion androidTargetSdk()
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api project(':play-services-basement')
|
||||||
|
}
|
34
firebase-dynamic-links-api/gradle.properties
Normal file
34
firebase-dynamic-links-api/gradle.properties
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#
|
||||||
|
# Copyright 2019 e Foundation
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
POM_NAME=Firebase Dynamic Links API
|
||||||
|
POM_DESCRIPTION=Interfaces and objects for IPC between Firebase Library and microG
|
||||||
|
|
||||||
|
POM_PACKAGING=aar
|
||||||
|
|
||||||
|
POM_URL=https://github.com/microg/android_external_GmsApi
|
||||||
|
|
||||||
|
POM_SCM_URL=https://github.com/microg/android_external_GmsApi
|
||||||
|
POM_SCM_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git
|
||||||
|
POM_SCM_DEV_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git
|
||||||
|
|
||||||
|
POM_LICENCE_NAME=The Apache Software License, Version 2.0
|
||||||
|
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
POM_LICENCE_DIST=repo
|
||||||
|
|
||||||
|
POM_DEVELOPER_ID=alexandruchircu
|
||||||
|
POM_DEVELOPER_NAME=Alexandru Chircu
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!--
|
<!--
|
||||||
~ Copyright (C) 2017 microG Project Team
|
~ Copyright (C) 2019 e Foundation
|
||||||
~
|
~
|
||||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
~ you may not use this file except in compliance with the License.
|
~ you may not use this file except in compliance with the License.
|
||||||
|
@ -15,8 +15,4 @@
|
||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest package="org.microg.gms.firebase.dynamiclinks.api"/>
|
||||||
<Preference
|
|
||||||
android:selectable="false"
|
|
||||||
android:summary="@string/pref_checkin_enable_summary"/>
|
|
||||||
</PreferenceScreen>
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package com.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
parcelable DynamicLinkData;
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.firebase.dynamiclinks.internal.DynamicLinkData;
|
||||||
|
import com.google.firebase.dynamiclinks.internal.ShortDynamicLink;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
|
||||||
|
interface IDynamicLinksCallbacks {
|
||||||
|
void onStatusDynamicLinkData(in Status status, in DynamicLinkData dldata) = 0;
|
||||||
|
void onStatusShortDynamicLink(in Status status, in ShortDynamicLink sdlink) = 1;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.firebase.dynamiclinks.internal.IDynamicLinksCallbacks;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
|
||||||
|
interface IDynamicLinksService {
|
||||||
|
void getInitialLink(IDynamicLinksCallbacks callback, String var2) = 0;
|
||||||
|
void func2(IDynamicLinksCallbacks callback, in Bundle var2) = 1;
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
package com.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
parcelable ShortDynamicLink;
|
|
@ -0,0 +1,3 @@
|
||||||
|
package com.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
parcelable Warning;
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
|
||||||
|
import org.microg.safeparcel.AutoSafeParcelable;
|
||||||
|
import org.microg.safeparcel.SafeParceled;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
|
||||||
|
public class DynamicLinkData extends AutoSafeParcelable {
|
||||||
|
@SafeParceled(1)
|
||||||
|
public final String dynamicLink;
|
||||||
|
|
||||||
|
@SafeParceled(2)
|
||||||
|
public final String deepLink;
|
||||||
|
|
||||||
|
@SafeParceled(3)
|
||||||
|
public final int minVersion;
|
||||||
|
|
||||||
|
@SafeParceled(4)
|
||||||
|
public final long clickTimestamp;
|
||||||
|
|
||||||
|
@SafeParceled(5)
|
||||||
|
public final Bundle extensionBundle;
|
||||||
|
|
||||||
|
@SafeParceled(6)
|
||||||
|
public final Uri redirectUrl;
|
||||||
|
|
||||||
|
public DynamicLinkData() {
|
||||||
|
dynamicLink = new String();
|
||||||
|
deepLink = new String();
|
||||||
|
minVersion = 0;
|
||||||
|
clickTimestamp = 0;
|
||||||
|
extensionBundle = new Bundle();
|
||||||
|
redirectUrl = Uri.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final Creator<DynamicLinkData> CREATOR = new AutoCreator<DynamicLinkData>(DynamicLinkData.class);
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.firebase.dynamiclinks.internal.Warning;
|
||||||
|
|
||||||
|
import org.microg.safeparcel.AutoSafeParcelable;
|
||||||
|
import org.microg.safeparcel.SafeParceled;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
|
public class ShortDynamicLink extends AutoSafeParcelable {
|
||||||
|
@SafeParceled(1)
|
||||||
|
public final Uri shortLink;
|
||||||
|
|
||||||
|
@SafeParceled(2)
|
||||||
|
public final Uri previewLink;
|
||||||
|
|
||||||
|
@SafeParceled(3)
|
||||||
|
public final List<Warning> warnings;
|
||||||
|
|
||||||
|
|
||||||
|
public ShortDynamicLink() {
|
||||||
|
shortLink = Uri.EMPTY;
|
||||||
|
previewLink = Uri.EMPTY;
|
||||||
|
|
||||||
|
warnings = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final Creator<ShortDynamicLink> CREATOR = new AutoCreator<ShortDynamicLink>(ShortDynamicLink.class);
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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.google.firebase.dynamiclinks.internal;
|
||||||
|
|
||||||
|
|
||||||
|
import org.microg.safeparcel.AutoSafeParcelable;
|
||||||
|
import org.microg.safeparcel.SafeParceled;
|
||||||
|
|
||||||
|
|
||||||
|
public class Warning extends AutoSafeParcelable {
|
||||||
|
@SafeParceled(1)
|
||||||
|
private int versionCode = 1;
|
||||||
|
|
||||||
|
@SafeParceled(2)
|
||||||
|
public final String message;
|
||||||
|
|
||||||
|
|
||||||
|
public Warning() {
|
||||||
|
message = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static final Creator<Warning> CREATOR = new AutoCreator<Warning>(Warning.class);
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':play-services-basement')
|
api project(':play-services-basement')
|
||||||
|
api project(':play-services-appinvite-api')
|
||||||
api project(':play-services-cast-api')
|
api project(':play-services-cast-api')
|
||||||
api project(':play-services-cast-framework-api')
|
api project(':play-services-cast-framework-api')
|
||||||
api project(':play-services-iid-api')
|
api project(':play-services-iid-api')
|
||||||
|
|
49
play-services-appinvite-api/build.gradle
Normal file
49
play-services-appinvite-api/build.gradle
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
String getMyVersionName() {
|
||||||
|
def stdout = new ByteArrayOutputStream()
|
||||||
|
if (rootProject.file("gradlew").exists())
|
||||||
|
exec { commandLine 'git', 'describe', '--tags', '--always', '--dirty'; standardOutput = stdout }
|
||||||
|
else // automatic build system, don't tag dirty
|
||||||
|
exec { commandLine 'git', 'describe', '--tags', '--always'; standardOutput = stdout }
|
||||||
|
return stdout.toString().trim().substring(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
group = 'org.microg'
|
||||||
|
version = getMyVersionName()
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion androidCompileSdk()
|
||||||
|
buildToolsVersion "$androidBuildVersionTools"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
versionName getMyVersionName()
|
||||||
|
minSdkVersion androidMinSdk()
|
||||||
|
targetSdkVersion androidTargetSdk()
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api project(':play-services-basement')
|
||||||
|
}
|
34
play-services-appinvite-api/gradle.properties
Normal file
34
play-services-appinvite-api/gradle.properties
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#
|
||||||
|
# Copyright 2019 e Foundation
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
POM_NAME=Play Services Internal AppInvite API
|
||||||
|
POM_DESCRIPTION=Interfaces and objects for IPC between Play Services Library and Play Services Core
|
||||||
|
|
||||||
|
POM_PACKAGING=aar
|
||||||
|
|
||||||
|
POM_URL=https://github.com/microg/android_external_GmsApi
|
||||||
|
|
||||||
|
POM_SCM_URL=https://github.com/microg/android_external_GmsApi
|
||||||
|
POM_SCM_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git
|
||||||
|
POM_SCM_DEV_CONNECTION=scm:git@github.com:microg/android_external_GmsApi.git
|
||||||
|
|
||||||
|
POM_LICENCE_NAME=The Apache Software License, Version 2.0
|
||||||
|
POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
POM_LICENCE_DIST=repo
|
||||||
|
|
||||||
|
POM_DEVELOPER_ID=alexandruchircu
|
||||||
|
POM_DEVELOPER_NAME=Alexandru Chircu
|
||||||
|
|
18
play-services-appinvite-api/src/main/AndroidManifest.xml
Normal file
18
play-services-appinvite-api/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2019 e Foundation
|
||||||
|
~
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<manifest package="org.microg.gms.appinvite.api"/>
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.google.android.gms.appinvite.internal;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
|
||||||
|
interface IAppInviteCallbacks {
|
||||||
|
void onStatus(in Status status) = 0;
|
||||||
|
void onStatusIntent(in Status status, in Intent intent) = 1;
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.google.android.gms.appinvite.internal;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.android.gms.appinvite.internal.IAppInviteCallbacks;
|
||||||
|
|
||||||
|
import com.google.android.gms.dynamic.IObjectWrapper;
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
|
||||||
|
|
||||||
|
interface IAppInviteService {
|
||||||
|
void updateInvitationOnInstall(IAppInviteCallbacks callback, String invitationId) = 0;
|
||||||
|
void convertInvitation(IAppInviteCallbacks callback, String invitationId) = 1;
|
||||||
|
void getInvitation(IAppInviteCallbacks callback) = 2;
|
||||||
|
}
|
40
play-services-base-api/build.gradle
Normal file
40
play-services-base-api/build.gradle
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013-2015 microG Project Team
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
api project(':play-services-basement')
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion androidCompileSdk
|
||||||
|
buildToolsVersion "$androidBuildVersionTools"
|
||||||
|
|
||||||
|
aidlPackageWhiteList "com/google/android/gms/common/data/DataHolder.aidl"
|
||||||
|
aidlPackageWhiteList "com/google/android/gms/common/images/WebImage.aidl"
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
versionName version
|
||||||
|
minSdkVersion androidMinSdk
|
||||||
|
targetSdkVersion androidTargetSdk
|
||||||
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility = 1.8
|
||||||
|
targetCompatibility = 1.8
|
||||||
|
}
|
||||||
|
}
|
6
play-services-base-api/src/main/AndroidManifest.xml
Normal file
6
play-services-base-api/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
~ SPDX-License-Identifier: Apache-2.0
|
||||||
|
-->
|
||||||
|
<manifest package="org.microg.gms.base.api"/>
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.google.android.gms.common.api.internal;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
|
||||||
|
interface IStatusCallback {
|
||||||
|
void onResult(in Status status);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.android.gms.auth.api.signin;
|
||||||
|
|
||||||
|
import org.microg.safeparcel.AutoSafeParcelable;
|
||||||
|
|
||||||
|
public class GoogleSignInAccount extends AutoSafeParcelable {
|
||||||
|
public static final Creator<GoogleSignInAccount> CREATOR = new AutoCreator<GoogleSignInAccount>(GoogleSignInAccount.class);
|
||||||
|
}
|
|
@ -35,6 +35,7 @@ android {
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':play-services-basement')
|
api project(':play-services-basement')
|
||||||
api project(':play-services-tasks')
|
api project(':play-services-tasks')
|
||||||
|
api project(':play-services-base-api')
|
||||||
|
|
||||||
implementation "androidx.fragment:fragment:$fragmentVersion"
|
implementation "androidx.fragment:fragment:$fragmentVersion"
|
||||||
implementation "com.google.android.gms:play-services-base:17.3.0"
|
implementation "com.google.android.gms:play-services-base:17.3.0"
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.google.android.gms.common.api;
|
||||||
|
|
||||||
import org.microg.safeparcel.AutoSafeParcelable;
|
import org.microg.safeparcel.AutoSafeParcelable;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class AccountInfo extends AutoSafeParcelable {
|
public class AccountInfo extends AutoSafeParcelable {
|
||||||
public static final Creator<AccountInfo> CREATOR = new AutoCreator<AccountInfo>(AccountInfo.class);
|
public static final Creator<AccountInfo> CREATOR = new AutoCreator<AccountInfo>(AccountInfo.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,12 @@
|
||||||
|
|
||||||
package com.google.android.gms.common.api;
|
package com.google.android.gms.common.api;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
|
|
||||||
|
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
||||||
|
|
||||||
import org.microg.gms.common.PublicApi;
|
import org.microg.gms.common.PublicApi;
|
||||||
import org.microg.gms.common.api.ApiBuilder;
|
import org.microg.gms.common.api.ApiClientBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a section of the Google Play Services API that should be made available. Instances of
|
* Describes a section of the Google Play Services API that should be made available. Instances of
|
||||||
|
@ -33,16 +37,15 @@ import org.microg.gms.common.api.ApiBuilder;
|
||||||
*/
|
*/
|
||||||
@PublicApi
|
@PublicApi
|
||||||
public final class Api<O extends Api.ApiOptions> {
|
public final class Api<O extends Api.ApiOptions> {
|
||||||
|
private final ApiClientBuilder<O> builder;
|
||||||
private final ApiBuilder<O> builder;
|
|
||||||
|
|
||||||
@PublicApi(exclude = true)
|
@PublicApi(exclude = true)
|
||||||
public Api(ApiBuilder<O> builder) {
|
public Api(ApiClientBuilder<O> builder) {
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PublicApi(exclude = true)
|
@PublicApi(exclude = true)
|
||||||
public ApiBuilder<O> getBuilder() {
|
public ApiClientBuilder<O> getBuilder() {
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +82,22 @@ public final class Api<O extends Api.ApiOptions> {
|
||||||
@PublicApi
|
@PublicApi
|
||||||
interface Optional extends HasOptions, NotRequiredOptions {
|
interface Optional extends HasOptions, NotRequiredOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for {@link ApiOptions} that include an account.
|
||||||
|
*/
|
||||||
|
@PublicApi
|
||||||
|
interface HasAccountOptions extends HasOptions, NotRequiredOptions {
|
||||||
|
Account getAccount();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for {@link ApiOptions} that includes a {@link GoogleSignInAccount}
|
||||||
|
*/
|
||||||
|
@PublicApi
|
||||||
|
interface HasGoogleSignInAccountOptions extends HasOptions {
|
||||||
|
GoogleSignInAccount getGoogleSignInAccount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.android.gms.common.api;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.internal.ApiKey;
|
||||||
|
import com.google.android.gms.tasks.Task;
|
||||||
|
import com.google.android.gms.tasks.TaskCompletionSource;
|
||||||
|
|
||||||
|
import org.microg.gms.common.PublicApi;
|
||||||
|
import org.microg.gms.common.api.ApiClient;
|
||||||
|
import org.microg.gms.common.api.GoogleApiManager;
|
||||||
|
import org.microg.gms.common.api.PendingGoogleApiCall;
|
||||||
|
|
||||||
|
@PublicApi
|
||||||
|
public abstract class GoogleApi<O extends Api.ApiOptions> implements HasApiKey<O> {
|
||||||
|
private GoogleApiManager manager;
|
||||||
|
@PublicApi(exclude = true)
|
||||||
|
public Api<O> api;
|
||||||
|
|
||||||
|
@PublicApi(exclude = true)
|
||||||
|
protected GoogleApi(Context context, Api<O> api) {
|
||||||
|
this.api = api;
|
||||||
|
this.manager = GoogleApiManager.getInstance(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PublicApi(exclude = true)
|
||||||
|
protected <R, A extends ApiClient> Task<R> scheduleTask(PendingGoogleApiCall<R, A> apiCall) {
|
||||||
|
TaskCompletionSource<R> completionSource = new TaskCompletionSource<>();
|
||||||
|
manager.scheduleTask(this, apiCall, completionSource);
|
||||||
|
return completionSource.getTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@PublicApi(exclude = true)
|
||||||
|
public ApiKey<O> getApiKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PublicApi(exclude = true)
|
||||||
|
public O getOptions() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ import com.google.android.gms.common.ConnectionResult;
|
||||||
|
|
||||||
import org.microg.gms.auth.AuthConstants;
|
import org.microg.gms.auth.AuthConstants;
|
||||||
import org.microg.gms.common.PublicApi;
|
import org.microg.gms.common.PublicApi;
|
||||||
|
import org.microg.gms.common.api.ApiClientSettings;
|
||||||
import org.microg.gms.common.api.GoogleApiClientImpl;
|
import org.microg.gms.common.api.GoogleApiClientImpl;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -56,6 +57,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
* in {@link Activity#onStop()}, regardless of the state.
|
* in {@link Activity#onStop()}, regardless of the state.
|
||||||
*/
|
*/
|
||||||
@PublicApi
|
@PublicApi
|
||||||
|
@Deprecated
|
||||||
public interface GoogleApiClient {
|
public interface GoogleApiClient {
|
||||||
/**
|
/**
|
||||||
* Connects the client to Google Play services. Blocks until the connection either succeeds or
|
* Connects the client to Google Play services. Blocks until the connection either succeeds or
|
||||||
|
@ -271,7 +273,7 @@ public interface GoogleApiClient {
|
||||||
* attempt fails.
|
* attempt fails.
|
||||||
*/
|
*/
|
||||||
public Builder(Context context, ConnectionCallbacks connectedListener,
|
public Builder(Context context, ConnectionCallbacks connectedListener,
|
||||||
OnConnectionFailedListener connectionFailedListener) {
|
OnConnectionFailedListener connectionFailedListener) {
|
||||||
this(context);
|
this(context);
|
||||||
addConnectionCallbacks(connectedListener);
|
addConnectionCallbacks(connectedListener);
|
||||||
addOnConnectionFailedListener(connectionFailedListener);
|
addOnConnectionFailedListener(connectionFailedListener);
|
||||||
|
@ -358,16 +360,15 @@ public interface GoogleApiClient {
|
||||||
* @return The {@link GoogleApiClient} object.
|
* @return The {@link GoogleApiClient} object.
|
||||||
*/
|
*/
|
||||||
public GoogleApiClient build() {
|
public GoogleApiClient build() {
|
||||||
return new GoogleApiClientImpl(context, looper, getAccountInfo(), apis,
|
return new GoogleApiClientImpl(context, looper, getClientSettings(), apis, connectionCallbacks, connectionFailedListeners, clientId);
|
||||||
connectionCallbacks, connectionFailedListeners, clientId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccountInfo getAccountInfo() {
|
private ApiClientSettings getClientSettings() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder enableAutoManage(FragmentActivity fragmentActivity, int cliendId,
|
public Builder enableAutoManage(FragmentActivity fragmentActivity, int cliendId,
|
||||||
OnConnectionFailedListener unresolvedConnectionFailedListener)
|
OnConnectionFailedListener unresolvedConnectionFailedListener)
|
||||||
throws NullPointerException, IllegalArgumentException, IllegalStateException {
|
throws NullPointerException, IllegalArgumentException, IllegalStateException {
|
||||||
this.fragmentActivity = fragmentActivity;
|
this.fragmentActivity = fragmentActivity;
|
||||||
this.clientId = cliendId;
|
this.clientId = cliendId;
|
||||||
|
@ -433,7 +434,8 @@ public interface GoogleApiClient {
|
||||||
* service. Most applications implement {@link #onConnected(Bundle)} to start making requests.
|
* service. Most applications implement {@link #onConnected(Bundle)} to start making requests.
|
||||||
*/
|
*/
|
||||||
@PublicApi
|
@PublicApi
|
||||||
interface ConnectionCallbacks {
|
@Deprecated
|
||||||
|
interface ConnectionCallbacks extends org.microg.gms.common.api.ConnectionCallbacks {
|
||||||
/**
|
/**
|
||||||
* A suspension cause informing that the service has been killed.
|
* A suspension cause informing that the service has been killed.
|
||||||
*/
|
*/
|
||||||
|
@ -442,34 +444,6 @@ public interface GoogleApiClient {
|
||||||
* A suspension cause informing you that a peer device connection was lost.
|
* A suspension cause informing you that a peer device connection was lost.
|
||||||
*/
|
*/
|
||||||
int CAUSE_NETWORK_LOST = 2;
|
int CAUSE_NETWORK_LOST = 2;
|
||||||
|
|
||||||
/**
|
|
||||||
* After calling {@link #connect()}, this method will be invoked asynchronously when the
|
|
||||||
* connect request has successfully completed. After this callback, the application can
|
|
||||||
* make requests on other methods provided by the client and expect that no user
|
|
||||||
* intervention is required to call methods that use account and scopes provided to the
|
|
||||||
* client constructor.
|
|
||||||
* <p/>
|
|
||||||
* Note that the contents of the {@code connectionHint} Bundle are defined by the specific
|
|
||||||
* services. Please see the documentation of the specific implementation of
|
|
||||||
* {@link GoogleApiClient} you are using for more information.
|
|
||||||
*
|
|
||||||
* @param connectionHint Bundle of data provided to clients by Google Play services. May
|
|
||||||
* be null if no content is provided by the service.
|
|
||||||
*/
|
|
||||||
void onConnected(Bundle connectionHint);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the client is temporarily in a disconnected state. This can happen if there
|
|
||||||
* is a problem with the remote service (e.g. a crash or resource problem causes it to be
|
|
||||||
* killed by the system). When called, all requests have been canceled and no outstanding
|
|
||||||
* listeners will be executed. GoogleApiClient will automatically attempt to restore the
|
|
||||||
* connection. Applications should disable UI components that require the service, and wait
|
|
||||||
* for a call to {@link #onConnected(Bundle)} to re-enable them.
|
|
||||||
*
|
|
||||||
* @param cause The reason for the disconnection. Defined by constants {@code CAUSE_*}.
|
|
||||||
*/
|
|
||||||
void onConnectionSuspended(int cause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -478,18 +452,7 @@ public interface GoogleApiClient {
|
||||||
* resolution.
|
* resolution.
|
||||||
*/
|
*/
|
||||||
@PublicApi
|
@PublicApi
|
||||||
interface OnConnectionFailedListener {
|
@Deprecated
|
||||||
/**
|
interface OnConnectionFailedListener extends org.microg.gms.common.api.OnConnectionFailedListener {
|
||||||
* Called when there was an error connecting the client to the service.
|
|
||||||
*
|
|
||||||
* @param result A {@link ConnectionResult} that can be used for resolving the error, and
|
|
||||||
* deciding what sort of error occurred. To resolve the error, the resolution
|
|
||||||
* must be started from an activity with a non-negative {@code requestCode}
|
|
||||||
* passed to {@link ConnectionResult#startResolutionForResult(Activity, int)}.
|
|
||||||
* Applications should implement {@link Activity#onActivityResult} in their
|
|
||||||
* Activity to call {@link #connect()} again if the user has resolved the
|
|
||||||
* issue (resultCode is {@link Activity#RESULT_OK}).
|
|
||||||
*/
|
|
||||||
void onConnectionFailed(ConnectionResult result);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.android.gms.common.api;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.internal.ApiKey;
|
||||||
|
|
||||||
|
public interface HasApiKey<O extends Api.ApiOptions> {
|
||||||
|
ApiKey<O> getApiKey();
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.android.gms.common.api.internal;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Api;
|
||||||
|
|
||||||
|
public class ApiKey<O extends Api.ApiOptions> {
|
||||||
|
private Api<O> api;
|
||||||
|
}
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
package org.microg.gms.common;
|
package org.microg.gms.common;
|
||||||
|
|
||||||
import org.microg.gms.common.api.ApiConnection;
|
import org.microg.gms.common.api.ApiClient;
|
||||||
|
|
||||||
public class DummyApiConnection implements ApiConnection {
|
public class DummyApiClient implements ApiClient {
|
||||||
private boolean connected = false;
|
private boolean connected = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -27,19 +27,20 @@ import android.os.RemoteException;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
import com.google.android.gms.common.api.GoogleApiClient;
|
|
||||||
import com.google.android.gms.common.internal.GetServiceRequest;
|
import com.google.android.gms.common.internal.GetServiceRequest;
|
||||||
import com.google.android.gms.common.internal.IGmsCallbacks;
|
import com.google.android.gms.common.internal.IGmsCallbacks;
|
||||||
import com.google.android.gms.common.internal.IGmsServiceBroker;
|
import com.google.android.gms.common.internal.IGmsServiceBroker;
|
||||||
|
|
||||||
import org.microg.gms.common.api.ApiConnection;
|
import org.microg.gms.common.api.ApiClient;
|
||||||
|
import org.microg.gms.common.api.ConnectionCallbacks;
|
||||||
|
import org.microg.gms.common.api.OnConnectionFailedListener;
|
||||||
|
|
||||||
public abstract class GmsClient<I extends IInterface> implements ApiConnection {
|
public abstract class GmsClient<I extends IInterface> implements ApiClient {
|
||||||
private static final String TAG = "GmsClient";
|
private static final String TAG = "GmsClient";
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
protected final GoogleApiClient.ConnectionCallbacks callbacks;
|
protected final ConnectionCallbacks callbacks;
|
||||||
protected final GoogleApiClient.OnConnectionFailedListener connectionFailedListener;
|
protected final OnConnectionFailedListener connectionFailedListener;
|
||||||
protected ConnectionState state = ConnectionState.NOT_CONNECTED;
|
protected ConnectionState state = ConnectionState.NOT_CONNECTED;
|
||||||
private ServiceConnection serviceConnection;
|
private ServiceConnection serviceConnection;
|
||||||
private I serviceInterface;
|
private I serviceInterface;
|
||||||
|
@ -49,8 +50,7 @@ public abstract class GmsClient<I extends IInterface> implements ApiConnection {
|
||||||
protected Account account = null;
|
protected Account account = null;
|
||||||
protected Bundle extras = new Bundle();
|
protected Bundle extras = new Bundle();
|
||||||
|
|
||||||
public GmsClient(Context context, GoogleApiClient.ConnectionCallbacks callbacks,
|
public GmsClient(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener, String actionString) {
|
||||||
GoogleApiClient.OnConnectionFailedListener connectionFailedListener, String actionString) {
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.callbacks = callbacks;
|
this.callbacks = callbacks;
|
||||||
this.connectionFailedListener = connectionFailedListener;
|
this.connectionFailedListener = connectionFailedListener;
|
||||||
|
@ -89,8 +89,7 @@ public abstract class GmsClient<I extends IInterface> implements ApiConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleConnectionFailed() {
|
public void handleConnectionFailed() {
|
||||||
connectionFailedListener.onConnectionFailed(new ConnectionResult(ConnectionResult
|
connectionFailedListener.onConnectionFailed(new ConnectionResult(ConnectionResult.API_UNAVAILABLE, null));
|
||||||
.API_UNAVAILABLE, null));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -147,8 +146,7 @@ public abstract class GmsClient<I extends IInterface> implements ApiConnection {
|
||||||
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
|
||||||
try {
|
try {
|
||||||
Log.d(TAG, "ServiceConnection : onServiceConnected(" + componentName + ")");
|
Log.d(TAG, "ServiceConnection : onServiceConnected(" + componentName + ")");
|
||||||
onConnectedToBroker(IGmsServiceBroker.Stub.asInterface(iBinder),
|
onConnectedToBroker(IGmsServiceBroker.Stub.asInterface(iBinder), new GmsCallbacks());
|
||||||
new GmsCallbacks());
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,10 @@ import com.google.android.gms.common.api.PendingResult;
|
||||||
import com.google.android.gms.common.api.Result;
|
import com.google.android.gms.common.api.Result;
|
||||||
|
|
||||||
import org.microg.gms.common.api.AbstractPendingResult;
|
import org.microg.gms.common.api.AbstractPendingResult;
|
||||||
import org.microg.gms.common.api.ApiConnection;
|
import org.microg.gms.common.api.ApiClient;
|
||||||
import org.microg.gms.common.api.GoogleApiClientImpl;
|
import org.microg.gms.common.api.GoogleApiClientImpl;
|
||||||
|
|
||||||
public class GmsConnector<C extends ApiConnection, R extends Result> {
|
public class GmsConnector<C extends ApiClient, R extends Result> {
|
||||||
private static final String TAG = "GmsConnector";
|
private static final String TAG = "GmsConnector";
|
||||||
|
|
||||||
private final GoogleApiClientImpl apiClient;
|
private final GoogleApiClientImpl apiClient;
|
||||||
|
@ -43,7 +43,7 @@ public class GmsConnector<C extends ApiConnection, R extends Result> {
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <C extends ApiConnection, R extends Result> PendingResult<R> call(GoogleApiClient client, Api api, GmsConnector.Callback<C, R> callback) {
|
public static <C extends ApiClient, R extends Result> PendingResult<R> call(GoogleApiClient client, Api api, GmsConnector.Callback<C, R> callback) {
|
||||||
return new GmsConnector<C, R>(client, api, callback).connect();
|
return new GmsConnector<C, R>(client, api, callback).connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
package org.microg.gms.common.api;
|
package org.microg.gms.common.api;
|
||||||
|
|
||||||
public interface ApiConnection {
|
public interface ApiClient {
|
||||||
void connect();
|
void connect();
|
||||||
|
|
||||||
void disconnect();
|
void disconnect();
|
|
@ -19,12 +19,8 @@ package org.microg.gms.common.api;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
|
||||||
import com.google.android.gms.common.api.AccountInfo;
|
|
||||||
import com.google.android.gms.common.api.Api;
|
import com.google.android.gms.common.api.Api;
|
||||||
import com.google.android.gms.common.api.GoogleApiClient;
|
|
||||||
|
|
||||||
public interface ApiBuilder<O extends Api.ApiOptions> {
|
public interface ApiClientBuilder<O extends Api.ApiOptions> {
|
||||||
ApiConnection build(Context context, Looper looper, O options, AccountInfo accountInfo,
|
ApiClient build(O options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener);
|
||||||
GoogleApiClient.ConnectionCallbacks callbacks,
|
|
||||||
GoogleApiClient.OnConnectionFailedListener connectionFailedListener);
|
|
||||||
}
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.common.api;
|
||||||
|
|
||||||
|
public class ApiClientSettings {
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.common.api;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
|
|
||||||
|
public interface ConnectionCallbacks {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After calling {@link #connect()}, this method will be invoked asynchronously when the
|
||||||
|
* connect request has successfully completed. After this callback, the application can
|
||||||
|
* make requests on other methods provided by the client and expect that no user
|
||||||
|
* intervention is required to call methods that use account and scopes provided to the
|
||||||
|
* client constructor.
|
||||||
|
* <p/>
|
||||||
|
* Note that the contents of the {@code connectionHint} Bundle are defined by the specific
|
||||||
|
* services. Please see the documentation of the specific implementation of
|
||||||
|
* {@link GoogleApiClient} you are using for more information.
|
||||||
|
*
|
||||||
|
* @param connectionHint Bundle of data provided to clients by Google Play services. May
|
||||||
|
* be null if no content is provided by the service.
|
||||||
|
*/
|
||||||
|
void onConnected(Bundle connectionHint);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the client is temporarily in a disconnected state. This can happen if there
|
||||||
|
* is a problem with the remote service (e.g. a crash or resource problem causes it to be
|
||||||
|
* killed by the system). When called, all requests have been canceled and no outstanding
|
||||||
|
* listeners will be executed. GoogleApiClient will automatically attempt to restore the
|
||||||
|
* connection. Applications should disable UI components that require the service, and wait
|
||||||
|
* for a call to {@link #onConnected(Bundle)} to re-enable them.
|
||||||
|
*
|
||||||
|
* @param cause The reason for the disconnection. Defined by constants {@code CAUSE_*}.
|
||||||
|
*/
|
||||||
|
void onConnectionSuspended(int cause);
|
||||||
|
}
|
|
@ -20,11 +20,12 @@ import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
import com.google.android.gms.common.api.AccountInfo;
|
|
||||||
import com.google.android.gms.common.api.Api;
|
import com.google.android.gms.common.api.Api;
|
||||||
import com.google.android.gms.common.api.GoogleApiClient;
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
import com.google.android.gms.common.api.PendingResult;
|
import com.google.android.gms.common.api.PendingResult;
|
||||||
|
@ -41,10 +42,9 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final Looper looper;
|
private final Looper looper;
|
||||||
private final AccountInfo accountInfo;
|
private final ApiClientSettings clientSettings;
|
||||||
private final Map<Api, Api.ApiOptions> apis = new HashMap<Api, Api.ApiOptions>();
|
private final Map<Api, Api.ApiOptions> apis = new HashMap<Api, Api.ApiOptions>();
|
||||||
private final Map<Api, ApiConnection> apiConnections = new HashMap<Api, ApiConnection>();
|
private final Map<Api, ApiClient> apiConnections = new HashMap<Api, ApiClient>();
|
||||||
private final Handler handler;
|
|
||||||
private final Set<ConnectionCallbacks> connectionCallbacks = new HashSet<ConnectionCallbacks>();
|
private final Set<ConnectionCallbacks> connectionCallbacks = new HashSet<ConnectionCallbacks>();
|
||||||
private final Set<OnConnectionFailedListener> connectionFailedListeners = new HashSet<OnConnectionFailedListener>();
|
private final Set<OnConnectionFailedListener> connectionFailedListeners = new HashSet<OnConnectionFailedListener>();
|
||||||
private final int clientId;
|
private final int clientId;
|
||||||
|
@ -78,23 +78,20 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
private int usageCounter = 0;
|
private int usageCounter = 0;
|
||||||
private boolean shouldDisconnect = false;
|
private boolean shouldDisconnect = false;
|
||||||
|
|
||||||
public GoogleApiClientImpl(Context context, Looper looper, AccountInfo accountInfo,
|
public GoogleApiClientImpl(Context context, Looper looper, ApiClientSettings clientSettings,
|
||||||
Map<Api, Api.ApiOptions> apis,
|
Map<Api, Api.ApiOptions> apis,
|
||||||
Set<ConnectionCallbacks> connectionCallbacks,
|
Set<ConnectionCallbacks> connectionCallbacks,
|
||||||
Set<OnConnectionFailedListener> connectionFailedListeners, int clientId) {
|
Set<OnConnectionFailedListener> connectionFailedListeners, int clientId) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.looper = looper;
|
this.looper = looper;
|
||||||
this.handler = new Handler(looper);
|
this.clientSettings = clientSettings;
|
||||||
this.accountInfo = accountInfo;
|
|
||||||
this.apis.putAll(apis);
|
this.apis.putAll(apis);
|
||||||
this.connectionCallbacks.addAll(connectionCallbacks);
|
this.connectionCallbacks.addAll(connectionCallbacks);
|
||||||
this.connectionFailedListeners.addAll(connectionFailedListeners);
|
this.connectionFailedListeners.addAll(connectionFailedListeners);
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
|
|
||||||
for (Api api : apis.keySet()) {
|
for (Api api : apis.keySet()) {
|
||||||
apiConnections.put(api, api.getBuilder().build(context, looper,
|
apiConnections.put(api, api.getBuilder().build(apis.get(api), context, looper, clientSettings, baseConnectionCallbacks, baseConnectionFailedListener));
|
||||||
apis.get(api), accountInfo, baseConnectionCallbacks,
|
|
||||||
baseConnectionFailedListener));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +108,7 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
return looper;
|
return looper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApiConnection getApiConnection(Api api) {
|
public ApiClient getApiConnection(Api api) {
|
||||||
return apiConnections.get(api);
|
return apiConnections.get(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +138,7 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
Log.d(TAG, "Already connected/connecting, nothing to do");
|
Log.d(TAG, "Already connected/connecting, nothing to do");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (ApiConnection connection : apiConnections.values()) {
|
for (ApiClient connection : apiConnections.values()) {
|
||||||
if (!connection.isConnected()) {
|
if (!connection.isConnected()) {
|
||||||
connection.connect();
|
connection.connect();
|
||||||
}
|
}
|
||||||
|
@ -154,7 +151,7 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
shouldDisconnect = true;
|
shouldDisconnect = true;
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "disconnect()");
|
Log.d(TAG, "disconnect()");
|
||||||
for (ApiConnection connection : apiConnections.values()) {
|
for (ApiClient connection : apiConnections.values()) {
|
||||||
if (connection.isConnected()) {
|
if (connection.isConnected()) {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
}
|
}
|
||||||
|
@ -164,7 +161,7 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean isConnected() {
|
public synchronized boolean isConnected() {
|
||||||
for (ApiConnection connection : apiConnections.values()) {
|
for (ApiClient connection : apiConnections.values()) {
|
||||||
if (!connection.isConnected()) return false;
|
if (!connection.isConnected()) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -172,7 +169,7 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean isConnecting() {
|
public synchronized boolean isConnecting() {
|
||||||
for (ApiConnection connection : apiConnections.values()) {
|
for (ApiClient connection : apiConnections.values()) {
|
||||||
if (connection.isConnecting()) return true;
|
if (connection.isConnecting()) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -220,23 +217,4 @@ public class GoogleApiClientImpl implements GoogleApiClient {
|
||||||
public void unregisterConnectionFailedListener(OnConnectionFailedListener listener) {
|
public void unregisterConnectionFailedListener(OnConnectionFailedListener listener) {
|
||||||
connectionFailedListeners.remove(listener);
|
connectionFailedListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Handler extends android.os.Handler {
|
|
||||||
private Handler(Looper looper) {
|
|
||||||
super(looper);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
if (msg.what == 0 && msg.obj instanceof Runnable) {
|
|
||||||
((Runnable) msg.obj).run();
|
|
||||||
} else {
|
|
||||||
super.handleMessage(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendRunnable(Runnable runnable) {
|
|
||||||
sendMessage(obtainMessage(1, runnable));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.common.api;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
|
import com.google.android.gms.common.api.Api;
|
||||||
|
import com.google.android.gms.common.api.GoogleApi;
|
||||||
|
import com.google.android.gms.tasks.TaskCompletionSource;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class GoogleApiManager {
|
||||||
|
private static GoogleApiManager instance;
|
||||||
|
private Context context;
|
||||||
|
private Map<ApiInstance, ApiClient> clientMap = new HashMap<>();
|
||||||
|
private Map<ApiInstance, List<WaitingApiCall<?>>> waitingApiCallMap = new HashMap<>();
|
||||||
|
|
||||||
|
private GoogleApiManager(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized static GoogleApiManager getInstance(Context context) {
|
||||||
|
if (instance == null) instance = new GoogleApiManager(context);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized <O extends Api.ApiOptions, A extends ApiClient> A clientForApi(GoogleApi<O> api) {
|
||||||
|
ApiInstance apiInstance = new ApiInstance(api);
|
||||||
|
if (clientMap.containsKey(apiInstance)) {
|
||||||
|
return (A) clientMap.get(apiInstance);
|
||||||
|
} else {
|
||||||
|
ApiClient client = api.api.getBuilder().build(api.getOptions(), context, context.getMainLooper(), null, new ConnectionCallback(apiInstance), new ConnectionFailedListener(apiInstance));
|
||||||
|
clientMap.put(apiInstance, client);
|
||||||
|
waitingApiCallMap.put(apiInstance, new ArrayList<>());
|
||||||
|
return (A) client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized <O extends Api.ApiOptions, R, A extends ApiClient> void scheduleTask(GoogleApi<O> api, PendingGoogleApiCall<R, A> apiCall, TaskCompletionSource<R> completionSource) {
|
||||||
|
A client = clientForApi(api);
|
||||||
|
boolean connecting = client.isConnecting();
|
||||||
|
boolean connected = client.isConnected();
|
||||||
|
if (connected) {
|
||||||
|
apiCall.execute(client, completionSource);
|
||||||
|
} else {
|
||||||
|
waitingApiCallMap.get(new ApiInstance(api)).add(new WaitingApiCall<R>((PendingGoogleApiCall<R, ApiClient>) apiCall, completionSource));
|
||||||
|
if (!connecting) {
|
||||||
|
client.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void onInstanceConnected(ApiInstance apiInstance, Bundle connectionHint) {
|
||||||
|
List<WaitingApiCall<?>> waitingApiCalls = waitingApiCallMap.get(apiInstance);
|
||||||
|
for (WaitingApiCall<?> waitingApiCall : waitingApiCalls) {
|
||||||
|
waitingApiCall.execute(clientMap.get(apiInstance));
|
||||||
|
}
|
||||||
|
waitingApiCalls.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void onInstanceSuspended(ApiInstance apiInstance, int cause) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void onInstanceFailed(ApiInstance apiInstance, ConnectionResult result) {
|
||||||
|
List<WaitingApiCall<?>> waitingApiCalls = waitingApiCallMap.get(apiInstance);
|
||||||
|
for (WaitingApiCall<?> waitingApiCall : waitingApiCalls) {
|
||||||
|
waitingApiCall.failed(new RuntimeException(result.getErrorMessage()));
|
||||||
|
}
|
||||||
|
waitingApiCalls.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConnectionCallback implements ConnectionCallbacks {
|
||||||
|
private ApiInstance apiInstance;
|
||||||
|
|
||||||
|
public ConnectionCallback(ApiInstance apiInstance) {
|
||||||
|
this.apiInstance = apiInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnected(Bundle connectionHint) {
|
||||||
|
onInstanceConnected(apiInstance, connectionHint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnectionSuspended(int cause) {
|
||||||
|
onInstanceSuspended(apiInstance, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConnectionFailedListener implements OnConnectionFailedListener {
|
||||||
|
private ApiInstance apiInstance;
|
||||||
|
|
||||||
|
public ConnectionFailedListener(ApiInstance apiInstance) {
|
||||||
|
this.apiInstance = apiInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnectionFailed(ConnectionResult result) {
|
||||||
|
onInstanceFailed(apiInstance, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class WaitingApiCall<R> {
|
||||||
|
private PendingGoogleApiCall<R, ApiClient> apiCall;
|
||||||
|
private TaskCompletionSource<R> completionSource;
|
||||||
|
|
||||||
|
public WaitingApiCall(PendingGoogleApiCall<R, ApiClient> apiCall, TaskCompletionSource<R> completionSource) {
|
||||||
|
this.apiCall = apiCall;
|
||||||
|
this.completionSource = completionSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(ApiClient client) {
|
||||||
|
apiCall.execute(client, completionSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void failed(Exception e) {
|
||||||
|
completionSource.setException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
WaitingApiCall<?> that = (WaitingApiCall<?>) o;
|
||||||
|
|
||||||
|
if (apiCall != null ? !apiCall.equals(that.apiCall) : that.apiCall != null) return false;
|
||||||
|
return completionSource != null ? completionSource.equals(that.completionSource) : that.completionSource == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = apiCall != null ? apiCall.hashCode() : 0;
|
||||||
|
result = 31 * result + (completionSource != null ? completionSource.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ApiInstance {
|
||||||
|
private Class<?> apiClass;
|
||||||
|
private Api.ApiOptions apiOptions;
|
||||||
|
|
||||||
|
public ApiInstance(Class<?> apiClass, Api.ApiOptions apiOptions) {
|
||||||
|
this.apiClass = apiClass;
|
||||||
|
this.apiOptions = apiOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ApiInstance(GoogleApi<?> api) {
|
||||||
|
this(api.getClass(), api.getOptions());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ApiInstance that = (ApiInstance) o;
|
||||||
|
|
||||||
|
if (apiClass != null ? !apiClass.equals(that.apiClass) : that.apiClass != null) return false;
|
||||||
|
return apiOptions != null ? apiOptions.equals(that.apiOptions) : that.apiOptions == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = apiClass != null ? apiClass.hashCode() : 0;
|
||||||
|
result = 31 * result + (apiOptions != null ? apiOptions.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.common.api;
|
||||||
|
|
||||||
|
import com.google.android.gms.tasks.TaskCompletionSource;
|
||||||
|
|
||||||
|
public interface InstantGoogleApiCall<R, A extends ApiClient> extends PendingGoogleApiCall<R, A> {
|
||||||
|
R execute(A client) throws Exception;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void execute(A client, TaskCompletionSource<R> completionSource) {
|
||||||
|
try {
|
||||||
|
completionSource.setResult(execute(client));
|
||||||
|
} catch (Exception e) {
|
||||||
|
completionSource.setException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.common.api;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
|
|
||||||
|
public interface OnConnectionFailedListener {
|
||||||
|
/**
|
||||||
|
* Called when there was an error connecting the client to the service.
|
||||||
|
*
|
||||||
|
* @param result A {@link ConnectionResult} that can be used for resolving the error, and
|
||||||
|
* deciding what sort of error occurred. To resolve the error, the resolution
|
||||||
|
* must be started from an activity with a non-negative {@code requestCode}
|
||||||
|
* passed to {@link ConnectionResult#startResolutionForResult(Activity, int)}.
|
||||||
|
* Applications should implement {@link Activity#onActivityResult} in their
|
||||||
|
* Activity to call {@link #connect()} again if the user has resolved the
|
||||||
|
* issue (resultCode is {@link Activity#RESULT_OK}).
|
||||||
|
*/
|
||||||
|
void onConnectionFailed(ConnectionResult result);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.common.api;
|
||||||
|
|
||||||
|
import com.google.android.gms.tasks.TaskCompletionSource;
|
||||||
|
|
||||||
|
public interface PendingGoogleApiCall<R, A extends ApiClient> {
|
||||||
|
void execute(A client, TaskCompletionSource<R> completionSource);
|
||||||
|
}
|
|
@ -30,8 +30,6 @@ android {
|
||||||
buildToolsVersion "$androidBuildVersionTools"
|
buildToolsVersion "$androidBuildVersionTools"
|
||||||
|
|
||||||
aidlPackageWhiteList "com/google/android/gms/common/api/Status.aidl"
|
aidlPackageWhiteList "com/google/android/gms/common/api/Status.aidl"
|
||||||
aidlPackageWhiteList "com/google/android/gms/common/data/DataHolder.aidl"
|
|
||||||
aidlPackageWhiteList "com/google/android/gms/common/images/WebImage.aidl"
|
|
||||||
aidlPackageWhiteList "com/google/android/gms/common/internal/ICancelToken.aidl"
|
aidlPackageWhiteList "com/google/android/gms/common/internal/ICancelToken.aidl"
|
||||||
aidlPackageWhiteList "com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl"
|
aidlPackageWhiteList "com/google/android/gms/common/server/FavaDiagnosticsEntity.aidl"
|
||||||
aidlPackageWhiteList "com/google/android/gms/dynamic/IObjectWrapper.aidl"
|
aidlPackageWhiteList "com/google/android/gms/dynamic/IObjectWrapper.aidl"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
package org.microg.gms.common;
|
package org.microg.gms.common;
|
||||||
|
|
||||||
public class Constants {
|
public class Constants {
|
||||||
public static final int MAX_REFERENCE_VERSION = 19420 * 1000;
|
public static final int MAX_REFERENCE_VERSION = 202414 * 1000;
|
||||||
public static final String GMS_PACKAGE_NAME = "com.google.android.gms";
|
public static final String GMS_PACKAGE_NAME = "com.google.android.gms";
|
||||||
public static final String GSF_PACKAGE_NAME = "com.mgoogle.android.gsf";
|
public static final String GSF_PACKAGE_NAME = "com.mgoogle.android.gsf";
|
||||||
public static final String GMS_PACKAGE_SIGNATURE_SHA1 = "38918a453d07199354f8b19af05ec6562ced5788";
|
public static final String GMS_PACKAGE_SIGNATURE_SHA1 = "38918a453d07199354f8b19af05ec6562ced5788";
|
||||||
|
|
|
@ -88,6 +88,7 @@ public enum GmsService {
|
||||||
PLUS_INTERNAL(70),
|
PLUS_INTERNAL(70),
|
||||||
SOURCE_DEVICE(75, "com.google.android.gms.smartdevice.d2d.SourceDeviceService.START"),
|
SOURCE_DEVICE(75, "com.google.android.gms.smartdevice.d2d.SourceDeviceService.START"),
|
||||||
TARGET_DEVICE(76, "com.google.android.gms.smartdevice.d2d.TargetDeviceService.START"),
|
TARGET_DEVICE(76, "com.google.android.gms.smartdevice.d2d.TargetDeviceService.START"),
|
||||||
|
APP_INVITE(77, "com.google.android.gms.appinvite.service.START"),
|
||||||
TAP_AND_PAY(79, "com.google.android.gms.tapandpay.service.BIND"),
|
TAP_AND_PAY(79, "com.google.android.gms.tapandpay.service.BIND"),
|
||||||
ACCOUNTS(81, "com.google.android.gms.smartdevice.setup.accounts.AccountsService.START"),
|
ACCOUNTS(81, "com.google.android.gms.smartdevice.setup.accounts.AccountsService.START"),
|
||||||
TRUST_AGENT(85, "com.google.android.gms.trustagent.StateApi.START"),
|
TRUST_AGENT(85, "com.google.android.gms.trustagent.StateApi.START"),
|
||||||
|
@ -98,6 +99,8 @@ public enum GmsService {
|
||||||
GASS(116, "com.google.android.gms.gass.START"),
|
GASS(116, "com.google.android.gms.gass.START"),
|
||||||
WORK_ACCOUNT(120),
|
WORK_ACCOUNT(120),
|
||||||
AD_CACHE(123, "com.google.android.gms.ads.service.CACHE"),
|
AD_CACHE(123, "com.google.android.gms.ads.service.CACHE"),
|
||||||
|
DYNAMIC_LINKS(131, "com.google.firebase.dynamiclinks.service.START"),
|
||||||
|
NEARBY_EXPOSURE(236, "com.google.android.gms.nearby.exposurenotification.START"),
|
||||||
;
|
;
|
||||||
|
|
||||||
public int SERVICE_ID;
|
public int SERVICE_ID;
|
||||||
|
|
|
@ -37,4 +37,6 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':play-services-basement')
|
api project(':play-services-basement')
|
||||||
|
|
||||||
|
api project(':play-services-base-api')
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,5 +34,7 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api project(':play-services-basement')
|
api project(':play-services-basement')
|
||||||
|
|
||||||
|
api project(':play-services-base-api')
|
||||||
api project(':play-services-cast-api')
|
api project(':play-services-cast-api')
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2017 microG Project Team
|
||||||
|
*
|
||||||
|
* 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.google.android.gms.cast;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Api;
|
||||||
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
|
import com.google.android.gms.common.api.PendingResult;
|
||||||
|
import com.google.android.gms.common.api.Result;
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
|
||||||
|
import org.microg.gms.cast.CastApiClientBuilder;
|
||||||
|
import org.microg.gms.cast.CastApiImpl;
|
||||||
|
import org.microg.gms.common.PublicApi;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@PublicApi
|
||||||
|
public final class Cast {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constant indicating that the Google Cast device is not the currently active video input.
|
||||||
|
*/
|
||||||
|
public static final int ACTIVE_INPUT_STATE_NO = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constant indicating that it is not known (and/or not possible to know) whether the Google Cast device is
|
||||||
|
* the currently active video input. Active input state can only be reported when the Google Cast device is
|
||||||
|
* connected to a TV or AVR with CEC support.
|
||||||
|
*/
|
||||||
|
public static final int ACTIVE_INPUT_STATE_UNKNOWN = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constant indicating that the Google Cast device is the currently active video input.
|
||||||
|
*/
|
||||||
|
public static final int ACTIVE_INPUT_STATE_YES = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean extra for the connection hint bundle passed to
|
||||||
|
* {@link GoogleApiClient.ConnectionCallbacks#onConnected(Bundle)} that indicates that the connection was
|
||||||
|
* re-established, but the receiver application that was in use at the time of the connection loss is no longer
|
||||||
|
* running on the receiver.
|
||||||
|
*/
|
||||||
|
public static final String EXTRA_APP_NO_LONGER_RUNNING = "com.google.android.gms.cast.EXTRA_APP_NO_LONGER_RUNNING";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum raw message length (in bytes) that is supported by a Cast channel.
|
||||||
|
*/
|
||||||
|
public static final int MAX_MESSAGE_LENGTH = 65536;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum length (in characters) of a namespace name.
|
||||||
|
*/
|
||||||
|
public static final int MAX_NAMESPACE_LENGTH = 128;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constant indicating that the Google Cast device is not currently in standby.
|
||||||
|
*/
|
||||||
|
public static final int STANDBY_STATE_NO = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constant indicating that it is not known (and/or not possible to know) whether the Google Cast device is
|
||||||
|
* currently in standby. Standby state can only be reported when the Google Cast device is connected to a TV or
|
||||||
|
* AVR with CEC support.
|
||||||
|
*/
|
||||||
|
public static final int STANDBY_STATE_UNKNOWN = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A constant indicating that the Google Cast device is currently in standby.
|
||||||
|
*/
|
||||||
|
public static final int STANDBY_STATE_YES = 1;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the Cast features.
|
||||||
|
*/
|
||||||
|
public static final Api<CastOptions> API = new Api<CastOptions>(new CastApiClientBuilder());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of the CastApi interface. The interface is used to interact with a cast device.
|
||||||
|
*/
|
||||||
|
public static final Cast.CastApi CastApi = new CastApiImpl();
|
||||||
|
|
||||||
|
private Cast() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ApplicationConnectionResult extends Result {
|
||||||
|
ApplicationMetadata getApplicationMetadata();
|
||||||
|
|
||||||
|
String getApplicationStatus();
|
||||||
|
|
||||||
|
String getSessionId();
|
||||||
|
|
||||||
|
boolean getWasLaunched();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface CastApi {
|
||||||
|
int getActiveInputState(GoogleApiClient client);
|
||||||
|
|
||||||
|
ApplicationMetadata getApplicationMetadata(GoogleApiClient client);
|
||||||
|
|
||||||
|
String getApplicationStatus(GoogleApiClient client);
|
||||||
|
|
||||||
|
int getStandbyState(GoogleApiClient client);
|
||||||
|
|
||||||
|
double getVolume(GoogleApiClient client);
|
||||||
|
|
||||||
|
boolean isMute(GoogleApiClient client);
|
||||||
|
|
||||||
|
PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client);
|
||||||
|
|
||||||
|
PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client, String applicationId, String sessionId);
|
||||||
|
|
||||||
|
PendingResult<Cast.ApplicationConnectionResult> joinApplication(GoogleApiClient client, String applicationId);
|
||||||
|
|
||||||
|
PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId, LaunchOptions launchOptions);
|
||||||
|
|
||||||
|
PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId);
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
PendingResult<Cast.ApplicationConnectionResult> launchApplication(GoogleApiClient client, String applicationId, boolean relaunchIfRunning);
|
||||||
|
|
||||||
|
PendingResult<Status> leaveApplication(GoogleApiClient client);
|
||||||
|
|
||||||
|
void removeMessageReceivedCallbacks(GoogleApiClient client, String namespace) throws IOException;
|
||||||
|
|
||||||
|
void requestStatus(GoogleApiClient client) throws IOException;
|
||||||
|
|
||||||
|
PendingResult<Status> sendMessage(GoogleApiClient client, String namespace, String message);
|
||||||
|
|
||||||
|
void setMessageReceivedCallbacks(GoogleApiClient client, String namespace, Cast.MessageReceivedCallback callbacks) throws IOException;
|
||||||
|
|
||||||
|
void setMute(GoogleApiClient client, boolean mute) throws IOException;
|
||||||
|
|
||||||
|
void setVolume(GoogleApiClient client, double volume) throws IOException;
|
||||||
|
|
||||||
|
PendingResult<Status> stopApplication(GoogleApiClient client);
|
||||||
|
|
||||||
|
PendingResult<Status> stopApplication(GoogleApiClient client, String sessionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CastOptions implements Api.ApiOptions.HasOptions {
|
||||||
|
private final CastDevice castDevice;
|
||||||
|
private final Listener castListener;
|
||||||
|
private final boolean verboseLoggingEnabled;
|
||||||
|
|
||||||
|
public CastOptions(CastDevice castDevice, Listener castListener, boolean verboseLoggingEnabled) {
|
||||||
|
this.castDevice = castDevice;
|
||||||
|
this.castListener = castListener;
|
||||||
|
this.verboseLoggingEnabled = verboseLoggingEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static Builder builder(CastDevice castDevice, Listener castListener) {
|
||||||
|
return new Builder(castDevice, castListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
private final CastDevice castDevice;
|
||||||
|
private final Listener castListener;
|
||||||
|
private boolean verboseLoggingEnabled;
|
||||||
|
|
||||||
|
public Builder(CastDevice castDevice, Listener castListener) {
|
||||||
|
this.castDevice = castDevice;
|
||||||
|
this.castListener = castListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CastOptions build() {
|
||||||
|
return new CastOptions(castDevice, castListener, verboseLoggingEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setVerboseLoggingEnabled(boolean verboseLoggingEnabled) {
|
||||||
|
this.verboseLoggingEnabled = verboseLoggingEnabled;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Listener {
|
||||||
|
public void onActiveInputStateChanged(int activeInputState) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onApplicationDisconnected(int statusCode) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onApplicationMetadataChanged(ApplicationMetadata applicationMetadata) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onApplicationStatusChanged() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStandbyStateChanged(int standbyState) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onVolumeChanged() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MessageReceivedCallback {
|
||||||
|
void onMessageReceived(CastDevice castDevice, String namespace, String message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2017 microG Project Team
|
||||||
|
*
|
||||||
|
* 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.google.android.gms.cast;
|
||||||
|
|
||||||
|
import android.view.Display;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Api;
|
||||||
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
|
import com.google.android.gms.common.api.Result;
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
|
||||||
|
import org.microg.gms.cast.CastRemoteDisplayApiClientBuilder;
|
||||||
|
import org.microg.gms.cast.CastRemoteDisplayApiImpl;
|
||||||
|
import org.microg.gms.common.PublicApi;
|
||||||
|
|
||||||
|
@PublicApi
|
||||||
|
public final class CastRemoteDisplay {
|
||||||
|
/**
|
||||||
|
* Token to pass to {@link GoogleApiClient.Builder#addApi(Api)} to enable the CastRemoteDisplay features.
|
||||||
|
*/
|
||||||
|
public static final Api<CastRemoteDisplayOptions> API = new Api<CastRemoteDisplayOptions>(new CastRemoteDisplayApiClientBuilder());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of the CastRemoteDisplayAPI interface. The interface is used to interact with a cast device.
|
||||||
|
*/
|
||||||
|
public static final CastRemoteDisplayApi CastApi = new CastRemoteDisplayApiImpl();
|
||||||
|
|
||||||
|
private CastRemoteDisplay() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class CastRemoteDisplayOptions implements Api.ApiOptions.HasOptions {
|
||||||
|
private CastDevice castDevice;
|
||||||
|
private CastRemoteDisplaySessionCallbacks callbacks;
|
||||||
|
|
||||||
|
private CastRemoteDisplayOptions(CastDevice castDevice, CastRemoteDisplaySessionCallbacks callbacks) {
|
||||||
|
this.castDevice = castDevice;
|
||||||
|
this.callbacks = callbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder {
|
||||||
|
private CastDevice castDevice;
|
||||||
|
private CastRemoteDisplaySessionCallbacks callbacks;
|
||||||
|
|
||||||
|
public Builder(CastDevice castDevice, CastRemoteDisplaySessionCallbacks callbacks) {
|
||||||
|
this.castDevice = castDevice;
|
||||||
|
this.callbacks = callbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CastRemoteDisplayOptions build() {
|
||||||
|
return new CastRemoteDisplayOptions(castDevice, callbacks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface CastRemoteDisplaySessionCallbacks {
|
||||||
|
void onRemoteDisplayEnded(Status status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface CastRemoteDisplaySessionResult extends Result {
|
||||||
|
Display getPresentationDisplay();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2017 microG Project Team
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.cast;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import com.google.android.gms.cast.Cast;
|
||||||
|
|
||||||
|
import org.microg.gms.common.api.ApiClientBuilder;
|
||||||
|
import org.microg.gms.common.api.ApiClientSettings;
|
||||||
|
import org.microg.gms.common.api.ApiClient;
|
||||||
|
import org.microg.gms.common.api.ConnectionCallbacks;
|
||||||
|
import org.microg.gms.common.api.OnConnectionFailedListener;
|
||||||
|
|
||||||
|
public class CastApiClientBuilder implements ApiClientBuilder<Cast.CastOptions> {
|
||||||
|
@Override
|
||||||
|
public ApiClient build(Cast.CastOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||||
|
return new CastClientImpl(context, options, callbacks, connectionFailedListener);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2017 microG Project Team
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.cast;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.google.android.gms.cast.Cast;
|
||||||
|
|
||||||
|
import org.microg.gms.common.DummyApiClient;
|
||||||
|
import org.microg.gms.common.api.ConnectionCallbacks;
|
||||||
|
import org.microg.gms.common.api.OnConnectionFailedListener;
|
||||||
|
|
||||||
|
public class CastClientImpl extends DummyApiClient {
|
||||||
|
public CastClientImpl(Context context, Cast.CastOptions options, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2017 microG Project Team
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.cast;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import com.google.android.gms.cast.CastRemoteDisplay;
|
||||||
|
|
||||||
|
import org.microg.gms.common.DummyApiClient;
|
||||||
|
import org.microg.gms.common.api.ApiClientBuilder;
|
||||||
|
import org.microg.gms.common.api.ApiClientSettings;
|
||||||
|
import org.microg.gms.common.api.ApiClient;
|
||||||
|
import org.microg.gms.common.api.ConnectionCallbacks;
|
||||||
|
import org.microg.gms.common.api.OnConnectionFailedListener;
|
||||||
|
|
||||||
|
public class CastRemoteDisplayApiClientBuilder implements ApiClientBuilder<CastRemoteDisplay.CastRemoteDisplayOptions> {
|
||||||
|
@Override
|
||||||
|
public ApiClient build(CastRemoteDisplay.CastRemoteDisplayOptions options, Context context, Looper looper, ApiClientSettings clientSettings, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||||
|
return new DummyApiClient();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,81 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2014 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 org.microg.tools.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.preference.Preference;
|
|
||||||
import androidx.preference.PreferenceViewHolder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A preference item that can dim the icon when it's disabled, either directly or because its parent
|
|
||||||
* is disabled.
|
|
||||||
*/
|
|
||||||
public class DimmableIconPreference extends Preference {
|
|
||||||
private static final int ICON_ALPHA_ENABLED = 255;
|
|
||||||
private static final int ICON_ALPHA_DISABLED = 102;
|
|
||||||
|
|
||||||
private final CharSequence mContentDescription;
|
|
||||||
|
|
||||||
public DimmableIconPreference(Context context) {
|
|
||||||
this(context, (AttributeSet) null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public DimmableIconPreference(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
mContentDescription = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DimmableIconPreference(Context context, CharSequence contentDescription) {
|
|
||||||
super(context);
|
|
||||||
mContentDescription = contentDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean shouldDimIcon() {
|
|
||||||
return !isEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dimIcon(boolean dimmed) {
|
|
||||||
Drawable icon = getIcon();
|
|
||||||
if (icon != null) {
|
|
||||||
icon.mutate().setAlpha(dimmed ? ICON_ALPHA_DISABLED : ICON_ALPHA_ENABLED);
|
|
||||||
setIcon(icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
|
||||||
super.onBindViewHolder(view);
|
|
||||||
if (!TextUtils.isEmpty(mContentDescription)) {
|
|
||||||
final TextView titleView = (TextView) view.findViewById(android.R.id.title);
|
|
||||||
titleView.setContentDescription(mContentDescription);
|
|
||||||
}
|
|
||||||
ViewGroup.LayoutParams layoutParams = view.findViewById(R.id.icon_frame).getLayoutParams();
|
|
||||||
if (layoutParams instanceof LinearLayout.LayoutParams) {
|
|
||||||
if (((LinearLayout.LayoutParams) layoutParams).leftMargin < 0) {
|
|
||||||
((LinearLayout.LayoutParams) layoutParams).leftMargin = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dimIcon(shouldDimIcon());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,24 +29,22 @@ public abstract class SwitchBarResourceSettingsFragment extends ResourceSettings
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
super.onActivityCreated(savedInstanceState);
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
|
||||||
AbstractSettingsActivity activity = (AbstractSettingsActivity) getActivity();
|
// switchBar = activity.getSwitchBar();
|
||||||
|
// switchBar.show();
|
||||||
switchBar = activity.getSwitchBar();
|
// switchCompat = switchBar.getSwitch();
|
||||||
switchBar.show();
|
|
||||||
switchCompat = switchBar.getSwitch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
switchBar.hide();
|
// switchBar.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (!listenerSetup) {
|
if (!listenerSetup) {
|
||||||
switchBar.addOnSwitchChangeListener(this);
|
// switchBar.addOnSwitchChangeListener(this);
|
||||||
listenerSetup = true;
|
listenerSetup = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +52,7 @@ public abstract class SwitchBarResourceSettingsFragment extends ResourceSettings
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
if (listenerSetup) {
|
if (listenerSetup) {
|
||||||
switchBar.removeOnSwitchChangeListener(this);
|
// switchBar.removeOnSwitchChangeListener(this);
|
||||||
listenerSetup = false;
|
listenerSetup = false;
|
||||||
}
|
}
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
package org.microg.tools.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
|
|
||||||
import androidx.core.graphics.drawable.DrawableCompat;
|
|
||||||
import androidx.preference.PreferenceViewHolder;
|
|
||||||
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
import static android.os.Build.VERSION_CODES.LOLLIPOP;
|
|
||||||
|
|
||||||
public class TintIconPreference extends DimmableIconPreference {
|
|
||||||
|
|
||||||
public TintIconPreference(Context context) {
|
|
||||||
this(context, (AttributeSet) null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TintIconPreference(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getThemeAccentColor(Context context) {
|
|
||||||
int colorAttr;
|
|
||||||
if (SDK_INT >= LOLLIPOP) {
|
|
||||||
colorAttr = android.R.attr.colorAccent;
|
|
||||||
} else {
|
|
||||||
//Get colorAccent defined for AppCompat
|
|
||||||
colorAttr = context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName());
|
|
||||||
}
|
|
||||||
TypedValue outValue = new TypedValue();
|
|
||||||
context.getTheme().resolveAttribute(colorAttr, outValue, true);
|
|
||||||
return outValue.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
|
||||||
super.onBindViewHolder(view);
|
|
||||||
Drawable icon = getIcon();
|
|
||||||
if (icon != null) {
|
|
||||||
DrawableCompat.setTint(icon, getThemeAccentColor(getContext()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2013-2017 microG Project Team
|
||||||
|
~
|
||||||
|
~ 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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<string name="lib_name">Strumenti interfaccia utente di microG</string>
|
||||||
|
<string name="lib_license">Licenza Apache 2.0, team di microG</string>
|
||||||
|
|
||||||
|
<string name="about_version_str">Versione %1$s</string>
|
||||||
|
<string name="about_name_version_str">%1$s %2$s</string>
|
||||||
|
<string name="about_default_license">Tutti i diritti sono riservati.</string>
|
||||||
|
|
||||||
|
<string name="prefcat_setup">Configurazione</string>
|
||||||
|
|
||||||
|
<string name="self_check_title">Auto-controllo</string>
|
||||||
|
<string name="self_check_desc">Verifica se il sistema è correttamente configurato per utilizzare microG.</string>
|
||||||
|
|
||||||
|
<string name="self_check_cat_permissions">Autorizzazione concessa</string>
|
||||||
|
<string name="self_check_name_permission">Autorizzazione a %1$s:</string>
|
||||||
|
<string name="self_check_resolution_permission">Tocca qui per concedere l\'autorizzazione a %1$s. Negare l\'autorizzazione può comportare il funzionamento anomalo di altre applicazioni.</string>
|
||||||
|
|
||||||
|
<string name="about_root_title">microG UI Demo</string>
|
||||||
|
<string name="about_root_summary">Sommario</string>
|
||||||
|
<string name="about_root_version">Versione v0.1.0</string>
|
||||||
|
<string name="about_root_libraries">Librerie incluse</string>
|
||||||
|
|
||||||
|
<string name="about_android_support_v4">v4 Support Library</string>
|
||||||
|
<string name="about_android_support_v7_appcompat">v7 appcompat Support Library</string>
|
||||||
|
<string name="about_android_support_v7_preference">v7 preference Support Library</string>
|
||||||
|
<string name="about_android_support_license">Licenza Apache 2.0, The Android Open Source Project</string>
|
||||||
|
</resources>
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.appinvite;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||||
|
import com.google.android.gms.common.internal.GetServiceRequest;
|
||||||
|
import com.google.android.gms.common.internal.IGmsCallbacks;
|
||||||
|
|
||||||
|
import org.microg.gms.BaseService;
|
||||||
|
import org.microg.gms.common.GmsService;
|
||||||
|
import org.microg.gms.common.PackageUtils;
|
||||||
|
|
||||||
|
import org.microg.gms.appinvite.AppInviteServiceImpl;
|
||||||
|
|
||||||
|
public class AppInviteService extends BaseService {
|
||||||
|
private static final String TAG = "GmsAppInviteService";
|
||||||
|
|
||||||
|
public AppInviteService() {
|
||||||
|
super("GmsAppInviteSvc", GmsService.APP_INVITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
|
||||||
|
PackageUtils.getAndCheckCallingPackage(this, request.packageName);
|
||||||
|
Log.d(TAG, "callb: " + callback + " ; req: " + request + " ; serv: " + service);
|
||||||
|
|
||||||
|
callback.onPostInitComplete(0, new AppInviteServiceImpl(this, request.packageName, request.extras), null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.appinvite;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
|
||||||
|
import com.google.android.gms.dynamic.IObjectWrapper;
|
||||||
|
import com.google.android.gms.dynamic.ObjectWrapper;
|
||||||
|
|
||||||
|
import com.google.android.gms.appinvite.internal.IAppInviteService;
|
||||||
|
import com.google.android.gms.appinvite.internal.IAppInviteCallbacks;
|
||||||
|
|
||||||
|
|
||||||
|
public class AppInviteServiceImpl extends IAppInviteService.Stub {
|
||||||
|
private static final String TAG = "GmsAppInviteServImpl";
|
||||||
|
|
||||||
|
public AppInviteServiceImpl(Context context, String packageName, Bundle extras) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateInvitationOnInstall(IAppInviteCallbacks callback, String invitationId) throws RemoteException {
|
||||||
|
callback.onStatus(Status.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertInvitation(IAppInviteCallbacks callback, String invitationId) throws RemoteException {
|
||||||
|
callback.onStatus(Status.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getInvitation(IAppInviteCallbacks callback) throws RemoteException {
|
||||||
|
callback.onStatusIntent(new Status(Activity.RESULT_CANCELED), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||||
|
if (super.onTransact(code, data, reply, flags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.checkin;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
public class CheckinPrefs implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
public static final String PREF_ENABLE_CHECKIN = "checkin_enable_service";
|
||||||
|
private static CheckinPrefs INSTANCE;
|
||||||
|
|
||||||
|
public static CheckinPrefs get(Context context) {
|
||||||
|
if (INSTANCE == null) {
|
||||||
|
if (context == null) return new CheckinPrefs(null);
|
||||||
|
INSTANCE = new CheckinPrefs(context.getApplicationContext());
|
||||||
|
}
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SharedPreferences preferences;
|
||||||
|
private boolean checkinEnabled = false;
|
||||||
|
|
||||||
|
private CheckinPrefs(Context context) {
|
||||||
|
if (context != null) {
|
||||||
|
preferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
|
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update() {
|
||||||
|
checkinEnabled = preferences.getBoolean(PREF_ENABLE_CHECKIN, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return checkinEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setEnabled(Context context, boolean newStatus) {
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(PREF_ENABLE_CHECKIN, newStatus).commit();
|
||||||
|
if (newStatus) {
|
||||||
|
context.sendOrderedBroadcast(new Intent(context, TriggerReceiver.class), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,6 @@ import static org.microg.gms.checkin.CheckinService.EXTRA_FORCE_CHECKIN;
|
||||||
|
|
||||||
public class TriggerReceiver extends WakefulBroadcastReceiver {
|
public class TriggerReceiver extends WakefulBroadcastReceiver {
|
||||||
private static final String TAG = "GmsCheckinTrigger";
|
private static final String TAG = "GmsCheckinTrigger";
|
||||||
public static final String PREF_ENABLE_CHECKIN = "checkin_enable_service";
|
|
||||||
private static final long REGULAR_CHECKIN_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours
|
private static final long REGULAR_CHECKIN_INTERVAL = 12 * 60 * 60 * 1000; // 12 hours
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -40,7 +39,7 @@ public class TriggerReceiver extends WakefulBroadcastReceiver {
|
||||||
boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction());
|
boolean force = "android.provider.Telephony.SECRET_CODE".equals(intent.getAction());
|
||||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
|
||||||
if (PreferenceManager.getDefaultSharedPreferences(context).getBoolean(PREF_ENABLE_CHECKIN, false) || force) {
|
if (CheckinPrefs.get(context).isEnabled() || force) {
|
||||||
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()) &&
|
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()) &&
|
||||||
LastCheckinInfo.read(context).lastCheckin > System.currentTimeMillis() - REGULAR_CHECKIN_INTERVAL) {
|
LastCheckinInfo.read(context).lastCheckin > System.currentTimeMillis() - REGULAR_CHECKIN_INTERVAL) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.firebase.dynamiclinks;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||||
|
import com.google.android.gms.common.internal.GetServiceRequest;
|
||||||
|
import com.google.android.gms.common.internal.IGmsCallbacks;
|
||||||
|
|
||||||
|
import org.microg.gms.BaseService;
|
||||||
|
import org.microg.gms.common.GmsService;
|
||||||
|
import org.microg.gms.common.PackageUtils;
|
||||||
|
|
||||||
|
import org.microg.gms.firebase.dynamiclinks.DynamicLinksServiceImpl;
|
||||||
|
|
||||||
|
public class DynamicLinksService extends BaseService {
|
||||||
|
private static final String TAG = "GmsDynamicLinksService";
|
||||||
|
|
||||||
|
public DynamicLinksService() {
|
||||||
|
super("GmsDynamicLinksSvc", GmsService.DYNAMIC_LINKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleServiceRequest(IGmsCallbacks callback, GetServiceRequest request, GmsService service) throws RemoteException {
|
||||||
|
PackageUtils.getAndCheckCallingPackage(this, request.packageName);
|
||||||
|
Log.d(TAG, "callb: " + callback + " ; req: " + request + " ; serv: " + service);
|
||||||
|
|
||||||
|
callback.onPostInitComplete(0, new DynamicLinksServiceImpl(this, request.packageName, request.extras), null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 e Foundation
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.firebase.dynamiclinks;
|
||||||
|
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.Status;
|
||||||
|
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||||
|
|
||||||
|
import com.google.firebase.dynamiclinks.internal.IDynamicLinksService;
|
||||||
|
import com.google.firebase.dynamiclinks.internal.IDynamicLinksCallbacks;
|
||||||
|
import com.google.firebase.dynamiclinks.internal.DynamicLinkData;
|
||||||
|
import com.google.firebase.dynamiclinks.internal.ShortDynamicLink;
|
||||||
|
|
||||||
|
|
||||||
|
public class DynamicLinksServiceImpl extends IDynamicLinksService.Stub {
|
||||||
|
private static final String TAG = "GmsDynamicLinksServImpl";
|
||||||
|
|
||||||
|
public DynamicLinksServiceImpl(Context context, String packageName, Bundle extras) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getInitialLink(IDynamicLinksCallbacks callback, String var2) throws RemoteException {
|
||||||
|
callback.onStatusDynamicLinkData(Status.SUCCESS, new DynamicLinkData());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void func2(IDynamicLinksCallbacks callback, Bundle var2) throws RemoteException {
|
||||||
|
Log.d(TAG, "func2: " + callback + ", " + var2);
|
||||||
|
callback.onStatusShortDynamicLink(Status.SUCCESS, new ShortDynamicLink());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
|
||||||
|
if (super.onTransact(code, data, reply, flags)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "onTransact [unknown]: " + code + ", " + data + ", " + flags);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
package org.microg.gms.gcm;
|
package org.microg.gms.gcm;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
@ -114,7 +115,7 @@ public class GcmPrefs implements SharedPreferences.OnSharedPreferenceChangeListe
|
||||||
|
|
||||||
public int getHeartbeatMsFor(String pref, boolean rawRoaming) {
|
public int getHeartbeatMsFor(String pref, boolean rawRoaming) {
|
||||||
if (PREF_NETWORK_ROAMING.equals(pref) && (rawRoaming || networkRoaming != 0)) {
|
if (PREF_NETWORK_ROAMING.equals(pref) && (rawRoaming || networkRoaming != 0)) {
|
||||||
return networkRoaming * 6000;
|
return networkRoaming * 60000;
|
||||||
} else if (PREF_NETWORK_MOBILE.equals(pref)) {
|
} else if (PREF_NETWORK_MOBILE.equals(pref)) {
|
||||||
if (networkMobile != 0) return networkMobile * 60000;
|
if (networkMobile != 0) return networkMobile * 60000;
|
||||||
else return learntMobile;
|
else return learntMobile;
|
||||||
|
@ -197,6 +198,15 @@ public class GcmPrefs implements SharedPreferences.OnSharedPreferenceChangeListe
|
||||||
return isEnabled() && info != null && getHeartbeatMsFor(info) >= 0;
|
return isEnabled() && info != null && getHeartbeatMsFor(info) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setEnabled(Context context, boolean newStatus) {
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(GcmPrefs.PREF_ENABLE_GCM, newStatus).commit();
|
||||||
|
if (!newStatus) {
|
||||||
|
McsService.stop(context);
|
||||||
|
} else {
|
||||||
|
context.sendBroadcast(new Intent(TriggerReceiver.FORCE_TRY_RECONNECT, null, context, TriggerReceiver.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isGcmLogEnabled() {
|
public boolean isGcmLogEnabled() {
|
||||||
return gcmLogEnabled;
|
return gcmLogEnabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2017 microG Project Team
|
|
||||||
*
|
|
||||||
* 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 org.microg.gms.ui;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import com.mgoogle.android.gms.R;
|
|
||||||
|
|
||||||
import org.microg.tools.ui.AbstractSettingsActivity;
|
|
||||||
import org.microg.tools.ui.SwitchBarResourceSettingsFragment;
|
|
||||||
|
|
||||||
import static org.microg.gms.checkin.TriggerReceiver.PREF_ENABLE_CHECKIN;
|
|
||||||
|
|
||||||
public class CheckinFragment extends SwitchBarResourceSettingsFragment {
|
|
||||||
|
|
||||||
public CheckinFragment() {
|
|
||||||
preferencesResource = R.xml.preferences_checkin;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Bundle savedInstanceState) {
|
|
||||||
super.onActivityCreated(savedInstanceState);
|
|
||||||
|
|
||||||
switchBar.setChecked(PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean(PREF_ENABLE_CHECKIN, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSwitchBarChanged(boolean isChecked) {
|
|
||||||
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putBoolean(PREF_ENABLE_CHECKIN, isChecked).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static class AsActivity extends AbstractSettingsActivity {
|
|
||||||
public AsActivity() {
|
|
||||||
showHomeAsUp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Fragment getFragment() {
|
|
||||||
return new CheckinFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -94,15 +94,4 @@ public class GcmAdvancedFragment extends ResourceSettingsFragment {
|
||||||
}
|
}
|
||||||
return (heartbeatMs / 60000) + " minutes";
|
return (heartbeatMs / 60000) + " minutes";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AsActivity extends AbstractSettingsActivity {
|
|
||||||
public AsActivity() {
|
|
||||||
showHomeAsUp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Fragment getFragment() {
|
|
||||||
return new GcmAdvancedFragment();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2013-2017 microG Project Team
|
||||||
|
*
|
||||||
|
* 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 org.microg.gms.ui;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.google.android.gms.R;
|
||||||
|
|
||||||
|
//import org.microg.nlp.Preferences;
|
||||||
|
import org.microg.tools.ui.AbstractDashboardActivity;
|
||||||
|
|
||||||
|
public class SettingsDashboardActivity extends AbstractDashboardActivity {
|
||||||
|
|
||||||
|
public SettingsDashboardActivity() {
|
||||||
|
preferencesResource = R.xml.preferences_start;
|
||||||
|
addCondition(Conditions.GCM_BATTERY_OPTIMIZATIONS);
|
||||||
|
addCondition(Conditions.PERMISSIONS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Fragment getFragment() {
|
||||||
|
return new SettingsFragment();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package org.microg.gms.ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
|
|
||||||
|
import com.google.android.gms.R;
|
||||||
|
|
||||||
|
import org.microg.gms.checkin.CheckinPrefs;
|
||||||
|
import org.microg.gms.gcm.GcmDatabase;
|
||||||
|
import org.microg.gms.gcm.GcmPrefs;
|
||||||
|
import org.microg.gms.snet.SafetyNetPrefs;
|
||||||
|
import org.microg.tools.ui.ResourceSettingsFragment;
|
||||||
|
|
||||||
|
public class SettingsFragment extends ResourceSettingsFragment {
|
||||||
|
|
||||||
|
public static final String PREF_ABOUT = "pref_about";
|
||||||
|
public static final String PREF_GCM = "pref_gcm";
|
||||||
|
public static final String PREF_SNET = "pref_snet";
|
||||||
|
public static final String PREF_UNIFIEDNLP = "pref_unifiednlp";
|
||||||
|
public static final String PREF_CHECKIN = "pref_checkin";
|
||||||
|
|
||||||
|
public SettingsFragment() {
|
||||||
|
preferencesResource = R.xml.preferences_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
|
||||||
|
super.onCreatePreferences(savedInstanceState, rootKey);
|
||||||
|
updateDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
updateDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDetails() {
|
||||||
|
findPreference(PREF_ABOUT).setSummary(getString(R.string.about_version_str, AboutFragment.getSelfVersion(getContext())));
|
||||||
|
findPreference(PREF_ABOUT).setOnPreferenceClickListener(preference -> {
|
||||||
|
NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openAbout);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (GcmPrefs.get(getContext()).isEnabled()) {
|
||||||
|
GcmDatabase database = new GcmDatabase(getContext());
|
||||||
|
int regCount = database.getRegistrationList().size();
|
||||||
|
database.close();
|
||||||
|
findPreference(PREF_GCM).setSummary(getString(R.string.service_status_enabled_short) + " - " + getResources().getQuantityString(R.plurals.gcm_registered_apps_counter, regCount, regCount));
|
||||||
|
} else {
|
||||||
|
findPreference(PREF_GCM).setSummary(R.string.service_status_disabled_short);
|
||||||
|
}
|
||||||
|
findPreference(PREF_GCM).setOnPreferenceClickListener(preference -> {
|
||||||
|
NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openGcmSettings);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (SafetyNetPrefs.get(getContext()).isEnabled()) {
|
||||||
|
String snet_info = "";
|
||||||
|
|
||||||
|
if (SafetyNetPrefs.get(getContext()).isOfficial()) {
|
||||||
|
snet_info = getString(R.string.pref_snet_status_official_info);
|
||||||
|
} else if (SafetyNetPrefs.get(getContext()).isSelfSigned()) {
|
||||||
|
snet_info = getString(R.string.pref_snet_status_self_signed_info);
|
||||||
|
} else if (SafetyNetPrefs.get(getContext()).isThirdParty()) {
|
||||||
|
snet_info = getString(R.string.pref_snet_status_third_party_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
findPreference(PREF_SNET).setSummary(getString(R.string.service_status_enabled_short));
|
||||||
|
} else {
|
||||||
|
findPreference(PREF_SNET).setSummary(R.string.service_status_disabled_short);
|
||||||
|
}
|
||||||
|
findPreference(PREF_SNET).setOnPreferenceClickListener(preference -> {
|
||||||
|
NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openSafetyNetSettings);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Preferences unifiedNlPrefs = new Preferences(getContext());
|
||||||
|
// int backendCount = TextUtils.isEmpty(unifiedNlPrefs.getLocationBackends()) ? 0 :
|
||||||
|
// Preferences.splitBackendString(unifiedNlPrefs.getLocationBackends()).length;
|
||||||
|
// backendCount += TextUtils.isEmpty(unifiedNlPrefs.getGeocoderBackends()) ? 0 :
|
||||||
|
// Preferences.splitBackendString(unifiedNlPrefs.getGeocoderBackends()).length;
|
||||||
|
// findPreference(PREF_UNIFIEDNLP).setSummary(getResources().getQuantityString(R.plurals.pref_unifiednlp_summary, backendCount, backendCount));
|
||||||
|
findPreference(PREF_UNIFIEDNLP).setOnPreferenceClickListener(preference -> {
|
||||||
|
NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openUnifiedNlpSettings);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
boolean checkinEnabled = CheckinPrefs.get(getContext()).isEnabled();
|
||||||
|
findPreference(PREF_CHECKIN).setSummary(checkinEnabled ? R.string.service_status_enabled_short : R.string.service_status_disabled_short);
|
||||||
|
findPreference(PREF_CHECKIN).setOnPreferenceClickListener(preference -> {
|
||||||
|
NavHostFragment.findNavController(SettingsFragment.this).navigate(R.id.openCheckinSettings);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
package org.microg.gms.ui;
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
|
|
||||||
import org.microg.tools.ui.AbstractSettingsActivity;
|
|
||||||
|
|
||||||
public class UnifiedBackendDetailsActivity extends AbstractSettingsActivity {
|
|
||||||
public UnifiedBackendDetailsActivity() {
|
|
||||||
showHomeAsUp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Fragment getFragment() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package org.microg.gms.ui;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentActivity;
|
|
||||||
|
|
||||||
import org.microg.tools.ui.AbstractSettingsActivity;
|
|
||||||
|
|
||||||
public class UnifiedBackendListActivity extends AppCompatActivity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
try {
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.w("GmsCoreSettingUi", e);
|
|
||||||
}
|
|
||||||
getSupportFragmentManager().beginTransaction().add(null, null).commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
super.onBackPressed();
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.provision
|
||||||
|
|
||||||
|
import android.app.Service
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.lifecycle.LifecycleService
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import org.microg.gms.checkin.CheckinPrefs
|
||||||
|
import org.microg.gms.gcm.GcmPrefs
|
||||||
|
import org.microg.gms.snet.SafetyNetPrefs
|
||||||
|
|
||||||
|
class ProvisionService : LifecycleService() {
|
||||||
|
private fun Bundle.getBooleanOrNull(key: String): Boolean? {
|
||||||
|
return if (containsKey(key)) getBoolean(key) else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
super.onStartCommand(intent, flags, startId)
|
||||||
|
lifecycleScope.launchWhenStarted {
|
||||||
|
intent?.extras?.let {
|
||||||
|
val s = it.keySet().map { key -> "$key = ${it[key]}" }.joinToString(", ")
|
||||||
|
Log.d(TAG, "Provisioning: $s")
|
||||||
|
}
|
||||||
|
|
||||||
|
intent?.extras?.getBooleanOrNull("checkin_enabled")?.let { CheckinPrefs.setEnabled(this@ProvisionService, it) }
|
||||||
|
intent?.extras?.getBooleanOrNull("gcm_enabled")?.let { GcmPrefs.setEnabled(this@ProvisionService, it) }
|
||||||
|
intent?.extras?.getBooleanOrNull("safetynet_enabled")?.let { SafetyNetPrefs.get(this@ProvisionService).isEnabled = it }
|
||||||
|
// What else?
|
||||||
|
|
||||||
|
delay(2 * 1000) // Wait 2 seconds to give provisioning some extra time
|
||||||
|
stopSelfResult(startId)
|
||||||
|
}
|
||||||
|
return Service.START_NOT_STICKY
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "GmsProvision"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.DisplayMetrics
|
||||||
|
import android.widget.ImageView
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceViewHolder
|
||||||
|
|
||||||
|
class AppIconPreference(context: Context) : Preference(context) {
|
||||||
|
override fun onBindViewHolder(holder: PreferenceViewHolder?) {
|
||||||
|
super.onBindViewHolder(holder)
|
||||||
|
val icon = holder?.findViewById(android.R.id.icon)
|
||||||
|
if (icon is ImageView) {
|
||||||
|
icon.adjustViewBounds = true
|
||||||
|
icon.scaleType = ImageView.ScaleType.CENTER_INSIDE
|
||||||
|
icon.maxHeight = (32.0 * context.resources.displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT).toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import com.google.android.gms.databinding.DeviceRegistrationFragmentBinding
|
||||||
|
import org.microg.gms.checkin.CheckinPrefs
|
||||||
|
|
||||||
|
class DeviceRegistrationFragment : Fragment(R.layout.device_registration_fragment) {
|
||||||
|
private lateinit var binding: DeviceRegistrationFragmentBinding
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
binding = DeviceRegistrationFragmentBinding.inflate(inflater, container, false)
|
||||||
|
binding.switchBarCallback = object : PreferenceSwitchBarCallback {
|
||||||
|
override fun onChecked(newStatus: Boolean) {
|
||||||
|
CheckinPrefs.setEnabled(context, newStatus)
|
||||||
|
binding.checkinEnabled = newStatus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
binding.checkinEnabled = CheckinPrefs.get(context).isEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceCategory
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import org.microg.gms.checkin.CheckinPrefs
|
||||||
|
import org.microg.gms.checkin.LastCheckinInfo
|
||||||
|
|
||||||
|
class DeviceRegistrationPreferencesFragment : PreferenceFragmentCompat() {
|
||||||
|
private lateinit var statusCategory: PreferenceCategory
|
||||||
|
private lateinit var status: Preference
|
||||||
|
private val handler = Handler()
|
||||||
|
private val updateRunnable = Runnable { updateStatus() }
|
||||||
|
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
addPreferencesFromResource(R.xml.preferences_device_registration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindPreferences() {
|
||||||
|
statusCategory = preferenceScreen.findPreference("prefcat_device_registration_status") ?: statusCategory
|
||||||
|
status = preferenceScreen.findPreference("pref_device_registration_status") ?: status
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
updateStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
handler.removeCallbacks(updateRunnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateStatus() {
|
||||||
|
handler.postDelayed(updateRunnable, UPDATE_INTERVAL)
|
||||||
|
statusCategory.isVisible = CheckinPrefs.get(context).isEnabled
|
||||||
|
val checkinInfo = LastCheckinInfo.read(requireContext())
|
||||||
|
status.summary = if (checkinInfo.lastCheckin > 0) {
|
||||||
|
getString(R.string.checkin_last_registration, DateUtils.getRelativeTimeSpanString(checkinInfo.lastCheckin, System.currentTimeMillis(), 0))
|
||||||
|
} else {
|
||||||
|
getString(R.string.checkin_not_registered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val UPDATE_INTERVAL = 1000L
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
interface PreferenceSwitchBarCallback {
|
||||||
|
fun onChecked(newStatus: Boolean)
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceCategory
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.microg.gms.gcm.GcmDatabase
|
||||||
|
|
||||||
|
class PushNotificationAllAppsFragment : PreferenceFragmentCompat() {
|
||||||
|
private lateinit var database: GcmDatabase
|
||||||
|
private lateinit var registered: PreferenceCategory
|
||||||
|
private lateinit var unregistered: PreferenceCategory
|
||||||
|
private lateinit var registeredNone: Preference
|
||||||
|
private lateinit var unregisteredNone: Preference
|
||||||
|
private lateinit var progress: Preference
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
database = GcmDatabase(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
updateContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
database.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
addPreferencesFromResource(R.xml.preferences_push_notifications_all_apps)
|
||||||
|
registered = preferenceScreen.findPreference("prefcat_push_apps_registered") ?: registered
|
||||||
|
unregistered = preferenceScreen.findPreference("prefcat_push_apps_unregistered") ?: unregistered
|
||||||
|
registeredNone = preferenceScreen.findPreference("pref_push_apps_registered_none") ?: registeredNone
|
||||||
|
unregisteredNone = preferenceScreen.findPreference("pref_push_apps_unregistered_none") ?: unregisteredNone
|
||||||
|
progress = preferenceScreen.findPreference("pref_push_apps_all_progress") ?: progress
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateContent() {
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
val context = requireContext()
|
||||||
|
val apps = withContext(Dispatchers.IO) {
|
||||||
|
val res = database.appList.map { app ->
|
||||||
|
try {
|
||||||
|
app to context.packageManager.getApplicationInfo(app.packageName, 0)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
app to null
|
||||||
|
}
|
||||||
|
}.map { (app, applicationInfo) ->
|
||||||
|
val pref = AppIconPreference(context)
|
||||||
|
pref.title = applicationInfo?.loadLabel(context.packageManager) ?: app.packageName
|
||||||
|
pref.summary = when {
|
||||||
|
app.lastMessageTimestamp > 0 -> getString(R.string.gcm_last_message_at, DateUtils.getRelativeTimeSpanString(app.lastMessageTimestamp))
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
pref.icon = applicationInfo?.loadIcon(context.packageManager)
|
||||||
|
?: AppCompatResources.getDrawable(context, android.R.mipmap.sym_def_app_icon)
|
||||||
|
pref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||||
|
findNavController().navigate(R.id.openGcmAppDetailsFromAll, bundleOf(
|
||||||
|
"package" to app.packageName
|
||||||
|
))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
pref.key = "pref_push_app_" + app.packageName
|
||||||
|
pref to (database.getRegistrationsByApp(app.packageName))
|
||||||
|
}.sortedBy {
|
||||||
|
it.first.title.toString().toLowerCase()
|
||||||
|
}.mapIndexed { idx, pair ->
|
||||||
|
pair.first.order = idx
|
||||||
|
pair
|
||||||
|
}
|
||||||
|
database.close()
|
||||||
|
res
|
||||||
|
}
|
||||||
|
registered.removeAll()
|
||||||
|
registered.isVisible = true
|
||||||
|
unregistered.removeAll()
|
||||||
|
unregistered.isVisible = true
|
||||||
|
|
||||||
|
var hadRegistered = false
|
||||||
|
var hadUnregistered = false
|
||||||
|
|
||||||
|
for (pair in apps) {
|
||||||
|
if (pair.second.isEmpty()) {
|
||||||
|
unregistered.addPreference(pair.first)
|
||||||
|
hadUnregistered = true
|
||||||
|
} else {
|
||||||
|
registered.addPreference(pair.first)
|
||||||
|
hadRegistered = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registeredNone.isVisible = !hadRegistered
|
||||||
|
unregisteredNone.isVisible = !hadUnregistered
|
||||||
|
if (!hadRegistered) registered.addPreference(registeredNone)
|
||||||
|
if (!hadUnregistered) unregistered.addPreference(unregisteredNone)
|
||||||
|
progress.isVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.appcompat.content.res.AppCompatResources
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.findFragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import com.google.android.gms.databinding.PushNotificationAppFragmentBinding
|
||||||
|
|
||||||
|
|
||||||
|
class PushNotificationAppFragment : Fragment(R.layout.push_notification_fragment) {
|
||||||
|
lateinit var binding: PushNotificationAppFragmentBinding
|
||||||
|
val packageName: String?
|
||||||
|
get() = arguments?.getString("package")
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
binding = PushNotificationAppFragmentBinding.inflate(inflater, container, false)
|
||||||
|
binding.callbacks = object : PushNotificationAppFragmentCallbacks {
|
||||||
|
override fun onAppClicked() {
|
||||||
|
val intent = Intent()
|
||||||
|
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
||||||
|
val uri: Uri = Uri.fromParts("package", packageName, null)
|
||||||
|
intent.data = uri
|
||||||
|
context!!.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
childFragmentManager.findFragmentById(R.id.sub_preferences)?.arguments = arguments
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
val pm = requireContext().packageManager
|
||||||
|
val applicationInfo = packageName?.let { pm.getApplicationInfo(it, 0) }
|
||||||
|
binding.appName = applicationInfo?.loadLabel(pm)?.toString() ?: packageName
|
||||||
|
binding.appIcon = applicationInfo?.loadIcon(pm)
|
||||||
|
?: AppCompatResources.getDrawable(requireContext(), android.R.mipmap.sym_def_app_icon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PushNotificationAppFragmentCallbacks {
|
||||||
|
fun onAppClicked()
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceCategory
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import androidx.preference.TwoStatePreference
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.microg.gms.gcm.GcmDatabase
|
||||||
|
import org.microg.gms.gcm.PushRegisterManager
|
||||||
|
|
||||||
|
class PushNotificationAppPreferencesFragment : PreferenceFragmentCompat() {
|
||||||
|
private lateinit var wakeForDelivery: TwoStatePreference
|
||||||
|
private lateinit var allowRegister: TwoStatePreference
|
||||||
|
private lateinit var status: Preference
|
||||||
|
private lateinit var unregister: Preference
|
||||||
|
private lateinit var unregisterCat: PreferenceCategory
|
||||||
|
|
||||||
|
private lateinit var database: GcmDatabase
|
||||||
|
private val packageName: String?
|
||||||
|
get() = arguments?.getString("package")
|
||||||
|
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
addPreferencesFromResource(R.xml.preferences_push_notifications_app)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
database = GcmDatabase(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindPreferences() {
|
||||||
|
wakeForDelivery = preferenceScreen.findPreference("pref_push_app_wake_for_delivery") ?: wakeForDelivery
|
||||||
|
allowRegister = preferenceScreen.findPreference("pref_push_app_allow_register") ?: allowRegister
|
||||||
|
unregister = preferenceScreen.findPreference("pref_push_app_unregister") ?: unregister
|
||||||
|
unregisterCat = preferenceScreen.findPreference("prefcat_push_app_unregister") ?: unregisterCat
|
||||||
|
status = preferenceScreen.findPreference("pref_push_app_status") ?: status
|
||||||
|
wakeForDelivery.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
|
||||||
|
database.setAppWakeForDelivery(packageName, newValue as Boolean)
|
||||||
|
database.close()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
allowRegister.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
|
||||||
|
val enabled = newValue as? Boolean ?: return@OnPreferenceChangeListener false
|
||||||
|
if (!enabled) {
|
||||||
|
val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList()
|
||||||
|
if (registrations.isNotEmpty()) {
|
||||||
|
showUnregisterConfirm(R.string.gcm_unregister_after_deny_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
database.setAppAllowRegister(packageName, enabled)
|
||||||
|
database.close()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
unregister.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||||
|
showUnregisterConfirm(R.string.gcm_unregister_confirm_message)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun showUnregisterConfirm(unregisterConfirmDesc: Int) {
|
||||||
|
val pm = requireContext().packageManager
|
||||||
|
val applicationInfo = packageName?.let { pm.getApplicationInfo(it, 0) }
|
||||||
|
AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle(getString(R.string.gcm_unregister_confirm_title, applicationInfo?.loadLabel(pm)
|
||||||
|
?: packageName))
|
||||||
|
.setMessage(unregisterConfirmDesc)
|
||||||
|
.setPositiveButton(android.R.string.yes) { _, _ -> unregister() }
|
||||||
|
.setNegativeButton(android.R.string.no) { _, _ -> }.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun unregister() {
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
for (registration in database.getRegistrationsByApp(packageName)) {
|
||||||
|
PushRegisterManager.unregister(context, registration.packageName, registration.signature, null, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateDetails()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
updateDetails()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDetails() {
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
val app = packageName?.let { database.getApp(it) }
|
||||||
|
wakeForDelivery.isChecked = app?.wakeForDelivery ?: true
|
||||||
|
allowRegister.isChecked = app?.allowRegister ?: true
|
||||||
|
val registrations = packageName?.let { database.getRegistrationsByApp(it) } ?: emptyList()
|
||||||
|
unregisterCat.isVisible = registrations.isNotEmpty()
|
||||||
|
|
||||||
|
val sb = StringBuilder()
|
||||||
|
if ((app?.totalMessageCount ?: 0L) == 0L) {
|
||||||
|
sb.append(getString(R.string.gcm_no_message_yet))
|
||||||
|
} else {
|
||||||
|
sb.append(getString(R.string.gcm_messages_counter, app?.totalMessageCount, app?.totalMessageBytes))
|
||||||
|
if (app?.lastMessageTimestamp != 0L) {
|
||||||
|
sb.append("\n").append(getString(R.string.gcm_last_message_at, DateUtils.getRelativeDateTimeString(context, app?.lastMessageTimestamp ?: 0L, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (registration in registrations) {
|
||||||
|
sb.append("\n")
|
||||||
|
if (registration.timestamp == 0L) {
|
||||||
|
sb.append(getString(R.string.gcm_registered))
|
||||||
|
} else {
|
||||||
|
sb.append(getString(R.string.gcm_registered_since, DateUtils.getRelativeDateTimeString(context, registration.timestamp, DateUtils.MINUTE_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, DateUtils.FORMAT_SHOW_TIME)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status.summary = sb.toString()
|
||||||
|
|
||||||
|
database.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
database.close()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.*
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import com.google.android.gms.databinding.PushNotificationFragmentBinding
|
||||||
|
import org.microg.gms.checkin.CheckinPrefs
|
||||||
|
import org.microg.gms.gcm.GcmPrefs
|
||||||
|
|
||||||
|
class PushNotificationFragment : Fragment(R.layout.push_notification_fragment) {
|
||||||
|
lateinit var binding: PushNotificationFragmentBinding
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
binding = PushNotificationFragmentBinding.inflate(inflater, container, false)
|
||||||
|
binding.switchBarCallback = object : PreferenceSwitchBarCallback {
|
||||||
|
override fun onChecked(newStatus: Boolean) {
|
||||||
|
GcmPrefs.setEnabled(context, newStatus)
|
||||||
|
binding.gcmEnabled = newStatus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
binding.gcmEnabled = GcmPrefs.get(context).isEnabled
|
||||||
|
binding.checkinEnabled = CheckinPrefs.get(context).isEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
setHasOptionsMenu(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced)
|
||||||
|
super.onCreateOptionsMenu(menu, inflater)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
|
MENU_ADVANCED -> {
|
||||||
|
findNavController().navigate(R.id.openGcmAdvancedSettings)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MENU_ADVANCED = Menu.FIRST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import androidx.core.os.bundleOf
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceCategory
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.microg.gms.gcm.GcmDatabase
|
||||||
|
import org.microg.gms.gcm.GcmPrefs
|
||||||
|
import org.microg.gms.gcm.McsService
|
||||||
|
|
||||||
|
class PushNotificationPreferencesFragment : PreferenceFragmentCompat() {
|
||||||
|
private lateinit var pushStatusCategory: PreferenceCategory
|
||||||
|
private lateinit var pushStatus: Preference
|
||||||
|
private lateinit var pushApps: PreferenceCategory
|
||||||
|
private lateinit var pushAppsAll: Preference
|
||||||
|
private lateinit var pushAppsNone: Preference
|
||||||
|
private lateinit var database: GcmDatabase
|
||||||
|
private val handler = Handler()
|
||||||
|
private val updateRunnable = Runnable { updateStatus() }
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
database = GcmDatabase(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
addPreferencesFromResource(R.xml.preferences_push_notifications)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindPreferences() {
|
||||||
|
pushStatusCategory = preferenceScreen.findPreference("prefcat_push_status") ?: pushStatusCategory
|
||||||
|
pushStatus = preferenceScreen.findPreference("pref_push_status") ?: pushStatus
|
||||||
|
pushApps = preferenceScreen.findPreference("prefcat_push_apps") ?: pushApps
|
||||||
|
pushAppsAll = preferenceScreen.findPreference("pref_push_apps_all") ?: pushAppsAll
|
||||||
|
pushAppsNone = preferenceScreen.findPreference("pref_push_apps_none") ?: pushAppsNone
|
||||||
|
pushAppsAll.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||||
|
findNavController().navigate(R.id.openAllGcmApps)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
updateStatus()
|
||||||
|
updateContent()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
database.close()
|
||||||
|
handler.removeCallbacks(updateRunnable)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateStatus() {
|
||||||
|
handler.postDelayed(updateRunnable, UPDATE_INTERVAL)
|
||||||
|
pushStatusCategory.isVisible = GcmPrefs.get(context).isEnabled
|
||||||
|
pushStatus.summary = if (McsService.isConnected()) {
|
||||||
|
getString(R.string.gcm_network_state_connected, DateUtils.getRelativeTimeSpanString(McsService.getStartTimestamp(), System.currentTimeMillis(), 0))
|
||||||
|
} else {
|
||||||
|
getString(R.string.gcm_network_state_disconnected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateContent() {
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
val context = requireContext()
|
||||||
|
val (apps, showAll) = withContext(Dispatchers.IO) {
|
||||||
|
val apps = database.appList.sortedByDescending { it.lastMessageTimestamp }
|
||||||
|
val res = apps.map { app ->
|
||||||
|
try {
|
||||||
|
app to context.packageManager.getApplicationInfo(app.packageName, 0)
|
||||||
|
} catch (ignored: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}.filterNotNull().take(3).mapIndexed { idx, (app, applicationInfo) ->
|
||||||
|
val pref = AppIconPreference(context)
|
||||||
|
pref.order = idx
|
||||||
|
pref.title = applicationInfo.loadLabel(context.packageManager)
|
||||||
|
pref.icon = applicationInfo.loadIcon(context.packageManager)
|
||||||
|
pref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||||
|
findNavController().navigate(R.id.openGcmAppDetails, bundleOf(
|
||||||
|
"package" to app.packageName
|
||||||
|
))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
pref.key = "pref_push_app_" + app.packageName
|
||||||
|
pref
|
||||||
|
}.let { it to (it.size < apps.size) }
|
||||||
|
database.close()
|
||||||
|
res
|
||||||
|
}
|
||||||
|
pushAppsAll.isVisible = showAll
|
||||||
|
pushApps.removeAll()
|
||||||
|
for (app in apps) {
|
||||||
|
pushApps.addPreference(app)
|
||||||
|
}
|
||||||
|
if (showAll) {
|
||||||
|
pushApps.addPreference(pushAppsAll)
|
||||||
|
} else if (apps.isEmpty()) {
|
||||||
|
pushApps.addPreference(pushAppsNone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val UPDATE_INTERVAL = 1000L
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.*
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.google.android.gms.R
|
||||||
|
import com.google.android.gms.databinding.SafetyNetFragmentBinding
|
||||||
|
import org.microg.gms.checkin.CheckinPrefs
|
||||||
|
import org.microg.gms.snet.SafetyNetPrefs
|
||||||
|
|
||||||
|
class SafetyNetFragment : Fragment(R.layout.safety_net_fragment) {
|
||||||
|
|
||||||
|
private lateinit var binding: SafetyNetFragmentBinding
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
binding = SafetyNetFragmentBinding.inflate(inflater, container, false)
|
||||||
|
binding.switchBarCallback = object : PreferenceSwitchBarCallback {
|
||||||
|
override fun onChecked(newStatus: Boolean) {
|
||||||
|
SafetyNetPrefs.get(requireContext()).isEnabled = newStatus
|
||||||
|
binding.safetynetEnabled = newStatus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
binding.checkinEnabled = CheckinPrefs.get(requireContext()).isEnabled
|
||||||
|
binding.safetynetEnabled = SafetyNetPrefs.get(requireContext()).isEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
setHasOptionsMenu(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
|
menu.add(0, MENU_ADVANCED, 0, R.string.menu_advanced)
|
||||||
|
super.onCreateOptionsMenu(menu, inflater)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
|
return when (item.itemId) {
|
||||||
|
MENU_ADVANCED -> {
|
||||||
|
findNavController().navigate(R.id.openSafetyNetAdvancedSettings)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> super.onOptionsItemSelected(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MENU_ADVANCED = Menu.FIRST
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.microg.gms.ui
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import com.google.android.gms.R
|
||||||
|
|
||||||
|
class SafetyNetPreferencesFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
|
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||||
|
addPreferencesFromResource(R.xml.preferences_safetynet)
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 169 B |
Binary file not shown.
Before Width: | Height: | Size: 195 B |
Binary file not shown.
Before Width: | Height: | Size: 328 B |
Binary file not shown.
Before Width: | Height: | Size: 428 B |
Binary file not shown.
Before Width: | Height: | Size: 586 B |
|
@ -2,6 +2,7 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorAccent"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
|
|
||||||
|
@ -10,4 +11,4 @@
|
||||||
<path
|
<path
|
||||||
android:fillColor="#ff000000"
|
android:fillColor="#ff000000"
|
||||||
android:pathData="M15,12 C17.21,12,19,10.21,19,8 S17.21,4,15,4 S11,5.79,11,8 S12.79,12,15,12 Z M6,10 L6,7 L4,7 L4,10 L1,10 L1,12 L4,12 L4,15 L6,15 L6,12 L9,12 L9,10 L6,10 Z M15,14 C12.33,14,7,15.34,7,18 L7,20 L23,20 L23,18 C23,15.34,17.67,14,15,14 Z" />
|
android:pathData="M15,12 C17.21,12,19,10.21,19,8 S17.21,4,15,4 S11,5.79,11,8 S12.79,12,15,12 Z M6,10 L6,7 L4,7 L4,10 L1,10 L1,12 L4,12 L4,15 L6,15 L6,12 L9,12 L9,10 L6,10 Z M15,14 C12.33,14,7,15.34,7,18 L7,20 L23,20 L23,18 C23,15.34,17.67,14,15,14 Z" />
|
||||||
</vector>
|
</vector>
|
|
@ -1,11 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportHeight="24"
|
android:tint="?attr/colorAccent"
|
||||||
android:viewportWidth="24">
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#000000"
|
android:fillColor="#000000"
|
||||||
android:pathData="M 12 4 C 9.11 4 6.5996094 5.6392969 5.3496094 8.0292969 C 2.3396094 8.3592969 0 10.9 0 14 A 6 6 0 0 0 6 20 L 19 20 A 5 5 0 0 0 24 15 C 24 12.36 21.949609 10.219297 19.349609 10.029297 C 18.669609 6.5892969 15.64 4 12 4 z M 12 7.5 A 0.5 0.5 0 0 1 12.5 8 L 12.5 8.5390625 C 13.92 8.7790625 15 10.015 15 11.5 L 15 14.5 L 16.5 16 L 7.5 16 L 9 14.5 L 9 11.5 C 9 10.015 10.08 8.7790625 11.5 8.5390625 L 11.5 8 A 0.5 0.5 0 0 1 12 7.5 z M 11 16.5 L 13 16.5 A 1 1 0 0 1 12 17.5 A 1 1 0 0 1 11 16.5 z"/>
|
android:pathData="M 12 4 C 9.11 4 6.5996094 5.6392969 5.3496094 8.0292969 C 2.3396094 8.3592969 0 10.9 0 14 A 6 6 0 0 0 6 20 L 19 20 A 5 5 0 0 0 24 15 C 24 12.36 21.949609 10.219297 19.349609 10.029297 C 18.669609 6.5892969 15.64 4 12 4 z M 12 7.5 A 0.5 0.5 0 0 1 12.5 8 L 12.5 8.5390625 C 13.92 8.7790625 15 10.015 15 11.5 L 15 14.5 L 16.5 16 L 7.5 16 L 9 14.5 L 9 11.5 C 9 10.015 10.08 8.7790625 11.5 8.5390625 L 11.5 8 A 0.5 0.5 0 0 1 12 7.5 z M 11 16.5 L 13 16.5 A 1 1 0 0 1 12 17.5 A 1 1 0 0 1 11 16.5 z" />
|
||||||
</vector>
|
</vector>
|
|
@ -1,11 +1,12 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportHeight="24"
|
android:tint="?attr/colorAccent"
|
||||||
android:viewportWidth="24">
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#000000"
|
android:fillColor="#000000"
|
||||||
android:pathData="M10,17.25V14H3V10H10V6.75L15.25,12L10,17.25M8,2H17A2,2 0 0,1 19,4V20A2,2 0 0,1 17,22H8A2,2 0 0,1 6,20V16H8V20H17V4H8V8H6V4A2,2 0 0,1 8,2Z"/>
|
android:pathData="M10,17.25V14H3V10H10V6.75L15.25,12L10,17.25M8,2H17A2,2 0 0,1 19,4V20A2,2 0 0,1 17,22H8A2,2 0 0,1 6,20V16H8V20H17V4H8V8H6V4A2,2 0 0,1 8,2Z" />
|
||||||
</vector>
|
</vector>
|
19
play-services-core/src/main/res/drawable/ic_expand_apps.xml
Normal file
19
play-services-core/src/main/res/drawable/ic_expand_apps.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ SPDX-FileCopyrightText: 2019, The Android Open Source Project
|
||||||
|
~ SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
~ SPDX-License-Identifier: Apache-2.0
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:autoMirrored="true"
|
||||||
|
android:tint="?attr/colorAccent"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M9.71,18.71l-1.42,-1.42l5.3,-5.29l-5.3,-5.29l1.42,-1.42l6.7,6.71z" />
|
||||||
|
</vector>
|
17
play-services-core/src/main/res/drawable/ic_info_outline.xml
Normal file
17
play-services-core/src/main/res/drawable/ic_info_outline.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ SPDX-FileCopyrightText: 2019, The Android Open Source Project
|
||||||
|
~ SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
~ SPDX-License-Identifier: Apache-2.0
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorAccent"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z" />
|
||||||
|
</vector>
|
17
play-services-core/src/main/res/drawable/ic_map_marker.xml
Normal file
17
play-services-core/src/main/res/drawable/ic_map_marker.xml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ SPDX-FileCopyrightText: 2019, The Android Open Source Project
|
||||||
|
~ SPDX-FileCopyrightText: 2020, microG Project Team
|
||||||
|
~ SPDX-License-Identifier: Apache-2.0
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?attr/colorAccent"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z" />
|
||||||
|
</vector>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue