PageRenderTime 468ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/app/src/test/java/org/fdroid/fdroid/data/RepoXMLHandlerTest.java

https://gitlab.com/eighthave/fdroidclient
Java | 953 lines | 877 code | 46 blank | 30 comment | 12 complexity | ee5bb9c74885a2f655010885b3f853b2 MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Copyright (C) 2016 Blue Jay Wireless
  3. * Copyright (C) 2015 Daniel Martí <mvdan@mvdan.cc>
  4. * Copyright (C) 2014-2016 Hans-Christoph Steiner <hans@eds.org>
  5. * Copyright (C) 2014-2016 Peter Serwylo <peter@serwylo.com>
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  20. * MA 02110-1301, USA.
  21. */
  22. package org.fdroid.fdroid.data;
  23. import android.support.annotation.NonNull;
  24. import android.text.TextUtils;
  25. import android.util.Log;
  26. import org.apache.commons.io.FileUtils;
  27. import org.fdroid.fdroid.BuildConfig;
  28. import org.fdroid.fdroid.mock.MockRepo;
  29. import org.fdroid.fdroid.mock.RepoDetails;
  30. import org.junit.BeforeClass;
  31. import org.junit.Test;
  32. import org.junit.runner.RunWith;
  33. import org.robolectric.RobolectricTestRunner;
  34. import org.robolectric.annotation.Config;
  35. import org.xml.sax.InputSource;
  36. import org.xml.sax.XMLReader;
  37. import javax.xml.parsers.SAXParser;
  38. import javax.xml.parsers.SAXParserFactory;
  39. import java.io.BufferedInputStream;
  40. import java.io.File;
  41. import java.io.IOException;
  42. import java.io.InputStream;
  43. import java.util.ArrayList;
  44. import java.util.Arrays;
  45. import java.util.Collections;
  46. import java.util.HashMap;
  47. import java.util.List;
  48. import java.util.Map;
  49. import java.util.TimeZone;
  50. import static org.junit.Assert.assertEquals;
  51. import static org.junit.Assert.assertFalse;
  52. import static org.junit.Assert.assertNotNull;
  53. import static org.junit.Assert.assertNull;
  54. import static org.junit.Assert.assertTrue;
  55. import static org.junit.Assert.fail;
  56. @Config(constants = BuildConfig.class)
  57. @RunWith(RobolectricTestRunner.class)
  58. public class RepoXMLHandlerTest {
  59. private static final String TAG = "RepoXMLHandlerTest";
  60. private static final String FAKE_SIGNING_CERT = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345"; // NOCHECKSTYLE LineLength
  61. /**
  62. * Set to random time zone to make sure that the dates are properly parsed.
  63. */
  64. @BeforeClass
  65. public static void setRandomTimeZone() {
  66. TimeZone.setDefault(TimeZone.getTimeZone(String.format("GMT-%d:%02d",
  67. System.currentTimeMillis() % 12, System.currentTimeMillis() % 60)));
  68. System.out.println("TIME ZONE for this test: " + TimeZone.getDefault());
  69. }
  70. @Test
  71. public void testExtendedPerms() throws IOException {
  72. Repo expectedRepo = new Repo();
  73. expectedRepo.name = "F-Droid";
  74. expectedRepo.signingCertificate = "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"; // NOCHECKSTYLE LineLength
  75. expectedRepo.description = "This is just a test of the extended permissions attributes.";
  76. expectedRepo.timestamp = 1467169032;
  77. RepoDetails actualDetails = getFromFile("extendedPerms.xml");
  78. handlerTestSuite(expectedRepo, actualDetails, 2, 6, 14, 16);
  79. }
  80. @Test
  81. public void testObbIndex() throws IOException {
  82. writeResourceToObbDir("main.1101613.obb.main.twoversions.obb");
  83. writeResourceToObbDir("main.1101615.obb.main.twoversions.obb");
  84. writeResourceToObbDir("main.1434483388.obb.main.oldversion.obb");
  85. writeResourceToObbDir("main.1619.obb.mainpatch.current.obb");
  86. writeResourceToObbDir("patch.1619.obb.mainpatch.current.obb");
  87. RepoDetails actualDetails = getFromFile("obbIndex.xml");
  88. for (Apk indexApk : actualDetails.apks) {
  89. Apk localApk = new Apk();
  90. localApk.packageName = indexApk.packageName;
  91. localApk.versionCode = indexApk.versionCode;
  92. localApk.hashType = indexApk.hashType;
  93. App.initInstalledObbFiles(localApk);
  94. assertEquals(indexApk.obbMainFile, localApk.obbMainFile);
  95. assertEquals(indexApk.obbMainFileSha256, localApk.obbMainFileSha256);
  96. assertEquals(indexApk.obbPatchFile, localApk.obbPatchFile);
  97. assertEquals(indexApk.obbPatchFileSha256, localApk.obbPatchFileSha256);
  98. }
  99. }
  100. @Test
  101. public void testSimpleIndex() {
  102. Repo expectedRepo = new Repo();
  103. expectedRepo.name = "F-Droid";
  104. expectedRepo.signingCertificate = "308201ee30820157a0030201020204300d845b300d06092a864886f70d01010b0500302a3110300e060355040b1307462d44726f6964311630140603550403130d70616c6174736368696e6b656e301e170d3134303432373030303633315a170d3431303931323030303633315a302a3110300e060355040b1307462d44726f6964311630140603550403130d70616c6174736368696e6b656e30819f300d06092a864886f70d010101050003818d0030818902818100a439472e4b6d01141bfc94ecfe131c7c728fdda670bb14c57ca60bd1c38a8b8bc0879d22a0a2d0bc0d6fdd4cb98d1d607c2caefbe250a0bd0322aedeb365caf9b236992fac13e6675d3184a6c7c6f07f73410209e399a9da8d5d7512bbd870508eebacff8b57c3852457419434d34701ccbf692267cbc3f42f1c5d1e23762d790203010001a321301f301d0603551d0e041604140b1840691dab909746fde4bfe28207d1cae15786300d06092a864886f70d01010b05000381810062424c928ffd1b6fd419b44daafef01ca982e09341f7077fb865905087aeac882534b3bd679b51fdfb98892cef38b63131c567ed26c9d5d9163afc775ac98ad88c405d211d6187bde0b0d236381cc574ba06ef9080721a92ae5a103a7301b2c397eecc141cc850dd3e123813ebc41c59d31ddbcb6e984168280c53272f6a442b"; // NOCHECKSTYLE LineLength
  105. expectedRepo.description = "The official repository of the F-Droid client. Applications in this repository are either official binaries built by the original application developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitorious.org/f-droid."; // NOCHECKSTYLE LineLength
  106. expectedRepo.timestamp = 1398733213;
  107. RepoDetails actualDetails = getFromFile("simpleIndex.xml");
  108. handlerTestSuite(expectedRepo, actualDetails, 0, 0, -1, 12);
  109. }
  110. @Test
  111. public void testSmallRepo() {
  112. Repo expectedRepo = new Repo();
  113. expectedRepo.name = "Android-Nexus-7-20139453 on UNSET";
  114. expectedRepo.signingCertificate = "308202da308201c2a00302010202080eb08c796fec91aa300d06092a864886f70d0101050500302d3111300f060355040a0c084b6572706c61707031183016060355040b0c0f477561726469616e50726f6a656374301e170d3134313030333135303631325a170d3135313030333135303631325a302d3111300f060355040a0c084b6572706c61707031183016060355040b0c0f477561726469616e50726f6a65637430820122300d06092a864886f70d01010105000382010f003082010a0282010100c7ab44b130be5c00eedcc3625462f6f6ac26e502641cd641f3e30cbb0ff1ba325158611e7fc2448a35b6a6df30dc6e23602cf6909448befcf11e2fe486b580f1e76fe5887d159050d00afd2c4079f6538896bb200627f4b3e874f011ce5df0fef5d150fcb0b377b531254e436eaf4083ea72fe3b8c3ef450789fa858f2be8f6c5335bb326aff3dda689fbc7b5ba98dea53651dbea7452c38d294985ac5dd8a9e491a695de92c706d682d6911411fcaef3b0a08a030fe8a84e47acaab0b7edcda9d190ce39e810b79b1d8732eca22b15f0d048c8d6f00503a7ee81ab6e08919ff465883432304d95238b95e95c5f74e0a421809e2a6a85825aed680e0d6939e8f0203010001300d06092a864886f70d010105050003820101006d17aad3271b8b2c299dbdb7b1182849b0d5ddb9f1016dcb3487ae0db02b6be503344c7d066e2050bcd01d411b5ee78c7ed450f0ff9da5ce228f774cbf41240361df53d9c6078159d16f4d34379ab7dedf6186489397c83b44b964251a2ebb42b7c4689a521271b1056d3b5a5fa8f28ba64fb8ce5e2226c33c45d27ba3f632dc266c12abf582b8438c2abcf3eae9de9f31152b4158ace0ef33435c20eb809f1b3988131db6e5a1442f2617c3491d9565fedb3e320e8df4236200d3bd265e47934aa578f84d0d1a5efeb49b39907e876452c46996d0feff9404b41aa5631b4482175d843d5512ded45e12a514690646492191e7add434afce63dbff8f0b03ec0c"; // NOCHECKSTYLE LineLength
  115. expectedRepo.description = "A local FDroid repo generated from apps installed on Android-Nexus-7-20139453";
  116. expectedRepo.timestamp = 1412696461;
  117. RepoDetails actualDetails = getFromFile("smallRepo.xml");
  118. handlerTestSuite(expectedRepo, actualDetails, 12, 12, 14, -1);
  119. checkIncludedApps(actualDetails.apps, new String[]{
  120. "org.mozilla.firefox",
  121. "com.koushikdutta.superuser",
  122. "info.guardianproject.courier",
  123. "org.adaway",
  124. "info.guardianproject.gilga",
  125. "com.google.zxing.client.android",
  126. "info.guardianproject.lildebi",
  127. "de.danoeh.antennapod",
  128. "info.guardianproject.otr.app.im",
  129. "org.torproject.android",
  130. "org.gege.caldavsyncadapter",
  131. "info.guardianproject.checkey",
  132. });
  133. for (App app : actualDetails.apps) {
  134. if ("org.mozilla.firefox".equals(app.packageName)) {
  135. assertEquals(1411776000000L, app.added.getTime());
  136. assertEquals(1411862400000L, app.lastUpdated.getTime());
  137. }
  138. }
  139. }
  140. @Test(expected = IllegalArgumentException.class)
  141. public void testSimpleIndexWithCorruptedPackageName() throws Throwable {
  142. Repo expectedRepo = new Repo();
  143. expectedRepo.name = "F-Droid";
  144. expectedRepo.signingCertificate = "308201ee30820157a0030201020204300d845b300d06092a864886f70d01010b0500302a3110300e060355040b1307462d44726f6964311630140603550403130d70616c6174736368696e6b656e301e170d3134303432373030303633315a170d3431303931323030303633315a302a3110300e060355040b1307462d44726f6964311630140603550403130d70616c6174736368696e6b656e30819f300d06092a864886f70d010101050003818d0030818902818100a439472e4b6d01141bfc94ecfe131c7c728fdda670bb14c57ca60bd1c38a8b8bc0879d22a0a2d0bc0d6fdd4cb98d1d607c2caefbe250a0bd0322aedeb365caf9b236992fac13e6675d3184a6c7c6f07f73410209e399a9da8d5d7512bbd870508eebacff8b57c3852457419434d34701ccbf692267cbc3f42f1c5d1e23762d790203010001a321301f301d0603551d0e041604140b1840691dab909746fde4bfe28207d1cae15786300d06092a864886f70d01010b05000381810062424c928ffd1b6fd419b44daafef01ca982e09341f7077fb865905087aeac882534b3bd679b51fdfb98892cef38b63131c567ed26c9d5d9163afc775ac98ad88c405d211d6187bde0b0d236381cc574ba06ef9080721a92ae5a103a7301b2c397eecc141cc850dd3e123813ebc41c59d31ddbcb6e984168280c53272f6a442b"; // NOCHECKSTYLE LineLength
  145. expectedRepo.description = "The official repository of the F-Droid client. Applications in this repository are either official binaries built by the original application developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitorious.org/f-droid."; // NOCHECKSTYLE LineLength
  146. expectedRepo.timestamp = 1398733213;
  147. InputStream inputStream = getClass().getClassLoader()
  148. .getResourceAsStream("simpleIndexWithCorruptedPackageName.xml");
  149. SAXParserFactory factory = SAXParserFactory.newInstance();
  150. factory.setNamespaceAware(true);
  151. SAXParser parser = factory.newSAXParser();
  152. XMLReader reader = parser.getXMLReader();
  153. RepoDetails repoDetails = new RepoDetails();
  154. MockRepo mockRepo = new MockRepo(100, Repo.PUSH_REQUEST_IGNORE);
  155. RepoXMLHandler handler = new RepoXMLHandler(mockRepo, repoDetails);
  156. reader.setContentHandler(handler);
  157. InputSource is = new InputSource(new BufferedInputStream(inputStream));
  158. try {
  159. reader.parse(is);
  160. } catch (org.xml.sax.SAXException e) {
  161. throw e.getCause();
  162. }
  163. fail();
  164. }
  165. @Test
  166. public void testPushRequestsRepoIgnore() {
  167. Repo expectedRepo = new Repo();
  168. expectedRepo.name = "non-public test repo";
  169. expectedRepo.signingCertificate = "308204e1308202c9a0030201020204483450fa300d06092a864886f70d01010b050030213110300e060355040b1307462d44726f6964310d300b06035504031304736f7661301e170d3136303832333133333131365a170d3434303130393133333131365a30213110300e060355040b1307462d44726f6964310d300b06035504031304736f766130820222300d06092a864886f70d01010105000382020f003082020a0282020100dfdcd120f3ab224999dddf4ea33ea588d295e4d7130bef48c143e9d76e5c0e0e9e5d45e64208e35feebc79a83f08939dd6a343b7d1e2179930a105a1249ccd36d88ff3feffc6e4dc53dae0163a7876dd45ecc1ddb0adf5099aa56c1a84b52affcd45d0711ffa4de864f35ac0333ebe61ea8673eeda35a88f6af678cc4d0f80b089338ac8f2a8279a64195c611d19445cab3fd1a020afed9bd739bb95142fb2c00a8f847db5ef3325c814f8eb741bacf86ed3907bfe6e4564d2de5895df0c263824e0b75407589bae2d3a4666c13b92102d8781a8ee9bb4a5a1a78c4a9c21efdaf5584da42e84418b28f5a81d0456a3dc5b420991801e6b21e38c99bbe018a5b2d690894a114bc860d35601416aa4dc52216aff8a288d4775cddf8b72d45fd2f87303a8e9c0d67e442530be28eaf139894337266e0b33d57f949256ab32083bcc545bc18a83c9ab8247c12aea037e2b68dee31c734cb1f04f241d3b94caa3a2b258ffaf8e6eae9fbbe029a934dc0a0859c5f120334812693a1c09352340a39f2a678dbc1afa2a978bfee43afefcb7e224a58af2f3d647e5745db59061236b8af6fcfd93b3602f9e456978534f3a7851e800071bf56da80401c81d91c45f82568373af0576b1cc5eef9b85654124b6319770be3cdba3fbebe3715e8918fb6c8966624f3d0e815effac3d2ee06dd34ab9c693218b2c7c06ba99d6b74d4f17b8c3cb0203010001a321301f301d0603551d0e04160414d62bee9f3798509546acc62eb1de14b08b954d4f300d06092a864886f70d01010b05000382020100743f7c5692085895f9d1fffad390fb4202c15f123ed094df259185960fd6dadf66cb19851070f180297bba4e6996a4434616573b375cfee94fee73a4505a7ec29136b7e6c22e6436290e3686fe4379d4e3140ec6a08e70cfd3ed5b634a5eb5136efaaabf5f38e0432d3d79568a556970b8cfba2972f5d23a3856d8a981b9e9bbbbb88f35e708bde9cbc5f681cbd974085b9da28911296fe2579fa64bbe9fa0b93475a7a8db051080b0c5fade0d1c018e7858cd4cbe95145b0620e2f632cbe0f8af9cbf22e2fdaa72245ae31b0877b07181cc69dd2df74454251d8de58d25e76354abe7eb690f22e59b08795a8f2c98c578e0599503d9085927634072c82c9f82abd50fd12b8fd1a9d1954eb5cc0b4cfb5796b5aaec0356643b4a65a368442d92ef94edd3ac6a2b7fe3571b8cf9f462729228aab023ef9183f73792f5379633ccac51079177d604c6bc1873ada6f07d8da6d68c897e88a5fa5d63fdb8df820f46090e0716e7562dd3c140ba279a65b996f60addb0abe29d4bf2f5abe89480771d492307b926d91f02f341b2148502903c43d40f3c6c86a811d060711f0698b384acdcc0add44eb54e42962d3d041accc715afd49407715adc09350cb55e8d9281a3b0b6b5fcd91726eede9b7c8b13afdebb2c2b377629595f1096ba62fb14946dbac5f3c5f0b4e5b712e7acc7dcf6c46cdc5e6d6dfdeee55a0c92c2d70f080ac6"; // NOCHECKSTYLE LineLength
  170. expectedRepo.description = "This is a repository of apps to be used with F-Droid. Applications in this repository are either official binaries built by the original application developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitlab.com/u/fdroid."; // NOCHECKSTYLE LineLength
  171. expectedRepo.timestamp = 1472071347;
  172. RepoDetails actualDetails = getFromFile("pushRequestsIndex.xml", Repo.PUSH_REQUEST_IGNORE);
  173. handlerTestSuite(expectedRepo, actualDetails, 2, 14, -1, 17);
  174. checkPushRequests(actualDetails);
  175. List<RepoPushRequest> repoPushRequests = actualDetails.repoPushRequestList;
  176. assertNotNull(repoPushRequests);
  177. assertEquals(0, repoPushRequests.size());
  178. }
  179. @Test
  180. public void testPushRequestsRepoAlways() {
  181. Repo expectedRepo = new Repo();
  182. expectedRepo.name = "non-public test repo";
  183. expectedRepo.signingCertificate = "308204e1308202c9a0030201020204483450fa300d06092a864886f70d01010b050030213110300e060355040b1307462d44726f6964310d300b06035504031304736f7661301e170d3136303832333133333131365a170d3434303130393133333131365a30213110300e060355040b1307462d44726f6964310d300b06035504031304736f766130820222300d06092a864886f70d01010105000382020f003082020a0282020100dfdcd120f3ab224999dddf4ea33ea588d295e4d7130bef48c143e9d76e5c0e0e9e5d45e64208e35feebc79a83f08939dd6a343b7d1e2179930a105a1249ccd36d88ff3feffc6e4dc53dae0163a7876dd45ecc1ddb0adf5099aa56c1a84b52affcd45d0711ffa4de864f35ac0333ebe61ea8673eeda35a88f6af678cc4d0f80b089338ac8f2a8279a64195c611d19445cab3fd1a020afed9bd739bb95142fb2c00a8f847db5ef3325c814f8eb741bacf86ed3907bfe6e4564d2de5895df0c263824e0b75407589bae2d3a4666c13b92102d8781a8ee9bb4a5a1a78c4a9c21efdaf5584da42e84418b28f5a81d0456a3dc5b420991801e6b21e38c99bbe018a5b2d690894a114bc860d35601416aa4dc52216aff8a288d4775cddf8b72d45fd2f87303a8e9c0d67e442530be28eaf139894337266e0b33d57f949256ab32083bcc545bc18a83c9ab8247c12aea037e2b68dee31c734cb1f04f241d3b94caa3a2b258ffaf8e6eae9fbbe029a934dc0a0859c5f120334812693a1c09352340a39f2a678dbc1afa2a978bfee43afefcb7e224a58af2f3d647e5745db59061236b8af6fcfd93b3602f9e456978534f3a7851e800071bf56da80401c81d91c45f82568373af0576b1cc5eef9b85654124b6319770be3cdba3fbebe3715e8918fb6c8966624f3d0e815effac3d2ee06dd34ab9c693218b2c7c06ba99d6b74d4f17b8c3cb0203010001a321301f301d0603551d0e04160414d62bee9f3798509546acc62eb1de14b08b954d4f300d06092a864886f70d01010b05000382020100743f7c5692085895f9d1fffad390fb4202c15f123ed094df259185960fd6dadf66cb19851070f180297bba4e6996a4434616573b375cfee94fee73a4505a7ec29136b7e6c22e6436290e3686fe4379d4e3140ec6a08e70cfd3ed5b634a5eb5136efaaabf5f38e0432d3d79568a556970b8cfba2972f5d23a3856d8a981b9e9bbbbb88f35e708bde9cbc5f681cbd974085b9da28911296fe2579fa64bbe9fa0b93475a7a8db051080b0c5fade0d1c018e7858cd4cbe95145b0620e2f632cbe0f8af9cbf22e2fdaa72245ae31b0877b07181cc69dd2df74454251d8de58d25e76354abe7eb690f22e59b08795a8f2c98c578e0599503d9085927634072c82c9f82abd50fd12b8fd1a9d1954eb5cc0b4cfb5796b5aaec0356643b4a65a368442d92ef94edd3ac6a2b7fe3571b8cf9f462729228aab023ef9183f73792f5379633ccac51079177d604c6bc1873ada6f07d8da6d68c897e88a5fa5d63fdb8df820f46090e0716e7562dd3c140ba279a65b996f60addb0abe29d4bf2f5abe89480771d492307b926d91f02f341b2148502903c43d40f3c6c86a811d060711f0698b384acdcc0add44eb54e42962d3d041accc715afd49407715adc09350cb55e8d9281a3b0b6b5fcd91726eede9b7c8b13afdebb2c2b377629595f1096ba62fb14946dbac5f3c5f0b4e5b712e7acc7dcf6c46cdc5e6d6dfdeee55a0c92c2d70f080ac6"; // NOCHECKSTYLE LineLength
  184. expectedRepo.description = "This is a repository of apps to be used with F-Droid. Applications in this repository are either official binaries built by the original application developers, or are binaries built from source by the admin of f-droid.org using the tools on https://gitlab.com/u/fdroid."; // NOCHECKSTYLE LineLength
  185. expectedRepo.timestamp = 1472071347;
  186. RepoDetails actualDetails = getFromFile("pushRequestsIndex.xml", Repo.PUSH_REQUEST_ACCEPT_ALWAYS);
  187. handlerTestSuite(expectedRepo, actualDetails, 2, 14, -1, 17);
  188. checkPushRequests(actualDetails);
  189. List<RepoPushRequest> repoPushRequests = actualDetails.repoPushRequestList;
  190. assertNotNull(repoPushRequests);
  191. assertEquals(6, repoPushRequests.size());
  192. }
  193. @Test
  194. public void testPushRequestsRepoCorruption() {
  195. RepoPushRequest repoPushRequest;
  196. repoPushRequest = new RepoPushRequest(null, null, null); // request with no data
  197. assertEquals(repoPushRequest.request, null);
  198. assertEquals(repoPushRequest.packageName, null);
  199. assertEquals(repoPushRequest.versionCode, null);
  200. repoPushRequest = new RepoPushRequest("install", "org.fdroid.fdroid", "999999999999");
  201. assertEquals(repoPushRequest.versionCode, null);
  202. repoPushRequest = new RepoPushRequest("install", "org.fdroid.fdroid",
  203. String.valueOf(((long) Integer.MAX_VALUE) + 1));
  204. assertEquals(repoPushRequest.versionCode, null);
  205. repoPushRequest = new RepoPushRequest("install", "org.fdroid.fdroid",
  206. String.valueOf(((long) Integer.MIN_VALUE) - 1));
  207. assertEquals(repoPushRequest.versionCode, null);
  208. repoPushRequest = new RepoPushRequest("Robert'); DROP TABLE Students; --", "org.fdroid.fdroid", null);
  209. assertEquals(repoPushRequest.request, null);
  210. assertEquals(repoPushRequest.packageName, "org.fdroid.fdroid");
  211. assertEquals(repoPushRequest.versionCode, null);
  212. repoPushRequest = new RepoPushRequest("install", "Robert'); DROP TABLE Students; --", "123.1.1");
  213. assertEquals(repoPushRequest.request, "install");
  214. assertEquals(repoPushRequest.packageName, null);
  215. assertEquals(repoPushRequest.versionCode, null);
  216. repoPushRequest = new RepoPushRequest("install", "--", "123");
  217. assertEquals(repoPushRequest.request, "install");
  218. assertEquals(repoPushRequest.packageName, null);
  219. assertEquals(repoPushRequest.versionCode, Integer.valueOf(123));
  220. repoPushRequest = new RepoPushRequest("uninstall", "Robert'); DROP TABLE Students; --", "123");
  221. assertEquals(repoPushRequest.request, "uninstall");
  222. assertEquals(repoPushRequest.packageName, null);
  223. assertEquals(repoPushRequest.versionCode, Integer.valueOf(123));
  224. repoPushRequest = new RepoPushRequest("badrquest", "asdfasdfasdf", "123");
  225. assertEquals(repoPushRequest.request, null);
  226. assertEquals(repoPushRequest.packageName, "asdfasdfasdf");
  227. assertEquals(repoPushRequest.versionCode, Integer.valueOf(123));
  228. }
  229. @Test
  230. public void testMediumRepo() {
  231. Repo expectedRepo = new Repo();
  232. expectedRepo.name = "Guardian Project Official Releases";
  233. expectedRepo.signingCertificate = "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f"; // NOCHECKSTYLE LineLength
  234. expectedRepo.description = "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store."; // NOCHECKSTYLE LineLength
  235. expectedRepo.timestamp = 1411427879;
  236. RepoDetails actualDetails = getFromFile("mediumRepo.xml");
  237. handlerTestSuite(expectedRepo, actualDetails, 15, 36, 60, 12);
  238. checkIncludedApps(actualDetails.apps, new String[]{
  239. "info.guardianproject.cacert",
  240. "info.guardianproject.otr.app.im",
  241. "info.guardianproject.soundrecorder",
  242. "info.guardianproject.checkey",
  243. "info.guardianproject.courier",
  244. "org.fdroid.fdroid",
  245. "info.guardianproject.gpg",
  246. "info.guardianproject.lildebi",
  247. "info.guardianproject.notepadbot",
  248. "org.witness.sscphase1",
  249. "org.torproject.android",
  250. "info.guardianproject.browser",
  251. "info.guardianproject.pixelknot",
  252. "info.guardianproject.chatsecure.emoji.core",
  253. "info.guardianproject.mrapp",
  254. });
  255. }
  256. @Test
  257. public void testLargeRepo() {
  258. Repo expectedRepo = new Repo();
  259. expectedRepo.name = "F-Droid";
  260. expectedRepo.signingCertificate = "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef"; // NOCHECKSTYLE LineLength
  261. expectedRepo.description = "The official FDroid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time."; // NOCHECKSTYLE LineLength
  262. expectedRepo.timestamp = 1412746769;
  263. RepoDetails actualDetails = getFromFile("largeRepo.xml");
  264. handlerTestSuite(expectedRepo, actualDetails, 1211, 2381, 14, 12);
  265. // Generated using something like the following:
  266. // sed 's,<application,\n<application,g' largeRepo.xml | grep "antifeatures" | sed 's,.*id="\(.*\)".*<antifeatures>\(.*\)</antifeatures>.*,\1 \2,p' | sort | uniq // NOCHECKSTYLE LineLength
  267. Map<String, List<String>> expectedAntiFeatures = new HashMap<>();
  268. expectedAntiFeatures.put("org.fdroid.fdroid", new ArrayList<String>());
  269. expectedAntiFeatures.put("org.adblockplus.android", Arrays.asList("Tracking", "Ads"));
  270. expectedAntiFeatures.put("org.microg.nlp.backend.apple", Arrays.asList("Tracking", "NonFreeNet"));
  271. expectedAntiFeatures.put("com.ds.avare", Collections.singletonList("NonFreeDep"));
  272. expectedAntiFeatures.put("com.miracleas.bitcoin_spinner", Collections.singletonList("NonFreeAdd"));
  273. expectedAntiFeatures.put("de.Cherubin7th.blackscreenpresentationremote", Collections.singletonList("Ads"));
  274. expectedAntiFeatures.put("budo.budoist", Collections.singletonList("NonFreeNet"));
  275. expectedAntiFeatures.put("no.rkkc.bysykkel", Collections.singletonList("NonFreeDep"));
  276. expectedAntiFeatures.put("com.jadn.cc", Collections.singletonList("Tracking"));
  277. expectedAntiFeatures.put("org.atai.TessUI", Collections.singletonList("NonFreeNet"));
  278. expectedAntiFeatures.put("org.zephyrsoft.checknetwork", Collections.singletonList("Tracking"));
  279. expectedAntiFeatures.put("de.bashtian.dashclocksunrise", Collections.singletonList("NonFreeDep"));
  280. expectedAntiFeatures.put("org.geometerplus.zlibrary.ui.android", Collections.singletonList("NonFreeAdd"));
  281. expectedAntiFeatures.put("org.mozilla.firefox", Arrays.asList("NonFreeAdd", "Tracking"));
  282. expectedAntiFeatures.put("com.gmail.charleszq", Collections.singletonList("NonFreeDep"));
  283. expectedAntiFeatures.put("it.andreascarpino.forvodroid", Arrays.asList("NonFreeNet", "NonFreeDep"));
  284. expectedAntiFeatures.put("de.b0nk.fp1_epo_autoupdate", Collections.singletonList("NonFreeNet"));
  285. expectedAntiFeatures.put("com.blogspot.tonyatkins.freespeech", Collections.singletonList("Tracking"));
  286. expectedAntiFeatures.put("com.frostwire.android", Collections.singletonList("Tracking"));
  287. expectedAntiFeatures.put("com.namsor.api.samples.gendre", Collections.singletonList("NonFreeNet"));
  288. expectedAntiFeatures.put("com.github.mobile", Collections.singletonList("NonFreeNet"));
  289. expectedAntiFeatures.put("com.cradle.iitc_mobile", Collections.singletonList("NonFreeNet"));
  290. expectedAntiFeatures.put("com.matteopacini.katana", Collections.singletonList("Tracking"));
  291. expectedAntiFeatures.put("de.enaikoon.android.keypadmapper3", Collections.singletonList("Tracking"));
  292. expectedAntiFeatures.put("org.linphone", Collections.singletonList("NonFreeDep"));
  293. expectedAntiFeatures.put("ch.rrelmy.android.locationcachemap", Collections.singletonList("NonFreeDep"));
  294. expectedAntiFeatures.put("com.powerpoint45.lucidbrowser", Arrays.asList("Ads", "NonFreeDep"));
  295. expectedAntiFeatures.put("org.mixare", Collections.singletonList("NonFreeDep"));
  296. expectedAntiFeatures.put("apps.droidnotify", Collections.singletonList("NonFreeAdd"));
  297. expectedAntiFeatures.put("com.numix.calculator", Collections.singletonList("NonFreeAdd"));
  298. expectedAntiFeatures.put("com.numix.icons_circle", Collections.singletonList("NonFreeAdd"));
  299. expectedAntiFeatures.put("com.gh4a", Collections.singletonList("NonFreeNet"));
  300. expectedAntiFeatures.put("at.tomtasche.reader", Collections.singletonList("Tracking"));
  301. expectedAntiFeatures.put("de.uni_potsdam.hpi.openmensa", Collections.singletonList("NonFreeNet"));
  302. expectedAntiFeatures.put("net.osmand.plus", Collections.singletonList("Tracking"));
  303. expectedAntiFeatures.put("byrne.utilities.pasteedroid", Collections.singletonList("NonFreeNet"));
  304. expectedAntiFeatures.put("com.bwx.bequick", Collections.singletonList("NonFreeAdd"));
  305. expectedAntiFeatures.put("be.geecko.QuickLyric", Collections.singletonList("Tracking"));
  306. expectedAntiFeatures.put("com.wanghaus.remembeer", Collections.singletonList("NonFreeNet"));
  307. expectedAntiFeatures.put("cri.sanity", Collections.singletonList("Ads"));
  308. expectedAntiFeatures.put("com.showmehills", Collections.singletonList("Tracking"));
  309. expectedAntiFeatures.put("com.akop.bach", Collections.singletonList("NonFreeNet"));
  310. expectedAntiFeatures.put("org.dmfs.tasks", Collections.singletonList("NonFreeAdd"));
  311. expectedAntiFeatures.put("org.telegram.messenger", Collections.singletonList("NonFreeNet"));
  312. expectedAntiFeatures.put("com.danvelazco.fbwrapper", Collections.singletonList("Tracking"));
  313. expectedAntiFeatures.put("org.zephyrsoft.trackworktime", Collections.singletonList("Tracking"));
  314. expectedAntiFeatures.put("org.transdroid", Collections.singletonList("Tracking"));
  315. expectedAntiFeatures.put("com.lonepulse.travisjr", Collections.singletonList("NonFreeNet"));
  316. expectedAntiFeatures.put("com.twsitedapps.homemanager", Collections.singletonList("NonFreeAdd"));
  317. expectedAntiFeatures.put("org.zeitgeist.movement", Collections.singletonList("NonFreeDep"));
  318. expectedAntiFeatures.put("net.wigle.wigleandroid", Collections.singletonList("NonFreeNet"));
  319. expectedAntiFeatures.put("org.nick.wwwjdic", Collections.singletonList("Tracking"));
  320. checkAntiFeatures(actualDetails.apps, expectedAntiFeatures);
  321. /*
  322. * generated using: sed 's,<application,\n<application,g' largeRepo.xml
  323. * | sed -n 's,.*id="\(.[^"]*\)".*,"\1"\,,p'
  324. */
  325. checkIncludedApps(actualDetails.apps, new String[]{
  326. "org.zeroxlab.zeroxbenchmark", "com.uberspot.a2048", "com.traffar.a24game",
  327. "info.staticfree.android.twentyfourhour", "nerd.tuxmobil.fahrplan.congress",
  328. "com.jecelyin.editor", "com.markuspage.android.atimetracker", "a2dp.Vol",
  329. "com.zoffcc.applications.aagtl", "aarddict.android", "com.kai1973i",
  330. "net.georgewhiteside.android.abstractart", "com.morphoss.acal",
  331. "org.billthefarmer.accordion", "com.achep.acdisplay", "anupam.acrylic",
  332. "net.androidcomics.acv", "org.adaway", "com.matoski.adbm",
  333. "org.adblockplus.android", "siir.es.adbWireless", "org.dgtale.icsimport",
  334. "com.addi", "org.hystudio.android.dosbox", "hu.vsza.adsdroid", "org.adw.launcher",
  335. "dev.ukanth.ufirewall", "com.madgag.agit", "jp.sblo.pandora.aGrep",
  336. "net.gorry.aicia", "com.brosmike.airpushdetector", "org.ligi.ajsha",
  337. "org.akvo.rsr.up", "com.angrydoughnuts.android.alarmclock", "org.jtb.alogcat",
  338. "rs.pedjaapps.alogcatroot.app", "org.ametro", "com.orphan.amplayer",
  339. "eu.domob.anacam", "com.as.anagramsolver", "com.nephoapp.anarxiv",
  340. "net.bible.android.activity", "li.klass.fhem", "org.xapek.andiodine", "net.avs234",
  341. "com.github.andlyticsproject", "org.quovadit.apps.andof",
  342. "com.gpl.rpg.AndorsTrail", "net.progval.android.andquote", "net.rocrail.androc",
  343. "de.hechler.andfish", "com.android.inputmethod.latin", "aws.apps.androidDrawables",
  344. "org.yuttadhammo.tipitaka", "uk.co.bitethebullet.android.token",
  345. "jp.ksksue.app.terminal", "com.templaro.opsiz.aka", "fr.asterope",
  346. "android.androidVNC", "com.tritop.androsense2", "net.tedstein.AndroSS",
  347. "com.androzic", "org.andstatus.app", "net.sourceforge.andsys",
  348. "com.miqote.angelplayerwp", "eu.domob.angulo", "com.ichi2.anki",
  349. "net.haltcondition.anode", "An.stop", "de.danoeh.antennapod",
  350. "com.fivasim.antikythera", "de.antonwolf.agendawidget", "com.example.anycut",
  351. "org.liberty.android.fantastischmemo", "com.menny.android.anysoftkeyboard",
  352. "com.anysoftkeyboard.languagepack.catalan", "com.anysoftkeyboard.theme.classic_pc",
  353. "com.anysoftkeyboard.languagepack.danish",
  354. "com.anysoftkeyboard.languagepack.esperanto",
  355. "com.anysoftkeyboard.languagepack.french_xlarge",
  356. "com.anysoftkeyboard.languagepack.georgian.fdroid",
  357. "com.anysoftkeyboard.languagepack.greek",
  358. "com.anysoftkeyboard.languagepack.hebrew_large",
  359. "org.herrlado.ask.languagepack.lithuanian",
  360. "com.anysoftkeyboard.languagepack.hungarian",
  361. "com.anysoftkeyboard.languagepack.malayalam",
  362. "com.anysoftkeyboard.languagepack.pali",
  363. "com.anysoftkeyboard.languagepack.persian",
  364. "com.anysoftkeyboard.languagepack.spain", "com.anysoftkeyboard.languagepack.SSH",
  365. "com.anysoftkeyboard.languagepack.ukrainian", "com.scar45.aokp.co.webviewer",
  366. "org.thialfihar.android.apg", "ch.blinkenlights.android.apnswitch",
  367. "com.andrew.apollo", "com.nolanlawson.apptracker",
  368. "com.episode6.android.appalarm.pro", "org.moparisthebest.appbak",
  369. "org.microg.nlp.backend.apple", "com.gueei.applocker",
  370. "com.google.code.appsorganizer", "com.google.code.apps2org",
  371. "cx.hell.android.pdfview", "org.androidfromfrankfurt.archnews", "org.ardour",
  372. "com.primavera.arduino.listener", "arity.calculator",
  373. "com.commonsware.android.arXiv", "com.dozingcatsoftware.asciicam",
  374. "com.alfray.asqare", "dk.andsen.asqlitemanager", "net.somethingdreadful.MAL",
  375. "org.tamanegi.atmosphere", "indrora.atomic",
  376. "com.google.android.apps.authenticator2", "com.teamdc.stephendiniz.autoaway",
  377. "com.everysoft.autoanswer", "com.elsdoerfer.android.autostarts", "com.ds.avare",
  378. "apps.babycaretimer", "com.tkjelectronics.balanduino", "com.liato.bankdroid",
  379. "uk.ac.cam.cl.dtg.android.barcodebox", "com.google.zxing.client.android",
  380. "net.szym.barnacle", "com.dougkeen.bart", "ch.blinkenlights.battery",
  381. "net.sf.andbatdog.batterydog", "ch.rrelmy.android.batterymanager",
  382. "org.droidparts.battery_widget", "org.androidappdev.batterywidget",
  383. "com.darshancomputing.BatteryIndicatorPro", "com.tobykurien.batteryfu",
  384. "com.mohammadag.beamfile", "com.corner23.android.beautyclocklivewallpaper",
  385. "com.knirirr.beecount", "com.beem.project.beem", "com.glanznig.beepme",
  386. "headrevision.BehatReporter", "com.asksven.betterwifionoff",
  387. "com.asksven.betterbatterystats", "net.imatruck.betterweather",
  388. "org.segin.bfinterpreter", "com.ihunda.android.binauralbeat",
  389. "org.birthdayadapter", "com.rigid.birthdroid", "com.saibotd.bitbeaker",
  390. "de.schildbach.wallet", "com.veken0m.bitcoinium", "com.miracleas.bitcoin_spinner",
  391. "caldwell.ben.bites", "eu.domob.bjtrainer",
  392. "de.Cherubin7th.blackscreenpresentationremote", "com.miqote.brswp",
  393. "com.blippex.app", "de.grobox.blitzmail", "org.blockinger.game",
  394. "org.scoutant.blokish", "org.broeuschmeul.android.gps.bluetooth.provider",
  395. "com.hermit.btreprap", "ru.sash0k.bluetooth_terminal", "net.bluetoothviewer",
  396. "com.hexad.bluezime", "com.hexad.bluezime.hidenabler", "cxa.lineswallpaper",
  397. "com.zola.bmi", "com.boardgamegeek", "byrne.utilities.converter",
  398. "org.yuttadhammo.BodhiTimer", "mobi.boilr.boilr", "org.beide.bomber",
  399. "org.bombusmod", "com.eleybourn.bookcatalogue", "com.totsp.bookworm",
  400. "com.botbrew.basil", "com.github.grimpy.botifier",
  401. "priv.twoerner.brightnesswidget", "nl.frankkie.bronylivewallpaper",
  402. "com.intrications.android.sharebrowser", "fr.strasweb.browserquest",
  403. "net.androgames.level", "com.notriddle.budget", "budo.budoist",
  404. "org.nathan.jf.build.prop.editor", "com.sandeel.bushidoblocks", "no.rkkc.bysykkel",
  405. "info.guardianproject.cacert", "com.frozendevs.cache.cleaner",
  406. "at.bitfire.cadroid", "org.iilab.pb", "home.jmstudios.calc",
  407. "com.android2.calculator3", "org.gege.caldavsyncadapter",
  408. "de.k3b.android.calendar.ics.adapter", "com.plusonelabs.calendar",
  409. "de.ub0r.android.callmeter", "com.call.recorder",
  410. "com.wordpress.sarfraznawaz.callerdetails", "com.integralblue.callerid",
  411. "com.android.camera2", "campyre.android", "com.dozingcatsoftware.cameratimer",
  412. "com.jadn.cc", "me.kuehle.carreport", "org.systemcall.scores",
  413. "com.ridgelineapps.resdicegame", "com.nolanlawson.logcat", "com.github.cetoolbox",
  414. "fr.strasweb.asso", "com.linkomnia.android.Changjie", "org.atai.TessUI",
  415. "com.kkinder.charmap", "com.googlecode.chartdroid",
  416. "info.guardianproject.otr.app.im", "org.zephyrsoft.checknetwork",
  417. "jwtc.android.chess", "cz.hejl.chesswalk", "org.hekmatof.chesswatch",
  418. "org.scoutant.cc", "com.nilhcem.frcndict", "com.nolanlawson.chordreader",
  419. "net.pmarks.chromadoze", "me.bpear.chromeapkpackager",
  420. "us.lindanrandy.cidrcalculator", "name.starnberger.guenther.android.cbw",
  421. "com.sapos_aplastados.game.clash_of_balls", "de.qspool.clementineremote",
  422. "de.ub0r.android.clipboardbeam", "com.ssaurel.clocklw", "org.floens.chan",
  423. "dk.mide.fas.cmnightlies", "de.fmaul.android.cmis", "com.banasiak.coinflip",
  424. "com.banasiak.coinflipext.example", "com.coinbase.android",
  425. "com.brianco.colorclock", "com.color.colornamer", "com.nauj27.android.colorpicker",
  426. "org.androidsoft.coloring", "org.gringene.colourclock", "net.kervala.comicsreader",
  427. "com.sgr_b2.compass", "net.micode.compass", "org.dyndns.fules.ck",
  428. "org.gringene.concentricclock", "org.connectbot", "de.measite.contactmerger",
  429. "com.appengine.paranoid_android.lost", "com.boombuler.widgets.contacts",
  430. "com.github.nutomic.controldlna", "eu.siacs.conversations", "org.coolreader",
  431. "com.dconstructing.cooper", "se.johanhil.clipboard", "ru.o2genum.coregame",
  432. "net.vivekiyer.GAL", "com.example.CosyDVR", "de.mreiter.countit",
  433. "com.cr5315.cfdc", "ch.fixme.cowsay", "com.qubling.sidekick",
  434. "com.bvalosek.cpuspy", "com.github.alijc.cricketsalarm", "groomiac.crocodilenote",
  435. "org.eehouse.android.xw4", "org.nick.cryptfs.passwdmanager", "com.csipsimple",
  436. "com.hykwok.CurrencyConverter", "com.elsewhat.android.currentwallpaper",
  437. "com.manor.currentwidget", "net.cyclestreets", "org.mult.daap",
  438. "com.bottleworks.dailymoney", "org.jessies.dalvikexplorer", "com.darknessmap",
  439. "net.nurik.roman.dashclock",
  440. "it.gmariotti.android.apps.dashclock.extensions.battery", "com.mridang.cellinfo",
  441. "net.logomancy.dashquotes.civ5", "me.malladi.dashcricket", "com.dwak.lastcall",
  442. "de.bashtian.dashclocksunrise", "com.mridang.wifiinfo", "dasher.android",
  443. "com.umang.dashnotifier", "at.bitfire.davdroid", "net.czlee.debatekeeper",
  444. "org.dyndns.sven_ola.debian_kit", "net.debian.debiandroid", "com.wentam.defcol",
  445. "com.serone.desktoplabel", "com.f2prateek.dfg", "org.dnaq.dialer2",
  446. "jpf.android.diary", "com.voidcode.diasporawebclient",
  447. "com.edwardoyarzun.diccionario", "de.kugihan.dictionaryformids.hmi_android",
  448. "si.modrajagoda.didi", "net.logomancy.diedroid",
  449. "kaljurand_at_gmail_dot_com.diktofon", "in.shick.diode",
  450. "com.google.android.diskusage", "to.networld.android.divedroid",
  451. "org.diygenomics.pg", "org.sufficientlysecure.viewer",
  452. "org.sufficientlysecure.viewer.fontpack", "com.dozingcatsoftware.dodge",
  453. "org.katsarov.dofcalc", "org.dolphinemu.dolphinemu", "us.bravender.android.dongsa",
  454. "net.iowaline.dotdash", "de.stefan_oltmann.kaesekaestchen", "steele.gerry.dotty",
  455. "fr.xtof54.dragonGoApp", "com.drismo", "com.xatik.app.droiddraw.client",
  456. "jackpal.droidexaminer", "edu.rit.poe.atomix", "org.petero.droidfish",
  457. "org.beide.droidgain", "org.jtb.droidlife", "com.mkf.droidsat", "org.droidseries",
  458. "org.droidupnp", "com.googlecode.droidwall", "de.delusions.measure",
  459. "com.shurik.droidzebra", "de.onyxbits.drudgery", "ch.dissem.android.drupal",
  460. "github.daneren2005.dsub", "se.johanhil.duckduckgo",
  461. "com.duckduckgo.mobile.android", "it.ecosw.dudo", "org.dynalogin.android",
  462. "org.uaraven.e", "com.seb.SLWP", "com.seb.SLWPmaps", "net.pejici.easydice",
  463. "de.audioattack.openlink", "app.easytoken", "com.f0x.eddymalou",
  464. "org.congresointeractivo.elegilegi", "com.ultramegatech.ey",
  465. "com.blntsoft.emailpopup", "com.kibab.android.EncPassChanger",
  466. "org.epstudios.epmobile", "org.jamienicol.episodes",
  467. "com.mirasmithy.epochlauncher", "it.angrydroids.epub3reader", "it.iiizio.epubator",
  468. "com.googlecode.awsms", "com.mehmetakiftutuncu.eshotroid",
  469. "com.googlecode.eyesfree.espeak", "com.sweetiepiggy.everylocale",
  470. "de.pinyto.exalteddicer", "org.kost.externalip", "ch.hsr.eyecam",
  471. "com.google.marvin.shell", "org.fdroid.fdroid",
  472. "com.easwareapps.f2lflap2lock_adfree", "faenza.adw.theme", "org.balau.fakedawn",
  473. "de.stefan_oltmann.falling_blocks", "com.codebutler.farebot", "org.ligi.fast",
  474. "com.mod.android.widget.fbcw", "org.fastergps",
  475. "org.geometerplus.zlibrary.ui.android",
  476. "org.geometerplus.fbreader.plugin.local_opds_scanner",
  477. "org.geometerplus.fbreader.plugin.tts", "com.hyperionics.fbreader.plugin.tts_plus",
  478. "net.micode.fileexplorer", "com.cyanogenmod.filemanager.ics",
  479. "com.michaldabski.filemanager", "com.github.wdkapps.fillup",
  480. "se.erikofsweden.findmyphone", "org.mozilla.firefox", "com.ten15.diyfish",
  481. "org.mysociety.FixMyStreet", "uk.co.danieljarvis.android.flashback",
  482. "com.nightshadelabs.anotherbrowser", "com.studio332.flickit",
  483. "com.gmail.charleszq", "fi.harism.wallpaper.flier", "org.aja.flightmode",
  484. "dk.nindroid.rss", "genius.mohammad.floating.stickies", "net.fred.feedex",
  485. "fr.xplod.focal", "com.oakley.fon", "com.sputnik.wispr", "ro.ieval.fonbot",
  486. "net.phunehehe.foocam", "com.iazasoft.footguy", "org.jsharkey.sky",
  487. "it.andreascarpino.forvodroid", "be.digitalia.fosdem",
  488. "de.b0nk.fp1_epo_autoupdate", "pt.isec.tp.am",
  489. "com.blogspot.tonyatkins.freespeech", "org.fedorahosted.freeotp",
  490. "de.cwde.freeshisen", "nf.frex.android", "de.wikilab.android.f…

Large files files are truncated, but you can click here to view the full file