├── README.md ├── app.apk ├── app └── src │ └── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ └── com │ │ └── ghost │ │ └── thunder │ │ ├── DelegateApplicationPackageManager.java │ │ ├── Download.java │ │ ├── MainActivity.java │ │ └── MyApp.java │ └── res │ ├── drawable │ └── progressbar_color.xml │ ├── layout │ ├── activity_main.xml │ ├── dialog_new_download.xml │ └── listview_item.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ ├── folder.png │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml ├── preview.jpg └── thunder └── src └── main ├── AndroidManifest.xml ├── java └── com │ └── xunlei │ └── downloadlib │ ├── BlockingItem.java │ ├── Daemon.java │ ├── DelegateApplication.java │ ├── LinuxFileCommand.java │ ├── XLAppKeyChecker.java │ ├── XLDownloadManager.java │ ├── XLLoader.java │ ├── XLTaskHelper.java │ ├── android │ ├── LogConfig.java │ ├── LogLevel.java │ ├── XLLog.java │ ├── XLLogInternal.java │ └── XLUtil.java │ └── parameter │ ├── BtIndexSet.java │ ├── BtSubTaskDetail.java │ ├── BtTaskParam.java │ ├── BtTaskStatus.java │ ├── CIDTaskParam.java │ ├── EmuleTaskParam.java │ ├── ErrorCodeToMsg.java │ ├── GetDownloadHead.java │ ├── GetDownloadLibVersion.java │ ├── GetFileName.java │ ├── GetTaskId.java │ ├── InitParam.java │ ├── MagnetTaskParam.java │ ├── MaxDownloadSpeedParam.java │ ├── P2spTaskParam.java │ ├── PeerResourceParam.java │ ├── ServerResourceParam.java │ ├── ThunderUrlInfo.java │ ├── TorrentFileInfo.java │ ├── TorrentInfo.java │ ├── UrlQuickInfo.java │ ├── XLConstant.java │ ├── XLProductInfo.java │ ├── XLSessionInfo.java │ ├── XLTaskInfo.java │ ├── XLTaskInfoEx.java │ └── XLTaskLocalUrl.java ├── jniLibs └── armeabi │ ├── libxl_stat.so │ ├── libxl_thunder_sdk.so │ └── libxluagc.so └── res └── values └── strings.xml /README.md: -------------------------------------------------------------------------------- 1 | # MiniThunder 2 | Android 迷你版迅雷,支持 thunder:// ftp:// http:// ed2k:// 磁力链的下载。 3 | 在 [安卓迅雷模块](https://github.com/oceanzhang01/MiniThunder) 的基础上增加了下载列表。 4 | 5 | ![alt](preview.jpg) 6 | 7 | ### 期望 8 | 有大佬可以把安卓迅雷移植到 Linux 平台,可以尝试移植到 Linux 的 Java UI。 -------------------------------------------------------------------------------- /app.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app.apk -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/com/ghost/thunder/DelegateApplicationPackageManager.java: -------------------------------------------------------------------------------- 1 | package com.ghost.thunder; 2 | 3 | import android.annotation.TargetApi; 4 | import android.content.ComponentName; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.content.pm.ActivityInfo; 8 | import android.content.pm.ApplicationInfo; 9 | import android.content.pm.FeatureInfo; 10 | import android.content.pm.InstrumentationInfo; 11 | import android.content.pm.PackageInfo; 12 | import android.content.pm.PackageInstaller; 13 | import android.content.pm.PackageManager; 14 | import android.content.pm.PermissionGroupInfo; 15 | import android.content.pm.PermissionInfo; 16 | import android.content.pm.ProviderInfo; 17 | import android.content.pm.ResolveInfo; 18 | import android.content.pm.ServiceInfo; 19 | import android.content.res.Resources; 20 | import android.content.res.XmlResourceParser; 21 | import android.graphics.Rect; 22 | import android.graphics.drawable.Drawable; 23 | import android.os.Build; 24 | import android.os.Bundle; 25 | import android.os.UserHandle; 26 | import android.support.annotation.RequiresApi; 27 | import android.util.Log; 28 | 29 | import java.util.List; 30 | 31 | /** 32 | * Created by oceanzhang on 2016/10/28. 33 | */ 34 | 35 | public class DelegateApplicationPackageManager extends PackageManager { 36 | private static final String TAG = "DelegateApplicationPack"; 37 | private static final String realPackageName = "com.ghost.thunder.demo"; 38 | PackageManager packageManager; 39 | public DelegateApplicationPackageManager(PackageManager packageManager) { 40 | this.packageManager = packageManager; 41 | } 42 | 43 | @Override 44 | public PackageInfo getPackageInfo(String packageName, int flags) 45 | throws NameNotFoundException { 46 | Log.w(TAG, "getPackageInfo() :" + packageName); 47 | PackageInfo pi = packageManager.getPackageInfo(realPackageName, flags); 48 | pi.applicationInfo.packageName = packageName; 49 | pi.packageName = packageName; 50 | return pi; 51 | } 52 | 53 | @Override 54 | public String[] currentToCanonicalPackageNames(String[] names) { 55 | return packageManager.currentToCanonicalPackageNames(names); 56 | } 57 | 58 | @Override 59 | public String[] canonicalToCurrentPackageNames(String[] names) { 60 | return packageManager.canonicalToCurrentPackageNames(names); 61 | } 62 | 63 | @Override 64 | public Intent getLaunchIntentForPackage(String packageName) { 65 | Log.w(TAG, "getLaunchIntentForPackage() "); 66 | return packageManager.getLaunchIntentForPackage(packageName); 67 | } 68 | 69 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 70 | @Override 71 | public Intent getLeanbackLaunchIntentForPackage(String packageName) { 72 | Log.w(TAG, "getLeanbackLaunchIntentForPackage() "); 73 | return packageManager.getLeanbackLaunchIntentForPackage(packageName); 74 | } 75 | 76 | @Override 77 | public int[] getPackageGids(String packageName) throws NameNotFoundException { 78 | Log.w(TAG, "getPackageGids() "); 79 | return getPackageGids(packageName, 0); 80 | } 81 | 82 | @Override 83 | public int[] getPackageGids(String packageName, int flags) 84 | throws NameNotFoundException { 85 | Log.w(TAG, "getPackageGids() "); 86 | return getPackageGids(packageName,flags); 87 | } 88 | 89 | @RequiresApi(api = Build.VERSION_CODES.N) 90 | @Override 91 | public int getPackageUid(String packageName, int flags) throws NameNotFoundException { 92 | Log.w(TAG, "getPackageUid() "); 93 | return packageManager.getPackageUid(packageName,flags); 94 | } 95 | 96 | @Override 97 | public PermissionInfo getPermissionInfo(String name, int flags) 98 | throws NameNotFoundException { 99 | Log.w(TAG, "getPermissionInfo() "); 100 | return packageManager.getPermissionInfo(name,flags); 101 | } 102 | 103 | @Override 104 | @SuppressWarnings("unchecked") 105 | public List queryPermissionsByGroup(String group, int flags) 106 | throws NameNotFoundException { 107 | return packageManager.queryPermissionsByGroup(group,flags); 108 | } 109 | 110 | @Override 111 | public PermissionGroupInfo getPermissionGroupInfo(String name, 112 | int flags) throws NameNotFoundException { 113 | return packageManager.getPermissionGroupInfo(name,flags); 114 | } 115 | 116 | @Override 117 | @SuppressWarnings("unchecked") 118 | public List getAllPermissionGroups(int flags) { 119 | return packageManager.getAllPermissionGroups(flags); 120 | } 121 | 122 | @Override 123 | public ApplicationInfo getApplicationInfo(String packageName, int flags) 124 | throws NameNotFoundException { 125 | Log.w(TAG, "getApplicationInfo() "); 126 | if("com.xunlei.downloadprovider".equals(packageName)) { 127 | packageName = realPackageName; 128 | } 129 | ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, flags); 130 | Bundle metaData = applicationInfo.metaData; 131 | if(metaData == null) { 132 | metaData = new Bundle(); 133 | applicationInfo.metaData = metaData; 134 | } 135 | metaData.putString("com.xunlei.download.APP_KEY","bpIzNjAxNTsxNTA0MDk0ODg4LjQyODAwMAOxNw==^a2cec7^10e7f1756b15519e20ffb6cf0fbf671f"); 136 | return applicationInfo; 137 | } 138 | 139 | @Override 140 | public ActivityInfo getActivityInfo(ComponentName className, int flags) 141 | throws NameNotFoundException { 142 | Log.w(TAG, "getActivityInfo() " + className.getClassName()); 143 | return packageManager.getActivityInfo(className, flags); 144 | } 145 | 146 | @Override 147 | public ActivityInfo getReceiverInfo(ComponentName className, int flags) 148 | throws NameNotFoundException { 149 | return packageManager.getReceiverInfo(className, flags); 150 | } 151 | 152 | @Override 153 | public ServiceInfo getServiceInfo(ComponentName className, int flags) 154 | throws NameNotFoundException { 155 | return packageManager.getServiceInfo(className,flags); 156 | } 157 | 158 | @Override 159 | public ProviderInfo getProviderInfo(ComponentName className, int flags) 160 | throws NameNotFoundException { 161 | return packageManager.getProviderInfo(className, flags); 162 | } 163 | 164 | @Override 165 | public String[] getSystemSharedLibraryNames() { 166 | return packageManager.getSystemSharedLibraryNames(); 167 | } 168 | 169 | 170 | @Override 171 | @SuppressWarnings("unchecked") 172 | public FeatureInfo[] getSystemAvailableFeatures() { 173 | return packageManager.getSystemAvailableFeatures(); 174 | } 175 | 176 | @Override 177 | public boolean hasSystemFeature(String name) { 178 | return packageManager.hasSystemFeature(name); 179 | } 180 | 181 | @TargetApi(Build.VERSION_CODES.N) 182 | @Override 183 | public boolean hasSystemFeature(String name, int version) { 184 | return packageManager.hasSystemFeature(name, version); 185 | } 186 | 187 | @Override 188 | public int checkPermission(String permName, String pkgName) { //TODO packagename 189 | return packageManager.checkPermission(permName, pkgName); 190 | } 191 | 192 | @RequiresApi(api = Build.VERSION_CODES.M) 193 | @Override 194 | public boolean isPermissionRevokedByPolicy(String permName, String pkgName) { 195 | Log.w(TAG, "isPermissionRevokedByPolicy() "); 196 | return packageManager.isPermissionRevokedByPolicy(permName,pkgName); 197 | } 198 | 199 | @Override 200 | public boolean addPermission(PermissionInfo info) { 201 | return packageManager.addPermission(info); 202 | } 203 | 204 | @Override 205 | public boolean addPermissionAsync(PermissionInfo info) { 206 | return packageManager.addPermissionAsync(info); 207 | } 208 | 209 | @Override 210 | public void removePermission(String name) { 211 | packageManager.removePermission(name); 212 | } 213 | 214 | @Override 215 | public int checkSignatures(String pkg1, String pkg2) { 216 | return packageManager.checkSignatures(pkg1, pkg2); 217 | } 218 | 219 | @Override 220 | public int checkSignatures(int uid1, int uid2) { 221 | return packageManager.checkSignatures(uid1, uid2); 222 | } 223 | 224 | @Override 225 | public String[] getPackagesForUid(int uid) { 226 | return packageManager.getPackagesForUid(uid); 227 | } 228 | 229 | @Override 230 | public String getNameForUid(int uid) { 231 | return packageManager.getNameForUid(uid); 232 | } 233 | 234 | @SuppressWarnings("unchecked") 235 | @Override 236 | public List getInstalledPackages(int flags) { 237 | return packageManager.getInstalledPackages(flags); 238 | } 239 | 240 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) 241 | @SuppressWarnings("unchecked") 242 | @Override 243 | public List getPackagesHoldingPermissions( 244 | String[] permissions, int flags) { 245 | return packageManager.getPackagesHoldingPermissions(permissions,flags); 246 | } 247 | 248 | @SuppressWarnings("unchecked") 249 | @Override 250 | public List getInstalledApplications(int flags) { 251 | return packageManager.getInstalledApplications(flags); 252 | } 253 | 254 | @Override 255 | public ResolveInfo resolveActivity(Intent intent, int flags) { 256 | ComponentName componentName = intent.getComponent(); 257 | Log.d(TAG,"resolveActivity" + componentName.getClassName()); 258 | intent.setComponent(new ComponentName(realPackageName,componentName.getClassName())); 259 | intent.setPackage(realPackageName); 260 | return packageManager.resolveActivity(intent,flags); 261 | } 262 | 263 | @Override 264 | public List queryIntentActivities(Intent intent, 265 | int flags) { 266 | return packageManager.queryIntentActivities(intent,flags); 267 | } 268 | 269 | 270 | @Override 271 | @SuppressWarnings("unchecked") 272 | public List queryIntentActivityOptions( 273 | ComponentName caller, Intent[] specifics, Intent intent, 274 | int flags) { 275 | return packageManager.queryIntentActivityOptions(caller,specifics,intent,flags); 276 | } 277 | 278 | @Override 279 | public List queryBroadcastReceivers(Intent intent, int flags) { 280 | return packageManager.queryBroadcastReceivers(intent, flags); 281 | } 282 | 283 | @Override 284 | public ResolveInfo resolveService(Intent intent, int flags) { 285 | ComponentName componentName = intent.getComponent(); 286 | Log.d(TAG,"resolveService" + componentName.getClassName()); 287 | intent.setComponent(new ComponentName(realPackageName,componentName.getClassName())); 288 | intent.setPackage(realPackageName); 289 | return packageManager.resolveService(intent, flags); 290 | } 291 | 292 | @Override 293 | public List queryIntentServices(Intent intent, int flags) { 294 | return packageManager.queryIntentServices(intent, flags); 295 | } 296 | 297 | @RequiresApi(api = Build.VERSION_CODES.KITKAT) 298 | @Override 299 | public List queryIntentContentProviders(Intent intent, int flags) { 300 | return packageManager.queryIntentContentProviders(intent, flags); 301 | } 302 | 303 | @Override 304 | public ProviderInfo resolveContentProvider(String name, int flags) { 305 | return packageManager.resolveContentProvider(name, flags); 306 | } 307 | 308 | 309 | @Override 310 | @SuppressWarnings("unchecked") 311 | public List queryContentProviders(String processName, 312 | int uid, int flags) { 313 | return packageManager.queryContentProviders(processName, uid, flags); 314 | } 315 | 316 | @Override 317 | public InstrumentationInfo getInstrumentationInfo( 318 | ComponentName className, int flags) 319 | throws NameNotFoundException { 320 | return packageManager.getInstrumentationInfo(className, flags); 321 | } 322 | 323 | @Override 324 | @SuppressWarnings("unchecked") 325 | public List queryInstrumentation( 326 | String targetPackage, int flags) { 327 | return packageManager.queryInstrumentation(targetPackage, flags); 328 | } 329 | 330 | @Override 331 | public Drawable getDrawable(String packageName, int resId, 332 | ApplicationInfo appInfo) { 333 | Log.w(TAG, "getDrawable() "); 334 | return packageManager.getDrawable(packageName, resId, appInfo); 335 | } 336 | 337 | @Override public Drawable getActivityIcon(ComponentName activityName) 338 | throws NameNotFoundException { 339 | return packageManager.getActivityIcon(activityName); 340 | } 341 | 342 | @Override public Drawable getActivityIcon(Intent intent) 343 | throws NameNotFoundException { 344 | if (intent.getComponent() != null) { 345 | return getActivityIcon(intent.getComponent()); 346 | } 347 | 348 | ResolveInfo info = resolveActivity( 349 | intent, PackageManager.MATCH_DEFAULT_ONLY); 350 | if (info != null) { 351 | return info.activityInfo.loadIcon(this); 352 | } 353 | 354 | throw new NameNotFoundException(intent.toUri(0)); 355 | } 356 | 357 | @Override public Drawable getDefaultActivityIcon() { 358 | return packageManager.getDefaultActivityIcon(); 359 | } 360 | 361 | @Override public Drawable getApplicationIcon(ApplicationInfo info) { 362 | return info.loadIcon(this); 363 | } 364 | 365 | @Override public Drawable getApplicationIcon(String packageName) 366 | throws NameNotFoundException { 367 | Log.w(TAG, "getApplicationIcon() "); 368 | return packageManager.getApplicationIcon(packageName); 369 | } 370 | 371 | @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) 372 | @Override 373 | public Drawable getActivityBanner(ComponentName activityName) 374 | throws NameNotFoundException { 375 | return packageManager.getActivityBanner(activityName); 376 | } 377 | 378 | @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) 379 | @Override 380 | public Drawable getActivityBanner(Intent intent) 381 | throws NameNotFoundException { 382 | return packageManager.getActivityBanner(intent); 383 | } 384 | 385 | @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) 386 | @Override 387 | public Drawable getApplicationBanner(ApplicationInfo info) { 388 | return packageManager.getApplicationBanner(info); 389 | } 390 | 391 | @RequiresApi(api = Build.VERSION_CODES.KITKAT_WATCH) 392 | @Override 393 | public Drawable getApplicationBanner(String packageName) 394 | throws NameNotFoundException { 395 | Log.w(TAG, "getApplicationBanner() "); 396 | return packageManager.getApplicationBanner(packageName); 397 | } 398 | 399 | @Override 400 | public Drawable getActivityLogo(ComponentName activityName) 401 | throws NameNotFoundException { 402 | return packageManager.getActivityLogo(activityName); 403 | } 404 | 405 | @Override 406 | public Drawable getActivityLogo(Intent intent) 407 | throws NameNotFoundException { 408 | if (intent.getComponent() != null) { 409 | return getActivityLogo(intent.getComponent()); 410 | } 411 | 412 | ResolveInfo info = resolveActivity( 413 | intent, PackageManager.MATCH_DEFAULT_ONLY); 414 | if (info != null) { 415 | return info.activityInfo.loadLogo(this); 416 | } 417 | 418 | throw new NameNotFoundException(intent.toUri(0)); 419 | } 420 | 421 | @Override 422 | public Drawable getApplicationLogo(ApplicationInfo info) { 423 | return info.loadLogo(this); 424 | } 425 | 426 | @Override 427 | public Drawable getApplicationLogo(String packageName) 428 | throws NameNotFoundException { 429 | Log.w(TAG, "getApplicationLogo() "); 430 | return packageManager.getApplicationLogo(packageName); 431 | } 432 | 433 | 434 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 435 | @Override 436 | public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) { 437 | return packageManager.getUserBadgedIcon(icon,user); 438 | } 439 | 440 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 441 | @Override 442 | public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, 443 | Rect badgeLocation, int badgeDensity) { 444 | return packageManager.getUserBadgedDrawableForDensity(drawable,user,badgeLocation,badgeDensity); 445 | } 446 | 447 | 448 | 449 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 450 | @Override 451 | public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) { 452 | return packageManager.getUserBadgedLabel(label,user); 453 | } 454 | 455 | @Override 456 | public Resources getResourcesForActivity(ComponentName activityName) 457 | throws NameNotFoundException { 458 | return packageManager.getResourcesForActivity(activityName); 459 | } 460 | 461 | @Override 462 | public Resources getResourcesForApplication(ApplicationInfo app) 463 | throws NameNotFoundException { 464 | return packageManager.getResourcesForApplication(app); 465 | } 466 | 467 | @Override 468 | public Resources getResourcesForApplication(String appPackageName) 469 | throws NameNotFoundException { 470 | Log.w(TAG, "getResourcesForApplication() "); 471 | return packageManager.getResourcesForApplication(appPackageName); 472 | } 473 | 474 | 475 | @Override 476 | public boolean isSafeMode() { 477 | return packageManager.isSafeMode(); 478 | } 479 | 480 | 481 | @Override 482 | public CharSequence getText(String packageName, int resid, 483 | ApplicationInfo appInfo) { 484 | Log.w(TAG, "getText() "); 485 | return packageManager.getText(packageName,resid,appInfo); 486 | } 487 | 488 | @Override 489 | public XmlResourceParser getXml(String packageName, int resid, 490 | ApplicationInfo appInfo) { 491 | Log.w(TAG, "getXml() "); 492 | return packageManager.getXml(packageName,resid,appInfo); 493 | } 494 | 495 | @Override 496 | public CharSequence getApplicationLabel(ApplicationInfo info) { 497 | Log.w(TAG, "getApplicationLabel() "); 498 | return packageManager.getApplicationLabel(info); 499 | } 500 | 501 | 502 | @Override 503 | public void verifyPendingInstall(int id, int response) { 504 | Log.w(TAG, "verifyPendingInstall() "); 505 | packageManager.verifyPendingInstall(id,response); 506 | } 507 | 508 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 509 | @Override 510 | public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, 511 | long millisecondsToDelay) { 512 | Log.w(TAG, "extendVerificationTimeout() "); 513 | packageManager.extendVerificationTimeout(id,verificationCodeAtTimeout,millisecondsToDelay); 514 | } 515 | 516 | 517 | @Override 518 | public void setInstallerPackageName(String targetPackage, 519 | String installerPackageName) { 520 | Log.w(TAG, "setInstallerPackageName() "); 521 | packageManager.setInstallerPackageName(targetPackage,installerPackageName); 522 | } 523 | 524 | @Override 525 | public String getInstallerPackageName(String packageName) { 526 | Log.w(TAG, "getInstallerPackageName() "); 527 | return packageManager.getInstallerPackageName(packageName); 528 | } 529 | 530 | 531 | @Override 532 | public void addPackageToPreferred(String packageName) { 533 | Log.w(TAG, "addPackageToPreferred() "); 534 | packageManager.addPackageToPreferred(packageName); 535 | } 536 | 537 | @Override 538 | public void removePackageFromPreferred(String packageName) { 539 | Log.w(TAG, "removePackageFromPreferred() is a no-op"); 540 | packageManager.removePackageFromPreferred(packageName); 541 | } 542 | 543 | @Override 544 | public List getPreferredPackages(int flags) { 545 | Log.w(TAG, "getPreferredPackages() is a no-op"); 546 | return packageManager.getPreferredPackages(flags); 547 | } 548 | 549 | @Override 550 | public void addPreferredActivity(IntentFilter filter, 551 | int match, ComponentName[] set, ComponentName activity) { 552 | Log.w(TAG, "addPreferredActivity() "); 553 | packageManager.addPreferredActivity(filter, match, set, activity); 554 | } 555 | 556 | 557 | 558 | @Override 559 | public void clearPackagePreferredActivities(String packageName) { 560 | Log.w(TAG, "clearPackagePreferredActivities() "); 561 | packageManager.clearPackagePreferredActivities(packageName); 562 | } 563 | 564 | @Override 565 | public int getPreferredActivities(List outFilters, 566 | List outActivities, String packageName) { 567 | Log.w(TAG, "getPreferredActivities() "); 568 | return packageManager.getPreferredActivities(outFilters,outActivities,packageName); 569 | } 570 | 571 | @Override 572 | public void setComponentEnabledSetting(ComponentName componentName, 573 | int newState, int flags) { 574 | packageManager.setComponentEnabledSetting(componentName,newState,flags); 575 | } 576 | 577 | @Override 578 | public int getComponentEnabledSetting(ComponentName componentName) { 579 | return packageManager.getComponentEnabledSetting(componentName); 580 | } 581 | 582 | @Override 583 | public void setApplicationEnabledSetting(String packageName, 584 | int newState, int flags) { 585 | Log.w(TAG, "setApplicationEnabledSetting() "); 586 | packageManager.setApplicationEnabledSetting(packageName,newState,flags); 587 | } 588 | 589 | @Override 590 | public int getApplicationEnabledSetting(String packageName) { 591 | Log.w(TAG, "getApplicationEnabledSetting() "); 592 | return packageManager.getApplicationEnabledSetting(packageName); 593 | } 594 | 595 | 596 | public boolean getApplicationHiddenSettingAsUser(String packageName, UserHandle user) { 597 | Log.w(TAG, "getApplicationHiddenSettingAsUser() "); 598 | return getApplicationHiddenSettingAsUser(packageName,user); 599 | } 600 | 601 | 602 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 603 | @Override 604 | public PackageInstaller getPackageInstaller() { 605 | Log.w(TAG, "getPackageInstaller() "); 606 | return packageManager.getPackageInstaller(); 607 | } 608 | 609 | } 610 | -------------------------------------------------------------------------------- /app/src/main/java/com/ghost/thunder/Download.java: -------------------------------------------------------------------------------- 1 | package com.ghost.thunder; 2 | 3 | public class Download { 4 | long taskId, mFileSize, mDownloadSize, mDownloadSpeed, mAdditionalResDCDNSpeed; 5 | String path, url, filename; 6 | 7 | public Download(long taskId, String url, String path, String filename) { 8 | super(); 9 | this.taskId = taskId; 10 | this.url = url; 11 | this.path = path; 12 | this.filename = filename; 13 | } 14 | 15 | public Download(){ 16 | super(); 17 | } 18 | 19 | /* 20 | public String getUserName() { 21 | return userName; 22 | } 23 | 24 | public void setUserName(String userName) { 25 | this.userName = userName; 26 | } 27 | 28 | public int getUserRank() { 29 | return userRank; 30 | } 31 | 32 | public void setUserRank(int userRank) { 33 | this.userRank = userRank; 34 | } 35 | */ 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/ghost/thunder/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.ghost.thunder; 2 | 3 | import android.app.Activity; 4 | import android.app.AlertDialog; 5 | import android.content.ClipData; 6 | import android.content.ClipboardManager; 7 | import android.content.DialogInterface; 8 | import android.content.Intent; 9 | import android.database.Cursor; 10 | import android.graphics.Color; 11 | import android.graphics.drawable.ColorDrawable; 12 | import android.net.Uri; 13 | import android.os.Environment; 14 | import android.os.Handler; 15 | import android.os.Looper; 16 | import android.os.Message; 17 | import android.support.v7.app.AppCompatActivity; 18 | import android.os.Bundle; 19 | import android.util.Log; 20 | import android.view.KeyEvent; 21 | import android.view.LayoutInflater; 22 | import android.view.Menu; 23 | import android.view.MenuItem; 24 | import android.view.View; 25 | import android.view.ViewGroup; 26 | import android.view.WindowManager; 27 | import android.webkit.MimeTypeMap; 28 | import android.widget.AdapterView; 29 | import android.widget.BaseAdapter; 30 | import android.widget.EditText; 31 | import android.widget.ImageButton; 32 | import android.widget.ListView; 33 | import android.widget.ProgressBar; 34 | import android.widget.TextView; 35 | import android.widget.Toast; 36 | 37 | import com.ghost.thunder.demo.R; 38 | 39 | import com.xunlei.downloadlib.XLTaskHelper; 40 | import com.xunlei.downloadlib.parameter.XLTaskInfo; 41 | 42 | import java.text.SimpleDateFormat; 43 | import java.util.ArrayList; 44 | import java.util.Date; 45 | import java.util.TimeZone; 46 | 47 | public class MainActivity extends AppCompatActivity { 48 | 49 | EditText editText_new_url, editText_new_path; 50 | String filepath = "", path = ""; 51 | SimpleDateFormat SDF = new SimpleDateFormat("HH:mm:ss"); 52 | ArrayList list_download = new ArrayList<>(); 53 | ListView listView; 54 | MyBaseAdapter adapter; 55 | 56 | Handler handler = new Handler(Looper.getMainLooper()){ 57 | @Override 58 | public void handleMessage(Message msg) { 59 | super.handleMessage(msg); 60 | if(msg.what == 0) { 61 | long taskId = (long) msg.obj; 62 | XLTaskInfo taskInfo = XLTaskHelper.instance(getApplicationContext()).getTaskInfo(taskId); 63 | filepath = Environment.getExternalStorageDirectory().getPath() + "/" + taskInfo.mFileName; 64 | for(int i=0; i adapterView, View view, int position, long id) { 98 | int i = list_download.size() - position -1; // 倒序还原 99 | String filepath = list_download.get(i).path + "/" + list_download.get(i).filename; 100 | if(!filepath.equals("")) { 101 | String suffix = MimeTypeMap.getFileExtensionFromUrl(filepath); 102 | String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(suffix); 103 | Log.e("line127", filepath); 104 | Log.e("line128", suffix + " = " + type); 105 | Intent intent = new Intent(Intent.ACTION_VIEW); 106 | intent.setDataAndType(Uri.parse("file://" + filepath), type); 107 | startActivity(intent); 108 | } 109 | } 110 | }); 111 | 112 | } 113 | 114 | @Override 115 | public boolean onCreateOptionsMenu(Menu menu) { 116 | menu.add(0, 0, 0, "新建"); 117 | menu.add(0, 1, 1, "关于"); 118 | menu.add(0, 2, 2, "更新日志"); 119 | menu.add(0, 3, 3, "退出"); 120 | return true; 121 | } 122 | 123 | @Override 124 | public boolean onOptionsItemSelected(MenuItem item) { 125 | int item_id = item.getItemId(); 126 | switch (item_id) { 127 | case 0: 128 | dialog_new_download(); 129 | break; 130 | case 1: 131 | new AlertDialog.Builder(this).setIcon(R.mipmap.ic_launcher) 132 | .setTitle("迷你迅雷 V1.0") 133 | .setMessage("使用 https://github.com/oceanzhang01/MiniThunder 提供的迅雷模块。\n作者:黄颖\nQQ:84429027") 134 | .setPositiveButton("确定", null).show(); 135 | break; 136 | case 2: 137 | new AlertDialog.Builder(this) 138 | .setIcon(R.mipmap.ic_launcher) 139 | .setTitle("更新日志") 140 | .setMessage("V1.0 (2018)\n1.增加打开文件、进度百分比、字节转换、剩余时长、下载列表、列表更新、新建下载对话框。") 141 | .setPositiveButton("确定", null).show(); 142 | break; 143 | case 3: 144 | finish(); 145 | break; 146 | } 147 | return true; 148 | } 149 | 150 | @Override 151 | public boolean onKeyDown(int keyCode, KeyEvent event) { 152 | if (keyCode == KeyEvent.KEYCODE_BACK) { 153 | moveTaskToBack(false); 154 | return true; 155 | } 156 | return super.onKeyDown(keyCode, event); 157 | } 158 | 159 | String convertFileSize(long size) { 160 | long kb = 1024; 161 | long mb = kb * 1024; 162 | long gb = mb * 1024; 163 | 164 | if (size >= gb) { 165 | return String.format("%.1f GB", (float) size / gb); 166 | } else if (size >= mb) { 167 | float f = (float) size / mb; 168 | return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); 169 | } else if (size >= kb) { 170 | float f = (float) size / kb; 171 | return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); 172 | } else 173 | return String.format("%d B", size); 174 | } 175 | 176 | 177 | void dialog_new_download(){ 178 | View view = LayoutInflater.from(this).inflate(R.layout.dialog_new_download, null, false); 179 | final AlertDialog dialog = new AlertDialog.Builder(this) 180 | .setTitle("新建下载") 181 | .setIcon(R.mipmap.ic_launcher) 182 | .setView(view) 183 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 184 | @Override 185 | public void onClick(DialogInterface dialog, int which) { 186 | //Toast.makeText(getApplicationContext(), "开始下载", Toast.LENGTH_SHORT).show(); 187 | String url = editText_new_url.getText().toString(); 188 | if(!url.equals("")) { 189 | long taskId = 0; 190 | try { 191 | taskId = XLTaskHelper.instance(getApplicationContext()).addThunderTask(url, path, null); 192 | String filename = XLTaskHelper.instance(getApplicationContext()).getFileName(editText_new_url.getText().toString()); 193 | list_download.add(new Download(taskId, url, path, filename)); 194 | } catch (Exception e) { 195 | e.printStackTrace(); 196 | } 197 | handler.sendMessage(handler.obtainMessage(0, taskId)); 198 | } 199 | } 200 | }) 201 | .setNegativeButton("取消", new DialogInterface.OnClickListener() { 202 | @Override 203 | public void onClick(DialogInterface dialog, int which) { 204 | } 205 | }) 206 | .setNeutralButton("打开BT种子", new DialogInterface.OnClickListener() { 207 | @Override 208 | public void onClick(DialogInterface dialog, int which) { 209 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 210 | intent.setType("application/x-bittorrent"); 211 | startActivityForResult(intent, 2); 212 | } 213 | }) 214 | .create(); 215 | 216 | editText_new_url = (EditText) view.findViewById(R.id.editText_new_url); 217 | EditText editText_new_filename = (EditText) view.findViewById(R.id.editText_new_filename); 218 | editText_new_path = (EditText) view.findViewById(R.id.editText_new_path); 219 | ImageButton imageButton_path = (ImageButton) view.findViewById(R.id.imageButton_path); 220 | 221 | // 获取剪贴板文本,填入网址和文件名 222 | ClipboardManager CM = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 223 | ClipData data = CM.getPrimaryClip(); 224 | if(data != null) { 225 | ClipData.Item item = data.getItemAt(0); 226 | String s = item.getText().toString(); 227 | if (s.contains("://") || s.startsWith("magnet:?xt=urn:btih:")) { 228 | editText_new_url.setText(s); 229 | editText_new_filename.setText(XLTaskHelper.instance(getApplicationContext()).getFileName(s)); 230 | } 231 | } 232 | String path = Environment.getExternalStorageDirectory().getPath() + "/"; 233 | editText_new_path.setText(path); 234 | 235 | dialog.show(); 236 | 237 | //此处设置位置窗体大小,我这里设置为了手机屏幕宽度的3/4 238 | //dialog.getWindow().setLayout((ScreenUtils.getScreenWidth(this)/4*3), LinearLayout.LayoutParams.WRAP_CONTENT); 239 | 240 | imageButton_path.setOnClickListener(new View.OnClickListener() { 241 | @Override 242 | public void onClick(View v) { 243 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 244 | intent.setType("*/*"); 245 | startActivityForResult(intent, 1); 246 | } 247 | }); 248 | } 249 | 250 | 251 | @Override 252 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 253 | if (resultCode == Activity.RESULT_OK) { //是否选择,没选择就不会继续 254 | Uri uri = data.getData(); // 得到uri,后面就是将uri转化成file的过程。 255 | //String scheme = uri.getScheme(); 256 | Log.e("uri", uri.toString()); 257 | String[] projection = { "_data" }; 258 | Cursor cursor = getContentResolver().query(uri, projection, null, null, null); 259 | if(cursor != null) { 260 | int column_index = cursor.getColumnIndexOrThrow("_data"); 261 | cursor.moveToFirst(); 262 | String filepath = cursor.getString(column_index); 263 | Log.e("filepath", filepath); 264 | if (requestCode == 1) { 265 | int endIndex = filepath.lastIndexOf("/"); 266 | if (endIndex != -1) { 267 | path = filepath.substring(0, endIndex); 268 | Log.e("path", path); 269 | //Toast.makeText(MainActivity.this, path, Toast.LENGTH_SHORT).show(); 270 | editText_new_path.setText(path); 271 | } 272 | } else if (requestCode == 2) { 273 | Toast.makeText(MainActivity.this, filepath, Toast.LENGTH_SHORT).show(); 274 | } 275 | } 276 | } 277 | } 278 | 279 | 280 | class MyBaseAdapter extends BaseAdapter { 281 | @Override 282 | public int getCount() { 283 | return list_download.size(); 284 | } 285 | 286 | @Override 287 | public Object getItem(int i) { 288 | return i; 289 | } 290 | 291 | @Override 292 | public long getItemId(int i) { 293 | return i; 294 | } 295 | 296 | @Override 297 | public View getView(int i, View view, ViewGroup viewGroup) { 298 | if (view == null) { 299 | view = getLayoutInflater().inflate(R.layout.listview_item, viewGroup, false); 300 | } 301 | 302 | TextView textView_taskId = (TextView) view.findViewById(R.id.textView_taskId); 303 | TextView textView_url = (TextView) view.findViewById(R.id.textView_url); 304 | TextView textView_filename = (TextView) view.findViewById(R.id.textView_filename); 305 | TextView textView_filesize = (TextView) view.findViewById(R.id.textView_filesize); 306 | TextView textView_downloadSize = (TextView) view.findViewById(R.id.textView_downloadSize); 307 | TextView textView_progress = (TextView) view.findViewById(R.id.textView_progress); 308 | TextView textView_downloadSpeed = (TextView) view.findViewById(R.id.textView_downloadSpeed); 309 | TextView textView_DCDNSpeed = (TextView) view.findViewById(R.id.textView_DCDNSpeed); 310 | TextView textView_timeLeft = (TextView) view.findViewById(R.id.textView_timeLeft); 311 | ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.progressBar); 312 | 313 | int j = getCount() - i -1; // 实现倒序 314 | textView_taskId.setText("taskId:" + list_download.get(j).taskId + ""); 315 | textView_url.setText("下载地址:" + list_download.get(j).url); 316 | textView_filename.setText("文件名:" + list_download.get(j).filename); 317 | textView_filesize.setText("文件大小:" + convertFileSize(list_download.get(j).mFileSize)); 318 | textView_downloadSize.setText("已下载:" + convertFileSize(list_download.get(j).mDownloadSize)); 319 | 320 | int progress; 321 | if(list_download.get(j).mFileSize != 0){ 322 | progress = (int)(list_download.get(j).mDownloadSize * 100 / list_download.get(j).mFileSize); 323 | }else{ 324 | progress = 0; 325 | } 326 | textView_progress.setText("进度:" + progress + "%"); 327 | progressBar.setProgress(progress); 328 | 329 | textView_downloadSpeed.setText("速度:" + convertFileSize(list_download.get(j).mDownloadSpeed) + "/s"); 330 | textView_DCDNSpeed.setText("DCDN速度:" + convertFileSize(list_download.get(j).mAdditionalResDCDNSpeed) + "/s"); 331 | 332 | long duration_left = 0; 333 | if(list_download.get(j).mDownloadSpeed != 0){ 334 | duration_left = (list_download.get(j).mFileSize - list_download.get(j).mDownloadSize) / list_download.get(j).mDownloadSpeed * 1000; 335 | } 336 | Date date = new Date(duration_left); 337 | textView_timeLeft.setText("剩余时间:" + SDF.format(date)); 338 | 339 | return view; 340 | } 341 | } 342 | 343 | } -------------------------------------------------------------------------------- /app/src/main/java/com/ghost/thunder/MyApp.java: -------------------------------------------------------------------------------- 1 | package com.ghost.thunder; 2 | 3 | import android.app.Application; 4 | import android.content.pm.PackageManager; 5 | import android.util.Log; 6 | 7 | /** 8 | * Created by oceanzhang on 2017/9/28. 9 | */ 10 | 11 | public class MyApp extends Application{ 12 | 13 | public static MyApp instance = null; 14 | 15 | @Override 16 | public void onCreate() { 17 | super.onCreate(); 18 | instance = this; 19 | } 20 | 21 | public static MyApp appInstance() { 22 | return instance; 23 | } 24 | @Override 25 | public String getPackageName() { 26 | if(Log.getStackTraceString(new Throwable()).contains("com.xunlei.downloadlib")) { 27 | return "com.xunlei.downloadprovider"; 28 | } 29 | return super.getPackageName(); 30 | } 31 | @Override 32 | public PackageManager getPackageManager() { 33 | if(Log.getStackTraceString(new Throwable()).contains("com.xunlei.downloadlib")) { 34 | return new DelegateApplicationPackageManager(super.getPackageManager()); 35 | } 36 | return super.getPackageManager(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/progressbar_color.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 15 | 16 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_new_download.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | 25 | 26 | 34 | 35 | 43 | 44 | 53 | 54 | 62 | 63 | 70 | 71 | 79 | 80 | 87 | 88 | -------------------------------------------------------------------------------- /app/src/main/res/layout/listview_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 18 | 19 | 25 | 26 | 33 | 34 | 40 | 41 | 47 | 48 | 54 | 55 | 61 | 62 | 68 | 69 | 75 | 76 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app/src/main/res/mipmap-xhdpi/folder.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #0000FF 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 迷你迅雷 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /preview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/preview.jpg -------------------------------------------------------------------------------- /thunder/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/BlockingItem.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | import java.util.concurrent.locks.Condition; 5 | import java.util.concurrent.locks.Lock; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | 8 | public class BlockingItem { 9 | final Lock lock = new ReentrantLock(); 10 | final Condition notEmpty = lock.newCondition(); 11 | 12 | private volatile T item; 13 | 14 | public void put(T x) { 15 | lock.lock(); 16 | try { 17 | item = x; 18 | if (x != null) 19 | notEmpty.signal(); 20 | } finally { 21 | lock.unlock(); 22 | } 23 | } 24 | 25 | public T take() throws InterruptedException { 26 | lock.lock(); 27 | try { 28 | while (item == null) 29 | notEmpty.await(); 30 | T t = item; 31 | item = null; 32 | return t; 33 | } finally { 34 | lock.unlock(); 35 | } 36 | } 37 | 38 | public T tryTake(long waitMs) throws InterruptedException { 39 | lock.lock(); 40 | try { 41 | while (item == null) 42 | if (!notEmpty.await(waitMs, TimeUnit.MILLISECONDS)) 43 | return null; 44 | T t = item; 45 | item = null; 46 | return t; 47 | } finally { 48 | lock.unlock(); 49 | } 50 | } 51 | 52 | public T peek() { 53 | return item; 54 | } 55 | } -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/Daemon.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib; 2 | 3 | import android.os.Looper; 4 | 5 | /** 6 | * 常驻的后台线程,用于处理一个消息循环 7 | *

8 | * 一般用于处理运算密集型任务、磁盘IO任务等执行时间小于1秒的任务 9 | * 10 | */ 11 | public class Daemon { 12 | private static volatile boolean shouldStop; 13 | private static Thread thread = null; 14 | private static Looper looper = null; 15 | 16 | public static synchronized void start() { 17 | if (thread == null) { 18 | final BlockingItem bl = new BlockingItem(); 19 | thread = new Thread(new Runnable() { 20 | @Override 21 | public void run() { 22 | Looper.prepare(); 23 | Looper l = Looper.myLooper(); 24 | bl.put(l); 25 | 26 | while (!shouldStop) { 27 | try { 28 | Looper.loop(); 29 | } catch (Exception e) { 30 | } 31 | } 32 | } 33 | }, "daemon"); 34 | 35 | shouldStop = false; 36 | thread.start(); 37 | try { 38 | looper = bl.take(); 39 | } catch (InterruptedException e) { 40 | } 41 | } 42 | } 43 | 44 | public static synchronized void stop() { 45 | shouldStop = true; 46 | 47 | if (thread != null && looper != null) { 48 | looper.quit(); 49 | try { 50 | thread.join(); 51 | } catch (Exception e) { 52 | } 53 | thread = null; 54 | looper = null; 55 | } 56 | } 57 | 58 | public static Looper looper() { 59 | if (looper == null) { 60 | start(); 61 | } 62 | return looper == null ? Looper.getMainLooper() : looper; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/DelegateApplication.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib; 2 | 3 | import android.app.Application; 4 | import android.content.BroadcastReceiver; 5 | import android.content.ComponentCallbacks; 6 | import android.content.ComponentName; 7 | import android.content.ContentResolver; 8 | import android.content.Context; 9 | import android.content.Intent; 10 | import android.content.IntentFilter; 11 | import android.content.IntentSender; 12 | import android.content.ServiceConnection; 13 | import android.content.SharedPreferences; 14 | import android.content.pm.ApplicationInfo; 15 | import android.content.pm.PackageManager; 16 | import android.content.res.AssetManager; 17 | import android.content.res.Configuration; 18 | import android.content.res.Resources; 19 | import android.database.DatabaseErrorHandler; 20 | import android.database.sqlite.SQLiteDatabase; 21 | import android.graphics.Bitmap; 22 | import android.graphics.drawable.Drawable; 23 | import android.net.Uri; 24 | import android.os.Build; 25 | import android.os.Bundle; 26 | import android.os.Handler; 27 | import android.os.Looper; 28 | import android.os.UserHandle; 29 | import android.support.annotation.RequiresApi; 30 | import android.util.Log; 31 | import android.view.Display; 32 | 33 | import java.io.File; 34 | import java.io.FileInputStream; 35 | import java.io.FileNotFoundException; 36 | import java.io.FileOutputStream; 37 | import java.io.IOException; 38 | import java.io.InputStream; 39 | 40 | /** 41 | * Created by oceanzhang on 16/10/8. 42 | */ 43 | 44 | public class DelegateApplication extends Application { 45 | private Application app; 46 | 47 | public DelegateApplication(Application app) { 48 | this.app = app; 49 | } 50 | 51 | private static final String TAG = "DelegateApplication"; 52 | @Override 53 | public Context getBaseContext() { 54 | Log.d(TAG,"----getBaseContext"); 55 | return app.getBaseContext(); 56 | } 57 | 58 | @Override 59 | public AssetManager getAssets() { 60 | return app.getAssets(); 61 | } 62 | 63 | @Override 64 | public Resources getResources() { 65 | return app.getResources(); 66 | } 67 | 68 | @Override 69 | public PackageManager getPackageManager() { 70 | Log.d(TAG,"----getPackageManager"); 71 | return app.getPackageManager(); 72 | } 73 | 74 | @Override 75 | public ContentResolver getContentResolver() { 76 | return app.getContentResolver(); 77 | } 78 | 79 | @Override 80 | public Looper getMainLooper() { 81 | return app.getMainLooper(); 82 | } 83 | 84 | @Override 85 | public Context getApplicationContext() { 86 | Log.d(TAG,"----getApplicationContext"); 87 | return app.getApplicationContext(); 88 | } 89 | 90 | @Override 91 | public void setTheme(int resid) { 92 | app.setTheme(resid); 93 | } 94 | 95 | @Override 96 | public Resources.Theme getTheme() { 97 | return app.getTheme(); 98 | } 99 | 100 | @Override 101 | public ClassLoader getClassLoader() { 102 | Log.d(TAG,"----getBaseContext"); 103 | return app.getClassLoader(); 104 | } 105 | 106 | @Override 107 | public String getPackageName() { 108 | Log.d(TAG,"----getPackageName"); 109 | return "com.xunlei.downloadprovider"; 110 | } 111 | 112 | @Override 113 | public ApplicationInfo getApplicationInfo() { 114 | Log.d(TAG,"----getApplicationInfo"); 115 | return app.getApplicationInfo(); 116 | } 117 | 118 | @Override 119 | public String getPackageResourcePath() { 120 | Log.d(TAG,"----getBaseContext"); 121 | return app.getPackageResourcePath(); 122 | } 123 | 124 | @Override 125 | public String getPackageCodePath() { 126 | Log.d(TAG,"----getBaseContext"); 127 | return app.getPackageCodePath(); 128 | } 129 | 130 | @Override 131 | public SharedPreferences getSharedPreferences(String name, int mode) { 132 | Log.d(TAG,"----getBaseContext"); 133 | return app.getSharedPreferences(name, mode); 134 | } 135 | 136 | @RequiresApi(api = Build.VERSION_CODES.N) 137 | @Override 138 | public boolean moveSharedPreferencesFrom(Context sourceContext, String name) { 139 | Log.d(TAG,"----getBaseContext"); 140 | return app.moveSharedPreferencesFrom(sourceContext, name); 141 | } 142 | 143 | @RequiresApi(api = Build.VERSION_CODES.N) 144 | @Override 145 | public boolean deleteSharedPreferences(String name) { 146 | Log.d(TAG,"----getBaseContext"); 147 | return app.deleteSharedPreferences(name); 148 | } 149 | 150 | @Override 151 | public FileInputStream openFileInput(String name) throws FileNotFoundException { 152 | Log.d(TAG,"----getBaseContext"); 153 | return app.openFileInput(name); 154 | } 155 | 156 | @Override 157 | public FileOutputStream openFileOutput(String name, int mode) throws FileNotFoundException { 158 | Log.d(TAG,"----getBaseContext"); 159 | return app.openFileOutput(name, mode); 160 | } 161 | 162 | @Override 163 | public boolean deleteFile(String name) { 164 | Log.d(TAG,"----getBaseContext"); 165 | return app.deleteFile(name); 166 | } 167 | 168 | @Override 169 | public File getFileStreamPath(String name) { 170 | Log.d(TAG,"----getBaseContext"); 171 | return app.getFileStreamPath(name); 172 | } 173 | 174 | @Override 175 | public String[] fileList() { 176 | return app.fileList(); 177 | } 178 | 179 | @RequiresApi(api = Build.VERSION_CODES.N) 180 | @Override 181 | public File getDataDir() { 182 | return app.getDataDir(); 183 | } 184 | 185 | @Override 186 | public File getFilesDir() { 187 | return app.getFilesDir(); 188 | } 189 | 190 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 191 | @Override 192 | public File getNoBackupFilesDir() { 193 | return app.getNoBackupFilesDir(); 194 | } 195 | 196 | @Override 197 | public File getExternalFilesDir(String type) { 198 | return app.getExternalFilesDir(type); 199 | } 200 | 201 | @RequiresApi(api = Build.VERSION_CODES.KITKAT) 202 | @Override 203 | public File[] getExternalFilesDirs(String type) { 204 | return app.getExternalFilesDirs(type); 205 | } 206 | 207 | @Override 208 | public File getObbDir() { 209 | return app.getObbDir(); 210 | } 211 | 212 | @RequiresApi(api = Build.VERSION_CODES.KITKAT) 213 | @Override 214 | public File[] getObbDirs() { 215 | return app.getObbDirs(); 216 | } 217 | 218 | @Override 219 | public File getCacheDir() { 220 | return app.getCacheDir(); 221 | } 222 | 223 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 224 | @Override 225 | public File getCodeCacheDir() { 226 | return app.getCodeCacheDir(); 227 | } 228 | 229 | @Override 230 | public File getExternalCacheDir() { 231 | return app.getExternalCacheDir(); 232 | } 233 | 234 | @RequiresApi(api = Build.VERSION_CODES.KITKAT) 235 | @Override 236 | public File[] getExternalCacheDirs() { 237 | return app.getExternalCacheDirs(); 238 | } 239 | 240 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 241 | @Override 242 | public File[] getExternalMediaDirs() { 243 | return app.getExternalMediaDirs(); 244 | } 245 | 246 | @Override 247 | public File getDir(String name, int mode) { 248 | return app.getDir(name, mode); 249 | } 250 | 251 | @Override 252 | public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory) { 253 | return app.openOrCreateDatabase(name, mode, factory); 254 | } 255 | 256 | @Override 257 | public SQLiteDatabase openOrCreateDatabase(String name, int mode, SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) { 258 | return app.openOrCreateDatabase(name, mode, factory, errorHandler); 259 | } 260 | 261 | @RequiresApi(api = Build.VERSION_CODES.N) 262 | @Override 263 | public boolean moveDatabaseFrom(Context sourceContext, String name) { 264 | return app.moveDatabaseFrom(sourceContext, name); 265 | } 266 | 267 | @Override 268 | public boolean deleteDatabase(String name) { 269 | return app.deleteDatabase(name); 270 | } 271 | 272 | @Override 273 | public File getDatabasePath(String name) { 274 | return app.getDatabasePath(name); 275 | } 276 | 277 | @Override 278 | public String[] databaseList() { 279 | return app.databaseList(); 280 | } 281 | 282 | @Override 283 | public Drawable getWallpaper() { 284 | return app.getWallpaper(); 285 | } 286 | 287 | @Override 288 | public Drawable peekWallpaper() { 289 | return app.peekWallpaper(); 290 | } 291 | 292 | @Override 293 | public int getWallpaperDesiredMinimumWidth() { 294 | return app.getWallpaperDesiredMinimumWidth(); 295 | } 296 | 297 | @Override 298 | public int getWallpaperDesiredMinimumHeight() { 299 | return app.getWallpaperDesiredMinimumHeight(); 300 | } 301 | 302 | @Override 303 | public void setWallpaper(Bitmap bitmap) throws IOException { 304 | app.setWallpaper(bitmap); 305 | } 306 | 307 | @Override 308 | public void setWallpaper(InputStream data) throws IOException { 309 | app.setWallpaper(data); 310 | } 311 | 312 | @Override 313 | public void clearWallpaper() throws IOException { 314 | app.clearWallpaper(); 315 | } 316 | 317 | @Override 318 | public void startActivity(Intent intent) { 319 | app.startActivity(intent); 320 | } 321 | 322 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) 323 | @Override 324 | public void startActivity(Intent intent, Bundle options) { 325 | app.startActivity(intent, options); 326 | } 327 | 328 | @Override 329 | public void startActivities(Intent[] intents) { 330 | app.startActivities(intents); 331 | } 332 | 333 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) 334 | @Override 335 | public void startActivities(Intent[] intents, Bundle options) { 336 | app.startActivities(intents, options); 337 | } 338 | 339 | @Override 340 | public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) throws IntentSender.SendIntentException { 341 | app.startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags); 342 | } 343 | 344 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) 345 | @Override 346 | public void startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags, Bundle options) throws IntentSender.SendIntentException { 347 | app.startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, options); 348 | } 349 | 350 | @Override 351 | public void sendBroadcast(Intent intent) { 352 | app.sendBroadcast(intent); 353 | } 354 | 355 | @Override 356 | public void sendBroadcast(Intent intent, String receiverPermission) { 357 | app.sendBroadcast(intent, receiverPermission); 358 | } 359 | 360 | @Override 361 | public void sendOrderedBroadcast(Intent intent, String receiverPermission) { 362 | app.sendOrderedBroadcast(intent, receiverPermission); 363 | } 364 | 365 | @Override 366 | public void sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 367 | app.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras); 368 | } 369 | 370 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 371 | @Override 372 | public void sendBroadcastAsUser(Intent intent, UserHandle user) { 373 | app.sendBroadcastAsUser(intent, user); 374 | } 375 | 376 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 377 | @Override 378 | public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) { 379 | app.sendBroadcastAsUser(intent, user, receiverPermission); 380 | } 381 | 382 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 383 | @Override 384 | public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 385 | app.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver, scheduler, initialCode, initialData, initialExtras); 386 | } 387 | 388 | @Override 389 | public void sendStickyBroadcast(Intent intent) { 390 | app.sendStickyBroadcast(intent); 391 | } 392 | 393 | @Override 394 | public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 395 | app.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, initialData, initialExtras); 396 | } 397 | 398 | @Override 399 | public void removeStickyBroadcast(Intent intent) { 400 | app.removeStickyBroadcast(intent); 401 | } 402 | 403 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 404 | @Override 405 | public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 406 | app.sendStickyBroadcastAsUser(intent, user); 407 | } 408 | 409 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 410 | @Override 411 | public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 412 | app.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode, initialData, initialExtras); 413 | } 414 | 415 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 416 | @Override 417 | public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { 418 | app.removeStickyBroadcastAsUser(intent, user); 419 | } 420 | 421 | @Override 422 | public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 423 | return app.registerReceiver(receiver, filter); 424 | } 425 | 426 | @Override 427 | public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) { 428 | return app.registerReceiver(receiver, filter, broadcastPermission, scheduler); 429 | } 430 | 431 | @Override 432 | public void unregisterReceiver(BroadcastReceiver receiver) { 433 | app.unregisterReceiver(receiver); 434 | } 435 | 436 | @Override 437 | public ComponentName startService(Intent service) { 438 | return app.startService(service); 439 | } 440 | 441 | @Override 442 | public boolean stopService(Intent name) { 443 | return app.stopService(name); 444 | } 445 | 446 | @Override 447 | public boolean bindService(Intent service, ServiceConnection conn, int flags) { 448 | return app.bindService(service, conn, flags); 449 | } 450 | 451 | @Override 452 | public void unbindService(ServiceConnection conn) { 453 | app.unbindService(conn); 454 | } 455 | 456 | @Override 457 | public boolean startInstrumentation(ComponentName className, String profileFile, Bundle arguments) { 458 | return app.startInstrumentation(className, profileFile, arguments); 459 | } 460 | 461 | @Override 462 | public Object getSystemService(String name) { 463 | return app.getSystemService(name); 464 | } 465 | 466 | @RequiresApi(api = Build.VERSION_CODES.M) 467 | @Override 468 | public String getSystemServiceName(Class serviceClass) { 469 | return app.getSystemServiceName(serviceClass); 470 | } 471 | 472 | @Override 473 | public int checkPermission(String permission, int pid, int uid) { 474 | return app.checkPermission(permission, pid, uid); 475 | } 476 | 477 | @Override 478 | public int checkCallingPermission(String permission) { 479 | return app.checkCallingPermission(permission); 480 | } 481 | 482 | @Override 483 | public int checkCallingOrSelfPermission(String permission) { 484 | return app.checkCallingOrSelfPermission(permission); 485 | } 486 | 487 | @RequiresApi(api = Build.VERSION_CODES.M) 488 | @Override 489 | public int checkSelfPermission(String permission) { 490 | return app.checkSelfPermission(permission); 491 | } 492 | 493 | @Override 494 | public void enforcePermission(String permission, int pid, int uid, String message) { 495 | app.enforcePermission(permission, pid, uid, message); 496 | } 497 | 498 | @Override 499 | public void enforceCallingPermission(String permission, String message) { 500 | app.enforceCallingPermission(permission, message); 501 | } 502 | 503 | @Override 504 | public void enforceCallingOrSelfPermission(String permission, String message) { 505 | app.enforceCallingOrSelfPermission(permission, message); 506 | } 507 | 508 | @Override 509 | public void grantUriPermission(String toPackage, Uri uri, int modeFlags) { 510 | app.grantUriPermission(toPackage, uri, modeFlags); 511 | } 512 | 513 | @Override 514 | public void revokeUriPermission(Uri uri, int modeFlags) { 515 | app.revokeUriPermission(uri, modeFlags); 516 | } 517 | 518 | @Override 519 | public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 520 | return app.checkUriPermission(uri, pid, uid, modeFlags); 521 | } 522 | 523 | @Override 524 | public int checkCallingUriPermission(Uri uri, int modeFlags) { 525 | return app.checkCallingUriPermission(uri, modeFlags); 526 | } 527 | 528 | @Override 529 | public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) { 530 | return app.checkCallingOrSelfUriPermission(uri, modeFlags); 531 | } 532 | 533 | @Override 534 | public int checkUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags) { 535 | return app.checkUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags); 536 | } 537 | 538 | @Override 539 | public void enforceUriPermission(Uri uri, int pid, int uid, int modeFlags, String message) { 540 | app.enforceUriPermission(uri, pid, uid, modeFlags, message); 541 | } 542 | 543 | @Override 544 | public void enforceCallingUriPermission(Uri uri, int modeFlags, String message) { 545 | app.enforceCallingUriPermission(uri, modeFlags, message); 546 | } 547 | 548 | @Override 549 | public void enforceCallingOrSelfUriPermission(Uri uri, int modeFlags, String message) { 550 | app.enforceCallingOrSelfUriPermission(uri, modeFlags, message); 551 | } 552 | 553 | @Override 554 | public void enforceUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags, String message) { 555 | app.enforceUriPermission(uri, readPermission, writePermission, pid, uid, modeFlags, message); 556 | } 557 | 558 | @Override 559 | public Context createPackageContext(String packageName, int flags) throws PackageManager.NameNotFoundException { 560 | return app.createPackageContext(packageName, flags); 561 | } 562 | 563 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 564 | @Override 565 | public Context createConfigurationContext(Configuration overrideConfiguration) { 566 | return app.createConfigurationContext(overrideConfiguration); 567 | } 568 | 569 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 570 | @Override 571 | public Context createDisplayContext(Display display) { 572 | return app.createDisplayContext(display); 573 | } 574 | 575 | @Override 576 | public boolean isRestricted() { 577 | return app.isRestricted(); 578 | } 579 | 580 | @RequiresApi(api = Build.VERSION_CODES.N) 581 | @Override 582 | public Context createDeviceProtectedStorageContext() { 583 | return app.createDeviceProtectedStorageContext(); 584 | } 585 | 586 | public DelegateApplication() { 587 | super(); 588 | } 589 | 590 | @Override 591 | public void onCreate() { 592 | app.onCreate(); 593 | } 594 | 595 | @Override 596 | public void onTerminate() { 597 | app.onTerminate(); 598 | } 599 | 600 | @Override 601 | public void onConfigurationChanged(Configuration newConfig) { 602 | app.onConfigurationChanged(newConfig); 603 | } 604 | 605 | @Override 606 | public void onLowMemory() { 607 | app.onLowMemory(); 608 | } 609 | 610 | @Override 611 | public void onTrimMemory(int level) { 612 | app.onTrimMemory(level); 613 | } 614 | 615 | @Override 616 | public void registerComponentCallbacks(ComponentCallbacks callback) { 617 | app.registerComponentCallbacks(callback); 618 | } 619 | 620 | @Override 621 | public void unregisterComponentCallbacks(ComponentCallbacks callback) { 622 | app.unregisterComponentCallbacks(callback); 623 | } 624 | 625 | @Override 626 | public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { 627 | app.registerActivityLifecycleCallbacks(callback); 628 | } 629 | 630 | @Override 631 | public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) { 632 | app.unregisterActivityLifecycleCallbacks(callback); 633 | } 634 | 635 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) 636 | @Override 637 | public void registerOnProvideAssistDataListener(OnProvideAssistDataListener callback) { 638 | app.registerOnProvideAssistDataListener(callback); 639 | } 640 | 641 | @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) 642 | @Override 643 | public void unregisterOnProvideAssistDataListener(OnProvideAssistDataListener callback) { 644 | app.unregisterOnProvideAssistDataListener(callback); 645 | } 646 | 647 | @Override 648 | public int hashCode() { 649 | return app.hashCode(); 650 | } 651 | 652 | @Override 653 | public boolean equals(Object obj) { 654 | return app.equals(obj); 655 | } 656 | 657 | 658 | @Override 659 | public String toString() { 660 | return app.toString(); 661 | } 662 | } 663 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/LinuxFileCommand.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib; 2 | 3 | import java.io.IOException; 4 | 5 | /** 6 | * File operators. Like: delete, create, move... 7 | * Use linux shell to implement these operators. 8 | * So, only for linux like operator system. 9 | * All return the execute process, and if the requested program can not be executed, 10 | * may throws IOException. 11 | * And all files or diretorys String parameters are absolute path. 12 | * The return new {@code Process} object that represents the native process. 13 | * */ 14 | public class LinuxFileCommand { 15 | public final Runtime shell; 16 | //private static final int c = 0; 17 | /** 18 | * Constructor. /data/busybox/ 19 | * @param 20 | * */ 21 | public LinuxFileCommand(Runtime runtime) { 22 | // TODO Auto-generated constructor stub 23 | shell = runtime; 24 | } 25 | 26 | /** Delete {@code file} file, nerver prompt*/ 27 | public final Process deleteFile(String file) throws IOException{ 28 | String[] cmds = {"rm", file}; 29 | return shell.exec(cmds); 30 | } 31 | 32 | public final Process delete(String file) throws IOException { 33 | String[] cmds = {"rm", "-r", file}; 34 | return shell.exec(cmds); 35 | } 36 | 37 | public final Process deleteMult(String[] cmds) throws IOException{ 38 | return shell.exec(cmds); 39 | } 40 | 41 | /** Delete {@code dire} directory, nerver prompt*/ 42 | public final Process deleteDirectory(String dire) throws IOException{ 43 | String[] cmds = {"rm", "-r", dire}; 44 | return shell.exec(cmds); 45 | } 46 | 47 | /** Create {@code file} file, if file has already exist, update the 48 | * file access and modification time to current time. 49 | * @throws IOException 50 | * */ 51 | public final Process createFile(String file) throws IOException { 52 | String[] cmds = {"touch", file}; 53 | return shell.exec(cmds); 54 | } 55 | 56 | /** Create directory. If parent path is not existed, also create parent directory 57 | * @throws IOException */ 58 | public final Process createDirectory(String dire) throws IOException{ 59 | String[] cmds = {"mkdir", dire}; 60 | return shell.exec(cmds); 61 | } 62 | 63 | /** Move or rename(if they in the same directory) file or directory 64 | * @throws IOException */ 65 | public final Process moveFile(String src, String dir) throws IOException{ 66 | String[] cmds = {"mv", src, dir}; 67 | return shell.exec(cmds); 68 | } 69 | 70 | /** Copy file 71 | * @throws IOException */ 72 | public final Process copyFile(String src, String dir) throws IOException{ 73 | String[] cmds = {"cp", "-r", src, dir}; 74 | return shell.exec(cmds); 75 | } 76 | 77 | /**` 78 | * File soft Link 79 | * @throws IOException 80 | * */ 81 | public final Process linkFile(String src, String dir) throws IOException{ 82 | String[] cmds = {"ln", "-l", src, dir}; 83 | return shell.exec(cmds); 84 | } 85 | 86 | 87 | public final Process du_s(String file) throws IOException{ 88 | String[] cmds = {"du", "-s", file}; 89 | return shell.exec(cmds); 90 | } 91 | 92 | public final Process ls_lhd(String file) throws IOException{ 93 | String[] cmds = {"ls", "-l", file}; 94 | return shell.exec(cmds); 95 | } 96 | 97 | public final Process ls_Directory(String directory) throws IOException{ 98 | if (directory.equals("/")) 99 | directory = ""; 100 | String[] cmds = {"ls", "-a", directory}; 101 | return shell.exec(cmds); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/XLAppKeyChecker.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib; 2 | 3 | import android.content.Context; 4 | import android.util.Base64; 5 | import com.xunlei.downloadlib.android.XLLog; 6 | import com.xunlei.downloadlib.android.XLUtil; 7 | import java.io.UnsupportedEncodingException; 8 | import java.text.ParseException; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Calendar; 11 | import java.util.Date; 12 | import java.util.Locale; 13 | 14 | public class XLAppKeyChecker { 15 | private static final byte APPTYPE_PRODUCT = (byte) 1; 16 | private static final String TAG = "XLAppKeyChecker"; 17 | private short mAppId = (short) 0; 18 | private String mAppKey = ""; 19 | private Context mContext = null; 20 | private String mPackageName = ""; 21 | 22 | private class AppKeyEntity { 23 | private String MD5; 24 | private RawItemsEntity mItemsEntity; 25 | private String mRawItems; 26 | 27 | private AppKeyEntity() { 28 | this.mRawItems = ""; 29 | this.MD5 = ""; 30 | this.mItemsEntity = null; 31 | } 32 | 33 | public RawItemsEntity getmItemsEntity() { 34 | return this.mItemsEntity; 35 | } 36 | 37 | public void setmItemsEntity(RawItemsEntity rawItemsEntity) { 38 | this.mItemsEntity = rawItemsEntity; 39 | } 40 | 41 | public String getMD5() { 42 | return this.MD5; 43 | } 44 | 45 | public void setMD5(String str) { 46 | this.MD5 = str; 47 | } 48 | 49 | public String getmRawItems() { 50 | return this.mRawItems; 51 | } 52 | 53 | public void setmRawItems(String str) { 54 | this.mRawItems = str; 55 | } 56 | } 57 | 58 | public class KeyFormateException extends Exception { 59 | private static final long serialVersionUID = 13923744320L; 60 | 61 | public KeyFormateException(String str) { 62 | super(str); 63 | } 64 | } 65 | 66 | private class RawItemsEntity { 67 | private short mAppId; 68 | private Date mExpired; 69 | 70 | private RawItemsEntity() { 71 | this.mAppId = (short) 0; 72 | this.mExpired = null; 73 | } 74 | 75 | public short getAppId() { 76 | return this.mAppId; 77 | } 78 | 79 | public void setAppId(short s) { 80 | this.mAppId = s; 81 | } 82 | 83 | public Date getExpired() { 84 | return this.mExpired; 85 | } 86 | 87 | public void setExpired(Date date) { 88 | this.mExpired = date; 89 | } 90 | } 91 | 92 | public XLAppKeyChecker(Context context, String str) { 93 | this.mContext = context; 94 | this.mAppKey = str; 95 | } 96 | 97 | public boolean verify() { 98 | try { 99 | AppKeyEntity keyEntity = getKeyEntity(); 100 | this.mPackageName = "com.xunlei.downloadprovider"; 101 | if (!verifyAppKeyMD5(keyEntity, this.mPackageName)) { 102 | XLLog.i(TAG, "appkey MD5 invalid."); 103 | return false; 104 | } else if (!verifyAppKeyExpired(keyEntity)) { 105 | return true; 106 | } else { 107 | XLLog.i(TAG, "appkey expired."); 108 | return false; 109 | } 110 | } catch (KeyFormateException e) { 111 | return false; 112 | } 113 | } 114 | 115 | private boolean verifyAppKeyMD5(AppKeyEntity appKeyEntity, String str) { 116 | String str2 = appKeyEntity.getmRawItems() + ";" + str; 117 | XLLog.i(TAG, "totalContent:" + str2); 118 | str2 = XLUtil.getMd5(str2).toLowerCase().replace('b', '^').replace('9', 'b'); 119 | XLLog.i(TAG, "keyEntity getMD5 MD5:" + appKeyEntity.getMD5()); 120 | if (str2.compareTo(appKeyEntity.getMD5()) == 0) { 121 | return true; 122 | } 123 | return false; 124 | } 125 | 126 | private boolean verifyAppKeyExpired(AppKeyEntity appKeyEntity) { 127 | Date expired = appKeyEntity.getmItemsEntity().getExpired(); 128 | if (expired == null) { 129 | return false; 130 | } 131 | return expired.before(Calendar.getInstance().getTime()); 132 | } 133 | 134 | public String getSoAppKey() { 135 | return XLUtil.generateAppKey("com.xunlei.downloadprovider", this.mAppId, (byte) 1); 136 | } 137 | 138 | private AppKeyEntity getKeyEntity() throws KeyFormateException { 139 | String[] split = this.mAppKey.split("=="); 140 | if (split.length != 2) { 141 | XLLog.i(TAG, "keyPair length invalid"); 142 | throw new KeyFormateException("error"); 143 | } 144 | AppKeyEntity appKeyEntity = new AppKeyEntity(); 145 | appKeyEntity.setMD5(split[1]); 146 | try { 147 | String replace = split[0].replace('^', '='); 148 | String str = new String(Base64.decode(replace.substring(2, replace.length() - 2), 0), "UTF-8"); 149 | appKeyEntity.setmRawItems(str); 150 | XLLog.i(TAG, "items:" + str); 151 | appKeyEntity.setmItemsEntity(getRawItemsEntity(str)); 152 | return appKeyEntity; 153 | } catch (UnsupportedEncodingException e) { 154 | throw new KeyFormateException("error"); 155 | } 156 | } 157 | 158 | private RawItemsEntity getRawItemsEntity(String str) throws KeyFormateException { 159 | String[] split = str.split(";"); 160 | RawItemsEntity rawItemsEntity = new RawItemsEntity(); 161 | if (split.length <= 0 || split.length > 2) { 162 | throw new KeyFormateException("raw item length invalid."); 163 | } 164 | try { 165 | this.mAppId = Short.parseShort(split[0]); 166 | rawItemsEntity.setAppId(this.mAppId); 167 | if (split.length == 2) { 168 | try { 169 | rawItemsEntity.setExpired(new SimpleDateFormat("yyyy-MM-dd", Locale.US).parse(split[1])); 170 | } catch (ParseException e) { 171 | throw new KeyFormateException("expired field formate error."); 172 | } 173 | } 174 | return rawItemsEntity; 175 | } catch (NumberFormatException e2) { 176 | XLLog.i(TAG, "appId invalid"); 177 | e2.printStackTrace(); 178 | throw new KeyFormateException("app id format error."); 179 | } 180 | } 181 | } -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/XLLoader.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib; 2 | 3 | import android.content.Context; 4 | 5 | import com.xunlei.downloadlib.parameter.BtIndexSet; 6 | import com.xunlei.downloadlib.parameter.BtSubTaskDetail; 7 | import com.xunlei.downloadlib.parameter.BtTaskStatus; 8 | import com.xunlei.downloadlib.parameter.GetDownloadHead; 9 | import com.xunlei.downloadlib.parameter.GetDownloadLibVersion; 10 | import com.xunlei.downloadlib.parameter.GetFileName; 11 | import com.xunlei.downloadlib.parameter.GetTaskId; 12 | import com.xunlei.downloadlib.parameter.MaxDownloadSpeedParam; 13 | import com.xunlei.downloadlib.parameter.ThunderUrlInfo; 14 | import com.xunlei.downloadlib.parameter.TorrentInfo; 15 | import com.xunlei.downloadlib.parameter.UrlQuickInfo; 16 | import com.xunlei.downloadlib.parameter.XLSessionInfo; 17 | import com.xunlei.downloadlib.parameter.XLTaskInfo; 18 | import com.xunlei.downloadlib.parameter.XLTaskInfoEx; 19 | import com.xunlei.downloadlib.parameter.XLTaskLocalUrl; 20 | 21 | class XLLoader { 22 | private static final String TAG = "XLLoader"; 23 | 24 | public native int addPeerResource(long j, String str, long j2, String str2, String str3, int i, int i2, int i3, int i4, int i5, int i6, int i7); 25 | 26 | public native int addServerResource(long j, String str, String str2, String str3, int i, int i2); 27 | 28 | public native int btAddPeerResource(long j, int i, String str, long j2, String str2, String str3, int i2, int i3, int i4, int i5, int i6, int i7, int i8); 29 | 30 | public native int btAddServerResource(long j, int i, String str, String str2, String str3, int i2, int i3); 31 | 32 | public native int btRemoveAddedResource(long j, int i, int i2); 33 | 34 | public native int clearTaskFile(String str); 35 | 36 | public native int createBtMagnetTask(String str, String str2, String str3, GetTaskId getTaskId); 37 | 38 | public native int createBtTask(String str, String str2, int i, int i2, int i3, GetTaskId getTaskId); 39 | 40 | public native int createCIDTask(String str, String str2, String str3, String str4, String str5, long j, int i, int i2, GetTaskId getTaskId); 41 | 42 | public native int createEmuleTask(String str, String str2, String str3, int i, int i2, GetTaskId getTaskId); 43 | 44 | public native int createP2spTask(String str, String str2, String str3, String str4, String str5, String str6, String str7, int i, int i2, GetTaskId getTaskId); 45 | 46 | public native int createShortVideoTask(String str, String str2, String str3, String str4, int i, int i2, int i3, GetTaskId getTaskId); 47 | 48 | public native int deselectBtSubTask(long j, BtIndexSet btIndexSet); 49 | 50 | public native int enterPrefetchMode(long j); 51 | 52 | public native int getBtSubTaskInfo(long j, int i, BtSubTaskDetail btSubTaskDetail); 53 | 54 | public native int getBtSubTaskStatus(long j, BtTaskStatus btTaskStatus, int i, int i2); 55 | 56 | public native int getDownloadHeader(long j, GetDownloadHead getDownloadHead); 57 | 58 | public native int getDownloadLibVersion(GetDownloadLibVersion getDownloadLibVersion); 59 | 60 | public native int getFileNameFromUrl(String str, GetFileName getFileName); 61 | 62 | public native int getLocalUrl(String str, XLTaskLocalUrl xLTaskLocalUrl); 63 | 64 | public native int getMaxDownloadSpeed(MaxDownloadSpeedParam maxDownloadSpeedParam); 65 | 66 | public native int getNameFromUrl(String str, String str2); 67 | 68 | public native int getSessionInfoByUrl(String str, XLSessionInfo xLSessionInfo); 69 | 70 | 71 | public native int getTaskInfo(long j, int i, XLTaskInfo xLTaskInfo); 72 | 73 | public native int getTaskInfoEx(long j, XLTaskInfoEx xLTaskInfoEx); 74 | 75 | public native int getTorrentInfo(String str, TorrentInfo torrentInfo); 76 | 77 | public native int getUrlQuickInfo(long j, UrlQuickInfo urlQuickInfo); 78 | 79 | public native int init(Context context, String str, String str2, String str3, String str4, String str5, String str6, int i, int i2); 80 | 81 | public native boolean isLogTurnOn(); 82 | 83 | public native int notifyNetWorkType(int i); 84 | 85 | public native int parserThunderUrl(String str, ThunderUrlInfo thunderUrlInfo); 86 | 87 | public native int playShortVideoBegin(long j); 88 | 89 | public native int releaseTask(long j); 90 | 91 | public native int removeAddedServerResource(long j, int i); 92 | 93 | public native int requeryIndex(long j); 94 | 95 | public native int selectBtSubTask(long j, BtIndexSet btIndexSet); 96 | 97 | public native int setBtPriorSubTask(long j, int i); 98 | 99 | public native int setDownloadTaskOrigin(long j, String str); 100 | 101 | public native int setFileName(long j, String str); 102 | 103 | public native int setHttpHeaderProperty(long j, String str, String str2); 104 | 105 | public native int setImei(String str); 106 | 107 | public native int setLocalProperty(String str, String str2); 108 | 109 | public native int setMac(String str); 110 | 111 | public native int setMiUiVersion(String str); 112 | 113 | public native int setNotifyNetWorkCarrier(int i); 114 | 115 | public native int setNotifyWifiBSSID(String str); 116 | 117 | public native int setOriginUserAgent(long j, String str); 118 | 119 | public native int setReleaseLog(int i, String str, int i2, int i3); 120 | 121 | public native int setSpeedLimit(long j, long j2); 122 | 123 | public native int setStatReportSwitch(boolean z); 124 | 125 | public native int setTaskAllowUseResource(long j, int i); 126 | 127 | public native int setTaskAppInfo(long j, String str, String str2, String str3); 128 | 129 | public native int setTaskGsState(long j, int i, int i2); 130 | 131 | public native int setTaskLxState(long j, int i, int i2); 132 | 133 | public native int setTaskUid(long j, int i); 134 | 135 | public native int setUserId(String str); 136 | 137 | public native int startDcdn(long j, int i, String str, String str2, String str3); 138 | 139 | public native int startTask(long j, boolean z); 140 | 141 | public native int statExternalInfo(long j, int i, String str, String str2); 142 | 143 | public native int stopDcdn(long j, int i); 144 | 145 | public native int stopTask(long j); 146 | 147 | public native int stopTaskWithReason(long j, int i); 148 | 149 | public native int switchOriginToAllResDownload(long j); 150 | 151 | public native int unInit(); 152 | 153 | public XLLoader() { 154 | System.loadLibrary("xl_stat"); 155 | System.loadLibrary("xluagc"); 156 | System.loadLibrary("xl_thunder_sdk"); 157 | } 158 | } -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/XLTaskHelper.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib; 2 | 3 | import android.content.Context; 4 | import android.os.Build; 5 | import android.os.Environment; 6 | import android.os.Handler; 7 | import android.text.TextUtils; 8 | 9 | import com.xunlei.downloadlib.parameter.BtIndexSet; 10 | import com.xunlei.downloadlib.parameter.BtSubTaskDetail; 11 | import com.xunlei.downloadlib.parameter.BtTaskParam; 12 | import com.xunlei.downloadlib.parameter.EmuleTaskParam; 13 | import com.xunlei.downloadlib.parameter.GetFileName; 14 | import com.xunlei.downloadlib.parameter.GetTaskId; 15 | import com.xunlei.downloadlib.parameter.InitParam; 16 | import com.xunlei.downloadlib.parameter.MagnetTaskParam; 17 | import com.xunlei.downloadlib.parameter.P2spTaskParam; 18 | import com.xunlei.downloadlib.parameter.TorrentFileInfo; 19 | import com.xunlei.downloadlib.parameter.TorrentInfo; 20 | import com.xunlei.downloadlib.parameter.XLTaskInfo; 21 | import com.xunlei.downloadlib.parameter.XLTaskLocalUrl; 22 | 23 | import java.util.concurrent.ConcurrentHashMap; 24 | import java.util.concurrent.atomic.AtomicInteger; 25 | 26 | /** 27 | * Created by oceanzhang on 2017/7/27. 28 | */ 29 | 30 | public class XLTaskHelper { 31 | private static final String TAG = "XLTaskHelper"; 32 | 33 | public static void init(Context context) { 34 | XLDownloadManager instance = XLDownloadManager.getInstance(); 35 | InitParam initParam = new InitParam(); 36 | initParam.mAppKey = "bpIzNjAxNTsxNTA0MDk0ODg4LjQyODAwMA&&OxNw==^a2cec7^10e7f1756b15519e20ffb6cf0fbf671f"; 37 | initParam.mAppVersion = "5.45.2.5080"; 38 | initParam.mStatSavePath = context.getFilesDir().getPath(); 39 | initParam.mStatCfgSavePath = context.getFilesDir().getPath(); 40 | initParam.mPermissionLevel = 2; 41 | instance.init(context, initParam); 42 | instance.setOSVersion(Build.VERSION.INCREMENTAL); 43 | instance.setSpeedLimit(-1, -1); 44 | XLDownloadManager.getInstance().setUserId(""); 45 | } 46 | 47 | 48 | private String innerSDCardPath; 49 | private Context context; 50 | private AtomicInteger seq = new AtomicInteger(0); 51 | 52 | private XLTaskHelper(final Context context) { 53 | this.context = context; 54 | innerSDCardPath = Environment.getExternalStorageDirectory().getPath(); 55 | } 56 | 57 | 58 | private static volatile XLTaskHelper instance = null; 59 | 60 | public static XLTaskHelper instance(Context context) { 61 | if (instance == null) { 62 | synchronized (XLTaskHelper.class) { 63 | if (instance == null) { 64 | instance = new XLTaskHelper(context.getApplicationContext()); 65 | } 66 | } 67 | 68 | } 69 | return instance; 70 | } 71 | 72 | /** 73 | * 获取任务详情, 包含当前状态,下载进度,下载速度,文件大小 74 | * mDownloadSize:已下载大小 mDownloadSpeed:下载速度 mFileSize:文件总大小 mTaskStatus:当前状态,0连接中1下载中 2下载完成 3失败 mAdditionalResDCDNSpeed DCDN加速 速度 75 | * @param taskId 76 | * @return 77 | */ 78 | public synchronized XLTaskInfo getTaskInfo(long taskId) { 79 | XLTaskInfo taskInfo = new XLTaskInfo(); 80 | XLDownloadManager.getInstance().getTaskInfo(taskId,1,taskInfo); 81 | return taskInfo; 82 | } 83 | 84 | /** 85 | * 添加迅雷链接任务 支持thunder:// ftp:// ed2k:// http:// https:// 协议 86 | * @param url 87 | * @param savePath 下载文件保存路径 88 | * @param fileName 下载文件名 可以通过 getFileName(url) 获取到,为空默认为getFileName(url)的值 89 | * @return 90 | */ 91 | public synchronized long addThunderTask(String url, String savePath, String fileName) throws Exception { 92 | if (url.startsWith("thunder://")) url = XLDownloadManager.getInstance().parserThunderUrl(url); 93 | final GetTaskId getTaskId = new GetTaskId(); 94 | GetFileName getFileName = new GetFileName(); 95 | XLDownloadManager.getInstance().getFileNameFromUrl(url, getFileName); 96 | if (url.startsWith("ftp://") || url.startsWith("http")) { 97 | P2spTaskParam taskParam = new P2spTaskParam(); 98 | taskParam.setCreateMode(1); 99 | taskParam.setFileName(getFileName.getFileName()); 100 | taskParam.setFilePath(savePath); 101 | taskParam.setUrl(url); 102 | taskParam.setSeqId(seq.incrementAndGet()); 103 | taskParam.setCookie(""); 104 | taskParam.setRefUrl(""); 105 | taskParam.setUser(""); 106 | taskParam.setPass(""); 107 | XLDownloadManager.getInstance().createP2spTask(taskParam, getTaskId); 108 | } else if (url.startsWith("ed2k://")) { 109 | EmuleTaskParam taskParam = new EmuleTaskParam(); 110 | taskParam.setFilePath(savePath); 111 | taskParam.setFileName(getFileName.getFileName()); 112 | taskParam.setUrl(url); 113 | taskParam.setSeqId(seq.incrementAndGet()); 114 | taskParam.setCreateMode(1); 115 | XLDownloadManager.getInstance().createEmuleTask(taskParam, getTaskId); 116 | } else { 117 | throw new Exception("url illegal."); 118 | } 119 | 120 | XLDownloadManager.getInstance().setDownloadTaskOrigin(getTaskId.getTaskId(), "out_app/out_app_paste"); 121 | XLDownloadManager.getInstance().setOriginUserAgent(getTaskId.getTaskId(), "AndroidDownloadManager/4.4.4 (Linux; U; Android 4.4.4; Build/KTU84Q)"); 122 | XLDownloadManager.getInstance().startTask(getTaskId.getTaskId(), false); 123 | XLDownloadManager.getInstance().setTaskLxState(getTaskId.getTaskId(), 0, 1); 124 | XLDownloadManager.getInstance().startDcdn(getTaskId.getTaskId(), 0, "", "", ""); 125 | 126 | return getTaskId.getTaskId(); 127 | } 128 | /** 129 | * 添加磁力链任务 130 | * @param url 磁力链接 magnet:? 开头 131 | * @param savePath 132 | * @param fileName 133 | * @return 134 | * @throws Exception 135 | */ 136 | public synchronized long addMagentTask(final String url,final String savePath,String fileName) throws Exception { 137 | if (url.startsWith("magnet:?")) { 138 | if(TextUtils.isEmpty(fileName)) { 139 | final GetFileName getFileName = new GetFileName(); 140 | XLDownloadManager.getInstance().getFileNameFromUrl(url, getFileName); 141 | fileName = getFileName.getFileName(); 142 | } 143 | MagnetTaskParam magnetTaskParam = new MagnetTaskParam(); 144 | magnetTaskParam.setFileName(fileName); 145 | magnetTaskParam.setFilePath(savePath); 146 | magnetTaskParam.setUrl(url); 147 | final GetTaskId getTaskId = new GetTaskId(); 148 | XLDownloadManager.getInstance().createBtMagnetTask(magnetTaskParam, getTaskId); 149 | 150 | XLDownloadManager.getInstance().setTaskLxState(getTaskId.getTaskId(), 0, 1); 151 | XLDownloadManager.getInstance().startDcdn(getTaskId.getTaskId(), 0, "", "", ""); 152 | XLDownloadManager.getInstance().startTask(getTaskId.getTaskId(), false); 153 | return getTaskId.getTaskId(); 154 | } else { 155 | throw new Exception("url illegal."); 156 | } 157 | } 158 | /** 159 | * 获取种子详情 160 | * @param torrentPath 161 | * @return 162 | */ 163 | public synchronized TorrentInfo getTorrentInfo(String torrentPath) { 164 | TorrentInfo torrentInfo = new TorrentInfo(); 165 | XLDownloadManager.getInstance().getTorrentInfo(torrentPath,torrentInfo); 166 | return torrentInfo; 167 | } 168 | 169 | /** 170 | * 添加种子下载任务,如果是磁力链需要先通过addMagentTask将种子下载下来 171 | * @param torrentPath 种子地址 172 | * @param savePath 保存路径 173 | * @param indexs 需要下载的文件索引 174 | * @return 175 | * @throws Exception 176 | */ 177 | public synchronized long addTorrentTask(String torrentPath,String savePath,int []indexs) throws Exception { 178 | TorrentInfo torrentInfo = new TorrentInfo(); 179 | XLDownloadManager.getInstance().getTorrentInfo(torrentPath,torrentInfo); 180 | TorrentFileInfo[] fileInfos = torrentInfo.mSubFileInfo; 181 | BtTaskParam taskParam = new BtTaskParam(); 182 | taskParam.setCreateMode(1); 183 | taskParam.setFilePath(savePath); 184 | taskParam.setMaxConcurrent(3); 185 | taskParam.setSeqId(seq.incrementAndGet()); 186 | taskParam.setTorrentPath(torrentPath); 187 | GetTaskId getTaskId = new GetTaskId(); 188 | XLDownloadManager.getInstance().createBtTask(taskParam,getTaskId); 189 | if(fileInfos.length > 1 && indexs != null && indexs.length > 0) { 190 | BtIndexSet btIndexSet = new BtIndexSet(indexs.length); 191 | int i = 0; 192 | for(int index : indexs) { 193 | btIndexSet.mIndexSet[i++] = index; 194 | } 195 | XLDownloadManager.getInstance().selectBtSubTask(getTaskId.getTaskId(),btIndexSet); 196 | } 197 | XLDownloadManager.getInstance().setTaskLxState(getTaskId.getTaskId(), 0, 1); 198 | // XLDownloadManager.getInstance().startDcdn(getTaskId.getTaskId(), currentFileInfo.mRealIndex, "", "", ""); 199 | XLDownloadManager.getInstance().startTask(getTaskId.getTaskId(), false); 200 | // XLDownloadManager.getInstance().setBtPriorSubTask(getTaskId.getTaskId(),currentFileInfo.mRealIndex); 201 | // XLTaskLocalUrl localUrl = new XLTaskLocalUrl(); 202 | // XLDownloadManager.getInstance().getLocalUrl(savePath+"/" +(TextUtils.isEmpty(currentFileInfo.mSubPath) ? "" : currentFileInfo.mSubPath+"/")+ currentFileInfo.mFileName,localUrl); 203 | // currentFileInfo.playUrl = localUrl.mStrUrl; 204 | // currentFileInfo.hash = torrentInfo.mInfoHash; 205 | // return currentFileInfo; 206 | return getTaskId.getTaskId(); 207 | } 208 | 209 | /** 210 | * 获取某个文件的本地proxy url,如果是音视频文件可以实现变下边播 211 | * @param filePath 212 | * @return 213 | */ 214 | public synchronized String getLoclUrl(String filePath) { 215 | XLTaskLocalUrl localUrl = new XLTaskLocalUrl(); 216 | XLDownloadManager.getInstance().getLocalUrl(filePath,localUrl); 217 | return localUrl.mStrUrl; 218 | } 219 | 220 | /** 221 | * 停止任务 文件保留 222 | * @param taskId 223 | */ 224 | public synchronized void stopTask(long taskId) { 225 | XLDownloadManager.getInstance().stopTask(taskId); 226 | XLDownloadManager.getInstance().releaseTask(taskId); 227 | } 228 | 229 | /** 230 | * 删除一个任务,会把文件也删掉 231 | * @param taskId 232 | * @param savePath 233 | */ 234 | public synchronized void deleteTask(long taskId,final String savePath) { 235 | stopTask(taskId); 236 | new Handler(Daemon.looper()).post(new Runnable() { 237 | @Override 238 | public void run() { 239 | try { 240 | new LinuxFileCommand(Runtime.getRuntime()).deleteDirectory(savePath); 241 | } catch (Exception e) { 242 | e.printStackTrace(); 243 | } 244 | } 245 | }); 246 | } 247 | 248 | 249 | /** 250 | * 通过链接获取文件名 251 | * @param url 252 | * @return 253 | */ 254 | public synchronized String getFileName(String url) { 255 | if (url.startsWith("thunder://")) url = XLDownloadManager.getInstance().parserThunderUrl(url); 256 | GetFileName getFileName = new GetFileName(); 257 | XLDownloadManager.getInstance().getFileNameFromUrl(url, getFileName); 258 | return getFileName.getFileName(); 259 | } 260 | 261 | /** 262 | * 获取种子文件子任务的详情 263 | * @param taskId 264 | * @param fileIndex 265 | * @return 266 | */ 267 | public synchronized BtSubTaskDetail getBtSubTaskInfo(long taskId, int fileIndex) { 268 | BtSubTaskDetail subTaskDetail = new BtSubTaskDetail(); 269 | XLDownloadManager.getInstance().getBtSubTaskInfo(taskId,fileIndex,subTaskDetail); 270 | return subTaskDetail; 271 | } 272 | 273 | /** 274 | * 开启dcdn加速 275 | * @param taskId 276 | * @param btFileIndex 277 | */ 278 | public synchronized void startDcdn(long taskId,int btFileIndex) { 279 | XLDownloadManager.getInstance().startDcdn(taskId, btFileIndex, "", "", ""); 280 | } 281 | 282 | 283 | /** 284 | * 停止dcdn加速 285 | * @param taskId 286 | * @param btFileIndex 287 | */ 288 | public synchronized void stopDcdn(long taskId,int btFileIndex) { 289 | XLDownloadManager.getInstance().stopDcdn(taskId,btFileIndex); 290 | } 291 | 292 | 293 | } 294 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/android/LogConfig.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.android; 2 | 3 | import android.text.TextUtils; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | /* compiled from: XLLog */ 10 | final class LogConfig { 11 | private final int mDestinationType; 12 | final String mFileName; 13 | final LogLevel mLevel; 14 | final String mLogDir; 15 | final long mLogSize; 16 | 17 | public LogConfig(String str) { 18 | Map parseConfigFile = parseConfigFile(str); 19 | long parseLong = Long.parseLong(getOrDefault(parseConfigFile, "LOG_FILE_SIZE", "0")); 20 | if (parseLong == 0) { 21 | parseLong = 20971520; 22 | } 23 | this.mLogSize = parseLong; 24 | this.mLevel = LogLevel.parseLevel(getOrDefault(parseConfigFile, "LOG_LEVEL", "").toLowerCase()); 25 | this.mFileName = getOrDefault(parseConfigFile, "LOG_FILE", ""); 26 | this.mLogDir = getOrDefault(parseConfigFile, "LOG_DIR", ""); 27 | if (TextUtils.isEmpty(this.mFileName) || TextUtils.isEmpty(this.mLogDir)) { 28 | this.mDestinationType = 0; 29 | return; 30 | } 31 | int parseInt = Integer.parseInt(getOrDefault(parseConfigFile, "LOG_DESTINATION_TYPE", "0")); 32 | if (parseInt > 0) { 33 | this.mDestinationType = parseInt; 34 | } else { 35 | this.mDestinationType = 3; 36 | } 37 | } 38 | 39 | public final boolean canLogToFile() { 40 | return (this.mDestinationType & 1) > 0; 41 | } 42 | 43 | public final boolean canLogToLogCat() { 44 | return (this.mDestinationType & 2) > 0; 45 | } 46 | 47 | private String getOrDefault(Map map, String str, String str2) { 48 | String str3 = (String) map.get(str); 49 | return str3 == null ? str2 : str3; 50 | } 51 | 52 | private Map parseConfigFile(String str) { 53 | File file = new File(str); 54 | Map hashMap = new HashMap(); 55 | if (file.exists()) { 56 | try { 57 | FileInputStream fileInputStream = new FileInputStream(file); 58 | String str2 = ""; 59 | StringBuilder stringBuilder = new StringBuilder(); 60 | StringBuilder stringBuilder2 = new StringBuilder(); 61 | while (true) { 62 | int read = fileInputStream.read(); 63 | if (read != -1) { 64 | if (stringBuilder.length() == 0 && read == 35) { 65 | do { 66 | read = fileInputStream.read(); 67 | if (read == -1 || read == 13) { 68 | break; 69 | } 70 | } while (read != 10); 71 | } else if (!(read == 32 || read == 9)) { 72 | if (read == 61) { 73 | str2 = stringBuilder.toString(); 74 | } else if (read == 10 || read == 13) { 75 | if (stringBuilder.length() != 0) { 76 | hashMap.put(str2, stringBuilder2.toString()); 77 | str2 = ""; 78 | stringBuilder = new StringBuilder(); 79 | stringBuilder2 = new StringBuilder(); 80 | } 81 | } else if (str2.length() == 0) { 82 | stringBuilder.append((char) read); 83 | } else { 84 | stringBuilder2.append((char) read); 85 | } 86 | } 87 | } else { 88 | break; 89 | } 90 | } 91 | fileInputStream.close(); 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | } 96 | return hashMap; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/android/LogLevel.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.android; 2 | 3 | 4 | /* compiled from: XLLog */ 5 | enum LogLevel { 6 | LOG_LEVEL_VERBOSE(2), 7 | LOG_LEVEL_DEBUG(3), 8 | LOG_LEVEL_INFO(4), 9 | LOG_LEVEL_WARN(5), 10 | LOG_LEVEL_ERROR(6); 11 | 12 | private final int logLevel; 13 | 14 | private LogLevel(int i) { 15 | this.logLevel = i; 16 | } 17 | 18 | static LogLevel parseLevel(String str) { 19 | if (str.equals("e") || str.equals("error")) { 20 | return LOG_LEVEL_ERROR; 21 | } 22 | if (str.equals("w") || str.equals("warn")) { 23 | return LOG_LEVEL_WARN; 24 | } 25 | if (str.equals("i") || str.equals("info")) { 26 | return LOG_LEVEL_INFO; 27 | } 28 | if (str.equals("d") || str.equals("debug")) { 29 | return LOG_LEVEL_DEBUG; 30 | } 31 | return LOG_LEVEL_VERBOSE; 32 | } 33 | 34 | public final int getValue() { 35 | return this.logLevel; 36 | } 37 | 38 | public final String toString() { 39 | return toString(true); 40 | } 41 | 42 | public final String toString(boolean z) { 43 | switch (this) { 44 | case LOG_LEVEL_DEBUG: 45 | return z ? "D" : "DEBUG"; 46 | case LOG_LEVEL_INFO: 47 | return z ? "I" : "INFO"; 48 | case LOG_LEVEL_WARN: 49 | return z ? "W" : "WARN"; 50 | case LOG_LEVEL_ERROR: 51 | return z ? "E" : "ERROR"; 52 | default: 53 | if (z) { 54 | return "V"; 55 | } 56 | return "VERBOSE"; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/android/XLLog.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.android; 2 | 3 | import android.os.Environment; 4 | import android.util.Log; 5 | import java.io.File; 6 | 7 | public class XLLog { 8 | private static LogConfig mLogConfig = null; 9 | private static XLLogInternal mXLLogInternal; 10 | 11 | @Deprecated 12 | public static boolean init(String str) { 13 | return init(); 14 | } 15 | 16 | public static synchronized boolean init() { 17 | synchronized (XLLog.class) { 18 | if (mLogConfig == null) { 19 | File file = new File(Environment.getExternalStorageDirectory().getPath(), "xunlei_ds_log.ini"); 20 | if (file.exists()) { 21 | LogConfig logConfig = new LogConfig(file.getPath()); 22 | mLogConfig = logConfig; 23 | if (logConfig.canLogToFile()) { 24 | mXLLogInternal = new XLLogInternal(mLogConfig); 25 | } 26 | } 27 | } 28 | } 29 | return true; 30 | } 31 | 32 | public static void i(String str, String str2) { 33 | log(LogLevel.LOG_LEVEL_INFO, str, str2); 34 | } 35 | 36 | public static void d(String str, String str2) { 37 | log(LogLevel.LOG_LEVEL_DEBUG, str, str2); 38 | } 39 | 40 | public static void w(String str, String str2) { 41 | log(LogLevel.LOG_LEVEL_WARN, str, str2); 42 | } 43 | 44 | public static void e(String str, String str2) { 45 | log(LogLevel.LOG_LEVEL_ERROR, str, str2); 46 | } 47 | 48 | public static void w(String str, String str2, Throwable th) { 49 | log(LogLevel.LOG_LEVEL_WARN, str, str2 + ": " + th); 50 | } 51 | 52 | public static void v(String str, String str2) { 53 | d(str, str2); 54 | } 55 | 56 | public static void wtf(String str, String str2, Throwable th) { 57 | log(LogLevel.LOG_LEVEL_WARN, str, str2 + ": " + th); 58 | } 59 | 60 | public static boolean canbeLog(LogLevel logLevel) { 61 | return mXLLogInternal != null; 62 | } 63 | 64 | static void log(LogLevel logLevel, String str, String str2) { 65 | Object obj = null; 66 | if (logLevel == LogLevel.LOG_LEVEL_ERROR || (mLogConfig != null && mLogConfig.canLogToLogCat())) { 67 | obj = 1; 68 | } 69 | if (obj != null || mXLLogInternal != null) { 70 | String formatMessage = formatMessage(logLevel, str, str2); 71 | if (obj != null) { 72 | Log.println(logLevel.getValue(), str, formatMessage); 73 | } 74 | if (mXLLogInternal != null) { 75 | mXLLogInternal.log(logLevel, str, formatMessage); 76 | } 77 | } 78 | } 79 | 80 | public static void printStackTrace(Throwable th) { 81 | if (mXLLogInternal != null) { 82 | mXLLogInternal.printStackTrace(th); 83 | } 84 | } 85 | 86 | private static String formatMessage(LogLevel logLevel, String str, String str2) { 87 | StringBuilder stringBuilder = new StringBuilder(str2 + "\t"); 88 | try { 89 | StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 90 | if (stackTrace.length > 5) { 91 | StackTraceElement stackTraceElement = stackTrace[5]; 92 | stringBuilder.append("[" + stackTraceElement.getFileName() + ":"); 93 | stringBuilder.append(stackTraceElement.getLineNumber() + "]"); 94 | } else { 95 | stringBuilder.append("[stack=" + stackTrace.length + "]"); 96 | } 97 | } catch (Exception e) { 98 | } 99 | return stringBuilder.toString(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/android/XLLogInternal.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.android; 2 | 3 | import android.os.Environment; 4 | import android.os.Handler; 5 | import android.os.HandlerThread; 6 | import java.io.BufferedWriter; 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | import java.io.PrintWriter; 12 | import java.io.Writer; 13 | import java.text.SimpleDateFormat; 14 | import java.util.Date; 15 | 16 | /* compiled from: XLLog */ 17 | final class XLLogInternal { 18 | private static final SimpleDateFormat DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 19 | private File mFile; 20 | private final Handler mHandler; 21 | private final LogConfig mLogConfig; 22 | private int mNext; 23 | private int mRun; 24 | 25 | XLLogInternal(LogConfig logConfig) { 26 | this.mLogConfig = logConfig; 27 | HandlerThread handlerThread = new HandlerThread("DownloadLib-XLLog"); 28 | handlerThread.start(); 29 | this.mHandler = new Handler(handlerThread.getLooper()); 30 | } 31 | 32 | final void log(final LogLevel logLevel, final String str, String str2) { 33 | final String appendHeader = appendHeader(logLevel, str, str2); 34 | if (logLevel.getValue() >= this.mLogConfig.mLevel.getValue() && this.mLogConfig.canLogToFile()) { 35 | this.mHandler.post(new Runnable() { 36 | public void run() { 37 | XLLogInternal.this.logfile(logLevel, str, appendHeader); 38 | } 39 | }); 40 | } 41 | } 42 | 43 | public final void printStackTrace(final Throwable th) { 44 | this.mHandler.post(new Runnable() { 45 | public void run() { 46 | try { 47 | Writer fileWriter = new FileWriter(XLLogInternal.this.getLogFile(), true); 48 | Writer bufferedWriter = new BufferedWriter(fileWriter); 49 | th.printStackTrace(new PrintWriter(bufferedWriter)); 50 | bufferedWriter.write("\n"); 51 | bufferedWriter.close(); 52 | fileWriter.close(); 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | } 56 | } 57 | }); 58 | } 59 | 60 | private static String appendHeader(LogLevel logLevel, String str, String str2) { 61 | StringBuilder stringBuilder = new StringBuilder(); 62 | stringBuilder.append(DATEFORMAT.format(new Date()) + ": " + logLevel.toString()); 63 | stringBuilder.append("/" + str + "(" + Thread.currentThread().getId() + "):\t"); 64 | stringBuilder.append(str2); 65 | stringBuilder.append("\r\n"); 66 | return stringBuilder.toString(); 67 | } 68 | 69 | private void logfile(LogLevel logLevel, String str, String str2) { 70 | try { 71 | Writer fileWriter = new FileWriter(getLogFile(), true); 72 | BufferedWriter bufferedWriter = new BufferedWriter(fileWriter); 73 | bufferedWriter.write(str2); 74 | bufferedWriter.newLine(); 75 | bufferedWriter.close(); 76 | fileWriter.close(); 77 | } catch (Exception e) { 78 | } 79 | } 80 | 81 | private File getLogFile() { 82 | if ("mounted".equalsIgnoreCase(Environment.getExternalStorageState())) { 83 | File file = new File(Environment.getExternalStorageDirectory().getPath() + File.separator + this.mLogConfig.mLogDir); 84 | if (!file.exists()) { 85 | file.mkdirs(); 86 | } 87 | while (this.mFile == null) { 88 | this.mFile = new File(file.getPath() + File.separator + new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".R" + this.mRun + ".0." + this.mLogConfig.mFileName); 89 | if (!this.mFile.exists()) { 90 | break; 91 | } 92 | this.mRun++; 93 | this.mFile = null; 94 | } 95 | if (getLogFileSize() >= this.mLogConfig.mLogSize) { 96 | this.mNext++; 97 | this.mFile = new File(file.getPath() + File.separator + new SimpleDateFormat("yyyyMMdd").format(new Date()) + ".R" + this.mRun + "." + this.mNext + "." + this.mLogConfig.mFileName); 98 | this.mFile.delete(); 99 | } 100 | } 101 | return this.mFile; 102 | } 103 | 104 | private long getLogFileSize() { 105 | long j = -1; 106 | if (this.mFile == null) { 107 | return -1; 108 | } 109 | try { 110 | FileInputStream fileInputStream = new FileInputStream(this.mFile); 111 | j = (long) fileInputStream.available(); 112 | fileInputStream.close(); 113 | return j; 114 | } catch (Exception e) { 115 | return j; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/android/XLUtil.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.android; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.Context; 5 | import android.net.ConnectivityManager; 6 | import android.net.NetworkInfo; 7 | import android.net.wifi.WifiInfo; 8 | import android.net.wifi.WifiManager; 9 | import android.os.Build; 10 | import android.os.Build.VERSION; 11 | import android.telephony.TelephonyManager; 12 | import android.text.TextUtils; 13 | import android.util.Base64; 14 | import java.io.FileNotFoundException; 15 | import java.io.IOException; 16 | import java.io.InputStream; 17 | import java.io.OutputStream; 18 | import java.io.UnsupportedEncodingException; 19 | import java.net.NetworkInterface; 20 | import java.security.MessageDigest; 21 | import java.security.NoSuchAlgorithmException; 22 | import java.util.Collections; 23 | import java.util.HashMap; 24 | import java.util.Iterator; 25 | import java.util.Map; 26 | import java.util.Map.Entry; 27 | import java.util.concurrent.locks.ReadWriteLock; 28 | import java.util.concurrent.locks.ReentrantReadWriteLock; 29 | import org.json.JSONException; 30 | import org.json.JSONObject; 31 | 32 | public class XLUtil { 33 | private static final int IMEI_LEN = 15; 34 | private static final String TAG = "XLUtil"; 35 | private static final ConfigFile sConfigFile = new ConfigFile(); 36 | 37 | private static class ConfigFile { 38 | private static final String IDENTIFY_FILE_NAME = "Identify.txt"; 39 | private Map configMap; 40 | private ReadWriteLock lock; 41 | 42 | private ConfigFile() { 43 | this.configMap = new HashMap(); 44 | this.lock = new ReentrantReadWriteLock(); 45 | } 46 | 47 | String get(Context context, String str, String str2) { 48 | this.lock.readLock().lock(); 49 | String str3 = (String) this.configMap.get(str); 50 | if (str3 == null) { 51 | loadFile(context); 52 | str3 = (String) this.configMap.get(str); 53 | } 54 | this.lock.readLock().unlock(); 55 | return str3 != null ? str3 : str2; 56 | } 57 | 58 | void set(Context context, String str, String str2) { 59 | this.lock.writeLock().lock(); 60 | this.configMap.put(str, str2); 61 | saveFile(context); 62 | this.lock.writeLock().unlock(); 63 | XLLog.i(XLUtil.TAG, "ConfigFile set key=" + str + " value=" + str2); 64 | } 65 | 66 | private void loadFile(Context context) { 67 | XLLog.i(XLUtil.TAG, "loadAndParseFile start"); 68 | if (context == null || IDENTIFY_FILE_NAME == null) { 69 | XLLog.e(XLUtil.TAG, "loadAndParseFile end, parameter invalid, fileName:Identify.txt"); 70 | return; 71 | } 72 | String readFromFile = readFromFile(context, IDENTIFY_FILE_NAME); 73 | if (readFromFile == null) { 74 | XLLog.i(XLUtil.TAG, "loadAndParseFile end, fileContext is empty"); 75 | return; 76 | } 77 | this.configMap.clear(); 78 | String[] split = readFromFile.split("\n"); 79 | for (String split2 : split) { 80 | String[] split3 = split2.split("="); 81 | if (split3.length == 2) { 82 | this.configMap.put(split3[0], split3[1]); 83 | XLLog.i(XLUtil.TAG, "ConfigFile loadFile key=" + split3[0] + " value=" + split3[1]); 84 | } 85 | } 86 | XLLog.i(XLUtil.TAG, "loadAndParseFile end"); 87 | } 88 | 89 | private void saveFile(Context context) { 90 | StringBuilder stringBuilder = new StringBuilder(); 91 | for (Entry entry : this.configMap.entrySet()) { 92 | stringBuilder.append(((String) entry.getKey()) + "=" + ((String) entry.getValue()) + "\n"); 93 | } 94 | writeToFile(context, stringBuilder.toString(), IDENTIFY_FILE_NAME); 95 | } 96 | 97 | private void writeToFile(Context context, String str, String str2) { 98 | if (context == null || str == null || str2 == null) { 99 | XLLog.e(XLUtil.TAG, "writeToFile, Parameter invalid, fileName:" + str2); 100 | return; 101 | } 102 | try { 103 | OutputStream openFileOutput = context.openFileOutput(str2, 0); 104 | try { 105 | openFileOutput.write(str.getBytes("utf-8")); 106 | openFileOutput.close(); 107 | } catch (UnsupportedEncodingException e) { 108 | e.printStackTrace(); 109 | } catch (IOException e2) { 110 | e2.printStackTrace(); 111 | } 112 | } catch (FileNotFoundException e3) { 113 | e3.printStackTrace(); 114 | } 115 | } 116 | 117 | private String readFromFile(Context context, String str) { 118 | String str2 = null; 119 | if (context == null || str == null) { 120 | XLLog.e(XLUtil.TAG, "readFromFile, parameter invalid, fileName:" + str); 121 | } else { 122 | try { 123 | InputStream openFileInput = context.openFileInput(str); 124 | byte[] bArr = new byte[256]; 125 | try { 126 | int read = openFileInput.read(bArr); 127 | if (read > 0) { 128 | str2 = new String(bArr, 0, read, "utf-8"); 129 | } 130 | openFileInput.close(); 131 | } catch (IOException e) { 132 | e.printStackTrace(); 133 | } 134 | } catch (FileNotFoundException e2) { 135 | XLLog.i(XLUtil.TAG, str + " File Not Found"); 136 | } 137 | } 138 | return str2; 139 | } 140 | } 141 | 142 | public enum GUID_TYPE { 143 | DEFAULT, 144 | JUST_IMEI, 145 | JUST_MAC, 146 | ALL 147 | } 148 | 149 | public static class GuidInfo { 150 | public String mGuid = null; 151 | public GUID_TYPE mType = GUID_TYPE.DEFAULT; 152 | } 153 | 154 | public enum NetWorkCarrier { 155 | UNKNOWN, 156 | CMCC, 157 | CU, 158 | CT 159 | } 160 | 161 | public static long getCurrentUnixTime() { 162 | return System.currentTimeMillis() / 1000; 163 | } 164 | 165 | public static String getPeerid(Context context) { 166 | if (context == null) { 167 | return null; 168 | } 169 | String str = sConfigFile.get(context, "peerid", null); 170 | if (!TextUtils.isEmpty(str)) { 171 | return str; 172 | } 173 | String mac = getMAC(context); 174 | if (TextUtils.isEmpty(mac)) { 175 | mac = getIMEI(context); 176 | if (!TextUtils.isEmpty(mac)) { 177 | str = mac + "V"; 178 | } 179 | } else { 180 | str = mac + "004V"; 181 | } 182 | if (TextUtils.isEmpty(str)) { 183 | return null; 184 | } 185 | sConfigFile.set(context, "peerid", str); 186 | return str; 187 | } 188 | 189 | public static String getMAC(Context context) { 190 | String str = null; 191 | if (context != null) { 192 | str = sConfigFile.get(context, "MAC", null); 193 | if (TextUtils.isEmpty(str)) { 194 | str = getWifiMacAddress(); 195 | if (!TextUtils.isEmpty(str)) { 196 | sConfigFile.set(context, "MAC", str); 197 | } 198 | } 199 | } 200 | return str; 201 | } 202 | 203 | @SuppressLint({"NewApi"}) 204 | public static String getWifiMacAddress() { 205 | try { 206 | String str = "wlan0"; 207 | for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) { 208 | if (networkInterface.getName().equalsIgnoreCase(str)) { 209 | byte[] hardwareAddress = networkInterface.getHardwareAddress(); 210 | if (hardwareAddress == null) { 211 | return null; 212 | } 213 | StringBuilder stringBuilder = new StringBuilder(); 214 | int length = hardwareAddress.length; 215 | for (int i = 0; i < length; i++) { 216 | stringBuilder.append(String.format("%02X", new Object[]{Byte.valueOf(hardwareAddress[i])})); 217 | } 218 | return stringBuilder.toString(); 219 | } 220 | } 221 | } catch (Exception e) { 222 | e.printStackTrace(); 223 | } 224 | return null; 225 | } 226 | 227 | public static String getIMEI(Context context) { 228 | Exception e; 229 | if (context == null) { 230 | return null; 231 | } 232 | String str = sConfigFile.get(context, "IMEI", null); 233 | if (!TextUtils.isEmpty(str)) { 234 | return str; 235 | } 236 | String deviceId; 237 | TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService("phone"); 238 | if (telephonyManager != null) { 239 | try { 240 | deviceId = telephonyManager.getDeviceId(); 241 | if (deviceId != null) { 242 | try { 243 | if (deviceId.length() < 15) { 244 | str = deviceId; 245 | int length = 15 - deviceId.length(); 246 | while (true) { 247 | int i = length - 1; 248 | if (length <= 0) { 249 | break; 250 | } 251 | str = str + "M"; 252 | length = i; 253 | } 254 | deviceId = str; 255 | } 256 | sConfigFile.set(context, "IMEI", deviceId); 257 | } catch (Exception e2) { 258 | e = e2; 259 | e.printStackTrace(); 260 | return deviceId; 261 | } 262 | } 263 | } catch (Exception e3) { 264 | Exception exception = e3; 265 | deviceId = str; 266 | e = exception; 267 | } 268 | } else { 269 | deviceId = str; 270 | } 271 | return deviceId; 272 | } 273 | 274 | public static GuidInfo generateGuid(Context context) { 275 | GuidInfo guidInfo = new GuidInfo(); 276 | GUID_TYPE guid_type = GUID_TYPE.DEFAULT; 277 | String imei = getIMEI(context); 278 | if (TextUtils.isEmpty(imei)) { 279 | imei = "000000000000000"; 280 | } else { 281 | guid_type = GUID_TYPE.JUST_IMEI; 282 | } 283 | String mac = getMAC(context); 284 | if (TextUtils.isEmpty(mac)) { 285 | mac = "000000000000"; 286 | } else if (guid_type == GUID_TYPE.JUST_IMEI) { 287 | guid_type = GUID_TYPE.ALL; 288 | } else { 289 | guid_type = GUID_TYPE.JUST_MAC; 290 | } 291 | guidInfo.mGuid = imei + "_" + mac; 292 | guidInfo.mType = guid_type; 293 | return guidInfo; 294 | } 295 | 296 | public static String getOSVersion(Context context) { 297 | StringBuilder stringBuilder = new StringBuilder(); 298 | stringBuilder.append("SDKV = " + VERSION.RELEASE); 299 | stringBuilder.append("_MANUFACTURER = " + Build.MANUFACTURER); 300 | stringBuilder.append("_MODEL = " + Build.MODEL); 301 | stringBuilder.append("_PRODUCT = " + Build.PRODUCT); 302 | stringBuilder.append("_FINGERPRINT = " + Build.FINGERPRINT); 303 | stringBuilder.append("_CPU_ABI = " + Build.CPU_ABI); 304 | stringBuilder.append("_ID = " + Build.ID); 305 | return stringBuilder.toString(); 306 | } 307 | 308 | public static String getAPNName(Context context) { 309 | if (context == null) { 310 | return null; 311 | } 312 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService("connectivity"); 313 | if (connectivityManager == null) { 314 | return null; 315 | } 316 | NetworkInfo networkInfo = connectivityManager.getNetworkInfo(0); 317 | if (networkInfo == null) { 318 | return null; 319 | } 320 | return networkInfo.getExtraInfo(); 321 | } 322 | 323 | public static String getSSID(Context context) { 324 | if (context == null) { 325 | XLLog.e(TAG, "getSSID, context invalid"); 326 | return null; 327 | } 328 | WifiManager wifiManager = (WifiManager) context.getSystemService("wifi"); 329 | if (wifiManager != null) { 330 | WifiInfo connectionInfo = wifiManager.getConnectionInfo(); 331 | if (connectionInfo != null) { 332 | return connectionInfo.getSSID(); 333 | } 334 | } 335 | return null; 336 | } 337 | 338 | public static String getBSSID(Context context) { 339 | if (context == null) { 340 | XLLog.e(TAG, "getBSSID, context invalid"); 341 | return null; 342 | } 343 | WifiManager wifiManager = (WifiManager) context.getSystemService("wifi"); 344 | if (wifiManager != null) { 345 | try { 346 | WifiInfo connectionInfo = wifiManager.getConnectionInfo(); 347 | if (connectionInfo != null) { 348 | return connectionInfo.getBSSID(); 349 | } 350 | } catch (Exception e) { 351 | } 352 | } 353 | return null; 354 | } 355 | 356 | public static int getNetworkTypeComplete(Context context) { 357 | if (context == null) { 358 | XLLog.e(TAG, "getNetworkTypeComplete, context invalid"); 359 | return 0; 360 | } 361 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService("connectivity"); 362 | if (connectivityManager == null) { 363 | return 0; 364 | } 365 | NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 366 | if (activeNetworkInfo == null) { 367 | return 0; 368 | } 369 | int type = activeNetworkInfo.getType(); 370 | if (type == 1) { 371 | return 9; 372 | } 373 | if (type != 0) { 374 | return 5; 375 | } 376 | int i; 377 | switch (activeNetworkInfo.getSubtype()) { 378 | case 1: 379 | case 2: 380 | case 4: 381 | case 7: 382 | case 11: 383 | return 2; 384 | case 3: 385 | case 5: 386 | case 6: 387 | case 8: 388 | case 9: 389 | case 10: 390 | case 12: 391 | case 14: 392 | case 15: 393 | return 3; 394 | case 13: 395 | i = 4; 396 | break; 397 | default: 398 | i = 0; 399 | break; 400 | } 401 | return i; 402 | } 403 | 404 | public static int getNetworkTypeSimple(Context context) { 405 | if (context == null) { 406 | XLLog.e(TAG, "getNetworkTypeSimple, context invalid"); 407 | return 0; 408 | } 409 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService("connectivity"); 410 | if (connectivityManager == null) { 411 | return 1; 412 | } 413 | NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 414 | if (activeNetworkInfo == null) { 415 | return 1; 416 | } 417 | int type = activeNetworkInfo.getType(); 418 | if (type == 1) { 419 | return 2; 420 | } 421 | if (type != 0) { 422 | return 1; 423 | } 424 | int i; 425 | switch (activeNetworkInfo.getSubtype()) { 426 | case 1: 427 | case 2: 428 | case 3: 429 | case 4: 430 | case 5: 431 | case 6: 432 | case 7: 433 | case 8: 434 | case 9: 435 | case 10: 436 | case 11: 437 | case 12: 438 | case 13: 439 | case 14: 440 | case 15: 441 | i = 3; 442 | break; 443 | default: 444 | i = 1; 445 | break; 446 | } 447 | return i; 448 | } 449 | 450 | public static String getMd5(String str) { 451 | if (str == null) { 452 | XLLog.e(TAG, "getMd5, key invalid"); 453 | return null; 454 | } 455 | try { 456 | char[] cArr = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; 457 | MessageDigest instance = MessageDigest.getInstance("MD5"); 458 | byte[] bytes = str.getBytes(); 459 | instance.update(bytes, 0, bytes.length); 460 | byte[] digest = instance.digest(); 461 | StringBuilder stringBuilder = new StringBuilder(32); 462 | for (byte b : digest) { 463 | stringBuilder.append(cArr[(b >> 4) & 15]).append(cArr[(b >> 0) & 15]); 464 | } 465 | return stringBuilder.toString(); 466 | } catch (NoSuchAlgorithmException e) { 467 | e.printStackTrace(); 468 | return str; 469 | } 470 | } 471 | 472 | public static String generateAppKey(String str, short s, byte b) { 473 | if (str == null) { 474 | XLLog.e(TAG, "generateAppKey, appName invalid"); 475 | return null; 476 | } 477 | int length = str.length(); 478 | byte[] bArr = new byte[(((length + 1) + 2) + 1)]; 479 | byte[] bytes = str.getBytes(); 480 | for (int i = 0; i < bytes.length; i++) { 481 | bArr[i] = bytes[i]; 482 | } 483 | bArr[length] = (byte) 0; 484 | bArr[length + 1] = (byte) (s & 255); 485 | bArr[length + 2] = (byte) ((s >> 8) & 255); 486 | bArr[length + 3] = b; 487 | return new String(Base64.encode(bArr, 0)).trim(); 488 | } 489 | 490 | public static Map parseJSONString(String str) { 491 | if (str == null) { 492 | XLLog.e(TAG, "parseJSONString, JSONString invalid"); 493 | return null; 494 | } 495 | Map hashMap = new HashMap(); 496 | try { 497 | JSONObject jSONObject = new JSONObject(str); 498 | Iterator keys = jSONObject.keys(); 499 | while (keys.hasNext()) { 500 | String str2 = (String) keys.next(); 501 | hashMap.put(str2, jSONObject.getString(str2)); 502 | } 503 | } catch (JSONException e) { 504 | e.printStackTrace(); 505 | } 506 | return hashMap; 507 | } 508 | 509 | public static NetWorkCarrier getNetWorkCarrier(Context context) { 510 | if (context != null) { 511 | TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService("phone"); 512 | if (telephonyManager != null) { 513 | try { 514 | String subscriberId = telephonyManager.getSubscriberId(); 515 | if (subscriberId.startsWith("46000") || subscriberId.startsWith("46002")) { 516 | return NetWorkCarrier.CMCC; 517 | } 518 | if (subscriberId.startsWith("46001")) { 519 | return NetWorkCarrier.CU; 520 | } 521 | if (subscriberId.startsWith("46003")) { 522 | return NetWorkCarrier.CT; 523 | } 524 | } catch (Exception e) { 525 | e.printStackTrace(); 526 | } 527 | } 528 | } 529 | return NetWorkCarrier.UNKNOWN; 530 | } 531 | } 532 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/BtIndexSet.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class BtIndexSet { 4 | public int[] mIndexSet; 5 | 6 | public BtIndexSet(int i) { 7 | this.mIndexSet = new int[i]; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/BtSubTaskDetail.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class BtSubTaskDetail { 4 | public int mFileIndex; 5 | public boolean mIsSelect; 6 | public XLTaskInfo mTaskInfo = new XLTaskInfo(); 7 | } 8 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/BtTaskParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class BtTaskParam { 4 | public int mCreateMode; 5 | public String mFilePath; 6 | public int mMaxConcurrent; 7 | public int mSeqId; 8 | public String mTorrentPath; 9 | 10 | public BtTaskParam() { 11 | } 12 | 13 | public BtTaskParam(String str, String str2, int i, int i2, int i3) { 14 | this.mTorrentPath = str; 15 | this.mFilePath = str2; 16 | this.mMaxConcurrent = i; 17 | this.mCreateMode = i2; 18 | this.mSeqId = i3; 19 | } 20 | 21 | public void setTorrentPath(String str) { 22 | this.mTorrentPath = str; 23 | } 24 | 25 | public void setFilePath(String str) { 26 | this.mFilePath = str; 27 | } 28 | 29 | public void setMaxConcurrent(int i) { 30 | this.mMaxConcurrent = i; 31 | } 32 | 33 | public void setCreateMode(int i) { 34 | this.mCreateMode = i; 35 | } 36 | 37 | public void setSeqId(int i) { 38 | this.mSeqId = i; 39 | } 40 | 41 | public boolean checkMemberVar() { 42 | if (this.mTorrentPath == null || this.mFilePath == null) { 43 | return false; 44 | } 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/BtTaskStatus.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class BtTaskStatus { 4 | public int[] mStatus; 5 | 6 | public BtTaskStatus(int i) { 7 | this.mStatus = new int[i]; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/CIDTaskParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class CIDTaskParam { 4 | public String mBcid; 5 | public String mCid; 6 | public int mCreateMode; 7 | public String mFileName; 8 | public String mFilePath; 9 | public long mFileSize; 10 | public String mGcid; 11 | public int mSeqId; 12 | 13 | public CIDTaskParam(String str, String str2, String str3, String str4, String str5, long j, int i, int i2) { 14 | this.mCid = str; 15 | this.mGcid = str2; 16 | this.mBcid = str3; 17 | this.mFilePath = str4; 18 | this.mFileName = str5; 19 | this.mFileSize = j; 20 | this.mCreateMode = i; 21 | this.mSeqId = i2; 22 | } 23 | 24 | public void setCid(String str) { 25 | this.mCid = str; 26 | } 27 | 28 | public void setGcid(String str) { 29 | this.mGcid = str; 30 | } 31 | 32 | public void setBcid(String str) { 33 | this.mBcid = str; 34 | } 35 | 36 | public void setFilePath(String str) { 37 | this.mFilePath = str; 38 | } 39 | 40 | public void setFileName(String str) { 41 | this.mFileName = str; 42 | } 43 | 44 | public void setFileSize(long j) { 45 | this.mFileSize = j; 46 | } 47 | 48 | public void setCreateMode(int i) { 49 | this.mCreateMode = i; 50 | } 51 | 52 | public void setSeqId(int i) { 53 | this.mSeqId = i; 54 | } 55 | 56 | public boolean checkMemberVar() { 57 | if (this.mCid == null || this.mGcid == null || this.mBcid == null || this.mFilePath == null || this.mFileName == null) { 58 | return false; 59 | } 60 | return true; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/EmuleTaskParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class EmuleTaskParam { 4 | public int mCreateMode; 5 | public String mFileName; 6 | public String mFilePath; 7 | public int mSeqId; 8 | public String mUrl; 9 | 10 | public EmuleTaskParam() { 11 | } 12 | 13 | public EmuleTaskParam(String str, String str2, String str3, int i, int i2) { 14 | this.mFileName = str; 15 | this.mFilePath = str2; 16 | this.mUrl = str3; 17 | this.mCreateMode = i; 18 | this.mSeqId = i2; 19 | } 20 | 21 | public void setFileName(String str) { 22 | this.mFileName = str; 23 | } 24 | 25 | public void setFilePath(String str) { 26 | this.mFilePath = str; 27 | } 28 | 29 | public void setUrl(String str) { 30 | this.mUrl = str; 31 | } 32 | 33 | public void setCreateMode(int i) { 34 | this.mCreateMode = i; 35 | } 36 | 37 | public void setSeqId(int i) { 38 | this.mSeqId = i; 39 | } 40 | 41 | public boolean checkMemberVar() { 42 | if (this.mFileName == null || this.mFilePath == null || this.mUrl == null) { 43 | return false; 44 | } 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/ErrorCodeToMsg.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class ErrorCodeToMsg { 4 | public static final String ErrCodeToMsg = "{ \"9000\": \"XL_NO_ERRNO \" , \"9101\": \"XL_ALREADY_INIT \" , \"9102\": \"XL_SDK_NOT_INIT \" , \"9103\": \"XL_TASK_ALREADY_EXIST \" , \"9104\": \"XL_TASK_NOT_EXIST \" , \"9105\": \"XL_TASK_ALREADY_STOPPED \" , \"9106\": \"XL_TASK_ALREADY_RUNNING \" , \"9107\": \"XL_TASK_NOT_START \" , \"9108\": \"XL_TASK_STILL_RUNNING \" , \"9109\": \"XL_FILE_EXISTED \" , \"9110\": \"XL_DISK_FULL \" , \"9111\": \"XL_TOO_MUCH_TASK \" , \"9112\": \"XL_PARAM_ERROR \" , \"9113\": \"XL_SCHEMA_NOT_SUPPORT \" , \"9114\": \"XL_DYNAMIC_PARAM_FAIL \" , \"9115\": \"XL_CONTINUE_NO_NAME \" , \"9116\": \"XL_APPNAME_APPKEY_ERROR \" , \"9117\": \"XL_CREATE_THREAD_ERROR \" , \"9118\": \"XL_TASK_FINISH \" , \"9119\": \"XL_TASK_NOT_RUNNING \" , \"9120\": \"XL_TASK_NOT_IDLE \" , \"9121\": \"XL_TASK_TYPE_NOT_SUPPORT \" , \"9122\": \"XL_ADD_RESOURCE_ERROR \" , \"9123\": \"XL_TASK_LOADING_CFG \" , \"9301\": \"XL_NO_ENOUGH_BUFFER \" , \"9302\": \"XL_TORRENT_PARSE_ERROR \" , \"9303\": \"XL_INDEX_NOT_READY \" , \"9304\": \"XL_TORRENT_IMCOMPLETE \" , \"9900\": \"DOWNLOAD_MANAGER_ERROR \" , \"9901\": \"APPKEY_CHECKER_ERROR \" , \"111024\": \"COMMON_ERRCODE_BASE \" , \"111025\": \"TARGET_THREAD_STOPING \" , \"111026\": \"OUT_OF_MEMORY \" , \"111031\": \"TASK_USE_TOO_MUCH_MEM \" , \"111032\": \"OUT_OF_FIXED_MEMORY \" , \"111033\": \"QUEUE_NO_ROOM \" , \"111035\": \"MAP_UNINIT \" , \"111036\": \"MAP_DUPLICATE_KEY \" , \"111037\": \"MAP_KEY_NOT_FOUND \" , \"111038\": \"INVALID_ITERATOR \" , \"111039\": \"BUFFER_OVERFLOW \" , \"111041\": \"INVALID_ARGUMENT \" , \"111048\": \"INVALID_SOCKET_DESCRIPTOR \" , \"111050\": \"ERROR_INVALID_INADDR \" , \"111181\": \"REDIRECT_TOO_MUCH \" , \"111057\": \"NOT_IMPLEMENT \" , \"111074\": \"INVALID_TIMER_INDEX \" , \"111078\": \"DNS_INVALID_ADDR \" , \"111083\": \"BAD_DIR_PATH \" , \"111084\": \"FILE_CANNOT_TRUNCATE \" , \"111085\": \"INSUFFICIENT_DISK_SPACE \" , \"111086\": \"FILE_TOO_BIG \" , \"111118\": \"DISPATCHER_ERRCODE_BASE \" , \"111119\": \"DATA_MGR_ERRCODE_BASE \" , \"111120\": \"ALLOC_INVALID_SIZE \" , \"111121\": \"DATA_BUFFER_IS_FULL \" , \"111122\": \"BLOCK_NO_INVALID \" , \"111123\": \"CHECK_DATA_BUFFER_NOT_ENOUG \" , \"111124\": \"BCID_CHECK_FAIL \" , \"111125\": \"BCID_ONCE_CHECT_TOO_MUCH \" , \"111126\": \"READ_FILE_ERR \" , \"111127\": \"WRITE_FILE_ERR \" , \"111128\": \"OPEN_FILE_ERR \" , \"111129\": \"FILE_PATH_TOO_LONG \" , \"111130\": \"SD_INVALID_FILE_SIZE \" , \"111131\": \"FILE_CFG_MAGIC_ERROR \" , \"111132\": \"FILE_CFG_READ_ERROR \" , \"111133\": \"FILE_CFG_WRITE_ERROR \" , \"111134\": \"FILE_CFG_READ_HEADER_ERROR \" , \"111135\": \"FILE_CFG_RESOLVE_ERROR \" , \"111136\": \"TASK_FAILURE_NO_DATA_PIPE \" , \"111137\": \"NO_FILE_NAME \" , \"111138\": \"CANNOT_GET_FILE_NAME \" , \"111139\": \"CREATE_FILE_FAIL \" , \"111140\": \"OPEN_OLD_FILE_FAIL \" , \"111141\": \"FILE_SIZE_NOT_BELIEVE \" , \"111142\": \"FILE_SIZE_TOO_SMALL \" , \"111143\": \"FILE_NOT_EXIST \" , \"111144\": \"FILE_INVALID_PARA \" , \"111145\": \"FILE_CREATING \" , \"111146\": \"FIL_INFO_INVALID_DATA \" , \"111147\": \"FIL_INFO_RECVED_DATA \" , \"111159\": \"CONF_MGR_ERRCODE_BASE \" , \"111160\": \"SETTINGS_ERR_UNKNOWN \" , \"111161\": \"SETTINGS_ERR_INVALID_FILE_NAME \" , \"111162\": \"SETTINGS_ERR_CFG_FILE_NOT_EXIST \" , \"111163\": \"SETTINGS_ERR_INVALID_LINE \" , \"111164\": \"SETTINGS_ERR_INVALID_ITEM_NAME \" , \"111165\": \"SETTINGS_ERR_INVALID_ITEM_VALUE \" , \"111166\": \"SETTINGS_ERR_LIST_EMPTY \" , \"111167\": \"SETTINGS_ERR_ITEM_NOT_FOUND \" , \"111168\": \"NET_REACTOR_ERRCODE_BASE \" , \"111169\": \"NET_CONNECT_SSL_ERR \" , \"111170\": \"NET_BROKEN_PIPE \" , \"111171\": \"NET_CONNECTION_REFUSED \" , \"111172\": \"NET_SSL_GET_FD_ERROR \" , \"111173\": \"NET_OP_CANCEL \" , \"111174\": \"NET_UNKNOWN_ERROR \" , \"111175\": \"NET_NORMAL_CLOSE \" , \"111176\": \"TASK_FAIL_LONG_TIME_NO_RECV_DATA \" , \"111177\": \"TASK_FILE_SIZE_TOO_LARGE \" , \"111178\": \"TASK_RETRY_ALWAY_FAIL \" , \"111300\": \"ASYN_FILE_E_BASE \" , \"111301\": \"ASYN_FILE_E_OP_NONE \" , \"111302\": \"ASYN_FILE_E_OP_BUSY \" , \"111303\": \"ASYN_FILE_E_FILE_NOT_OPEN \" , \"111304\": \"ASYN_FILE_E_FILE_REOPEN \" , \"111305\": \"ASYN_FILE_E_EMPTY_FILE \" , \"111306\": \"ASYN_FILE_E_FILE_SIZE_LESS \" , \"111307\": \"ASYN_FILE_E_TOO_MUCH_DATA \" , \"111308\": \"ASYN_FILE_E_FILE_CLOSING \" , \"112400\": \"ERR_PTL_PROTOCOL_NOT_SUPPORT \" , \"112500\": \"ERR_PTL_PEER_OFFLINE \" , \"112600\": \"ERR_PTL_GET_PEERSN_FAILED \" , \"11300\": \"P2P_PIPE_ERRCODE_BASE\t\t\t \" , \"11301\": \"ERR_P2P_VERSION_NOT_SUPPORT\t\t \" , \"11302\": \"ERR_P2P_WAITING_CLOSE\t\t\t \" , \"11303\": \"ERR_P2P_HANDSHAKE_RESP_FAIL\t\t \" , \"11304\": \"ERR_P2P_REQUEST_RESP_FAIL\t\t \" , \"11305\": \"ERR_P2P_UPLOAD_OVER_MAX\t\t\t \" , \"11306\": \"ERR_P2P_REMOTE_UNKNOWN_MY_CMD\t \" , \"11307\": \"ERR_P2P_NOT_SUPPORT_UDT\t\t\t \" , \"11308\": \"ERR_P2P_BROKER_CONNECT\t\t\t \" , \"11309\": \"ERR_P2P_INVALID_COMMAND\t\t\t \" , \"11310\": \"ERR_P2P_INVALID_PARAM\t\t\t \" , \"11311\": \"ERR_P2P_CONNECT_FAILED\t\t\t \" , \"11312\": \"ERR_P2P_CONNECT_UPLOAD_SLOW\t \" , \"11313\": \"ERR_P2P_ALLOC_MEM_ERR \" , \"11314\": \"ERR_P2P_SEND_HANDSHAKE \" , \"114001\": \"TASK_FAILURE_QUERY_EMULE_HUB_FAILED\" , \"114101\": \"TASK_FAILURE_EMULE_NO_RECORD \" , \"114002\": \"TASK_FAILURE_SUBTASK_FAILED \" , \"114003\": \"TASK_FAILURE_CANNOT_START_SUBTASK \" , \"114004\": \"TASK_FAILURE_QUERY_BT_HUB_FAILED \" , \"114005\": \"TASK_FAILURE_PARSE_TORRENT_FAILED \" , \"114006\": \"TASK_FAILURE_GET_TORRENT_FAILED \" , \"114007\": \"TASK_FAILURE_SAVE_TORRENT_FAILED \" , \"115000\": \"RES_QUERY_E_BASE \" , \"115100\": \"HTTP_HUB_CLIENT_E_BASE \" , \"116000\": \"IP6_ERRCODE_BASE \" , \"116001\": \"ERR_INVALID_ADDRESS_FAMILY \" , \"116002\": \"IP6_INVALID_IN6ADDR \" , \"116003\": \"IP6_NOT_SUPPORT_SSL \" , \"117000\": \"PAUSE_TASK_WRITE_CFG_ERR \" , \"117001\": \"PAUSE_TASK_WRITE_DATA_TIMEOUT \" }"; 5 | } 6 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/GetDownloadHead.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class GetDownloadHead { 4 | public String mHttpResponse = null; 5 | public int mHttpState = -1; 6 | } 7 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/GetDownloadLibVersion.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class GetDownloadLibVersion { 4 | public String mVersion = null; 5 | } 6 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/GetFileName.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class GetFileName { 4 | private String mFileName; 5 | 6 | public String getFileName() { 7 | return this.mFileName; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/GetTaskId.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class GetTaskId { 4 | private long mTaskId; 5 | 6 | public long getTaskId() { 7 | return this.mTaskId; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/InitParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class InitParam { 4 | public String mAppKey; 5 | public String mAppVersion; 6 | public int mPermissionLevel; 7 | public String mStatCfgSavePath; 8 | public String mStatSavePath; 9 | 10 | public InitParam(String str, String str2, String str3, String str4, int i) { 11 | this.mAppKey = str; 12 | this.mAppVersion = str2; 13 | this.mStatSavePath = str3; 14 | this.mStatCfgSavePath = str4; 15 | this.mPermissionLevel = i; 16 | } 17 | 18 | public InitParam() { 19 | } 20 | 21 | public boolean checkMemberVar() { 22 | if (this.mAppKey == null || this.mAppVersion == null || this.mStatSavePath == null || this.mStatCfgSavePath == null) { 23 | return false; 24 | } 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/MagnetTaskParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class MagnetTaskParam { 4 | public String mFileName; 5 | public String mFilePath; 6 | public String mUrl; 7 | 8 | public MagnetTaskParam(String str, String str2, String str3) { 9 | this.mFileName = str; 10 | this.mFilePath = str2; 11 | this.mUrl = str3; 12 | } 13 | 14 | public MagnetTaskParam() { 15 | } 16 | 17 | public void setUrl(String str) { 18 | this.mUrl = str; 19 | } 20 | 21 | public void setFileName(String str) { 22 | this.mFileName = str; 23 | } 24 | 25 | public void setFilePath(String str) { 26 | this.mFilePath = str; 27 | } 28 | 29 | 30 | 31 | public boolean checkMemberVar() { 32 | if (this.mFileName == null || this.mFilePath == null || this.mUrl == null) { 33 | return false; 34 | } 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/MaxDownloadSpeedParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class MaxDownloadSpeedParam { 4 | public long mSpeed; 5 | } 6 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/P2spTaskParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class P2spTaskParam { 4 | public String mCookie; 5 | public int mCreateMode; 6 | public String mFileName; 7 | public String mFilePath; 8 | public String mPass; 9 | public String mRefUrl; 10 | public int mSeqId; 11 | public String mUrl; 12 | public String mUser; 13 | 14 | public P2spTaskParam() { 15 | } 16 | 17 | public P2spTaskParam(String str, String str2, String str3, String str4, String str5, String str6, String str7, int i, int i2) { 18 | this.mFileName = str; 19 | this.mFilePath = str2; 20 | this.mUrl = str3; 21 | this.mCookie = str4; 22 | this.mRefUrl = str5; 23 | this.mUser = str6; 24 | this.mPass = str7; 25 | this.mCreateMode = i; 26 | this.mSeqId = i2; 27 | } 28 | 29 | public void setUrl(String str) { 30 | this.mUrl = str; 31 | } 32 | 33 | public void setFileName(String str) { 34 | this.mFileName = str; 35 | } 36 | 37 | public void setFilePath(String str) { 38 | this.mFilePath = str; 39 | } 40 | 41 | public void setCookie(String str) { 42 | this.mCookie = str; 43 | } 44 | 45 | public void setRefUrl(String str) { 46 | this.mRefUrl = str; 47 | } 48 | 49 | public void setUser(String str) { 50 | this.mUser = str; 51 | } 52 | 53 | public void setPass(String str) { 54 | this.mPass = str; 55 | } 56 | 57 | public void setCreateMode(int i) { 58 | this.mCreateMode = i; 59 | } 60 | 61 | public void setSeqId(int i) { 62 | this.mSeqId = i; 63 | } 64 | 65 | public boolean checkMemberVar() { 66 | if (this.mFileName == null || this.mFilePath == null || this.mUrl == null || this.mCookie == null || this.mRefUrl == null || this.mUser == null || this.mPass == null) { 67 | return false; 68 | } 69 | return true; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/PeerResourceParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class PeerResourceParam { 4 | public int mCapabilityFlag; 5 | public int mInternalIp; 6 | public String mJmpKey; 7 | public String mPeerId; 8 | public int mResLevel; 9 | public int mResPriority; 10 | public int mResType; 11 | public int mTcpPort; 12 | public int mUdpPort; 13 | public long mUserId; 14 | public String mVipCdnAuth; 15 | 16 | public PeerResourceParam(String str, long j, String str2, String str3, int i, int i2, int i3, int i4, int i5, int i6, int i7) { 17 | this.mPeerId = str; 18 | this.mUserId = j; 19 | this.mJmpKey = str2; 20 | this.mVipCdnAuth = str3; 21 | this.mInternalIp = i; 22 | this.mTcpPort = i2; 23 | this.mUdpPort = i3; 24 | this.mResLevel = i4; 25 | this.mResPriority = i5; 26 | this.mCapabilityFlag = i6; 27 | this.mResType = i7; 28 | } 29 | 30 | public void setPeerId(String str) { 31 | this.mPeerId = str; 32 | } 33 | 34 | public void setUserId(long j) { 35 | this.mUserId = j; 36 | } 37 | 38 | public void setJmpKey(String str) { 39 | this.mJmpKey = str; 40 | } 41 | 42 | public void setVipCdnAuth(String str) { 43 | this.mVipCdnAuth = str; 44 | } 45 | 46 | public void setInternalIp(int i) { 47 | this.mInternalIp = i; 48 | } 49 | 50 | public void setTcpPort(int i) { 51 | this.mTcpPort = i; 52 | } 53 | 54 | public void setUdpPort(int i) { 55 | this.mUdpPort = i; 56 | } 57 | 58 | public void setResLevel(int i) { 59 | this.mResLevel = i; 60 | } 61 | 62 | public void setResPriority(int i) { 63 | this.mResPriority = i; 64 | } 65 | 66 | public void setCapabilityFlag(int i) { 67 | this.mCapabilityFlag = i; 68 | } 69 | 70 | public void setResType(int i) { 71 | this.mResType = i; 72 | } 73 | 74 | public boolean checkMemberVar() { 75 | if (this.mPeerId == null || this.mJmpKey == null || this.mVipCdnAuth == null) { 76 | return false; 77 | } 78 | return true; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/ServerResourceParam.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class ServerResourceParam { 4 | public String mCookie; 5 | public String mRefUrl; 6 | public int mResType; 7 | public int mStrategy; 8 | public String mUrl; 9 | 10 | public ServerResourceParam(String str, String str2, String str3, int i, int i2) { 11 | this.mUrl = str; 12 | this.mRefUrl = str2; 13 | this.mCookie = str3; 14 | this.mResType = i; 15 | this.mStrategy = i2; 16 | } 17 | 18 | public void setUrl(String str) { 19 | this.mUrl = str; 20 | } 21 | 22 | public void setRefUrl(String str) { 23 | this.mRefUrl = str; 24 | } 25 | 26 | public void setCookie(String str) { 27 | this.mCookie = str; 28 | } 29 | 30 | public void setRestype(int i) { 31 | this.mResType = i; 32 | } 33 | 34 | public void setStrategy(int i) { 35 | this.mStrategy = i; 36 | } 37 | 38 | public boolean checkMemberVar() { 39 | if (this.mUrl == null || this.mRefUrl == null || this.mCookie == null) { 40 | return false; 41 | } 42 | return true; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/ThunderUrlInfo.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class ThunderUrlInfo { 4 | public String mUrl; 5 | 6 | public ThunderUrlInfo() { 7 | } 8 | 9 | public ThunderUrlInfo(String str) { 10 | this.mUrl = str; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/TorrentFileInfo.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class TorrentFileInfo { 4 | public int mFileIndex; 5 | public String mFileName; 6 | public long mFileSize; 7 | public int mRealIndex; 8 | public String mSubPath; 9 | public String playUrl; 10 | public String hash; 11 | } 12 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/TorrentInfo.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class TorrentInfo { 4 | public int mFileCount; 5 | public String mInfoHash; 6 | public boolean mIsMultiFiles; 7 | public String mMultiFileBaseFolder; 8 | public TorrentFileInfo[] mSubFileInfo; 9 | } 10 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/UrlQuickInfo.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class UrlQuickInfo { 4 | public String mContentType; 5 | public String mFileNameAdvice; 6 | public long mFileSize; 7 | public int mState; 8 | } 9 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/XLConstant.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class XLConstant { 4 | 5 | public static class QuickInfoState { 6 | public static final int QI_FAILED = 3; 7 | public static final int QI_FINISH = 2; 8 | public static final int QI_STOP = 0; 9 | public static final int QI_TRY = 1; 10 | } 11 | 12 | public enum XLCreateTaskMode { 13 | NEW_TASK, 14 | CONTINUE_TASK 15 | } 16 | 17 | public enum XLDownloadHeaderState { 18 | GDHS_UNKOWN, 19 | GDHS_REQUESTING, 20 | GDHS_SUCCESS, 21 | GDHS_ERROR 22 | } 23 | 24 | public static class XLErrorCode { 25 | public static final int ADD_RESOURCE_ERROR = 9122; 26 | public static final int ALREADY_INIT = 9101; 27 | public static final int APPKEY_CHECKER_ERROR = 9901; 28 | public static final int APPNAME_APPKEY_ERROR = 9116; 29 | public static final int ASYN_FILE_E_BASE = 111300; 30 | public static final int ASYN_FILE_E_EMPTY_FILE = 111305; 31 | public static final int ASYN_FILE_E_FILE_CLOSING = 111308; 32 | public static final int ASYN_FILE_E_FILE_NOT_OPEN = 111303; 33 | public static final int ASYN_FILE_E_FILE_REOPEN = 111304; 34 | public static final int ASYN_FILE_E_FILE_SIZE_LESS = 111306; 35 | public static final int ASYN_FILE_E_OP_BUSY = 111302; 36 | public static final int ASYN_FILE_E_OP_NONE = 111301; 37 | public static final int ASYN_FILE_E_TOO_MUCH_DATA = 111307; 38 | public static final int BAD_DIR_PATH = 111083; 39 | public static final int BT_SUB_TASK_NOT_SELECT = 9306; 40 | public static final int BUFFER_OVERFLOW = 111039; 41 | public static final int COMMON_ERRCODE_BASE = 111024; 42 | public static final int CONF_MGR_ERRCODE_BASE = 111159; 43 | public static final int CONTINUE_NO_NAME = 9115; 44 | public static final int CORRECT_CDN_ERROR = 111180; 45 | public static final int CORRECT_TIMES_TOO_MUCH = 111179; 46 | public static final int CREATE_FILE_FAIL = 111139; 47 | public static final int CREATE_THREAD_ERROR = 9117; 48 | public static final int DATA_MGR_ERRCODE_BASE = 111119; 49 | public static final int DISK_FULL = 9110; 50 | public static final int DISPATCHER_ERRCODE_BASE = 111118; 51 | public static final int DNS_INVALID_ADDR = 111078; 52 | public static final int DNS_NO_SERVER = 111077; 53 | public static final int DOWNLOAD_MANAGER_ERROR = 9900; 54 | public static final int DYNAMIC_PARAM_FAIL = 9114; 55 | public static final int ERROR_INVALID_INADDR = 111050; 56 | public static final int ERR_DPLAY_ALL_SEND_COMPLETE = 118000; 57 | public static final int ERR_DPLAY_BROKEN_SOCKET_RECV = 118307; 58 | public static final int ERR_DPLAY_BROKEN_SOCKET_SEND = 118306; 59 | public static final int ERR_DPLAY_CLIENT_ACTIVE_DISCONNECT = 118001; 60 | public static final int ERR_DPLAY_DO_DOWNLOAD_FAIL = 118305; 61 | public static final int ERR_DPLAY_DO_READFILE_FAIL = 118311; 62 | public static final int ERR_DPLAY_EV_SEND_TIMTOUT = 118310; 63 | public static final int ERR_DPLAY_HANDLE_DOWNLOAD_FAILED = 118302; 64 | public static final int ERR_DPLAY_NOT_FOUND = 118005; 65 | public static final int ERR_DPLAY_PLAY_FILE_NOT_EXIST = 118304; 66 | public static final int ERR_DPLAY_RECV_STATE_INVALID = 118308; 67 | public static final int ERR_DPLAY_SEND_FAILED = 118300; 68 | public static final int ERR_DPLAY_SEND_RANGE_INVALID = 118301; 69 | public static final int ERR_DPLAY_SEND_STATE_INVALID = 118309; 70 | public static final int ERR_DPLAY_TASK_FINISH_CANNT_DOWNLOAD = 118004; 71 | public static final int ERR_DPLAY_TASK_FINISH_CONTINUE = 118003; 72 | public static final int ERR_DPLAY_TASK_FINISH_DESTROY = 118002; 73 | public static final int ERR_DPLAY_UNKNOW_HTTP_METHOD = 118303; 74 | public static final int ERR_INVALID_ADDRESS_FAMILY = 116001; 75 | public static final int ERR_P2P_ALLOC_MEM_ERR = 11313; 76 | public static final int ERR_P2P_BROKER_CONNECT = 11308; 77 | public static final int ERR_P2P_CONNECT_FAILED = 11311; 78 | public static final int ERR_P2P_CONNECT_UPLOAD_SLOW = 11312; 79 | public static final int ERR_P2P_HANDSHAKE_RESP_FAIL = 11303; 80 | public static final int ERR_P2P_INVALID_COMMAND = 11309; 81 | public static final int ERR_P2P_INVALID_PARAM = 11310; 82 | public static final int ERR_P2P_NOT_SUPPORT_UDT = 11307; 83 | public static final int ERR_P2P_REMOTE_UNKNOWN_MY_CMD = 11306; 84 | public static final int ERR_P2P_REQUEST_RESP_FAIL = 11304; 85 | public static final int ERR_P2P_SEND_HANDSHAKE = 11314; 86 | public static final int ERR_P2P_UPLOAD_OVER_MAX = 11305; 87 | public static final int ERR_P2P_VERSION_NOT_SUPPORT = 11301; 88 | public static final int ERR_P2P_WAITING_CLOSE = 11302; 89 | public static final int ERR_PTL_GET_PEERSN_FAILED = 112600; 90 | public static final int ERR_PTL_PEER_OFFLINE = 112500; 91 | public static final int ERR_PTL_PROTOCOL_NOT_SUPPORT = 112400; 92 | public static final int FILE_CANNOT_TRUNCATE = 111084; 93 | public static final int FILE_CFG_ERASE_ERROR = 111130; 94 | public static final int FILE_CFG_MAGIC_ERROR = 111131; 95 | public static final int FILE_CFG_READ_ERROR = 111132; 96 | public static final int FILE_CFG_READ_HEADER_ERROR = 111134; 97 | public static final int FILE_CFG_RESOLVE_ERROR = 111135; 98 | public static final int FILE_CFG_TRY_FIX = 111129; 99 | public static final int FILE_CFG_WRITE_ERROR = 111133; 100 | public static final int FILE_CREATING = 111145; 101 | public static final int FILE_EXISTED = 9109; 102 | public static final int FILE_INVALID_PARA = 111144; 103 | public static final int FILE_NAME_TOO_LONG = 9125; 104 | public static final int FILE_NOT_EXIST = 111143; 105 | public static final int FILE_PATH_TOO_LONG = 111120; 106 | public static final int FILE_SIZE_NOT_BELIEVE = 111141; 107 | public static final int FILE_SIZE_TOO_SMALL = 111142; 108 | public static final int FILE_TOO_BIG = 111086; 109 | public static final int FIL_INFO_INVALID_DATA = 111146; 110 | public static final int FIL_INFO_RECVED_DATA = 111147; 111 | public static final int FULL_PATH_NAME_OCCUPIED = 9128; 112 | public static final int FULL_PATH_NAME_TOO_LONG = 9127; 113 | public static final int FUNCTION_NOT_SUPPORT = 9123; 114 | public static final int HTTP_HUB_CLIENT_E_BASE = 115100; 115 | public static final int HTTP_SERVER_NOT_START = 9400; 116 | public static final int INDEX_NOT_READY = 9303; 117 | public static final int INSUFFICIENT_DISK_SPACE = 111085; 118 | public static final int INVALID_ARGUMENT = 111041; 119 | public static final int INVALID_ITERATOR = 111038; 120 | public static final int INVALID_SOCKET_DESCRIPTOR = 111048; 121 | public static final int INVALID_TIMER_INDEX = 111074; 122 | public static final int IP6_ERRCODE_BASE = 116000; 123 | public static final int IP6_INVALID_IN6ADDR = 116002; 124 | public static final int IP6_NOT_SUPPORT_SSL = 116003; 125 | public static final int MAP_DUPLICATE_KEY = 111036; 126 | public static final int MAP_KEY_NOT_FOUND = 111037; 127 | public static final int MAP_UNINIT = 111035; 128 | public static final int NET_BROKEN_PIPE = 111170; 129 | public static final int NET_CONNECTION_REFUSED = 111171; 130 | public static final int NET_CONNECT_SSL_ERR = 111169; 131 | public static final int NET_NORMAL_CLOSE = 111175; 132 | public static final int NET_OP_CANCEL = 111173; 133 | public static final int NET_REACTOR_ERRCODE_BASE = 111168; 134 | public static final int NET_SSL_GET_FD_ERROR = 111172; 135 | public static final int NET_UNKNOWN_ERROR = 111174; 136 | public static final int NOT_FULL_PATH_NAME = 9404; 137 | public static final int NOT_IMPLEMENT = 111057; 138 | public static final int NO_ENOUGH_BUFFER = 9301; 139 | public static final int NO_ERROR = 9000; 140 | public static final int ONE_PATH_LEVEL_NAME_TOO_LONG = 9126; 141 | public static final int OPEN_FILE_ERR = 111128; 142 | public static final int OPEN_OLD_FILE_FAIL = 111140; 143 | public static final int OUT_OF_FIXED_MEMORY = 111032; 144 | public static final int OUT_OF_MEMORY = 111026; 145 | public static final int P2P_PIPE_ERRCODE_BASE = 11300; 146 | public static final int PARAM_ERROR = 9112; 147 | public static final int PAUSE_TASK_WRITE_CFG_ERR = 117000; 148 | public static final int PAUSE_TASK_WRITE_DATA_TIMEOUT = 117001; 149 | public static final int PRIOR_TASK_FINISH = 9308; 150 | public static final int PRIOR_TASK_NO_INDEX = 9307; 151 | public static final int QUEUE_NO_ROOM = 111033; 152 | public static final int READ_FILE_ERR = 111126; 153 | public static final int REDIRECT_TOO_MUCH = 111181; 154 | public static final int RES_QUERY_E_BASE = 115000; 155 | public static final int SCHEMA_NOT_SUPPORT = 9113; 156 | public static final int SDK_NOT_INIT = 9102; 157 | public static final int SETTINGS_ERR_CFG_FILE_NOT_EXIST = 111162; 158 | public static final int SETTINGS_ERR_INVALID_FILE_NAME = 111161; 159 | public static final int SETTINGS_ERR_INVALID_ITEM_NAME = 111164; 160 | public static final int SETTINGS_ERR_INVALID_ITEM_VALUE = 111165; 161 | public static final int SETTINGS_ERR_INVALID_LINE = 111163; 162 | public static final int SETTINGS_ERR_ITEM_NOT_FOUND = 111167; 163 | public static final int SETTINGS_ERR_LIST_EMPTY = 111166; 164 | public static final int SETTINGS_ERR_UNKNOWN = 111160; 165 | public static final int TARGET_THREAD_STOPING = 111025; 166 | public static final int TASK_ALREADY_EXIST = 9103; 167 | public static final int TASK_ALREADY_RUNNING = 9106; 168 | public static final int TASK_ALREADY_STOPPED = 9105; 169 | public static final int TASK_CONTROL_STRATEGY = 9501; 170 | public static final int TASK_FAILURE_ALL_SUBTASK_FAILED = 114009; 171 | public static final int TASK_FAILURE_BTHUB_NO_RECORD = 114008; 172 | public static final int TASK_FAILURE_CANNOT_START_SUBTASK = 114003; 173 | public static final int TASK_FAILURE_EMULE_NO_RECORD = 114101; 174 | public static final int TASK_FAILURE_GET_TORRENT_FAILED = 114006; 175 | public static final int TASK_FAILURE_NO_DATA_PIPE = 111136; 176 | public static final int TASK_FAILURE_PARSE_TORRENT_FAILED = 114005; 177 | public static final int TASK_FAILURE_PART_SUBTASK_FAILED = 114011; 178 | public static final int TASK_FAILURE_QUERY_BT_HUB_FAILED = 114004; 179 | public static final int TASK_FAILURE_QUERY_EMULE_HUB_FAILED = 114001; 180 | public static final int TASK_FAILURE_SAVE_TORRENT_FAILED = 114007; 181 | public static final int TASK_FAILURE_SUBTASK_FAILED = 114002; 182 | public static final int TASK_FAILURE_THEONLY_SUBTASK_FAILED = 114010; 183 | public static final int TASK_FAIL_LONG_TIME_NO_RECV_DATA = 111176; 184 | public static final int TASK_FILE_NAME_EMPTY = 9401; 185 | public static final int TASK_FILE_NOT_VEDIO = 9402; 186 | public static final int TASK_FILE_SIZE_TOO_LARGE = 111177; 187 | public static final int TASK_FINISH = 9118; 188 | public static final int TASK_NOT_EXIST = 9104; 189 | public static final int TASK_NOT_IDLE = 9120; 190 | public static final int TASK_NOT_RUNNING = 9119; 191 | public static final int TASK_NOT_START = 9107; 192 | public static final int TASK_NO_FILE_NAME = 9129; 193 | public static final int TASK_NO_INDEX_NO_ORIGIN = 111148; 194 | public static final int TASK_ORIGIN_NONEXISTENCE = 111149; 195 | public static final int TASK_RETRY_ALWAY_FAIL = 111178; 196 | public static final int TASK_STILL_RUNNING = 9108; 197 | public static final int TASK_TYPE_NOT_SUPPORT = 9121; 198 | public static final int TASK_UNKNOWN_ERROR = 9403; 199 | public static final int TASK_USE_TOO_MUCH_MEM = 111031; 200 | public static final int THUNDER_URL_PARSE_ERROR = 9305; 201 | public static final int TOO_MUCH_TASK = 9111; 202 | public static final int TORRENT_IMCOMPLETE = 9304; 203 | public static final int TORRENT_PARSE_ERROR = 9302; 204 | public static final int URL_IS_TOO_LONG = 111047; 205 | public static final int URL_PARSER_ERROR = 111046; 206 | public static final int VIDEO_CACHE_FINISH = 9410; 207 | public static final int WRITE_FILE_ERR = 111127; 208 | } 209 | 210 | public enum XLManagerStatus { 211 | MANAGER_UNINIT, 212 | MANAGER_INIT_FAIL, 213 | MANAGER_RUNNING 214 | } 215 | 216 | public enum XLNetWorkCarrier { 217 | NWC_Unknow, 218 | NWC_CMCC, 219 | NWC_CU, 220 | NWC_CT 221 | } 222 | 223 | public static class XLOriginResState { 224 | public static final int ORIGIN_RES_CHECKING = 1; 225 | public static final int ORIGIN_RES_DEATH_LINK = 3; 226 | public static final int ORIGIN_RES_UNUSED = 0; 227 | public static final int ORIGIN_RES_VALID_LINK = 2; 228 | } 229 | 230 | public enum XLQueryIndexStatus { 231 | QIS_UNQUERY, 232 | QIS_QUERYING, 233 | QIS_QUERY_HAVE_INFO, 234 | QIS_QUERY_HAVENT_INFO 235 | } 236 | 237 | public enum XLResStrategy { 238 | RUS_PRIOR_USE 239 | } 240 | 241 | public static class XLTaskStatus { 242 | public static final int TASK_FAILED = 3; 243 | public static final int TASK_IDLE = 0; 244 | public static final int TASK_RUNNING = 1; 245 | public static final int TASK_STOPPED = 4; 246 | public static final int TASK_SUCCESS = 2; 247 | } 248 | 249 | public static class XLTaskType { 250 | public static final int P2SP_TASK_TYP = 1; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/XLProductInfo.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class XLProductInfo { 4 | public String mProductKey; 5 | public String mProductName; 6 | 7 | public XLProductInfo(String str, String str2) { 8 | this.mProductKey = str; 9 | this.mProductName = str2; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/XLSessionInfo.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class XLSessionInfo { 4 | public long mSendByte; 5 | public long mStartTime; 6 | } 7 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/XLTaskInfo.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | import android.os.Parcel; 4 | import android.os.Parcelable; 5 | import android.os.Parcelable.Creator; 6 | 7 | public class XLTaskInfo implements Parcelable { 8 | public static final Creator CREATOR = new Creator() { 9 | public final XLTaskInfo createFromParcel(Parcel parcel) { 10 | return new XLTaskInfo(parcel); 11 | } 12 | 13 | public final XLTaskInfo[] newArray(int i) { 14 | return new XLTaskInfo[i]; 15 | } 16 | }; 17 | public int mAddedHighSourceState; 18 | public int mAdditionalResCount; 19 | public long mAdditionalResDCDNBytes; 20 | public long mAdditionalResDCDNSpeed; 21 | public long mAdditionalResPeerBytes; 22 | public long mAdditionalResPeerSpeed; 23 | public int mAdditionalResType; 24 | public long mAdditionalResVipRecvBytes; 25 | public long mAdditionalResVipSpeed; 26 | public String mCid; 27 | public long mDownloadSize; 28 | public long mDownloadSpeed; 29 | public int mErrorCode; 30 | public String mFileName; 31 | public long mFileSize; 32 | public String mGcid; 33 | public int mInfoLen; 34 | public long mOriginRecvBytes; 35 | public long mOriginSpeed; 36 | public long mP2PRecvBytes; 37 | public long mP2PSpeed; 38 | public long mP2SRecvBytes; 39 | public long mP2SSpeed; 40 | public int mQueryIndexStatus; 41 | public long mTaskId; 42 | public int mTaskStatus; 43 | 44 | public int describeContents() { 45 | return 0; 46 | } 47 | 48 | public void writeToParcel(Parcel parcel, int i) { 49 | parcel.writeLong(this.mTaskId); 50 | parcel.writeString(this.mFileName); 51 | parcel.writeInt(this.mInfoLen); 52 | parcel.writeInt(this.mTaskStatus); 53 | parcel.writeInt(this.mErrorCode); 54 | parcel.writeLong(this.mFileSize); 55 | parcel.writeLong(this.mDownloadSize); 56 | parcel.writeLong(this.mDownloadSpeed); 57 | parcel.writeInt(this.mQueryIndexStatus); 58 | parcel.writeString(this.mCid); 59 | parcel.writeString(this.mGcid); 60 | parcel.writeLong(this.mOriginSpeed); 61 | parcel.writeLong(this.mOriginRecvBytes); 62 | parcel.writeLong(this.mP2SSpeed); 63 | parcel.writeLong(this.mP2SRecvBytes); 64 | parcel.writeLong(this.mP2PSpeed); 65 | parcel.writeLong(this.mP2PRecvBytes); 66 | parcel.writeInt(this.mAdditionalResCount); 67 | parcel.writeInt(this.mAdditionalResType); 68 | parcel.writeLong(this.mAdditionalResVipSpeed); 69 | parcel.writeLong(this.mAdditionalResVipRecvBytes); 70 | parcel.writeLong(this.mAdditionalResPeerSpeed); 71 | parcel.writeLong(this.mAdditionalResPeerBytes); 72 | } 73 | 74 | public XLTaskInfo() { 75 | } 76 | 77 | public XLTaskInfo(Parcel parcel) { 78 | this.mTaskId = parcel.readLong(); 79 | this.mFileName = parcel.readString(); 80 | this.mInfoLen = parcel.readInt(); 81 | this.mTaskStatus = parcel.readInt(); 82 | this.mErrorCode = parcel.readInt(); 83 | this.mFileSize = parcel.readLong(); 84 | this.mDownloadSize = parcel.readLong(); 85 | this.mDownloadSpeed = parcel.readLong(); 86 | this.mQueryIndexStatus = parcel.readInt(); 87 | this.mCid = parcel.readString(); 88 | this.mGcid = parcel.readString(); 89 | this.mOriginSpeed = parcel.readLong(); 90 | this.mOriginRecvBytes = parcel.readLong(); 91 | this.mP2SSpeed = parcel.readLong(); 92 | this.mP2SRecvBytes = parcel.readLong(); 93 | this.mP2PSpeed = parcel.readLong(); 94 | this.mP2PRecvBytes = parcel.readLong(); 95 | this.mAdditionalResCount = parcel.readInt(); 96 | this.mAdditionalResType = parcel.readInt(); 97 | this.mAdditionalResVipSpeed = parcel.readLong(); 98 | this.mAdditionalResVipRecvBytes = parcel.readLong(); 99 | this.mAdditionalResPeerSpeed = parcel.readLong(); 100 | this.mAdditionalResPeerBytes = parcel.readLong(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/XLTaskInfoEx.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class XLTaskInfoEx { 4 | public int mErrorCode; 5 | public int mInfoLen; 6 | public int mOriginResState; 7 | public int mP2pAbandonTotal; 8 | public int mP2pUsedTotal; 9 | public int mP2sAbandonTotal; 10 | public int mP2sUsedTotal; 11 | public long mTaskId; 12 | } 13 | -------------------------------------------------------------------------------- /thunder/src/main/java/com/xunlei/downloadlib/parameter/XLTaskLocalUrl.java: -------------------------------------------------------------------------------- 1 | package com.xunlei.downloadlib.parameter; 2 | 3 | public class XLTaskLocalUrl { 4 | public String mStrUrl; 5 | } 6 | -------------------------------------------------------------------------------- /thunder/src/main/jniLibs/armeabi/libxl_stat.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/thunder/src/main/jniLibs/armeabi/libxl_stat.so -------------------------------------------------------------------------------- /thunder/src/main/jniLibs/armeabi/libxl_thunder_sdk.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/thunder/src/main/jniLibs/armeabi/libxl_thunder_sdk.so -------------------------------------------------------------------------------- /thunder/src/main/jniLibs/armeabi/libxluagc.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redstorm82/MiniThunder/e26b8414750d6608493394adf19eeffd47262874/thunder/src/main/jniLibs/armeabi/libxluagc.so -------------------------------------------------------------------------------- /thunder/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | thunder 3 | 4 | --------------------------------------------------------------------------------