diff options
Diffstat (limited to 'sdkmanager/libs')
324 files changed, 0 insertions, 78043 deletions
diff --git a/sdkmanager/libs/Android.mk b/sdkmanager/libs/Android.mk deleted file mode 100644 index a934aa7..0000000 --- a/sdkmanager/libs/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -SDKLIBS_LOCAL_DIR := $(call my-dir) -include $(SDKLIBS_LOCAL_DIR)/sdklib/Android.mk -include $(SDKLIBS_LOCAL_DIR)/sdkuilib/Android.mk diff --git a/sdkmanager/libs/sdklib/.classpath b/sdkmanager/libs/sdklib/.classpath deleted file mode 100644 index 476a320..0000000 --- a/sdkmanager/libs/sdklib/.classpath +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry kind="src" path="src"/> - <classpathentry kind="src" path="tests/src"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> - <classpathentry combineaccessrules="false" kind="src" path="/common"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/commons-compress/commons-compress-1.0.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/commons-codec-1.4.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/commons-logging-1.1.1.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/httpclient-4.1.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/http-client/src/httpcomponents-client-4.1.1-src.zip"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/httpcore-4.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/http-client/src/httpcomponents-core-4.1-src.zip"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/httpmime-4.1.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/http-client/src/httpcomponents-client-4.1.1-src.zip"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/guava-tools/guava-13.0.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/guava-tools/src.zip"/> - <classpathentry combineaccessrules="false" kind="src" path="/dvlib"/> - <classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/> - <classpathentry kind="output" path="bin"/> -</classpath> diff --git a/sdkmanager/libs/sdklib/.project b/sdkmanager/libs/sdklib/.project deleted file mode 100644 index 97a8578..0000000 --- a/sdkmanager/libs/sdklib/.project +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>SdkLib</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.jdt.core.javabuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.jdt.core.javanature</nature> - </natures> -</projectDescription> diff --git a/sdkmanager/libs/sdklib/.settings/org.eclipse.core.resources.prefs b/sdkmanager/libs/sdklib/.settings/org.eclipse.core.resources.prefs deleted file mode 100755 index b6a93e0..0000000 --- a/sdkmanager/libs/sdklib/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,4 +0,0 @@ -#Mon Aug 29 11:46:20 PDT 2011
-eclipse.preferences.version=1
-encoding//tests/com/android/sdklib/testdata/addon_sample_1.xml=UTF-8
-encoding//tests/src/com/android/sdklib/io/MockFileOpTest.java=UTF-8
diff --git a/sdkmanager/libs/sdklib/.settings/org.eclipse.jdt.core.prefs b/sdkmanager/libs/sdklib/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index d11c211..0000000 --- a/sdkmanager/libs/sdklib/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,98 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled -org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=warning -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=error -org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning -org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning -org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 diff --git a/sdkmanager/libs/sdklib/.settings/org.eclipse.jdt.ui.prefs b/sdkmanager/libs/sdklib/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100755 index 4712267..0000000 --- a/sdkmanager/libs/sdklib/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,55 +0,0 @@ -#Tue Aug 07 12:32:32 PDT 2012 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=false -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=false -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=false -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=false -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=false -sp_cleanup.remove_trailing_whitespaces_ignore_empty=true -sp_cleanup.remove_unnecessary_casts=false -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/sdkmanager/libs/sdklib/Android.mk b/sdkmanager/libs/sdklib/Android.mk deleted file mode 100644 index 30c4e04..0000000 --- a/sdkmanager/libs/sdklib/Android.mk +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_JAVA_RESOURCE_DIRS := src - -LOCAL_JAR_MANIFEST := manifest.txt - -# IMPORTANT: if you add a new dependency here, please make sure -# to also check the following files: -# sdkmanager/sdklib/manifest.txt -# sdkmanager/app/etc/android.bat -LOCAL_JAVA_LIBRARIES := \ - common \ - commons-codec-1.4 \ - commons-compress-1.0 \ - commons-logging-1.1.1 \ - dvlib \ - guava-tools \ - httpclient-4.1.1 \ - httpcore-4.1 \ - httpmime-4.1.1 \ - mkidentity-prebuilt \ - layoutlib_api - -LOCAL_MODULE := sdklib - -include $(BUILD_HOST_JAVA_LIBRARY) - - -# Build all sub-directories -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/sdkmanager/libs/sdklib/NOTICE b/sdkmanager/libs/sdklib/NOTICE deleted file mode 100644 index c5b1efa..0000000 --- a/sdkmanager/libs/sdklib/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/sdkmanager/libs/sdklib/build.gradle b/sdkmanager/libs/sdklib/build.gradle deleted file mode 100644 index 3e200ae..0000000 --- a/sdkmanager/libs/sdklib/build.gradle +++ /dev/null @@ -1,36 +0,0 @@ -apply plugin: 'java' - -dependencies { - compile project(':layoutlib_api') - compile project(':device_validator:dvlib') - - compile 'org.apache.commons:commons-compress:1.0' - compile 'org.apache.httpcomponents:httpclient:4.1.1' - compile 'org.apache.httpcomponents:httpmime:4.1' - compile 'org.apache.commons:commons-compress:1.0' - - testCompile project(':device_validator:dvlib').sourceSets.test.output - testCompile 'junit:junit:3.8.1' -} - -group = 'com.android.tools' -archivesBaseName = 'sdklib' - -sourceSets { - main { - java { - srcDir 'src' - } - resources { - srcDir 'src' - } - } - test { - java { - srcDir 'tests/src' - } - resources { - srcDir 'tests/src' - } - } -} diff --git a/sdkmanager/libs/sdklib/manifest.txt b/sdkmanager/libs/sdklib/manifest.txt deleted file mode 100644 index 5d6cbd8..0000000 --- a/sdkmanager/libs/sdklib/manifest.txt +++ /dev/null @@ -1 +0,0 @@ -Class-Path: layoutlib_api.jar common.jar guava-tools.jar commons-compress-1.0.jar httpclient-4.1.1.jar httpcore-4.1.jar httpmime-4.1.1.jar commons-logging-1.1.1.jar commons-codec-1.4.jar dvlib.jar diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java deleted file mode 100644 index 12d4a49..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import com.android.SdkConstants; - -import java.io.File; -import java.io.FileFilter; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; - -/** - * Represents an add-on target in the SDK. - * An add-on extends a standard {@link PlatformTarget}. - */ -final class AddOnTarget implements IAndroidTarget { - /** - * String to compute hash for add-on targets. - * Format is vendor:name:apiVersion - * */ - private final static String ADD_ON_FORMAT = "%s:%s:%s"; //$NON-NLS-1$ - - private final static class OptionalLibrary implements IOptionalLibrary { - private final String mJarName; - private final String mJarPath; - private final String mName; - private final String mDescription; - - OptionalLibrary(String jarName, String jarPath, String name, String description) { - mJarName = jarName; - mJarPath = jarPath; - mName = name; - mDescription = description; - } - - @Override - public String getJarName() { - return mJarName; - } - - @Override - public String getJarPath() { - return mJarPath; - } - - @Override - public String getName() { - return mName; - } - - @Override - public String getDescription() { - return mDescription; - } - } - - private final String mLocation; - private final PlatformTarget mBasePlatform; - private final String mName; - private final ISystemImage[] mSystemImages; - private final String mVendor; - private final int mRevision; - private final String mDescription; - private final boolean mHasRenderingLibrary; - private final boolean mHasRenderingResources; - - private String[] mSkins; - private String mDefaultSkin; - private IOptionalLibrary[] mLibraries; - private int mVendorId = NO_USB_ID; - - /** - * Creates a new add-on - * @param location the OS path location of the add-on - * @param name the name of the add-on - * @param vendor the vendor name of the add-on - * @param revision the revision of the add-on - * @param description the add-on description - * @param systemImages list of supported system images. Can be null or empty. - * @param libMap A map containing the optional libraries. The map key is the fully-qualified - * library name. The value is a 2 string array with the .jar filename, and the description. - * @param hasRenderingLibrary whether the addon has a custom layoutlib.jar - * @param hasRenderingResources whether the add has custom framework resources. - * @param basePlatform the platform the add-on is extending. - */ - AddOnTarget( - String location, - String name, - String vendor, - int revision, - String description, - ISystemImage[] systemImages, - Map<String, String[]> libMap, - boolean hasRenderingLibrary, - boolean hasRenderingResources, - PlatformTarget basePlatform) { - if (location.endsWith(File.separator) == false) { - location = location + File.separator; - } - - mLocation = location; - mName = name; - mVendor = vendor; - mRevision = revision; - mDescription = description; - mHasRenderingLibrary = hasRenderingLibrary; - mHasRenderingResources = hasRenderingResources; - mBasePlatform = basePlatform; - - // If the add-on does not have any system-image of its own, the list here - // is empty and it's up to the callers to query the parent platform. - mSystemImages = systemImages == null ? new ISystemImage[0] : systemImages; - Arrays.sort(mSystemImages); - - // handle the optional libraries. - if (libMap != null) { - mLibraries = new IOptionalLibrary[libMap.size()]; - int index = 0; - for (Entry<String, String[]> entry : libMap.entrySet()) { - String jarFile = entry.getValue()[0]; - String desc = entry.getValue()[1]; - mLibraries[index++] = new OptionalLibrary(jarFile, - mLocation + SdkConstants.OS_ADDON_LIBS_FOLDER + jarFile, - entry.getKey(), desc); - } - } - } - - @Override - public String getLocation() { - return mLocation; - } - - @Override - public String getName() { - return mName; - } - - @Override - public ISystemImage getSystemImage(String abiType) { - for (ISystemImage sysImg : mSystemImages) { - if (sysImg.getAbiType().equals(abiType)) { - return sysImg; - } - } - return null; - } - - @Override - public ISystemImage[] getSystemImages() { - return mSystemImages; - } - - @Override - public String getVendor() { - return mVendor; - } - - @Override - public String getFullName() { - return String.format("%1$s (%2$s)", mName, mVendor); - } - - @Override - public String getClasspathName() { - return String.format("%1$s [%2$s]", mName, mBasePlatform.getClasspathName()); - } - - @Override - public String getShortClasspathName() { - return String.format("%1$s [%2$s]", mName, mBasePlatform.getVersionName()); - } - - @Override - public String getDescription() { - return mDescription; - } - - @Override - public AndroidVersion getVersion() { - // this is always defined by the base platform - return mBasePlatform.getVersion(); - } - - @Override - public String getVersionName() { - return mBasePlatform.getVersionName(); - } - - @Override - public int getRevision() { - return mRevision; - } - - @Override - public boolean isPlatform() { - return false; - } - - @Override - public IAndroidTarget getParent() { - return mBasePlatform; - } - - @Override - public String getPath(int pathId) { - switch (pathId) { - case SKINS: - return mLocation + SdkConstants.OS_SKINS_FOLDER; - case DOCS: - return mLocation + SdkConstants.FD_DOCS + File.separator - + SdkConstants.FD_DOCS_REFERENCE; - - case LAYOUT_LIB: - if (mHasRenderingLibrary) { - return mLocation + SdkConstants.FD_DATA + File.separator - + SdkConstants.FN_LAYOUTLIB_JAR; - } - return mBasePlatform.getPath(pathId); - - case RESOURCES: - if (mHasRenderingResources) { - return mLocation + SdkConstants.FD_DATA + File.separator - + SdkConstants.FD_RES; - } - return mBasePlatform.getPath(pathId); - - case FONTS: - if (mHasRenderingResources) { - return mLocation + SdkConstants.FD_DATA + File.separator - + SdkConstants.FD_FONTS; - } - return mBasePlatform.getPath(pathId); - - case SAMPLES: - // only return the add-on samples folder if there is actually a sample (or more) - File sampleLoc = new File(mLocation, SdkConstants.FD_SAMPLES); - if (sampleLoc.isDirectory()) { - File[] files = sampleLoc.listFiles(new FileFilter() { - @Override - public boolean accept(File pathname) { - return pathname.isDirectory(); - } - - }); - if (files != null && files.length > 0) { - return sampleLoc.getAbsolutePath(); - } - } - //$FALL-THROUGH$ - default : - return mBasePlatform.getPath(pathId); - } - } - - @Override - public boolean hasRenderingLibrary() { - return mHasRenderingLibrary || mHasRenderingResources; - } - - @Override - public String[] getSkins() { - return mSkins; - } - - @Override - public String getDefaultSkin() { - return mDefaultSkin; - } - - @Override - public IOptionalLibrary[] getOptionalLibraries() { - return mLibraries; - } - - /** - * Returns the list of libraries of the underlying platform. - * - * {@inheritDoc} - */ - @Override - public String[] getPlatformLibraries() { - return mBasePlatform.getPlatformLibraries(); - } - - @Override - public String getProperty(String name) { - return mBasePlatform.getProperty(name); - } - - @Override - public Integer getProperty(String name, Integer defaultValue) { - return mBasePlatform.getProperty(name, defaultValue); - } - - @Override - public Boolean getProperty(String name, Boolean defaultValue) { - return mBasePlatform.getProperty(name, defaultValue); - } - - @Override - public Map<String, String> getProperties() { - return mBasePlatform.getProperties(); - } - - @Override - public int getUsbVendorId() { - return mVendorId; - } - - @Override - public boolean canRunOn(IAndroidTarget target) { - // basic test - if (target == this) { - return true; - } - - /* - * The method javadoc indicates: - * Returns whether the given target is compatible with the receiver. - * <p/>A target is considered compatible if applications developed for the receiver can - * run on the given target. - */ - - // The receiver is an add-on. There are 2 big use cases: The add-on has libraries - // or the add-on doesn't (in which case we consider it a platform). - if (mLibraries == null || mLibraries.length == 0) { - return mBasePlatform.canRunOn(target); - } else { - // the only targets that can run the receiver are the same add-on in the same or later - // versions. - // first check: vendor/name - if (mVendor.equals(target.getVendor()) == false || - mName.equals(target.getName()) == false) { - return false; - } - - // now check the version. At this point since we checked the add-on part, - // we can revert to the basic check on version/codename which are done by the - // base platform already. - return mBasePlatform.canRunOn(target); - } - - } - - @Override - public String hashString() { - return String.format(ADD_ON_FORMAT, mVendor, mName, - mBasePlatform.getVersion().getApiString()); - } - - @Override - public int hashCode() { - return hashString().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof AddOnTarget) { - AddOnTarget addon = (AddOnTarget)obj; - - return mVendor.equals(addon.mVendor) && mName.equals(addon.mName) && - mBasePlatform.getVersion().equals(addon.mBasePlatform.getVersion()); - } - - return false; - } - - /* - * Order by API level (preview/n count as between n and n+1). - * At the same API level, order as: Platform first, then add-on ordered by vendor and then name - * (non-Javadoc) - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - @Override - public int compareTo(IAndroidTarget target) { - // quick check. - if (this == target) { - return 0; - } - - int versionDiff = getVersion().compareTo(target.getVersion()); - - // only if the version are the same do we care about platform/add-ons. - if (versionDiff == 0) { - // platforms go before add-ons. - if (target.isPlatform()) { - return +1; - } else { - AddOnTarget targetAddOn = (AddOnTarget)target; - - // both are add-ons of the same version. Compare per vendor then by name - int vendorDiff = mVendor.compareTo(targetAddOn.mVendor); - if (vendorDiff == 0) { - return mName.compareTo(targetAddOn.mName); - } else { - return vendorDiff; - } - } - - } - - return versionDiff; - } - - /** - * Returns a string representation suitable for debugging. - * The representation is not intended for display to the user. - * - * The representation is also purposely compact. It does not describe _all_ the properties - * of the target, only a few key ones. - * - * @see #getDescription() - */ - @Override - public String toString() { - return String.format("AddonTarget %1$s rev %2$d (based on %3$s)", //$NON-NLS-1$ - getVersion(), - getRevision(), - getParent().toString()); - } - - // ---- local methods. - - void setSkins(String[] skins, String defaultSkin) { - mDefaultSkin = defaultSkin; - - // we mix the add-on and base platform skins - HashSet<String> skinSet = new HashSet<String>(); - skinSet.addAll(Arrays.asList(skins)); - skinSet.addAll(Arrays.asList(mBasePlatform.getSkins())); - - mSkins = skinSet.toArray(new String[skinSet.size()]); - } - - /** - * Sets the USB vendor id in the add-on. - */ - void setUsbVendorId(int vendorId) { - if (vendorId == 0) { - throw new IllegalArgumentException( "VendorId must be > 0"); - } - - mVendorId = vendorId; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/AndroidVersion.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/AndroidVersion.java deleted file mode 100644 index 44ffa63..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/AndroidVersion.java +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import com.android.SdkConstants; -import com.android.annotations.Nullable; -import com.android.sdklib.repository.PkgProps; - -import java.util.Properties; - -/** - * Represents the version of a target or device. - * <p/> - * A version is defined by an API level and an optional code name. - * <ul><li>Release versions of the Android platform are identified by their API level (integer), - * (technically the code name for release version is "REL" but this class will return - * <code>null<code> instead.)</li> - * <li>Preview versions of the platform are identified by a code name. Their API level - * is usually set to the value of the previous platform.</li></ul> - * <p/> - * While this class contains both values, its goal is to abstract them, so that code comparing 2+ - * versions doesn't have to deal with the logic of handle both values. - * <p/> - * There are some cases where ones may want to access the values directly. This can be done - * with {@link #getApiLevel()} and {@link #getCodename()}. - * <p/> - * For generic UI display of the API version, {@link #getApiString()} is to be used. - */ -public final class AndroidVersion implements Comparable<AndroidVersion> { - - private final int mApiLevel; - private final String mCodename; - - /** - * Thrown when an {@link AndroidVersion} object could not be created. - * @see AndroidVersion#AndroidVersion(Properties) - */ - public final static class AndroidVersionException extends Exception { - private static final long serialVersionUID = 1L; - - AndroidVersionException(String message, Throwable cause) { - super(message, cause); - } - } - - /** - * Creates an {@link AndroidVersion} with the given api level and codename. - * Codename should be null for a release version, otherwise it's a preview codename. - */ - public AndroidVersion(int apiLevel, String codename) { - mApiLevel = apiLevel; - mCodename = sanitizeCodename(codename); - } - - /** - * Creates an {@link AndroidVersion} from {@link Properties}, with default values if the - * {@link Properties} object doesn't contain the expected values. - * <p/>The {@link Properties} is expected to have been filled with - * {@link #saveProperties(Properties)}. - */ - public AndroidVersion(Properties properties, int defaultApiLevel, String defaultCodeName) { - if (properties == null) { - mApiLevel = defaultApiLevel; - mCodename = sanitizeCodename(defaultCodeName); - } else { - mApiLevel = Integer.parseInt(properties.getProperty(PkgProps.VERSION_API_LEVEL, - Integer.toString(defaultApiLevel))); - mCodename = sanitizeCodename( - properties.getProperty(PkgProps.VERSION_CODENAME, defaultCodeName)); - } - } - - /** - * Creates an {@link AndroidVersion} from {@link Properties}. The properties must contain - * android version information, or an exception will be thrown. - * @throws AndroidVersionException if no Android version information have been found - * - * @see #saveProperties(Properties) - */ - public AndroidVersion(Properties properties) throws AndroidVersionException { - Exception error = null; - - String apiLevel = properties.getProperty(PkgProps.VERSION_API_LEVEL, null/*defaultValue*/); - if (apiLevel != null) { - try { - mApiLevel = Integer.parseInt(apiLevel); - mCodename = sanitizeCodename(properties.getProperty(PkgProps.VERSION_CODENAME, - null/*defaultValue*/)); - return; - } catch (NumberFormatException e) { - error = e; - } - } - - // reaching here means the Properties object did not contain the apiLevel which is required. - throw new AndroidVersionException(PkgProps.VERSION_API_LEVEL + " not found!", error); - } - - public void saveProperties(Properties props) { - props.setProperty(PkgProps.VERSION_API_LEVEL, Integer.toString(mApiLevel)); - if (mCodename != null) { - props.setProperty(PkgProps.VERSION_CODENAME, mCodename); - } - } - - /** - * Returns the api level as an integer. - * <p/>For target that are in preview mode, this can be superseded by - * {@link #getCodename()}. - * <p/>To display the API level in the UI, use {@link #getApiString()}, which will use the - * codename if applicable. - * @see #getCodename() - * @see #getApiString() - */ - public int getApiLevel() { - return mApiLevel; - } - - /** - * Returns the version code name if applicable, null otherwise. - * <p/>If the codename is non null, then the API level should be ignored, and this should be - * used as a unique identifier of the target instead. - */ - public String getCodename() { - return mCodename; - } - - /** - * Returns a string representing the API level and/or the code name. - */ - public String getApiString() { - if (mCodename != null) { - return mCodename; - } - - return Integer.toString(mApiLevel); - } - - /** - * Returns whether or not the version is a preview version. - */ - public boolean isPreview() { - return mCodename != null; - } - - /** - * Checks whether a device running a version similar to the receiver can run a project compiled - * for the given <var>version</var>. - * <p/> - * Be aware that this is not a perfect test, as other properties could break compatibility - * despite this method returning true. For a more comprehensive test, see - * {@link IAndroidTarget#canRunOn(IAndroidTarget)}. - * <p/> - * Nevertheless, when testing if an application can run on a device (where there is no - * access to the list of optional libraries), this method can give a good indication of whether - * there is a chance the application could run, or if there's a direct incompatibility. - */ - public boolean canRun(AndroidVersion appVersion) { - // if the application is compiled for a preview version, the device must be running exactly - // the same. - if (appVersion.mCodename != null) { - return appVersion.mCodename.equals(mCodename); - } - - // otherwise, we check the api level (note that a device running a preview version - // will have the api level of the previous platform). - return mApiLevel >= appVersion.mApiLevel; - } - - /** - * Returns <code>true</code> if the AndroidVersion is an API level equals to - * <var>apiLevel</var>. - */ - public boolean equals(int apiLevel) { - return mCodename == null && apiLevel == mApiLevel; - } - - /** - * Compares the receiver with either an {@link AndroidVersion} object or a {@link String} - * object. - * <p/>If <var>obj</var> is a {@link String}, then the method will first check if it's a string - * representation of a number, in which case it'll compare it to the api level. Otherwise, it'll - * compare it against the code name. - * <p/>For all other type of object give as parameter, this method will return - * <code>false</code>. - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof AndroidVersion) { - AndroidVersion version = (AndroidVersion)obj; - - if (mCodename == null) { - return version.mCodename == null && - mApiLevel == version.mApiLevel; - } else { - return mCodename.equals(version.mCodename) && - mApiLevel == version.mApiLevel; - } - - } else if (obj instanceof String) { - // if we have a code name, this must match. - if (mCodename != null) { - return mCodename.equals(obj); - } - - // else we try to convert to a int and compare to the api level - try { - int value = Integer.parseInt((String)obj); - return value == mApiLevel; - } catch (NumberFormatException e) { - // not a number? we'll return false below. - } - } - - return false; - } - - @Override - public int hashCode() { - if (mCodename != null) { - return mCodename.hashCode(); - } - - // there may be some collisions between the hashcode of the codename and the api level - // but it's acceptable. - return mApiLevel; - } - - /** - * Returns a string with the API Level and optional codename. - * Useful for debugging. - * For display purpose, please use {@link #getApiString()} instead. - */ - @Override - public String toString() { - String s = String.format("API %1$d", mApiLevel); //$NON-NLS-1$ - if (isPreview()) { - s += String.format(", %1$s preview", mCodename); //$NON-NLS-1$ - } - return s; - } - - /** - * Compares this object with the specified object for order. Returns a - * negative integer, zero, or a positive integer as this object is less - * than, equal to, or greater than the specified object. - * - * @param o the Object to be compared. - * @return a negative integer, zero, or a positive integer as this object is - * less than, equal to, or greater than the specified object. - */ - @Override - public int compareTo(AndroidVersion o) { - return compareTo(o.mApiLevel, o.mCodename); - } - - public int compareTo(int apiLevel, String codename) { - if (mCodename == null) { - if (codename == null) { - return mApiLevel - apiLevel; - } else { - if (mApiLevel == apiLevel) { - return -1; // same api level but argument is a preview for next version - } - - return mApiLevel - apiLevel; - } - } else { - // 'this' is a preview - if (mApiLevel == apiLevel) { - if (codename == null) { - return +1; - } else { - return mCodename.compareTo(codename); // strange case where the 2 previews - // have different codename? - } - } else { - return mApiLevel - apiLevel; - } - } - } - - /** - * Compares this version with the specified API and returns true if this version - * is greater or equal than the requested API -- that is the current version is a - * suitable min-api-level for the argument API. - */ - public boolean isGreaterOrEqualThan(int api) { - return compareTo(api, null /*codename*/) >= 0; - } - - /** - * Sanitizes the codename string according to the following rules: - * - A codename should be {@code null} for a release version or it should be a non-empty - * string for an actual preview. - * - In input, spacing is trimmed since it is irrelevant. - * - An empty string or the special codename "REL" means a release version - * and is converted to {@code null}. - * - * @param codename A possible-null codename. - * @return Null for a release version or a non-empty codename. - */ - private @Nullable String sanitizeCodename(@Nullable String codename) { - if (codename != null) { - codename = codename.trim(); - if (codename.length() == 0 || SdkConstants.CODENAME_RELEASE.equals(codename)) { - codename = null; - } - } - return codename; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java deleted file mode 100644 index 18577cf..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import java.util.Map; - - - -/** - * A version of Android that applications can target when building. - */ -public interface IAndroidTarget extends Comparable<IAndroidTarget> { - - /** - * Prefix used to build hash strings for platform targets - * @see SdkManager#getTargetFromHashString(String) - */ - public static final String PLATFORM_HASH_PREFIX = "android-"; - - /** OS Path to the "android.jar" file. */ - public final static int ANDROID_JAR = 1; - /** OS Path to the "framework.aidl" file. */ - public final static int ANDROID_AIDL = 2; - /** OS Path to the "samples" folder which contains sample projects. */ - public final static int SAMPLES = 4; - /** OS Path to the "skins" folder which contains the emulator skins. */ - public final static int SKINS = 5; - /** OS Path to the "templates" folder which contains the templates for new projects. */ - public final static int TEMPLATES = 6; - /** OS Path to the "data" folder which contains data & libraries for the SDK tools. */ - public final static int DATA = 7; - /** OS Path to the "attrs.xml" file. */ - public final static int ATTRIBUTES = 8; - /** OS Path to the "attrs_manifest.xml" file. */ - public final static int MANIFEST_ATTRIBUTES = 9; - /** OS Path to the "data/layoutlib.jar" library. */ - public final static int LAYOUT_LIB = 10; - /** OS Path to the "data/res" folder. */ - public final static int RESOURCES = 11; - /** OS Path to the "data/fonts" folder. */ - public final static int FONTS = 12; - /** OS Path to the "data/widgets.txt" file. */ - public final static int WIDGETS = 13; - /** OS Path to the "data/activity_actions.txt" file. */ - public final static int ACTIONS_ACTIVITY = 14; - /** OS Path to the "data/broadcast_actions.txt" file. */ - public final static int ACTIONS_BROADCAST = 15; - /** OS Path to the "data/service_actions.txt" file. */ - public final static int ACTIONS_SERVICE = 16; - /** OS Path to the "data/categories.txt" file. */ - public final static int CATEGORIES = 17; - /** OS Path to the "sources" folder. */ - public final static int SOURCES = 18; - /** OS Path to the target specific docs */ - public final static int DOCS = 19; - /** OS Path to the target's version of the aapt tool. - * This is deprecated as aapt is now in the platform tools and not in the platform. */ - @Deprecated - public final static int AAPT = 20; - /** OS Path to the target's version of the aidl tool. - * This is deprecated as aidl is now in the platform tools and not in the platform. */ - @Deprecated - public final static int AIDL = 21; - /** OS Path to the target's version of the dx too.<br> - * This is deprecated as dx is now in the platform tools and not in the platform. */ - @Deprecated - public final static int DX = 22; - /** OS Path to the target's version of the dx.jar file.<br> - * This is deprecated as dx.jar is now in the platform tools and not in the platform. */ - @Deprecated - public final static int DX_JAR = 23; - /** OS Path to the "ant" folder which contains the ant build rules (ver 2 and above) */ - public final static int ANT = 24; - /** OS Path to the Renderscript include folder. - * This is deprecated as this is now in the platform tools and not in the platform. */ - @Deprecated - public final static int ANDROID_RS = 25; - /** OS Path to the Renderscript(clang) include folder. - * This is deprecated as this is now in the platform tools and not in the platform. */ - @Deprecated - public final static int ANDROID_RS_CLANG = 26; - /** OS Path to the "uiautomator.jar" file. */ - public final static int UI_AUTOMATOR_JAR = 27; - - /** - * Return value for {@link #getUsbVendorId()} meaning no USB vendor IDs are defined by the - * Android target. - */ - public final static int NO_USB_ID = 0; - - /** An optional library provided by an Android Target */ - public interface IOptionalLibrary { - /** The name of the library, as used in the manifest (<uses-library>). */ - String getName(); - /** The file name of the jar file. */ - String getJarName(); - /** Absolute OS path to the jar file. */ - String getJarPath(); - /** Description of the library. */ - String getDescription(); - } - - /** - * Returns the target location. - */ - String getLocation(); - - /** - * Returns the name of the vendor of the target. - */ - String getVendor(); - - /** - * Returns the name of the target. - */ - String getName(); - - /** - * Returns the full name of the target, possibly including vendor name. - */ - String getFullName(); - - /** - * Returns the name to be displayed when representing all the libraries this target contains. - */ - String getClasspathName(); - - /** - * Returns the name to be displayed when representing all the libraries this target contains. - */ - String getShortClasspathName(); - - /** - * Returns the description of the target. - */ - String getDescription(); - - /** - * Returns the version of the target. This is guaranteed to be non-null. - */ - AndroidVersion getVersion(); - - /** - * Returns the platform version as a readable string. - */ - public String getVersionName(); - - /** Returns the revision number for the target. */ - int getRevision(); - - /** - * Returns true if the target is a standard Android platform. - */ - boolean isPlatform(); - - /** - * Returns the parent target. This is likely to only be non <code>null</code> if - * {@link #isPlatform()} returns <code>false</code> - */ - IAndroidTarget getParent(); - - /** - * Returns the path of a platform component. - * @param pathId the id representing the path to return. Any of the constants defined in the - * {@link IAndroidTarget} interface can be used. - */ - String getPath(int pathId); - - /** - * Returns whether the target is able to render layouts. - */ - boolean hasRenderingLibrary(); - - /** - * Returns the available skins for this target. - */ - String[] getSkins(); - - /** - * Returns the default skin for this target. - */ - String getDefaultSkin(); - - /** - * Returns the available optional libraries for this target. - * @return an array of optional libraries or <code>null</code> if there is none. - */ - IOptionalLibrary[] getOptionalLibraries(); - - /** - * Returns the list of libraries available for a given platform. - * - * @return an array of libraries provided by the platform or <code>null</code> if there is none. - */ - String[] getPlatformLibraries(); - - /** - * Return the value of a given property for this target. - * @return the property value or <code>null</code> if it was not found. - */ - String getProperty(String name); - - /** - * Returns the value of a given property for this target as an Integer value. - * <p/> If the value is missing or is not an integer, the method will return the given default - * value. - * @param name the name of the property to return - * @param defaultValue the default value to return. - * - * @see Integer#decode(String) - */ - Integer getProperty(String name, Integer defaultValue); - - /** - * Returns the value of a given property for this target as a Boolean value. - * <p/> If the value is missing or is not an boolean, the method will return the given default - * value. - * - * @param name the name of the property to return - * @param defaultValue the default value to return. - * - * @see Boolean#valueOf(String) - */ - - Boolean getProperty(String name, Boolean defaultValue); - - /** - * Returns all the properties associated with this target. This can be null if the target has - * no properties. - */ - Map<String, String> getProperties(); - - /** - * Returns the USB Vendor ID for the vendor of this target. - * <p/>If the target defines no USB Vendor ID, then the method return 0. - */ - int getUsbVendorId(); - - /** - * Returns an array of system images for this target. - * The array can be empty but not null. - */ - public ISystemImage[] getSystemImages(); - - /** - * Returns the system image information for the given {@code abiType}. - * - * @param abiType An ABI type string. - * @return An existing {@link ISystemImage} for the requested {@code abiType} - * or null if none exists for this type. - */ - public ISystemImage getSystemImage(String abiType); - - /** - * Returns whether the given target is compatible with the receiver. - * <p/> - * This means that a project using the receiver's target can run on the given target. - * <br/> - * Example: - * <pre> - * CupcakeTarget.canRunOn(DonutTarget) == true - * </pre>. - * - * @param target the IAndroidTarget to test. - */ - boolean canRunOn(IAndroidTarget target); - - /** - * Returns a string able to uniquely identify a target. - * Typically the target will encode information such as api level, whether it's a platform - * or add-on, and if it's an add-on vendor and add-on name. - */ - String hashString(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/ISystemImage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/ISystemImage.java deleted file mode 100755 index 7a69030..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/ISystemImage.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import com.android.SdkConstants; - -import java.io.File; - - -/** - * Describes a system image as used by an {@link IAndroidTarget}. - * A system image has an installation path, a location type and an ABI type. - */ -public interface ISystemImage extends Comparable<ISystemImage> { - - /** Indicates the type of location for the system image folder in the SDK. */ - public enum LocationType { - /** - * The system image is located in the legacy platform's {@link SdkConstants#FD_IMAGES} - * folder. - * <p/> - * Used by both platform and add-ons. - */ - IN_PLATFORM_LEGACY, - - /** - * The system image is located in a sub-directory of the platform's - * {@link SdkConstants#FD_IMAGES} folder, allowing for multiple system - * images within the platform. - * <p/> - * Used by both platform and add-ons. - */ - IN_PLATFORM_SUBFOLDER, - - /** - * The system image is located in the new SDK's {@link SdkConstants#FD_SYSTEM_IMAGES} - * folder. Supported as of Tools R14 and Repository XSD version 5. - * <p/> - * Used <em>only</em> by both platform. This is not supported for add-ons yet. - */ - IN_SYSTEM_IMAGE, - } - - /** Returns the actual location of an installed system image. */ - public abstract File getLocation(); - - /** Indicates the location strategy for this system image in the SDK. */ - public abstract LocationType getLocationType(); - - /** - * Returns the ABI type. For example, one of {@link SdkConstants#ABI_ARMEABI}, - * {@link SdkConstants#ABI_ARMEABI_V7A}, {@link SdkConstants#ABI_INTEL_ATOM} or - * {@link SdkConstants#ABI_MIPS}. - * Cannot be null nor empty. - */ - public abstract String getAbiType(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java deleted file mode 100644 index 7c2b4aa..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import com.android.SdkConstants; -import com.android.sdklib.SdkManager.LayoutlibVersion; -import com.android.sdklib.util.SparseArray; - -import java.io.File; -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; - -/** - * Represents a platform target in the SDK. - */ -final class PlatformTarget implements IAndroidTarget { - /** String used to get a hash to the platform target */ - private final static String PLATFORM_HASH = "android-%s"; - - private final static String PLATFORM_VENDOR = "Android Open Source Project"; - - private final static String PLATFORM_NAME = "Android %s"; - private final static String PLATFORM_NAME_PREVIEW = "Android %s (Preview)"; - - /** the OS path to the root folder of the platform component. */ - private final String mRootFolderOsPath; - private final String mName; - private final AndroidVersion mVersion; - private final String mVersionName; - private final int mRevision; - private final Map<String, String> mProperties; - private final SparseArray<String> mPaths = new SparseArray<String>(); - private String[] mSkins; - private final ISystemImage[] mSystemImages; - private final LayoutlibVersion mLayoutlibVersion; - - /** - * Creates a Platform target. - * - * @param sdkOsPath the root folder of the SDK - * @param platformOSPath the root folder of the platform component - * @param apiVersion the API Level + codename. - * @param versionName the version name of the platform. - * @param revision the revision of the platform component. - * @param layoutlibVersion The {@link LayoutlibVersion}. May be null. - * @param systemImages list of supported system images - * @param properties the platform properties - */ - @SuppressWarnings("deprecation") - PlatformTarget( - String sdkOsPath, - String platformOSPath, - AndroidVersion apiVersion, - String versionName, - int revision, - LayoutlibVersion layoutlibVersion, - ISystemImage[] systemImages, - Map<String, String> properties) { - if (platformOSPath.endsWith(File.separator) == false) { - platformOSPath = platformOSPath + File.separator; - } - mRootFolderOsPath = platformOSPath; - mProperties = Collections.unmodifiableMap(properties); - mVersion = apiVersion; - mVersionName = versionName; - mRevision = revision; - mLayoutlibVersion = layoutlibVersion; - mSystemImages = systemImages == null ? new ISystemImage[0] : systemImages; - Arrays.sort(mSystemImages); - - if (mVersion.isPreview()) { - mName = String.format(PLATFORM_NAME_PREVIEW, mVersionName); - } else { - mName = String.format(PLATFORM_NAME, mVersionName); - } - - // pre-build the path to the platform components - mPaths.put(ANDROID_JAR, mRootFolderOsPath + SdkConstants.FN_FRAMEWORK_LIBRARY); - mPaths.put(UI_AUTOMATOR_JAR, mRootFolderOsPath + SdkConstants.FN_UI_AUTOMATOR_LIBRARY); - mPaths.put(SOURCES, mRootFolderOsPath + SdkConstants.FD_ANDROID_SOURCES); - mPaths.put(ANDROID_AIDL, mRootFolderOsPath + SdkConstants.FN_FRAMEWORK_AIDL); - mPaths.put(SAMPLES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_SAMPLES_FOLDER); - mPaths.put(SKINS, mRootFolderOsPath + SdkConstants.OS_SKINS_FOLDER); - mPaths.put(TEMPLATES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_TEMPLATES_FOLDER); - mPaths.put(DATA, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER); - mPaths.put(ATTRIBUTES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_ATTRS_XML); - mPaths.put(MANIFEST_ATTRIBUTES, - mRootFolderOsPath + SdkConstants.OS_PLATFORM_ATTRS_MANIFEST_XML); - mPaths.put(RESOURCES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_RESOURCES_FOLDER); - mPaths.put(FONTS, mRootFolderOsPath + SdkConstants.OS_PLATFORM_FONTS_FOLDER); - mPaths.put(LAYOUT_LIB, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + - SdkConstants.FN_LAYOUTLIB_JAR); - mPaths.put(WIDGETS, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + - SdkConstants.FN_WIDGETS); - mPaths.put(ACTIONS_ACTIVITY, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + - SdkConstants.FN_INTENT_ACTIONS_ACTIVITY); - mPaths.put(ACTIONS_BROADCAST, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + - SdkConstants.FN_INTENT_ACTIONS_BROADCAST); - mPaths.put(ACTIONS_SERVICE, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + - SdkConstants.FN_INTENT_ACTIONS_SERVICE); - mPaths.put(CATEGORIES, mRootFolderOsPath + SdkConstants.OS_PLATFORM_DATA_FOLDER + - SdkConstants.FN_INTENT_CATEGORIES); - mPaths.put(ANT, mRootFolderOsPath + SdkConstants.OS_PLATFORM_ANT_FOLDER); - - // location for aapt, aidl, dx is now in the platform-tools folder. - mPaths.put(AAPT, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + - SdkConstants.FN_AAPT); - mPaths.put(AIDL, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + - SdkConstants.FN_AIDL); - mPaths.put(DX, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + - SdkConstants.FN_DX); - mPaths.put(DX_JAR, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_LIB_FOLDER + - SdkConstants.FN_DX_JAR); - mPaths.put(ANDROID_RS, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + - SdkConstants.OS_FRAMEWORK_RS); - mPaths.put(ANDROID_RS_CLANG, sdkOsPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER + - SdkConstants.OS_FRAMEWORK_RS_CLANG); - } - - /** - * Returns the {@link LayoutlibVersion}. May be null. - */ - public LayoutlibVersion getLayoutlibVersion() { - return mLayoutlibVersion; - } - - @Override - public ISystemImage getSystemImage(String abiType) { - for (ISystemImage sysImg : mSystemImages) { - if (sysImg.getAbiType().equals(abiType)) { - return sysImg; - } - } - return null; - } - - @Override - public ISystemImage[] getSystemImages() { - return mSystemImages; - } - - @Override - public String getLocation() { - return mRootFolderOsPath; - } - - /** - * {@inheritDoc} - * <p/> - * For Platform, the vendor name is always "Android". - * - * @see com.android.sdklib.IAndroidTarget#getVendor() - */ - @Override - public String getVendor() { - return PLATFORM_VENDOR; - } - - @Override - public String getName() { - return mName; - } - - @Override - public String getFullName() { - return mName; - } - - @Override - public String getClasspathName() { - return mName; - } - - @Override - public String getShortClasspathName() { - return mName; - } - - /* - * (non-Javadoc) - * - * Description for the Android platform is dynamically generated. - * - * @see com.android.sdklib.IAndroidTarget#getDescription() - */ - @Override - public String getDescription() { - return String.format("Standard Android platform %s", mVersionName); - } - - @Override - public AndroidVersion getVersion() { - return mVersion; - } - - @Override - public String getVersionName() { - return mVersionName; - } - - @Override - public int getRevision() { - return mRevision; - } - - @Override - public boolean isPlatform() { - return true; - } - - @Override - public IAndroidTarget getParent() { - return null; - } - - @Override - public String getPath(int pathId) { - return mPaths.get(pathId); - } - - /** - * Returns whether the target is able to render layouts. This is always true for platforms. - */ - @Override - public boolean hasRenderingLibrary() { - return true; - } - - - @Override - public String[] getSkins() { - return mSkins; - } - - @Override - public String getDefaultSkin() { - // only one skin? easy. - if (mSkins.length == 1) { - return mSkins[0]; - } - - // look for the skin name in the platform props - String skinName = mProperties.get(SdkConstants.PROP_SDK_DEFAULT_SKIN); - if (skinName != null) { - return skinName; - } - - // otherwise try to find a good default. - if (mVersion.getApiLevel() >= 4) { - // at this time, this is the default skin for all older platforms that had 2+ skins. - return "WVGA800"; - } - - return "HVGA"; // this is for 1.5 and earlier. - } - - /** - * Always returns null, as a standard platform ha no optional libraries. - * - * {@inheritDoc} - * @see com.android.sdklib.IAndroidTarget#getOptionalLibraries() - */ - @Override - public IOptionalLibrary[] getOptionalLibraries() { - return null; - } - - /** - * Currently always return a fixed list with "android.test.runner" in it. - * <p/> - * TODO change the fixed library list to be build-dependent later. - * {@inheritDoc} - */ - @Override - public String[] getPlatformLibraries() { - return new String[] { SdkConstants.ANDROID_TEST_RUNNER_LIB }; - } - - /** - * The platform has no USB Vendor Id: always return {@link IAndroidTarget#NO_USB_ID}. - * {@inheritDoc} - */ - @Override - public int getUsbVendorId() { - return NO_USB_ID; - } - - @Override - public boolean canRunOn(IAndroidTarget target) { - // basic test - if (target == this) { - return true; - } - - // if the platform has a codename (ie it's a preview of an upcoming platform), then - // both platforms must be exactly identical. - if (mVersion.getCodename() != null) { - return mVersion.equals(target.getVersion()); - } - - // target is compatible wit the receiver as long as its api version number is greater or - // equal. - return target.getVersion().getApiLevel() >= mVersion.getApiLevel(); - } - - @Override - public String hashString() { - return String.format(PLATFORM_HASH, mVersion.getApiString()); - } - - @Override - public int hashCode() { - return hashString().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PlatformTarget) { - PlatformTarget platform = (PlatformTarget)obj; - - return mVersion.equals(platform.getVersion()); - } - - return false; - } - - /* - * Order by API level (preview/n count as between n and n+1). - * At the same API level, order as: Platform first, then add-on ordered by vendor and then name - * (non-Javadoc) - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - @Override - public int compareTo(IAndroidTarget target) { - // quick check. - if (this == target) { - return 0; - } - - int versionDiff = mVersion.compareTo(target.getVersion()); - - // only if the version are the same do we care about add-ons. - if (versionDiff == 0) { - // platforms go before add-ons. - if (target.isPlatform() == false) { - return -1; - } - } - - return versionDiff; - } - - /** - * Returns a string representation suitable for debugging. - * The representation is not intended for display to the user. - * - * The representation is also purposely compact. It does not describe _all_ the properties - * of the target, only a few key ones. - * - * @see #getDescription() - */ - @Override - public String toString() { - return String.format("PlatformTarget %1$s rev %2$d", //$NON-NLS-1$ - getVersion(), - getRevision()); - } - - @Override - public String getProperty(String name) { - return mProperties.get(name); - } - - @Override - public Integer getProperty(String name, Integer defaultValue) { - try { - String value = getProperty(name); - if (value != null) { - return Integer.decode(value); - } - } catch (NumberFormatException e) { - // ignore, return default value; - } - - return defaultValue; - } - - @Override - public Boolean getProperty(String name, Boolean defaultValue) { - String value = getProperty(name); - if (value != null) { - return Boolean.valueOf(value); - } - - return defaultValue; - } - - @Override - public Map<String, String> getProperties() { - return mProperties; // mProperties is unmodifiable. - } - - // ---- platform only methods. - - void setSkins(String[] skins) { - mSkins = skins; - } - - void setSamplesPath(String osLocation) { - mPaths.put(SAMPLES, osLocation); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java deleted file mode 100644 index 0bca185..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java +++ /dev/null @@ -1,1368 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.io.FileWrapper; -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.AndroidVersion.AndroidVersionException; -import com.android.sdklib.ISystemImage.LocationType; -import com.android.sdklib.internal.project.ProjectProperties; -import com.android.sdklib.internal.repository.LocalSdkParser; -import com.android.sdklib.internal.repository.NullTaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.repository.PkgProps; -import com.android.utils.ILogger; -import com.android.utils.NullLogger; -import com.android.utils.Pair; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.TreeMap; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.Adler32; - -/** - * The SDK manager parses the SDK folder and gives access to the content. - * @see PlatformTarget - * @see AddOnTarget - */ -public class SdkManager { - - private static final boolean DEBUG = System.getenv("SDKMAN_DEBUG") != null; //$NON-NLS-1$ - - public final static String PROP_VERSION_SDK = "ro.build.version.sdk"; //$NON-NLS-1$ - public final static String PROP_VERSION_CODENAME = "ro.build.version.codename"; //$NON-NLS-1$ - public final static String PROP_VERSION_RELEASE = "ro.build.version.release"; //$NON-NLS-1$ - - public final static String ADDON_NAME = "name"; //$NON-NLS-1$ - public final static String ADDON_VENDOR = "vendor"; //$NON-NLS-1$ - public final static String ADDON_API = "api"; //$NON-NLS-1$ - public final static String ADDON_DESCRIPTION = "description"; //$NON-NLS-1$ - public final static String ADDON_LIBRARIES = "libraries"; //$NON-NLS-1$ - public final static String ADDON_DEFAULT_SKIN = "skin"; //$NON-NLS-1$ - public final static String ADDON_USB_VENDOR = "usb-vendor"; //$NON-NLS-1$ - public final static String ADDON_REVISION = "revision"; //$NON-NLS-1$ - public final static String ADDON_REVISION_OLD = "version"; //$NON-NLS-1$ - - - private final static Pattern PATTERN_LIB_DATA = Pattern.compile( - "^([a-zA-Z0-9._-]+\\.jar);(.*)$", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ - - // usb ids are 16-bit hexadecimal values. - private final static Pattern PATTERN_USB_IDS = Pattern.compile( - "^0x[a-f0-9]{4}$", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ - - /** List of items in the platform to check when parsing it. These paths are relative to the - * platform root folder. */ - private final static String[] sPlatformContentList = new String[] { - SdkConstants.FN_FRAMEWORK_LIBRARY, - SdkConstants.FN_FRAMEWORK_AIDL, - }; - - /** Preference file containing the usb ids for adb */ - private final static String ADB_INI_FILE = "adb_usb.ini"; //$NON-NLS-1$ - //0--------90--------90--------90--------90--------90--------90--------90--------9 - private final static String ADB_INI_HEADER = - "# ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT.\n" + //$NON-NLS-1$ - "# USE 'android update adb' TO GENERATE.\n" + //$NON-NLS-1$ - "# 1 USB VENDOR ID PER LINE.\n"; //$NON-NLS-1$ - - /** The location of the SDK as an OS path */ - private final String mOsSdkPath; - /** Valid targets that have been loaded. Can be empty but not null. */ - private IAndroidTarget[] mTargets = new IAndroidTarget[0]; - /** A map to keep information on directories to see if they change later. */ - private final Map<File, DirInfo> mTargetDirs = new HashMap<File, SdkManager.DirInfo>(); - - /** - * Create a new {@link SdkManager} instance. - * External users should use {@link #createManager(String, ILogger)}. - * - * @param osSdkPath the location of the SDK. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected SdkManager(String osSdkPath) { - mOsSdkPath = osSdkPath; - } - - /** - * Creates an {@link SdkManager} for a given sdk location. - * @param osSdkPath the location of the SDK. - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - * @return the created {@link SdkManager} or null if the location is not valid. - */ - public static SdkManager createManager(String osSdkPath, ILogger log) { - try { - SdkManager manager = new SdkManager(osSdkPath); - manager.reloadSdk(log); - - return manager; - } catch (IllegalArgumentException e) { - log.error(e, "Error parsing the sdk."); - } - - return null; - } - - /** - * Reloads the content of the SDK. - * - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - */ - public void reloadSdk(ILogger log) { - // get the current target list. - mTargetDirs.clear(); - ArrayList<IAndroidTarget> targets = new ArrayList<IAndroidTarget>(); - loadPlatforms(mOsSdkPath, targets, mTargetDirs, log); - loadAddOns(mOsSdkPath, targets, mTargetDirs, log); - - // For now replace the old list with the new one. - // In the future we may want to keep the current objects, so that ADT doesn't have to deal - // with new IAndroidTarget objects when a target didn't actually change. - - // sort the targets/add-ons - Collections.sort(targets); - setTargets(targets.toArray(new IAndroidTarget[targets.size()])); - - // load the samples, after the targets have been set. - initializeSamplePaths(log); - } - - /** - * Checks whether any of the SDK platforms/add-ons have changed on-disk - * since we last loaded the SDK. This does not reload the SDK nor does it - * change the underlying targets. - * - * @return True if at least one directory or source.prop has changed. - */ - public boolean hasChanged() { - Set<File> visited = new HashSet<File>(); - boolean changed = false; - - File platformFolder = new File(mOsSdkPath, SdkConstants.FD_PLATFORMS); - if (platformFolder.isDirectory()) { - File[] platforms = platformFolder.listFiles(); - if (platforms != null) { - for (File platform : platforms) { - if (!platform.isDirectory()) { - continue; - } - visited.add(platform); - DirInfo dirInfo = mTargetDirs.get(platform); - if (dirInfo == null) { - // This is a new platform directory. - changed = true; - } else { - changed = dirInfo.hasChanged(); - } - if (changed) { - if (DEBUG) { - System.out.println("SDK changed due to " + //$NON-NLS-1$ - (dirInfo != null ? dirInfo.toString() : platform.getPath())); - } - } - } - } - } - - File addonFolder = new File(mOsSdkPath, SdkConstants.FD_ADDONS); - - if (!changed && addonFolder.isDirectory()) { - File[] addons = addonFolder.listFiles(); - if (addons != null) { - for (File addon : addons) { - if (!addon.isDirectory()) { - continue; - } - visited.add(addon); - DirInfo dirInfo = mTargetDirs.get(addon); - if (dirInfo == null) { - // This is a new add-on directory. - changed = true; - } else { - changed = dirInfo.hasChanged(); - } - if (changed) { - if (DEBUG) { - System.out.println("SDK changed due to " + //$NON-NLS-1$ - (dirInfo != null ? dirInfo.toString() : addon.getPath())); - } - } - } - } - } - - if (!changed) { - // Check whether some pre-existing target directories have vanished. - for (File previousDir : mTargetDirs.keySet()) { - if (!visited.contains(previousDir)) { - // This directory is no longer present. - changed = true; - if (DEBUG) { - System.out.println("SDK changed: " + //$NON-NLS-1$ - previousDir.getPath() + " removed"); //$NON-NLS-1$ - } - break; - } - } - } - - return changed; - } - - /** - * Returns the location of the SDK. - */ - public String getLocation() { - return mOsSdkPath; - } - - /** - * Returns the targets that are available in the SDK. - * <p/> - * The array can be empty but not null. - */ - public IAndroidTarget[] getTargets() { - return mTargets; - } - - /** - * Sets the targets that are available in the SDK. - * <p/> - * The array can be empty but not null. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected void setTargets(IAndroidTarget[] targets) { - assert targets != null; - mTargets = targets; - } - - /** - * Returns a target from a hash that was generated by {@link IAndroidTarget#hashString()}. - * - * @param hash the {@link IAndroidTarget} hash string. - * @return The matching {@link IAndroidTarget} or null. - */ - public IAndroidTarget getTargetFromHashString(String hash) { - if (hash != null) { - for (IAndroidTarget target : mTargets) { - if (hash.equals(target.hashString())) { - return target; - } - } - } - - return null; - } - - /** - * Updates adb with the USB devices declared in the SDK add-ons. - * @throws AndroidLocationException - * @throws IOException - */ - public void updateAdb() throws AndroidLocationException, IOException { - FileWriter writer = null; - try { - // get the android prefs location to know where to write the file. - File adbIni = new File(AndroidLocation.getFolder(), ADB_INI_FILE); - writer = new FileWriter(adbIni); - - // first, put all the vendor id in an HashSet to remove duplicate. - HashSet<Integer> set = new HashSet<Integer>(); - IAndroidTarget[] targets = getTargets(); - for (IAndroidTarget target : targets) { - if (target.getUsbVendorId() != IAndroidTarget.NO_USB_ID) { - set.add(target.getUsbVendorId()); - } - } - - // write file header. - writer.write(ADB_INI_HEADER); - - // now write the Id in a text file, one per line. - for (Integer i : set) { - writer.write(String.format("0x%04x\n", i)); //$NON-NLS-1$ - } - } finally { - if (writer != null) { - writer.close(); - } - } - } - - /** - * Returns the greatest {@link LayoutlibVersion} found amongst all platform - * targets currently loaded in the SDK. - * <p/> - * We only started recording Layoutlib Versions recently in the platform meta data - * so it's possible to have an SDK with many platforms loaded but no layoutlib - * version defined. - * - * @return The greatest {@link LayoutlibVersion} or null if none is found. - * @deprecated This does NOT solve the right problem and will be changed later. - */ - @Deprecated - public LayoutlibVersion getMaxLayoutlibVersion() { - LayoutlibVersion maxVersion = null; - - for (IAndroidTarget target : getTargets()) { - if (target instanceof PlatformTarget) { - LayoutlibVersion lv = ((PlatformTarget) target).getLayoutlibVersion(); - if (lv != null) { - if (maxVersion == null || lv.compareTo(maxVersion) > 0) { - maxVersion = lv; - } - } - } - } - - return maxVersion; - } - - /** - * Returns a map of the <em>root samples directories</em> located in the SDK/extras packages. - * No guarantee is made that the extras' samples directory actually contain any valid samples. - * The only guarantee is that the root samples directory actually exists. - * The map is { File: Samples root directory => String: Extra package display name. } - * - * @return A non-null possibly empty map of extra samples directories and their associated - * extra package display name. - */ - public @NonNull Map<File, String> getExtraSamples() { - LocalSdkParser parser = new LocalSdkParser(); - Package[] packages = parser.parseSdk(mOsSdkPath, - this, - LocalSdkParser.PARSE_EXTRAS, - new NullTaskMonitor(NullLogger.getLogger())); - - Map<File, String> samples = new HashMap<File, String>(); - - for (Package pkg : packages) { - if (pkg instanceof ExtraPackage && pkg.isLocal()) { - // isLocal()==true implies there's a single locally-installed archive. - assert pkg.getArchives() != null && pkg.getArchives().length == 1; - Archive a = pkg.getArchives()[0]; - assert a != null; - File path = new File(a.getLocalOsPath(), SdkConstants.FD_SAMPLES); - if (path.isDirectory()) { - samples.put(path, pkg.getListDescription()); - continue; - } - // Some old-style extras simply have a single "sample" directory. - // Accept it if it contains an AndroidManifest.xml. - path = new File(a.getLocalOsPath(), SdkConstants.FD_SAMPLE); - if (path.isDirectory() && - new File(path, SdkConstants.FN_ANDROID_MANIFEST_XML).isFile()) { - samples.put(path, pkg.getListDescription()); - } - } - } - - return samples; - } - - /** - * Returns a map of all the extras found in the <em>local</em> SDK with their major revision. - * <p/> - * Map keys are in the form "vendor-id/path-id". These ids uniquely identify an extra package. - * The version is the incremental integer major revision of the package. - * - * @return A non-null possibly empty map of { string "vendor/path" => integer major revision } - */ - public @NonNull Map<String, Integer> getExtrasVersions() { - LocalSdkParser parser = new LocalSdkParser(); - Package[] packages = parser.parseSdk(mOsSdkPath, - this, - LocalSdkParser.PARSE_EXTRAS, - new NullTaskMonitor(NullLogger.getLogger())); - - Map<String, Integer> extraVersions = new TreeMap<String, Integer>(); - - for (Package pkg : packages) { - if (pkg instanceof ExtraPackage && pkg.isLocal()) { - ExtraPackage ep = (ExtraPackage) pkg; - String vendor = ep.getVendorId(); - String path = ep.getPath(); - int majorRev = ep.getRevision().getMajor(); - - extraVersions.put(vendor + '/' + path, majorRev); - } - } - - return extraVersions; - } - - /** Returns the platform tools version if installed, null otherwise. */ - public @Nullable String getPlatformToolsVersion() { - LocalSdkParser parser = new LocalSdkParser(); - Package[] packages = parser.parseSdk(mOsSdkPath, this, LocalSdkParser.PARSE_PLATFORM_TOOLS, - new NullTaskMonitor(NullLogger.getLogger())); - - for (Package pkg : packages) { - if (pkg instanceof PlatformToolPackage && pkg.isLocal()) { - return pkg.getRevision().toShortString(); - } - } - - return null; - } - - - // -------- private methods ---------- - - /** - * Loads the Platforms from the SDK. - * Creates the "platforms" folder if necessary. - * - * @param sdkOsPath Location of the SDK - * @param targets the list to fill with the platforms. - * @param dirInfos a map to keep information on directories to see if they change later. - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - * @throws RuntimeException when the "platforms" folder is missing and cannot be created. - */ - private static void loadPlatforms( - String sdkOsPath, - ArrayList<IAndroidTarget> targets, - Map<File, DirInfo> dirInfos, ILogger log) { - File platformFolder = new File(sdkOsPath, SdkConstants.FD_PLATFORMS); - - if (platformFolder.isDirectory()) { - File[] platforms = platformFolder.listFiles(); - - for (File platform : platforms) { - PlatformTarget target = null; - if (platform.isDirectory()) { - target = loadPlatform(sdkOsPath, platform, log); - if (target != null) { - targets.add(target); - } - // Remember we visited this file/directory, - // even if we failed to load anything from it. - dirInfos.put(platform, new DirInfo(platform)); - } else { - log.warning("Ignoring platform '%1$s', not a folder.", platform.getName()); - } - } - - return; - } - - // Try to create it or complain if something else is in the way. - if (!platformFolder.exists()) { - if (!platformFolder.mkdir()) { - throw new RuntimeException( - String.format("Failed to create %1$s.", - platformFolder.getAbsolutePath())); - } - } else { - throw new RuntimeException( - String.format("%1$s is not a folder.", - platformFolder.getAbsolutePath())); - } - } - - /** - * Loads a specific Platform at a given location. - * @param sdkOsPath Location of the SDK - * @param platformFolder the root folder of the platform. - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - */ - private static PlatformTarget loadPlatform( - String sdkOsPath, - File platformFolder, - ILogger log) { - FileWrapper buildProp = new FileWrapper(platformFolder, SdkConstants.FN_BUILD_PROP); - FileWrapper sourcePropFile = new FileWrapper(platformFolder, SdkConstants.FN_SOURCE_PROP); - - if (buildProp.isFile() && sourcePropFile.isFile()) { - Map<String, String> platformProp = new HashMap<String, String>(); - - // add all the property files - Map<String, String> map = ProjectProperties.parsePropertyFile(buildProp, log); - if (map != null) { - platformProp.putAll(map); - } - - map = ProjectProperties.parsePropertyFile(sourcePropFile, log); - if (map != null) { - platformProp.putAll(map); - } - - FileWrapper sdkPropFile = new FileWrapper(platformFolder, SdkConstants.FN_SDK_PROP); - if (sdkPropFile.isFile()) { // obsolete platforms don't have this. - map = ProjectProperties.parsePropertyFile(sdkPropFile, log); - if (map != null) { - platformProp.putAll(map); - } - } - - // look for some specific values in the map. - - // api level - int apiNumber; - String stringValue = platformProp.get(PROP_VERSION_SDK); - if (stringValue == null) { - log.warning( - "Ignoring platform '%1$s': %2$s is missing from '%3$s'", - platformFolder.getName(), PROP_VERSION_SDK, - SdkConstants.FN_BUILD_PROP); - return null; - } else { - try { - apiNumber = Integer.parseInt(stringValue); - } catch (NumberFormatException e) { - // looks like apiNumber does not parse to a number. - // Ignore this platform. - log.warning( - "Ignoring platform '%1$s': %2$s is not a valid number in %3$s.", - platformFolder.getName(), PROP_VERSION_SDK, - SdkConstants.FN_BUILD_PROP); - return null; - } - } - - // Codename must be either null or a platform codename. - // REL means it's a release version and therefore the codename should be null. - AndroidVersion apiVersion = - new AndroidVersion(apiNumber, platformProp.get(PROP_VERSION_CODENAME)); - - // version string - String apiName = platformProp.get(PkgProps.PLATFORM_VERSION); - if (apiName == null) { - apiName = platformProp.get(PROP_VERSION_RELEASE); - } - if (apiName == null) { - log.warning( - "Ignoring platform '%1$s': %2$s is missing from '%3$s'", - platformFolder.getName(), PROP_VERSION_RELEASE, - SdkConstants.FN_BUILD_PROP); - return null; - } - - // platform rev number & layoutlib version are extracted from the source.properties - // saved by the SDK Manager when installing the package. - - int revision = 1; - LayoutlibVersion layoutlibVersion = null; - try { - revision = Integer.parseInt(platformProp.get(PkgProps.PKG_REVISION)); - } catch (NumberFormatException e) { - // do nothing, we'll keep the default value of 1. - } - - try { - String propApi = platformProp.get(PkgProps.LAYOUTLIB_API); - String propRev = platformProp.get(PkgProps.LAYOUTLIB_REV); - int llApi = propApi == null ? LayoutlibVersion.NOT_SPECIFIED : - Integer.parseInt(propApi); - int llRev = propRev == null ? LayoutlibVersion.NOT_SPECIFIED : - Integer.parseInt(propRev); - if (llApi > LayoutlibVersion.NOT_SPECIFIED && - llRev >= LayoutlibVersion.NOT_SPECIFIED) { - layoutlibVersion = new LayoutlibVersion(llApi, llRev); - } - } catch (NumberFormatException e) { - // do nothing, we'll ignore the layoutlib version if it's invalid - } - - // api number and name look valid, perform a few more checks - if (checkPlatformContent(platformFolder, log) == false) { - return null; - } - - ISystemImage[] systemImages = - getPlatformSystemImages(sdkOsPath, platformFolder, apiVersion); - - // create the target. - PlatformTarget target = new PlatformTarget( - sdkOsPath, - platformFolder.getAbsolutePath(), - apiVersion, - apiName, - revision, - layoutlibVersion, - systemImages, - platformProp); - - // need to parse the skins. - String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS)); - target.setSkins(skins); - - return target; - } else { - log.warning("Ignoring platform '%1$s': %2$s is missing.", //$NON-NLS-1$ - platformFolder.getName(), - SdkConstants.FN_BUILD_PROP); - } - - return null; - } - - /** - * Get all the system images supported by an add-on target. - * For an add-on, we first look for sub-folders in the addon/images directory. - * If none are found but the directory exists and is not empty, assume it's a legacy - * arm eabi system image. - * <p/> - * Note that it's OK for an add-on to have no system-images at all, since it can always - * rely on the ones from its base platform. - * - * @param root Root of the add-on target being loaded. - * @return an array of ISystemImage containing all the system images for the target. - * The list can be empty. - */ - private static ISystemImage[] getAddonSystemImages(File root) { - Set<ISystemImage> found = new TreeSet<ISystemImage>(); - - root = new File(root, SdkConstants.OS_IMAGES_FOLDER); - File[] files = root.listFiles(); - boolean hasImgFiles = false; - - if (files != null) { - // Look for sub-directories - for (File file : files) { - if (file.isDirectory()) { - found.add(new SystemImage( - file, - LocationType.IN_PLATFORM_SUBFOLDER, - file.getName())); - } else if (!hasImgFiles && file.isFile()) { - if (file.getName().endsWith(".img")) { //$NON-NLS-1$ - hasImgFiles = true; - } - } - } - } - - if (found.size() == 0 && hasImgFiles && root.isDirectory()) { - // We found no sub-folder system images but it looks like the top directory - // has some img files in it. It must be a legacy ARM EABI system image folder. - found.add(new SystemImage( - root, - LocationType.IN_PLATFORM_LEGACY, - SdkConstants.ABI_ARMEABI)); - } - - return found.toArray(new ISystemImage[found.size()]); - } - - /** - * Get all the system images supported by a platform target. - * For a platform, we first look in the new sdk/system-images folders then we - * look for sub-folders in the platform/images directory and/or the one legacy - * folder. - * If any given API appears twice or more, the first occurrence wins. - * - * @param sdkOsPath The path to the SDK. - * @param root Root of the platform target being loaded. - * @param version API level + codename of platform being loaded. - * @return an array of ISystemImage containing all the system images for the target. - * The list can be empty. - */ - private static ISystemImage[] getPlatformSystemImages( - String sdkOsPath, - File root, - AndroidVersion version) { - Set<ISystemImage> found = new TreeSet<ISystemImage>(); - Set<String> abiFound = new HashSet<String>(); - - // First look in the SDK/system-image/platform-n/abi folders. - // We require/enforce the system image to have a valid properties file. - // The actual directory names are irrelevant. - // If we find multiple occurrences of the same platform/abi, the first one read wins. - - File[] firstLevelFiles = new File(sdkOsPath, SdkConstants.FD_SYSTEM_IMAGES).listFiles(); - if (firstLevelFiles != null) { - for (File firstLevel : firstLevelFiles) { - File[] secondLevelFiles = firstLevel.listFiles(); - if (secondLevelFiles != null) { - for (File secondLevel : secondLevelFiles) { - try { - File propFile = new File(secondLevel, SdkConstants.FN_SOURCE_PROP); - Properties props = new Properties(); - FileInputStream fis = null; - try { - fis = new FileInputStream(propFile); - props.load(fis); - } finally { - if (fis != null) { - fis.close(); - } - } - - AndroidVersion propsVersion = new AndroidVersion(props); - if (!propsVersion.equals(version)) { - continue; - } - - String abi = props.getProperty(PkgProps.SYS_IMG_ABI); - if (abi != null && !abiFound.contains(abi)) { - found.add(new SystemImage( - secondLevel, - LocationType.IN_SYSTEM_IMAGE, - abi)); - abiFound.add(abi); - } - } catch (Exception ignore) { - } - } - } - } - } - - // Then look in either the platform/images/abi or the legacy folder - root = new File(root, SdkConstants.OS_IMAGES_FOLDER); - File[] files = root.listFiles(); - boolean useLegacy = true; - boolean hasImgFiles = false; - - if (files != null) { - // Look for sub-directories - for (File file : files) { - if (file.isDirectory()) { - useLegacy = false; - String abi = file.getName(); - if (!abiFound.contains(abi)) { - found.add(new SystemImage( - file, - LocationType.IN_PLATFORM_SUBFOLDER, - abi)); - abiFound.add(abi); - } - } else if (!hasImgFiles && file.isFile()) { - if (file.getName().endsWith(".img")) { //$NON-NLS-1$ - hasImgFiles = true; - } - } - } - } - - if (useLegacy && hasImgFiles && root.isDirectory() && - !abiFound.contains(SdkConstants.ABI_ARMEABI)) { - // We found no sub-folder system images but it looks like the top directory - // has some img files in it. It must be a legacy ARM EABI system image folder. - found.add(new SystemImage( - root, - LocationType.IN_PLATFORM_LEGACY, - SdkConstants.ABI_ARMEABI)); - } - - return found.toArray(new ISystemImage[found.size()]); - } - - /** - * Loads the Add-on from the SDK. - * Creates the "add-ons" folder if necessary. - * - * @param osSdkPath Location of the SDK - * @param targets the list to fill with the add-ons. - * @param dirInfos a map to keep information on directories to see if they change later. - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - * @throws RuntimeException when the "add-ons" folder is missing and cannot be created. - */ - private static void loadAddOns( - String osSdkPath, - ArrayList<IAndroidTarget> targets, - Map<File, DirInfo> dirInfos, ILogger log) { - File addonFolder = new File(osSdkPath, SdkConstants.FD_ADDONS); - - if (addonFolder.isDirectory()) { - File[] addons = addonFolder.listFiles(); - - IAndroidTarget[] targetList = targets.toArray(new IAndroidTarget[targets.size()]); - - if (addons != null) { - for (File addon : addons) { - // Add-ons have to be folders. Ignore files and no need to warn about them. - AddOnTarget target = null; - if (addon.isDirectory()) { - target = loadAddon(addon, targetList, log); - if (target != null) { - targets.add(target); - } - // Remember we visited this file/directory, - // even if we failed to load anything from it. - dirInfos.put(addon, new DirInfo(addon)); - } - } - } - - return; - } - - // Try to create it or complain if something else is in the way. - if (!addonFolder.exists()) { - if (!addonFolder.mkdir()) { - throw new RuntimeException( - String.format("Failed to create %1$s.", - addonFolder.getAbsolutePath())); - } - } else { - throw new RuntimeException( - String.format("%1$s is not a folder.", - addonFolder.getAbsolutePath())); - } - } - - /** - * Loads a specific Add-on at a given location. - * @param addonDir the location of the add-on directory. - * @param targetList The list of Android target that were already loaded from the SDK. - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - */ - private static AddOnTarget loadAddon(File addonDir, - IAndroidTarget[] targetList, - ILogger log) { - - // Parse the addon properties to ensure we can load it. - Pair<Map<String, String>, String> infos = parseAddonProperties(addonDir, targetList, log); - - Map<String, String> propertyMap = infos.getFirst(); - String error = infos.getSecond(); - - if (error != null) { - log.warning("Ignoring add-on '%1$s': %2$s", addonDir.getName(), error); - return null; - } - - // Since error==null we're not supposed to encounter any issues loading this add-on. - try { - assert propertyMap != null; - - String api = propertyMap.get(ADDON_API); - String name = propertyMap.get(ADDON_NAME); - String vendor = propertyMap.get(ADDON_VENDOR); - - assert api != null; - assert name != null; - assert vendor != null; - - PlatformTarget baseTarget = null; - - // Look for a platform that has a matching api level or codename. - for (IAndroidTarget target : targetList) { - if (target.isPlatform() && target.getVersion().equals(api)) { - baseTarget = (PlatformTarget)target; - break; - } - } - - assert baseTarget != null; - - // get the optional description - String description = propertyMap.get(ADDON_DESCRIPTION); - - // get the add-on revision - int revisionValue = 1; - String revision = propertyMap.get(ADDON_REVISION); - if (revision == null) { - revision = propertyMap.get(ADDON_REVISION_OLD); - } - if (revision != null) { - revisionValue = Integer.parseInt(revision); - } - - // get the optional libraries - String librariesValue = propertyMap.get(ADDON_LIBRARIES); - Map<String, String[]> libMap = null; - - if (librariesValue != null) { - librariesValue = librariesValue.trim(); - if (librariesValue.length() > 0) { - // split in the string into the libraries name - String[] libraries = librariesValue.split(";"); //$NON-NLS-1$ - if (libraries.length > 0) { - libMap = new HashMap<String, String[]>(); - for (String libName : libraries) { - libName = libName.trim(); - - // get the library data from the properties - String libData = propertyMap.get(libName); - - if (libData != null) { - // split the jar file from the description - Matcher m = PATTERN_LIB_DATA.matcher(libData); - if (m.matches()) { - libMap.put(libName, new String[] { - m.group(1), m.group(2) }); - } else { - log.warning( - "Ignoring library '%1$s', property value has wrong format\n\t%2$s", - libName, libData); - } - } else { - log.warning( - "Ignoring library '%1$s', missing property value", - libName, libData); - } - } - } - } - } - - // get the abi list. - ISystemImage[] systemImages = getAddonSystemImages(addonDir); - - // check whether the add-on provides its own rendering info/library. - boolean hasRenderingLibrary = false; - boolean hasRenderingResources = false; - - File dataFolder = new File(addonDir, SdkConstants.FD_DATA); - if (dataFolder.isDirectory()) { - hasRenderingLibrary = new File(dataFolder, SdkConstants.FN_LAYOUTLIB_JAR).isFile(); - hasRenderingResources = new File(dataFolder, SdkConstants.FD_RES).isDirectory() && - new File(dataFolder, SdkConstants.FD_FONTS).isDirectory(); - } - - AddOnTarget target = new AddOnTarget(addonDir.getAbsolutePath(), name, vendor, - revisionValue, description, systemImages, libMap, - hasRenderingLibrary, hasRenderingResources,baseTarget); - - // need to parse the skins. - String[] skins = parseSkinFolder(target.getPath(IAndroidTarget.SKINS)); - - // get the default skin, or take it from the base platform if needed. - String defaultSkin = propertyMap.get(ADDON_DEFAULT_SKIN); - if (defaultSkin == null) { - if (skins.length == 1) { - defaultSkin = skins[0]; - } else { - defaultSkin = baseTarget.getDefaultSkin(); - } - } - - // get the USB ID (if available) - int usbVendorId = convertId(propertyMap.get(ADDON_USB_VENDOR)); - if (usbVendorId != IAndroidTarget.NO_USB_ID) { - target.setUsbVendorId(usbVendorId); - } - - target.setSkins(skins, defaultSkin); - - return target; - } - catch (Exception e) { - log.warning("Ignoring add-on '%1$s': error %2$s.", - addonDir.getName(), e.toString()); - } - - return null; - } - - /** - * Parses the add-on properties and decodes any error that occurs when loading an addon. - * - * @param addonDir the location of the addon directory. - * @param targetList The list of Android target that were already loaded from the SDK. - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - * @return A pair with the property map and an error string. Both can be null but not at the - * same time. If a non-null error is present then the property map must be ignored. The error - * should be translatable as it might show up in the SdkManager UI. - */ - public static Pair<Map<String, String>, String> parseAddonProperties( - File addonDir, - IAndroidTarget[] targetList, - ILogger log) { - Map<String, String> propertyMap = null; - String error = null; - - FileWrapper addOnManifest = new FileWrapper(addonDir, SdkConstants.FN_MANIFEST_INI); - - do { - if (!addOnManifest.isFile()) { - error = String.format("File not found: %1$s", SdkConstants.FN_MANIFEST_INI); - break; - } - - propertyMap = ProjectProperties.parsePropertyFile(addOnManifest, log); - if (propertyMap == null) { - error = String.format("Failed to parse properties from %1$s", - SdkConstants.FN_MANIFEST_INI); - break; - } - - // look for some specific values in the map. - // we require name, vendor, and api - String name = propertyMap.get(ADDON_NAME); - if (name == null) { - error = addonManifestWarning(ADDON_NAME); - break; - } - - String vendor = propertyMap.get(ADDON_VENDOR); - if (vendor == null) { - error = addonManifestWarning(ADDON_VENDOR); - break; - } - - String api = propertyMap.get(ADDON_API); - PlatformTarget baseTarget = null; - if (api == null) { - error = addonManifestWarning(ADDON_API); - break; - } - - // Look for a platform that has a matching api level or codename. - for (IAndroidTarget target : targetList) { - if (target.isPlatform() && target.getVersion().equals(api)) { - baseTarget = (PlatformTarget)target; - break; - } - } - - if (baseTarget == null) { - error = String.format("Unable to find base platform with API level '%1$s'", api); - break; - } - - // get the add-on revision - String revision = propertyMap.get(ADDON_REVISION); - if (revision == null) { - revision = propertyMap.get(ADDON_REVISION_OLD); - } - if (revision != null) { - try { - Integer.parseInt(revision); - } catch (NumberFormatException e) { - // looks like revision does not parse to a number. - error = String.format("%1$s is not a valid number in %2$s.", - ADDON_REVISION, SdkConstants.FN_BUILD_PROP); - break; - } - } - - } while(false); - - return Pair.of(propertyMap, error); - } - - /** - * Converts a string representation of an hexadecimal ID into an int. - * @param value the string to convert. - * @return the int value, or {@link IAndroidTarget#NO_USB_ID} if the convertion failed. - */ - private static int convertId(String value) { - if (value != null && value.length() > 0) { - if (PATTERN_USB_IDS.matcher(value).matches()) { - String v = value.substring(2); - try { - return Integer.parseInt(v, 16); - } catch (NumberFormatException e) { - // this shouldn't happen since we check the pattern above, but this is safer. - // the method will return 0 below. - } - } - } - - return IAndroidTarget.NO_USB_ID; - } - - /** - * Prepares a warning about the addon being ignored due to a missing manifest value. - * This string will show up in the SdkManager UI. - * - * @param valueName The missing manifest value, for display. - */ - private static String addonManifestWarning(String valueName) { - return String.format("'%1$s' is missing from %2$s.", - valueName, SdkConstants.FN_MANIFEST_INI); - } - - /** - * Checks the given platform has all the required files, and returns true if they are all - * present. - * <p/>This checks the presence of the following files: android.jar, framework.aidl, aapt(.exe), - * aidl(.exe), dx(.bat), and dx.jar - * - * @param platform The folder containing the platform. - * @param log Logger. Cannot be null. - */ - private static boolean checkPlatformContent(File platform, ILogger log) { - for (String relativePath : sPlatformContentList) { - File f = new File(platform, relativePath); - if (!f.exists()) { - log.warning( - "Ignoring platform '%1$s': %2$s is missing.", //$NON-NLS-1$ - platform.getName(), relativePath); - return false; - } - } - return true; - } - - - - /** - * Parses the skin folder and builds the skin list. - * @param osPath The path of the skin root folder. - */ - private static String[] parseSkinFolder(String osPath) { - File skinRootFolder = new File(osPath); - - if (skinRootFolder.isDirectory()) { - ArrayList<String> skinList = new ArrayList<String>(); - - File[] files = skinRootFolder.listFiles(); - - for (File skinFolder : files) { - if (skinFolder.isDirectory()) { - // check for layout file - File layout = new File(skinFolder, SdkConstants.FN_SKIN_LAYOUT); - - if (layout.isFile()) { - // for now we don't parse the content of the layout and - // simply add the directory to the list. - skinList.add(skinFolder.getName()); - } - } - } - - return skinList.toArray(new String[skinList.size()]); - } - - return new String[0]; - } - - /** - * Initialize the sample folders for all known targets (platforms and addons). - * <p/> - * Samples used to be located at SDK/Target/samples. We then changed this to - * have a separate SDK/samples/samples-API directory. This parses either directories - * and sets the targets' sample path accordingly. - * - * @param log Logger. Cannot be null. - */ - private void initializeSamplePaths(ILogger log) { - File sampleFolder = new File(mOsSdkPath, SdkConstants.FD_SAMPLES); - if (sampleFolder.isDirectory()) { - File[] platforms = sampleFolder.listFiles(); - - for (File platform : platforms) { - if (platform.isDirectory()) { - // load the source.properties file and get an AndroidVersion object from it. - AndroidVersion version = getSamplesVersion(platform, log); - - if (version != null) { - // locate the platform matching this version - for (IAndroidTarget target : mTargets) { - if (target.isPlatform() && target.getVersion().equals(version)) { - ((PlatformTarget)target).setSamplesPath(platform.getAbsolutePath()); - break; - } - } - } - } - } - } - } - - /** - * Returns the {@link AndroidVersion} of the sample in the given folder. - * - * @param folder The sample's folder. - * @param log Logger for errors. Cannot be null. - * @return An {@link AndroidVersion} or null on error. - */ - private AndroidVersion getSamplesVersion(File folder, ILogger log) { - File sourceProp = new File(folder, SdkConstants.FN_SOURCE_PROP); - try { - Properties p = new Properties(); - FileInputStream fis = null; - try { - fis = new FileInputStream(sourceProp); - p.load(fis); - } finally { - if (fis != null) { - fis.close(); - } - } - - return new AndroidVersion(p); - } catch (FileNotFoundException e) { - log.warning("Ignoring sample '%1$s': does not contain %2$s.", //$NON-NLS-1$ - folder.getName(), SdkConstants.FN_SOURCE_PROP); - } catch (IOException e) { - log.warning("Ignoring sample '%1$s': failed reading %2$s.", //$NON-NLS-1$ - folder.getName(), SdkConstants.FN_SOURCE_PROP); - } catch (AndroidVersionException e) { - log.warning("Ignoring sample '%1$s': no android version found in %2$s.", //$NON-NLS-1$ - folder.getName(), SdkConstants.FN_SOURCE_PROP); - } - - return null; - } - - // ------------- - - public static class LayoutlibVersion implements Comparable<LayoutlibVersion> { - private final int mApi; - private final int mRevision; - - public static final int NOT_SPECIFIED = 0; - - public LayoutlibVersion(int api, int revision) { - mApi = api; - mRevision = revision; - } - - public int getApi() { - return mApi; - } - - public int getRevision() { - return mRevision; - } - - @Override - public int compareTo(LayoutlibVersion rhs) { - boolean useRev = this.mRevision > NOT_SPECIFIED && rhs.mRevision > NOT_SPECIFIED; - int lhsValue = (this.mApi << 16) + (useRev ? this.mRevision : 0); - int rhsValue = (rhs.mApi << 16) + (useRev ? rhs.mRevision : 0); - return lhsValue - rhsValue; - } - } - - // ------------- - - private static class DirInfo { - private final @NonNull File mDir; - private final long mDirModifiedTS; - private final long mPropsModifedTS; - private final long mPropsChecksum; - - /** - * Creates a new immutable {@link DirInfo}. - * - * @param dir The platform/addon directory of the target. It should be a directory. - */ - public DirInfo(@NonNull File dir) { - mDir = dir; - mDirModifiedTS = dir.lastModified(); - - // Capture some info about the source.properties file if it exists. - // We use propsModifedTS == 0 to mean there is no props file. - long propsChecksum = 0; - long propsModifedTS = 0; - File props = new File(dir, SdkConstants.FN_SOURCE_PROP); - if (props.isFile()) { - propsModifedTS = props.lastModified(); - propsChecksum = getFileChecksum(props); - } - mPropsModifedTS = propsModifedTS; - mPropsChecksum = propsChecksum; - } - - /** - * Checks whether the directory/source.properties attributes have changed. - * - * @return True if the directory modified timestampd or - * its source.property files have changed. - */ - public boolean hasChanged() { - // Does platform directory still exist? - if (!mDir.isDirectory()) { - return true; - } - // Has platform directory modified-timestamp changed? - if (mDirModifiedTS != mDir.lastModified()) { - return true; - } - - File props = new File(mDir, SdkConstants.FN_SOURCE_PROP); - - // The directory did not have a props file if target was null or - // if mPropsModifedTS is 0. - boolean hadProps = mPropsModifedTS != 0; - - // Was there a props file and it vanished, or there wasn't and there's one now? - if (hadProps != props.isFile()) { - return true; - } - - if (hadProps) { - // Has source.props file modified-timestampd changed? - if (mPropsModifedTS != props.lastModified()) { - return true; - } - // Had the content of source.props changed? - if (mPropsChecksum != getFileChecksum(props)) { - return true; - } - } - - return false; - } - - /** - * Computes an adler32 checksum (source.props are small files, so this - * should be OK with an acceptable collision rate.) - */ - private static long getFileChecksum(File file) { - FileInputStream fis = null; - try { - fis = new FileInputStream(file); - Adler32 a = new Adler32(); - byte[] buf = new byte[1024]; - int n; - while ((n = fis.read(buf)) > 0) { - a.update(buf, 0, n); - } - return a.getValue(); - } catch (Exception ignore) { - } finally { - try { - if (fis != null) { - fis.close(); - } - } catch(Exception ignore) {}; - } - return 0; - } - - /** Returns a visual representation of this object for debugging. */ - @Override - public String toString() { - String s = String.format("<DirInfo %1$s TS=%2$d", mDir, mDirModifiedTS); //$NON-NLS-1$ - if (mPropsModifedTS != 0) { - s += String.format(" | Props TS=%1$d, Chksum=%2$s", //$NON-NLS-1$ - mPropsModifedTS, mPropsChecksum); - } - return s + ">"; //$NON-NLS-1$ - } - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SystemImage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SystemImage.java deleted file mode 100755 index afc11c7..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SystemImage.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import com.android.SdkConstants; -import com.android.sdklib.io.FileOp; - -import java.io.File; -import java.util.Locale; - - -/** - * Describes a system image as used by an {@link IAndroidTarget}. - * A system image has an installation path, a location type and an ABI type. - */ -public class SystemImage implements ISystemImage { - - public static final String ANDROID_PREFIX = "android-"; //$NON-NLS-1$ - - private final LocationType mLocationtype; - private final String mAbiType; - private final File mLocation; - - /** - * Creates a {@link SystemImage} description for an existing system image folder. - * - * @param location The location of an installed system image. - * @param locationType Where the system image folder is located for this ABI. - * @param abiType The ABI type. For example, one of {@link SdkConstants#ABI_ARMEABI}, - * {@link SdkConstants#ABI_ARMEABI_V7A}, {@link SdkConstants#ABI_INTEL_ATOM} or - * {@link SdkConstants#ABI_MIPS}. - */ - public SystemImage(File location, LocationType locationType, String abiType) { - mLocation = location; - mLocationtype = locationType; - mAbiType = abiType; - } - - /** - * Creates a {@link SystemImage} description for a non-existing system image folder. - * The actual location is computed based on the {@code locationtype}. - * - * @param sdkManager The current SDK manager. - * @param locationType Where the system image folder is located for this ABI. - * @param abiType The ABI type. For example, one of {@link SdkConstants#ABI_ARMEABI}, - * {@link SdkConstants#ABI_ARMEABI_V7A}, {@link SdkConstants#ABI_INTEL_ATOM} or - * {@link SdkConstants#ABI_MIPS}. - * @throws IllegalArgumentException if the {@code target} used for - * {@link ISystemImage.LocationType#IN_SYSTEM_IMAGE} is not a {@link PlatformTarget}. - */ - public SystemImage( - SdkManager sdkManager, - IAndroidTarget target, - LocationType locationType, - String abiType) { - mLocationtype = locationType; - mAbiType = abiType; - - File location = null; - switch(locationType) { - case IN_PLATFORM_LEGACY: - location = new File(target.getLocation(), SdkConstants.OS_IMAGES_FOLDER); - break; - - case IN_PLATFORM_SUBFOLDER: - location = FileOp.append(target.getLocation(), SdkConstants.OS_IMAGES_FOLDER, abiType); - break; - - case IN_SYSTEM_IMAGE: - if (!target.isPlatform()) { - throw new IllegalArgumentException( - "Add-ons do not support the system-image location type"); //$NON-NLS-1$ - } - - location = getCanonicalFolder(sdkManager.getLocation(), target.getVersion(), abiType); - break; - default: - // This is not supposed to happen unless LocationType is - // extended without adjusting this code. - assert false : "SystemImage used with an incorrect locationType"; //$NON-NLS-1$ - } - mLocation = location; - } - - /** - * Static helper method that returns the canonical path for a system-image that uses - * the {@link ISystemImage.LocationType#IN_SYSTEM_IMAGE} location type. - * <p/> - * Such an image is located in {@code SDK/system-images/android-N/abiType}. - * For this reason this method requires the root SDK as well as the platform and the ABI type. - * - * @param sdkOsPath The OS path to the SDK. - * @param platformVersion The platform version. - * @param abiType An optional ABI type. If null, the parent directory is returned. - * @return A file that represents the location of the canonical system-image folder - * for this configuration. - */ - public static File getCanonicalFolder( - String sdkOsPath, - AndroidVersion platformVersion, - String abiType) { - File root = FileOp.append( - sdkOsPath, - SdkConstants.FD_SYSTEM_IMAGES, - ANDROID_PREFIX + platformVersion.getApiString()); - if (abiType == null) { - return root; - } else { - return FileOp.append(root, abiType); - } - } - - /** Returns the actual location of an installed system image. */ - @Override - public File getLocation() { - return mLocation; - } - - /** Indicates the location strategy for this system image in the SDK. */ - @Override - public LocationType getLocationType() { - return mLocationtype; - } - - /** - * Returns the ABI type. For example, one of {@link SdkConstants#ABI_ARMEABI}, - * {@link SdkConstants#ABI_ARMEABI_V7A}, {@link SdkConstants#ABI_INTEL_ATOM} or - * {@link SdkConstants#ABI_MIPS}. - * Cannot be null nor empty. - */ - @Override - public String getAbiType() { - return mAbiType; - } - - @Override - public int compareTo(ISystemImage other) { - // Sort by ABI name only. This is what matters from a user point of view. - return this.getAbiType().compareToIgnoreCase(other.getAbiType()); - } - - /** - * Generates a string representation suitable for debug purposes. - * The string is not intended to be displayed to the user. - * - * {@inheritDoc} - */ - @Override - public String toString() { - return String.format("SystemImage ABI=%s, location %s='%s'", //$NON-NLS-1$ - mAbiType, - mLocationtype.toString().replace('_', ' ').toLowerCase(Locale.US), - mLocation - ); - } - - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilder.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilder.java deleted file mode 100644 index f5abe9e..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilder.java +++ /dev/null @@ -1,998 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.build; - -import com.android.SdkConstants; -import com.android.sdklib.internal.build.DebugKeyProvider; -import com.android.sdklib.internal.build.DebugKeyProvider.IKeyGenOutput; -import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException; -import com.android.sdklib.internal.build.SignedJarBuilder; -import com.android.sdklib.internal.build.SignedJarBuilder.IZipEntryFilter; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.regex.Pattern; - -/** - * Class making the final apk packaging. - * The inputs are: - * - packaged resources (output of aapt) - * - code file (ouput of dx) - * - Java resources coming from the project, its libraries, and its jar files - * - Native libraries from the project or its library. - * - */ -public final class ApkBuilder implements IArchiveBuilder { - - private final static Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$", - Pattern.CASE_INSENSITIVE); - private final static Pattern PATTERN_BITCODELIB_EXT = Pattern.compile("^.+\\.bc$", - Pattern.CASE_INSENSITIVE); - - /** - * A No-op zip filter. It's used to detect conflicts. - * - */ - private final class NullZipFilter implements IZipEntryFilter { - private File mInputFile; - - void reset(File inputFile) { - mInputFile = inputFile; - } - - @Override - public boolean checkEntry(String archivePath) throws ZipAbortException { - verbosePrintln("=> %s", archivePath); - - File duplicate = checkFileForDuplicate(archivePath); - if (duplicate != null) { - throw new DuplicateFileException(archivePath, duplicate, mInputFile); - } else { - mAddedFiles.put(archivePath, mInputFile); - } - - return true; - } - } - - /** - * Custom {@link IZipEntryFilter} to filter out everything that is not a standard java - * resources, and also record whether the zip file contains native libraries. - * <p/>Used in {@link SignedJarBuilder#writeZip(java.io.InputStream, IZipEntryFilter)} when - * we only want the java resources from external jars. - */ - private final class JavaAndNativeResourceFilter implements IZipEntryFilter { - private final List<String> mNativeLibs = new ArrayList<String>(); - private boolean mNativeLibsConflict = false; - private File mInputFile; - - @Override - public boolean checkEntry(String archivePath) throws ZipAbortException { - // split the path into segments. - String[] segments = archivePath.split("/"); - - // empty path? skip to next entry. - if (segments.length == 0) { - return false; - } - - // Check each folders to make sure they should be included. - // Folders like CVS, .svn, etc.. should already have been excluded from the - // jar file, but we need to exclude some other folder (like /META-INF) so - // we check anyway. - for (int i = 0 ; i < segments.length - 1; i++) { - if (checkFolderForPackaging(segments[i]) == false) { - return false; - } - } - - // get the file name from the path - String fileName = segments[segments.length-1]; - - boolean check = checkFileForPackaging(fileName); - - // only do additional checks if the file passes the default checks. - if (check) { - verbosePrintln("=> %s", archivePath); - - File duplicate = checkFileForDuplicate(archivePath); - if (duplicate != null) { - throw new DuplicateFileException(archivePath, duplicate, mInputFile); - } else { - mAddedFiles.put(archivePath, mInputFile); - } - - if (archivePath.endsWith(".so") || archivePath.endsWith(".bc")) { - mNativeLibs.add(archivePath); - - // only .so located in lib/ will interfere with the installation - if (archivePath.startsWith(SdkConstants.FD_APK_NATIVE_LIBS + "/")) { - mNativeLibsConflict = true; - } - } else if (archivePath.endsWith(".jnilib")) { - mNativeLibs.add(archivePath); - } - } - - return check; - } - - List<String> getNativeLibs() { - return mNativeLibs; - } - - boolean getNativeLibsConflict() { - return mNativeLibsConflict; - } - - void reset(File inputFile) { - mInputFile = inputFile; - mNativeLibs.clear(); - mNativeLibsConflict = false; - } - } - - private File mApkFile; - private File mResFile; - private File mDexFile; - private PrintStream mVerboseStream; - private SignedJarBuilder mBuilder; - private boolean mDebugMode = false; - private boolean mIsSealed = false; - - private final NullZipFilter mNullFilter = new NullZipFilter(); - private final JavaAndNativeResourceFilter mFilter = new JavaAndNativeResourceFilter(); - private final HashMap<String, File> mAddedFiles = new HashMap<String, File>(); - - /** - * Status for the addition of a jar file resources into the APK. - * This indicates possible issues with native library inside the jar file. - */ - public interface JarStatus { - /** - * Returns the list of native libraries found in the jar file. - */ - List<String> getNativeLibs(); - - /** - * Returns whether some of those libraries were located in the location that Android - * expects its native libraries. - */ - boolean hasNativeLibsConflicts(); - - } - - /** Internal implementation of {@link JarStatus}. */ - private final static class JarStatusImpl implements JarStatus { - public final List<String> mLibs; - public final boolean mNativeLibsConflict; - - private JarStatusImpl(List<String> libs, boolean nativeLibsConflict) { - mLibs = libs; - mNativeLibsConflict = nativeLibsConflict; - } - - @Override - public List<String> getNativeLibs() { - return mLibs; - } - - @Override - public boolean hasNativeLibsConflicts() { - return mNativeLibsConflict; - } - } - - /** - * Signing information. - * - * Both the {@link PrivateKey} and the {@link X509Certificate} are guaranteed to be non-null. - * - */ - public final static class SigningInfo { - public final PrivateKey key; - public final X509Certificate certificate; - - private SigningInfo(PrivateKey key, X509Certificate certificate) { - if (key == null || certificate == null) { - throw new IllegalArgumentException("key and certificate cannot be null"); - } - this.key = key; - this.certificate = certificate; - } - } - - /** - * Returns the key and certificate from a given debug store. - * - * It is expected that the store password is 'android' and the key alias and password are - * 'androiddebugkey' and 'android' respectively. - * - * @param storeOsPath the OS path to the debug store. - * @param verboseStream an option {@link PrintStream} to display verbose information - * @return they key and certificate in a {@link SigningInfo} object or null. - * @throws ApkCreationException - */ - public static SigningInfo getDebugKey(String storeOsPath, final PrintStream verboseStream) - throws ApkCreationException { - try { - if (storeOsPath != null) { - File storeFile = new File(storeOsPath); - try { - checkInputFile(storeFile); - } catch (FileNotFoundException e) { - // ignore these since the debug store can be created on the fly anyway. - } - - // get the debug key - if (verboseStream != null) { - verboseStream.println(String.format("Using keystore: %s", storeOsPath)); - } - - IKeyGenOutput keygenOutput = null; - if (verboseStream != null) { - keygenOutput = new IKeyGenOutput() { - @Override - public void out(String message) { - verboseStream.println(message); - } - - @Override - public void err(String message) { - verboseStream.println(message); - } - }; - } - - DebugKeyProvider keyProvider = new DebugKeyProvider( - storeOsPath, null /*store type*/, keygenOutput); - - PrivateKey key = keyProvider.getDebugKey(); - X509Certificate certificate = (X509Certificate)keyProvider.getCertificate(); - - if (key == null) { - throw new ApkCreationException("Unable to get debug signature key"); - } - - // compare the certificate expiration date - if (certificate != null && certificate.getNotAfter().compareTo(new Date()) < 0) { - // TODO, regenerate a new one. - throw new ApkCreationException("Debug Certificate expired on " + - DateFormat.getInstance().format(certificate.getNotAfter())); - } - - return new SigningInfo(key, certificate); - } else { - return null; - } - } catch (KeytoolException e) { - if (e.getJavaHome() == null) { - throw new ApkCreationException(e.getMessage() + - "\nJAVA_HOME seems undefined, setting it will help locating keytool automatically\n" + - "You can also manually execute the following command\n:" + - e.getCommandLine(), e); - } else { - throw new ApkCreationException(e.getMessage() + - "\nJAVA_HOME is set to: " + e.getJavaHome() + - "\nUpdate it if necessary, or manually execute the following command:\n" + - e.getCommandLine(), e); - } - } catch (ApkCreationException e) { - throw e; - } catch (Exception e) { - throw new ApkCreationException(e); - } - } - - /** - * Creates a new instance. - * - * This creates a new builder that will create the specified output file, using the two - * mandatory given input files. - * - * An optional debug keystore can be provided. If set, it is expected that the store password - * is 'android' and the key alias and password are 'androiddebugkey' and 'android'. - * - * An optional {@link PrintStream} can also be provided for verbose output. If null, there will - * be no output. - * - * @param apkOsPath the OS path of the file to create. - * @param resOsPath the OS path of the packaged resource file. - * @param dexOsPath the OS path of the dex file. This can be null for apk with no code. - * @param verboseStream the stream to which verbose output should go. If null, verbose mode - * is not enabled. - * @throws ApkCreationException - */ - public ApkBuilder(String apkOsPath, String resOsPath, String dexOsPath, String storeOsPath, - PrintStream verboseStream) throws ApkCreationException { - this(new File(apkOsPath), - new File(resOsPath), - dexOsPath != null ? new File(dexOsPath) : null, - storeOsPath, - verboseStream); - } - - /** - * Creates a new instance. - * - * This creates a new builder that will create the specified output file, using the two - * mandatory given input files. - * - * Optional {@link PrivateKey} and {@link X509Certificate} can be provided to sign the APK. - * - * An optional {@link PrintStream} can also be provided for verbose output. If null, there will - * be no output. - * - * @param apkOsPath the OS path of the file to create. - * @param resOsPath the OS path of the packaged resource file. - * @param dexOsPath the OS path of the dex file. This can be null for apk with no code. - * @param key the private key used to sign the package. Can be null. - * @param certificate the certificate used to sign the package. Can be null. - * @param verboseStream the stream to which verbose output should go. If null, verbose mode - * is not enabled. - * @throws ApkCreationException - */ - public ApkBuilder(String apkOsPath, String resOsPath, String dexOsPath, PrivateKey key, - X509Certificate certificate, PrintStream verboseStream) throws ApkCreationException { - this(new File(apkOsPath), - new File(resOsPath), - dexOsPath != null ? new File(dexOsPath) : null, - key, certificate, - verboseStream); - } - - /** - * Creates a new instance. - * - * This creates a new builder that will create the specified output file, using the two - * mandatory given input files. - * - * An optional debug keystore can be provided. If set, it is expected that the store password - * is 'android' and the key alias and password are 'androiddebugkey' and 'android'. - * - * An optional {@link PrintStream} can also be provided for verbose output. If null, there will - * be no output. - * - * @param apkFile the file to create - * @param resFile the file representing the packaged resource file. - * @param dexFile the file representing the dex file. This can be null for apk with no code. - * @param debugStoreOsPath the OS path to the debug keystore, if needed or null. - * @param verboseStream the stream to which verbose output should go. If null, verbose mode - * is not enabled. - * @throws ApkCreationException - */ - public ApkBuilder(File apkFile, File resFile, File dexFile, String debugStoreOsPath, - final PrintStream verboseStream) throws ApkCreationException { - - SigningInfo info = getDebugKey(debugStoreOsPath, verboseStream); - if (info != null) { - init(apkFile, resFile, dexFile, info.key, info.certificate, verboseStream); - } else { - init(apkFile, resFile, dexFile, null /*key*/, null/*certificate*/, verboseStream); - } - } - - /** - * Creates a new instance. - * - * This creates a new builder that will create the specified output file, using the two - * mandatory given input files. - * - * Optional {@link PrivateKey} and {@link X509Certificate} can be provided to sign the APK. - * - * An optional {@link PrintStream} can also be provided for verbose output. If null, there will - * be no output. - * - * @param apkFile the file to create - * @param resFile the file representing the packaged resource file. - * @param dexFile the file representing the dex file. This can be null for apk with no code. - * @param key the private key used to sign the package. Can be null. - * @param certificate the certificate used to sign the package. Can be null. - * @param verboseStream the stream to which verbose output should go. If null, verbose mode - * is not enabled. - * @throws ApkCreationException - */ - public ApkBuilder(File apkFile, File resFile, File dexFile, PrivateKey key, - X509Certificate certificate, PrintStream verboseStream) throws ApkCreationException { - init(apkFile, resFile, dexFile, key, certificate, verboseStream); - } - - - /** - * Constructor init method. - * - * @see #ApkBuilder(File, File, File, String, PrintStream) - * @see #ApkBuilder(String, String, String, String, PrintStream) - * @see #ApkBuilder(File, File, File, PrivateKey, X509Certificate, PrintStream) - */ - private void init(File apkFile, File resFile, File dexFile, PrivateKey key, - X509Certificate certificate, PrintStream verboseStream) throws ApkCreationException { - - try { - checkOutputFile(mApkFile = apkFile); - checkInputFile(mResFile = resFile); - if (dexFile != null) { - checkInputFile(mDexFile = dexFile); - } else { - mDexFile = null; - } - mVerboseStream = verboseStream; - - mBuilder = new SignedJarBuilder( - new FileOutputStream(mApkFile, false /* append */), key, - certificate); - - verbosePrintln("Packaging %s", mApkFile.getName()); - - // add the resources - addZipFile(mResFile); - - // add the class dex file at the root of the apk - if (mDexFile != null) { - addFile(mDexFile, SdkConstants.FN_APK_CLASSES_DEX); - } - - } catch (ApkCreationException e) { - if (mBuilder != null) { - mBuilder.cleanUp(); - } - throw e; - } catch (Exception e) { - if (mBuilder != null) { - mBuilder.cleanUp(); - } - throw new ApkCreationException(e); - } - } - - /** - * Sets the debug mode. In debug mode, when native libraries are present, the packaging - * will also include one or more copies of gdbserver in the final APK file. - * - * These are used for debugging native code, to ensure that gdbserver is accessible to the - * application. - * - * There will be one version of gdbserver for each ABI supported by the application. - * - * the gbdserver files are placed in the libs/abi/ folders automatically by the NDK. - * - * @param debugMode the debug mode flag. - */ - public void setDebugMode(boolean debugMode) { - mDebugMode = debugMode; - } - - /** - * Adds a file to the APK at a given path - * @param file the file to add - * @param archivePath the path of the file inside the APK archive. - * @throws ApkCreationException if an error occurred - * @throws SealedApkException if the APK is already sealed. - * @throws DuplicateFileException if a file conflicts with another already added to the APK - * at the same location inside the APK archive. - */ - @Override - public void addFile(File file, String archivePath) throws ApkCreationException, - SealedApkException, DuplicateFileException { - if (mIsSealed) { - throw new SealedApkException("APK is already sealed"); - } - - try { - doAddFile(file, archivePath); - } catch (DuplicateFileException e) { - mBuilder.cleanUp(); - throw e; - } catch (Exception e) { - mBuilder.cleanUp(); - throw new ApkCreationException(e, "Failed to add %s", file); - } - } - - /** - * Adds the content from a zip file. - * All file keep the same path inside the archive. - * @param zipFile the zip File. - * @throws ApkCreationException if an error occurred - * @throws SealedApkException if the APK is already sealed. - * @throws DuplicateFileException if a file conflicts with another already added to the APK - * at the same location inside the APK archive. - */ - public void addZipFile(File zipFile) throws ApkCreationException, SealedApkException, - DuplicateFileException { - if (mIsSealed) { - throw new SealedApkException("APK is already sealed"); - } - - try { - verbosePrintln("%s:", zipFile); - - // reset the filter with this input. - mNullFilter.reset(zipFile); - - // ask the builder to add the content of the file. - FileInputStream fis = new FileInputStream(zipFile); - mBuilder.writeZip(fis, mNullFilter); - } catch (DuplicateFileException e) { - mBuilder.cleanUp(); - throw e; - } catch (Exception e) { - mBuilder.cleanUp(); - throw new ApkCreationException(e, "Failed to add %s", zipFile); - } - } - - /** - * Adds the resources from a jar file. - * @param jarFile the jar File. - * @return a {@link JarStatus} object indicating if native libraries where found in - * the jar file. - * @throws ApkCreationException if an error occurred - * @throws SealedApkException if the APK is already sealed. - * @throws DuplicateFileException if a file conflicts with another already added to the APK - * at the same location inside the APK archive. - */ - public JarStatus addResourcesFromJar(File jarFile) throws ApkCreationException, - SealedApkException, DuplicateFileException { - if (mIsSealed) { - throw new SealedApkException("APK is already sealed"); - } - - try { - verbosePrintln("%s:", jarFile); - - // reset the filter with this input. - mFilter.reset(jarFile); - - // ask the builder to add the content of the file, filtered to only let through - // the java resources. - FileInputStream fis = new FileInputStream(jarFile); - mBuilder.writeZip(fis, mFilter); - - // check if native libraries were found in the external library. This should - // constitutes an error or warning depending on if they are in lib/ - return new JarStatusImpl(mFilter.getNativeLibs(), mFilter.getNativeLibsConflict()); - } catch (DuplicateFileException e) { - mBuilder.cleanUp(); - throw e; - } catch (Exception e) { - mBuilder.cleanUp(); - throw new ApkCreationException(e, "Failed to add %s", jarFile); - } - } - - /** - * Adds the resources from a source folder. - * @param sourceFolder the source folder. - * @throws ApkCreationException if an error occurred - * @throws SealedApkException if the APK is already sealed. - * @throws DuplicateFileException if a file conflicts with another already added to the APK - * at the same location inside the APK archive. - */ - public void addSourceFolder(File sourceFolder) throws ApkCreationException, SealedApkException, - DuplicateFileException { - if (mIsSealed) { - throw new SealedApkException("APK is already sealed"); - } - - addSourceFolder(this, sourceFolder); - } - - /** - * Adds the resources from a source folder to a given {@link IArchiveBuilder} - * @param sourceFolder the source folder. - * @throws ApkCreationException if an error occurred - * @throws DuplicateFileException if a file conflicts with another already added to the APK - * at the same location inside the APK archive. - */ - public static void addSourceFolder(IArchiveBuilder builder, File sourceFolder) - throws ApkCreationException, DuplicateFileException { - if (sourceFolder.isDirectory()) { - try { - // file is a directory, process its content. - File[] files = sourceFolder.listFiles(); - for (File file : files) { - processFileForResource(builder, file, null); - } - } catch (DuplicateFileException e) { - throw e; - } catch (Exception e) { - throw new ApkCreationException(e, "Failed to add %s", sourceFolder); - } - } else { - // not a directory? check if it's a file or doesn't exist - if (sourceFolder.exists()) { - throw new ApkCreationException("%s is not a folder", sourceFolder); - } else { - throw new ApkCreationException("%s does not exist", sourceFolder); - } - } - } - - /** - * Adds the native libraries from the top native folder. - * The content of this folder must be the various ABI folders. - * - * This may or may not copy gdbserver into the apk based on whether the debug mode is set. - * - * @param nativeFolder the native folder. - * - * @throws ApkCreationException if an error occurred - * @throws SealedApkException if the APK is already sealed. - * @throws DuplicateFileException if a file conflicts with another already added to the APK - * at the same location inside the APK archive. - * - * @see #setDebugMode(boolean) - */ - public void addNativeLibraries(File nativeFolder) - throws ApkCreationException, SealedApkException, DuplicateFileException { - if (mIsSealed) { - throw new SealedApkException("APK is already sealed"); - } - - if (nativeFolder.isDirectory() == false) { - // not a directory? check if it's a file or doesn't exist - if (nativeFolder.exists()) { - throw new ApkCreationException("%s is not a folder", nativeFolder); - } else { - throw new ApkCreationException("%s does not exist", nativeFolder); - } - } - - File[] abiList = nativeFolder.listFiles(); - - verbosePrintln("Native folder: %s", nativeFolder); - - if (abiList != null) { - for (File abi : abiList) { - if (abi.isDirectory()) { // ignore files - - File[] libs = abi.listFiles(); - if (libs != null) { - for (File lib : libs) { - // only consider files that are .so or, if in debug mode, that - // are gdbserver executables - if (lib.isFile() && - (PATTERN_NATIVELIB_EXT.matcher(lib.getName()).matches() || - PATTERN_BITCODELIB_EXT.matcher(lib.getName()).matches() || - (mDebugMode && - SdkConstants.FN_GDBSERVER.equals( - lib.getName())))) { - String path = - SdkConstants.FD_APK_NATIVE_LIBS + "/" + - abi.getName() + "/" + lib.getName(); - - try { - doAddFile(lib, path); - } catch (IOException e) { - mBuilder.cleanUp(); - throw new ApkCreationException(e, "Failed to add %s", lib); - } - } - } - } - } - } - } - } - - public void addNativeLibraries(List<FileEntry> entries) throws SealedApkException, - DuplicateFileException, ApkCreationException { - if (mIsSealed) { - throw new SealedApkException("APK is already sealed"); - } - - for (FileEntry entry : entries) { - try { - doAddFile(entry.mFile, entry.mPath); - } catch (IOException e) { - mBuilder.cleanUp(); - throw new ApkCreationException(e, "Failed to add %s", entry.mFile); - } - } - } - - public static final class FileEntry { - public final File mFile; - public final String mPath; - - FileEntry(File file, String path) { - mFile = file; - mPath = path; - } - } - - public static List<FileEntry> getNativeFiles(File nativeFolder, boolean debugMode) - throws ApkCreationException { - - if (nativeFolder.isDirectory() == false) { - // not a directory? check if it's a file or doesn't exist - if (nativeFolder.exists()) { - throw new ApkCreationException("%s is not a folder", nativeFolder); - } else { - throw new ApkCreationException("%s does not exist", nativeFolder); - } - } - - List<FileEntry> files = new ArrayList<FileEntry>(); - - File[] abiList = nativeFolder.listFiles(); - - if (abiList != null) { - for (File abi : abiList) { - if (abi.isDirectory()) { // ignore files - - File[] libs = abi.listFiles(); - if (libs != null) { - for (File lib : libs) { - // only consider files that are .so or, if in debug mode, that - // are gdbserver executables - if (lib.isFile() && - (PATTERN_NATIVELIB_EXT.matcher(lib.getName()).matches() || - PATTERN_BITCODELIB_EXT.matcher(lib.getName()).matches() || - (debugMode && - SdkConstants.FN_GDBSERVER.equals( - lib.getName())))) { - String path = - SdkConstants.FD_APK_NATIVE_LIBS + "/" + - abi.getName() + "/" + lib.getName(); - - files.add(new FileEntry(lib, path)); - } - } - } - } - } - } - - return files; - } - - - - /** - * Seals the APK, and signs it if necessary. - * @throws ApkCreationException - * @throws ApkCreationException if an error occurred - * @throws SealedApkException if the APK is already sealed. - */ - public void sealApk() throws ApkCreationException, SealedApkException { - if (mIsSealed) { - throw new SealedApkException("APK is already sealed"); - } - - // close and sign the application package. - try { - mBuilder.close(); - mIsSealed = true; - } catch (Exception e) { - throw new ApkCreationException(e, "Failed to seal APK"); - } finally { - mBuilder.cleanUp(); - } - } - - /** - * Output a given message if the verbose mode is enabled. - * @param format the format string for {@link String#format(String, Object...)} - * @param args the string arguments - */ - private void verbosePrintln(String format, Object... args) { - if (mVerboseStream != null) { - mVerboseStream.println(String.format(format, args)); - } - } - - private void doAddFile(File file, String archivePath) throws DuplicateFileException, - IOException { - verbosePrintln("%1$s => %2$s", file, archivePath); - - File duplicate = checkFileForDuplicate(archivePath); - if (duplicate != null) { - throw new DuplicateFileException(archivePath, duplicate, file); - } - - mAddedFiles.put(archivePath, file); - mBuilder.writeFile(file, archivePath); - } - - /** - * Processes a {@link File} that could be an APK {@link File}, or a folder containing - * java resources. - * - * @param file the {@link File} to process. - * @param path the relative path of this file to the source folder. - * Can be <code>null</code> to identify a root file. - * @throws IOException - * @throws DuplicateFileException if a file conflicts with another already added - * to the APK at the same location inside the APK archive. - * @throws SealedApkException if the APK is already sealed. - * @throws ApkCreationException if an error occurred - */ - private static void processFileForResource(IArchiveBuilder builder, File file, String path) - throws IOException, DuplicateFileException, ApkCreationException, SealedApkException { - if (file.isDirectory()) { - // a directory? we check it - if (checkFolderForPackaging(file.getName())) { - // if it's valid, we append its name to the current path. - if (path == null) { - path = file.getName(); - } else { - path = path + "/" + file.getName(); - } - - // and process its content. - File[] files = file.listFiles(); - for (File contentFile : files) { - processFileForResource(builder, contentFile, path); - } - } - } else { - // a file? we check it to make sure it should be added - if (checkFileForPackaging(file.getName())) { - // we append its name to the current path - if (path == null) { - path = file.getName(); - } else { - path = path + "/" + file.getName(); - } - - // and add it to the apk - builder.addFile(file, path); - } - } - } - - /** - * Checks if the given path in the APK archive has not already been used and if it has been, - * then returns a {@link File} object for the source of the duplicate - * @param archivePath the archive path to test. - * @return A File object of either a file at the same location or an archive that contains a - * file that was put at the same location. - */ - private File checkFileForDuplicate(String archivePath) { - return mAddedFiles.get(archivePath); - } - - /** - * Checks an output {@link File} object. - * This checks the following: - * - the file is not an existing directory. - * - if the file exists, that it can be modified. - * - if it doesn't exists, that a new file can be created. - * @param file the File to check - * @throws ApkCreationException If the check fails - */ - private void checkOutputFile(File file) throws ApkCreationException { - if (file.isDirectory()) { - throw new ApkCreationException("%s is a directory!", file); - } - - if (file.exists()) { // will be a file in this case. - if (file.canWrite() == false) { - throw new ApkCreationException("Cannot write %s", file); - } - } else { - try { - if (file.createNewFile() == false) { - throw new ApkCreationException("Failed to create %s", file); - } - } catch (IOException e) { - throw new ApkCreationException( - "Failed to create '%1$ss': %2$s", file, e.getMessage()); - } - } - } - - /** - * Checks an input {@link File} object. - * This checks the following: - * - the file is not an existing directory. - * - that the file exists (if <var>throwIfDoesntExist</var> is <code>false</code>) and can - * be read. - * @param file the File to check - * @throws FileNotFoundException if the file is not here. - * @throws ApkCreationException If the file is a folder or a file that cannot be read. - */ - private static void checkInputFile(File file) throws FileNotFoundException, ApkCreationException { - if (file.isDirectory()) { - throw new ApkCreationException("%s is a directory!", file); - } - - if (file.exists()) { - if (file.canRead() == false) { - throw new ApkCreationException("Cannot read %s", file); - } - } else { - throw new FileNotFoundException(String.format("%s does not exist", file)); - } - } - - public static String getDebugKeystore() throws ApkCreationException { - try { - return DebugKeyProvider.getDefaultKeyStoreOsPath(); - } catch (Exception e) { - throw new ApkCreationException(e, e.getMessage()); - } - } - - /** - * Checks whether a folder and its content is valid for packaging into the .apk as - * standard Java resource. - * @param folderName the name of the folder. - */ - public static boolean checkFolderForPackaging(String folderName) { - return folderName.equalsIgnoreCase("CVS") == false && - folderName.equalsIgnoreCase(".svn") == false && - folderName.equalsIgnoreCase("SCCS") == false && - folderName.equalsIgnoreCase("META-INF") == false && - folderName.startsWith("_") == false; - } - - /** - * Checks a file to make sure it should be packaged as standard resources. - * @param fileName the name of the file (including extension) - * @return true if the file should be packaged as standard java resources. - */ - public static boolean checkFileForPackaging(String fileName) { - String[] fileSegments = fileName.split("\\."); - String fileExt = ""; - if (fileSegments.length > 1) { - fileExt = fileSegments[fileSegments.length-1]; - } - - return checkFileForPackaging(fileName, fileExt); - } - - /** - * Checks a file to make sure it should be packaged as standard resources. - * @param fileName the name of the file (including extension) - * @param extension the extension of the file (excluding '.') - * @return true if the file should be packaged as standard java resources. - */ - public static boolean checkFileForPackaging(String fileName, String extension) { - // ignore hidden files and backup files - if (fileName.charAt(0) == '.' || fileName.charAt(fileName.length()-1) == '~') { - return false; - } - - return "aidl".equalsIgnoreCase(extension) == false && // Aidl files - "rs".equalsIgnoreCase(extension) == false && // RenderScript files - "rsh".equalsIgnoreCase(extension) == false && // RenderScript header files - "d".equalsIgnoreCase(extension) == false && // Dependency files - "java".equalsIgnoreCase(extension) == false && // Java files - "scala".equalsIgnoreCase(extension) == false && // Scala files - "class".equalsIgnoreCase(extension) == false && // Java class files - "scc".equalsIgnoreCase(extension) == false && // VisualSourceSafe - "swp".equalsIgnoreCase(extension) == false && // vi swap file - "thumbs.db".equalsIgnoreCase(fileName) == false && // image index file - "picasa.ini".equalsIgnoreCase(fileName) == false && // image index file - "package.html".equalsIgnoreCase(fileName) == false && // Javadoc - "overview.html".equalsIgnoreCase(fileName) == false; // Javadoc - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilderMain.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilderMain.java deleted file mode 100644 index 805b74a..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkBuilderMain.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.build; - - -import java.io.File; -import java.io.FilenameFilter; -import java.util.ArrayList; -import java.util.regex.Pattern; - - -/** - * Command line APK builder with signing support. - */ -public final class ApkBuilderMain { - - private final static Pattern PATTERN_JAR_EXT = Pattern.compile("^.+\\.jar$", - Pattern.CASE_INSENSITIVE); - - /** - * Main method. This is meant to be called from the command line through an exec. - * <p/>WARNING: this will call {@link System#exit(int)} if anything goes wrong. - * @param args command line arguments. - */ - public static void main(String[] args) { - if (args.length < 1) { - printUsageAndQuit(); - } - - System.err.println("\nTHIS TOOL IS DEPRECATED. See --help for more information.\n"); - - try { - File outApk = new File(args[0]); - - File dexFile = null; - ArrayList<File> zipArchives = new ArrayList<File>(); - ArrayList<File> sourceFolders = new ArrayList<File>(); - ArrayList<File> jarFiles = new ArrayList<File>(); - ArrayList<File> nativeFolders = new ArrayList<File>(); - - boolean verbose = false; - boolean signed = true; - boolean debug = false; - - int index = 1; - do { - String argument = args[index++]; - - if ("-v".equals(argument)) { - verbose = true; - - } else if ("-d".equals(argument)) { - debug = true; - - } else if ("-u".equals(argument)) { - signed = false; - - } else if ("-z".equals(argument)) { - // quick check on the next argument. - if (index == args.length) { - printAndExit("Missing value for -z"); - } - - zipArchives.add(new File(args[index++])); - } else if ("-f". equals(argument)) { - if (dexFile != null) { - // can't have more than one dex file. - printAndExit("Can't have more than one dex file (-f)"); - } - // quick check on the next argument. - if (index == args.length) { - printAndExit("Missing value for -f"); - } - - dexFile = new File(args[index++]); - } else if ("-rf". equals(argument)) { - // quick check on the next argument. - if (index == args.length) { - printAndExit("Missing value for -rf"); - } - - sourceFolders.add(new File(args[index++])); - } else if ("-rj". equals(argument)) { - // quick check on the next argument. - if (index == args.length) { - printAndExit("Missing value for -rj"); - } - - jarFiles.add(new File(args[index++])); - } else if ("-nf".equals(argument)) { - // quick check on the next argument. - if (index == args.length) { - printAndExit("Missing value for -nf"); - } - - nativeFolders.add(new File(args[index++])); - } else if ("-storetype".equals(argument)) { - // quick check on the next argument. - if (index == args.length) { - printAndExit("Missing value for -storetype"); - } - - // FIXME - } else { - printAndExit("Unknown argument: " + argument); - } - } while (index < args.length); - - if (zipArchives.size() == 0) { - printAndExit("No zip archive, there must be one for the resources"); - } - - // create the builder with the basic files. - ApkBuilder builder = new ApkBuilder(outApk, zipArchives.get(0), dexFile, - signed ? ApkBuilder.getDebugKeystore() : null, - verbose ? System.out : null); - builder.setDebugMode(debug); - - // add the rest of the files. - // first zip Archive was used in the constructor. - for (int i = 1 ; i < zipArchives.size() ; i++) { - builder.addZipFile(zipArchives.get(i)); - } - - for (File sourceFolder : sourceFolders) { - builder.addSourceFolder(sourceFolder); - } - - for (File jarFile : jarFiles) { - if (jarFile.isDirectory()) { - String[] filenames = jarFile.list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return PATTERN_JAR_EXT.matcher(name).matches(); - } - }); - - for (String filename : filenames) { - builder.addResourcesFromJar(new File(jarFile, filename)); - } - } else { - builder.addResourcesFromJar(jarFile); - } - } - - for (File nativeFolder : nativeFolders) { - builder.addNativeLibraries(nativeFolder); - } - - // seal the apk - builder.sealApk(); - - - } catch (ApkCreationException e) { - printAndExit(e.getMessage()); - } catch (DuplicateFileException e) { - printAndExit(String.format( - "Found duplicate file for APK: %1$s\nOrigin 1: %2$s\nOrigin 2: %3$s", - e.getArchivePath(), e.getFile1(), e.getFile2())); - } catch (SealedApkException e) { - printAndExit(e.getMessage()); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static void printUsageAndQuit() { - // 80 cols marker: 01234567890123456789012345678901234567890123456789012345678901234567890123456789 - System.err.println("\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"); - System.err.println("THIS TOOL IS DEPRECATED and may stop working at any time!\n"); - System.err.println("If you wish to use apkbuilder for a custom build system, please look at the"); - System.err.println("com.android.sdklib.build.ApkBuilder which provides support for"); - System.err.println("recent build improvements including library projects."); - System.err.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n"); - System.err.println("A command line tool to package an Android application from various sources."); - System.err.println("Usage: apkbuilder <out archive> [-v][-u][-storetype STORE_TYPE] [-z inputzip]"); - System.err.println(" [-f inputfile] [-rf input-folder] [-rj -input-path]"); - System.err.println(""); - System.err.println(" -v Verbose."); - System.err.println(" -d Debug Mode: Includes debug files in the APK file."); - System.err.println(" -u Creates an unsigned package."); - System.err.println(" -storetype Forces the KeyStore type. If ommited the default is used."); - System.err.println(""); - System.err.println(" -z Followed by the path to a zip archive."); - System.err.println(" Adds the content of the application package."); - System.err.println(""); - System.err.println(" -f Followed by the path to a file."); - System.err.println(" Adds the file to the application package."); - System.err.println(""); - System.err.println(" -rf Followed by the path to a source folder."); - System.err.println(" Adds the java resources found in that folder to the application"); - System.err.println(" package, while keeping their path relative to the source folder."); - System.err.println(""); - System.err.println(" -rj Followed by the path to a jar file or a folder containing"); - System.err.println(" jar files."); - System.err.println(" Adds the java resources found in the jar file(s) to the application"); - System.err.println(" package."); - System.err.println(""); - System.err.println(" -nf Followed by the root folder containing native libraries to"); - System.err.println(" include in the application package."); - - System.exit(1); - } - - private static void printAndExit(String... messages) { - for (String message : messages) { - System.err.println(message); - } - System.exit(1); - } - - private ApkBuilderMain() { - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkCreationException.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkCreationException.java deleted file mode 100644 index 2379915..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/ApkCreationException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.build; - -/** - * An exception thrown during packaging of an APK file. - */ -public final class ApkCreationException extends Exception { - private static final long serialVersionUID = 1L; - - public ApkCreationException(String format, Object... args) { - super(String.format(format, args)); - } - - public ApkCreationException(Throwable cause, String format, Object... args) { - super(String.format(format, args), cause); - } - - public ApkCreationException(Throwable cause) { - super(cause); - } -}
\ No newline at end of file diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/DuplicateFileException.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/DuplicateFileException.java deleted file mode 100644 index ba53ba3..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/DuplicateFileException.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.build; - -import com.android.sdklib.internal.build.SignedJarBuilder.IZipEntryFilter.ZipAbortException; - -import java.io.File; - -/** - * An exception thrown during packaging of an APK file. - */ -public final class DuplicateFileException extends ZipAbortException { - private static final long serialVersionUID = 1L; - private final String mArchivePath; - private final File mFile1; - private final File mFile2; - - public DuplicateFileException(String archivePath, File file1, File file2) { - super(); - mArchivePath = archivePath; - mFile1 = file1; - mFile2 = file2; - } - - public String getArchivePath() { - return mArchivePath; - } - - public File getFile1() { - return mFile1; - } - - public File getFile2() { - return mFile2; - } - - @Override - public String getMessage() { - return "Duplicate files at the same path inside the APK"; - } -}
\ No newline at end of file diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/IArchiveBuilder.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/IArchiveBuilder.java deleted file mode 100644 index e2230e9..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/IArchiveBuilder.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.build; - -import java.io.File; - -public interface IArchiveBuilder { - - /** - * Adds a file to the archive at a given path - * @param file the file to add - * @param archivePath the path of the file inside the APK archive. - * @throws ApkCreationException if an error occurred - * @throws SealedApkException if the APK is already sealed. - * @throws DuplicateFileException if a file conflicts with another already added to the APK - * at the same location inside the APK archive. - */ - void addFile(File file, String archivePath) throws ApkCreationException, - SealedApkException, DuplicateFileException; - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java deleted file mode 100644 index 4d1dcdb..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/JarListSanitizer.java +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.build; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.PrintStream; -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Formatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A Class to handle a list of jar files, finding and removing duplicates. - * - * Right now duplicates are based on: - * - same filename - * - same length - * - same content: using sha1 comparison. - * - * The length/sha1 are kept in a cache and only updated if the library is changed. - */ -public class JarListSanitizer { - - private static final byte[] sBuffer = new byte[4096]; - private static final String CACHE_FILENAME = "jarlist.cache"; - private static final Pattern READ_PATTERN = Pattern.compile("^(\\d+) (\\d+) ([0-9a-f]+) (.+)$"); - - /** - * Simple class holding the data regarding a jar dependency. - * - */ - private static final class JarEntity { - private final File mFile; - private final long mLastModified; - private long mLength; - private String mSha1; - - /** - * Creates an entity from cached data. - * @param path the file path - * @param lastModified when it was last modified - * @param length its length - * @param sha1 its sha1 - */ - private JarEntity(String path, long lastModified, long length, String sha1) { - mFile = new File(path); - mLastModified = lastModified; - mLength = length; - mSha1 = sha1; - } - - /** - * Creates an entity from a {@link File}. - * @param file the file. - */ - private JarEntity(File file) { - mFile = file; - mLastModified = file.lastModified(); - mLength = file.length(); - } - - /** - * Checks whether the {@link File#lastModified()} matches the cached value. If not, length - * is updated and the sha1 is reset (but not recomputed, this is done on demand). - * @return return whether the file was changed. - */ - private boolean checkValidity() { - if (mLastModified != mFile.lastModified()) { - mLength = mFile.length(); - mSha1 = null; - return true; - } - - return false; - } - - private File getFile() { - return mFile; - } - - private long getLastModified() { - return mLastModified; - } - - private long getLength() { - return mLength; - } - - /** - * Returns the file's sha1, computing it if necessary. - * @return the sha1 - * @throws Sha1Exception - */ - private String getSha1() throws Sha1Exception { - if (mSha1 == null) { - mSha1 = JarListSanitizer.getSha1(mFile); - } - return mSha1; - } - - private boolean hasSha1() { - return mSha1 != null; - } - } - - /** - * Exception used to indicate the sanitized list of jar dependency cannot be computed due - * to inconsistency in duplicate jar files. - */ - public static final class DifferentLibException extends Exception { - private static final long serialVersionUID = 1L; - private final String[] mDetails; - - public DifferentLibException(String message, String[] details) { - super(message); - mDetails = details; - } - - public String[] getDetails() { - return mDetails; - } - } - - /** - * Exception to indicate a failure to check a jar file's content. - */ - public static final class Sha1Exception extends Exception { - private static final long serialVersionUID = 1L; - private final File mJarFile; - - public Sha1Exception(File jarFile, Throwable cause) { - super(cause); - mJarFile = jarFile; - } - - public File getJarFile() { - return mJarFile; - } - } - - private final File mOut; - private final PrintStream mOutStream; - - /** - * Creates a sanitizer. - * @param out the project output where the cache is to be stored. - */ - public JarListSanitizer(File out) { - mOut = out; - mOutStream = System.out; - } - - public JarListSanitizer(File out, PrintStream outStream) { - mOut = out; - mOutStream = outStream; - } - - /** - * Sanitize a given list of files - * @param files the list to sanitize - * @return a new list containing no duplicates. - * @throws DifferentLibException - * @throws Sha1Exception - */ - public List<File> sanitize(Collection<File> files) throws DifferentLibException, Sha1Exception { - List<File> results = new ArrayList<File>(); - - // get the cache list. - Map<String, JarEntity> jarList = getCachedJarList(); - - boolean updateJarList = false; - - // clean it up of removed files. - // use results as a temp storage to store the files to remove as we go through the map. - for (JarEntity entity : jarList.values()) { - if (entity.getFile().exists() == false) { - results.add(entity.getFile()); - } - } - - // the actual clean up. - if (results.size() > 0) { - for (File f : results) { - jarList.remove(f.getAbsolutePath()); - } - - results.clear(); - updateJarList = true; - } - - Map<String, List<JarEntity>> nameMap = new HashMap<String, List<JarEntity>>(); - - // update the current jar list if needed, while building a 2ndary map based on - // filename only. - for (File file : files) { - String path = file.getAbsolutePath(); - JarEntity entity = jarList.get(path); - - if (entity == null) { - entity = new JarEntity(file); - jarList.put(path, entity); - updateJarList = true; - } else { - updateJarList |= entity.checkValidity(); - } - - String filename = file.getName(); - List<JarEntity> nameList = nameMap.get(filename); - if (nameList == null) { - nameList = new ArrayList<JarEntity>(); - nameMap.put(filename, nameList); - } - nameList.add(entity); - } - - try { - // now look for dups. Each name list can have more than one file but they must - // have the same size/sha1 - for (Entry<String, List<JarEntity>> entry : nameMap.entrySet()) { - List<JarEntity> list = entry.getValue(); - checkEntities(entry.getKey(), list); - - // if we are here, there's no issue. Add the first of the list to the results. - results.add(list.get(0).getFile()); - } - - // special case for android-support-v4/13 - checkSupportLibs(nameMap, results); - } finally { - if (updateJarList) { - writeJarList(nameMap); - } - } - - return results; - } - - /** - * Checks whether a given list of duplicates can be replaced by a single one. - * @param filename the filename of the files - * @param list the list of dup files - * @throws DifferentLibException - * @throws Sha1Exception - */ - private void checkEntities(String filename, List<JarEntity> list) - throws DifferentLibException, Sha1Exception { - if (list.size() == 1) { - return; - } - - JarEntity baseEntity = list.get(0); - long baseLength = baseEntity.getLength(); - String baseSha1 = baseEntity.getSha1(); - - final int count = list.size(); - for (int i = 1; i < count ; i++) { - JarEntity entity = list.get(i); - if (entity.getLength() != baseLength || entity.getSha1().equals(baseSha1) == false) { - throw new DifferentLibException("Jar mismatch! Fix your dependencies", - getEntityDetails(filename, list)); - } - - } - } - - /** - * Checks for present of both support libraries in v4 and v13. If both are detected, - * v4 is removed from <var>results</var> - * @param nameMap the list of jar as a map of (filename, list of files). - * @param results the current list of jar file set to be used. it's already been cleaned of - * duplicates. - */ - private void checkSupportLibs(Map<String, List<JarEntity>> nameMap, List<File> results) { - List<JarEntity> v4 = nameMap.get("android-support-v4.jar"); - List<JarEntity> v13 = nameMap.get("android-support-v13.jar"); - - if (v13 != null && v4 != null) { - mOutStream.println("WARNING: Found both android-support-v4 and android-support-v13 in the dependency list."); - mOutStream.println("Because v13 includes v4, using only v13."); - results.remove(v4.get(0).getFile()); - } - } - - private Map<String, JarEntity> getCachedJarList() { - Map<String, JarEntity> cache = new HashMap<String, JarListSanitizer.JarEntity>(); - - File cacheFile = new File(mOut, CACHE_FILENAME); - if (cacheFile.exists() == false) { - return cache; - } - - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(cacheFile), - "UTF-8")); - - String line = null; - while ((line = reader.readLine()) != null) { - // skip comments - if (line.charAt(0) == '#') { - continue; - } - - // get the data with a regexp - Matcher m = READ_PATTERN.matcher(line); - if (m.matches()) { - String path = m.group(4); - - JarEntity entity = new JarEntity( - path, - Long.parseLong(m.group(1)), - Long.parseLong(m.group(2)), - m.group(3)); - - cache.put(path, entity); - } - } - - } catch (FileNotFoundException e) { - // won't happen, we check up front. - } catch (UnsupportedEncodingException e) { - // shouldn't happen, but if it does, we just won't have a cache. - } catch (IOException e) { - // shouldn't happen, but if it does, we just won't have a cache. - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - } - } - } - - return cache; - } - - private void writeJarList(Map<String, List<JarEntity>> nameMap) { - File cacheFile = new File(mOut, CACHE_FILENAME); - OutputStreamWriter writer = null; - try { - writer = new OutputStreamWriter( - new FileOutputStream(cacheFile), "UTF-8"); - - writer.write("# cache for current jar dependecy. DO NOT EDIT.\n"); - writer.write("# format is <lastModified> <length> <SHA-1> <path>\n"); - writer.write("# Encoding is UTF-8\n"); - - for (List<JarEntity> list : nameMap.values()) { - // clean up the list of files that don't have a sha1. - for (int i = 0 ; i < list.size() ; ) { - JarEntity entity = list.get(i); - if (entity.hasSha1()) { - i++; - } else { - list.remove(i); - } - } - - if (list.size() > 1) { - for (JarEntity entity : list) { - writer.write(String.format("%d %d %s %s\n", - entity.getLastModified(), - entity.getLength(), - entity.getSha1(), - entity.getFile().getAbsolutePath())); - } - } - } - } catch (IOException e) { - mOutStream.println("WARNING: unable to write jarlist cache file " + - cacheFile.getAbsolutePath()); - } catch (Sha1Exception e) { - // shouldn't happen here since we check that the sha1 is present first, meaning it's - // already been computing. - } finally { - if (writer != null) { - try { - writer.close(); - } catch (IOException e) { - } - } - } - } - - private String[] getEntityDetails(String filename, List<JarEntity> list) throws Sha1Exception { - ArrayList<String> result = new ArrayList<String>(); - result.add( - String.format("Found %d versions of %s in the dependency list,", - list.size(), filename)); - result.add("but not all the versions are identical (check is based on SHA-1 only at this time)."); - result.add("All versions of the libraries must be the same at this time."); - result.add("Versions found are:"); - for (JarEntity entity : list) { - result.add("Path: " + entity.getFile().getAbsolutePath()); - result.add("\tLength: " + entity.getLength()); - result.add("\tSHA-1: " + entity.getSha1()); - } - - return result.toArray(new String[result.size()]); - } - - /** - * Computes the sha1 of a file and returns it. - * @param f the file to compute the sha1 for. - * @return the sha1 value - * @throws Sha1Exception if the sha1 value cannot be computed. - */ - private static String getSha1(File f) throws Sha1Exception { - synchronized (sBuffer) { - FileInputStream fis = null; - try { - MessageDigest md = MessageDigest.getInstance("SHA-1"); - - fis = new FileInputStream(f); - while (true) { - int length = fis.read(sBuffer); - if (length > 0) { - md.update(sBuffer, 0, length); - } else { - break; - } - } - - return byteArray2Hex(md.digest()); - - } catch (Exception e) { - throw new Sha1Exception(f, e); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - // ignore - } - } - } - } - } - - private static String byteArray2Hex(final byte[] hash) { - Formatter formatter = new Formatter(); - try { - for (byte b : hash) { - formatter.format("%02x", b); - } - return formatter.toString(); - } finally { - formatter.close(); - } - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/SealedApkException.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/build/SealedApkException.java deleted file mode 100644 index 97f03bd..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/build/SealedApkException.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.build; - -/** - * An exception thrown when trying to add files to a sealed APK. - */ -public final class SealedApkException extends Exception { - private static final long serialVersionUID = 1L; - - public SealedApkException(String format, Object... args) { - super(String.format(format, args)); - } - - public SealedApkException(Throwable cause, String format, Object... args) { - super(String.format(format, args), cause); - } - - public SealedApkException(Throwable cause) { - super(cause); - } -}
\ No newline at end of file diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Abi.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Abi.java deleted file mode 100644 index 080ae75..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Abi.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.SdkConstants; - -public enum Abi { - ARMEABI(SdkConstants.ABI_ARMEABI), - ARMEABI_V7A(SdkConstants.ABI_ARMEABI_V7A), - X86(SdkConstants.ABI_INTEL_ATOM), - MIPS(SdkConstants.ABI_MIPS); - - private final String mValue; - - private Abi(String value) { - mValue = value; - } - - public static Abi getEnum(String value) { - for (Abi a : values()) { - if (a.mValue.equals(value)) { - return a; - } - } - return null; - } - - @Override - public String toString() { - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/BluetoothProfile.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/BluetoothProfile.java deleted file mode 100644 index 536dcd8..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/BluetoothProfile.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum BluetoothProfile { - A2DP("A2DP"), - ATT("ATT"), - AVRCP("AVRCP"), - AVDTP("AVDTP"), - BIP("BIP"), - BPP("BPP"), - CIP("CIP"), - CTP("CTP"), - DIP("DIP"), - DUN("DUN"), - FAX("FAX"), - FTP("FTP"), - GAVDP("GAVDP"), - GAP("GAP"), - GATT("GATT"), - GOEP("GOEP"), - HCRP("HCRP"), - HDP("HDP"), - HFP("HFP"), - HID("HID"), - HSP("HSP"), - ICP("ICP"), - LAP("LAP"), - MAP("MAP"), - OPP("OPP"), - PAN("PAN"), - PBA("PBA"), - PBAP("PBAP"), - SPP("SPP"), - SDAP("SDAP"), - SAP("SAP"), - SIM("SIM"), - rSAP("rSAP"), - SYNCH("SYNCH"), - VDP("VDP"), - WAPB("WAPB"); - - - private final String mValue; - - private BluetoothProfile(String value) { - mValue = value; - } - - public static BluetoothProfile getEnum(String value) { - for (BluetoothProfile bp : values()) { - if (bp.mValue.equals(value)) { - return bp; - } - } - return null; - } - - @Override - public String toString() { - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/ButtonType.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/ButtonType.java deleted file mode 100644 index 6ab67d4..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/ButtonType.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum ButtonType { - HARD("hard"), - SOFT("soft"); - - private final String mValue; - - private ButtonType(String value) { - mValue = value; - } - - public static ButtonType getEnum(String value) { - for (ButtonType n : values()) { - if (n.mValue.equals(value)) { - return n; - } - } - return null; - } - - @Override - public String toString() { - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Camera.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Camera.java deleted file mode 100644 index d7d33fe..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Camera.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public class Camera { - private CameraLocation mLocation; - private boolean mAutofocus; - private boolean mFlash; - - /** - * Creates a {@link Camera} with reasonable defaults. - * - * The resulting {@link Camera} with be on the {@link CameraLocation#BACK} with both autofocus - * and flash. - */ - public Camera() { - this(CameraLocation.BACK, true, true); - } - - /** - * Creates a new {@link Camera} which describes an on device camera and it's features. - * @param location The location of the {@link Camera} on the device. Either - * {@link CameraLocation#FRONT} or {@link CameraLocation#BACK}. - * @param autofocus Whether the {@link Camera} can auto-focus. - * @param flash Whether the {@link Camera} has flash. - */ - public Camera(CameraLocation location, boolean autofocus, boolean flash) { - mLocation = location; - mAutofocus = autofocus; - mFlash = flash; - } - - public CameraLocation getLocation() { - return mLocation; - } - - public void setLocation(CameraLocation cl) { - mLocation = cl; - } - - public boolean hasAutofocus() { - return mAutofocus; - } - - public void setAutofocus(boolean hasAutofocus) { - mAutofocus = hasAutofocus; - } - - public boolean hasFlash() { - return mFlash; - } - - public void setFlash(boolean flash) { - mFlash = flash; - } - - /** - * Returns a copy of the object that shares no state with it, - * but is initialized to equivalent values. - * - * @return A copy of the object. - */ - public Camera deepCopy() { - Camera c = new Camera(); - c.mLocation = mLocation; - c.mAutofocus = mAutofocus; - c.mFlash = mFlash; - return c; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Camera)) { - return false; - } - Camera c = (Camera) o; - return mLocation == c.mLocation - && mAutofocus == c.hasAutofocus() - && mFlash == c.hasFlash(); - } - - @Override - public int hashCode() { - int hash = 17; - hash = 31 * hash + mLocation.ordinal(); - hash = 31 * hash + (mAutofocus ? 1 : 0); - hash = 31 * hash + (mFlash ? 1 : 0); - return hash; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/CameraLocation.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/CameraLocation.java deleted file mode 100644 index 9a8554d..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/CameraLocation.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum CameraLocation { - FRONT("front"), - BACK("back"); - - private final String mValue; - - private CameraLocation(String value) { - mValue = value; - } - - public static CameraLocation getEnum(String value) { - for (CameraLocation l : values()) { - if (l.mValue.equals(value)) { - return l; - } - } - return null; - } - - @Override - public String toString() { - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Device.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Device.java deleted file mode 100644 index cb712f0..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Device.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.dvlib.DeviceSchema; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -/** - * Instances of this class contain the specifications for a device. Use the - * {@link Builder} class to construct a Device object, or the - * {@link DeviceParser} if constructing device objects from XML conforming to - * the {@link DeviceSchema} standards. - */ -public final class Device { - /** Name of the device */ - private final String mName; - /** Manufacturer of the device */ - private final String mManufacturer; - /** A list of software capabilities, one for each API level range */ - private final List<Software> mSoftware; - /** A list of phone states (landscape, portrait with keyboard out, etc.) */ - private final List<State> mState; - /** Meta information such as icon files and device frames */ - private final Meta mMeta; - /** Default state of the device */ - private final State mDefaultState; - - /** - * Returns the name of the {@link Device}. - * - * @return The name of the {@link Device}. - */ - public String getName() { - return mName; - } - - /** - * Returns the manufacturer of the {@link Device}. - * - * @return The name of the manufacturer of the {@link Device}. - */ - public String getManufacturer() { - return mManufacturer; - } - - /** - * Returns all of the {@link Software} configurations of the {@link Device}. - * - * @return A list of all the {@link Software} configurations. - */ - public List<Software> getAllSoftware() { - return mSoftware; - } - - /** - * Returns all of the {@link State}s the {@link Device} can be in. - * - * @return A list of all the {@link State}s. - */ - public List<State> getAllStates() { - return mState; - } - - /** - * Returns the default {@link Hardware} configuration for the device. This - * is really just a shortcut for getting the {@link Hardware} on the default - * {@link State} - * - * @return The default {@link Hardware} for the device. - */ - public Hardware getDefaultHardware() { - return mDefaultState.getHardware(); - } - - /** - * Returns the {@link Meta} object for the device, which contains meta - * information about the device, such as the location of icons. - * - * @return The {@link Meta} object for the {@link Device}. - */ - public Meta getMeta() { - return mMeta; - } - - /** - * Returns the default {@link State} of the {@link Device}. - * - * @return The default {@link State} of the {@link Device}. - */ - public State getDefaultState() { - return mDefaultState; - } - - /** - * Returns the software configuration for the given API version. - * - * @param apiVersion - * The API version requested. - * @return The Software instance for the requested API version or null if - * the API version is unsupported for this device. - */ - public Software getSoftware(int apiVersion) { - for (Software s : mSoftware) { - if (apiVersion >= s.getMinSdkLevel() && apiVersion <= s.getMaxSdkLevel()) { - return s; - } - } - return null; - } - - /** - * Returns the state of the device with the given name. - * - * @param name - * The name of the state requested. - * @return The State object requested or null if there's no state with the - * given name. - */ - public State getState(String name) { - for (State s : getAllStates()) { - if (s.getName().equals(name)) { - return s; - } - } - return null; - } - - public static class Builder { - private String mName; - private String mManufacturer; - private final List<Software> mSoftware = new ArrayList<Software>(); - private final List<State> mState = new ArrayList<State>(); - private Meta mMeta; - private State mDefaultState; - - public Builder() { } - - public Builder(Device d) { - mName = d.getName(); - mManufacturer = d.getManufacturer(); - for (Software s : d.getAllSoftware()) { - mSoftware.add(s.deepCopy()); - } - for (State s : d.getAllStates()) { - mState.add(s.deepCopy()); - } - mSoftware.addAll(d.getAllSoftware()); - mState.addAll(d.getAllStates()); - mMeta = d.getMeta(); - mDefaultState = d.getDefaultState(); - } - - public void setName(String name) { - mName = name; - } - - public void setManufacturer(String manufacturer) { - mManufacturer = manufacturer; - } - - public void addSoftware(Software sw) { - mSoftware.add(sw); - } - - public void addAllSoftware(Collection<? extends Software> sw) { - mSoftware.addAll(sw); - } - - public void addState(State state) { - mState.add(state); - } - - public void addAllState(Collection<? extends State> states) { - mState.addAll(states); - } - - /** - * Removes the first {@link State} with the given name - * @param stateName The name of the {@link State} to remove. - * @return Whether a {@link State} was removed or not. - */ - public boolean removeState(String stateName) { - for (int i = 0; i < mState.size(); i++) { - if (stateName != null && stateName.equals(mState.get(i).getName())) { - mState.remove(i); - return true; - } - } - return false; - } - - public void setMeta(Meta meta) { - mMeta = meta; - } - - public Device build() { - if (mSoftware.size() <= 0) { - throw generateBuildException("Device software not configured"); - } else if (mState.size() <= 0) { - throw generateBuildException("Device states not configured"); - } - - if (mMeta == null) { - mMeta = new Meta(); - } - for (State s : mState) { - if (s.isDefaultState()) { - mDefaultState = s; - break; - } - } - return new Device(this); - } - - private IllegalStateException generateBuildException(String err) { - String device = ""; - if (mManufacturer != null) { - device = mManufacturer + " "; - } - if (mName != null) { - device += mName; - } else { - device = "Unknown " + device +"Device"; - } - - return new IllegalStateException("Error building " + device + ": " +err); - } - } - - protected Device(Builder b) { - mName = b.mName; - mManufacturer = b.mManufacturer; - mSoftware = Collections.unmodifiableList(b.mSoftware); - mState = Collections.unmodifiableList(b.mState); - mMeta = b.mMeta; - mDefaultState = b.mDefaultState; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Device)) { - return false; - } - Device d = (Device) o; - return mName.equals(d.getName()) - && mManufacturer.equals(d.getManufacturer()) - && mSoftware.equals(d.getAllSoftware()) - && mState.equals(d.getAllStates()) - && mMeta.equals(d.getMeta()) - && mDefaultState.equals(d.getDefaultState()); - } - - @Override - /** A hash that's stable across JVM instances */ - public int hashCode() { - int hash = 17; - for (Character c : mName.toCharArray()) { - hash = 31 * hash + c; - } - for (Character c : mManufacturer.toCharArray()) { - hash = 31 * hash + c; - } - hash = 31 * hash + mSoftware.hashCode(); - hash = 31 * hash + mState.hashCode(); - hash = 31 * hash + mMeta.hashCode(); - hash = 31 * hash + mDefaultState.hashCode(); - return hash; - } - - @Override - public String toString() { - return mName; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceManager.java deleted file mode 100644 index 3662c26..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceManager.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.SdkConstants; -import com.android.annotations.Nullable; -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.resources.Keyboard; -import com.android.resources.KeyboardState; -import com.android.resources.Navigation; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.avd.HardwareProperties; -import com.android.sdklib.repository.PkgProps; -import com.android.utils.ILogger; - -import org.xml.sax.SAXException; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactoryConfigurationError; - -/** - * Manager class for interacting with {@link Device}s within the SDK - */ -public class DeviceManager { - - private final static String sDeviceProfilesProp = "DeviceProfiles"; - private final static Pattern sPathPropertyPattern = Pattern.compile("^" + PkgProps.EXTRA_PATH - + "=" + sDeviceProfilesProp + "$"); - private ILogger mLog; - // Vendor devices can't be a static list since they change based on the SDK - // Location - private List<Device> mVendorDevices; - // Keeps track of where the currently loaded vendor devices were loaded from - private String mVendorDevicesLocation = ""; - private static List<Device> mUserDevices; - private static List<Device> mDefaultDevices; - private static final Object sLock = new Object(); - private static final List<DevicesChangeListener> sListeners = - new ArrayList<DevicesChangeListener>(); - - public static enum DeviceStatus { - /** - * The device exists unchanged from the given configuration - */ - EXISTS, - /** - * A device exists with the given name and manufacturer, but has a different configuration - */ - CHANGED, - /** - * There is no device with the given name and manufacturer - */ - MISSING; - } - - // TODO: Refactor this to look more like AvdManager so that we don't have - // multiple instances in the same application, which forces us to parse - // the XML multiple times when we don't have to. - public DeviceManager(ILogger log) { - mLog = log; - } - - /** - * Interface implemented by objects which want to know when changes occur to the {@link Device} - * lists. - */ - public static interface DevicesChangeListener { - /** - * Called after one of the {@link Device} lists has been updated. - */ - public void onDevicesChange(); - } - - /** - * Register a listener to be notified when the device lists are modified. - * - * @param listener The listener to add. Ignored if already registered. - */ - public void registerListener(DevicesChangeListener listener) { - if (listener != null) { - synchronized (sListeners) { - if (!sListeners.contains(listener)) { - sListeners.add(listener); - } - } - } - } - - /** - * Removes a listener from the notification list such that it will no longer receive - * notifications when modifications to the {@link Device} list occur. - * - * @param listener The listener to remove. - */ - public boolean unregisterListener(DevicesChangeListener listener) { - synchronized (sListeners) { - return sListeners.remove(listener); - } - } - - public DeviceStatus getDeviceStatus( - @Nullable String sdkLocation, String name, String manufacturer, int hashCode) { - Device d = getDevice(sdkLocation, name, manufacturer); - if (d == null) { - return DeviceStatus.MISSING; - } else { - return d.hashCode() == hashCode ? DeviceStatus.EXISTS : DeviceStatus.CHANGED; - } - } - - public Device getDevice(@Nullable String sdkLocation, String name, String manufacturer) { - List<Device> devices; - if (sdkLocation != null) { - devices = getDevices(sdkLocation); - } else { - devices = new ArrayList<Device>(getDefaultDevices()); - devices.addAll(getUserDevices()); - } - for (Device d : devices) { - if (d.getName().equals(name) && d.getManufacturer().equals(manufacturer)) { - return d; - } - } - return null; - } - - /** - * Returns both vendor provided and user created {@link Device}s. - * - * @param sdkLocation Location of the Android SDK - * @return A list of both vendor and user provided {@link Device}s - */ - public List<Device> getDevices(String sdkLocation) { - List<Device> devices = new ArrayList<Device>(getVendorDevices(sdkLocation)); - devices.addAll(getDefaultDevices()); - devices.addAll(getUserDevices()); - return Collections.unmodifiableList(devices); - } - - /** - * Gets the {@link List} of {@link Device}s packaged with the SDK. - * - * @return The {@link List} of default {@link Device}s - */ - public List<Device> getDefaultDevices() { - synchronized (sLock) { - if (mDefaultDevices == null) { - try { - mDefaultDevices = DeviceParser.parse( - DeviceManager.class.getResourceAsStream(SdkConstants.FN_DEVICES_XML)); - } catch (IllegalStateException e) { - // The device builders can throw IllegalStateExceptions if - // build gets called before everything is properly setup - mLog.error(e, null); - mDefaultDevices = new ArrayList<Device>(); - } catch (Exception e) { - mLog.error(null, "Error reading default devices"); - mDefaultDevices = new ArrayList<Device>(); - } - notifyListeners(); - } - } - return Collections.unmodifiableList(mDefaultDevices); - } - - /** - * Returns all vendor-provided {@link Device}s - * - * @param sdkLocation Location of the Android SDK - * @return A list of vendor-provided {@link Device}s - */ - public List<Device> getVendorDevices(String sdkLocation) { - synchronized (sLock) { - if (mVendorDevices == null || !mVendorDevicesLocation.equals(sdkLocation)) { - mVendorDevicesLocation = sdkLocation; - List<Device> devices = new ArrayList<Device>(); - - // Load devices from tools folder - File toolsDevices = new File(sdkLocation, SdkConstants.OS_SDK_TOOLS_LIB_FOLDER + - File.separator + SdkConstants.FN_DEVICES_XML); - if (toolsDevices.isFile()) { - devices.addAll(loadDevices(toolsDevices)); - } - - // Load devices from vendor extras - File extrasFolder = new File(sdkLocation, SdkConstants.FD_EXTRAS); - List<File> deviceDirs = getExtraDirs(extrasFolder); - for (File deviceDir : deviceDirs) { - File deviceXml = new File(deviceDir, SdkConstants.FN_DEVICES_XML); - if (deviceXml.isFile()) { - devices.addAll(loadDevices(deviceXml)); - } - } - mVendorDevices = devices; - notifyListeners(); - } - } - return Collections.unmodifiableList(mVendorDevices); - } - - /** - * Returns all user-created {@link Device}s - * - * @return All user-created {@link Device}s - */ - public List<Device> getUserDevices() { - synchronized (sLock) { - if (mUserDevices == null) { - // User devices should be saved out to - // $HOME/.android/devices.xml - mUserDevices = new ArrayList<Device>(); - File userDevicesFile = null; - try { - userDevicesFile = new File(AndroidLocation.getFolder(), - SdkConstants.FN_DEVICES_XML); - if (userDevicesFile.exists()) { - mUserDevices.addAll(DeviceParser.parse(userDevicesFile)); - notifyListeners(); - } - } catch (AndroidLocationException e) { - mLog.warning("Couldn't load user devices: %1$s", e.getMessage()); - } catch (SAXException e) { - // Probably an old config file which we don't want to overwrite. - if (userDevicesFile != null) { - String base = userDevicesFile.getAbsoluteFile() + ".old"; - File renamedConfig = new File(base); - int i = 0; - while (renamedConfig.exists()) { - renamedConfig = new File(base + '.' + (i++)); - } - mLog.error(null, "Error parsing %1$s, backing up to %2$s", - userDevicesFile.getAbsolutePath(), renamedConfig.getAbsolutePath()); - userDevicesFile.renameTo(renamedConfig); - } - } catch (ParserConfigurationException e) { - mLog.error(null, "Error parsing %1$s", - userDevicesFile == null ? "(null)" : userDevicesFile.getAbsolutePath()); - } catch (IOException e) { - mLog.error(null, "Error parsing %1$s", - userDevicesFile == null ? "(null)" : userDevicesFile.getAbsolutePath()); - } - } - } - return Collections.unmodifiableList(mUserDevices); - } - - public void addUserDevice(Device d) { - synchronized (sLock) { - if (mUserDevices == null) { - getUserDevices(); - } - mUserDevices.add(d); - } - notifyListeners(); - } - - public void removeUserDevice(Device d) { - synchronized (sLock) { - if (mUserDevices == null) { - getUserDevices(); - } - Iterator<Device> it = mUserDevices.iterator(); - while (it.hasNext()) { - Device userDevice = it.next(); - if (userDevice.getName().equals(d.getName()) - && userDevice.getManufacturer().equals(d.getManufacturer())) { - it.remove(); - notifyListeners(); - break; - } - - } - } - } - - public void replaceUserDevice(Device d) { - synchronized (sLock) { - if (mUserDevices == null) { - getUserDevices(); - } - removeUserDevice(d); - addUserDevice(d); - } - } - - /** - * Saves out the user devices to {@link SdkConstants#FN_DEVICES_XML} in - * {@link AndroidLocation#getFolder()}. - */ - public void saveUserDevices() { - synchronized (sLock) { - if (mUserDevices != null && mUserDevices.size() != 0) { - File userDevicesFile; - try { - userDevicesFile = new File(AndroidLocation.getFolder(), - SdkConstants.FN_DEVICES_XML); - DeviceWriter.writeToXml(new FileOutputStream(userDevicesFile), mUserDevices); - } catch (AndroidLocationException e) { - mLog.warning("Couldn't find user directory: %1$s", e.getMessage()); - } catch (FileNotFoundException e) { - mLog.warning("Couldn't open file: %1$s", e.getMessage()); - } catch (ParserConfigurationException e) { - mLog.warning("Error writing file: %1$s", e.getMessage()); - } catch (TransformerFactoryConfigurationError e) { - mLog.warning("Error writing file: %1$s", e.getMessage()); - } catch (TransformerException e) { - mLog.warning("Error writing file: %1$s", e.getMessage()); - } - } - } - } - - /** - * Returns hardware properties (defined in hardware.ini) as a {@link Map}. - * - * @param s The {@link State} from which to derive the hardware properties. - * @return A {@link Map} of hardware properties. - */ - public static Map<String, String> getHardwareProperties(State s) { - Hardware hw = s.getHardware(); - Map<String, String> props = new HashMap<String, String>(); - props.put(HardwareProperties.HW_MAINKEYS, - getBooleanVal(hw.getButtonType().equals(ButtonType.HARD))); - props.put(HardwareProperties.HW_TRACKBALL, - getBooleanVal(hw.getNav().equals(Navigation.TRACKBALL))); - props.put(HardwareProperties.HW_KEYBOARD, - getBooleanVal(hw.getKeyboard().equals(Keyboard.QWERTY))); - props.put(HardwareProperties.HW_DPAD, - getBooleanVal(hw.getNav().equals(Navigation.DPAD))); - - Set<Sensor> sensors = hw.getSensors(); - props.put(HardwareProperties.HW_GPS, getBooleanVal(sensors.contains(Sensor.GPS))); - props.put(HardwareProperties.HW_BATTERY, - getBooleanVal(hw.getChargeType().equals(PowerType.BATTERY))); - props.put(HardwareProperties.HW_ACCELEROMETER, - getBooleanVal(sensors.contains(Sensor.ACCELEROMETER))); - props.put(HardwareProperties.HW_ORIENTATION_SENSOR, - getBooleanVal(sensors.contains(Sensor.GYROSCOPE))); - props.put(HardwareProperties.HW_AUDIO_INPUT, getBooleanVal(hw.hasMic())); - props.put(HardwareProperties.HW_SDCARD, getBooleanVal(hw.getRemovableStorage().size() > 0)); - props.put(HardwareProperties.HW_LCD_DENSITY, - Integer.toString(hw.getScreen().getPixelDensity().getDpiValue())); - props.put(HardwareProperties.HW_PROXIMITY_SENSOR, - getBooleanVal(sensors.contains(Sensor.PROXIMITY_SENSOR))); - return props; - } - - /** - * Returns the hardware properties defined in - * {@link AvdManager#HARDWARE_INI} as a {@link Map}. - * - * @param d The {@link Device} from which to derive the hardware properties. - * @return A {@link Map} of hardware properties. - */ - public static Map<String, String> getHardwareProperties(Device d) { - Map<String, String> props = getHardwareProperties(d.getDefaultState()); - for (State s : d.getAllStates()) { - if (s.getKeyState().equals(KeyboardState.HIDDEN)) { - props.put("hw.keyboard.lid", getBooleanVal(true)); - } - } - props.put(AvdManager.AVD_INI_DEVICE_HASH, Integer.toString(d.hashCode())); - props.put(AvdManager.AVD_INI_DEVICE_NAME, d.getName()); - props.put(AvdManager.AVD_INI_DEVICE_MANUFACTURER, d.getManufacturer()); - return props; - } - - /** - * Takes a boolean and returns the appropriate value for - * {@link HardwareProperties} - * - * @param bool The boolean value to turn into the appropriate - * {@link HardwareProperties} value. - * @return {@code HardwareProperties#BOOLEAN_VALUES[0]} if true, - * {@code HardwareProperties#BOOLEAN_VALUES[1]} otherwise. - */ - private static String getBooleanVal(boolean bool) { - if (bool) { - return HardwareProperties.BOOLEAN_VALUES[0]; - } - return HardwareProperties.BOOLEAN_VALUES[1]; - } - - private Collection<Device> loadDevices(File deviceXml) { - try { - return DeviceParser.parse(deviceXml); - } catch (SAXException e) { - mLog.error(null, "Error parsing %1$s", deviceXml.getAbsolutePath()); - } catch (ParserConfigurationException e) { - mLog.error(null, "Error parsing %1$s", deviceXml.getAbsolutePath()); - } catch (IOException e) { - mLog.error(null, "Error reading %1$s", deviceXml.getAbsolutePath()); - } catch (IllegalStateException e) { - // The device builders can throw IllegalStateExceptions if - // build gets called before everything is properly setup - mLog.error(e, null); - } - return new ArrayList<Device>(); - } - - private void notifyListeners() { - synchronized (sListeners) { - for (DevicesChangeListener listener : sListeners) { - listener.onDevicesChange(); - } - } - } - - /* Returns all of DeviceProfiles in the extras/ folder */ - private List<File> getExtraDirs(File extrasFolder) { - List<File> extraDirs = new ArrayList<File>(); - // All OEM provided device profiles are in - // $SDK/extras/$VENDOR/$ITEM/devices.xml - if (extrasFolder != null && extrasFolder.isDirectory()) { - for (File vendor : extrasFolder.listFiles()) { - if (vendor.isDirectory()) { - for (File item : vendor.listFiles()) { - if (item.isDirectory() && isDevicesExtra(item)) { - extraDirs.add(item); - } - } - } - } - } - - return extraDirs; - } - - /* - * Returns whether a specific folder for a specific vendor is a - * DeviceProfiles folder - */ - private boolean isDevicesExtra(File item) { - File properties = new File(item, SdkConstants.FN_SOURCE_PROP); - try { - BufferedReader propertiesReader = new BufferedReader(new FileReader(properties)); - try { - String line; - while ((line = propertiesReader.readLine()) != null) { - Matcher m = sPathPropertyPattern.matcher(line); - if (m.matches()) { - return true; - } - } - } finally { - propertiesReader.close(); - } - } catch (IOException ignore) { - } - return false; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceParser.java deleted file mode 100644 index dd63af2..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceParser.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.annotations.Nullable; -import com.android.dvlib.DeviceSchema; -import com.android.resources.Density; -import com.android.resources.Keyboard; -import com.android.resources.KeyboardState; -import com.android.resources.Navigation; -import com.android.resources.NavigationState; -import com.android.resources.ScreenOrientation; -import com.android.resources.ScreenRatio; -import com.android.resources.ScreenSize; -import com.android.resources.TouchScreen; -import com.android.resources.UiMode; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; -import org.xml.sax.helpers.DefaultHandler; - -import java.awt.Point; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -public class DeviceParser { - - private static class DeviceHandler extends DefaultHandler { - private final static String sSpaceRegex = "[\\s]+"; - private final List<Device> mDevices = new ArrayList<Device>(); - private final StringBuilder mStringAccumulator = new StringBuilder(); - private final File mParentFolder; - private Meta mMeta; - private Hardware mHardware; - private Software mSoftware; - private State mState; - private Device.Builder mBuilder; - private Camera mCamera; - private Storage.Unit mUnit; - - public DeviceHandler(@Nullable File parentFolder) { - mParentFolder = parentFolder; - } - - public List<Device> getDevices() { - return mDevices; - } - - @Override - public void startElement(String uri, String localName, String name, Attributes attributes) - throws SAXException { - - if (DeviceSchema.NODE_DEVICE.equals(localName)) { - // Reset everything - mMeta = null; - mHardware = null; - mSoftware = null; - mState = null; - mCamera = null; - mBuilder = new Device.Builder(); - } else if (DeviceSchema.NODE_META.equals(localName)) { - mMeta = new Meta(); - } else if (DeviceSchema.NODE_HARDWARE.equals(localName)) { - mHardware = new Hardware(); - } else if (DeviceSchema.NODE_SOFTWARE.equals(localName)) { - mSoftware = new Software(); - } else if (DeviceSchema.NODE_STATE.equals(localName)) { - mState = new State(); - // mState can embed a Hardware instance - mHardware = mHardware.deepCopy(); - String defaultState = attributes.getValue(DeviceSchema.ATTR_DEFAULT); - if ("true".equals(defaultState) || "1".equals(defaultState)) { - mState.setDefaultState(true); - } - mState.setName(attributes.getValue(DeviceSchema.ATTR_NAME).trim()); - } else if (DeviceSchema.NODE_CAMERA.equals(localName)) { - mCamera = new Camera(); - } else if (DeviceSchema.NODE_RAM.equals(localName) - || DeviceSchema.NODE_INTERNAL_STORAGE.equals(localName) - || DeviceSchema.NODE_REMOVABLE_STORAGE.equals(localName)) { - mUnit = Storage.Unit.getEnum(attributes.getValue(DeviceSchema.ATTR_UNIT)); - } else if (DeviceSchema.NODE_FRAME.equals(localName)) { - mMeta.setFrameOffsetLandscape(new Point()); - mMeta.setFrameOffsetPortrait(new Point()); - } else if (DeviceSchema.NODE_SCREEN.equals(localName)) { - mHardware.setScreen(new Screen()); - } - mStringAccumulator.setLength(0); - } - - @Override - public void characters(char[] ch, int start, int length) { - mStringAccumulator.append(ch, start, length); - } - - @Override - public void endElement(String uri, String localName, String name) throws SAXException { - if (DeviceSchema.NODE_DEVICE.equals(localName)) { - mDevices.add(mBuilder.build()); - } else if (DeviceSchema.NODE_NAME.equals(localName)) { - mBuilder.setName(getString(mStringAccumulator)); - } else if (DeviceSchema.NODE_MANUFACTURER.equals(localName)) { - mBuilder.setManufacturer(getString(mStringAccumulator)); - } else if (DeviceSchema.NODE_META.equals(localName)) { - mBuilder.setMeta(mMeta); - } else if (DeviceSchema.NODE_SOFTWARE.equals(localName)) { - mBuilder.addSoftware(mSoftware); - } else if (DeviceSchema.NODE_STATE.equals(localName)) { - mState.setHardware(mHardware); - mBuilder.addState(mState); - } else if (DeviceSchema.NODE_SIXTY_FOUR.equals(localName)) { - mMeta.setIconSixtyFour(new File(mParentFolder, getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_SIXTEEN.equals(localName)) { - mMeta.setIconSixteen(new File(mParentFolder, getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_PATH.equals(localName)) { - mMeta.setFrame(new File(mParentFolder, mStringAccumulator.toString().trim())); - } else if (DeviceSchema.NODE_PORTRAIT_X_OFFSET.equals(localName)) { - mMeta.getFrameOffsetPortrait().x = getInteger(mStringAccumulator); - } else if (DeviceSchema.NODE_PORTRAIT_Y_OFFSET.equals(localName)) { - mMeta.getFrameOffsetPortrait().y = getInteger(mStringAccumulator); - } else if (DeviceSchema.NODE_LANDSCAPE_X_OFFSET.equals(localName)) { - mMeta.getFrameOffsetLandscape().x = getInteger(mStringAccumulator); - } else if (DeviceSchema.NODE_LANDSCAPE_Y_OFFSET.equals(localName)) { - mMeta.getFrameOffsetLandscape().y = getInteger(mStringAccumulator); - } else if (DeviceSchema.NODE_SCREEN_SIZE.equals(localName)) { - mHardware.getScreen().setSize(ScreenSize.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_DIAGONAL_LENGTH.equals(localName)) { - mHardware.getScreen().setDiagonalLength(getDouble(mStringAccumulator)); - } else if (DeviceSchema.NODE_PIXEL_DENSITY.equals(localName)) { - mHardware.getScreen().setPixelDensity( - Density.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_SCREEN_RATIO.equals(localName)) { - mHardware.getScreen().setRatio( - ScreenRatio.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_X_DIMENSION.equals(localName)) { - mHardware.getScreen().setXDimension(getInteger(mStringAccumulator)); - } else if (DeviceSchema.NODE_Y_DIMENSION.equals(localName)) { - mHardware.getScreen().setYDimension(getInteger(mStringAccumulator)); - } else if (DeviceSchema.NODE_XDPI.equals(localName)) { - mHardware.getScreen().setXdpi(getDouble(mStringAccumulator)); - } else if (DeviceSchema.NODE_YDPI.equals(localName)) { - mHardware.getScreen().setYdpi(getDouble(mStringAccumulator)); - } else if (DeviceSchema.NODE_MULTITOUCH.equals(localName)) { - mHardware.getScreen().setMultitouch( - Multitouch.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_MECHANISM.equals(localName)) { - mHardware.getScreen().setMechanism( - TouchScreen.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_SCREEN_TYPE.equals(localName)) { - mHardware.getScreen().setScreenType( - ScreenType.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_NETWORKING.equals(localName)) { - for (String n : getStringList(mStringAccumulator)) { - Network net = Network.getEnum(n); - if (net != null) { - mHardware.addNetwork(net); - } - } - } else if (DeviceSchema.NODE_SENSORS.equals(localName)) { - for (String s : getStringList(mStringAccumulator)) { - Sensor sens = Sensor.getEnum(s); - if (sens != null) { - mHardware.addSensor(sens); - } - } - } else if (DeviceSchema.NODE_MIC.equals(localName)) { - mHardware.setHasMic(getBool(mStringAccumulator)); - } else if (DeviceSchema.NODE_CAMERA.equals(localName)) { - mHardware.addCamera(mCamera); - mCamera = null; - } else if (DeviceSchema.NODE_LOCATION.equals(localName)) { - mCamera.setLocation(CameraLocation.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_AUTOFOCUS.equals(localName)) { - mCamera.setFlash(getBool(mStringAccumulator)); - } else if (DeviceSchema.NODE_FLASH.equals(localName)) { - mCamera.setFlash(getBool(mStringAccumulator)); - } else if (DeviceSchema.NODE_KEYBOARD.equals(localName)) { - mHardware.setKeyboard(Keyboard.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_NAV.equals(localName)) { - mHardware.setNav(Navigation.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_RAM.equals(localName)) { - int val = getInteger(mStringAccumulator); - mHardware.setRam(new Storage(val, mUnit)); - } else if (DeviceSchema.NODE_BUTTONS.equals(localName)) { - mHardware.setButtonType(ButtonType.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_INTERNAL_STORAGE.equals(localName)) { - for (String s : getStringList(mStringAccumulator)) { - int val = Integer.parseInt(s); - mHardware.addInternalStorage(new Storage(val, mUnit)); - } - } else if (DeviceSchema.NODE_REMOVABLE_STORAGE.equals(localName)) { - for (String s : getStringList(mStringAccumulator)) { - if (s != null && !s.isEmpty()) { - int val = Integer.parseInt(s); - mHardware.addRemovableStorage(new Storage(val, mUnit)); - } - } - } else if (DeviceSchema.NODE_CPU.equals(localName)) { - mHardware.setCpu(getString(mStringAccumulator)); - } else if (DeviceSchema.NODE_GPU.equals(localName)) { - mHardware.setGpu(getString(mStringAccumulator)); - } else if (DeviceSchema.NODE_ABI.equals(localName)) { - for (String s : getStringList(mStringAccumulator)) { - Abi abi = Abi.getEnum(s); - if (abi != null) { - mHardware.addSupportedAbi(abi); - } - } - } else if (DeviceSchema.NODE_DOCK.equals(localName)) { - for (String s : getStringList(mStringAccumulator)) { - UiMode d = UiMode.getEnum(s); - if (d != null) { - mHardware.addSupportedUiMode(d); - } - } - } else if (DeviceSchema.NODE_POWER_TYPE.equals(localName)) { - mHardware.setChargeType(PowerType.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_API_LEVEL.equals(localName)) { - String val = getString(mStringAccumulator); - // Can be one of 5 forms: - // 1 - // 1-2 - // 1- - // -2 - // - - int index; - if (val.charAt(0) == '-') { - if (val.length() == 1) { // - - mSoftware.setMinSdkLevel(0); - mSoftware.setMaxSdkLevel(Integer.MAX_VALUE); - } else { // -2 - // Remove the front dash and any whitespace between it - // and the upper bound. - val = val.substring(1).trim(); - mSoftware.setMinSdkLevel(0); - mSoftware.setMaxSdkLevel(Integer.parseInt(val)); - } - } else if ((index = val.indexOf('-')) > 0) { - if (index == val.length() - 1) { // 1- - // Strip the last dash and any whitespace between it and - // the lower bound. - val = val.substring(0, val.length() - 1).trim(); - mSoftware.setMinSdkLevel(Integer.parseInt(val)); - mSoftware.setMaxSdkLevel(Integer.MAX_VALUE); - } else { // 1-2 - String min = val.substring(0, index).trim(); - String max = val.substring(index + 1); - mSoftware.setMinSdkLevel(Integer.parseInt(min)); - mSoftware.setMaxSdkLevel(Integer.parseInt(max)); - } - } else { // 1 - int apiLevel = Integer.parseInt(val); - mSoftware.setMinSdkLevel(apiLevel); - mSoftware.setMaxSdkLevel(apiLevel); - } - } else if (DeviceSchema.NODE_LIVE_WALLPAPER_SUPPORT.equals(localName)) { - mSoftware.setLiveWallpaperSupport(getBool(mStringAccumulator)); - } else if (DeviceSchema.NODE_BLUETOOTH_PROFILES.equals(localName)) { - for (String s : getStringList(mStringAccumulator)) { - BluetoothProfile profile = BluetoothProfile.getEnum(s); - if (profile != null) { - mSoftware.addBluetoothProfile(profile); - } - } - } else if (DeviceSchema.NODE_GL_VERSION.equals(localName)) { - // Guaranteed to be in the form [\d]\.[\d] - mSoftware.setGlVersion(getString(mStringAccumulator)); - } else if (DeviceSchema.NODE_GL_EXTENSIONS.equals(localName)) { - mSoftware.addAllGlExtensions(getStringList(mStringAccumulator)); - } else if (DeviceSchema.NODE_DESCRIPTION.equals(localName)) { - mState.setDescription(getString(mStringAccumulator)); - } else if (DeviceSchema.NODE_SCREEN_ORIENTATION.equals(localName)) { - mState.setOrientation(ScreenOrientation.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_KEYBOARD_STATE.equals(localName)) { - mState.setKeyState(KeyboardState.getEnum(getString(mStringAccumulator))); - } else if (DeviceSchema.NODE_NAV_STATE.equals(localName)) { - // We have an extra state in our XML for nonav that - // NavigationState doesn't contain - String navState = getString(mStringAccumulator); - if (navState.equals("nonav")) { - mState.setNavState(NavigationState.HIDDEN); - } else { - mState.setNavState(NavigationState.getEnum(getString(mStringAccumulator))); - } - } else if (DeviceSchema.NODE_STATUS_BAR.equals(localName)) { - mSoftware.setStatusBar(getBool(mStringAccumulator)); - } - } - - @Override - public void error(SAXParseException e) throws SAXParseException { - throw e; - } - - private List<String> getStringList(StringBuilder stringAccumulator) { - List<String> filteredStrings = new ArrayList<String>(); - for (String s : getString(mStringAccumulator).split(sSpaceRegex)) { - if (s != null && !s.isEmpty()) { - filteredStrings.add(s.trim()); - } - } - return filteredStrings; - } - - private Boolean getBool(StringBuilder stringAccumulator) { - String b = getString(stringAccumulator); - return b.equalsIgnoreCase("true") || b.equalsIgnoreCase("1"); - } - - private double getDouble(StringBuilder stringAccumulator) { - return Double.parseDouble(getString(stringAccumulator)); - } - - private String getString(StringBuilder stringAccumulator) { - return stringAccumulator.toString().trim(); - } - - private int getInteger(StringBuilder stringAccumulator) { - return Integer.parseInt(getString(stringAccumulator)); - } - - } - - private final static SAXParserFactory sParserFactory; - - static { - sParserFactory = SAXParserFactory.newInstance(); - sParserFactory.setNamespaceAware(true); - } - - public static List<Device> parse(File devicesFile) throws SAXException, - ParserConfigurationException, IOException { - SAXParser parser = getParser(); - DeviceHandler dHandler = new DeviceHandler(devicesFile.getAbsoluteFile().getParentFile()); - parser.parse(devicesFile, dHandler); - return dHandler.getDevices(); - } - - public static List<Device> parse(InputStream devices) throws SAXException, IOException, - ParserConfigurationException { - SAXParser parser = getParser(); - DeviceHandler dHandler = new DeviceHandler(null); - parser.parse(devices, dHandler); - return dHandler.getDevices(); - } - - private static SAXParser getParser() throws ParserConfigurationException, SAXException { - sParserFactory.setSchema(DeviceSchema.getSchema()); - return sParserFactory.newSAXParser(); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java deleted file mode 100644 index feed6d4..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/DeviceWriter.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.SdkConstants; -import com.android.dvlib.DeviceSchema; -import com.android.resources.UiMode; - -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import java.awt.Point; -import java.io.OutputStream; -import java.util.Collection; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.TransformerFactoryConfigurationError; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -public class DeviceWriter { - - public static final String LOCAL_NS = "d"; - public static final String PREFIX = LOCAL_NS + ":"; - - /** - * Writes the XML definition of the given {@link Collection} of {@link Device}s according to - * {@value SdkConstants#NS_DEVICES_XSD} to the {@link OutputStream}. - * Note that it is up to the caller to close the {@link OutputStream}. - * @param out The {@link OutputStream} to write the resulting XML to. - * @param devices The {@link Device}s from which to generate the XML. - * @throws ParserConfigurationException - * @throws TransformerFactoryConfigurationError - * @throws TransformerException - */ - public static void writeToXml(OutputStream out, Collection<Device> devices) throws - ParserConfigurationException, - TransformerFactoryConfigurationError, - TransformerException { - Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); - Element root = doc.createElement(PREFIX + DeviceSchema.NODE_DEVICES); - root.setAttribute(XMLConstants.XMLNS_ATTRIBUTE + ":xsi", - XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI); - root.setAttribute(XMLConstants.XMLNS_ATTRIBUTE + ":" + LOCAL_NS, SdkConstants.NS_DEVICES_XSD); - doc.appendChild(root); - - for (Device device : devices) { - Element deviceNode = doc.createElement(PREFIX + DeviceSchema.NODE_DEVICE); - root.appendChild(deviceNode); - - Element name = doc.createElement(PREFIX + DeviceSchema.NODE_NAME); - name.appendChild(doc.createTextNode(device.getName())); - deviceNode.appendChild(name); - - Element manufacturer = doc.createElement(PREFIX + DeviceSchema.NODE_MANUFACTURER); - manufacturer.appendChild(doc.createTextNode(device.getManufacturer())); - deviceNode.appendChild(manufacturer); - - deviceNode.appendChild(generateMetaNode(device.getMeta(), doc)); - deviceNode.appendChild(generateHardwareNode(device.getDefaultHardware(), doc)); - for (Software sw : device.getAllSoftware()) { - deviceNode.appendChild(generateSoftwareNode(sw, doc)); - } - for (State s : device.getAllStates()) { - deviceNode.appendChild(generateStateNode(s, doc, device.getDefaultHardware())); - } - } - - Transformer tf = TransformerFactory.newInstance().newTransformer(); - tf.setOutputProperty(OutputKeys.INDENT, "yes"); - tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - DOMSource source = new DOMSource(doc); - StreamResult result = new StreamResult(out); - tf.transform(source, result); - } - - /* This returns the XML Element for the given instance of Meta */ - private static Node generateMetaNode(Meta meta, Document doc) { - Element m = doc.createElement(PREFIX + DeviceSchema.NODE_META); - if (meta.hasIconSixtyFour() || meta.hasIconSixteen()) { - Element icons = doc.createElement(PREFIX + DeviceSchema.NODE_ICONS); - m.appendChild(icons); - if (meta.hasIconSixtyFour()) { - addElement(doc, icons, DeviceSchema.NODE_SIXTY_FOUR, - meta.getIconSixtyFour().getPath()); - } - if (meta.hasIconSixteen()) { - addElement(doc, icons, DeviceSchema.NODE_SIXTEEN, meta.getIconSixteen().getPath()); - } - } - - if (meta.hasFrame()) { - Element frame = doc.createElement(PREFIX + DeviceSchema.NODE_FRAME); - addElement(doc, frame, DeviceSchema.NODE_PATH, meta.getFrame().getPath()); - Point offset = meta.getFrameOffsetPortrait(); - addElement(doc, frame, DeviceSchema.NODE_PORTRAIT_X_OFFSET, Integer.toString(offset.x)); - addElement(doc, frame, DeviceSchema.NODE_PORTRAIT_Y_OFFSET, Integer.toString(offset.y)); - offset = meta.getFrameOffsetLandscape(); - addElement(doc, frame, DeviceSchema.NODE_LANDSCAPE_X_OFFSET, - Integer.toString(offset.x)); - addElement(doc, frame, DeviceSchema.NODE_LANDSCAPE_Y_OFFSET, - Integer.toString(offset.y)); - } - - return m; - } - - /* This returns the XML Element for the given instance of Hardware */ - private static Element generateHardwareNode(Hardware hw, Document doc) { - Screen s = hw.getScreen(); - Element hardware = doc.createElement(PREFIX + DeviceSchema.NODE_HARDWARE); - Element screen = doc.createElement(PREFIX + DeviceSchema.NODE_SCREEN); - hardware.appendChild(screen); - - addElement(doc, screen, DeviceSchema.NODE_SCREEN_SIZE, s.getSize().getResourceValue()); - addElement(doc, screen, DeviceSchema.NODE_DIAGONAL_LENGTH, - String.format("%.2f",s.getDiagonalLength())); - addElement(doc, screen, DeviceSchema.NODE_PIXEL_DENSITY, - s.getPixelDensity().getResourceValue()); - addElement(doc, screen, DeviceSchema.NODE_SCREEN_RATIO, s.getRatio().getResourceValue()); - - Element dimensions = doc.createElement(PREFIX + DeviceSchema.NODE_DIMENSIONS); - screen.appendChild(dimensions); - - addElement(doc, dimensions, DeviceSchema.NODE_X_DIMENSION, - Integer.toString(s.getXDimension())); - addElement(doc, dimensions, DeviceSchema.NODE_Y_DIMENSION, - Integer.toString(s.getYDimension())); - addElement(doc, screen, DeviceSchema.NODE_XDPI, String.format("%.2f", s.getXdpi())); - addElement(doc, screen, DeviceSchema.NODE_YDPI, String.format("%.2f", s.getYdpi())); - - Element touch = doc.createElement(PREFIX + DeviceSchema.NODE_TOUCH); - screen.appendChild(touch); - - addElement(doc, touch, DeviceSchema.NODE_MULTITOUCH, s.getMultitouch().toString()); - addElement(doc, touch, DeviceSchema.NODE_MECHANISM, s.getMechanism().getResourceValue()); - addElement(doc, touch, DeviceSchema.NODE_SCREEN_TYPE, s.getScreenType().toString()); - - addElement(doc, hardware, DeviceSchema.NODE_NETWORKING, hw.getNetworking()); - addElement(doc, hardware, DeviceSchema.NODE_SENSORS, hw.getSensors()); - addElement(doc, hardware, DeviceSchema.NODE_MIC, Boolean.toString(hw.hasMic())); - - for(Camera c : hw.getCameras()) { - Element camera = doc.createElement(PREFIX + DeviceSchema.NODE_CAMERA); - hardware.appendChild(camera); - addElement(doc, camera, DeviceSchema.NODE_LOCATION, c.getLocation().toString()); - addElement(doc, camera, DeviceSchema.NODE_AUTOFOCUS, - Boolean.toString(c.hasAutofocus())); - addElement(doc, camera, DeviceSchema.NODE_FLASH, Boolean.toString(c.hasFlash())); - } - - addElement(doc, hardware, DeviceSchema.NODE_KEYBOARD, hw.getKeyboard().getResourceValue()); - addElement(doc, hardware, DeviceSchema.NODE_NAV, hw.getNav().getResourceValue()); - - Storage.Unit unit = hw.getRam().getApproriateUnits(); - Element ram = addElement(doc, hardware, DeviceSchema.NODE_RAM, - Long.toString(hw.getRam().getSizeAsUnit(unit))); - ram.setAttribute(DeviceSchema.ATTR_UNIT, unit.toString()); - - addElement(doc, hardware, DeviceSchema.NODE_BUTTONS, hw.getButtonType().toString()); - addStorageElement(doc, hardware, DeviceSchema.NODE_INTERNAL_STORAGE, - hw.getInternalStorage()); - addStorageElement(doc, hardware, DeviceSchema.NODE_REMOVABLE_STORAGE, - hw.getRemovableStorage()); - addElement(doc, hardware, DeviceSchema.NODE_CPU, hw.getCpu()); - addElement(doc, hardware, DeviceSchema.NODE_GPU, hw.getGpu()); - addElement(doc, hardware, DeviceSchema.NODE_ABI, hw.getSupportedAbis()); - - StringBuilder sb = new StringBuilder(); - for (UiMode u : hw.getSupportedUiModes()) { - sb.append("\n" + u.getResourceValue()); - } - addElement(doc, hardware, DeviceSchema.NODE_DOCK, sb.toString()); - - addElement(doc, hardware, DeviceSchema.NODE_POWER_TYPE, hw.getChargeType().toString()); - - return hardware; - } - - /* This returns the XML Element for the given instance of Software */ - private static Element generateSoftwareNode(Software sw, Document doc) { - Element software = doc.createElement(PREFIX + DeviceSchema.NODE_SOFTWARE); - - String apiVersion = ""; - if (sw.getMinSdkLevel() != 0) { - apiVersion += Integer.toString(sw.getMinSdkLevel()); - } - apiVersion += "-"; - if (sw.getMaxSdkLevel() != Integer.MAX_VALUE) { - apiVersion += Integer.toString(sw.getMaxSdkLevel()); - } - addElement(doc, software, DeviceSchema.NODE_API_LEVEL, apiVersion); - addElement(doc, software, DeviceSchema.NODE_LIVE_WALLPAPER_SUPPORT, - Boolean.toString(sw.hasLiveWallpaperSupport())); - addElement(doc, software, DeviceSchema.NODE_BLUETOOTH_PROFILES, sw.getBluetoothProfiles()); - addElement(doc, software, DeviceSchema.NODE_GL_VERSION, sw.getGlVersion()); - addElement(doc, software, DeviceSchema.NODE_GL_EXTENSIONS, sw.getGlExtensions()); - addElement(doc, software, DeviceSchema.NODE_STATUS_BAR, - Boolean.toString(sw.hasStatusBar())); - - return software; - } - - /* This returns the XML Element for the given instance of State */ - private static Element generateStateNode(State s, Document doc, Hardware defaultHardware) { - Element state = doc.createElement(PREFIX + DeviceSchema.NODE_STATE); - state.setAttribute(DeviceSchema.ATTR_NAME, s.getName()); - if (s.isDefaultState()) { - state.setAttribute(DeviceSchema.ATTR_DEFAULT, Boolean.toString(s.isDefaultState())); - } - addElement(doc, state, DeviceSchema.NODE_DESCRIPTION, s.getDescription()); - addElement(doc, state, DeviceSchema.NODE_SCREEN_ORIENTATION, - s.getOrientation().getResourceValue()); - addElement(doc, state, DeviceSchema.NODE_KEYBOARD_STATE, - s.getKeyState().getResourceValue()); - addElement(doc, state, DeviceSchema.NODE_NAV_STATE, s.getNavState().getResourceValue()); - - // Only if the hardware is different do we want to append hardware values - if (!s.getHardware().equals(defaultHardware)){ - // TODO: Only append nodes which are different from the default hardware - Element hardware = generateHardwareNode(s.getHardware(), doc); - NodeList children = hardware.getChildNodes(); - for (int i = 0 ; i < children.getLength(); i++) { - Node child = children.item(i); - state.appendChild(child); - } - } - return state; - } - - private static Element addElement(Document doc, Element parent, String tag, String content) { - Element child = doc.createElement(PREFIX + tag); - child.appendChild(doc.createTextNode(content)); - parent.appendChild(child); - return child; - } - - private static Element addElement(Document doc, Element parent, String tag, - Collection<? extends Object> content) { - StringBuilder sb = new StringBuilder(); - for (Object o : content) { - sb.append("\n" + o.toString()); - } - return addElement(doc, parent, tag, sb.toString()); - } - - /* This adds generates the XML for a Collection<Storage> and appends it to the parent. Note - * that it picks the proper unit for the unit attribute and sets it on the node. - */ - private static Element addStorageElement(Document doc, Element parent, String tag, - Collection<Storage> content){ - Storage.Unit unit = Storage.Unit.TiB; - - // Get the lowest common unit (so if one piece of storage is 128KiB and another is 1MiB, - // use KiB for units) - for(Storage storage : content) { - if(storage.getApproriateUnits().getNumberOfBytes() < unit.getNumberOfBytes()) { - unit = storage.getApproriateUnits(); - } - } - - StringBuilder sb = new StringBuilder(); - for(Storage storage : content) { - sb.append("\n" + storage.getSizeAsUnit(unit)); - } - Element storage = addElement(doc, parent, tag, sb.toString()); - storage.setAttribute(DeviceSchema.ATTR_UNIT, unit.toString()); - return storage; - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Hardware.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Hardware.java deleted file mode 100644 index b12f11d..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Hardware.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.resources.Keyboard; -import com.android.resources.Navigation; -import com.android.resources.UiMode; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class Hardware { - private Screen mScreen; - private Set<Network> mNetworking = new HashSet<Network>(); - private Set<Sensor> mSensors = new HashSet<Sensor>(); - private boolean mMic; - private List<Camera> mCameras = new ArrayList<Camera>(); - private Keyboard mKeyboard; - private Navigation mNav; - private Storage mRam; - private ButtonType mButtons; - private List<Storage> mInternalStorage = new ArrayList<Storage>(); - private List<Storage> mRemovableStorage = new ArrayList<Storage>(); - private String mCpu; - private String mGpu; - private Set<Abi> mAbis = new HashSet<Abi>(); - private Set<UiMode> mUiModes = new HashSet<UiMode>(); - private PowerType mPluggedIn; - - public Set<Network> getNetworking() { - return mNetworking; - } - - public void addNetwork(Network n) { - mNetworking.add(n); - } - - public void addAllNetworks(Collection<Network> ns) { - mNetworking.addAll(ns); - } - - public Set<Sensor> getSensors() { - return mSensors; - } - - public void addSensor(Sensor sensor) { - mSensors.add(sensor); - } - - public void addAllSensors(Collection<Sensor> sensors) { - mSensors.addAll(sensors); - } - - public boolean hasMic() { - return mMic; - } - - public void setHasMic(boolean hasMic) { - mMic = hasMic; - } - - public List<Camera> getCameras() { - return mCameras; - } - - public void addCamera(Camera c) { - mCameras.add(c); - } - - public void addAllCameras(Collection<Camera> cs) { - mCameras.addAll(cs); - } - - public Camera getCamera(int i) { - return mCameras.get(i); - } - - public Camera getCamera(CameraLocation location) { - for (Camera c : mCameras) { - if (location.equals(c.getLocation())) { - return c; - } - } - return null; - } - - public Keyboard getKeyboard() { - return mKeyboard; - } - - public void setKeyboard(Keyboard k) { - mKeyboard = k; - } - - public Navigation getNav() { - return mNav; - } - - public void setNav(Navigation n) { - mNav = n; - } - - public Storage getRam() { - return mRam; - } - - public void setRam(Storage ram) { - mRam = ram; - } - - public ButtonType getButtonType() { - return mButtons; - } - - public void setButtonType(ButtonType bt) { - mButtons = bt; - } - - public List<Storage> getInternalStorage() { - return mInternalStorage; - } - - public void addInternalStorage(Storage is) { - mInternalStorage.add(is); - } - - public void addAllInternalStorage(Collection<Storage> is) { - mInternalStorage.addAll(is); - } - - public List<Storage> getRemovableStorage() { - return mRemovableStorage; - } - - public void addRemovableStorage(Storage rs) { - mRemovableStorage.add(rs); - } - - public void addAllRemovableStorage(Collection<Storage> rs) { - mRemovableStorage.addAll(rs); - } - - public String getCpu() { - return mCpu; - } - - public void setCpu(String cpuName) { - mCpu = cpuName; - } - - public String getGpu() { - return mGpu; - } - - public void setGpu(String gpuName) { - mGpu = gpuName; - } - - public Set<Abi> getSupportedAbis() { - return mAbis; - } - - public void addSupportedAbi(Abi abi) { - mAbis.add(abi); - } - - public void addAllSupportedAbis(Collection<Abi> abis) { - mAbis.addAll(abis); - } - - public Set<UiMode> getSupportedUiModes() { - return mUiModes; - } - - public void addSupportedUiMode(UiMode uiMode) { - mUiModes.add(uiMode); - } - - public void addAllSupportedUiModes(Collection<UiMode> uiModes) { - mUiModes.addAll(uiModes); - } - - public PowerType getChargeType() { - return mPluggedIn; - } - - public void setChargeType(PowerType chargeType) { - mPluggedIn = chargeType; - } - - public Screen getScreen() { - return mScreen; - } - - public void setScreen(Screen s) { - mScreen = s; - } - - /** - * Returns a copy of the object that shares no state with it, - * but is initialized to equivalent values. - * - * @return A copy of the object. - */ - public Hardware deepCopy() { - Hardware hw = new Hardware(); - hw.mScreen = mScreen.deepCopy(); - hw.mNetworking = new HashSet<Network>(mNetworking); - hw.mSensors = new HashSet<Sensor>(mSensors); - // Get the constant boolean value - hw.mMic = mMic; - hw.mCameras = new ArrayList<Camera>(); - for (Camera c : mCameras) { - hw.mCameras.add(c.deepCopy()); - } - hw.mKeyboard = mKeyboard; - hw.mNav = mNav; - hw.mRam = mRam.deepCopy(); - hw.mButtons = mButtons; - hw.mInternalStorage = new ArrayList<Storage>(); - for (Storage s : mInternalStorage) { - hw.mInternalStorage.add(s.deepCopy()); - } - hw.mRemovableStorage = new ArrayList<Storage>(); - for (Storage s : mRemovableStorage) { - hw.mRemovableStorage.add(s.deepCopy()); - } - hw.mCpu = mCpu; - hw.mGpu = mGpu; - hw.mAbis = new HashSet<Abi>(mAbis); - hw.mUiModes = new HashSet<UiMode>(mUiModes); - hw.mPluggedIn = mPluggedIn; - return hw; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Hardware)) { - return false; - } - Hardware hw = (Hardware) o; - return mScreen.equals(hw.getScreen()) - && mNetworking.equals(hw.getNetworking()) - && mSensors.equals(hw.getSensors()) - && mMic == hw.hasMic() - && mCameras.equals(hw.getCameras()) - && mKeyboard == hw.getKeyboard() - && mNav == hw.getNav() - && mRam.equals(hw.getRam()) - && mButtons == hw.getButtonType() - && mInternalStorage.equals(hw.getInternalStorage()) - && mRemovableStorage.equals(hw.getRemovableStorage()) - && mCpu.equals(hw.getCpu()) - && mGpu.equals(hw.getGpu()) - && mAbis.equals(hw.getSupportedAbis()) - && mUiModes.equals(hw.getSupportedUiModes()) - && mPluggedIn == hw.getChargeType(); - - } - - @Override - public int hashCode() { - int hash = 17; - hash = 31 * hash + mScreen.hashCode(); - - // Since sets have no defined order, we need to hash them in such a way that order doesn't - // matter. - int temp = 0; - for (Network n : mNetworking) { - temp |= 1 << n.ordinal(); - } - hash = 31 * hash + temp; - - temp = 0; - for (Sensor s : mSensors) { - temp |= 1 << s.ordinal(); - } - - hash = 31 * hash + temp; - hash = 31 * hash + (mMic ? 1 : 0); - hash = mCameras.hashCode(); - hash = 31 * hash + mKeyboard.ordinal(); - hash = 31 * hash + mNav.ordinal(); - hash = 31 * hash + mRam.hashCode(); - hash = 31 * hash + mButtons.ordinal(); - hash = 31 * hash + mInternalStorage.hashCode(); - hash = 31 * hash + mRemovableStorage.hashCode(); - - for (Character c : mCpu.toCharArray()) { - hash = 31 * hash + c; - } - - for (Character c : mGpu.toCharArray()) { - hash = 31 * hash + c; - } - - temp = 0; - for (Abi a : mAbis) { - temp |= 1 << a.ordinal(); - } - hash = 31 * hash + temp; - - temp = 0; - for (UiMode ui : mUiModes) { - temp |= 1 << ui.ordinal(); - } - hash = 31 * hash + temp; - - return hash; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Meta.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Meta.java deleted file mode 100644 index 4c19f3f..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Meta.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import java.awt.Point; -import java.io.File; - -public class Meta { - private File mIconSixtyFour; - private File mIconSixteen; - private File mFrame; - private Point mFrameOffsetLandscape; - private Point mFrameOffsetPortrait; - - public File getIconSixtyFour() { - return mIconSixtyFour; - } - - public void setIconSixtyFour(File iconSixtyFour) { - mIconSixtyFour = iconSixtyFour; - } - - public boolean hasIconSixtyFour() { - if (mIconSixtyFour != null && mIconSixtyFour.isFile()) { - return true; - } else { - return false; - } - } - - public File getIconSixteen() { - return mIconSixteen; - } - - public void setIconSixteen(File iconSixteen) { - mIconSixteen = iconSixteen; - } - - public boolean hasIconSixteen() { - if (mIconSixteen != null && mIconSixteen.isFile()) { - return true; - } else { - return false; - } - } - - public File getFrame() { - return mFrame; - } - - public void setFrame(File frame) { - mFrame = frame; - } - - public boolean hasFrame() { - if (mFrame != null && mFrame.isFile()) { - return true; - } else { - return false; - } - } - - public Point getFrameOffsetLandscape() { - return mFrameOffsetLandscape; - } - - public void setFrameOffsetLandscape(Point offset) { - mFrameOffsetLandscape = offset; - } - - public Point getFrameOffsetPortrait() { - return mFrameOffsetPortrait; - } - - public void setFrameOffsetPortrait(Point offset) { - mFrameOffsetPortrait = offset; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Meta)) { - return false; - } - Meta m = (Meta) o; - - // Note that any of the fields of either object can be null - if (mIconSixtyFour != null && !mIconSixtyFour.equals(m.getIconSixtyFour())){ - return false; - } else if (m.getIconSixtyFour() != null && !m.getIconSixtyFour().equals(mIconSixtyFour)) { - return false; - } - - if (mIconSixteen != null && !mIconSixteen.equals(m.getIconSixteen())){ - return false; - } else if (m.getIconSixteen() != null && !m.getIconSixteen().equals(mIconSixteen)) { - return false; - } - - if (mFrame != null && !mFrame.equals(m.getFrame())) { - return false; - } else if (m.getFrame() != null && !m.getFrame().equals(mFrame)) { - return false; - } - - if (mFrameOffsetLandscape != null - && !mFrameOffsetLandscape.equals(m.getFrameOffsetLandscape())){ - return false; - } else if (m.getFrameOffsetLandscape() != null - && !m.getFrameOffsetLandscape().equals(mFrameOffsetLandscape)){ - return false; - } - - - if (mFrameOffsetPortrait != null - && !mFrameOffsetPortrait.equals(m.getFrameOffsetPortrait())){ - return false; - } else if (m.getFrameOffsetPortrait() != null - && !m.getFrameOffsetPortrait().equals(mFrameOffsetPortrait)){ - return false; - } - - return true; - } - - @Override - public int hashCode() { - int hash = 17; - if(mIconSixteen != null){ - for (Character c : mIconSixteen.getAbsolutePath().toCharArray()) { - hash = 31 * hash + c; - } - } - if(mIconSixtyFour != null){ - for (Character c : mIconSixtyFour.getAbsolutePath().toCharArray()) { - hash = 31 * hash + c; - } - } - if(mFrame != null){ - for (Character c : mFrame.getAbsolutePath().toCharArray()) { - hash = 31 * hash + c; - } - } - if(mFrameOffsetLandscape != null){ - hash = 31 * hash + mFrameOffsetLandscape.x; - hash = 31 * hash + mFrameOffsetLandscape.y; - } - if(mFrameOffsetPortrait != null){ - hash = 31 * hash + mFrameOffsetPortrait.x; - hash = 31 * hash + mFrameOffsetPortrait.y; - } - return hash; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Multitouch.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Multitouch.java deleted file mode 100644 index bfd4618..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Multitouch.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum Multitouch { - NONE("none"), - BASIC("basic"), - DISTINCT("distinct"), - JAZZ_HANDS("jazz-hands"); - - private final String mValue; - - private Multitouch(String value){ - mValue = value; - } - - public static Multitouch getEnum(String val){ - for (Multitouch m : values()) { - if (m.mValue.equals(val)) { - return m; - } - } - return null; - } - - @Override - public String toString() { - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Network.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Network.java deleted file mode 100644 index df84b44..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Network.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum Network { - BLUETOOTH("Bluetooth"), - WIFI("Wifi"), - NFC("NFC"); - - private final String mValue; - - private Network(String value) { - mValue = value; - } - - public static Network getEnum(String value) { - for (Network n : values()) { - if (n.mValue.equals(value)) { - return n; - } - } - return null; - } - - @Override - public String toString(){ - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/PowerType.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/PowerType.java deleted file mode 100644 index e38ba28..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/PowerType.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum PowerType { - PLUGGEDIN("plugged-in"), - BATTERY("battery"); - - private final String mValue; - - private PowerType(String value) { - mValue = value; - } - - public static PowerType getEnum(String value) { - for (PowerType c : values()) { - if (c.mValue.equals(value)) { - return c; - } - } - return null; - } - - @Override - public String toString() { - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Screen.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Screen.java deleted file mode 100644 index a7f4334..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Screen.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.resources.Density; -import com.android.resources.ScreenRatio; -import com.android.resources.ScreenSize; -import com.android.resources.TouchScreen; - - -public class Screen { - private ScreenSize mScreenSize; - private double mDiagonalLength; - private Density mPixelDensity; - private ScreenRatio mScreenRatio; - private int mXDimension; - private int mYDimension; - private double mXdpi; - private double mYdpi; - private Multitouch mMultitouch; - private TouchScreen mMechanism; - private ScreenType mScreenType; - - public ScreenSize getSize() { - return mScreenSize; - } - - public void setSize(ScreenSize s) { - mScreenSize = s; - } - - public double getDiagonalLength() { - return mDiagonalLength; - } - - public void setDiagonalLength(double diagonalLength) { - mDiagonalLength = diagonalLength; - } - - public Density getPixelDensity() { - return mPixelDensity; - } - - public void setPixelDensity(Density pDensity) { - mPixelDensity = pDensity; - } - - public ScreenRatio getRatio() { - return mScreenRatio; - } - - public void setRatio(ScreenRatio ratio) { - mScreenRatio = ratio; - } - - public int getXDimension() { - return mXDimension; - } - - public void setXDimension(int xDimension) { - mXDimension = xDimension; - } - - public int getYDimension() { - return mYDimension; - } - - public void setYDimension(int yDimension) { - mYDimension = yDimension; - } - - public double getXdpi() { - return mXdpi; - } - - public void setXdpi(double xdpi) { - mXdpi = xdpi; - } - - public double getYdpi() { - return mYdpi; - } - - public void setYdpi(double ydpi) { - mYdpi = ydpi; - } - - public Multitouch getMultitouch() { - return mMultitouch; - } - - public void setMultitouch(Multitouch m) { - mMultitouch = m; - } - - public TouchScreen getMechanism() { - return mMechanism; - } - - public void setMechanism(TouchScreen mechanism) { - mMechanism = mechanism; - } - - public ScreenType getScreenType() { - return mScreenType; - } - - public void setScreenType(ScreenType screenType) { - mScreenType = screenType; - } - - /** - * Returns a copy of the object that shares no state with it, - * but is initialized to equivalent values. - * - * @return A copy of the object. - */ - public Screen deepCopy() { - Screen s = new Screen(); - s.mScreenSize = mScreenSize; - s.mDiagonalLength = mDiagonalLength; - s.mPixelDensity = mPixelDensity; - s.mScreenRatio = mScreenRatio; - s.mXDimension = mXDimension; - s.mYDimension = mYDimension; - s.mXdpi = mXdpi; - s.mYdpi = mYdpi; - s.mMultitouch = mMultitouch; - s.mMechanism = mMechanism; - s.mScreenType = mScreenType; - return s; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Screen)) { - return false; - } - Screen s = (Screen) o; - return s.mScreenSize == mScreenSize - && s.mDiagonalLength == mDiagonalLength - && s.mPixelDensity == mPixelDensity - && s.mScreenRatio == mScreenRatio - && s.mXDimension == mXDimension - && s.mYDimension == mYDimension - && s.mXdpi == mXdpi - && s.mYdpi == mYdpi - && s.mMultitouch == mMultitouch - && s.mMechanism == mMechanism - && s.mScreenType == mScreenType; - } - - @Override - public int hashCode() { - int hash = 17; - hash = 31 * hash + mScreenSize.ordinal(); - long f = Double.doubleToLongBits(mDiagonalLength); - hash = 31 * hash + (int) (f ^ (f >>> 32)); - hash = 31 * hash + mPixelDensity.ordinal(); - hash = 31 * hash + mScreenRatio.ordinal(); - hash = 31 * hash + mXDimension; - hash = 31 * hash + mYDimension; - f = Double.doubleToLongBits(mXdpi); - hash = 31 * hash + (int) (f ^ (f >>> 32)); - f = Double.doubleToLongBits(mYdpi); - hash = 31 * hash + (int) (f ^ (f >>> 32)); - hash = 31 * hash + mMultitouch.ordinal(); - hash = 31 * hash + mMechanism.ordinal(); - hash = 31 * hash + mScreenType.ordinal(); - return hash; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/ScreenType.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/ScreenType.java deleted file mode 100644 index 21d6005..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/ScreenType.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum ScreenType { - CAPACITIVE("capacitive"), - RESISTIVE("resistive"), - NOTOUCH("notouch"); - - private final String mValue; - - private ScreenType(String value) { - mValue = value; - } - - public static ScreenType getEnum(String value) { - for (ScreenType s : values()) { - if (s.mValue.equals(value)) { - return s; - } - } - return null; - } - - @Override - public String toString() { - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Sensor.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Sensor.java deleted file mode 100644 index 3fc3e14..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Sensor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public enum Sensor { - ACCELEROMETER("Accelerometer"), - BAROMETER("Barometer"), - COMPASS("Compass"), - GPS("GPS"), - GYROSCOPE("Gyroscope"), - LIGHT_SENSOR("LightSensor"), - PROXIMITY_SENSOR("ProximitySensor"); - - private final String mValue; - - private Sensor(String value) { - mValue = value; - } - - public static Sensor getEnum(String value) { - for (Sensor s : values()) { - if (s.mValue.equals(value)) { - return s; - } - } - return null; - } - - @Override - public String toString(){ - return mValue; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Software.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Software.java deleted file mode 100644 index 58f13b0..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Software.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -public class Software { - private int mMinSdkLevel = 0; - private int mMaxSdkLevel = Integer.MAX_VALUE; - private boolean mLiveWallpaperSupport; - private Set<BluetoothProfile> mBluetoothProfiles = new HashSet<BluetoothProfile>(); - private String mGlVersion; - private Set<String> mGlExtensions = new HashSet<String>(); - private boolean mStatusBar; - - public int getMinSdkLevel() { - return mMinSdkLevel; - } - - public void setMinSdkLevel(int sdkLevel) { - mMinSdkLevel = sdkLevel; - } - - public int getMaxSdkLevel() { - return mMaxSdkLevel; - } - - public void setMaxSdkLevel(int sdkLevel) { - mMaxSdkLevel = sdkLevel; - } - - public boolean hasLiveWallpaperSupport() { - return mLiveWallpaperSupport; - } - - public void setLiveWallpaperSupport(boolean liveWallpaperSupport) { - mLiveWallpaperSupport = liveWallpaperSupport; - } - - public Set<BluetoothProfile> getBluetoothProfiles() { - return mBluetoothProfiles; - } - - public void addBluetoothProfile(BluetoothProfile bp) { - mBluetoothProfiles.add(bp); - } - - public void addAllBluetoothProfiles(Collection<BluetoothProfile> bps) { - mBluetoothProfiles.addAll(bps); - } - - public String getGlVersion() { - return mGlVersion; - } - - public void setGlVersion(String version) { - mGlVersion = version; - } - - public Set<String> getGlExtensions() { - return mGlExtensions; - } - - public void addGlExtension(String extension) { - mGlExtensions.add(extension); - } - - public void addAllGlExtensions(Collection<String> extensions) { - mGlExtensions.addAll(extensions); - } - - public void setStatusBar(boolean hasBar) { - mStatusBar = hasBar; - } - - public boolean hasStatusBar() { - return mStatusBar; - } - - public Software deepCopy() { - Software s = new Software(); - s.setMinSdkLevel(getMinSdkLevel()); - s.setMaxSdkLevel(getMaxSdkLevel()); - s.setLiveWallpaperSupport(hasLiveWallpaperSupport()); - s.addAllBluetoothProfiles(getBluetoothProfiles()); - s.setGlVersion(getGlVersion()); - s.addAllGlExtensions(getGlExtensions()); - s.setStatusBar(hasStatusBar()); - return s; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Software)) { - return false; - } - - Software sw = (Software) o; - return mMinSdkLevel == sw.getMinSdkLevel() - && mMaxSdkLevel == sw.getMaxSdkLevel() - && mLiveWallpaperSupport == sw.hasLiveWallpaperSupport() - && mBluetoothProfiles.equals(sw.getBluetoothProfiles()) - && mGlVersion.equals(sw.getGlVersion()) - && mGlExtensions.equals(sw.getGlExtensions()) - && mStatusBar == sw.hasStatusBar(); - } - - @Override - /** A stable hash across JVM instances */ - public int hashCode() { - int hash = 17; - hash = 31 * hash + mMinSdkLevel; - hash = 31 * hash + mMaxSdkLevel; - hash = 31 * hash + (mLiveWallpaperSupport ? 1 : 0); - for (BluetoothProfile bp : mBluetoothProfiles) { - hash = 31 * hash + bp.ordinal(); - } - for (Character c : mGlVersion.toCharArray()) { - hash = 31 * hash + c; - } - for (String glExtension : mGlExtensions) { - for (Character c : glExtension.toCharArray()) { - hash = 31 * hash + c; - } - } - hash = 31 * hash + (mStatusBar ? 1 : 0); - return hash; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/State.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/State.java deleted file mode 100644 index 27e5448..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/State.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.resources.KeyboardState; -import com.android.resources.NavigationState; -import com.android.resources.ScreenOrientation; - -public class State { - private boolean mDefaultState; - private String mName; - private String mDescription; - private ScreenOrientation mOrientation; - private KeyboardState mKeyState; - private NavigationState mNavState; - private Hardware mHardwareOverride; - - public boolean isDefaultState() { - return mDefaultState; - } - - public void setDefaultState(boolean defaultState) { - mDefaultState = defaultState; - } - - public String getName() { - return mName; - } - - public void setName(String name) { - mName = name; - } - - public String getDescription() { - return mDescription; - } - - public void setDescription(String description) { - mDescription = description; - } - - public ScreenOrientation getOrientation() { - return mOrientation; - } - - public void setOrientation(ScreenOrientation orientation) { - mOrientation = orientation; - } - - public KeyboardState getKeyState() { - return mKeyState; - } - - public void setKeyState(KeyboardState keyState) { - mKeyState = keyState; - } - - public NavigationState getNavState() { - return mNavState; - } - - public void setNavState(NavigationState navState) { - mNavState = navState; - } - - public Hardware getHardware() { - return mHardwareOverride; - } - - public void setHardware(Hardware hw) { - mHardwareOverride = hw; - } - - /** - * Returns a copy of the object that shares no state with it, - * but is initialized to equivalent values. - * - * @return A copy of the object. - */ - public State deepCopy() { - State s = new State(); - s.setDefaultState(isDefaultState()); - s.setName(getName()); - s.setDescription(getDescription()); - s.setOrientation(getOrientation()); - s.setKeyState(getKeyState()); - s.setNavState(getNavState()); - s.setHardware(getHardware().deepCopy()); - return s; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof State)) { - return false; - } - State s = (State) o; - return mDefaultState == s.isDefaultState() - && mName.equals(s.getName()) - && mDescription.equals(s.getDescription()) - && mOrientation.equals(s.getOrientation()) - && mKeyState.equals(s.getKeyState()) - && mNavState.equals(s.getNavState()) - && mHardwareOverride.equals(s.getHardware()); - } - - @Override - public int hashCode() { - int hash = 17; - hash = 31 * hash + (mDefaultState ? 1 : 0); - for (Character c : mName.toCharArray()) { - hash = 31 * hash + c; - } - for (Character c : mDescription.toCharArray()) { - hash = 31 * hash + c; - } - hash = 31 * hash + mOrientation.ordinal(); - hash = 31 * hash + mKeyState.ordinal(); - hash = 31 * hash + mNavState.ordinal(); - hash = 31 * hash + mHardwareOverride.hashCode(); - return hash; - } - - @Override - public String toString() { - return mName; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Storage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Storage.java deleted file mode 100644 index b30fe6e..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/Storage.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -public class Storage { - private long mNoBytes; - - public Storage(long amount, Unit unit){ - mNoBytes = amount * unit.getNumberOfBytes(); - } - - public Storage(long amount){ - this(amount, Unit.B); - } - - /** Returns the amount of storage represented, in Bytes */ - public long getSize() { - return getSizeAsUnit(Unit.B); - } - - public Storage deepCopy() { - return new Storage(mNoBytes); - } - - /** - * Return the amount of storage represented by the instance in the given unit - * @param unit The unit of the result. - * @return The size of the storage in the given unit. - */ - public long getSizeAsUnit(Unit unit) { - return mNoBytes / unit.getNumberOfBytes(); - } - - @Override - public boolean equals(Object o) { - if (o == this){ - return true; - } - - if (!(o instanceof Storage)) { - return false; - } - - Storage s = (Storage) o; - if (s.getSize() == this.getSize()) { - return true; - } else { - return false; - } - } - - @Override - public int hashCode() { - int result = 17; - return 31 * result + (int) (mNoBytes^(mNoBytes>>>32)); - } - - public enum Unit{ - B("B", 1), - KiB("KiB", 1024), - MiB("MiB", 1024 * 1024), - GiB("GiB", 1024 * 1024 * 1024), - TiB("TiB", 1024l * 1024l * 1024l * 1024l); - - private String mValue; - /** The number of bytes needed to have one of the given unit */ - private long mNoBytes; - - private Unit(String val, long noBytes) { - mValue = val; - mNoBytes = noBytes; - } - - public static Unit getEnum(String val) { - for(Unit v : values()){ - if(v.mValue.equals(val)) { - return v; - } - } - return null; - } - - public long getNumberOfBytes() { - return mNoBytes; - } - - @Override - public String toString() { - return mValue; - } - } - - /** - * Finds the largest {@link Unit} which can display the storage value as a positive integer - * with no loss of accuracy. - * @return The most appropriate {@link Unit}. - */ - public Unit getApproriateUnits() { - Unit optimalUnit = Unit.B; - for(Unit unit : Unit.values()) { - if(mNoBytes % unit.getNumberOfBytes() == 0) { - optimalUnit = unit; - } else { - break; - } - } - return optimalUnit; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/devices.xml b/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/devices.xml deleted file mode 100644 index e18280d..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/devices/devices.xml +++ /dev/null @@ -1,1412 +0,0 @@ -<?xml version="1.0"?> -<d:devices - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:d="http://schemas.android.com/sdk/devices/1"> - - <d:device> - <d:name> - 2.7in QVGA - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>small</d:screen-size> - <d:diagonal-length>2.7</d:diagonal-length> - <d:pixel-density>ldpi</d:pixel-density> - <d:screen-ratio>notlong</d:screen-ratio> - <d:dimensions> - <d:x-dimension>240</d:x-dimension> - <d:y-dimension>320</d:y-dimension> - </d:dimensions> - <d:xdpi>145</d:xdpi> - <d:ydpi>145</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 2.7in QVGA slider - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>small</d:screen-size> - <d:diagonal-length>2.7</d:diagonal-length> - <d:pixel-density>ldpi</d:pixel-density> - <d:screen-ratio>notlong</d:screen-ratio> - <d:dimensions> - <d:x-dimension>240</d:x-dimension> - <d:y-dimension>320</d:y-dimension> - </d:dimensions> - <d:xdpi>145</d:xdpi> - <d:ydpi>145</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>qwerty</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape, closed"> - <d:description>The phone in landscape view with the keyboard closed</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyshidden</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape, open"> - <d:description>The phone in landscape view with the keyboard open</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keysexposed</d:keyboard-state> - <d:nav-state>navexposed</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 3.2in HVGA slider (ADP1) - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>3.2</d:diagonal-length> - <d:pixel-density>mdpi</d:pixel-density> - <d:screen-ratio>notlong</d:screen-ratio> - <d:dimensions> - <d:x-dimension>320</d:x-dimension> - <d:y-dimension>480</d:y-dimension> - </d:dimensions> - <d:xdpi>180.6</d:xdpi> - <d:ydpi>182</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>qwerty</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyshidden</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape, closed"> - <d:description>The phone in landscape view with the keyboard closed</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyshidden</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape, open"> - <d:description>The phone in landscape view with the keyboard open</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keysexposed</d:keyboard-state> - <d:nav-state>navexposed</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 3.2in QVGA (ADP2) - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>3.2</d:diagonal-length> - <d:pixel-density>mdpi</d:pixel-density> - <d:screen-ratio>notlong</d:screen-ratio> - <d:dimensions> - <d:x-dimension>320</d:x-dimension> - <d:y-dimension>480</d:y-dimension> - </d:dimensions> - <d:xdpi>180.6</d:xdpi> - <d:ydpi>182</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>trackball</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navexposed</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navexposed</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 3.3in WQVGA - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>3.3</d:diagonal-length> - <d:pixel-density>ldpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>240</d:x-dimension> - <d:y-dimension>400</d:y-dimension> - </d:dimensions> - <d:xdpi>141</d:xdpi> - <d:ydpi>141</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - <d:device> - <d:name> - 3.4in WQVGA - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>3.4</d:diagonal-length> - <d:pixel-density>ldpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>240</d:x-dimension> - <d:y-dimension>432</d:y-dimension> - </d:dimensions> - <d:xdpi>145</d:xdpi> - <d:ydpi>145</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 3.7in WVGA (Nexus One) - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>3.4</d:diagonal-length> - <d:pixel-density>hdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>480</d:x-dimension> - <d:y-dimension>800</d:y-dimension> - </d:dimensions> - <d:xdpi>254</d:xdpi> - <d:ydpi>254</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>trackball</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navexposed</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navexposed</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 3.7 FWVGA slider - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>3.7</d:diagonal-length> - <d:pixel-density>hdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>480</d:x-dimension> - <d:y-dimension>854</d:y-dimension> - </d:dimensions> - <d:xdpi>265</d:xdpi> - <d:ydpi>265</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>qwerty</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyshidden</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape, closed"> - <d:description>The phone in landscape view with the keyboard closed</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyshidden</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape, open"> - <d:description>The phone in landscape view with the keyboard open</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keysexposed</d:keyboard-state> - <d:nav-state>navexposed</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 4in WVGA (Nexus S) - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>4.0</d:diagonal-length> - <d:pixel-density>hdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>480</d:x-dimension> - <d:y-dimension>800</d:y-dimension> - </d:dimensions> - <d:xdpi>235</d:xdpi> - <d:ydpi>235</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 4.65in 720p (Galaxy Nexus) - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>4.65</d:diagonal-length> <!-- In inches --> - <d:pixel-density>xhdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>720</d:x-dimension> - <d:y-dimension>1280</d:y-dimension> - </d:dimensions> - <d:xdpi>316</d:xdpi> - <d:ydpi>316</d:ydpi> - <d:touch> - <d:multitouch>jazz-hands</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>front</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>false</d:flash> - </d:camera> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="GiB">1</d:ram> - <d:buttons>soft</d:buttons> - <d:internal-storage unit="GiB">16</d:internal-storage> - <d:removable-storage unit="KiB"></d:removable-storage> - <d:cpu>OMAP 4460</d:cpu> <!-- cpu type (Tegra3) freeform --> - <d:gpu>PowerVR SGX540</d:gpu> - <d:abi> - armeabi - armeabi-v7a - </d:abi> - <!--dock (car, desk, tv, none)--> - <d:dock> - car - desk - </d:dock> - <!-- plugged in (never, charge, always) --> - <d:power-type>battery</d:power-type> - </d:hardware> - <d:software> - <d:api-level>14-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles> - HSP - HFP - SPP - A2DP - AVRCP - OPP - PBAP - GAVDP - AVDTP - HID - HDP - PAN - </d:bluetooth-profiles> - <d:gl-version>2.0</d:gl-version> - <!-- - These can be gotten via - javax.microedition.khronos.opengles.GL10.glGetString(GL10.GL_EXTENSIONS); - --> - <d:gl-extensions> - GL_EXT_discard_framebuffer - GL_EXT_multi_draw_arrays - GL_EXT_shader_texture_lod - GL_EXT_texture_format_BGRA8888 - GL_IMG_multisampled_render_to_texture - GL_IMG_program_binary - GL_IMG_read_format - GL_IMG_shader_binary - GL_IMG_texture_compression_pvrtc - GL_IMG_texture_format_BGRA8888 - GL_IMG_texture_npot - GL_OES_compressed_ETC1_RGB8_texture - GL_OES_depth_texture - GL_OES_depth24 - GL_OES_EGL_image - GL_OES_EGL_image_external - GL_OES_egl_sync - GL_OES_element_index_uint - GL_OES_fragment_precision_high - GL_OES_get_program_binary - GL_OES_mapbuffer - GL_OES_packed_depth_stencil - GL_OES_required_internalformat - GL_OES_rgb8_rgba8 - GL_OES_standard_derivatives - GL_OES_texture_float - GL_OES_texture_half_float - GL_OES_vertex_array_object - GL_OES_vertex_half_float - </d:gl-extensions> - <d:status-bar>true</d:status-bar> - </d:software> - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>nonav</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>nonav</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 4.7in WXGA - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>normal</d:screen-size> - <d:diagonal-length>4.7</d:diagonal-length> - <d:pixel-density>xhdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>1280</d:x-dimension> - <d:y-dimension>720</d:y-dimension> - </d:dimensions> - <d:xdpi>320</d:xdpi> - <d:ydpi>320</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 5.1in WVGA - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>large</d:screen-size> - <d:diagonal-length>5.1</d:diagonal-length> - <d:pixel-density>mdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>480</d:x-dimension> - <d:y-dimension>800</d:y-dimension> - </d:dimensions> - <d:xdpi>183</d:xdpi> - <d:ydpi>183</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 5.4in FWVGA - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>large</d:screen-size> - <d:diagonal-length>5.4</d:diagonal-length> - <d:pixel-density>mdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>480</d:x-dimension> - <d:y-dimension>854</d:y-dimension> - </d:dimensions> - <d:xdpi>181</d:xdpi> - <d:ydpi>181</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - - <d:device> - <d:name> - 7in WSVGA (Tablet) - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>large</d:screen-size> - <d:diagonal-length>7.0</d:diagonal-length> - <d:pixel-density>mdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>1024</d:x-dimension> - <d:y-dimension>600</d:y-dimension> - </d:dimensions> - <d:xdpi>169</d:xdpi> - <d:ydpi>169</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>front</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> - - - <d:device> - <d:name> - 10.1in WXGA (Tablet) - </d:name> - <d:manufacturer> - Generic - </d:manufacturer> - <d:hardware> - <d:screen> - <d:screen-size>xlarge</d:screen-size> - <d:diagonal-length>10.1</d:diagonal-length> - <d:pixel-density>mdpi</d:pixel-density> - <d:screen-ratio>long</d:screen-ratio> - <d:dimensions> - <d:x-dimension>1280</d:x-dimension> - <d:y-dimension>800</d:y-dimension> - </d:dimensions> - <d:xdpi>149</d:xdpi> - <d:ydpi>149</d:ydpi> - <d:touch> - <d:multitouch>distinct</d:multitouch> - <d:mechanism>finger</d:mechanism> - <d:screen-type>capacitive</d:screen-type> - </d:touch> - </d:screen> - <d:networking> - Bluetooth - Wifi - NFC - </d:networking> - <d:sensors> - Accelerometer - Barometer - Gyroscope - Compass - GPS - ProximitySensor - </d:sensors> - <d:mic>true</d:mic> - <d:camera> - <d:location>front</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:camera> - <d:location>back</d:location> - <d:autofocus>true</d:autofocus> - <d:flash>true</d:flash> - </d:camera> - <d:keyboard>nokeys</d:keyboard> - <d:nav>nonav</d:nav> - <d:ram unit="MiB">512</d:ram> - <d:buttons>hard</d:buttons> - <d:internal-storage unit="GiB">8</d:internal-storage> - <d:removable-storage unit="MiB"></d:removable-storage> - <d:cpu>OMAP 9001</d:cpu> - <d:gpu>Ultra Nexus 3D S++</d:gpu> - <d:abi> - armeabi - armeabi-v7a - mips - x86 - </d:abi> - <d:dock> - car - television - desk - </d:dock> - <d:power-type>battery</d:power-type> - </d:hardware> - - <d:software> - <d:api-level>-</d:api-level> - <d:live-wallpaper-support>true</d:live-wallpaper-support> - <d:bluetooth-profiles /> - <d:gl-version>2.1</d:gl-version> - <d:gl-extensions /> - <d:status-bar>true</d:status-bar> - </d:software> - - <d:state name="Portrait" default="true"> - <d:description>The phone in portrait view</d:description> - <d:screen-orientation>port</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - <d:state name="Landscape"> - <d:description>The phone in landscape view</d:description> - <d:screen-orientation>land</d:screen-orientation> - <d:keyboard-state>keyssoft</d:keyboard-state> - <d:nav-state>navhidden</d:nav-state> - </d:state> - </d:device> -</d:devices> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java deleted file mode 100755 index c4b6b18..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdInfo.java +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.avd; - -import com.android.SdkConstants; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.devices.Device; - -import java.io.File; -import java.util.Collections; -import java.util.Map; - -/** - * An immutable structure describing an Android Virtual Device. - */ -public final class AvdInfo implements Comparable<AvdInfo> { - - /** - * Status for an {@link AvdInfo}. Indicates whether or not this AVD is valid. - */ - public static enum AvdStatus { - /** No error */ - OK, - /** Missing 'path' property in the ini file */ - ERROR_PATH, - /** Missing config.ini file in the AVD data folder */ - ERROR_CONFIG, - /** Missing 'target' property in the ini file */ - ERROR_TARGET_HASH, - /** Target was not resolved from its hash */ - ERROR_TARGET, - /** Unable to parse config.ini */ - ERROR_PROPERTIES, - /** System Image folder in config.ini doesn't exist */ - ERROR_IMAGE_DIR, - /** The {@link Device} this AVD is based on has changed from its original configuration*/ - ERROR_DEVICE_CHANGED, - /** The {@link Device} this AVD is based on is no longer available */ - ERROR_DEVICE_MISSING; - } - - private final String mName; - private final File mIniFile; - private final String mFolderPath; - private final String mTargetHash; - private final IAndroidTarget mTarget; - private final String mAbiType; - private final Map<String, String> mProperties; - private final AvdStatus mStatus; - - /** - * Creates a new valid AVD info. Values are immutable. - * <p/> - * Such an AVD is available and can be used. - * The error string is set to null. - * - * @param name The name of the AVD (for display or reference) - * @param iniFile The path to the config.ini file - * @param folderPath The path to the data directory - * @param targetHash the target hash - * @param target The target. Can be null, if the target was not resolved. - * @param abiType Name of the abi. - * @param properties The property map. Cannot be null. - */ - public AvdInfo(String name, - File iniFile, - String folderPath, - String targetHash, - IAndroidTarget target, - String abiType, - Map<String, String> properties) { - this(name, iniFile, folderPath, targetHash, target, abiType, properties, AvdStatus.OK); - } - - /** - * Creates a new <em>invalid</em> AVD info. Values are immutable. - * <p/> - * Such an AVD is not complete and cannot be used. - * The error string must be non-null. - * - * @param name The name of the AVD (for display or reference) - * @param iniFile The path to the config.ini file - * @param folderPath The path to the data directory - * @param targetHash the target hash - * @param target The target. Can be null, if the target was not resolved. - * @param abiType Name of the abi. - * @param properties The property map. Can be null. - * @param status The {@link AvdStatus} of this AVD. Cannot be null. - */ - public AvdInfo(String name, - File iniFile, - String folderPath, - String targetHash, - IAndroidTarget target, - String abiType, - Map<String, String> properties, - AvdStatus status) { - mName = name; - mIniFile = iniFile; - mFolderPath = folderPath; - mTargetHash = targetHash; - mTarget = target; - mAbiType = abiType; - mProperties = properties == null ? null : Collections.unmodifiableMap(properties); - mStatus = status; - } - - /** Returns the name of the AVD. */ - public String getName() { - return mName; - } - - /** Returns the path of the AVD data directory. */ - public String getDataFolderPath() { - return mFolderPath; - } - - /** Returns the processor type of the AVD. */ - public String getAbiType() { - return mAbiType; - } - - public String getCpuArch() { - String cpuArch = mProperties.get(AvdManager.AVD_INI_CPU_ARCH); - if (cpuArch != null) { - return cpuArch; - } - - // legacy - return SdkConstants.CPU_ARCH_ARM; - } - - public String getDeviceManufacturer() { - String deviceManufacturer = mProperties.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER); - if (deviceManufacturer != null && !deviceManufacturer.isEmpty()) { - return deviceManufacturer; - } - - return ""; - } - - public String getDeviceName() { - String deviceName = mProperties.get(AvdManager.AVD_INI_DEVICE_NAME); - if (deviceName != null && !deviceName.isEmpty()) { - return deviceName; - } - - return ""; - } - - /** Convenience function to return a more user friendly name of the abi type. */ - public static String getPrettyAbiType(String raw) { - String s = null; - if (raw.equalsIgnoreCase(SdkConstants.ABI_ARMEABI)) { - s = "ARM (" + SdkConstants.ABI_ARMEABI + ")"; - - } else if (raw.equalsIgnoreCase(SdkConstants.ABI_ARMEABI_V7A)) { - s = "ARM (" + SdkConstants.ABI_ARMEABI_V7A + ")"; - - } else if (raw.equalsIgnoreCase(SdkConstants.ABI_INTEL_ATOM)) { - s = "Intel Atom (" + SdkConstants.ABI_INTEL_ATOM + ")"; - - } else if (raw.equalsIgnoreCase(SdkConstants.ABI_MIPS)) { - s = "MIPS (" + SdkConstants.ABI_MIPS + ")"; - - } else { - s = raw + " (" + raw + ")"; - } - return s; - } - - /** - * Returns the target hash string. - */ - public String getTargetHash() { - return mTargetHash; - } - - /** Returns the target of the AVD, or <code>null</code> if it has not been resolved. */ - public IAndroidTarget getTarget() { - return mTarget; - } - - /** Returns the {@link AvdStatus} of the receiver. */ - public AvdStatus getStatus() { - return mStatus; - } - - /** - * Helper method that returns the default AVD folder that would be used for a given - * AVD name <em>if and only if</em> the AVD was created with the default choice. - * <p/> - * Callers must NOT use this to "guess" the actual folder from an actual AVD since - * the purpose of the AVD .ini file is to be able to change this folder. Callers - * should however use this to create a new {@link AvdInfo} to setup its data folder - * to the default. - * <p/> - * The default is {@code getDefaultAvdFolder()/avdname.avd/}. - * <p/> - * For an actual existing AVD, callers must use {@link #getDataFolderPath()} instead. - * - * @param manager The AVD Manager, used to get the AVD storage path. - * @param avdName The name of the desired AVD. - * @throws AndroidLocationException if there's a problem getting android root directory. - */ - public static File getDefaultAvdFolder(AvdManager manager, String avdName) - throws AndroidLocationException { - return new File(manager.getBaseAvdFolder(), - avdName + AvdManager.AVD_FOLDER_EXTENSION); - } - - /** - * Helper method that returns the .ini {@link File} for a given AVD name. - * <p/> - * The default is {@code getDefaultAvdFolder()/avdname.ini}. - * - * @param manager The AVD Manager, used to get the AVD storage path. - * @param avdName The name of the desired AVD. - * @throws AndroidLocationException if there's a problem getting android root directory. - */ - public static File getDefaultIniFile(AvdManager manager, String avdName) - throws AndroidLocationException { - String avdRoot = manager.getBaseAvdFolder(); - return new File(avdRoot, avdName + AvdManager.INI_EXTENSION); - } - - /** - * Returns the .ini {@link File} for this AVD. - */ - public File getIniFile() { - return mIniFile; - } - - /** - * Helper method that returns the Config {@link File} for a given AVD name. - */ - public static File getConfigFile(String path) { - return new File(path, AvdManager.CONFIG_INI); - } - - /** - * Returns the Config {@link File} for this AVD. - */ - public File getConfigFile() { - return getConfigFile(mFolderPath); - } - - /** - * Returns an unmodifiable map of properties for the AVD. This can be null. - */ - public Map<String, String> getProperties() { - return mProperties; - } - - /** - * Returns the error message for the AVD or <code>null</code> if {@link #getStatus()} - * returns {@link AvdStatus#OK} - */ - public String getErrorMessage() { - switch (mStatus) { - case ERROR_PATH: - return String.format("Missing AVD 'path' property in %1$s", getIniFile()); - case ERROR_CONFIG: - return String.format("Missing config.ini file in %1$s", mFolderPath); - case ERROR_TARGET_HASH: - return String.format("Missing 'target' property in %1$s", getIniFile()); - case ERROR_TARGET: - return String.format("Unknown target '%1$s' in %2$s", - mTargetHash, getIniFile()); - case ERROR_PROPERTIES: - return String.format("Failed to parse properties from %1$s", - getConfigFile()); - case ERROR_IMAGE_DIR: - return String.format( - "Invalid value in image.sysdir. Run 'android update avd -n %1$s'", - mName); - case ERROR_DEVICE_CHANGED: - return String.format("%1$s %2$s configuration has changed since AVD creation", - mProperties.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER), - mProperties.get(AvdManager.AVD_INI_DEVICE_NAME)); - case ERROR_DEVICE_MISSING: - return String.format("%1$s %2$s no longer exists as a device", - mProperties.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER), - mProperties.get(AvdManager.AVD_INI_DEVICE_NAME)); - case OK: - assert false; - return null; - } - - return null; - } - - /** - * Returns whether an emulator is currently running the AVD. - */ - public boolean isRunning() { - File f = new File(mFolderPath, "userdata-qemu.img.lock"); //$NON-NLS-1$ - return f.isFile(); - } - - /** - * Compares this object with the specified object for order. Returns a - * negative integer, zero, or a positive integer as this object is less - * than, equal to, or greater than the specified object. - * - * @param o the Object to be compared. - * @return a negative integer, zero, or a positive integer as this object is - * less than, equal to, or greater than the specified object. - */ - @Override - public int compareTo(AvdInfo o) { - // first handle possible missing targets (if the AVD failed to load for unresolved targets) - if (mTarget == null && o != null && o.mTarget == null) { - return 0; - } if (mTarget == null) { - return +1; - } else if (o == null || o.mTarget == null) { - return -1; - } - - // then compare the targets - int targetDiff = mTarget.compareTo(o.mTarget); - - if (targetDiff == 0) { - // same target? compare on the avd name - return mName.compareTo(o.mName); - } - - return targetDiff; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java deleted file mode 100644 index d2ba1b6..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/AvdManager.java +++ /dev/null @@ -1,1691 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.avd; - -import com.android.SdkConstants; -import com.android.annotations.Nullable; -import com.android.io.FileWrapper; -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISystemImage; -import com.android.sdklib.SdkManager; -import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.devices.DeviceManager.DeviceStatus; -import com.android.sdklib.internal.avd.AvdInfo.AvdStatus; -import com.android.sdklib.internal.project.ProjectProperties; -import com.android.sdklib.util.GrabProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.IProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.Wait; -import com.android.utils.ILogger; -import com.android.utils.Pair; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.WeakHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Android Virtual Device Manager to manage AVDs. - */ -public class AvdManager { - - /** - * Exception thrown when something is wrong with a target path. - */ - private final static class InvalidTargetPathException extends Exception { - private static final long serialVersionUID = 1L; - - InvalidTargetPathException(String message) { - super(message); - } - } - - public static final String AVD_FOLDER_EXTENSION = ".avd"; //$NON-NLS-1$ - - public final static String AVD_INFO_PATH = "path"; //$NON-NLS-1$ - public final static String AVD_INFO_TARGET = "target"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing the abi type of the specific avd - * - */ - public final static String AVD_INI_ABI_TYPE = "abi.type"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing the CPU architecture of the specific avd - * - */ - public final static String AVD_INI_CPU_ARCH = "hw.cpu.arch"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing the CPU architecture of the specific avd - * - */ - public final static String AVD_INI_CPU_MODEL = "hw.cpu.model"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing the manufacturer of the device this avd was based on. - */ - public static final String AVD_INI_DEVICE_MANUFACTURER = "hw.device.manufacturer"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing the name of the device this avd was based on. - */ - public static final String AVD_INI_DEVICE_NAME = "hw.device.name"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing the SDK-relative path of the skin folder, if any, - * or a 320x480 like constant for a numeric skin size. - * - * @see #NUMERIC_SKIN_SIZE - */ - public final static String AVD_INI_SKIN_PATH = "skin.path"; //$NON-NLS-1$ - /** - * AVD/config.ini key name representing an UI name for the skin. - * This config key is ignored by the emulator. It is only used by the SDK manager or - * tools to give a friendlier name to the skin. - * If missing, use the {@link #AVD_INI_SKIN_PATH} key instead. - */ - public final static String AVD_INI_SKIN_NAME = "skin.name"; //$NON-NLS-1$ - /** - * AVD/config.ini key name representing the path to the sdcard file. - * If missing, the default name "sdcard.img" will be used for the sdcard, if there's such - * a file. - * - * @see #SDCARD_IMG - */ - public final static String AVD_INI_SDCARD_PATH = "sdcard.path"; //$NON-NLS-1$ - /** - * AVD/config.ini key name representing the size of the SD card. - * This property is for UI purposes only. It is not used by the emulator. - * - * @see #SDCARD_SIZE_PATTERN - * @see #parseSdcardSize(String, String[]) - */ - public final static String AVD_INI_SDCARD_SIZE = "sdcard.size"; //$NON-NLS-1$ - /** - * AVD/config.ini key name representing the first path where the emulator looks - * for system images. Typically this is the path to the add-on system image or - * the path to the platform system image if there's no add-on. - * <p/> - * The emulator looks at {@link #AVD_INI_IMAGES_1} before {@link #AVD_INI_IMAGES_2}. - */ - public final static String AVD_INI_IMAGES_1 = "image.sysdir.1"; //$NON-NLS-1$ - /** - * AVD/config.ini key name representing the second path where the emulator looks - * for system images. Typically this is the path to the platform system image. - * - * @see #AVD_INI_IMAGES_1 - */ - public final static String AVD_INI_IMAGES_2 = "image.sysdir.2"; //$NON-NLS-1$ - /** - * AVD/config.ini key name representing the presence of the snapshots file. - * This property is for UI purposes only. It is not used by the emulator. - * - * @see #SNAPSHOTS_IMG - */ - public final static String AVD_INI_SNAPSHOT_PRESENT = "snapshot.present"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing whether hardware OpenGLES emulation is enabled - */ - public final static String AVD_INI_GPU_EMULATION = "hw.gpu.enabled"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing how to emulate the front facing camera - */ - public final static String AVD_INI_CAMERA_FRONT = "hw.camera.front"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing how to emulate the rear facing camera - */ - public final static String AVD_INI_CAMERA_BACK = "hw.camera.back"; //$NON-NLS-1$ - - /** - * AVD/config.ini key name representing the amount of RAM the emulated device should have - */ - public final static String AVD_INI_RAM_SIZE = "hw.ramSize"; - - /** - * AVD/config.ini key name representing the amount of memory available to applications by default - */ - public final static String AVD_INI_VM_HEAP_SIZE = "vm.heapSize"; - - /** - * AVD/config.ini key name representing the size of the data partition - */ - public final static String AVD_INI_DATA_PARTITION_SIZE = "disk.dataPartition.size"; - - /** - * AVD/config.ini key name representing the hash of the device this AVD is based on - */ - public final static String AVD_INI_DEVICE_HASH = "hw.device.hash"; - - /** - * Pattern to match pixel-sized skin "names", e.g. "320x480". - */ - public final static Pattern NUMERIC_SKIN_SIZE = Pattern.compile("([0-9]{2,})x([0-9]{2,})"); //$NON-NLS-1$ - - private final static String USERDATA_IMG = "userdata.img"; //$NON-NLS-1$ - final static String CONFIG_INI = "config.ini"; //$NON-NLS-1$ - private final static String SDCARD_IMG = "sdcard.img"; //$NON-NLS-1$ - private final static String SNAPSHOTS_IMG = "snapshots.img"; //$NON-NLS-1$ - - final static String INI_EXTENSION = ".ini"; //$NON-NLS-1$ - private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\" + //$NON-NLS-1$ - INI_EXTENSION + "$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - private final static Pattern IMAGE_NAME_PATTERN = Pattern.compile("(.+)\\.img$", //$NON-NLS-1$ - Pattern.CASE_INSENSITIVE); - - /** - * Pattern for matching SD Card sizes, e.g. "4K" or "16M". - * Callers should use {@link #parseSdcardSize(String, String[])} instead of using this directly. - */ - private final static Pattern SDCARD_SIZE_PATTERN = Pattern.compile("(\\d+)([KMG])"); //$NON-NLS-1$ - - /** - * Minimal size of an SDCard image file in bytes. Currently 9 MiB. - */ - - public static final long SDCARD_MIN_BYTE_SIZE = 9<<20; - /** - * Maximal size of an SDCard image file in bytes. Currently 1023 GiB. - */ - public static final long SDCARD_MAX_BYTE_SIZE = 1023L<<30; - - /** The sdcard string represents a valid number but the size is outside of the allowed range. */ - public final static int SDCARD_SIZE_NOT_IN_RANGE = 0; - /** The sdcard string looks like a size number+suffix but the number failed to decode. */ - public final static int SDCARD_SIZE_INVALID = -1; - /** The sdcard string doesn't look like a size, it might be a path instead. */ - public final static int SDCARD_NOT_SIZE_PATTERN = -2; - - /** Regex used to validate characters that compose an AVD name. */ - public final static Pattern RE_AVD_NAME = Pattern.compile("[a-zA-Z0-9._-]+"); //$NON-NLS-1$ - - /** List of valid characters for an AVD name. Used for display purposes. */ - public final static String CHARS_AVD_NAME = "a-z A-Z 0-9 . _ -"; //$NON-NLS-1$ - - public final static String HARDWARE_INI = "hardware.ini"; //$NON-NLS-1$ - - /** - * Status returned by {@link AvdManager#isAvdNameConflicting(String)}. - */ - public static enum AvdConflict { - /** There is no known conflict for the given AVD name. */ - NO_CONFLICT, - /** The AVD name conflicts with an existing valid AVD. */ - CONFLICT_EXISTING_AVD, - /** The AVD name conflicts with an existing invalid AVD. */ - CONFLICT_INVALID_AVD, - /** - * The AVD name does not conflict with any known AVD however there are - * files or directory that would cause a conflict if this were to be created. - */ - CONFLICT_EXISTING_PATH, - } - - // A map where the keys are the locations of the SDK and the values are the corresponding - // AvdManagers. This prevents us from creating multiple AvdManagers for the same SDK and having - // them get out of sync. - private static final Map<String, AvdManager> mManagers = - Collections.synchronizedMap(new WeakHashMap<String, AvdManager>()); - - private final ArrayList<AvdInfo> mAllAvdList = new ArrayList<AvdInfo>(); - private AvdInfo[] mValidAvdList; - private AvdInfo[] mBrokenAvdList; - private final SdkManager mSdkManager; - - /** - * Creates an AVD Manager for a given SDK represented by a {@link SdkManager}. - * @param sdkManager The SDK. - * @param log The log object to receive the log of the initial loading of the AVDs. - * This log object is not kept by this instance of AvdManager and each - * method takes its own logger. The rationale is that the AvdManager - * might be called from a variety of context, each with different - * logging needs. Cannot be null. - * @throws AndroidLocationException - */ - protected AvdManager(SdkManager sdkManager, ILogger log) throws AndroidLocationException { - mSdkManager = sdkManager; - buildAvdList(mAllAvdList, log); - } - - public static AvdManager getInstance(SdkManager sdkManager, ILogger log) - throws AndroidLocationException { - synchronized(mManagers) { - AvdManager manager; - if ((manager = mManagers.get(sdkManager.getLocation())) != null) { - return manager; - } - manager = new AvdManager(sdkManager, log); - mManagers.put(sdkManager.getLocation(), manager); - return manager; - } - } - - /** - * Returns the base folder where AVDs are created. - * - * @throws AndroidLocationException - */ - public String getBaseAvdFolder() throws AndroidLocationException { - assert AndroidLocation.getFolder().endsWith(File.separator); - return AndroidLocation.getFolder() + AndroidLocation.FOLDER_AVD; - } - - /** - * Returns the {@link SdkManager} associated with the {@link AvdManager}. - */ - public SdkManager getSdkManager() { - return mSdkManager; - } - - /** - * Parse the sdcard string to decode the size. - * Returns: - * <ul> - * <li> The size in bytes > 0 if the sdcard string is a valid size in the allowed range. - * <li> {@link #SDCARD_SIZE_NOT_IN_RANGE} (0) - * if the sdcard string is a valid size NOT in the allowed range. - * <li> {@link #SDCARD_SIZE_INVALID} (-1) - * if the sdcard string is number that fails to parse correctly. - * <li> {@link #SDCARD_NOT_SIZE_PATTERN} (-2) - * if the sdcard string is not a number, in which case it's probably a file path. - * </ul> - * - * @param sdcard The sdcard string, which can be a file path, a size string or something else. - * @param parsedStrings If non-null, an array of 2 strings. The first string will be - * filled with the parsed numeric size and the second one will be filled with the - * parsed suffix. This is filled even if the returned size is deemed out of range or - * failed to parse. The values are null if the sdcard is not a size pattern. - * @return A size in byte if > 0, or {@link #SDCARD_SIZE_NOT_IN_RANGE}, - * {@link #SDCARD_SIZE_INVALID} or {@link #SDCARD_NOT_SIZE_PATTERN} as error codes. - */ - public static long parseSdcardSize(String sdcard, String[] parsedStrings) { - - if (parsedStrings != null) { - assert parsedStrings.length == 2; - parsedStrings[0] = null; - parsedStrings[1] = null; - } - - Matcher m = SDCARD_SIZE_PATTERN.matcher(sdcard); - if (m.matches()) { - if (parsedStrings != null) { - assert parsedStrings.length == 2; - parsedStrings[0] = m.group(1); - parsedStrings[1] = m.group(2); - } - - // get the sdcard values for checks - try { - long sdcardSize = Long.parseLong(m.group(1)); - - String sdcardSizeModifier = m.group(2); - if ("K".equals(sdcardSizeModifier)) { //$NON-NLS-1$ - sdcardSize <<= 10; - } else if ("M".equals(sdcardSizeModifier)) { //$NON-NLS-1$ - sdcardSize <<= 20; - } else if ("G".equals(sdcardSizeModifier)) { //$NON-NLS-1$ - sdcardSize <<= 30; - } - - if (sdcardSize < SDCARD_MIN_BYTE_SIZE || - sdcardSize > SDCARD_MAX_BYTE_SIZE) { - return SDCARD_SIZE_NOT_IN_RANGE; - } - - return sdcardSize; - } catch (NumberFormatException e) { - // This could happen if the number is too large to fit in a long. - return SDCARD_SIZE_INVALID; - } - } - - return SDCARD_NOT_SIZE_PATTERN; - } - - /** - * Returns all the existing AVDs. - * @return a newly allocated array containing all the AVDs. - */ - public AvdInfo[] getAllAvds() { - synchronized (mAllAvdList) { - return mAllAvdList.toArray(new AvdInfo[mAllAvdList.size()]); - } - } - - /** - * Returns all the valid AVDs. - * @return a newly allocated array containing all valid the AVDs. - */ - public AvdInfo[] getValidAvds() { - synchronized (mAllAvdList) { - if (mValidAvdList == null) { - ArrayList<AvdInfo> list = new ArrayList<AvdInfo>(); - for (AvdInfo avd : mAllAvdList) { - if (avd.getStatus() == AvdStatus.OK) { - list.add(avd); - } - } - - mValidAvdList = list.toArray(new AvdInfo[list.size()]); - } - return mValidAvdList; - } - } - - /** - * Returns all the broken AVDs. - * @return a newly allocated array containing all the broken AVDs. - */ - public AvdInfo[] getBrokenAvds() { - synchronized (mAllAvdList) { - if (mBrokenAvdList == null) { - ArrayList<AvdInfo> list = new ArrayList<AvdInfo>(); - for (AvdInfo avd : mAllAvdList) { - if (avd.getStatus() != AvdStatus.OK) { - list.add(avd); - } - } - mBrokenAvdList = list.toArray(new AvdInfo[list.size()]); - } - return mBrokenAvdList; - } - } - - /** - * Returns the {@link AvdInfo} matching the given <var>name</var>. - * <p/> - * The search is case-insensitive. - * - * @param name the name of the AVD to return - * @param validAvdOnly if <code>true</code>, only look through the list of valid AVDs. - * @return the matching AvdInfo or <code>null</code> if none were found. - */ - public AvdInfo getAvd(String name, boolean validAvdOnly) { - - boolean ignoreCase = SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS; - - if (validAvdOnly) { - for (AvdInfo info : getValidAvds()) { - String name2 = info.getName(); - if (name2.equals(name) || (ignoreCase && name2.equalsIgnoreCase(name))) { - return info; - } - } - } else { - synchronized (mAllAvdList) { - for (AvdInfo info : mAllAvdList) { - String name2 = info.getName(); - if (name2.equals(name) || (ignoreCase && name2.equalsIgnoreCase(name))) { - return info; - } - } - } - } - - return null; - } - - /** - * Returns whether this AVD name would generate a conflict. - * - * @param name the name of the AVD to return - * @return A pair of {@link AvdConflict} and the path or AVD name that conflicts. - */ - public Pair<AvdConflict, String> isAvdNameConflicting(String name) { - - boolean ignoreCase = SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS; - - // Check whether we have a conflict with an existing or invalid AVD - // known to the manager. - synchronized (mAllAvdList) { - for (AvdInfo info : mAllAvdList) { - String name2 = info.getName(); - if (name2.equals(name) || (ignoreCase && name2.equalsIgnoreCase(name))) { - if (info.getStatus() == AvdStatus.OK) { - return Pair.of(AvdConflict.CONFLICT_EXISTING_AVD, name2); - } else { - return Pair.of(AvdConflict.CONFLICT_INVALID_AVD, name2); - } - } - } - } - - // No conflict with known AVDs. - // Are some existing files/folders in the way of creating this AVD? - - try { - File file = AvdInfo.getDefaultIniFile(this, name); - if (file.exists()) { - return Pair.of(AvdConflict.CONFLICT_EXISTING_PATH, file.getPath()); - } - - file = AvdInfo.getDefaultAvdFolder(this, name); - if (file.exists()) { - return Pair.of(AvdConflict.CONFLICT_EXISTING_PATH, file.getPath()); - } - - } catch (AndroidLocationException e) { - // ignore - } - - - return Pair.of(AvdConflict.NO_CONFLICT, null); - } - - /** - * Reloads the AVD list. - * @param log the log object to receive action logs. Cannot be null. - * @throws AndroidLocationException if there was an error finding the location of the - * AVD folder. - */ - public void reloadAvds(ILogger log) throws AndroidLocationException { - // build the list in a temp list first, in case the method throws an exception. - // It's better than deleting the whole list before reading the new one. - ArrayList<AvdInfo> allList = new ArrayList<AvdInfo>(); - buildAvdList(allList, log); - - synchronized (mAllAvdList) { - mAllAvdList.clear(); - mAllAvdList.addAll(allList); - mValidAvdList = mBrokenAvdList = null; - } - } - - /** - * Creates a new AVD. It is expected that there is no existing AVD with this name already. - * - * @param avdFolder the data folder for the AVD. It will be created as needed. - * Unless you want to locate it in a specific directory, the ideal default is - * {@code AvdManager.AvdInfo.getAvdFolder}. - * @param avdName the name of the AVD - * @param target the target of the AVD - * @param abiType the abi type of the AVD - * @param skinName the name of the skin. Can be null. Must have been verified by caller. - * @param sdcard the parameter value for the sdCard. Can be null. This is either a path to - * an existing sdcard image or a sdcard size (\d+, \d+K, \dM). - * @param hardwareConfig the hardware setup for the AVD. Can be null to use defaults. - * @param createSnapshot If true copy a blank snapshot image into the AVD. - * @param removePrevious If true remove any previous files. - * @param editExisting If true, edit an existing AVD, changing only the minimum required. - * This won't remove files unless required or unless {@code removePrevious} is set. - * @param log the log object to receive action logs. Cannot be null. - * @return The new {@link AvdInfo} in case of success (which has just been added to the - * internal list) or null in case of failure. - */ - public AvdInfo createAvd( - File avdFolder, - String avdName, - IAndroidTarget target, - String abiType, - String skinName, - String sdcard, - Map<String,String> hardwareConfig, - boolean createSnapshot, - boolean removePrevious, - boolean editExisting, - ILogger log) { - if (log == null) { - throw new IllegalArgumentException("log cannot be null"); - } - - File iniFile = null; - boolean needCleanup = false; - try { - if (avdFolder.exists()) { - if (removePrevious) { - // AVD already exists and removePrevious is set, try to remove the - // directory's content first (but not the directory itself). - try { - deleteContentOf(avdFolder); - } catch (SecurityException e) { - log.error(e, "Failed to delete %1$s", avdFolder.getAbsolutePath()); - } - } else if (!editExisting) { - // AVD shouldn't already exist if removePrevious is false and - // we're not editing an existing AVD. - log.error(null, - "Folder %1$s is in the way. Use --force if you want to overwrite.", - avdFolder.getAbsolutePath()); - return null; - } - } else { - // create the AVD folder. - avdFolder.mkdir(); - // We're not editing an existing AVD. - editExisting = false; - } - - // actually write the ini file - iniFile = createAvdIniFile(avdName, avdFolder, target, removePrevious); - - // writes the userdata.img in it. - - File userdataSrc = null; - - // Look for a system image in the add-on. - // If we don't find one there, look in the base platform. - ISystemImage systemImage = target.getSystemImage(abiType); - - if (systemImage != null) { - File imageFolder = systemImage.getLocation(); - userdataSrc = new File(imageFolder, USERDATA_IMG); - } - - if ((userdataSrc == null || !userdataSrc.exists()) && !target.isPlatform()) { - // If we don't find a system-image in the add-on, look into the platform. - - systemImage = target.getParent().getSystemImage(abiType); - if (systemImage != null) { - File imageFolder = systemImage.getLocation(); - userdataSrc = new File(imageFolder, USERDATA_IMG); - } - } - - if (userdataSrc == null || !userdataSrc.exists()) { - log.error(null, - "Unable to find a '%1$s' file for ABI %2$s to copy into the AVD folder.", - USERDATA_IMG, - abiType); - needCleanup = true; - return null; - } - - File userdataDest = new File(avdFolder, USERDATA_IMG); - - copyImageFile(userdataSrc, userdataDest); - - if (userdataDest.exists() == false) { - log.error(null, "Unable to create '%1$s' file in the AVD folder.", - userdataDest); - needCleanup = true; - return null; - } - - // Config file. - HashMap<String, String> values = new HashMap<String, String>(); - - if (setImagePathProperties(target, abiType, values, log) == false) { - log.error(null, "Failed to set image path properties in the AVD folder."); - needCleanup = true; - return null; - } - - // Create the snapshot file - if (createSnapshot) { - File snapshotDest = new File(avdFolder, SNAPSHOTS_IMG); - if (snapshotDest.isFile() && editExisting) { - log.info("Snapshot image already present, was not changed.\n"); - - } else { - String toolsLib = mSdkManager.getLocation() + File.separator - + SdkConstants.OS_SDK_TOOLS_LIB_EMULATOR_FOLDER; - File snapshotBlank = new File(toolsLib, SNAPSHOTS_IMG); - if (snapshotBlank.exists() == false) { - log.error(null, - "Unable to find a '%2$s%1$s' file to copy into the AVD folder.", - SNAPSHOTS_IMG, toolsLib); - needCleanup = true; - return null; - } - - copyImageFile(snapshotBlank, snapshotDest); - } - values.put(AVD_INI_SNAPSHOT_PRESENT, "true"); - } - - // Now the abi type - values.put(AVD_INI_ABI_TYPE, abiType); - - // and the cpu arch. - if (SdkConstants.ABI_ARMEABI.equals(abiType)) { - values.put(AVD_INI_CPU_ARCH, SdkConstants.CPU_ARCH_ARM); - } else if (SdkConstants.ABI_ARMEABI_V7A.equals(abiType)) { - values.put(AVD_INI_CPU_ARCH, SdkConstants.CPU_ARCH_ARM); - values.put(AVD_INI_CPU_MODEL, SdkConstants.CPU_MODEL_CORTEX_A8); - } else if (SdkConstants.ABI_INTEL_ATOM.equals(abiType)) { - values.put(AVD_INI_CPU_ARCH, SdkConstants.CPU_ARCH_INTEL_ATOM); - } else if (SdkConstants.ABI_MIPS.equals(abiType)) { - values.put(AVD_INI_CPU_ARCH, SdkConstants.CPU_ARCH_MIPS); - } else { - log.error(null, - "ABI %1$s is not supported by this version of the SDK Tools", abiType); - needCleanup = true; - return null; - } - - // Now the skin. - if (skinName == null || skinName.length() == 0) { - skinName = target.getDefaultSkin(); - } - - if (NUMERIC_SKIN_SIZE.matcher(skinName).matches()) { - // Skin name is an actual screen resolution. - // Set skin.name for display purposes in the AVD manager and - // set skin.path for use by the emulator. - values.put(AVD_INI_SKIN_NAME, skinName); - values.put(AVD_INI_SKIN_PATH, skinName); - } else { - // get the path of the skin (relative to the SDK) - // assume skin name is valid - String skinPath = getSkinRelativePath(skinName, target, log); - if (skinPath == null) { - log.error(null, "Missing skinpath in the AVD folder."); - needCleanup = true; - return null; - } - - values.put(AVD_INI_SKIN_PATH, skinPath); - values.put(AVD_INI_SKIN_NAME, skinName); - } - - if (sdcard != null && sdcard.length() > 0) { - // Sdcard is possibly a size. In that case we create a file called 'sdcard.img' - // in the AVD folder, and do not put any value in config.ini. - - long sdcardSize = parseSdcardSize(sdcard, null/*parsedStrings*/); - - if (sdcardSize == SDCARD_SIZE_NOT_IN_RANGE) { - log.error(null, "SD Card size must be in the range 9 MiB..1023 GiB."); - needCleanup = true; - return null; - - } else if (sdcardSize == SDCARD_SIZE_INVALID) { - log.error(null, "Unable to parse SD Card size"); - needCleanup = true; - return null; - - } else if (sdcardSize == SDCARD_NOT_SIZE_PATTERN) { - File sdcardFile = new File(sdcard); - if (sdcardFile.isFile()) { - // sdcard value is an external sdcard, so we put its path into the config.ini - values.put(AVD_INI_SDCARD_PATH, sdcard); - } else { - log.error(null, "'%1$s' is not recognized as a valid sdcard value.\n" - + "Value should be:\n" + "1. path to an sdcard.\n" - + "2. size of the sdcard to create: <size>[K|M]", sdcard); - needCleanup = true; - return null; - } - } else { - // create the sdcard. - File sdcardFile = new File(avdFolder, SDCARD_IMG); - - boolean runMkSdcard = true; - if (sdcardFile.exists()) { - if (sdcardFile.length() == sdcardSize && editExisting) { - // There's already an sdcard file with the right size and we're - // not overriding it... so don't remove it. - runMkSdcard = false; - log.info("SD Card already present with same size, was not changed.\n"); - } - } - - if (runMkSdcard) { - String path = sdcardFile.getAbsolutePath(); - - // execute mksdcard with the proper parameters. - File toolsFolder = new File(mSdkManager.getLocation(), - SdkConstants.FD_TOOLS); - File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName()); - - if (mkSdCard.isFile() == false) { - log.error(null, "'%1$s' is missing from the SDK tools folder.", - mkSdCard.getName()); - needCleanup = true; - return null; - } - - if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path, log) == false) { - log.error(null, "Failed to create sdcard in the AVD folder."); - needCleanup = true; - return null; // mksdcard output has already been displayed, no need to - // output anything else. - } - } - - // add a property containing the size of the sdcard for display purpose - // only when the dev does 'android list avd' - values.put(AVD_INI_SDCARD_SIZE, sdcard); - } - } - - // add the hardware config to the config file. - // priority order is: - // - values provided by the user - // - values provided by the skin - // - values provided by the target (add-on only). - // In order to follow this priority, we'll add the lowest priority values first and then - // override by higher priority values. - // In the case of a platform with override values from the user, the skin value might - // already be there, but it's ok. - - HashMap<String, String> finalHardwareValues = new HashMap<String, String>(); - - FileWrapper targetHardwareFile = new FileWrapper(target.getLocation(), - AvdManager.HARDWARE_INI); - if (targetHardwareFile.isFile()) { - Map<String, String> targetHardwareConfig = ProjectProperties.parsePropertyFile( - targetHardwareFile, log); - - if (targetHardwareConfig != null) { - finalHardwareValues.putAll(targetHardwareConfig); - values.putAll(targetHardwareConfig); - } - } - - // get the hardware properties for this skin - File skinFolder = getSkinPath(skinName, target); - FileWrapper skinHardwareFile = new FileWrapper(skinFolder, AvdManager.HARDWARE_INI); - if (skinHardwareFile.isFile()) { - Map<String, String> skinHardwareConfig = ProjectProperties.parsePropertyFile( - skinHardwareFile, log); - - if (skinHardwareConfig != null) { - finalHardwareValues.putAll(skinHardwareConfig); - values.putAll(skinHardwareConfig); - } - } - - // finally put the hardware provided by the user. - if (hardwareConfig != null) { - finalHardwareValues.putAll(hardwareConfig); - values.putAll(hardwareConfig); - } - - File configIniFile = new File(avdFolder, CONFIG_INI); - writeIniFile(configIniFile, values); - - // Generate the log report first because we want to control where line breaks - // are located when generating the hardware config list. - StringBuilder report = new StringBuilder(); - - if (target.isPlatform()) { - if (editExisting) { - report.append(String.format("Updated AVD '%1$s' based on %2$s", - avdName, target.getName())); - } else { - report.append(String.format("Created AVD '%1$s' based on %2$s", - avdName, target.getName())); - } - } else { - if (editExisting) { - report.append(String.format("Updated AVD '%1$s' based on %2$s (%3$s)", avdName, - target.getName(), target.getVendor())); - } else { - report.append(String.format("Created AVD '%1$s' based on %2$s (%3$s)", avdName, - target.getName(), target.getVendor())); - } - } - report.append(String.format(", %s processor", AvdInfo.getPrettyAbiType(abiType))); - - // display the chosen hardware config - if (finalHardwareValues.size() > 0) { - report.append(",\nwith the following hardware config:\n"); - for (Entry<String, String> entry : finalHardwareValues.entrySet()) { - report.append(String.format("%s=%s\n",entry.getKey(), entry.getValue())); - } - } else { - report.append("\n"); - } - - log.info(report.toString()); - - // create the AvdInfo object, and add it to the list - AvdInfo newAvdInfo = new AvdInfo( - avdName, - iniFile, - avdFolder.getAbsolutePath(), - target.hashString(), - target, abiType, values); - - AvdInfo oldAvdInfo = getAvd(avdName, false /*validAvdOnly*/); - - synchronized (mAllAvdList) { - if (oldAvdInfo != null && (removePrevious || editExisting)) { - mAllAvdList.remove(oldAvdInfo); - } - mAllAvdList.add(newAvdInfo); - mValidAvdList = mBrokenAvdList = null; - } - - if ((removePrevious || editExisting) && - newAvdInfo != null && - oldAvdInfo != null && - !oldAvdInfo.getDataFolderPath().equals(newAvdInfo.getDataFolderPath())) { - log.warning("Removing previous AVD directory at %s", - oldAvdInfo.getDataFolderPath()); - // Remove the old data directory - File dir = new File(oldAvdInfo.getDataFolderPath()); - try { - deleteContentOf(dir); - dir.delete(); - } catch (SecurityException e) { - log.error(e, "Failed to delete %1$s", dir.getAbsolutePath()); - } - } - - return newAvdInfo; - } catch (AndroidLocationException e) { - log.error(e, null); - } catch (IOException e) { - log.error(e, null); - } catch (SecurityException e) { - log.error(e, null); - } finally { - if (needCleanup) { - if (iniFile != null && iniFile.exists()) { - iniFile.delete(); - } - - try { - deleteContentOf(avdFolder); - avdFolder.delete(); - } catch (SecurityException e) { - log.error(e, "Failed to delete %1$s", avdFolder.getAbsolutePath()); - } - } - } - - return null; - } - - /** - * Copy the nominated file to the given destination. - * - * @throws FileNotFoundException - * @throws IOException - */ - private void copyImageFile(File source, File destination) - throws FileNotFoundException, IOException { - FileInputStream fis = new FileInputStream(source); - FileOutputStream fos = new FileOutputStream(destination); - - byte[] buffer = new byte[4096]; - int count; - while ((count = fis.read(buffer)) != -1) { - fos.write(buffer, 0, count); - } - - fos.close(); - fis.close(); - } - - /** - * Returns the path to the target images folder as a relative path to the SDK, if the folder - * is not empty. If the image folder is empty or does not exist, <code>null</code> is returned. - * @throws InvalidTargetPathException if the target image folder is not in the current SDK. - */ - private String getImageRelativePath(IAndroidTarget target, String abiType) - throws InvalidTargetPathException { - - ISystemImage systemImage = target.getSystemImage(abiType); - if (systemImage == null) { - // ABI Type is unknown for target - return null; - } - - File folder = systemImage.getLocation(); - String imageFullPath = folder.getAbsolutePath(); - - // make this path relative to the SDK location - String sdkLocation = mSdkManager.getLocation(); - if (!imageFullPath.startsWith(sdkLocation)) { - // this really really should not happen. - assert false; - throw new InvalidTargetPathException("Target location is not inside the SDK."); - } - - if (folder.isDirectory()) { - String[] list = folder.list(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return IMAGE_NAME_PATTERN.matcher(name).matches(); - } - }); - - if (list.length > 0) { - // Remove the SDK root path, e.g. /sdk/dir1/dir2 => /dir1/dir2 - imageFullPath = imageFullPath.substring(sdkLocation.length()); - // The path is relative, so it must not start with a file separator - if (imageFullPath.charAt(0) == File.separatorChar) { - imageFullPath = imageFullPath.substring(1); - } - // For compatibility with previous versions, we denote folders - // by ending the path with file separator - if (!imageFullPath.endsWith(File.separator)) { - imageFullPath += File.separator; - } - - return imageFullPath; - } - } - - return null; - } - - /** - * Returns the path to the skin, as a relative path to the SDK. - * @param skinName The name of the skin to find. Case-sensitive. - * @param target The target where to find the skin. - * @param log the log object to receive action logs. Cannot be null. - */ - public String getSkinRelativePath(String skinName, IAndroidTarget target, ILogger log) { - if (log == null) { - throw new IllegalArgumentException("log cannot be null"); - } - - // first look to see if the skin is in the target - File skin = getSkinPath(skinName, target); - - // skin really does not exist! - if (skin.exists() == false) { - log.error(null, "Skin '%1$s' does not exist.", skinName); - return null; - } - - // get the skin path - String path = skin.getAbsolutePath(); - - // make this path relative to the SDK location - String sdkLocation = mSdkManager.getLocation(); - if (path.startsWith(sdkLocation) == false) { - // this really really should not happen. - log.error(null, "Target location is not inside the SDK."); - assert false; - return null; - } - - path = path.substring(sdkLocation.length()); - if (path.charAt(0) == File.separatorChar) { - path = path.substring(1); - } - return path; - } - - /** - * Returns the full absolute OS path to a skin specified by name for a given target. - * @param skinName The name of the skin to find. Case-sensitive. - * @param target The target where to find the skin. - * @return a {@link File} that may or may not actually exist. - */ - public File getSkinPath(String skinName, IAndroidTarget target) { - String path = target.getPath(IAndroidTarget.SKINS); - File skin = new File(path, skinName); - - if (skin.exists() == false && target.isPlatform() == false) { - target = target.getParent(); - - path = target.getPath(IAndroidTarget.SKINS); - skin = new File(path, skinName); - } - - return skin; - } - - /** - * Creates the ini file for an AVD. - * - * @param name of the AVD. - * @param avdFolder path for the data folder of the AVD. - * @param target of the AVD. - * @param removePrevious True if an existing ini file should be removed. - * @throws AndroidLocationException if there's a problem getting android root directory. - * @throws IOException if {@link File#getAbsolutePath()} fails. - */ - private File createAvdIniFile(String name, - File avdFolder, - IAndroidTarget target, - boolean removePrevious) - throws AndroidLocationException, IOException { - File iniFile = AvdInfo.getDefaultIniFile(this, name); - - if (removePrevious) { - if (iniFile.isFile()) { - iniFile.delete(); - } else if (iniFile.isDirectory()) { - deleteContentOf(iniFile); - iniFile.delete(); - } - } - - HashMap<String, String> values = new HashMap<String, String>(); - values.put(AVD_INFO_PATH, avdFolder.getAbsolutePath()); - values.put(AVD_INFO_TARGET, target.hashString()); - writeIniFile(iniFile, values); - - return iniFile; - } - - /** - * Creates the ini file for an AVD. - * - * @param info of the AVD. - * @throws AndroidLocationException if there's a problem getting android root directory. - * @throws IOException if {@link File#getAbsolutePath()} fails. - */ - private File createAvdIniFile(AvdInfo info) throws AndroidLocationException, IOException { - return createAvdIniFile(info.getName(), - new File(info.getDataFolderPath()), - info.getTarget(), - false /*removePrevious*/); - } - - /** - * Actually deletes the files of an existing AVD. - * <p/> - * This also remove it from the manager's list, The caller does not need to - * call {@link #removeAvd(AvdInfo)} afterwards. - * <p/> - * This method is designed to somehow work with an unavailable AVD, that is an AVD that - * could not be loaded due to some error. That means this method still tries to remove - * the AVD ini file or its folder if it can be found. An error will be output if any of - * these operations fail. - * - * @param avdInfo the information on the AVD to delete - * @param log the log object to receive action logs. Cannot be null. - * @return True if the AVD was deleted with no error. - */ - public boolean deleteAvd(AvdInfo avdInfo, ILogger log) { - try { - boolean error = false; - - File f = avdInfo.getIniFile(); - if (f != null && f.exists()) { - log.info("Deleting file %1$s\n", f.getCanonicalPath()); - if (!f.delete()) { - log.error(null, "Failed to delete %1$s\n", f.getCanonicalPath()); - error = true; - } - } - - String path = avdInfo.getDataFolderPath(); - if (path != null) { - f = new File(path); - if (f.exists()) { - log.info("Deleting folder %1$s\n", f.getCanonicalPath()); - if (deleteContentOf(f) == false || f.delete() == false) { - log.error(null, "Failed to delete %1$s\n", f.getCanonicalPath()); - error = true; - } - } - } - - removeAvd(avdInfo); - - if (error) { - log.info("\nAVD '%1$s' deleted with errors. See errors above.\n", - avdInfo.getName()); - } else { - log.info("\nAVD '%1$s' deleted.\n", avdInfo.getName()); - return true; - } - - } catch (IOException e) { - log.error(e, null); - } catch (SecurityException e) { - log.error(e, null); - } - return false; - } - - /** - * Moves and/or rename an existing AVD and its files. - * This also change it in the manager's list. - * <p/> - * The caller should make sure the name or path given are valid, do not exist and are - * actually different than current values. - * - * @param avdInfo the information on the AVD to move. - * @param newName the new name of the AVD if non null. - * @param paramFolderPath the new data folder if non null. - * @param log the log object to receive action logs. Cannot be null. - * @return True if the move succeeded or there was nothing to do. - * If false, this method will have had already output error in the log. - */ - public boolean moveAvd(AvdInfo avdInfo, String newName, String paramFolderPath, ILogger log) { - - try { - if (paramFolderPath != null) { - File f = new File(avdInfo.getDataFolderPath()); - log.warning("Moving '%1$s' to '%2$s'.", - avdInfo.getDataFolderPath(), - paramFolderPath); - if (!f.renameTo(new File(paramFolderPath))) { - log.error(null, "Failed to move '%1$s' to '%2$s'.", - avdInfo.getDataFolderPath(), paramFolderPath); - return false; - } - - // update AVD info - AvdInfo info = new AvdInfo( - avdInfo.getName(), - avdInfo.getIniFile(), - paramFolderPath, - avdInfo.getTargetHash(), - avdInfo.getTarget(), - avdInfo.getAbiType(), - avdInfo.getProperties()); - replaceAvd(avdInfo, info); - - // update the ini file - createAvdIniFile(info); - } - - if (newName != null) { - File oldIniFile = avdInfo.getIniFile(); - File newIniFile = AvdInfo.getDefaultIniFile(this, newName); - - log.warning("Moving '%1$s' to '%2$s'.", oldIniFile.getPath(), newIniFile.getPath()); - if (!oldIniFile.renameTo(newIniFile)) { - log.error(null, "Failed to move '%1$s' to '%2$s'.", - oldIniFile.getPath(), newIniFile.getPath()); - return false; - } - - // update AVD info - AvdInfo info = new AvdInfo( - newName, - avdInfo.getIniFile(), - avdInfo.getDataFolderPath(), - avdInfo.getTargetHash(), - avdInfo.getTarget(), - avdInfo.getAbiType(), - avdInfo.getProperties()); - replaceAvd(avdInfo, info); - } - - log.info("AVD '%1$s' moved.\n", avdInfo.getName()); - - } catch (AndroidLocationException e) { - log.error(e, null); - } catch (IOException e) { - log.error(e, null); - } - - // nothing to do or succeeded - return true; - } - - /** - * Helper method to recursively delete a folder's content (but not the folder itself). - * - * @throws SecurityException like {@link File#delete()} does if file/folder is not writable. - */ - private boolean deleteContentOf(File folder) throws SecurityException { - File[] files = folder.listFiles(); - if (files != null) { - for (File f : files) { - if (f.isDirectory()) { - if (deleteContentOf(f) == false) { - return false; - } - } - if (f.delete() == false) { - return false; - } - - } - } - - return true; - } - - /** - * Returns a list of files that are potential AVD ini files. - * <p/> - * This lists the $HOME/.android/avd/<name>.ini files. - * Such files are properties file than then indicate where the AVD folder is located. - * <p/> - * Note: the method is to be considered private. It is made protected so that - * unit tests can easily override the AVD root. - * - * @return A new {@link File} array or null. The array might be empty. - * @throws AndroidLocationException if there's a problem getting android root directory. - */ - private File[] buildAvdFilesList() throws AndroidLocationException { - File folder = new File(getBaseAvdFolder()); - - // ensure folder validity. - if (folder.isFile()) { - throw new AndroidLocationException( - String.format("%1$s is not a valid folder.", folder.getAbsolutePath())); - } else if (folder.exists() == false) { - // folder is not there, we create it and return - folder.mkdirs(); - return null; - } - - File[] avds = folder.listFiles(new FilenameFilter() { - @Override - public boolean accept(File parent, String name) { - if (INI_NAME_PATTERN.matcher(name).matches()) { - // check it's a file and not a folder - boolean isFile = new File(parent, name).isFile(); - return isFile; - } - - return false; - } - }); - - return avds; - } - - /** - * Computes the internal list of available AVDs - * @param allList the list to contain all the AVDs - * @param log the log object to receive action logs. Cannot be null. - * - * @throws AndroidLocationException if there's a problem getting android root directory. - */ - private void buildAvdList(ArrayList<AvdInfo> allList, ILogger log) - throws AndroidLocationException { - File[] avds = buildAvdFilesList(); - if (avds != null) { - for (File avd : avds) { - AvdInfo info = parseAvdInfo(avd, log); - if (info != null) { - allList.add(info); - } - } - } - } - - /** - * Parses an AVD .ini file to create an {@link AvdInfo}. - * - * @param iniPath The path to the AVD .ini file - * @param log the log object to receive action logs. Cannot be null. - * @return A new {@link AvdInfo} with an {@link AvdStatus} indicating whether this AVD is - * valid or not. - */ - private AvdInfo parseAvdInfo(File iniPath, ILogger log) { - Map<String, String> map = ProjectProperties.parsePropertyFile( - new FileWrapper(iniPath), - log); - - String avdPath = map.get(AVD_INFO_PATH); - String targetHash = map.get(AVD_INFO_TARGET); - - IAndroidTarget target = null; - FileWrapper configIniFile = null; - Map<String, String> properties = null; - - if (targetHash != null) { - target = mSdkManager.getTargetFromHashString(targetHash); - } - - // load the AVD properties. - if (avdPath != null) { - configIniFile = new FileWrapper(avdPath, CONFIG_INI); - } - - if (configIniFile != null) { - if (!configIniFile.isFile()) { - log.warning("Missing file '%1$s'.", configIniFile.getPath()); - } else { - properties = ProjectProperties.parsePropertyFile(configIniFile, log); - } - } - - // get name - String name = iniPath.getName(); - Matcher matcher = INI_NAME_PATTERN.matcher(iniPath.getName()); - if (matcher.matches()) { - name = matcher.group(1); - } - - // get abi type - String abiType = properties == null ? null : properties.get(AVD_INI_ABI_TYPE); - // for the avds created previously without enhancement, i.e. They are created based - // on previous API Levels. They are supposed to have ARM processor type - if (abiType == null) { - abiType = SdkConstants.ABI_ARMEABI; - } - - // check the image.sysdir are valid - boolean validImageSysdir = true; - if (properties != null) { - String imageSysDir = properties.get(AVD_INI_IMAGES_1); - if (imageSysDir != null) { - File f = new File(mSdkManager.getLocation() + File.separator + imageSysDir); - if (f.isDirectory() == false) { - validImageSysdir = false; - } else { - imageSysDir = properties.get(AVD_INI_IMAGES_2); - if (imageSysDir != null) { - f = new File(mSdkManager.getLocation() + File.separator + imageSysDir); - if (f.isDirectory() == false) { - validImageSysdir = false; - } - } - } - } - } - - // Get the device status if this AVD is associated with a device - DeviceStatus deviceStatus = null; - if (properties != null) { - String deviceName = properties.get(AVD_INI_DEVICE_NAME); - String deviceMfctr = properties.get(AVD_INI_DEVICE_MANUFACTURER); - String hash = properties.get(AVD_INI_DEVICE_HASH); - if (deviceName != null && deviceMfctr != null && hash != null) { - int deviceHash = Integer.parseInt(hash); - deviceStatus = (new DeviceManager(log)).getDeviceStatus( - mSdkManager.getLocation(), deviceName, deviceMfctr, deviceHash); - } - } - - - // TODO: What about missing sdcard, skins, etc? - - AvdStatus status; - - if (avdPath == null) { - status = AvdStatus.ERROR_PATH; - } else if (configIniFile == null) { - status = AvdStatus.ERROR_CONFIG; - } else if (targetHash == null) { - status = AvdStatus.ERROR_TARGET_HASH; - } else if (target == null) { - status = AvdStatus.ERROR_TARGET; - } else if (properties == null) { - status = AvdStatus.ERROR_PROPERTIES; - } else if (validImageSysdir == false) { - status = AvdStatus.ERROR_IMAGE_DIR; - } else if (deviceStatus == DeviceStatus.CHANGED) { - status = AvdStatus.ERROR_DEVICE_CHANGED; - } else if (deviceStatus == DeviceStatus.MISSING) { - status = AvdStatus.ERROR_DEVICE_MISSING; - } else { - status = AvdStatus.OK; - } - - AvdInfo info = new AvdInfo( - name, - iniPath, - avdPath, - targetHash, - target, - abiType, - properties, - status); - - return info; - } - - /** - * Writes a .ini file from a set of properties, using UTF-8 encoding. - * - * @param iniFile The file to generate. - * @param values THe properties to place in the ini file. - * @throws IOException if {@link FileWriter} fails to open, write or close the file. - */ - private static void writeIniFile(File iniFile, Map<String, String> values) - throws IOException { - OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(iniFile), - SdkConstants.INI_CHARSET); - - for (Entry<String, String> entry : values.entrySet()) { - writer.write(String.format("%1$s=%2$s\n", entry.getKey(), entry.getValue())); - } - writer.close(); - } - - /** - * Invokes the tool to create a new SD card image file. - * - * @param toolLocation The path to the mksdcard tool. - * @param size The size of the new SD Card, compatible with {@link #SDCARD_SIZE_PATTERN}. - * @param location The path of the new sdcard image file to generate. - * @param log the log object to receive action logs. Cannot be null. - * @return True if the sdcard could be created. - */ - private boolean createSdCard(String toolLocation, String size, String location, ILogger log) { - try { - String[] command = new String[3]; - command[0] = toolLocation; - command[1] = size; - command[2] = location; - Process process = Runtime.getRuntime().exec(command); - - final ArrayList<String> errorOutput = new ArrayList<String>(); - final ArrayList<String> stdOutput = new ArrayList<String>(); - - int status = GrabProcessOutput.grabProcessOutput( - process, - Wait.WAIT_FOR_READERS, - new IProcessOutput() { - @Override - public void out(@Nullable String line) { - if (line != null) { - stdOutput.add(line); - } - } - - @Override - public void err(@Nullable String line) { - if (line != null) { - errorOutput.add(line); - } - } - }); - - if (status == 0) { - return true; - } else { - for (String error : errorOutput) { - log.error(null, error); - } - } - - } catch (InterruptedException e) { - // pass, print error below - } catch (IOException e) { - // pass, print error below - } - - log.error(null, "Failed to create the SD card."); - return false; - } - - /** - * Removes an {@link AvdInfo} from the internal list. - * - * @param avdInfo The {@link AvdInfo} to remove. - * @return true if this {@link AvdInfo} was present and has been removed. - */ - public boolean removeAvd(AvdInfo avdInfo) { - synchronized (mAllAvdList) { - if (mAllAvdList.remove(avdInfo)) { - mValidAvdList = mBrokenAvdList = null; - return true; - } - } - - return false; - } - - /** - * Updates an AVD with new path to the system image folders. - * @param name the name of the AVD to update. - * @param log the log object to receive action logs. Cannot be null. - * @throws IOException - */ - public void updateAvd(String name, ILogger log) throws IOException { - // find the AVD to update. It should be be in the broken list. - AvdInfo avd = null; - synchronized (mAllAvdList) { - for (AvdInfo info : mAllAvdList) { - if (info.getName().equals(name)) { - avd = info; - break; - } - } - } - - if (avd == null) { - // not in the broken list, just return. - log.error(null, "There is no Android Virtual Device named '%s'.", name); - return; - } - - updateAvd(avd, log); - } - - - /** - * Updates an AVD with new path to the system image folders. - * @param avd the AVD to update. - * @param log the log object to receive action logs. Cannot be null. - * @throws IOException - */ - public void updateAvd(AvdInfo avd, ILogger log) throws IOException { - // get the properties. This is a unmodifiable Map. - Map<String, String> oldProperties = avd.getProperties(); - - // create a new map - Map<String, String> properties = new HashMap<String, String>(); - if (oldProperties != null) { - properties.putAll(oldProperties); - } - - AvdStatus status; - - // create the path to the new system images. - if (setImagePathProperties(avd.getTarget(), avd.getAbiType(), properties, log)) { - if (properties.containsKey(AVD_INI_IMAGES_1)) { - log.info("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_1, - properties.get(AVD_INI_IMAGES_1)); - } - - if (properties.containsKey(AVD_INI_IMAGES_2)) { - log.info("Updated '%1$s' with value '%2$s'\n", AVD_INI_IMAGES_2, - properties.get(AVD_INI_IMAGES_2)); - } - - status = AvdStatus.OK; - } else { - log.error(null, "Unable to find non empty system images folders for %1$s", - avd.getName()); - //FIXME: display paths to empty image folders? - status = AvdStatus.ERROR_IMAGE_DIR; - } - updateAvd(avd, properties, status, log); - } - - public void updateAvd(AvdInfo avd, - Map<String, String> newProperties, - AvdStatus status, - ILogger log) throws IOException { - // now write the config file - File configIniFile = new File(avd.getDataFolderPath(), CONFIG_INI); - writeIniFile(configIniFile, newProperties); - - // finally create a new AvdInfo for this unbroken avd and add it to the list. - // instead of creating the AvdInfo object directly we reparse it, to detect other possible - // errors - // FIXME: We may want to create this AvdInfo by reparsing the AVD instead. This could detect other errors. - AvdInfo newAvd = new AvdInfo( - avd.getName(), - avd.getIniFile(), - avd.getDataFolderPath(), - avd.getTargetHash(), - avd.getTarget(), - avd.getAbiType(), - newProperties); - - replaceAvd(avd, newAvd); - } - - /** - * Sets the paths to the system images in a properties map. - * - * @param target the target in which to find the system images. - * @param abiType the abi type of the avd to find - * the architecture-dependent system images. - * @param properties the properties in which to set the paths. - * @param log the log object to receive action logs. Cannot be null. - * @return true if success, false if some path are missing. - */ - private boolean setImagePathProperties(IAndroidTarget target, - String abiType, - Map<String, String> properties, - ILogger log) { - properties.remove(AVD_INI_IMAGES_1); - properties.remove(AVD_INI_IMAGES_2); - - try { - String property = AVD_INI_IMAGES_1; - - // First the image folders of the target itself - String imagePath = getImageRelativePath(target, abiType); - if (imagePath != null) { - properties.put(property, imagePath); - property = AVD_INI_IMAGES_2; - } - - // If the target is an add-on we need to add the Platform image as a backup. - IAndroidTarget parent = target.getParent(); - if (parent != null) { - imagePath = getImageRelativePath(parent, abiType); - if (imagePath != null) { - properties.put(property, imagePath); - } - } - - // we need at least one path! - return properties.containsKey(AVD_INI_IMAGES_1); - } catch (InvalidTargetPathException e) { - log.error(e, e.getMessage()); - } - - return false; - } - - /** - * Replaces an old {@link AvdInfo} with a new one in the lists storing them. - * @param oldAvd the {@link AvdInfo} to remove. - * @param newAvd the {@link AvdInfo} to add. - */ - private void replaceAvd(AvdInfo oldAvd, AvdInfo newAvd) { - synchronized (mAllAvdList) { - mAllAvdList.remove(oldAvd); - mAllAvdList.add(newAvd); - mValidAvdList = mBrokenAvdList = null; - } - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/HardwareProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/HardwareProperties.java deleted file mode 100644 index 02241ef..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/avd/HardwareProperties.java +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.avd; - -import com.android.utils.ILogger; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Map; -import java.util.TreeMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class HardwareProperties { - /** AVD/config.ini key for whether hardware buttons are present. */ - public static final String HW_MAINKEYS = "hw.mainKeys"; - - /** AVD/config.ini key indicating whether trackball is present. */ - public static final String HW_TRACKBALL = "hw.trackBall"; - - /** AVD/config.ini key indicating whether qwerty keyboard is present. */ - public static final String HW_KEYBOARD = "hw.keyboard"; - - /** AVD/config.ini key indicating whether dpad is present. */ - public static final String HW_DPAD = "hw.dPad"; - - /** AVD/config.ini key indicating whether gps is present. */ - public static final String HW_GPS = "hw.gps"; - - /** AVD/config.ini key indicating whether the device is running on battery. */ - public static final String HW_BATTERY = "hw.battery"; - - /** AVD/config.ini key indicating whether accelerometer is present. */ - public static final String HW_ACCELEROMETER = "hw.accelerometer"; - - /** AVD/config.ini key indicating whether gyroscope is present. */ - public static final String HW_ORIENTATION_SENSOR = "hw.sensors.orientation"; - - /** AVD/config.ini key indicating whether h/w mic is present. */ - public static final String HW_AUDIO_INPUT = "hw.audioInput"; - - /** AVD/config.ini key indicating whether sdcard is present. */ - public static final String HW_SDCARD = "hw.sdCard"; - - /** AVD/config.ini key for LCD density. */ - public static final String HW_LCD_DENSITY = "hw.lcd.density"; - - /** AVD/config.ini key indicating whether proximity sensor present. */ - public static final String HW_PROXIMITY_SENSOR = "hw.sensors.proximity"; - - - private final static Pattern PATTERN_PROP = Pattern.compile( - "^([a-zA-Z0-9._-]+)\\s*=\\s*(.*)\\s*$"); - - /** Property name in the generated avd config file; String; e.g. "hw.screen" */ - private final static String HW_PROP_NAME = "name"; //$NON-NLS-1$ - /** Property type, one of {@link HardwarePropertyType} */ - private final static String HW_PROP_TYPE = "type"; //$NON-NLS-1$ - /** Default value of the property. String matching the property type. */ - private final static String HW_PROP_DEFAULT = "default"; //$NON-NLS-1$ - /** User-visible name of the property. String. */ - private final static String HW_PROP_ABSTRACT = "abstract"; //$NON-NLS-1$ - /** User-visible description of the property. String. */ - private final static String HW_PROP_DESC = "description"; //$NON-NLS-1$ - /** Comma-separate values for a property of type "enum" */ - private final static String HW_PROP_ENUM = "enum"; //$NON-NLS-1$ - - public final static String BOOLEAN_YES = "yes"; - public final static String BOOLEAN_NO = "no"; - public final static String[] BOOLEAN_VALUES = new String[] { BOOLEAN_YES, BOOLEAN_NO }; - public final static Pattern DISKSIZE_PATTERN = Pattern.compile("\\d+[MK]B"); //$NON-NLS-1$ - - /** Represents the type of a hardware property value. */ - public enum HardwarePropertyType { - INTEGER ("integer", false /*isEnum*/), //$NON-NLS-1$ - BOOLEAN ("boolean", false /*isEnum*/), //$NON-NLS-1$ - DISKSIZE ("diskSize", false /*isEnum*/), //$NON-NLS-1$ - STRING ("string", false /*isEnum*/), //$NON-NLS-1$ - INTEGER_ENUM("integer", true /*isEnum*/), //$NON-NLS-1$ - STRING_ENUM ("string", true /*isEnum*/); //$NON-NLS-1$ - - - private String mName; - private boolean mIsEnum; - - HardwarePropertyType(String name, boolean isEnum) { - mName = name; - mIsEnum = isEnum; - } - - /** Returns the name of the type (e.g. "string", "boolean", etc.) */ - public String getName() { - return mName; - } - - /** Indicates whether this type is an enum (e.g. "enum of strings"). */ - public boolean isEnum() { - return mIsEnum; - } - - /** Returns the internal HardwarePropertyType object matching the given type name. */ - public static HardwarePropertyType getEnum(String name, boolean isEnum) { - for (HardwarePropertyType type : values()) { - if (type.mName.equals(name) && type.mIsEnum == isEnum) { - return type; - } - } - - return null; - } - } - - public static final class HardwareProperty { - private String mName; - private HardwarePropertyType mType; - /** the string representation of the default value. can be null. */ - private String mDefault; - /** the choices for an enum. Null if not an enum. */ - private String[] mEnum; - private String mAbstract; - private String mDescription; - - public HardwareProperty() { - // initialize strings to sane defaults, as not all properties will be set from - // the ini file - mName = ""; - mDefault = ""; - mAbstract = ""; - mDescription = ""; - } - - /** Returns the hardware config name of the property, e.g. "hw.screen" */ - public String getName() { - return mName; - } - - /** Returns the property type, one of {@link HardwarePropertyType} */ - public HardwarePropertyType getType() { - return mType; - } - - /** - * Returns the default value of the property. - * String matching the property type. - * Can be null. - */ - public String getDefault() { - return mDefault; - } - - /** Returns the user-visible name of the property. */ - public String getAbstract() { - return mAbstract; - } - - /** Returns the user-visible description of the property. */ - public String getDescription() { - return mDescription; - } - - /** Returns the possible values for an enum property. Can be null. */ - public String[] getEnum() { - return mEnum; - } - - public boolean isValidForUi() { - // don't display single string type for now. - return mType != HardwarePropertyType.STRING || mType.isEnum(); - } - } - - /** - * Parses the hardware definition file. - * @param file the property file to parse - * @param log the ILogger object receiving warning/error from the parsing. Cannot be null. - * @return the map of (key,value) pairs, or null if the parsing failed. - */ - public static Map<String, HardwareProperty> parseHardwareDefinitions(File file, ILogger log) { - BufferedReader reader = null; - try { - FileInputStream fis = new FileInputStream(file); - reader = new BufferedReader(new InputStreamReader(fis)); - - Map<String, HardwareProperty> map = new TreeMap<String, HardwareProperty>(); - - String line = null; - HardwareProperty prop = null; - while ((line = reader.readLine()) != null) { - if (line.length() > 0 && line.charAt(0) != '#') { - Matcher m = PATTERN_PROP.matcher(line); - if (m.matches()) { - String key = m.group(1); - String value = m.group(2); - - if (HW_PROP_NAME.equals(key)) { - prop = new HardwareProperty(); - prop.mName = value; - map.put(prop.mName, prop); - } - - if (prop == null) { - log.warning("Error parsing '%1$s': missing '%2$s'", - file.getAbsolutePath(), HW_PROP_NAME); - return null; - } - - if (HW_PROP_TYPE.equals(key)) { - // Note: we don't know yet whether this type is an enum. - // This is indicated by the "enum = value" line that is parsed later. - prop.mType = HardwarePropertyType.getEnum(value, false); - assert (prop.mType != null); - } else if (HW_PROP_DEFAULT.equals(key)) { - prop.mDefault = value; - } else if (HW_PROP_ABSTRACT.equals(key)) { - prop.mAbstract = value; - } else if (HW_PROP_DESC.equals(key)) { - prop.mDescription = value; - } else if (HW_PROP_ENUM.equals(key)) { - if (!prop.mType.isEnum()) { - // Change the type to an enum, if valid. - prop.mType = HardwarePropertyType.getEnum(prop.mType.getName(), - true); - assert (prop.mType != null); - } - - // Sanitize input: trim spaces, ignore empty entries. - String[] v = value.split(","); - int n = 0; - for (int i = 0; i < v.length; i++) { - String s = v[i] = v[i].trim(); - if (s.length() > 0) { - n++; - } - } - prop.mEnum = new String[n]; - n = 0; - for (int i = 0; i < v.length; i++) { - String s = v[i]; - if (s.length() > 0) { - prop.mEnum[n++] = s; - } - } - } - } else { - log.warning("Error parsing '%1$s': \"%2$s\" is not a valid syntax", - file.getAbsolutePath(), line); - return null; - } - } - } - - return map; - } catch (FileNotFoundException e) { - // this should not happen since we usually test the file existence before - // calling the method. - // Return null below. - } catch (IOException e) { - log.warning("Error parsing '%1$s': %2$s.", file.getAbsolutePath(), - e.getMessage()); - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - // ignore - } - } - } - - return null; - } - - /** - * Returns the index of <var>value</var> in {@link #BOOLEAN_VALUES}. - */ - public static int getBooleanValueIndex(String value) { - if (BOOLEAN_YES.equals(value)) { - return 0; - } else if (BOOLEAN_NO.equals(value)) { - return 1; - } - - return -1; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/BuildConfig.template b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/BuildConfig.template deleted file mode 100644 index 0344b55..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/BuildConfig.template +++ /dev/null @@ -1,6 +0,0 @@ -/** Automatically generated file. DO NOT MODIFY */ -package #PACKAGE#; - -public final class BuildConfig { - public final static boolean DEBUG = #DEBUG#; -}
\ No newline at end of file diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/BuildConfigGenerator.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/BuildConfigGenerator.java deleted file mode 100644 index 038975a..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/BuildConfigGenerator.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.build; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -/** - * Class able to generate a BuildConfig class in Android project. - * The BuildConfig class contains constants related to the build target. - */ -public class BuildConfigGenerator { - - public final static String BUILD_CONFIG_NAME = "BuildConfig.java"; - - private final static String PH_PACKAGE = "#PACKAGE#"; - private final static String PH_DEBUG = "#DEBUG#"; - - private final String mGenFolder; - private final String mAppPackage; - private final boolean mDebug; - - /** - * Creates a generator - * @param genFolder the gen folder of the project - * @param appPackage the application package - * @param debug whether it's a debug build - */ - public BuildConfigGenerator(String genFolder, String appPackage, boolean debug) { - mGenFolder = genFolder; - mAppPackage = appPackage; - mDebug = debug; - } - - /** - * Returns a File representing where the BuildConfig class will be. - */ - public File getFolderPath() { - File genFolder = new File(mGenFolder); - return new File(genFolder, mAppPackage.replace('.', File.separatorChar)); - } - - public File getBuildConfigFile() { - File folder = getFolderPath(); - return new File(folder, BUILD_CONFIG_NAME); - } - - /** - * Generates the BuildConfig class. - */ - public void generate() throws IOException { - String template = readEmbeddedTextFile("BuildConfig.template"); - - Map<String, String> map = new HashMap<String, String>(); - map.put(PH_PACKAGE, mAppPackage); - map.put(PH_DEBUG, Boolean.toString(mDebug)); - - String content = replaceParameters(template, map); - - File pkgFolder = getFolderPath(); - if (pkgFolder.isDirectory() == false) { - pkgFolder.mkdirs(); - } - - File buildConfigJava = new File(pkgFolder, BUILD_CONFIG_NAME); - writeFile(buildConfigJava, content); - } - - /** - * Reads and returns the content of a text file embedded in the jar file. - * @param filepath the file path to the text file - * @return null if the file could not be read - * @throws IOException - */ - private String readEmbeddedTextFile(String filepath) throws IOException { - InputStream is = BuildConfigGenerator.class.getResourceAsStream(filepath); - if (is != null) { - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - - String line; - StringBuilder total = new StringBuilder(reader.readLine()); - while ((line = reader.readLine()) != null) { - total.append('\n'); - total.append(line); - } - - return total.toString(); - } - - // this really shouldn't happen unless the sdklib packaging is broken. - throw new IOException("BuildConfig template is missing!"); - } - - private void writeFile(File file, String content) throws IOException { - FileOutputStream fos = null; - try { - fos = new FileOutputStream(file); - InputStream source = new ByteArrayInputStream(content.getBytes("UTF-8")); - - byte[] buffer = new byte[1024]; - int count = 0; - while ((count = source.read(buffer)) != -1) { - fos.write(buffer, 0, count); - } - } finally { - if (fos != null) { - fos.close(); - } - } - } - - /** - * Replaces placeholders found in a string with values. - * - * @param str the string to search for placeholders. - * @param parameters a map of <placeholder, Value> to search for in the string - * @return A new String object with the placeholder replaced by the values. - */ - private String replaceParameters(String str, Map<String, String> parameters) { - - for (Entry<String, String> entry : parameters.entrySet()) { - String value = entry.getValue(); - if (value != null) { - str = str.replaceAll(entry.getKey(), value); - } - } - - return str; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/DebugKeyProvider.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/DebugKeyProvider.java deleted file mode 100644 index 4f4af36..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/DebugKeyProvider.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.build; - -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.UnrecoverableEntryException; -import java.security.UnrecoverableKeyException; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; - -/** - * A provider of a dummy key to sign Android application for debugging purpose. - * <p/>This provider uses a custom keystore to create and store a key with a known password. - */ -public class DebugKeyProvider { - - public interface IKeyGenOutput { - public void out(String message); - public void err(String message); - } - - private static final String PASSWORD_STRING = "android"; - private static final char[] PASSWORD_CHAR = PASSWORD_STRING.toCharArray(); - private static final String DEBUG_ALIAS = "AndroidDebugKey"; - - // Certificate CN value. This is a hard-coded value for the debug key. - // Android Market checks against this value in order to refuse applications signed with - // debug keys. - private static final String CERTIFICATE_DESC = "CN=Android Debug,O=Android,C=US"; - - private KeyStore.PrivateKeyEntry mEntry; - - public static class KeytoolException extends Exception { - /** default serial uid */ - private static final long serialVersionUID = 1L; - private String mJavaHome = null; - private String mCommandLine = null; - - KeytoolException(String message) { - super(message); - } - - KeytoolException(String message, String javaHome, String commandLine) { - super(message); - - mJavaHome = javaHome; - mCommandLine = commandLine; - } - - public String getJavaHome() { - return mJavaHome; - } - - public String getCommandLine() { - return mCommandLine; - } - } - - /** - * Creates a provider using a keystore at the given location. - * <p/>The keystore, and a new random android debug key are created if they do not yet exist. - * <p/>Password for the store/key is <code>android</code>, and the key alias is - * <code>AndroidDebugKey</code>. - * @param osKeyStorePath the OS path to the keystore, or <code>null</code> if the default one - * is to be used. - * @param storeType an optional keystore type, or <code>null</code> if the default is to - * be used. - * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr - * of the keytool process call. - * @throws KeytoolException If the creation of the debug key failed. - * @throws AndroidLocationException - */ - public DebugKeyProvider(String osKeyStorePath, String storeType, IKeyGenOutput output) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, - UnrecoverableEntryException, IOException, KeytoolException, AndroidLocationException { - - if (osKeyStorePath == null) { - osKeyStorePath = getDefaultKeyStoreOsPath(); - } - - if (loadKeyEntry(osKeyStorePath, storeType) == false) { - // create the store with the key - createNewStore(osKeyStorePath, storeType, output); - } - } - - /** - * Returns the OS path to the default debug keystore. - * - * @return The OS path to the default debug keystore. - * @throws KeytoolException - * @throws AndroidLocationException - */ - public static String getDefaultKeyStoreOsPath() - throws KeytoolException, AndroidLocationException { - String folder = AndroidLocation.getFolder(); - if (folder == null) { - throw new KeytoolException("Failed to get HOME directory!\n"); - } - String osKeyStorePath = folder + "debug.keystore"; - - return osKeyStorePath; - } - - /** - * Returns the debug {@link PrivateKey} to use to sign applications for debug purpose. - * @return the private key or <code>null</code> if its creation failed. - */ - @SuppressWarnings("unused") // the thrown Exceptions are not actually thrown - public PrivateKey getDebugKey() throws KeyStoreException, NoSuchAlgorithmException, - UnrecoverableKeyException, UnrecoverableEntryException { - if (mEntry != null) { - return mEntry.getPrivateKey(); - } - - return null; - } - - /** - * Returns the debug {@link Certificate} to use to sign applications for debug purpose. - * @return the certificate or <code>null</code> if its creation failed. - */ - @SuppressWarnings("unused") // the thrown Exceptions are not actually thrown - public Certificate getCertificate() throws KeyStoreException, NoSuchAlgorithmException, - UnrecoverableKeyException, UnrecoverableEntryException { - if (mEntry != null) { - return mEntry.getCertificate(); - } - - return null; - } - - /** - * Loads the debug key from the keystore. - * @param osKeyStorePath the OS path to the keystore. - * @param storeType an optional keystore type, or <code>null</code> if the default is to - * be used. - * @return <code>true</code> if success, <code>false</code> if the keystore does not exist. - */ - private boolean loadKeyEntry(String osKeyStorePath, String storeType) throws KeyStoreException, - NoSuchAlgorithmException, CertificateException, IOException, - UnrecoverableEntryException { - FileInputStream fis = null; - try { - KeyStore keyStore = KeyStore.getInstance( - storeType != null ? storeType : KeyStore.getDefaultType()); - fis = new FileInputStream(osKeyStorePath); - keyStore.load(fis, PASSWORD_CHAR); - mEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry( - DEBUG_ALIAS, new KeyStore.PasswordProtection(PASSWORD_CHAR)); - } catch (FileNotFoundException e) { - return false; - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - // pass - } - } - } - - return true; - } - - /** - * Creates a new store - * @param osKeyStorePath the location of the store - * @param storeType an optional keystore type, or <code>null</code> if the default is to - * be used. - * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr - * of the keytool process call. - * @throws KeyStoreException - * @throws NoSuchAlgorithmException - * @throws CertificateException - * @throws UnrecoverableEntryException - * @throws IOException - * @throws KeytoolException - */ - private void createNewStore(String osKeyStorePath, String storeType, IKeyGenOutput output) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, - UnrecoverableEntryException, IOException, KeytoolException { - - if (KeystoreHelper.createNewStore(osKeyStorePath, storeType, PASSWORD_STRING, DEBUG_ALIAS, - PASSWORD_STRING, CERTIFICATE_DESC, 30 /* validity*/, output)) { - loadKeyEntry(osKeyStorePath, storeType); - } - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/KeystoreHelper.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/KeystoreHelper.java deleted file mode 100644 index ba4ce8c..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/KeystoreHelper.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.build; - -import com.android.annotations.Nullable; -import com.android.sdklib.internal.build.DebugKeyProvider.IKeyGenOutput; -import com.android.sdklib.internal.build.DebugKeyProvider.KeytoolException; -import com.android.sdklib.util.GrabProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.IProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.Wait; - -import java.io.File; -import java.io.IOException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableEntryException; -import java.security.cert.CertificateException; -import java.util.ArrayList; - -/** - * A Helper to create new keystore/key. - */ -public final class KeystoreHelper { - - /** - * Creates a new store - * @param osKeyStorePath the location of the store - * @param storeType an optional keystore type, or <code>null</code> if the default is to - * be used. - * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr - * of the keytool process call. - * @throws KeyStoreException - * @throws NoSuchAlgorithmException - * @throws CertificateException - * @throws UnrecoverableEntryException - * @throws IOException - * @throws KeytoolException - */ - public static boolean createNewStore( - String osKeyStorePath, - String storeType, - String storePassword, - String alias, - String keyPassword, - String description, - int validityYears, - final IKeyGenOutput output) - throws KeyStoreException, NoSuchAlgorithmException, CertificateException, - UnrecoverableEntryException, IOException, KeytoolException { - - // get the executable name of keytool depending on the platform. - String os = System.getProperty("os.name"); - - String keytoolCommand; - if (os.startsWith("Windows")) { - keytoolCommand = "keytool.exe"; - } else { - keytoolCommand = "keytool"; - } - - String javaHome = System.getProperty("java.home"); - - if (javaHome != null && javaHome.length() > 0) { - keytoolCommand = javaHome + File.separator + "bin" + File.separator + keytoolCommand; - } - - // create the command line to call key tool to build the key with no user input. - ArrayList<String> commandList = new ArrayList<String>(); - commandList.add(keytoolCommand); - commandList.add("-genkey"); - commandList.add("-alias"); - commandList.add(alias); - commandList.add("-keyalg"); - commandList.add("RSA"); - commandList.add("-dname"); - commandList.add(description); - commandList.add("-validity"); - commandList.add(Integer.toString(validityYears * 365)); - commandList.add("-keypass"); - commandList.add(keyPassword); - commandList.add("-keystore"); - commandList.add(osKeyStorePath); - commandList.add("-storepass"); - commandList.add(storePassword); - if (storeType != null) { - commandList.add("-storetype"); - commandList.add(storeType); - } - - String[] commandArray = commandList.toArray(new String[commandList.size()]); - - // launch the command line process - int result = 0; - try { - Process process = Runtime.getRuntime().exec(commandArray); - result = GrabProcessOutput.grabProcessOutput( - process, - Wait.WAIT_FOR_READERS, - new IProcessOutput() { - @Override - public void out(@Nullable String line) { - if (line != null) { - if (output != null) { - output.out(line); - } else { - System.out.println(line); - } - } - } - - @Override - public void err(@Nullable String line) { - if (line != null) { - if (output != null) { - output.err(line); - } else { - System.err.println(line); - } - } - } - }); - } catch (Exception e) { - // create the command line as one string for debugging purposes - StringBuilder builder = new StringBuilder(); - boolean firstArg = true; - for (String arg : commandArray) { - boolean hasSpace = arg.indexOf(' ') != -1; - - if (firstArg == true) { - firstArg = false; - } else { - builder.append(' '); - } - - if (hasSpace) { - builder.append('"'); - } - - builder.append(arg); - - if (hasSpace) { - builder.append('"'); - } - } - - throw new KeytoolException("Failed to create key: " + e.getMessage(), - javaHome, builder.toString()); - } - - if (result != 0) { - return false; - } - - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SignedJarBuilder.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SignedJarBuilder.java deleted file mode 100644 index 48f1b91..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SignedJarBuilder.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.build; - -import com.android.sdklib.internal.build.SignedJarBuilder.IZipEntryFilter.ZipAbortException; - -import sun.misc.BASE64Encoder; -import sun.security.pkcs.ContentInfo; -import sun.security.pkcs.PKCS7; -import sun.security.pkcs.SignerInfo; -import sun.security.x509.AlgorithmId; -import sun.security.x509.X500Name; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.security.DigestOutputStream; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.Signature; -import java.security.SignatureException; -import java.security.cert.X509Certificate; -import java.util.Map; -import java.util.jar.Attributes; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.jar.JarOutputStream; -import java.util.jar.Manifest; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * A Jar file builder with signature support. - */ -public class SignedJarBuilder { - private static final String DIGEST_ALGORITHM = "SHA1"; - private static final String DIGEST_ATTR = "SHA1-Digest"; - private static final String DIGEST_MANIFEST_ATTR = "SHA1-Digest-Manifest"; - - /** Write to another stream and also feed it to the Signature object. */ - private static class SignatureOutputStream extends FilterOutputStream { - private Signature mSignature; - private int mCount = 0; - - public SignatureOutputStream(OutputStream out, Signature sig) { - super(out); - mSignature = sig; - } - - @Override - public void write(int b) throws IOException { - try { - mSignature.update((byte) b); - } catch (SignatureException e) { - throw new IOException("SignatureException: " + e); - } - super.write(b); - mCount++; - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - try { - mSignature.update(b, off, len); - } catch (SignatureException e) { - throw new IOException("SignatureException: " + e); - } - super.write(b, off, len); - mCount += len; - } - - public int size() { - return mCount; - } - } - - private JarOutputStream mOutputJar; - private PrivateKey mKey; - private X509Certificate mCertificate; - private Manifest mManifest; - private BASE64Encoder mBase64Encoder; - private MessageDigest mMessageDigest; - - private byte[] mBuffer = new byte[4096]; - - /** - * Classes which implement this interface provides a method to check whether a file should - * be added to a Jar file. - */ - public interface IZipEntryFilter { - - /** - * An exception thrown during packaging of a zip file into APK file. - * This is typically thrown by implementations of - * {@link IZipEntryFilter#checkEntry(String)}. - */ - public static class ZipAbortException extends Exception { - private static final long serialVersionUID = 1L; - - public ZipAbortException() { - super(); - } - - public ZipAbortException(String format, Object... args) { - super(String.format(format, args)); - } - - public ZipAbortException(Throwable cause, String format, Object... args) { - super(String.format(format, args), cause); - } - - public ZipAbortException(Throwable cause) { - super(cause); - } - } - - - /** - * Checks a file for inclusion in a Jar archive. - * @param archivePath the archive file path of the entry - * @return <code>true</code> if the file should be included. - * @throws ZipAbortException if writing the file should be aborted. - */ - public boolean checkEntry(String archivePath) throws ZipAbortException; - } - - /** - * Creates a {@link SignedJarBuilder} with a given output stream, and signing information. - * <p/>If either <code>key</code> or <code>certificate</code> is <code>null</code> then - * the archive will not be signed. - * @param out the {@link OutputStream} where to write the Jar archive. - * @param key the {@link PrivateKey} used to sign the archive, or <code>null</code>. - * @param certificate the {@link X509Certificate} used to sign the archive, or - * <code>null</code>. - * @throws IOException - * @throws NoSuchAlgorithmException - */ - public SignedJarBuilder(OutputStream out, PrivateKey key, X509Certificate certificate) - throws IOException, NoSuchAlgorithmException { - mOutputJar = new JarOutputStream(out); - mOutputJar.setLevel(9); - mKey = key; - mCertificate = certificate; - - if (mKey != null && mCertificate != null) { - mManifest = new Manifest(); - Attributes main = mManifest.getMainAttributes(); - main.putValue("Manifest-Version", "1.0"); - main.putValue("Created-By", "1.0 (Android)"); - - mBase64Encoder = new BASE64Encoder(); - mMessageDigest = MessageDigest.getInstance(DIGEST_ALGORITHM); - } - } - - /** - * Writes a new {@link File} into the archive. - * @param inputFile the {@link File} to write. - * @param jarPath the filepath inside the archive. - * @throws IOException - */ - public void writeFile(File inputFile, String jarPath) throws IOException { - // Get an input stream on the file. - FileInputStream fis = new FileInputStream(inputFile); - try { - - // create the zip entry - JarEntry entry = new JarEntry(jarPath); - entry.setTime(inputFile.lastModified()); - - writeEntry(fis, entry); - } finally { - // close the file stream used to read the file - fis.close(); - } - } - - /** - * Copies the content of a Jar/Zip archive into the receiver archive. - * <p/>An optional {@link IZipEntryFilter} allows to selectively choose which files - * to copy over. - * @param input the {@link InputStream} for the Jar/Zip to copy. - * @param filter the filter or <code>null</code> - * @throws IOException - * @throws ZipAbortException if the {@link IZipEntryFilter} filter indicated that the write - * must be aborted. - */ - public void writeZip(InputStream input, IZipEntryFilter filter) - throws IOException, ZipAbortException { - ZipInputStream zis = new ZipInputStream(input); - - try { - // loop on the entries of the intermediary package and put them in the final package. - ZipEntry entry; - while ((entry = zis.getNextEntry()) != null) { - String name = entry.getName(); - - // do not take directories or anything inside a potential META-INF folder. - if (entry.isDirectory() || name.startsWith("META-INF/")) { - continue; - } - - // if we have a filter, we check the entry against it - if (filter != null && filter.checkEntry(name) == false) { - continue; - } - - JarEntry newEntry; - - // Preserve the STORED method of the input entry. - if (entry.getMethod() == JarEntry.STORED) { - newEntry = new JarEntry(entry); - } else { - // Create a new entry so that the compressed len is recomputed. - newEntry = new JarEntry(name); - } - - writeEntry(zis, newEntry); - - zis.closeEntry(); - } - } finally { - zis.close(); - } - } - - /** - * Closes the Jar archive by creating the manifest, and signing the archive. - * @throws IOException - * @throws GeneralSecurityException - */ - public void close() throws IOException, GeneralSecurityException { - if (mManifest != null) { - // write the manifest to the jar file - mOutputJar.putNextEntry(new JarEntry(JarFile.MANIFEST_NAME)); - mManifest.write(mOutputJar); - - // CERT.SF - Signature signature = Signature.getInstance("SHA1with" + mKey.getAlgorithm()); - signature.initSign(mKey); - mOutputJar.putNextEntry(new JarEntry("META-INF/CERT.SF")); - writeSignatureFile(new SignatureOutputStream(mOutputJar, signature)); - - // CERT.* - mOutputJar.putNextEntry(new JarEntry("META-INF/CERT." + mKey.getAlgorithm())); - writeSignatureBlock(signature, mCertificate, mKey); - } - - mOutputJar.close(); - mOutputJar = null; - } - - /** - * Clean up of the builder for interrupted workflow. - * This does nothing if {@link #close()} was called successfully. - */ - public void cleanUp() { - if (mOutputJar != null) { - try { - mOutputJar.close(); - } catch (IOException e) { - // pass - } - } - } - - /** - * Adds an entry to the output jar, and write its content from the {@link InputStream} - * @param input The input stream from where to write the entry content. - * @param entry the entry to write in the jar. - * @throws IOException - */ - private void writeEntry(InputStream input, JarEntry entry) throws IOException { - // add the entry to the jar archive - mOutputJar.putNextEntry(entry); - - // read the content of the entry from the input stream, and write it into the archive. - int count; - while ((count = input.read(mBuffer)) != -1) { - mOutputJar.write(mBuffer, 0, count); - - // update the digest - if (mMessageDigest != null) { - mMessageDigest.update(mBuffer, 0, count); - } - } - - // close the entry for this file - mOutputJar.closeEntry(); - - if (mManifest != null) { - // update the manifest for this entry. - Attributes attr = mManifest.getAttributes(entry.getName()); - if (attr == null) { - attr = new Attributes(); - mManifest.getEntries().put(entry.getName(), attr); - } - attr.putValue(DIGEST_ATTR, mBase64Encoder.encode(mMessageDigest.digest())); - } - } - - /** Writes a .SF file with a digest to the manifest. */ - private void writeSignatureFile(SignatureOutputStream out) - throws IOException, GeneralSecurityException { - Manifest sf = new Manifest(); - Attributes main = sf.getMainAttributes(); - main.putValue("Signature-Version", "1.0"); - main.putValue("Created-By", "1.0 (Android)"); - - BASE64Encoder base64 = new BASE64Encoder(); - MessageDigest md = MessageDigest.getInstance(DIGEST_ALGORITHM); - PrintStream print = new PrintStream( - new DigestOutputStream(new ByteArrayOutputStream(), md), - true, "UTF-8"); - - // Digest of the entire manifest - mManifest.write(print); - print.flush(); - main.putValue(DIGEST_MANIFEST_ATTR, base64.encode(md.digest())); - - Map<String, Attributes> entries = mManifest.getEntries(); - for (Map.Entry<String, Attributes> entry : entries.entrySet()) { - // Digest of the manifest stanza for this entry. - print.print("Name: " + entry.getKey() + "\r\n"); - for (Map.Entry<Object, Object> att : entry.getValue().entrySet()) { - print.print(att.getKey() + ": " + att.getValue() + "\r\n"); - } - print.print("\r\n"); - print.flush(); - - Attributes sfAttr = new Attributes(); - sfAttr.putValue(DIGEST_ATTR, base64.encode(md.digest())); - sf.getEntries().put(entry.getKey(), sfAttr); - } - - sf.write(out); - - // A bug in the java.util.jar implementation of Android platforms - // up to version 1.6 will cause a spurious IOException to be thrown - // if the length of the signature file is a multiple of 1024 bytes. - // As a workaround, add an extra CRLF in this case. - if ((out.size() % 1024) == 0) { - out.write('\r'); - out.write('\n'); - } - } - - /** Write the certificate file with a digital signature. */ - private void writeSignatureBlock(Signature signature, X509Certificate publicKey, - PrivateKey privateKey) - throws IOException, GeneralSecurityException { - SignerInfo signerInfo = new SignerInfo( - new X500Name(publicKey.getIssuerX500Principal().getName()), - publicKey.getSerialNumber(), - AlgorithmId.get(DIGEST_ALGORITHM), - AlgorithmId.get(privateKey.getAlgorithm()), - signature.sign()); - - PKCS7 pkcs7 = new PKCS7( - new AlgorithmId[] { AlgorithmId.get(DIGEST_ALGORITHM) }, - new ContentInfo(ContentInfo.DATA_OID, null), - new X509Certificate[] { publicKey }, - new SignerInfo[] { signerInfo }); - - pkcs7.encodeSignedData(mOutputJar); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SymbolLoader.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SymbolLoader.java deleted file mode 100644 index 775c558..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SymbolLoader.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.build; - -import com.google.common.base.Charsets; -import com.google.common.collect.HashBasedTable; -import com.google.common.collect.Table; -import com.google.common.io.Files; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -/** - */ -public class SymbolLoader { - - private final File mSymbolFile; - private HashBasedTable<String, String, SymbolEntry> mSymbols; - - public static class SymbolEntry { - private final String mName; - private final String mType; - private final String mValue; - - public SymbolEntry(String name, String type, String value) { - mName = name; - mType = type; - mValue = value; - } - - public String getValue() { - return mValue; - } - - public String getName() { - return mName; - } - - public String getType() { - return mType; - } - } - - public SymbolLoader(File symbolFile) { - mSymbolFile = symbolFile; - } - - public void load() throws IOException { - List<String> lines = Files.readLines(mSymbolFile, Charsets.UTF_8); - - mSymbols = HashBasedTable.create(); - - try { - for (String line : lines) { - // format is "<type> <class> <name> <value>" - // don't want to split on space as value could contain spaces. - int pos = line.indexOf(' '); - String type = line.substring(0, pos); - int pos2 = line.indexOf(' ', pos + 1); - String className = line.substring(pos + 1, pos2); - int pos3 = line.indexOf(' ', pos2 + 1); - String name = line.substring(pos2 + 1, pos3); - String value = line.substring(pos3 + 1); - - mSymbols.put(className, name, new SymbolEntry(name, type, value)); - } - } catch (ArrayIndexOutOfBoundsException e) { - throw new IOException("File format error reading " + mSymbolFile.getAbsolutePath()); - } - } - - Table<String, String, SymbolEntry> getSymbols() { - return mSymbols; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SymbolWriter.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SymbolWriter.java deleted file mode 100644 index 63346c2..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/build/SymbolWriter.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.build; - -import com.android.SdkConstants; -import com.android.sdklib.internal.build.SymbolLoader.SymbolEntry; -import com.google.common.base.Charsets; -import com.google.common.base.Splitter; -import com.google.common.collect.Table; -import com.google.common.io.Closeables; -import com.google.common.io.Files; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.util.Map; - -/** - */ -public class SymbolWriter { - - private final String mOutFolder; - private final String mPackageName; - private final SymbolLoader mSymbols; - private final SymbolLoader mValues; - - public SymbolWriter(String outFolder, String packageName, SymbolLoader symbols, - SymbolLoader values) { - mOutFolder = outFolder; - mPackageName = packageName; - mSymbols = symbols; - mValues = values; - } - - public void write() throws IOException { - Splitter splitter = Splitter.on('.'); - Iterable<String> folders = splitter.split(mPackageName); - File file = new File(mOutFolder); - for (String folder : folders) { - file = new File(file, folder); - } - file.mkdirs(); - file = new File(file, SdkConstants.FN_RESOURCE_CLASS); - - BufferedWriter writer = null; - try { - writer = Files.newWriter(file, Charsets.UTF_8); - - writer.write("/* AUTO-GENERATED FILE. DO NOT MODIFY.\n"); - writer.write(" *\n"); - writer.write(" * This class was automatically generated by the\n"); - writer.write(" * aapt tool from the resource data it found. It\n"); - writer.write(" * should not be modified by hand.\n"); - writer.write(" */\n"); - - writer.write("package "); - writer.write(mPackageName); - writer.write(";\n\npublic final class R {\n"); - - Table<String, String, SymbolEntry> symbols = mSymbols.getSymbols(); - Table<String, String, SymbolEntry> values = mValues.getSymbols(); - - for (String row : symbols.rowKeySet()) { - writer.write("\tpublic static final class "); - writer.write(row); - writer.write(" {\n"); - - for (Map.Entry<String, SymbolEntry> symbol : symbols.row(row).entrySet()) { - // get the matching SymbolEntry from the values Table. - SymbolEntry value = values.get(row, symbol.getKey()); - if (value != null) { - writer.write("\t\tpublic static final "); - writer.write(value.getType()); - writer.write(" "); - writer.write(value.getName()); - writer.write(" = "); - writer.write(value.getValue()); - writer.write(";\n"); - } - } - - writer.write("\t}\n"); - } - - writer.write("}\n"); - } finally { - Closeables.closeQuietly(writer); - } - } -}
\ No newline at end of file diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/IPropertySource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/IPropertySource.java deleted file mode 100644 index 92bd6b9..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/IPropertySource.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.project; - -/** - * A source able to return properties by name. - * - */ -public interface IPropertySource { - String getProperty(String name); - void debugPrint(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java deleted file mode 100644 index fee9472..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java +++ /dev/null @@ -1,1324 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.project; - -import com.android.SdkConstants; -import com.android.io.FileWrapper; -import com.android.io.FolderWrapper; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.project.ProjectProperties.PropertyType; -import com.android.utils.ILogger; -import com.android.xml.AndroidManifest; -import com.android.xml.AndroidXPathFactory; - -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; - -/** - * Creates the basic files needed to get an Android project up and running. - * - * @hide - */ -public class ProjectCreator { - - /** Version of the build.xml. Stored in version-tag */ - private final static int MIN_BUILD_VERSION_TAG = 1; - - /** Package path substitution string used in template files, i.e. "PACKAGE_PATH" */ - private final static String PH_JAVA_FOLDER = "PACKAGE_PATH"; - /** Package name substitution string used in template files, i.e. "PACKAGE" */ - private final static String PH_PACKAGE = "PACKAGE"; - /** Activity name substitution string used in template files, i.e. "ACTIVITY_NAME". - * @deprecated This is only used for older templates. For new ones see - * {@link #PH_ACTIVITY_ENTRY_NAME}, and {@link #PH_ACTIVITY_CLASS_NAME}. */ - @Deprecated - private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME"; - /** Activity name substitution string used in manifest templates, i.e. "ACTIVITY_ENTRY_NAME".*/ - private final static String PH_ACTIVITY_ENTRY_NAME = "ACTIVITY_ENTRY_NAME"; - /** Activity name substitution string used in class templates, i.e. "ACTIVITY_CLASS_NAME".*/ - private final static String PH_ACTIVITY_CLASS_NAME = "ACTIVITY_CLASS_NAME"; - /** Activity FQ-name substitution string used in class templates, i.e. "ACTIVITY_FQ_NAME".*/ - private final static String PH_ACTIVITY_FQ_NAME = "ACTIVITY_FQ_NAME"; - /** Original Activity class name substitution string used in class templates, i.e. - * "ACTIVITY_TESTED_CLASS_NAME".*/ - private final static String PH_ACTIVITY_TESTED_CLASS_NAME = "ACTIVITY_TESTED_CLASS_NAME"; - /** Project name substitution string used in template files, i.e. "PROJECT_NAME". */ - private final static String PH_PROJECT_NAME = "PROJECT_NAME"; - /** Application icon substitution string used in the manifest template */ - private final static String PH_ICON = "ICON"; - /** Version tag name substitution string used in template files, i.e. "VERSION_TAG". */ - private final static String PH_VERSION_TAG = "VERSION_TAG"; - - /** The xpath to find a project name in an Ant build file. */ - private static final String XPATH_PROJECT_NAME = "/project/@name"; - - /** Pattern for characters accepted in a project name. Since this will be used as a - * directory name, we're being a bit conservative on purpose: dot and space cannot be used. */ - public static final Pattern RE_PROJECT_NAME = Pattern.compile("[a-zA-Z0-9_]+"); - /** List of valid characters for a project name. Used for display purposes. */ - public final static String CHARS_PROJECT_NAME = "a-z A-Z 0-9 _"; - - /** Pattern for characters accepted in a package name. A package is list of Java identifier - * separated by a dot. We need to have at least one dot (e.g. a two-level package name). - * A Java identifier cannot start by a digit. */ - public static final Pattern RE_PACKAGE_NAME = - Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*(?:\\.[a-zA-Z_][a-zA-Z0-9_]*)+"); - /** List of valid characters for a project name. Used for display purposes. */ - public final static String CHARS_PACKAGE_NAME = "a-z A-Z 0-9 _"; - - /** Pattern for characters accepted in an activity name, which is a Java identifier. */ - public static final Pattern RE_ACTIVITY_NAME = - Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*"); - /** List of valid characters for a project name. Used for display purposes. */ - public final static String CHARS_ACTIVITY_NAME = "a-z A-Z 0-9 _"; - - - public enum OutputLevel { - /** Silent mode. Project creation will only display errors. */ - SILENT, - /** Normal mode. Project creation will display what's being done, display - * error but not warnings. */ - NORMAL, - /** Verbose mode. Project creation will display what's being done, errors and warnings. */ - VERBOSE; - } - - /** - * Exception thrown when a project creation fails, typically because a template - * file cannot be written. - */ - private static class ProjectCreateException extends Exception { - /** default UID. This will not be serialized anyway. */ - private static final long serialVersionUID = 1L; - - @SuppressWarnings("unused") - ProjectCreateException(String message) { - super(message); - } - - ProjectCreateException(Throwable t, String format, Object... args) { - super(format != null ? String.format(format, args) : format, t); - } - - ProjectCreateException(String format, Object... args) { - super(String.format(format, args)); - } - } - - /** The {@link OutputLevel} verbosity. */ - private final OutputLevel mLevel; - /** Logger for errors and output. Cannot be null. */ - private final ILogger mLog; - /** The OS path of the SDK folder. */ - private final String mSdkFolder; - /** The {@link SdkManager} instance. */ - private final SdkManager mSdkManager; - - /** - * Helper class to create android projects. - * - * @param sdkManager The {@link SdkManager} instance. - * @param sdkFolder The OS path of the SDK folder. - * @param level The {@link OutputLevel} verbosity. - * @param log Logger for errors and output. Cannot be null. - */ - public ProjectCreator(SdkManager sdkManager, String sdkFolder, OutputLevel level, ILogger log) { - mSdkManager = sdkManager; - mSdkFolder = sdkFolder; - mLevel = level; - mLog = log; - } - - /** - * Creates a new project. - * <p/> - * The caller should have already checked and sanitized the parameters. - * - * @param folderPath the folder of the project to create. - * @param projectName the name of the project. The name must match the - * {@link #RE_PROJECT_NAME} regex. - * @param packageName the package of the project. The name must match the - * {@link #RE_PACKAGE_NAME} regex. - * @param activityEntry the activity of the project as it will appear in the manifest. Can be - * null if no activity should be created. The name must match the - * {@link #RE_ACTIVITY_NAME} regex. - * @param target the project target. - * @param library whether the project is a library. - * @param pathToMainProject if non-null the project will be setup to test a main project - * located at the given path. - */ - public void createProject(String folderPath, String projectName, - String packageName, String activityEntry, IAndroidTarget target, boolean library, - String pathToMainProject) { - - // create project folder if it does not exist - File projectFolder = checkNewProjectLocation(folderPath); - if (projectFolder == null) { - return; - } - - try { - boolean isTestProject = pathToMainProject != null; - - // first create the project properties. - - // location of the SDK goes in localProperty - ProjectPropertiesWorkingCopy localProperties = ProjectProperties.create(folderPath, - PropertyType.LOCAL); - localProperties.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder); - localProperties.save(); - - // target goes in default properties - ProjectPropertiesWorkingCopy defaultProperties = ProjectProperties.create(folderPath, - PropertyType.PROJECT); - defaultProperties.setProperty(ProjectProperties.PROPERTY_TARGET, target.hashString()); - if (library) { - defaultProperties.setProperty(ProjectProperties.PROPERTY_LIBRARY, "true"); - } - defaultProperties.save(); - - // create a build.properties file with just the application package - ProjectPropertiesWorkingCopy buildProperties = ProjectProperties.create(folderPath, - PropertyType.ANT); - - if (isTestProject) { - buildProperties.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, - pathToMainProject); - } - - buildProperties.save(); - - // create the map for place-holders of values to replace in the templates - final HashMap<String, String> keywords = new HashMap<String, String>(); - - // create the required folders. - // compute src folder path - final String packagePath = - stripString(packageName.replace(".", File.separator), - File.separatorChar); - - // put this path in the place-holder map for project files that needs to list - // files manually. - keywords.put(PH_JAVA_FOLDER, packagePath); - keywords.put(PH_PACKAGE, packageName); - keywords.put(PH_VERSION_TAG, Integer.toString(MIN_BUILD_VERSION_TAG)); - - - // compute some activity related information - String fqActivityName = null, activityPath = null, activityClassName = null; - String originalActivityEntry = activityEntry; - String originalActivityClassName = null; - if (activityEntry != null) { - if (isTestProject) { - // append Test so that it doesn't collide with the main project activity. - activityEntry += "Test"; - - // get the classname from the original activity entry. - int pos = originalActivityEntry.lastIndexOf('.'); - if (pos != -1) { - originalActivityClassName = originalActivityEntry.substring(pos + 1); - } else { - originalActivityClassName = originalActivityEntry; - } - } - - // get the fully qualified name of the activity - fqActivityName = AndroidManifest.combinePackageAndClassName(packageName, - activityEntry); - - // get the activity path (replace the . to /) - activityPath = stripString(fqActivityName.replace(".", File.separator), - File.separatorChar); - - // remove the last segment, so that we only have the path to the activity, but - // not the activity filename itself. - activityPath = activityPath.substring(0, - activityPath.lastIndexOf(File.separatorChar)); - - // finally, get the class name for the activity - activityClassName = fqActivityName.substring(fqActivityName.lastIndexOf('.') + 1); - } - - // at this point we have the following for the activity: - // activityEntry: this is the manifest entry. For instance .MyActivity - // fqActivityName: full-qualified class name: com.foo.MyActivity - // activityClassName: only the classname: MyActivity - // originalActivityClassName: the classname of the activity being tested (if applicable) - - // Add whatever activity info is needed in the place-holder map. - // Older templates only expect ACTIVITY_NAME to be the same (and unmodified for tests). - if (target.getVersion().getApiLevel() < 4) { // legacy - if (originalActivityEntry != null) { - keywords.put(PH_ACTIVITY_NAME, originalActivityEntry); - } - } else { - // newer templates make a difference between the manifest entries, classnames, - // as well as the main and test classes. - if (activityEntry != null) { - keywords.put(PH_ACTIVITY_ENTRY_NAME, activityEntry); - keywords.put(PH_ACTIVITY_CLASS_NAME, activityClassName); - keywords.put(PH_ACTIVITY_FQ_NAME, fqActivityName); - if (originalActivityClassName != null) { - keywords.put(PH_ACTIVITY_TESTED_CLASS_NAME, originalActivityClassName); - } - } - } - - // Take the project name from the command line if there's one - if (projectName != null) { - keywords.put(PH_PROJECT_NAME, projectName); - } else { - if (activityClassName != null) { - // Use the activity class name as project name - keywords.put(PH_PROJECT_NAME, activityClassName); - } else { - // We need a project name. Just pick up the basename of the project - // directory. - projectName = projectFolder.getName(); - keywords.put(PH_PROJECT_NAME, projectName); - } - } - - // create the source folder for the activity - if (activityClassName != null) { - String srcActivityFolderPath = - SdkConstants.FD_SOURCES + File.separator + activityPath; - File sourceFolder = createDirs(projectFolder, srcActivityFolderPath); - - String javaTemplate = isTestProject ? "java_tests_file.template" - : "java_file.template"; - String activityFileName = activityClassName + ".java"; - - installTargetTemplate(javaTemplate, new File(sourceFolder, activityFileName), - keywords, target); - } else { - // we should at least create 'src' - createDirs(projectFolder, SdkConstants.FD_SOURCES); - } - - // create other useful folders - File resourceFolder = createDirs(projectFolder, SdkConstants.FD_RESOURCES); - createDirs(projectFolder, SdkConstants.FD_OUTPUT); - createDirs(projectFolder, SdkConstants.FD_NATIVE_LIBS); - - if (isTestProject == false) { - /* Make res files only for non test projects */ - File valueFolder = createDirs(resourceFolder, SdkConstants.FD_RES_VALUES); - installTargetTemplate("strings.template", new File(valueFolder, "strings.xml"), - keywords, target); - - File layoutFolder = createDirs(resourceFolder, SdkConstants.FD_RES_LAYOUT); - installTargetTemplate("layout.template", new File(layoutFolder, "main.xml"), - keywords, target); - - // create the icons - if (installIcons(resourceFolder, target)) { - keywords.put(PH_ICON, "android:icon=\"@drawable/ic_launcher\""); - } else { - keywords.put(PH_ICON, ""); - } - } - - /* Make AndroidManifest.xml and build.xml files */ - String manifestTemplate = "AndroidManifest.template"; - if (isTestProject) { - manifestTemplate = "AndroidManifest.tests.template"; - } - - installTargetTemplate(manifestTemplate, - new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML), - keywords, target); - - installTemplate("build.template", - new File(projectFolder, SdkConstants.FN_BUILD_XML), - keywords); - - // install the proguard config file. - installTemplate(SdkConstants.FN_PROJECT_PROGUARD_FILE, - new File(projectFolder, SdkConstants.FN_PROJECT_PROGUARD_FILE), - null /*keywords*/); - } catch (Exception e) { - mLog.error(e, null); - } - } - - private File checkNewProjectLocation(String folderPath) { - File projectFolder = new File(folderPath); - if (!projectFolder.exists()) { - - boolean created = false; - Throwable t = null; - try { - created = projectFolder.mkdirs(); - } catch (Exception e) { - t = e; - } - - if (created) { - println("Created project directory: %1$s", projectFolder); - } else { - mLog.error(t, "Could not create directory: %1$s", projectFolder); - return null; - } - } else { - Exception e = null; - String error = null; - try { - String[] content = projectFolder.list(); - if (content == null) { - error = "Project folder '%1$s' is not a directory."; - } else if (content.length != 0) { - error = "Project folder '%1$s' is not empty. Please consider using '%2$s update' instead."; - } - } catch (Exception e1) { - e = e1; - } - - if (e != null || error != null) { - mLog.error(e, error, projectFolder, SdkConstants.androidCmdName()); - } - } - return projectFolder; - } - - /** - * Updates an existing project. - * <p/> - * Workflow: - * <ul> - * <li> Check AndroidManifest.xml is present (required) - * <li> Check if there's a legacy properties file and convert it - * <li> Check there's a project.properties with a target *or* --target was specified - * <li> Update default.prop if --target was specified - * <li> Refresh/create "sdk" in local.properties - * <li> Build.xml: create if not present or if version-tag is found or not. version-tag:custom - * prevent any overwrite. version-tag:[integer] will override. missing version-tag will query - * the dev. - * </ul> - * - * @param folderPath the folder of the project to update. This folder must exist. - * @param target the project target. Can be null. - * @param projectName The project name from --name. Can be null. - * @param libraryPath the path to a library to add to the references. Can be null. - * @return true if the project was successfully updated. - */ - @SuppressWarnings("deprecation") - public boolean updateProject(String folderPath, IAndroidTarget target, String projectName, - String libraryPath) { - // since this is an update, check the folder does point to a project - FileWrapper androidManifest = checkProjectFolder(folderPath, - SdkConstants.FN_ANDROID_MANIFEST_XML); - if (androidManifest == null) { - return false; - } - - // get the parent folder. - FolderWrapper projectFolder = (FolderWrapper) androidManifest.getParentFolder(); - - boolean hasProguard = false; - - // Check there's a project.properties with a target *or* --target was specified - IAndroidTarget originalTarget = null; - boolean writeProjectProp = false; - ProjectProperties props = ProjectProperties.load(projectFolder, PropertyType.PROJECT); - - if (props == null) { - // no project.properties, try to load default.properties - props = ProjectProperties.load(projectFolder, PropertyType.LEGACY_DEFAULT); - writeProjectProp = true; - } - - if (props != null) { - String targetHash = props.getProperty(ProjectProperties.PROPERTY_TARGET); - originalTarget = mSdkManager.getTargetFromHashString(targetHash); - - // if the project is already setup with proguard, we won't copy the proguard config. - hasProguard = props.getProperty(ProjectProperties.PROPERTY_PROGUARD_CONFIG) != null; - } - - if (originalTarget == null && target == null) { - mLog.error(null, - "The project either has no target set or the target is invalid.\n" + - "Please provide a --target to the '%1$s update' command.", - SdkConstants.androidCmdName()); - return false; - } - - boolean saveProjectProps = false; - - ProjectPropertiesWorkingCopy propsWC = null; - - // Update default.prop if --target was specified - if (target != null || writeProjectProp) { - // we already attempted to load the file earlier, if that failed, create it. - if (props == null) { - propsWC = ProjectProperties.create(projectFolder, PropertyType.PROJECT); - } else { - propsWC = props.makeWorkingCopy(PropertyType.PROJECT); - } - - // set or replace the target - if (target != null) { - propsWC.setProperty(ProjectProperties.PROPERTY_TARGET, target.hashString()); - } - saveProjectProps = true; - } - - if (libraryPath != null) { - // At this point, the default properties already exists, either because they were - // already there or because they were created with a new target - if (propsWC == null) { - assert props != null; - propsWC = props.makeWorkingCopy(); - } - - // check the reference is valid - File libProject = new File(libraryPath); - String resolvedPath; - if (libProject.isAbsolute() == false) { - libProject = new File(projectFolder, libraryPath); - try { - resolvedPath = libProject.getCanonicalPath(); - } catch (IOException e) { - mLog.error(e, "Unable to resolve path to library project: %1$s", libraryPath); - return false; - } - } else { - resolvedPath = libProject.getAbsolutePath(); - } - - println("Resolved location of library project to: %1$s", resolvedPath); - - // check the lib project exists - if (checkProjectFolder(resolvedPath, SdkConstants.FN_ANDROID_MANIFEST_XML) == null) { - mLog.error(null, "No Android Manifest at: %1$s", resolvedPath); - return false; - } - - // look for other references to figure out the index - int index = 1; - while (true) { - String propName = ProjectProperties.PROPERTY_LIB_REF + Integer.toString(index); - assert props != null; - if (props == null) { - // This should not happen yet SDK bug 20535 says it can, not sure how. - break; - } - String ref = props.getProperty(propName); - if (ref == null) { - break; - } else { - index++; - } - } - - String propName = ProjectProperties.PROPERTY_LIB_REF + Integer.toString(index); - propsWC.setProperty(propName, libraryPath); - saveProjectProps = true; - } - - // save the default props if needed. - if (saveProjectProps) { - try { - assert propsWC != null; - propsWC.save(); - if (writeProjectProp) { - println("Updated and renamed %1$s to %2$s", - PropertyType.LEGACY_DEFAULT.getFilename(), - PropertyType.PROJECT.getFilename()); - } else { - println("Updated %1$s", PropertyType.PROJECT.getFilename()); - } - } catch (Exception e) { - mLog.error(e, "Failed to write %1$s file in '%2$s'", - PropertyType.PROJECT.getFilename(), - folderPath); - return false; - } - - if (writeProjectProp) { - // need to delete the default prop file. - ProjectProperties.delete(projectFolder, PropertyType.LEGACY_DEFAULT); - } - } - - // Refresh/create "sdk" in local.properties - // because the file may already exists and contain other values (like apk config), - // we first try to load it. - props = ProjectProperties.load(projectFolder, PropertyType.LOCAL); - if (props == null) { - propsWC = ProjectProperties.create(projectFolder, PropertyType.LOCAL); - } else { - propsWC = props.makeWorkingCopy(); - } - - // set or replace the sdk location. - propsWC.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder); - try { - propsWC.save(); - println("Updated %1$s", PropertyType.LOCAL.getFilename()); - } catch (Exception e) { - mLog.error(e, "Failed to write %1$s file in '%2$s'", - PropertyType.LOCAL.getFilename(), - folderPath); - return false; - } - - // legacy: check if build.properties must be renamed to ant.properties. - props = ProjectProperties.load(projectFolder, PropertyType.ANT); - if (props == null) { - props = ProjectProperties.load(projectFolder, PropertyType.LEGACY_BUILD); - if (props != null) { - try { - // get a working copy with the new property type - propsWC = props.makeWorkingCopy(PropertyType.ANT); - propsWC.save(); - - // delete the old file - ProjectProperties.delete(projectFolder, PropertyType.LEGACY_BUILD); - - println("Renamed %1$s to %2$s", - PropertyType.LEGACY_BUILD.getFilename(), - PropertyType.ANT.getFilename()); - } catch (Exception e) { - mLog.error(e, "Failed to write %1$s file in '%2$s'", - PropertyType.ANT.getFilename(), - folderPath); - return false; - } - } - } - - // Build.xml: create if not present or no <androidinit/> in it - File buildXml = new File(projectFolder, SdkConstants.FN_BUILD_XML); - boolean needsBuildXml = projectName != null || !buildXml.exists(); - - // if it seems there's no need for a new build.xml, look for inside the file - // to try to detect old ones that may need updating. - if (!needsBuildXml) { - // we are looking for version-tag: followed by either an integer or "custom". - if (checkFileContainsRegexp(buildXml, "version-tag:\\s*custom") != null) { //$NON-NLS-1$ - println("%1$s: Found version-tag: custom. File will not be updated.", - SdkConstants.FN_BUILD_XML); - } else { - Matcher m = checkFileContainsRegexp(buildXml, "version-tag:\\s*(\\d+)"); //$NON-NLS-1$ - if (m == null) { - println("----------\n" + - "%1$s: Failed to find version-tag string. File must be updated.\n" + - "In order to not erase potential customizations, the file will not be automatically regenerated.\n" + - "If no changes have been made to the file, delete it manually and run the command again.\n" + - "If you have made customizations to the build process, the file must be manually updated.\n" + - "It is recommended to:\n" + - "\t* Copy current file to a safe location.\n" + - "\t* Delete original file.\n" + - "\t* Run command again to generate a new file.\n" + - "\t* Port customizations to the new file, by looking at the new rules file\n" + - "\t located at <SDK>/tools/ant/build.xml\n" + - "\t* Update file to contain\n" + - "\t version-tag: custom\n" + - "\t to prevent file from being rewritten automatically by the SDK tools.\n" + - "----------\n", - SdkConstants.FN_BUILD_XML); - } else { - String versionStr = m.group(1); - if (versionStr != null) { - // can't fail due to regexp above. - int version = Integer.parseInt(versionStr); - if (version < MIN_BUILD_VERSION_TAG) { - println("%1$s: Found version-tag: %2$d. Expected version-tag: %3$d: file must be updated.", - SdkConstants.FN_BUILD_XML, version, MIN_BUILD_VERSION_TAG); - needsBuildXml = true; - } - } - } - } - } - - if (needsBuildXml) { - // create the map for place-holders of values to replace in the templates - final HashMap<String, String> keywords = new HashMap<String, String>(); - - // put the current version-tag value - keywords.put(PH_VERSION_TAG, Integer.toString(MIN_BUILD_VERSION_TAG)); - - // if there was no project name on the command line, figure one out. - if (projectName == null) { - // otherwise, take it from the existing build.xml if it exists already. - if (buildXml.exists()) { - try { - XPathFactory factory = XPathFactory.newInstance(); - XPath xpath = factory.newXPath(); - - projectName = xpath.evaluate(XPATH_PROJECT_NAME, - new InputSource(new FileInputStream(buildXml))); - } catch (XPathExpressionException e) { - // this is ok since we're going to recreate the file. - mLog.error(e, "Unable to find existing project name from %1$s", - SdkConstants.FN_BUILD_XML); - } catch (FileNotFoundException e) { - // can't happen since we check above. - } - } - - // if the project is still null, then we find another way. - if (projectName == null) { - extractPackageFromManifest(androidManifest, keywords); - if (keywords.containsKey(PH_ACTIVITY_ENTRY_NAME)) { - String activity = keywords.get(PH_ACTIVITY_ENTRY_NAME); - // keep only the last segment if applicable - int pos = activity.lastIndexOf('.'); - if (pos != -1) { - activity = activity.substring(pos + 1); - } - - // Use the activity as project name - projectName = activity; - - println("No project name specified, using Activity name '%1$s'.\n" + - "If you wish to change it, edit the first line of %2$s.", - activity, SdkConstants.FN_BUILD_XML); - } else { - // We need a project name. Just pick up the basename of the project - // directory. - File projectCanonicalFolder = projectFolder; - try { - projectCanonicalFolder = projectCanonicalFolder.getCanonicalFile(); - } catch (IOException e) { - // ignore, keep going - } - - // Use the folder name as project name - projectName = projectCanonicalFolder.getName(); - - println("No project name specified, using project folder name '%1$s'.\n" + - "If you wish to change it, edit the first line of %2$s.", - projectName, SdkConstants.FN_BUILD_XML); - } - } - } - - // put the project name in the map for replacement during the template installation. - keywords.put(PH_PROJECT_NAME, projectName); - - if (mLevel == OutputLevel.VERBOSE) { - println("Regenerating %1$s with project name %2$s", - SdkConstants.FN_BUILD_XML, - keywords.get(PH_PROJECT_NAME)); - } - - try { - installTemplate("build.template", buildXml, keywords); - } catch (ProjectCreateException e) { - mLog.error(e, null); - return false; - } - } - - if (hasProguard == false) { - try { - installTemplate(SdkConstants.FN_PROJECT_PROGUARD_FILE, - // Write ProGuard config files with the extension .pro which - // is what is used in the ProGuard documentation and samples - new File(projectFolder, SdkConstants.FN_PROJECT_PROGUARD_FILE), - null /*placeholderMap*/); - } catch (ProjectCreateException e) { - mLog.error(e, null); - return false; - } - } - - return true; - } - - /** - * Updates a test project with a new path to the main (tested) project. - * @param folderPath the path of the test project. - * @param pathToMainProject the path to the main project, relative to the test project. - */ - @SuppressWarnings("deprecation") - public void updateTestProject(final String folderPath, final String pathToMainProject, - final SdkManager sdkManager) { - // since this is an update, check the folder does point to a project - if (checkProjectFolder(folderPath, SdkConstants.FN_ANDROID_MANIFEST_XML) == null) { - return; - } - - // check the path to the main project is valid. - File mainProject = new File(pathToMainProject); - String resolvedPath; - if (mainProject.isAbsolute() == false) { - mainProject = new File(folderPath, pathToMainProject); - try { - resolvedPath = mainProject.getCanonicalPath(); - } catch (IOException e) { - mLog.error(e, "Unable to resolve path to main project: %1$s", pathToMainProject); - return; - } - } else { - resolvedPath = mainProject.getAbsolutePath(); - } - - println("Resolved location of main project to: %1$s", resolvedPath); - - // check the main project exists - if (checkProjectFolder(resolvedPath, SdkConstants.FN_ANDROID_MANIFEST_XML) == null) { - mLog.error(null, "No Android Manifest at: %1$s", resolvedPath); - return; - } - - // now get the target from the main project - ProjectProperties projectProp = ProjectProperties.load(resolvedPath, PropertyType.PROJECT); - if (projectProp == null) { - // legacy support for older file name. - projectProp = ProjectProperties.load(resolvedPath, PropertyType.LEGACY_DEFAULT); - if (projectProp == null) { - mLog.error(null, "No %1$s at: %2$s", PropertyType.PROJECT.getFilename(), - resolvedPath); - return; - } - } - - String targetHash = projectProp.getProperty(ProjectProperties.PROPERTY_TARGET); - if (targetHash == null) { - mLog.error(null, "%1$s in the main project has no target property.", - PropertyType.PROJECT.getFilename()); - return; - } - - IAndroidTarget target = sdkManager.getTargetFromHashString(targetHash); - if (target == null) { - mLog.error(null, "Main project target %1$s is not a valid target.", targetHash); - return; - } - - // update test-project does not support the --name parameter, therefore the project - // name should generally not be passed to updateProject(). - // However if build.xml does not exist then updateProject() will recreate it. In this - // case we will need the project name. - // To do this, we look for the parent project name and add "test" to it. - // If the main project does not have a project name (yet), then the default behavior - // will be used (look for activity and then folder name) - String projectName = null; - XPathFactory factory = XPathFactory.newInstance(); - XPath xpath = factory.newXPath(); - - File testBuildXml = new File(folderPath, SdkConstants.FN_BUILD_XML); - if (testBuildXml.isFile() == false) { - File mainBuildXml = new File(resolvedPath, SdkConstants.FN_BUILD_XML); - if (mainBuildXml.isFile()) { - try { - // get the name of the main project and add Test to it. - String mainProjectName = xpath.evaluate(XPATH_PROJECT_NAME, - new InputSource(new FileInputStream(mainBuildXml))); - projectName = mainProjectName + "Test"; - } catch (XPathExpressionException e) { - // it's ok, updateProject() will figure out a name automatically. - // We do log the error though as the build.xml file may be broken. - mLog.warning("Failed to parse %1$s.\n" + - "File may not be valid. Consider running 'android update project' on the main project.", - mainBuildXml.getPath()); - } catch (FileNotFoundException e) { - // should not happen since we check first. - } - } - } - - // now update the project as if it's a normal project - if (updateProject(folderPath, target, projectName, null /*libraryPath*/) == false) { - // error message has already been displayed. - return; - } - - // add the test project specific properties. - // At this point, we know build.prop has been renamed ant.prop - ProjectProperties antProps = ProjectProperties.load(folderPath, PropertyType.ANT); - ProjectPropertiesWorkingCopy antWorkingCopy; - if (antProps == null) { - antWorkingCopy = ProjectProperties.create(folderPath, PropertyType.ANT); - } else { - antWorkingCopy = antProps.makeWorkingCopy(); - } - - // set or replace the path to the main project - antWorkingCopy.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, pathToMainProject); - try { - antWorkingCopy.save(); - println("Updated %1$s", PropertyType.ANT.getFilename()); - } catch (Exception e) { - mLog.error(e, "Failed to write %1$s file in '%2$s'", - PropertyType.ANT.getFilename(), - folderPath); - return; - } - } - - /** - * Checks whether the give <var>folderPath</var> is a valid project folder, and returns - * a {@link FileWrapper} to the required file. - * <p/>This checks that the folder exists and contains an AndroidManifest.xml file in it. - * <p/>Any error are output using {@link #mLog}. - * @param folderPath the folder to check - * @param requiredFilename the file name of the file that's required. - * @return a {@link FileWrapper} to the AndroidManifest.xml file, or null otherwise. - */ - private FileWrapper checkProjectFolder(String folderPath, String requiredFilename) { - // project folder must exist and be a directory, since this is an update - FolderWrapper projectFolder = new FolderWrapper(folderPath); - if (!projectFolder.isDirectory()) { - mLog.error(null, "Project folder '%1$s' is not a valid directory.", - projectFolder); - return null; - } - - // Check AndroidManifest.xml is present - FileWrapper requireFile = new FileWrapper(projectFolder, requiredFilename); - if (!requireFile.isFile()) { - mLog.error(null, - "%1$s is not a valid project (%2$s not found).", - folderPath, requiredFilename); - return null; - } - - return requireFile; - } - - /** - * Looks for a given regex in a file and returns the matcher if any line of the input file - * contains the requested regexp. - * - * @param file the file to search. - * @param regexp the regexp to search for. - * - * @return a Matcher or null if the regexp is not found. - */ - private Matcher checkFileContainsRegexp(File file, String regexp) { - Pattern p = Pattern.compile(regexp); - - BufferedReader in = null; - try { - in = new BufferedReader(new FileReader(file)); - String line; - - while ((line = in.readLine()) != null) { - Matcher m = p.matcher(line); - if (m.find()) { - return m; - } - } - - in.close(); - } catch (Exception e) { - // ignore - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - // ignore - } - } - } - - return null; - } - - /** - * Extracts a "full" package & activity name from an AndroidManifest.xml. - * <p/> - * The keywords dictionary is always filed the package name under the key {@link #PH_PACKAGE}. - * If an activity name can be found, it is filed under the key {@link #PH_ACTIVITY_ENTRY_NAME}. - * When no activity is found, this key is not created. - * - * @param manifestFile The AndroidManifest.xml file - * @param outKeywords Place where to put the out parameters: package and activity names. - * @return True if the package/activity was parsed and updated in the keyword dictionary. - */ - private boolean extractPackageFromManifest(File manifestFile, - Map<String, String> outKeywords) { - try { - XPath xpath = AndroidXPathFactory.newXPath(); - - InputSource source = new InputSource(new FileReader(manifestFile)); - String packageName = xpath.evaluate("/manifest/@package", source); - - source = new InputSource(new FileReader(manifestFile)); - - // Select the "android:name" attribute of all <activity> nodes but only if they - // contain a sub-node <intent-filter><action> with an "android:name" attribute which - // is 'android.intent.action.MAIN' and an <intent-filter><category> with an - // "android:name" attribute which is 'android.intent.category.LAUNCHER' - String expression = String.format("/manifest/application/activity" + - "[intent-filter/action/@%1$s:name='android.intent.action.MAIN' and " + - "intent-filter/category/@%1$s:name='android.intent.category.LAUNCHER']" + - "/@%1$s:name", AndroidXPathFactory.DEFAULT_NS_PREFIX); - - NodeList activityNames = (NodeList) xpath.evaluate(expression, source, - XPathConstants.NODESET); - - // If we get here, both XPath expressions were valid so we're most likely dealing - // with an actual AndroidManifest.xml file. The nodes may not have the requested - // attributes though, if which case we should warn. - - if (packageName == null || packageName.length() == 0) { - mLog.error(null, - "Missing <manifest package=\"...\"> in '%1$s'", - manifestFile.getName()); - return false; - } - - // Get the first activity that matched earlier. If there is no activity, - // activityName is set to an empty string and the generated "combined" name - // will be in the form "package." (with a dot at the end). - String activityName = ""; - if (activityNames.getLength() > 0) { - activityName = activityNames.item(0).getNodeValue(); - } - - if (mLevel == OutputLevel.VERBOSE && activityNames.getLength() > 1) { - println("WARNING: There is more than one activity defined in '%1$s'.\n" + - "Only the first one will be used. If this is not appropriate, you need\n" + - "to specify one of these values manually instead:", - manifestFile.getName()); - - for (int i = 0; i < activityNames.getLength(); i++) { - String name = activityNames.item(i).getNodeValue(); - name = combinePackageActivityNames(packageName, name); - println("- %1$s", name); - } - } - - if (activityName.length() == 0) { - mLog.warning("Missing <activity %1$s:name=\"...\"> in '%2$s'.\n" + - "No activity will be generated.", - AndroidXPathFactory.DEFAULT_NS_PREFIX, manifestFile.getName()); - } else { - outKeywords.put(PH_ACTIVITY_ENTRY_NAME, activityName); - } - - outKeywords.put(PH_PACKAGE, packageName); - return true; - - } catch (IOException e) { - mLog.error(e, "Failed to read %1$s", manifestFile.getName()); - } catch (XPathExpressionException e) { - Throwable t = e.getCause(); - mLog.error(t == null ? e : t, - "Failed to parse %1$s", - manifestFile.getName()); - } - - return false; - } - - private String combinePackageActivityNames(String packageName, String activityName) { - // Activity Name can have 3 forms: - // - ".Name" means this is a class name in the given package name. - // The full FQCN is thus packageName + ".Name" - // - "Name" is an older variant of the former. Full FQCN is packageName + "." + "Name" - // - "com.blah.Name" is a full FQCN. Ignore packageName and use activityName as-is. - // To be valid, the package name should have at least two components. This is checked - // later during the creation of the build.xml file, so we just need to detect there's - // a dot but not at pos==0. - - int pos = activityName.indexOf('.'); - if (pos == 0) { - return packageName + activityName; - } else if (pos > 0) { - return activityName; - } else { - return packageName + "." + activityName; - } - } - - /** - * Installs a new file that is based on a template file provided by a given target. - * Each match of each key from the place-holder map in the template will be replaced with its - * corresponding value in the created file. - * - * @param templateName the name of to the template file - * @param destFile the path to the destination file, relative to the project - * @param placeholderMap a map of (place-holder, value) to create the file from the template. - * @param target the Target of the project that will be providing the template. - * @throws ProjectCreateException - */ - private void installTargetTemplate(String templateName, File destFile, - Map<String, String> placeholderMap, IAndroidTarget target) - throws ProjectCreateException { - // query the target for its template directory - String templateFolder = target.getPath(IAndroidTarget.TEMPLATES); - final String sourcePath = templateFolder + File.separator + templateName; - - installFullPathTemplate(sourcePath, destFile, placeholderMap); - } - - /** - * Installs a new file that is based on a template file provided by the tools folder. - * Each match of each key from the place-holder map in the template will be replaced with its - * corresponding value in the created file. - * - * @param templateName the name of to the template file - * @param destFile the path to the destination file, relative to the project - * @param placeholderMap a map of (place-holder, value) to create the file from the template. - * @throws ProjectCreateException - */ - private void installTemplate(String templateName, File destFile, - Map<String, String> placeholderMap) - throws ProjectCreateException { - // query the target for its template directory - String templateFolder = mSdkFolder + File.separator + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER; - final String sourcePath = templateFolder + File.separator + templateName; - - installFullPathTemplate(sourcePath, destFile, placeholderMap); - } - - /** - * Installs a new file that is based on a template. - * Each match of each key from the place-holder map in the template will be replaced with its - * corresponding value in the created file. - * - * @param sourcePath the full path to the source template file - * @param destFile the destination file - * @param placeholderMap a map of (place-holder, value) to create the file from the template. - * @throws ProjectCreateException - */ - private void installFullPathTemplate(String sourcePath, File destFile, - Map<String, String> placeholderMap) throws ProjectCreateException { - - boolean existed = destFile.exists(); - - try { - BufferedWriter out = new BufferedWriter(new FileWriter(destFile)); - BufferedReader in = new BufferedReader(new FileReader(sourcePath)); - String line; - - while ((line = in.readLine()) != null) { - if (placeholderMap != null) { - for (Map.Entry<String, String> entry : placeholderMap.entrySet()) { - line = line.replace(entry.getKey(), entry.getValue()); - } - } - - out.write(line); - out.newLine(); - } - - out.close(); - in.close(); - } catch (Exception e) { - throw new ProjectCreateException(e, "Could not access %1$s: %2$s", - destFile, e.getMessage()); - } - - println("%1$s file %2$s", - existed ? "Updated" : "Added", - destFile); - } - - /** - * Installs the project icons. - * @param resourceFolder the resource folder - * @param target the target of the project. - * @return true if any icon was installed. - */ - private boolean installIcons(File resourceFolder, IAndroidTarget target) - throws ProjectCreateException { - // query the target for its template directory - String templateFolder = target.getPath(IAndroidTarget.TEMPLATES); - - boolean installedIcon = false; - - installedIcon |= installIcon(templateFolder, "ic_launcher_xhdpi.png", resourceFolder, - "drawable-xhdpi"); - installedIcon |= installIcon(templateFolder, "ic_launcher_hdpi.png", resourceFolder, - "drawable-hdpi"); - installedIcon |= installIcon(templateFolder, "ic_launcher_mdpi.png", resourceFolder, - "drawable-mdpi"); - installedIcon |= installIcon(templateFolder, "ic_launcher_ldpi.png", resourceFolder, - "drawable-ldpi"); - - return installedIcon; - } - - /** - * Installs an Icon in the project. - * @return true if the icon was installed. - */ - private boolean installIcon(String templateFolder, String iconName, File resourceFolder, - String folderName) throws ProjectCreateException { - File icon = new File(templateFolder, iconName); - if (icon.exists()) { - File drawable = createDirs(resourceFolder, folderName); - installBinaryFile(icon, new File(drawable, "ic_launcher.png")); - return true; - } - - return false; - } - - /** - * Installs a binary file - * @param source the source file to copy - * @param destination the destination file to write - * @throws ProjectCreateException - */ - private void installBinaryFile(File source, File destination) throws ProjectCreateException { - byte[] buffer = new byte[8192]; - - FileInputStream fis = null; - FileOutputStream fos = null; - try { - fis = new FileInputStream(source); - fos = new FileOutputStream(destination); - - int read; - while ((read = fis.read(buffer)) != -1) { - fos.write(buffer, 0, read); - } - - } catch (FileNotFoundException e) { - // shouldn't happen since we check before. - } catch (IOException e) { - throw new ProjectCreateException(e, "Failed to read binary file: %1$s", - source.getAbsolutePath()); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - // ignore - } - } - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - // ignore - } - } - } - - } - - /** - * Prints a message unless silence is enabled. - * <p/> - * This is just a convenience wrapper around {@link ILogger#info(String, Object...)} from - * {@link #mLog} after testing if output level is {@link OutputLevel#VERBOSE}. - * - * @param format Format for String.format - * @param args Arguments for String.format - */ - private void println(String format, Object... args) { - if (mLevel != OutputLevel.SILENT) { - if (!format.endsWith("\n")) { - format += "\n"; - } - mLog.info(format, args); - } - } - - /** - * Creates a new folder, along with any parent folders that do not exists. - * - * @param parent the parent folder - * @param name the name of the directory to create. - * @throws ProjectCreateException - */ - private File createDirs(File parent, String name) throws ProjectCreateException { - final File newFolder = new File(parent, name); - boolean existedBefore = true; - - if (!newFolder.exists()) { - if (!newFolder.mkdirs()) { - throw new ProjectCreateException("Could not create directory: %1$s", newFolder); - } - existedBefore = false; - } - - if (newFolder.isDirectory()) { - if (!newFolder.canWrite()) { - throw new ProjectCreateException("Path is not writable: %1$s", newFolder); - } - } else { - throw new ProjectCreateException("Path is not a directory: %1$s", newFolder); - } - - if (!existedBefore) { - try { - println("Created directory %1$s", newFolder.getCanonicalPath()); - } catch (IOException e) { - throw new ProjectCreateException( - "Could not determine canonical path of created directory", e); - } - } - - return newFolder; - } - - /** - * Strips the string of beginning and trailing characters (multiple - * characters will be stripped, example stripString("..test...", '.') - * results in "test"; - * - * @param s the string to strip - * @param strip the character to strip from beginning and end - * @return the stripped string or the empty string if everything is stripped. - */ - private static String stripString(String s, char strip) { - final int sLen = s.length(); - int newStart = 0, newEnd = sLen - 1; - - while (newStart < sLen && s.charAt(newStart) == strip) { - newStart++; - } - while (newEnd >= 0 && s.charAt(newEnd) == strip) { - newEnd--; - } - - /* - * newEnd contains a char we want, and substring takes end as being - * exclusive - */ - newEnd++; - - if (newStart >= sLen || newEnd < 0) { - return ""; - } - - return s.substring(newStart, newEnd); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java deleted file mode 100644 index 57e6190..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectProperties.java +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.project; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.io.FolderWrapper; -import com.android.io.IAbstractFile; -import com.android.io.IAbstractFolder; -import com.android.io.StreamException; -import com.android.utils.ILogger; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Class representing project properties for both ADT and Ant-based build. - * <p/>The class is associated to a {@link PropertyType} that indicate which of the project - * property file is represented. - * <p/>To load an existing file, use {@link #load(IAbstractFolder, PropertyType)}. - * <p/>The class is meant to be always in sync (or at least not newer) than the file it represents. - * Once created, it can only be updated through {@link #reload()} - * - * <p/>The make modification or make new file, use a {@link ProjectPropertiesWorkingCopy} instance, - * either through {@link #create(IAbstractFolder, PropertyType)} or through - * {@link #makeWorkingCopy()}. - * - */ -public class ProjectProperties implements IPropertySource { - protected final static Pattern PATTERN_PROP = Pattern.compile( - "^([a-zA-Z0-9._-]+)\\s*=\\s*(.*)\\s*$"); - - /** The property name for the project target */ - public final static String PROPERTY_TARGET = "target"; - - public final static String PROPERTY_LIBRARY = "android.library"; - public final static String PROPERTY_LIB_REF = "android.library.reference."; - private final static String PROPERTY_LIB_REF_REGEX = "android.library.reference.\\d+"; - - public final static String PROPERTY_PROGUARD_CONFIG = "proguard.config"; - public final static String PROPERTY_RULES_PATH = "layoutrules.jars"; - - public final static String PROPERTY_SDK = "sdk.dir"; - // LEGACY - Kept so that we can actually remove it from local.properties. - private final static String PROPERTY_SDK_LEGACY = "sdk-location"; - - public final static String PROPERTY_SPLIT_BY_DENSITY = "split.density"; - public final static String PROPERTY_SPLIT_BY_ABI = "split.abi"; - public final static String PROPERTY_SPLIT_BY_LOCALE = "split.locale"; - - public final static String PROPERTY_TESTED_PROJECT = "tested.project.dir"; - - public final static String PROPERTY_BUILD_SOURCE_DIR = "source.dir"; - public final static String PROPERTY_BUILD_OUT_DIR = "out.dir"; - - public final static String PROPERTY_PACKAGE = "package"; - public final static String PROPERTY_VERSIONCODE = "versionCode"; - public final static String PROPERTY_PROJECTS = "projects"; - public final static String PROPERTY_KEY_STORE = "key.store"; - public final static String PROPERTY_KEY_ALIAS = "key.alias"; - - public static enum PropertyType { - ANT(SdkConstants.FN_ANT_PROPERTIES, BUILD_HEADER, new String[] { - PROPERTY_BUILD_SOURCE_DIR, PROPERTY_BUILD_OUT_DIR - }, null), - PROJECT(SdkConstants.FN_PROJECT_PROPERTIES, DEFAULT_HEADER, new String[] { - PROPERTY_TARGET, PROPERTY_LIBRARY, PROPERTY_LIB_REF_REGEX, - PROPERTY_KEY_STORE, PROPERTY_KEY_ALIAS, PROPERTY_PROGUARD_CONFIG, - PROPERTY_RULES_PATH - }, null), - LOCAL(SdkConstants.FN_LOCAL_PROPERTIES, LOCAL_HEADER, new String[] { - PROPERTY_SDK - }, - new String[] { PROPERTY_SDK_LEGACY }), - @Deprecated - LEGACY_DEFAULT("default.properties", null, null, null), - @Deprecated - LEGACY_BUILD("build.properties", null, null, null); - - - private final String mFilename; - private final String mHeader; - private final Set<String> mKnownProps; - private final Set<String> mRemovedProps; - - /** - * Returns the PropertyTypes ordered the same way Ant order them. - */ - public static PropertyType[] getOrderedTypes() { - return new PropertyType[] { - PropertyType.LOCAL, PropertyType.ANT, PropertyType.PROJECT - }; - } - - PropertyType(String filename, String header, String[] validProps, String[] removedProps) { - mFilename = filename; - mHeader = header; - HashSet<String> s = new HashSet<String>(); - if (validProps != null) { - s.addAll(Arrays.asList(validProps)); - } - mKnownProps = Collections.unmodifiableSet(s); - - s = new HashSet<String>(); - if (removedProps != null) { - s.addAll(Arrays.asList(removedProps)); - } - mRemovedProps = Collections.unmodifiableSet(s); - - } - - public String getFilename() { - return mFilename; - } - - public String getHeader() { - return mHeader; - } - - /** - * Returns whether a given property is known for the property type. - */ - public boolean isKnownProperty(String name) { - for (String propRegex : mKnownProps) { - if (propRegex.equals(name) || Pattern.matches(propRegex, name)) { - return true; - } - } - - return false; - } - - /** - * Returns whether a given property should be removed for the property type. - */ - public boolean isRemovedProperty(String name) { - for (String propRegex : mRemovedProps) { - if (propRegex.equals(name) || Pattern.matches(propRegex, name)) { - return true; - } - } - - return false; - } - } - - private final static String LOCAL_HEADER = -// 1-------10--------20--------30--------40--------50--------60--------70--------80 - "# This file is automatically generated by Android Tools.\n" + - "# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" + - "#\n" + - "# This file must *NOT* be checked into Version Control Systems,\n" + - "# as it contains information specific to your local configuration.\n" + - "\n"; - - private final static String DEFAULT_HEADER = -// 1-------10--------20--------30--------40--------50--------60--------70--------80 - "# This file is automatically generated by Android Tools.\n" + - "# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" + - "#\n" + - "# This file must be checked in Version Control Systems.\n" + - "#\n" + - "# To customize properties used by the Ant build system edit\n" + - "# \"ant.properties\", and override values to adapt the script to your\n" + - "# project structure.\n" + - "#\n" + - "# To enable ProGuard to shrink and obfuscate your code, uncomment this " - + "(available properties: sdk.dir, user.home):\n" + - // Note: always use / separators in the properties paths. Both Ant and - // our ExportHelper will convert them properly according to the platform. - "#" + PROPERTY_PROGUARD_CONFIG + "=${" + PROPERTY_SDK +"}/" - + SdkConstants.FD_TOOLS + '/' + SdkConstants.FD_PROGUARD + '/' - + SdkConstants.FN_ANDROID_PROGUARD_FILE + ':' - + SdkConstants.FN_PROJECT_PROGUARD_FILE +'\n' + - "\n"; - - private final static String BUILD_HEADER = -// 1-------10--------20--------30--------40--------50--------60--------70--------80 - "# This file is used to override default values used by the Ant build system.\n" + - "#\n" + - "# This file must be checked into Version Control Systems, as it is\n" + - "# integral to the build system of your project.\n" + - "\n" + - "# This file is only used by the Ant script.\n" + - "\n" + - "# You can use this to override default values such as\n" + - "# 'source.dir' for the location of your java source folder and\n" + - "# 'out.dir' for the location of your output folder.\n" + - "\n" + - "# You can also use it define how the release builds are signed by declaring\n" + - "# the following properties:\n" + - "# 'key.store' for the location of your keystore and\n" + - "# 'key.alias' for the name of the key to use.\n" + - "# The password will be asked during the build when you use the 'release' target.\n" + - "\n"; - - protected final IAbstractFolder mProjectFolder; - protected final Map<String, String> mProperties; - protected final PropertyType mType; - - /** - * Loads a project properties file and return a {@link ProjectProperties} object - * containing the properties. - * - * @param projectFolderOsPath the project folder. - * @param type One the possible {@link PropertyType}s. - */ - public static ProjectProperties load(String projectFolderOsPath, PropertyType type) { - IAbstractFolder wrapper = new FolderWrapper(projectFolderOsPath); - return load(wrapper, type); - } - - /** - * Loads a project properties file and return a {@link ProjectProperties} object - * containing the properties. - * - * @param projectFolder the project folder. - * @param type One the possible {@link PropertyType}s. - */ - public static ProjectProperties load(IAbstractFolder projectFolder, PropertyType type) { - if (projectFolder.exists()) { - IAbstractFile propFile = projectFolder.getFile(type.mFilename); - if (propFile.exists()) { - Map<String, String> map = parsePropertyFile(propFile, null /* log */); - if (map != null) { - return new ProjectProperties(projectFolder, map, type); - } - } - } - return null; - } - - /** - * Deletes a project properties file. - * - * @param projectFolder the project folder. - * @param type One the possible {@link PropertyType}s. - * @return true if success. - */ - public static boolean delete(IAbstractFolder projectFolder, PropertyType type) { - if (projectFolder.exists()) { - IAbstractFile propFile = projectFolder.getFile(type.mFilename); - if (propFile.exists()) { - return propFile.delete(); - } - } - - return false; - } - - /** - * Deletes a project properties file. - * - * @param projectFolderOsPath the project folder. - * @param type One the possible {@link PropertyType}s. - * @return true if success. - */ - public static boolean delete(String projectFolderOsPath, PropertyType type) { - IAbstractFolder wrapper = new FolderWrapper(projectFolderOsPath); - return delete(wrapper, type); - } - - - /** - * Creates a new project properties object, with no properties. - * <p/>The file is not created until {@link ProjectPropertiesWorkingCopy#save()} is called. - * @param projectFolderOsPath the project folder. - * @param type the type of property file to create - * - * @see #createEmpty(String, PropertyType) - */ - public static ProjectPropertiesWorkingCopy create(@NonNull String projectFolderOsPath, - @NonNull PropertyType type) { - // create and return a ProjectProperties with an empty map. - IAbstractFolder folder = new FolderWrapper(projectFolderOsPath); - return create(folder, type); - } - - /** - * Creates a new project properties object, with no properties. - * <p/>The file is not created until {@link ProjectPropertiesWorkingCopy#save()} is called. - * @param projectFolder the project folder. - * @param type the type of property file to create - * - * @see #createEmpty(IAbstractFolder, PropertyType) - */ - public static ProjectPropertiesWorkingCopy create(@NonNull IAbstractFolder projectFolder, - @NonNull PropertyType type) { - // create and return a ProjectProperties with an empty map. - return new ProjectPropertiesWorkingCopy(projectFolder, new HashMap<String, String>(), type); - } - - /** - * Creates a new project properties object, with no properties. - * <p/>Nothing can be added to it, unless a {@link ProjectPropertiesWorkingCopy} is created - * first with {@link #makeWorkingCopy()}. - * @param projectFolderOsPath the project folder. - * @param type the type of property file to create - * - * @see #create(String, PropertyType) - */ - public static ProjectProperties createEmpty(@NonNull String projectFolderOsPath, - @NonNull PropertyType type) { - // create and return a ProjectProperties with an empty map. - IAbstractFolder folder = new FolderWrapper(projectFolderOsPath); - return createEmpty(folder, type); - } - - /** - * Creates a new project properties object, with no properties. - * <p/>Nothing can be added to it, unless a {@link ProjectPropertiesWorkingCopy} is created - * first with {@link #makeWorkingCopy()}. - * @param projectFolder the project folder. - * @param type the type of property file to create - * - * @see #create(IAbstractFolder, PropertyType) - */ - public static ProjectProperties createEmpty(@NonNull IAbstractFolder projectFolder, - @NonNull PropertyType type) { - // create and return a ProjectProperties with an empty map. - return new ProjectProperties(projectFolder, new HashMap<String, String>(), type); - } - - /** - * Creates and returns a copy of the current properties as a - * {@link ProjectPropertiesWorkingCopy} that can be modified and saved. - * @return a new instance of {@link ProjectPropertiesWorkingCopy} - */ - public ProjectPropertiesWorkingCopy makeWorkingCopy() { - return makeWorkingCopy(mType); - } - - /** - * Creates and returns a copy of the current properties as a - * {@link ProjectPropertiesWorkingCopy} that can be modified and saved. This also allows - * converting to a new type, by specifying a different {@link PropertyType}. - * - * @param type the {@link PropertyType} of the prop file to save. - * - * @return a new instance of {@link ProjectPropertiesWorkingCopy} - */ - public ProjectPropertiesWorkingCopy makeWorkingCopy(PropertyType type) { - // copy the current properties in a new map - Map<String, String> propList = new HashMap<String, String>(mProperties); - - return new ProjectPropertiesWorkingCopy(mProjectFolder, propList, type); - } - - /** - * Returns the type of the property file. - * - * @see PropertyType - */ - public PropertyType getType() { - return mType; - } - - /** - * Returns the value of a property. - * @param name the name of the property. - * @return the property value or null if the property is not set. - */ - @Override - public synchronized String getProperty(String name) { - return mProperties.get(name); - } - - /** - * Returns a set of the property keys. Unlike {@link Map#keySet()} this is not a view of the - * map keys. Modifying the returned {@link Set} will not impact the underlying {@link Map}. - */ - public synchronized Set<String> keySet() { - return new HashSet<String>(mProperties.keySet()); - } - - /** - * Reloads the properties from the underlying file. - */ - public synchronized void reload() { - if (mProjectFolder.exists()) { - IAbstractFile propFile = mProjectFolder.getFile(mType.mFilename); - if (propFile.exists()) { - Map<String, String> map = parsePropertyFile(propFile, null /* log */); - if (map != null) { - mProperties.clear(); - mProperties.putAll(map); - } - } - } - } - - /** - * Parses a property file (using UTF-8 encoding) and returns a map of the content. - * <p/>If the file is not present, null is returned with no error messages sent to the log. - * - * @param propFile the property file to parse - * @param log the ILogger object receiving warning/error from the parsing. - * @return the map of (key,value) pairs, or null if the parsing failed. - */ - public static Map<String, String> parsePropertyFile( - @NonNull IAbstractFile propFile, - @Nullable ILogger log) { - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(propFile.getContents(), - SdkConstants.INI_CHARSET)); - - String line = null; - Map<String, String> map = new HashMap<String, String>(); - while ((line = reader.readLine()) != null) { - line = line.trim(); - if (line.length() > 0 && line.charAt(0) != '#') { - - Matcher m = PATTERN_PROP.matcher(line); - if (m.matches()) { - map.put(m.group(1), unescape(m.group(2))); - } else { - if (log != null) { - log.warning("Error parsing '%1$s': \"%2$s\" is not a valid syntax", - propFile.getOsLocation(), - line); - } - return null; - } - } - } - - return map; - } catch (FileNotFoundException e) { - // this should not happen since we usually test the file existence before - // calling the method. - // Return null below. - } catch (IOException e) { - if (log != null) { - log.warning("Error parsing '%1$s': %2$s.", - propFile.getOsLocation(), - e.getMessage()); - } - } catch (StreamException e) { - if (log != null) { - log.warning("Error parsing '%1$s': %2$s.", - propFile.getOsLocation(), - e.getMessage()); - } - } finally { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - // pass - } - } - } - - return null; - } - - /** - * Private constructor. - * <p/> - * Use {@link #load(String, PropertyType)} or {@link #create(String, PropertyType)} - * to instantiate. - */ - protected ProjectProperties( - @NonNull IAbstractFolder projectFolder, - @NonNull Map<String, String> map, - @NonNull PropertyType type) { - mProjectFolder = projectFolder; - mProperties = map; - mType = type; - } - - private static String unescape(String value) { - return value.replaceAll("\\\\\\\\", "\\\\"); - } - - protected static String escape(String value) { - return value.replaceAll("\\\\", "\\\\\\\\"); - } - - @Override - public void debugPrint() { - System.out.println("DEBUG PROJECTPROPERTIES: " + mProjectFolder); - System.out.println("type: " + mType); - for (Entry<String, String> entry : mProperties.entrySet()) { - System.out.println(entry.getKey() + " -> " + entry.getValue()); - } - System.out.println("<<< DEBUG PROJECTPROPERTIES"); - - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectPropertiesWorkingCopy.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectPropertiesWorkingCopy.java deleted file mode 100644 index 21dcc36..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectPropertiesWorkingCopy.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.project; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.io.IAbstractFile; -import com.android.io.IAbstractFolder; -import com.android.io.StreamException; - -import java.io.BufferedReader; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.regex.Matcher; - -/** - * A modifyable and saveable copy of a {@link ProjectProperties}. - * <p/>This copy gives access to modification method such as {@link #setProperty(String, String)} - * and {@link #removeProperty(String)}. - * - * To get access to an instance, use {@link ProjectProperties#makeWorkingCopy()} or - * {@link ProjectProperties#create(IAbstractFolder, PropertyType)}. - */ -public class ProjectPropertiesWorkingCopy extends ProjectProperties { - - private final static Map<String, String> COMMENT_MAP = new HashMap<String, String>(); - static { -// 1-------10--------20--------30--------40--------50--------60--------70--------80 - COMMENT_MAP.put(PROPERTY_TARGET, - "# Project target.\n"); - COMMENT_MAP.put(PROPERTY_SPLIT_BY_DENSITY, - "# Indicates whether an apk should be generated for each density.\n"); - COMMENT_MAP.put(PROPERTY_SDK, - "# location of the SDK. This is only used by Ant\n" + - "# For customization when using a Version Control System, please read the\n" + - "# header note.\n"); - COMMENT_MAP.put(PROPERTY_PACKAGE, - "# Package of the application being exported\n"); - COMMENT_MAP.put(PROPERTY_VERSIONCODE, - "# Major version code\n"); - COMMENT_MAP.put(PROPERTY_PROJECTS, - "# List of the Android projects being used for the export.\n" + - "# The list is made of paths that are relative to this project,\n" + - "# using forward-slash (/) as separator, and are separated by colons (:).\n"); - } - - - /** - * Sets a new properties. If a property with the same name already exists, it is replaced. - * @param name the name of the property. - * @param value the value of the property. - */ - public synchronized void setProperty(String name, String value) { - mProperties.put(name, value); - } - - /** - * Removes a property and returns its previous value (or null if the property did not exist). - * @param name the name of the property to remove. - */ - public synchronized String removeProperty(String name) { - return mProperties.remove(name); - } - - /** - * Merges all properties from the given file into the current properties. - * <p/> - * This emulates the Ant behavior: existing properties are <em>not</em> overridden. - * Only new undefined properties become defined. - * <p/> - * Typical usage: - * <ul> - * <li>Create a ProjectProperties with {@code PropertyType#ANT} - * <li>Merge in values using {@code PropertyType#PROJECT} - * <li>The result is that this contains all the properties from default plus those - * overridden by the build.properties file. - * </ul> - * - * @param type One the possible {@link ProjectProperties.PropertyType}s. - * @return this object, for chaining. - */ - public synchronized ProjectPropertiesWorkingCopy merge(PropertyType type) { - if (mProjectFolder.exists() && mType != type) { - IAbstractFile propFile = mProjectFolder.getFile(type.getFilename()); - if (propFile.exists()) { - Map<String, String> map = parsePropertyFile(propFile, null /* log */); - if (map != null) { - for (Entry<String, String> entry : map.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - if (!mProperties.containsKey(key) && value != null) { - mProperties.put(key, value); - } - } - } - } - } - return this; - } - - - /** - * Saves the property file, using UTF-8 encoding. - * @throws IOException - * @throws StreamException - */ - public synchronized void save() throws IOException, StreamException { - IAbstractFile toSave = mProjectFolder.getFile(mType.getFilename()); - - // write the whole file in a byte array before dumping it in the file. This - // This is so that if the file already existing - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - OutputStreamWriter writer = new OutputStreamWriter(baos, SdkConstants.INI_CHARSET); - - if (toSave.exists()) { - BufferedReader reader = new BufferedReader(new InputStreamReader(toSave.getContents(), - SdkConstants.INI_CHARSET)); - - // since we're reading the existing file and replacing values with new ones, or skipping - // removed values, we need to record what properties have been visited, so that - // we can figure later what new properties need to be added at the end of the file. - HashSet<String> visitedProps = new HashSet<String>(); - - String line = null; - while ((line = reader.readLine()) != null) { - // check if this is a line containing a property. - if (line.length() > 0 && line.charAt(0) != '#') { - - Matcher m = PATTERN_PROP.matcher(line); - if (m.matches()) { - String key = m.group(1); - String value = m.group(2); - - // record the prop - visitedProps.add(key); - - // check if this property must be removed. - if (mType.isRemovedProperty(key)) { - value = null; - } else if (mProperties.containsKey(key)) { // if the property still exists. - // put the new value. - value = mProperties.get(key); - } else { - // property doesn't exist. Check if it's a known property. - // if it's a known one, we'll remove it, otherwise, leave it untouched. - if (mType.isKnownProperty(key)) { - value = null; - } - } - - // if the value is still valid, write it down. - if (value != null) { - writeValue(writer, key, value, false /*addComment*/); - } - } else { - // the line was wrong, let's just ignore it so that it's removed from the - // file. - } - } else { - // non-property line: just write the line in the output as-is. - writer.append(line).append('\n'); - } - } - - // now add the new properties. - for (Entry<String, String> entry : mProperties.entrySet()) { - if (visitedProps.contains(entry.getKey()) == false) { - String value = entry.getValue(); - if (value != null) { - writeValue(writer, entry.getKey(), value, true /*addComment*/); - } - } - } - - } else { - // new file, just write it all - - // write the header (can be null, for example for PropertyType.LEGACY_BUILD) - if (mType.getHeader() != null) { - writer.write(mType.getHeader()); - } - - // write the properties. - for (Entry<String, String> entry : mProperties.entrySet()) { - String value = entry.getValue(); - if (value != null) { - writeValue(writer, entry.getKey(), value, true /*addComment*/); - } - } - } - - writer.flush(); - - // now put the content in the file. - OutputStream filestream = toSave.getOutputStream(); - filestream.write(baos.toByteArray()); - filestream.flush(); - } - - private void writeValue(OutputStreamWriter writer, String key, String value, - boolean addComment) throws IOException { - if (addComment) { - String comment = COMMENT_MAP.get(key); - if (comment != null) { - writer.write(comment); - } - } - - writer.write(String.format("%s=%s\n", key, escape(value))); - } - - /** - * Private constructor. - * <p/> - * Use {@link #load(String, PropertyType)} or {@link #create(String, PropertyType)} - * to instantiate. - */ - ProjectPropertiesWorkingCopy(IAbstractFolder projectFolder, Map<String, String> map, - PropertyType type) { - super(projectFolder, map, type); - } - - @NonNull - public ProjectProperties makeReadOnlyCopy() { - // copy the current properties in a new map - Map<String, String> propList = new HashMap<String, String>(mProperties); - - return new ProjectProperties(mProjectFolder, propList, mType); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AdbWrapper.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AdbWrapper.java deleted file mode 100755 index 8d4a0c2..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AdbWrapper.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.SdkConstants; - -import java.io.File; -import java.io.IOException; - -/** - * A lightweight wrapper to start & stop ADB. - * This is <b>specific</b> to the SDK Manager install process. - */ -public class AdbWrapper { - - /* - * Note: we could bring ddmlib in SdkManager for that purpose, however this allows us to - * specialize the start/stop methods to our needs (e.g. a task monitor, etc.) - */ - - private final String mAdbOsLocation; - private final ITaskMonitor mMonitor; - - /** - * Creates a new lightweight ADB wrapper. - * - * @param osSdkPath The root OS path of the SDK. Cannot be null. - * @param monitor A logger object. Cannot be null. - */ - public AdbWrapper(String osSdkPath, ITaskMonitor monitor) { - mMonitor = monitor; - - if (!osSdkPath.endsWith(File.separator)) { - osSdkPath += File.separator; - } - mAdbOsLocation = osSdkPath + SdkConstants.OS_SDK_PLATFORM_TOOLS_FOLDER - + SdkConstants.FN_ADB; - } - - private void display(String format, Object...args) { - mMonitor.log(format, args); - } - - private void displayError(String format, Object...args) { - mMonitor.logError(format, args); - } - - /** - * Starts the adb host side server. - * @return true if success - */ - public synchronized boolean startAdb() { - if (mAdbOsLocation == null) { - displayError("Error: missing path to ADB."); //$NON-NLS-1$ - return false; - } - - Process proc; - int status = -1; - - try { - ProcessBuilder processBuilder = new ProcessBuilder( - mAdbOsLocation, - "start-server"); //$NON-NLS-1$ - proc = processBuilder.start(); - status = proc.waitFor(); - - // Implementation note: normally on Windows we need to capture stderr/stdout - // to make sure the process isn't blocked if it's output isn't read. However - // in this case this happens to hang when reading stdout with no proper way - // to properly close the streams. On the other hand the output from start - // server is rather short and not very interesting so we just drop it. - - } catch (IOException ioe) { - displayError("Unable to run 'adb': %1$s.", ioe.getMessage()); //$NON-NLS-1$ - // we'll return false; - } catch (InterruptedException ie) { - displayError("Unable to run 'adb': %1$s.", ie.getMessage()); //$NON-NLS-1$ - // we'll return false; - } - - if (status != 0) { - displayError(String.format( - "Starting ADB server failed (code %d).", //$NON-NLS-1$ - status)); - return false; - } - - display("Starting ADB server succeeded."); //$NON-NLS-1$ - - return true; - } - - /** - * Stops the adb host side server. - * @return true if success - */ - public synchronized boolean stopAdb() { - if (mAdbOsLocation == null) { - displayError("Error: missing path to ADB."); //$NON-NLS-1$ - return false; - } - - Process proc; - int status = -1; - - try { - String[] command = new String[2]; - command[0] = mAdbOsLocation; - command[1] = "kill-server"; //$NON-NLS-1$ - proc = Runtime.getRuntime().exec(command); - status = proc.waitFor(); - - // See comment in startAdb about not needing/wanting to capture stderr/stdout. - } - catch (IOException ioe) { - // we'll return false; - } - catch (InterruptedException ie) { - // we'll return false; - } - - // adb kill-server returns: - // 0 if adb was running and was correctly killed. - // 1 if adb wasn't running and thus wasn't killed. - // This error case is not worth reporting. - - if (status != 0 && status != 1) { - displayError(String.format( - "Stopping ADB server failed (code %d).", //$NON-NLS-1$ - status)); - return false; - } - - display("Stopping ADB server succeeded."); //$NON-NLS-1$ - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java deleted file mode 100755 index ac7b5d0..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/AddonsListFetcher.java +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.io.NonClosingInputStream; -import com.android.sdklib.io.NonClosingInputStream.CloseBehavior; -import com.android.sdklib.repository.SdkAddonsListConstants; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.SSLKeyException; -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -/** - * Fetches and loads an sdk-addons-list XML. - * <p/> - * Such an XML contains a simple list of add-ons site that are to be loaded by default by the - * SDK Manager. <br/> - * The XML must conform to the sdk-addons-list-N.xsd. <br/> - * Constants used in the XML are defined in {@link SdkAddonsListConstants}. - */ -public class AddonsListFetcher { - - public enum SiteType { - ADDON_SITE, - SYS_IMG_SITE - } - - /** - * An immutable structure representing an add-on site. - */ - public static class Site { - private final String mUrl; - private final String mUiName; - private final SiteType mType; - - private Site(String url, String uiName, SiteType type) { - mType = type; - mUrl = url.trim(); - mUiName = uiName; - } - - public String getUrl() { - return mUrl; - } - - public String getUiName() { - return mUiName; - } - - public SiteType getType() { - return mType; - } - - /** Returns a debug string representation of this object. Not for user display. */ - @Override - public String toString() { - return String.format("<%1$s URL='%2$s' Name='%3$s'>", //$NON-NLS-1$ - mType, mUrl, mUiName); - } - } - - /** - * Fetches the addons list from the given URL. - * - * @param url The URL of an XML file resource that conforms to the latest sdk-addons-list-N.xsd. - * For the default operation, use {@link SdkAddonsListConstants#URL_ADDON_LIST}. - * Cannot be null. - * @param cache The {@link DownloadCache} instance to use. Cannot be null. - * @param monitor A monitor to report errors. Cannot be null. - * @return An array of {@link Site} on success (possibly empty), or null on error. - */ - public Site[] fetch(String url, DownloadCache cache, ITaskMonitor monitor) { - - url = url == null ? "" : url.trim(); - - monitor.setProgressMax(6); - monitor.setDescription("Fetching %1$s", url); - monitor.incProgress(1); - - Exception[] exception = new Exception[] { null }; - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - Document validatedDoc = null; - String validatedUri = null; - - String[] defaultNames = new String[SdkAddonsListConstants.NS_LATEST_VERSION]; - for (int version = SdkAddonsListConstants.NS_LATEST_VERSION, i = 0; - version >= 1; - version--, i++) { - defaultNames[i] = SdkAddonsListConstants.getDefaultName(version); - } - - InputStream xml = fetchXmlUrl(url, cache, monitor.createSubMonitor(1), exception); - if (xml != null) { - int version = getXmlSchemaVersion(xml); - if (version == 0) { - closeStream(xml); - xml = null; - } - } - - String baseUrl = url; - if (!baseUrl.endsWith("/")) { //$NON-NLS-1$ - int pos = baseUrl.lastIndexOf('/'); - if (pos > 0) { - baseUrl = baseUrl.substring(0, pos + 1); - } - } - - // If we can't find the latest version, try earlier schema versions. - if (xml == null && defaultNames.length > 0) { - ITaskMonitor subMonitor = monitor.createSubMonitor(1); - subMonitor.setProgressMax(defaultNames.length); - - for (String name : defaultNames) { - String newUrl = baseUrl + name; - if (newUrl.equals(url)) { - continue; - } - xml = fetchXmlUrl(newUrl, cache, subMonitor.createSubMonitor(1), exception); - if (xml != null) { - int version = getXmlSchemaVersion(xml); - if (version == 0) { - closeStream(xml); - xml = null; - } else { - url = newUrl; - subMonitor.incProgress( - subMonitor.getProgressMax() - subMonitor.getProgress()); - break; - } - } - } - } else { - monitor.incProgress(1); - } - - if (xml != null) { - monitor.setDescription("Validate XML"); - - // Explore the XML to find the potential XML schema version - int version = getXmlSchemaVersion(xml); - - if (version >= 1 && version <= SdkAddonsListConstants.NS_LATEST_VERSION) { - // This should be a version we can handle. Try to validate it - // and report any error as invalid XML syntax, - - String uri = validateXml(xml, url, version, validationError, validatorFound); - if (uri != null) { - // Validation was successful - validatedDoc = getDocument(xml, monitor); - validatedUri = uri; - - } - } else if (version > SdkAddonsListConstants.NS_LATEST_VERSION) { - // The schema used is more recent than what is supported by this tool. - // We don't have an upgrade-path support yet, so simply ignore the document. - closeStream(xml); - return null; - } - } - - // If any exception was handled during the URL fetch, display it now. - if (exception[0] != null) { - String reason = null; - if (exception[0] instanceof FileNotFoundException) { - // FNF has no useful getMessage, so we need to special handle it. - reason = "File not found"; - } else if (exception[0] instanceof UnknownHostException && - exception[0].getMessage() != null) { - // This has no useful getMessage yet could really use one - reason = String.format("Unknown Host %1$s", exception[0].getMessage()); - } else if (exception[0] instanceof SSLKeyException) { - // That's a common error and we have a pref for it. - reason = "HTTPS SSL error. You might want to force download through HTTP in the settings."; - } else if (exception[0].getMessage() != null) { - reason = exception[0].getMessage(); - } else { - // We don't know what's wrong. Let's give the exception class at least. - reason = String.format("Unknown (%1$s)", exception[0].getClass().getName()); - } - - monitor.logError("Failed to fetch URL %1$s, reason: %2$s", url, reason); - } - - if (validationError[0] != null) { - monitor.logError("%s", validationError[0]); //$NON-NLS-1$ - } - - // Stop here if we failed to validate the XML. We don't want to load it. - if (validatedDoc == null) { - closeStream(xml); - return null; - } - - monitor.incProgress(1); - - Site[] result = null; - - if (xml != null) { - monitor.setDescription("Parse XML"); - monitor.incProgress(1); - result = parseAddonsList(validatedDoc, validatedUri, baseUrl, monitor); - } - - // done - monitor.incProgress(1); - - closeStream(xml); - return result; - } - - /** - * Fetches the document at the given URL and returns it as a stream. Returns - * null if anything wrong happens. - * - * @param urlString The URL to load, as a string. - * @param monitor {@link ITaskMonitor} related to this URL. - * @param outException If non null, where to store any exception that - * happens during the fetch. - * @see UrlOpener UrlOpener, which handles all URL logic. - */ - private InputStream fetchXmlUrl(String urlString, - DownloadCache cache, - ITaskMonitor monitor, - Exception[] outException) { - try { - InputStream xml = cache.openCachedUrl(urlString, monitor); - if (xml != null) { - xml.mark(500000); - xml = new NonClosingInputStream(xml); - ((NonClosingInputStream) xml).setCloseBehavior(CloseBehavior.RESET); - } - return xml; - } catch (Exception e) { - if (outException != null) { - outException[0] = e; - } - } - - return null; - } - - /** - * Closes the stream, ignore any exception from InputStream.close(). - * If the stream is a NonClosingInputStream, sets it to CloseBehavior.CLOSE first. - */ - private void closeStream(InputStream is) { - if (is != null) { - if (is instanceof NonClosingInputStream) { - ((NonClosingInputStream) is).setCloseBehavior(CloseBehavior.CLOSE); - } - try { - is.close(); - } catch (IOException ignore) {} - } - } - - /** - * Manually parses the root element of the XML to extract the schema version - * at the end of the xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/$N" - * declaration. - * - * @return 1..{@link SdkAddonsListConstants#NS_LATEST_VERSION} for a valid schema version - * or 0 if no schema could be found. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected int getXmlSchemaVersion(InputStream xml) { - if (xml == null) { - return 0; - } - - // Get an XML document - Document doc = null; - try { - assert xml.markSupported(); - xml.reset(); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(false); - factory.setValidating(false); - - // Parse the old document using a non namespace aware builder - factory.setNamespaceAware(false); - DocumentBuilder builder = factory.newDocumentBuilder(); - - // We don't want the default handler which prints errors to stderr. - builder.setErrorHandler(new ErrorHandler() { - @Override - public void warning(SAXParseException e) throws SAXException { - // pass - } - @Override - public void fatalError(SAXParseException e) throws SAXException { - throw e; - } - @Override - public void error(SAXParseException e) throws SAXException { - throw e; - } - }); - - doc = builder.parse(xml); - - // Prepare a new document using a namespace aware builder - factory.setNamespaceAware(true); - builder = factory.newDocumentBuilder(); - - } catch (Exception e) { - // Failed to reset XML stream - // Failed to get builder factor - // Failed to create XML document builder - // Failed to parse XML document - // Failed to read XML document - //--For debug--System.err.println("getXmlSchemaVersion exception: " + e.toString()); - } - - if (doc == null) { - return 0; - } - - // Check the root element is an XML with at least the following properties: - // <sdk:sdk-addons-list - // xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/$N"> - // - // Note that we don't have namespace support enabled, we just do it manually. - - Pattern nsPattern = Pattern.compile(SdkAddonsListConstants.NS_PATTERN); - - String prefix = null; - for (Node child = doc.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - prefix = null; - String name = child.getNodeName(); - int pos = name.indexOf(':'); - if (pos > 0 && pos < name.length() - 1) { - prefix = name.substring(0, pos); - name = name.substring(pos + 1); - } - if (SdkAddonsListConstants.NODE_SDK_ADDONS_LIST.equals(name)) { - NamedNodeMap attrs = child.getAttributes(); - String xmlns = "xmlns"; //$NON-NLS-1$ - if (prefix != null) { - xmlns += ":" + prefix; //$NON-NLS-1$ - } - Node attr = attrs.getNamedItem(xmlns); - if (attr != null) { - String uri = attr.getNodeValue(); - if (uri != null) { - Matcher m = nsPattern.matcher(uri); - if (m.matches()) { - String version = m.group(1); - try { - return Integer.parseInt(version); - } catch (NumberFormatException e) { - return 0; - } - } - } - } - } - } - } - - return 0; - } - - /** - * Validates this XML against one of the requested SDK Repository schemas. - * If the XML was correctly validated, returns the schema that worked. - * If it doesn't validate, returns null and stores the error in outError[0]. - * If we can't find a validator, returns null and set validatorFound[0] to false. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected String validateXml(InputStream xml, String url, int version, - String[] outError, Boolean[] validatorFound) { - - if (xml == null) { - return null; - } - - try { - Validator validator = getValidator(version); - - if (validator == null) { - validatorFound[0] = Boolean.FALSE; - outError[0] = String.format( - "XML verification failed for %1$s.\nNo suitable XML Schema Validator could be found in your Java environment. Please consider updating your version of Java.", - url); - return null; - } - - validatorFound[0] = Boolean.TRUE; - - // Reset the stream if it supports that operation. - assert xml.markSupported(); - xml.reset(); - - // Validation throws a bunch of possible Exceptions on failure. - validator.validate(new StreamSource(xml)); - return SdkAddonsListConstants.getSchemaUri(version); - - } catch (SAXParseException e) { - outError[0] = String.format( - "XML verification failed for %1$s.\nLine %2$d:%3$d, Error: %4$s", - url, - e.getLineNumber(), - e.getColumnNumber(), - e.toString()); - - } catch (Exception e) { - outError[0] = String.format( - "XML verification failed for %1$s.\nError: %2$s", - url, - e.toString()); - } - return null; - } - - /** - * Helper method that returns a validator for our XSD, or null if the current Java - * implementation can't process XSD schemas. - * - * @param version The version of the XML Schema. - * See {@link SdkAddonsListConstants#getXsdStream(int)} - */ - private Validator getValidator(int version) throws SAXException { - InputStream xsdStream = SdkAddonsListConstants.getXsdStream(version); - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - - if (factory == null) { - return null; - } - - // This may throw a SAX Exception if the schema itself is not a valid XSD - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - - Validator validator = schema == null ? null : schema.newValidator(); - - return validator; - } - - /** - * Takes an XML document as a string as parameter and returns a DOM for it. - * - * On error, returns null and prints a (hopefully) useful message on the monitor. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected Document getDocument(InputStream xml, ITaskMonitor monitor) { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(true); - factory.setNamespaceAware(true); - - DocumentBuilder builder = factory.newDocumentBuilder(); - assert xml.markSupported(); - xml.reset(); - Document doc = builder.parse(new InputSource(xml)); - - return doc; - } catch (ParserConfigurationException e) { - monitor.logError("Failed to create XML document builder"); - - } catch (SAXException e) { - monitor.logError("Failed to parse XML document"); - - } catch (IOException e) { - monitor.logError("Failed to read XML document"); - } - - return null; - } - - /** - * Parse all sites defined in the Addaons list XML and returns an array of sites. - * - * @param doc The XML DOM to parse. - * @param nsUri The addons-list schema URI of the document. - * @param baseUrl The base URL of the caller (e.g. where addons-list-N.xml was fetched from.) - * @param monitor A non-null monitor to print to. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected Site[] parseAddonsList( - Document doc, - String nsUri, - String baseUrl, - ITaskMonitor monitor) { - - String testBaseUrl = System.getenv("SDK_TEST_BASE_URL"); //$NON-NLS-1$ - if (testBaseUrl != null) { - if (testBaseUrl.length() <= 0 || !testBaseUrl.endsWith("/")) { //$NON-NLS-1$ - testBaseUrl = null; - } - } - - Node root = getFirstChild(doc, nsUri, SdkAddonsListConstants.NODE_SDK_ADDONS_LIST); - if (root != null) { - ArrayList<Site> sites = new ArrayList<Site>(); - - for (Node child = root.getFirstChild(); - child != null; - child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI())) { - - String elementName = child.getLocalName(); - SiteType type = null; - - if (SdkAddonsListConstants.NODE_SYS_IMG_SITE.equals(elementName)) { - type = SiteType.SYS_IMG_SITE; - - } else if (SdkAddonsListConstants.NODE_ADDON_SITE.equals(elementName)) { - type = SiteType.ADDON_SITE; - } - - // Not an addon-site nor a sys-img-site, don't process this. - if (type == null) { - continue; - } - - Node url = getFirstChild(child, nsUri, SdkAddonsListConstants.NODE_URL); - Node name = getFirstChild(child, nsUri, SdkAddonsListConstants.NODE_NAME); - - if (name != null && url != null) { - String strUrl = url.getTextContent().trim(); - String strName = name.getTextContent().trim(); - - if (testBaseUrl != null && - strUrl.startsWith(SdkRepoConstants.URL_GOOGLE_SDK_SITE)) { - strUrl = testBaseUrl + - strUrl.substring(SdkRepoConstants.URL_GOOGLE_SDK_SITE.length()); - } else if (!strUrl.startsWith("http://") && //$NON-NLS-1$ - !strUrl.startsWith("https://")) { //$NON-NLS-1$ - // This looks like a relative URL, add the fetcher's base URL to it. - strUrl = baseUrl + strUrl; - } - - if (strUrl.length() > 0 && strName.length() > 0) { - sites.add(new Site(strUrl, strName, type)); - } - } - } - } - - return sites.toArray(new Site[sites.size()]); - } - - return null; - } - - /** - * Returns the first child element with the given XML local name. - * If xmlLocalName is null, returns the very first child element. - */ - private Node getFirstChild(Node node, String nsUri, String xmlLocalName) { - - for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI())) { - if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) { - return child; - } - } - } - - return null; - } - - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/CanceledByUserException.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/CanceledByUserException.java deleted file mode 100755 index a0a74d8..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/CanceledByUserException.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -/** - * Exception thrown by {@link DownloadCache} and {@link UrlOpener} when a user - * cancels an HTTP Basic authentication or NTML authentication dialog. - */ -public class CanceledByUserException extends Exception { - private static final long serialVersionUID = -7669346110926032403L; - - public CanceledByUserException(String message) { - super(message); - } -} - diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DownloadCache.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DownloadCache.java deleted file mode 100755 index e02023d..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/DownloadCache.java +++ /dev/null @@ -1,830 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.utils.Pair; - -import org.apache.http.Header; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.message.BasicHeader; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicInteger; - - -/** - * A simple cache for the XML resources handled by the SDK Manager. - * <p/> - * Callers should use {@link #openDirectUrl} to download "large files" - * that should not be cached (like actual installation packages which are several MBs big) - * and call {@link #openCachedUrl(String, ITaskMonitor)} to download small XML files. - * <p/> - * The cache can work in 3 different strategies (direct is a pass-through, fresh-cache is the - * default and tries to update resources if they are older than 10 minutes by respecting - * either ETag or Last-Modified, and finally server-cache is a strategy to always serve - * cached entries if present.) - */ -public class DownloadCache { - - /* - * HTTP/1.1 references: - * - Possible headers: - * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - * - Rules about conditional requests: - * http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 - * - Error codes: - * http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 - */ - - private static final boolean DEBUG = System.getenv("SDKMAN_DEBUG_CACHE") != null; //$NON-NLS-1$ - - /** Key for the Status-Code in the info properties. */ - private static final String KEY_STATUS_CODE = "Status-Code"; //$NON-NLS-1$ - /** Key for the URL in the info properties. */ - private static final String KEY_URL = "URL"; //$NON-NLS-1$ - - /** Prefix of binary files stored in the {@link SdkConstants#FD_CACHE} directory. */ - private final static String BIN_FILE_PREFIX = "sdkbin"; //$NON-NLS-1$ - /** Prefix of meta info files stored in the {@link SdkConstants#FD_CACHE} directory. */ - private final static String INFO_FILE_PREFIX = "sdkinf"; //$NON-NLS-1$ - /* Revision suffixed to the prefix. */ - private final static String REV_FILE_PREFIX = "-1_"; //$NON-NLS-1$ - - /** - * Minimum time before we consider a cached entry is potentially stale. - * Expressed in milliseconds. - * <p/> - * When using the {@link Strategy#FRESH_CACHE}, the cache will not try to refresh - * a cached file if it's has been saved more recently than this time. - * When using the direct mode or the serve mode, the cache either doesn't serve - * cached files or always serves caches files so this expiration delay is not used. - * <p/> - * Default is 10 minutes. - * <p/> - * TODO: change for a dynamic preference later. - */ - private final static long MIN_TIME_EXPIRED_MS = 10*60*1000; - /** - * Maximum time before we consider a cache entry to be stale. - * Expressed in milliseconds. - * <p/> - * When using the {@link Strategy#FRESH_CACHE}, entries that have no ETag - * or Last-Modified will be refreshed if their file timestamp is older than - * this value. - * <p/> - * Default is 4 hours. - * <p/> - * TODO: change for a dynamic preference later. - */ - private final static long MAX_TIME_EXPIRED_MS = 4*60*60*1000; - - /** - * The maximum file size we'll cache for "small" files. - * 640KB is more than enough and is already a stretch since these are read in memory. - * (The actual typical size of the files handled here is in the 4-64KB range.) - */ - private final static int MAX_SMALL_FILE_SIZE = 640 * 1024; - - /** - * HTTP Headers that are saved in an info file. - * For HTTP/1.1 header names, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html - */ - private final static String[] INFO_HTTP_HEADERS = { - HttpHeaders.LAST_MODIFIED, - HttpHeaders.ETAG, - HttpHeaders.CONTENT_LENGTH, - HttpHeaders.DATE - }; - - private final Strategy mStrategy; - private final File mCacheRoot; - - public enum Strategy { - /** - * Exclusively serves data from the cache. If files are available in the - * cache, serve them as is (without trying to refresh them). If files are - * not available, they are <em>not</em> fetched at all. - */ - ONLY_CACHE, - /** - * If the files are available in the cache, serve them as-is, otherwise - * download them and return the cached version. No expiration or refresh - * is attempted if a file is in the cache. - */ - SERVE_CACHE, - /** - * If the files are available in the cache, check if there's an update - * (either using an e-tag check or comparing to the default time expiration). - * If files have expired or are not in the cache then download them and return - * the cached version. - */ - FRESH_CACHE, - /** - * Disables caching. URLs are always downloaded and returned directly. - * Downloaded streams aren't cached locally. - */ - DIRECT - } - - /** Creates a default instance of the URL cache */ - public DownloadCache(Strategy strategy) { - mCacheRoot = initCacheRoot(); - - // If this is defined in the environment, never use the cache. Useful for testing. - if (System.getenv("SDKMAN_DISABLE_CACHE") != null) { //$NON-NLS-1$ - strategy = Strategy.DIRECT; - } - - mStrategy = mCacheRoot == null ? Strategy.DIRECT : strategy; - } - - public Strategy getStrategy() { - return mStrategy; - } - - public File getCacheRoot() { - return mCacheRoot; - } - - /** - * Computes the size of the cached files. - * - * @return The sum of the byte size of the cached files. - */ - public long getCurrentSize() { - long size = 0; - - if (mCacheRoot != null) { - File[] files = mCacheRoot.listFiles(); - if (files != null) { - for (File f : files) { - if (f.isFile()) { - String name = f.getName(); - if (name.startsWith(BIN_FILE_PREFIX) || - name.startsWith(INFO_FILE_PREFIX)) { - size += f.length(); - } - } - } - } - } - - return size; - } - - /** - * Removes all cached files from the cache directory. - */ - public void clearCache() { - if (mCacheRoot != null) { - File[] files = mCacheRoot.listFiles(); - if (files != null) { - for (File f : files) { - if (f.isFile()) { - String name = f.getName(); - if (name.startsWith(BIN_FILE_PREFIX) || - name.startsWith(INFO_FILE_PREFIX)) { - f.delete(); - } - } - } - } - } - } - - /** - * Removes all obsolete cached files from the cache directory - * that do not match the latest revision. - */ - public void clearOldCache() { - String prefix1 = BIN_FILE_PREFIX + REV_FILE_PREFIX; - String prefix2 = INFO_FILE_PREFIX + REV_FILE_PREFIX; - if (mCacheRoot != null) { - File[] files = mCacheRoot.listFiles(); - if (files != null) { - for (File f : files) { - if (f.isFile()) { - String name = f.getName(); - if (name.startsWith(BIN_FILE_PREFIX) || - name.startsWith(INFO_FILE_PREFIX)) { - if (!name.startsWith(prefix1) && !name.startsWith(prefix2)) { - f.delete(); - } - } - } - } - } - } - } - - /** - * Returns the directory to be used as a cache. - * Creates it if necessary. - * Makes it possible to disable or override the cache location in unit tests. - * - * @return An existing directory to use as a cache root dir, - * or null in case of error in which case the cache will be disabled. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected File initCacheRoot() { - try { - File root = new File(AndroidLocation.getFolder()); - root = new File(root, SdkConstants.FD_CACHE); - if (!root.exists()) { - root.mkdirs(); - } - return root; - } catch (AndroidLocationException e) { - // No root? Disable the cache. - return null; - } - } - - /** - * Does a direct download of the given URL using {@link UrlOpener}. - * This does not check the download cache and does not attempt to cache the file. - * Instead the HttpClient library returns a progressive download stream. - * <p/> - * For details on realm authentication and user/password handling, - * check the underlying {@link UrlOpener#openUrl(String, boolean, ITaskMonitor, Header[])} - * documentation. - * <p/> - * The resulting input stream may not support mark/reset. - * - * @param urlString the URL string to be opened. - * @param headers An optional set of headers to pass when requesting the resource. Can be null. - * @param monitor {@link ITaskMonitor} which is related to this URL - * fetching. - * @return Returns a pair with a {@link InputStream} and an {@link HttpResponse}. - * The pair is never null. - * The input stream can be null in case of error, although in general the - * method will probably throw an exception instead. - * The caller should look at the response code's status and only accept the - * input stream if it's the desired code (e.g. 200 or 206). - * @throws IOException Exception thrown when there are problems retrieving - * the URL or its content. - * @throws CanceledByUserException Exception thrown if the user cancels the - * authentication dialog. - */ - public Pair<InputStream, HttpResponse> openDirectUrl( - @NonNull String urlString, - @Nullable Header[] headers, - @NonNull ITaskMonitor monitor) - throws IOException, CanceledByUserException { - if (DEBUG) { - System.out.println(String.format("%s : Direct download", urlString)); //$NON-NLS-1$ - } - return UrlOpener.openUrl( - urlString, - false /*needsMarkResetSupport*/, - monitor, - headers); - } - - /** - * This is a simplified convenience method that calls - * {@link #openDirectUrl(String, Header[], ITaskMonitor)} - * without passing any specific HTTP headers and returns the resulting input stream - * and the HTTP status code. - * See the original method's description for details on its behavior. - * <p/> - * {@link #openDirectUrl(String, Header[], ITaskMonitor)} can accept customized - * HTTP headers to send with the requests and also returns the full HTTP - * response -- status line with code and protocol and all headers. - * <p/> - * The resulting input stream may not support mark/reset. - * - * @param urlString the URL string to be opened. - * @param monitor {@link ITaskMonitor} which is related to this URL - * fetching. - * @return Returns a pair with a {@link InputStream} and an HTTP status code. - * The pair is never null. - * The input stream can be null in case of error, although in general the - * method will probably throw an exception instead. - * The caller should look at the response code's status and only accept the - * input stream if it's the desired code (e.g. 200 or 206). - * @throws IOException Exception thrown when there are problems retrieving - * the URL or its content. - * @throws CanceledByUserException Exception thrown if the user cancels the - * authentication dialog. - * @see #openDirectUrl(String, Header[], ITaskMonitor) - */ - public Pair<InputStream, Integer> openDirectUrl( - @NonNull String urlString, - @NonNull ITaskMonitor monitor) - throws IOException, CanceledByUserException { - if (DEBUG) { - System.out.println(String.format("%s : Direct download", urlString)); //$NON-NLS-1$ - } - Pair<InputStream, HttpResponse> result = UrlOpener.openUrl( - urlString, - false /*needsMarkResetSupport*/, - monitor, - null /*headers*/); - return Pair.of(result.getFirst(), result.getSecond().getStatusLine().getStatusCode()); - } - - /** - * Downloads a small file, typically XML manifests. - * The current {@link Strategy} governs whether the file is served as-is - * from the cache, potentially updated first or directly downloaded. - * <p/> - * For large downloads (e.g. installable archives) please do not invoke the - * cache and instead use the {@link #openDirectUrl} method. - * <p/> - * For details on realm authentication and user/password handling, - * check the underlying {@link UrlOpener#openUrl(String, boolean, ITaskMonitor, Header[])} - * documentation. - * - * @param urlString the URL string to be opened. - * @param monitor {@link ITaskMonitor} which is related to this URL - * fetching. - * @return Returns an {@link InputStream} holding the URL content. - * Returns null if there's no content (e.g. resource not found.) - * Returns null if the document is not cached and strategy is {@link Strategy#ONLY_CACHE}. - * @throws IOException Exception thrown when there are problems retrieving - * the URL or its content. - * @throws CanceledByUserException Exception thrown if the user cancels the - * authentication dialog. - */ - public InputStream openCachedUrl(String urlString, ITaskMonitor monitor) - throws IOException, CanceledByUserException { - // Don't cache in direct mode. - if (mStrategy == Strategy.DIRECT) { - Pair<InputStream, HttpResponse> result = UrlOpener.openUrl( - urlString, - true /*needsMarkResetSupport*/, - monitor, - null /*headers*/); - return result.getFirst(); - } - - File cached = new File(mCacheRoot, getCacheFilename(urlString)); - File info = new File(mCacheRoot, getInfoFilename(cached.getName())); - - boolean useCached = cached.exists(); - - if (useCached && mStrategy == Strategy.FRESH_CACHE) { - // Check whether the file should be served from the cache or - // refreshed first. - - long cacheModifiedMs = cached.lastModified(); /* last mod time in epoch/millis */ - boolean checkCache = true; - - Properties props = readInfo(info); - if (props == null) { - // No properties, no chocolate for you. - useCached = false; - } else { - long minExpiration = System.currentTimeMillis() - MIN_TIME_EXPIRED_MS; - checkCache = cacheModifiedMs < minExpiration; - - if (!checkCache && DEBUG) { - System.out.println(String.format( - "%s : Too fresh [%,d ms], not checking yet.", //$NON-NLS-1$ - urlString, cacheModifiedMs - minExpiration)); - } - } - - if (useCached && checkCache) { - assert props != null; - - // Right now we only support 200 codes and will requery all 404s. - String code = props.getProperty(KEY_STATUS_CODE, ""); //$NON-NLS-1$ - useCached = Integer.toString(HttpStatus.SC_OK).equals(code); - - if (!useCached && DEBUG) { - System.out.println(String.format( - "%s : cache disabled by code %s", //$NON-NLS-1$ - urlString, code)); - } - - if (useCached) { - // Do we have a valid Content-Length? If so, it should match the file size. - try { - long length = Long.parseLong(props.getProperty(HttpHeaders.CONTENT_LENGTH, - "-1")); //$NON-NLS-1$ - if (length >= 0) { - useCached = length == cached.length(); - - if (!useCached && DEBUG) { - System.out.println(String.format( - "%s : cache disabled by length mismatch %d, expected %d", //$NON-NLS-1$ - urlString, length, cached.length())); - } - } - } catch (NumberFormatException ignore) {} - } - - if (useCached) { - // Do we have an ETag and/or a Last-Modified? - String etag = props.getProperty(HttpHeaders.ETAG); - String lastMod = props.getProperty(HttpHeaders.LAST_MODIFIED); - - if (etag != null || lastMod != null) { - // Details on how to use them is defined at - // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.4 - // Bottom line: - // - if there's an ETag, it should be used first with an - // If-None-Match header. That's a strong comparison for HTTP/1.1 servers. - // - otherwise use a Last-Modified if an If-Modified-Since header exists. - // In this case, we place both and the rules indicates a spec-abiding - // server should strongly match ETag and weakly the Modified-Since. - - // TODO there are some servers out there which report ETag/Last-Mod - // yet don't honor them when presented with a precondition. In this - // case we should identify it in the reply and invalidate ETag support - // for these servers and instead fallback on the pure-timeout case below. - - AtomicInteger statusCode = new AtomicInteger(0); - InputStream is = null; - List<Header> headers = new ArrayList<Header>(2); - - if (etag != null) { - headers.add(new BasicHeader(HttpHeaders.IF_NONE_MATCH, etag)); - } - - if (lastMod != null) { - headers.add(new BasicHeader(HttpHeaders.IF_MODIFIED_SINCE, lastMod)); - } - - if (!headers.isEmpty()) { - is = downloadAndCache(urlString, monitor, cached, info, - headers.toArray(new Header[headers.size()]), - statusCode); - } - - if (is != null && statusCode.get() == HttpStatus.SC_OK) { - // The resource was modified, the server said there was something - // new, which has been cached. We can return that to the caller. - return is; - } - - // If we get here, we should have is == null and code - // could be: - // - 304 for not-modified -- same resource, still available, in - // which case we'll use the cached one. - // - 404 -- resource doesn't exist anymore in which case there's - // no point in retrying. - // - For any other code, just retry a download. - - if (is != null) { - try { - is.close(); - } catch (Exception ignore) {} - is = null; - } - - if (statusCode.get() == HttpStatus.SC_NOT_MODIFIED) { - // Cached file was not modified. - // Change its timestamp for the next MIN_TIME_EXPIRED_MS check. - cached.setLastModified(System.currentTimeMillis()); - - // At this point useCached==true so we'll return - // the cached file below. - } else { - // URL fetch returned something other than 200 or 304. - // For 404, we're done, no need to check the server again. - // For all other codes, we'll retry a download below. - useCached = false; - if (statusCode.get() == HttpStatus.SC_NOT_FOUND) { - return null; - } - } - } else { - // If we don't have an Etag nor Last-Modified, let's use a - // basic file timestamp and compare to a 1 hour threshold. - - long maxExpiration = System.currentTimeMillis() - MAX_TIME_EXPIRED_MS; - useCached = cacheModifiedMs >= maxExpiration; - - if (!useCached && DEBUG) { - System.out.println(String.format( - "[%1$s] cache disabled by timestamp %2$tD %2$tT < %3$tD %3$tT", //$NON-NLS-1$ - urlString, cacheModifiedMs, maxExpiration)); - } - } - } - } - } - - if (useCached) { - // The caller needs an InputStream that supports the reset() operation. - // The default FileInputStream does not, so load the file into a byte - // array and return that. - try { - InputStream is = readCachedFile(cached); - if (is != null) { - if (DEBUG) { - System.out.println(String.format("%s : Use cached file", urlString)); //$NON-NLS-1$ - } - - return is; - } - } catch (IOException ignore) {} - } - - if (!useCached && mStrategy == Strategy.ONLY_CACHE) { - // We don't have a document to serve from the cache. - if (DEBUG) { - System.out.println(String.format("%s : file not in cache", urlString)); //$NON-NLS-1$ - } - return null; - } - - // If we're not using the cache, try to remove the cache and download again. - try { - cached.delete(); - info.delete(); - } catch (SecurityException ignore) {} - - return downloadAndCache(urlString, monitor, cached, info, - null /*headers*/, null /*statusCode*/); - } - - - - // -------------- - - private InputStream readCachedFile(File cached) throws IOException { - InputStream is = null; - - int inc = 65536; - int curr = 0; - long len = cached.length(); - assert len < Integer.MAX_VALUE; - if (len >= MAX_SMALL_FILE_SIZE) { - // This is supposed to cache small files, not 2+ GB files. - return null; - } - byte[] result = new byte[(int) (len > 0 ? len : inc)]; - - try { - is = new FileInputStream(cached); - - int n; - while ((n = is.read(result, curr, result.length - curr)) != -1) { - curr += n; - if (curr == result.length) { - byte[] temp = new byte[curr + inc]; - System.arraycopy(result, 0, temp, 0, curr); - result = temp; - } - } - - return new ByteArrayInputStream(result, 0, curr); - - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException ignore) {} - } - } - } - - /** - * Download, cache and return as an in-memory byte stream. - * The download is only done if the server returns 200/OK. - * On success, store an info file next to the download with - * a few headers. - * <p/> - * This method deletes the cached file and the info file ONLY if it - * attempted a download and it failed to complete. It doesn't erase - * anything if there's no download because the server returned a 404 - * or 304 or similar. - * - * @return An in-memory byte buffer input stream for the downloaded - * and locally cached file, or null if nothing was downloaded - * (including if it was a 304 Not-Modified status code.) - */ - private InputStream downloadAndCache( - String urlString, - ITaskMonitor monitor, - File cached, - File info, - @Nullable Header[] headers, - @Nullable AtomicInteger outStatusCode) - throws FileNotFoundException, IOException, CanceledByUserException { - InputStream is = null; - OutputStream os = null; - - int inc = 65536; - int curr = 0; - byte[] result = new byte[inc]; - - try { - Pair<InputStream, HttpResponse> r = - UrlOpener.openUrl(urlString, true /*needsMarkResetSupport*/, monitor, headers); - - is = r.getFirst(); - HttpResponse response = r.getSecond(); - - if (DEBUG) { - System.out.println(String.format("%s : fetch: %s => %s", //$NON-NLS-1$ - urlString, - headers == null ? "" : Arrays.toString(headers), //$NON-NLS-1$ - response.getStatusLine())); - } - - int code = response.getStatusLine().getStatusCode(); - - if (outStatusCode != null) { - outStatusCode.set(code); - } - - if (code != HttpStatus.SC_OK) { - // Only a 200 response code makes sense here. - // Even the other 20x codes should not apply, e.g. no content or partial - // content are not statuses we want to handle and should never happen. - // (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1 for list) - return null; - } - - os = new FileOutputStream(cached); - - int n; - while ((n = is.read(result, curr, result.length - curr)) != -1) { - if (os != null && n > 0) { - os.write(result, curr, n); - } - - curr += n; - - if (os != null && curr > MAX_SMALL_FILE_SIZE) { - // If the file size exceeds our "small file size" threshold, - // stop caching. We don't want to fill the disk. - try { - os.close(); - } catch (IOException ignore) {} - try { - cached.delete(); - info.delete(); - } catch (SecurityException ignore) {} - os = null; - } - if (curr == result.length) { - byte[] temp = new byte[curr + inc]; - System.arraycopy(result, 0, temp, 0, curr); - result = temp; - } - } - - // Close the output stream, signaling it was stored properly. - if (os != null) { - try { - os.close(); - os = null; - - saveInfo(urlString, response, info); - } catch (IOException ignore) {} - } - - return new ByteArrayInputStream(result, 0, curr); - - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException ignore) {} - } - if (os != null) { - try { - os.close(); - } catch (IOException ignore) {} - // If we get here with the output stream not null, it means there - // was an issue and we don't want to keep that file. We'll try to - // delete it. - try { - cached.delete(); - info.delete(); - } catch (SecurityException ignore) {} - } - } - } - - /** - * Saves part of the HTTP Response to the info file. - */ - private void saveInfo(String urlString, HttpResponse response, File info) throws IOException { - Properties props = new Properties(); - - // we don't need the status code & URL right now. - // Save it in case we want to have it later (e.g. to differentiate 200 and 404.) - props.setProperty(KEY_URL, urlString); - props.setProperty(KEY_STATUS_CODE, - Integer.toString(response.getStatusLine().getStatusCode())); - - for (String name : INFO_HTTP_HEADERS) { - Header h = response.getFirstHeader(name); - if (h != null) { - props.setProperty(name, h.getValue()); - } - } - - FileOutputStream os = null; - try { - os = new FileOutputStream(info); - props.store(os, "## Meta data for SDK Manager cache. Do not modify."); //$NON-NLS-1$ - } finally { - if (os != null) { - os.close(); - } - } - } - - /** - * Reads the info properties file. - * @return The properties found or null if there's no file or it can't be read. - */ - private Properties readInfo(File info) { - if (info.exists()) { - Properties props = new Properties(); - - InputStream is = null; - try { - is = new FileInputStream(info); - props.load(is); - return props; - } catch (IOException ignore) { - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException ignore) {} - } - } - } - return null; - } - - /** - * Computes the cache filename for the given URL. - * The filename uses the {@link #BIN_FILE_PREFIX}, the full URL string's hashcode and - * a sanitized portion of the URL filename. The returned filename is never - * more than 64 characters to ensure maximum file system compatibility. - * - * @param urlString The download URL. - * @return A leaf filename for the cached download file. - */ - private String getCacheFilename(String urlString) { - String hash = String.format("%08x", urlString.hashCode()); - - String leaf = urlString.toLowerCase(Locale.US); - if (leaf.length() >= 2) { - int index = urlString.lastIndexOf('/', leaf.length() - 2); - leaf = urlString.substring(index + 1); - } - - leaf = leaf.replaceAll("[^a-z0-9_-]+", "_"); - leaf = leaf.replaceAll("__+", "_"); - - leaf = hash + '-' + leaf; - String prefix = BIN_FILE_PREFIX + REV_FILE_PREFIX; - int n = 64 - prefix.length(); - if (leaf.length() > n) { - leaf = leaf.substring(0, n); - } - - return prefix + leaf; - } - - private String getInfoFilename(String cacheFilename) { - return cacheFilename.replaceFirst(BIN_FILE_PREFIX, INFO_FILE_PREFIX); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IDescription.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IDescription.java deleted file mode 100755 index 5662a9c..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/IDescription.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -/** - * Interface for elements that can provide a description of themselves. - */ -public interface IDescription { - - /** - * Returns a description of the given element. Cannot be null. - * <p/> - * A description is a multi-line of text, typically much more - * elaborate than what {@link #toString()} would provide. - */ - public abstract String getShortDescription(); - - /** - * Returns a description of the given element. Cannot be null. - * <p/> - * A description is a multi-line of text, typically much more - * elaborate than what {@link #toString()} would provide. - */ - public abstract String getLongDescription(); - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java deleted file mode 100755 index 5e561eb..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITask.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - - -/** - * A task that executes and can update a monitor to display its status. - * The task will generally be run in a separate thread. - */ -public interface ITask { - public abstract void run(ITaskMonitor monitor); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java deleted file mode 100755 index 959549b..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskFactory.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - - -/** - * A factory that can start and run new {@link ITask}s. - */ -public interface ITaskFactory { - - /** - * Starts a new task with a new {@link ITaskMonitor}. - * <p/> - * The task will execute in a thread and runs it own UI loop. - * This means the task can perform UI operations using - * {@code Display#asyncExec(Runnable)}. - * <p/> - * In either case, the method only returns when the task has finished. - * - * @param title The title of the task, displayed in the monitor if any. - * @param task The task to run. - */ - public abstract void start(String title, ITask task); - - /** - * Starts a new task contributing to an already existing {@link ITaskMonitor}. - * <p/> - * To use this properly, you should use {@link ITaskMonitor#createSubMonitor(int)} - * and give the sub-monitor to the new task with the number of work units you want - * it to fill. The {@link #start} method will make sure to <em>fill</em> the progress - * when the task is completed, in case the actual task did not. - * <p/> - * When a task is started from within a monitor, it reuses the thread - * from the parent. Otherwise it starts a new thread and runs it own - * UI loop. This means the task can perform UI operations using - * {@code Display#asyncExec(Runnable)}. - * <p/> - * In either case, the method only returns when the task has finished. - * - * @param title The title of the task, displayed in the monitor if any. - * @param parentMonitor The parent monitor. Can be null. - * @param task The task to run and have it display on the monitor. - */ - public abstract void start(String title, ITaskMonitor parentMonitor, ITask task); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java deleted file mode 100755 index 74dd14a..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/ITaskMonitor.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.utils.ILogger; - - -/** - * A monitor interface for a {@link ITask}. - * <p/> - * Depending on the task factory that created the task, there might not be any UI - * or it might not implement all the methods, in which case calling them would be - * a no-op but is guaranteed not to crash. - * <p/> - * If the task runs in a non-UI worker thread, the task factory implementation - * will take care of the update the UI in the correct thread. The task itself - * must not have to deal with it. - * <p/> - * A monitor typically has 3 levels of text displayed: <br/> - * - A <b>title</b> <em>may</em> be present on a task dialog, typically when a task - * dialog is created. This is not covered by this monitor interface. <br/> - * - A <b>description</b> displays prominent information on what the task - * is currently doing. This is expected to vary over time, typically changing - * with each sub-monitor, and typically only the last description is visible. - * For example an updater would typically have descriptions such as "downloading", - * "installing" and finally "done". This is set using {@link #setDescription}. <br/> - * - A <b>verbose</b> optional log that can provide more information than the summary - * description and is typically displayed in some kind of scrollable multi-line - * text field so that the user can keep track of what happened. 3 levels are - * provided: error, normal and verbose. An UI may hide the log till an error is - * logged and/or might hide the verbose text unless a flag is checked by the user. - * This is set using {@link #log}, {@link #logError} and {@link #logVerbose}. - * <p/> - * A monitor is also an {@link ILogger} implementation. - */ -public interface ITaskMonitor extends ILogger { - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - public void setDescription(String format, Object...args); - - /** - * Logs a "normal" information line. - * This method can be invoked from a non-UI thread. - */ - public void log(String format, Object...args); - - /** - * Logs an "error" information line. - * This method can be invoked from a non-UI thread. - */ - public void logError(String format, Object...args); - - /** - * Logs a "verbose" information line, that is extra details which are typically - * not that useful for the end-user and might be hidden until explicitly shown. - * This method can be invoked from a non-UI thread. - */ - public void logVerbose(String format, Object...args); - - /** - * Sets the max value of the progress bar. - * This method can be invoked from a non-UI thread. - * - * This method MUST be invoked once before using {@link #incProgress(int)} or - * {@link #getProgress()} or {@link #createSubMonitor(int)}. Callers are - * discouraged from using more than once -- implementations can either discard - * the next calls or behave incoherently. - */ - public void setProgressMax(int max); - - /** - * Returns the max valie of the progress bar, as last set by {@link #setProgressMax(int)}. - * Returns 0 if the max has never been set yet. - */ - public int getProgressMax(); - - /** - * Increments the current value of the progress bar. - * This method can be invoked from a non-UI thread. - * - * Callers MUST use setProgressMax before using this method. - */ - public void incProgress(int delta); - - /** - * Returns the current value of the progress bar, - * between 0 and up to {@link #setProgressMax(int)} - 1. - * - * Callers MUST use setProgressMax before using this method. - */ - public int getProgress(); - - /** - * Returns true if the user requested to cancel the operation. - * It is up to the task thread to pool this and exit as soon - * as possible. - */ - public boolean isCancelRequested(); - - /** - * Creates a sub-monitor that will use up to tickCount on the progress bar. - * tickCount must be 1 or more. - */ - public ITaskMonitor createSubMonitor(int tickCount); - - /** - * Display a yes/no question dialog box. - * - * Implementations MUST allow this to be called from any thread, e.g. by - * making sure the dialog is opened synchronously in the ui thread. - * - * @param title The title of the dialog box - * @param message The error message - * @return true if YES was clicked. - */ - public boolean displayPrompt(final String title, final String message); - - /** - * Launch an interface which asks for user credentials. Implementations - * MUST allow this to be called from any thread, e.g. by making sure the - * dialog is opened synchronously in the UI thread. - * - * @param title The title of the dialog box. - * @param message The message to be displayed as an instruction. - * @return Returns the user provided credentials. Some fields may be blank if the user - * did not provide any input. - If operation is <b>canceled</b> by user the return value must be <b>null</b>. - */ - public UserCredentials displayLoginCredentialsPrompt(String title, String message); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java deleted file mode 100755 index 313819b..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/LocalSdkParser.java +++ /dev/null @@ -1,659 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISystemImage; -import com.android.sdklib.ISystemImage.LocationType; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.AddonPackage; -import com.android.sdklib.internal.repository.packages.DocPackage; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.internal.repository.packages.SamplePackage; -import com.android.sdklib.internal.repository.packages.SourcePackage; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.utils.ILogger; -import com.android.utils.Pair; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; - -/** - * Scans a local SDK to find which packages are currently installed. - */ -public class LocalSdkParser { - - private Package[] mPackages; - - /** Parse all SDK folders. */ - public static final int PARSE_ALL = 0xFFFF; - /** Parse the SDK/tools folder. */ - public static final int PARSE_TOOLS = 0x0001; - /** Parse the SDK/platform-tools folder */ - public static final int PARSE_PLATFORM_TOOLS = 0x0002; - /** Parse the SDK/docs folder. */ - public static final int PARSE_DOCS = 0x0004; - /** - * Equivalent to parsing the SDK/platforms folder but does so - * by using the <em>valid</em> targets loaded by the {@link SdkManager}. - * Parsing the platforms also parses the SDK/system-images folder. - */ - public static final int PARSE_PLATFORMS = 0x0010; - /** - * Equivalent to parsing the SDK/addons folder but does so - * by using the <em>valid</em> targets loaded by the {@link SdkManager}. - */ - public static final int PARSE_ADDONS = 0x0020; - /** Parse the SDK/samples folder. - * Note: this will not detect samples located in the SDK/extras packages. */ - public static final int PARSE_SAMPLES = 0x0100; - /** Parse the SDK/sources folder. */ - public static final int PARSE_SOURCES = 0x0200; - /** Parse the SDK/extras folder. */ - public static final int PARSE_EXTRAS = 0x0400; - - public LocalSdkParser() { - // pass - } - - /** - * Returns the packages found by the last call to {@link #parseSdk}. - * <p/> - * This returns initially returns null. - * Once the parseSdk() method has been called, this returns a possibly empty but non-null array. - */ - public Package[] getPackages() { - return mPackages; - } - - /** - * Clear the internal packages list. After this call, {@link #getPackages()} will return - * null till {@link #parseSdk} is called. - */ - public void clearPackages() { - mPackages = null; - } - - /** - * Scan the give SDK to find all the packages already installed at this location. - * <p/> - * Store the packages internally. You can use {@link #getPackages()} to retrieve them - * at any time later. - * <p/> - * Equivalent to calling {@code parseSdk(..., PARSE_ALL, ...); } - * - * @param osSdkRoot The path to the SDK folder, typically {@code sdkManager.getLocation()}. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @param monitor A monitor to track progress. Cannot be null. - * @return The packages found. Can be retrieved later using {@link #getPackages()}. - */ - public @NonNull Package[] parseSdk( - @NonNull String osSdkRoot, - @NonNull SdkManager sdkManager, - @NonNull ITaskMonitor monitor) { - return parseSdk(osSdkRoot, sdkManager, PARSE_ALL, monitor); - } - - /** - * Scan the give SDK to find all the packages already installed at this location. - * <p/> - * Store the packages internally. You can use {@link #getPackages()} to retrieve them - * at any time later. - * - * @param osSdkRoot The path to the SDK folder, typically {@code sdkManager.getLocation()}. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @param parseFilter Either {@link #PARSE_ALL} or an ORed combination of the other - * {@code PARSE_} constants to indicate what should be parsed. - * @param monitor A monitor to track progress. Cannot be null. - * @return The packages found. Can be retrieved later using {@link #getPackages()}. - */ - public @NonNull Package[] parseSdk( - @NonNull String osSdkRoot, - @NonNull SdkManager sdkManager, - int parseFilter, - @NonNull ITaskMonitor monitor) { - ArrayList<Package> packages = new ArrayList<Package>(); - HashSet<File> visited = new HashSet<File>(); - - monitor.setProgressMax(10); - - File dir = null; - Package pkg = null; - - if ((parseFilter & PARSE_DOCS) != 0) { - dir = new File(osSdkRoot, SdkConstants.FD_DOCS); - pkg = scanDoc(dir, monitor); - if (pkg != null) { - packages.add(pkg); - visited.add(dir); - } - } - monitor.incProgress(1); - - if ((parseFilter & PARSE_TOOLS) != 0) { - dir = new File(osSdkRoot, SdkConstants.FD_TOOLS); - pkg = scanTools(dir, monitor); - if (pkg != null) { - packages.add(pkg); - visited.add(dir); - } - } - monitor.incProgress(1); - - if ((parseFilter & PARSE_PLATFORM_TOOLS) != 0) { - dir = new File(osSdkRoot, SdkConstants.FD_PLATFORM_TOOLS); - pkg = scanPlatformTools(dir, monitor); - if (pkg != null) { - packages.add(pkg); - visited.add(dir); - } - } - monitor.incProgress(1); - - // for platforms, add-ons and samples, rely on the SdkManager parser - if ((parseFilter & (PARSE_ADDONS | PARSE_PLATFORMS)) != 0) { - File samplesRoot = new File(osSdkRoot, SdkConstants.FD_SAMPLES); - - for(IAndroidTarget target : sdkManager.getTargets()) { - Properties props = parseProperties(new File(target.getLocation(), - SdkConstants.FN_SOURCE_PROP)); - - try { - pkg = null; - if (target.isPlatform() && (parseFilter & PARSE_PLATFORMS) != 0) { - pkg = PlatformPackage.create(target, props); - - if (samplesRoot.isDirectory()) { - // Get the samples dir for a platform if it is located in the new - // root /samples dir. We purposely ignore "old" samples that are - // located under the platform dir. - File samplesDir = new File(target.getPath(IAndroidTarget.SAMPLES)); - if (samplesDir.exists() && - samplesDir.getParentFile().equals(samplesRoot)) { - Properties samplesProps = parseProperties( - new File(samplesDir, SdkConstants.FN_SOURCE_PROP)); - if (samplesProps != null) { - Package pkg2 = SamplePackage.create(target, samplesProps); - packages.add(pkg2); - } - visited.add(samplesDir); - } - } - } else if ((parseFilter & PARSE_ADDONS) != 0) { - pkg = AddonPackage.create(target, props); - } - - if (pkg != null) { - for (ISystemImage systemImage : target.getSystemImages()) { - if (systemImage.getLocationType() == LocationType.IN_SYSTEM_IMAGE) { - File siDir = systemImage.getLocation(); - if (siDir.isDirectory()) { - Properties siProps = parseProperties( - new File(siDir, SdkConstants.FN_SOURCE_PROP)); - Package pkg2 = new SystemImagePackage( - target.getVersion(), - 0 /*rev*/, // this will use the one from siProps - systemImage.getAbiType(), - siProps, - siDir.getAbsolutePath()); - packages.add(pkg2); - visited.add(siDir); - } - } - } - } - - } catch (Exception e) { - monitor.error(e, null); - } - - if (pkg != null) { - packages.add(pkg); - visited.add(new File(target.getLocation())); - } - } - } - monitor.incProgress(1); - - if ((parseFilter & PARSE_PLATFORMS) != 0) { - scanMissingSystemImages(sdkManager, visited, packages, monitor); - } - monitor.incProgress(1); - if ((parseFilter & PARSE_ADDONS) != 0) { - scanMissingAddons(sdkManager, visited, packages, monitor); - } - monitor.incProgress(1); - if ((parseFilter & PARSE_SAMPLES) != 0) { - scanMissingSamples(sdkManager, visited, packages, monitor); - } - monitor.incProgress(1); - if ((parseFilter & PARSE_EXTRAS) != 0) { - scanExtras(sdkManager, visited, packages, monitor); - } - monitor.incProgress(1); - if ((parseFilter & PARSE_EXTRAS) != 0) { - scanExtrasDirectory(osSdkRoot, visited, packages, monitor); - } - monitor.incProgress(1); - if ((parseFilter & PARSE_SOURCES) != 0) { - scanSources(sdkManager, visited, packages, monitor); - } - monitor.incProgress(1); - - Collections.sort(packages); - - mPackages = packages.toArray(new Package[packages.size()]); - return mPackages; - } - - /** - * Find any directory in the /extras/vendors/path folders for extra packages. - * This isn't a recursive search. - */ - private void scanExtras(SdkManager sdkManager, - HashSet<File> visited, - ArrayList<Package> packages, - ILogger log) { - File root = new File(sdkManager.getLocation(), SdkConstants.FD_EXTRAS); - - if (!root.isDirectory()) { - // This should not happen. It makes listFiles() return null so let's avoid it. - return; - } - - for (File vendor : root.listFiles()) { - if (vendor.isDirectory()) { - scanExtrasDirectory(vendor.getAbsolutePath(), visited, packages, log); - } - } - } - - /** - * Find any other directory in the given "root" directory that hasn't been visited yet - * and assume they contain extra packages. This is <em>not</em> a recursive search. - */ - private void scanExtrasDirectory(String extrasRoot, - HashSet<File> visited, - ArrayList<Package> packages, - ILogger log) { - File root = new File(extrasRoot); - - if (!root.isDirectory()) { - // This should not happen. It makes listFiles() return null so let's avoid it. - return; - } - - for (File dir : root.listFiles()) { - if (dir.isDirectory() && !visited.contains(dir)) { - Properties props = parseProperties(new File(dir, SdkConstants.FN_SOURCE_PROP)); - if (props != null) { - try { - Package pkg = ExtraPackage.create( - null, //source - props, //properties - null, //vendor - dir.getName(), //path - 0, //revision - null, //license - null, //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - dir.getPath() //archiveOsPath - ); - - packages.add(pkg); - visited.add(dir); - } catch (Exception e) { - log.error(e, null); - } - } - } - } - } - - /** - * Find any other sub-directories under the /samples root that hasn't been visited yet - * and assume they contain sample packages. This is <em>not</em> a recursive search. - * <p/> - * The use case is to find samples dirs under /samples when their target isn't loaded. - */ - private void scanMissingSamples(SdkManager sdkManager, - HashSet<File> visited, - ArrayList<Package> packages, - ILogger log) { - File root = new File(sdkManager.getLocation()); - root = new File(root, SdkConstants.FD_SAMPLES); - - if (!root.isDirectory()) { - // It makes listFiles() return null so let's avoid it. - return; - } - - for (File dir : root.listFiles()) { - if (dir.isDirectory() && !visited.contains(dir)) { - Properties props = parseProperties(new File(dir, SdkConstants.FN_SOURCE_PROP)); - if (props != null) { - try { - Package pkg = SamplePackage.create(dir.getAbsolutePath(), props); - packages.add(pkg); - visited.add(dir); - } catch (Exception e) { - log.error(e, null); - } - } - } - } - } - - /** - * The sdk manager only lists valid addons. However here we also want to find "broken" - * addons, i.e. addons that failed to load for some reason. - * <p/> - * Find any other sub-directories under the /add-ons root that hasn't been visited yet - * and assume they contain broken addons. - */ - private void scanMissingAddons(SdkManager sdkManager, - HashSet<File> visited, - ArrayList<Package> packages, - ILogger log) { - File addons = new File(new File(sdkManager.getLocation()), SdkConstants.FD_ADDONS); - - File[] files = addons.listFiles(); - if (files == null) { - return; - } - - for (File dir : files) { - if (dir.isDirectory() && !visited.contains(dir)) { - Pair<Map<String, String>, String> infos = - SdkManager.parseAddonProperties(dir, sdkManager.getTargets(), log); - Properties sourceProps = - parseProperties(new File(dir, SdkConstants.FN_SOURCE_PROP)); - - Map<String, String> addonProps = infos.getFirst(); - String error = infos.getSecond(); - try { - Package pkg = AddonPackage.createBroken(dir.getAbsolutePath(), - sourceProps, - addonProps, - error); - packages.add(pkg); - visited.add(dir); - } catch (Exception e) { - log.error(e, null); - } - } - } - } - - /** - * The sdk manager only lists valid system image via its addons or platform targets. - * However here we also want to find "broken" system images, that is system images - * that are located in the sdk/system-images folder but somehow not loaded properly. - */ - private void scanMissingSystemImages(SdkManager sdkManager, - HashSet<File> visited, - ArrayList<Package> packages, - ILogger log) { - File siRoot = new File(sdkManager.getLocation(), SdkConstants.FD_SYSTEM_IMAGES); - - File[] files = siRoot.listFiles(); - if (files == null) { - return; - } - - // The system-images folder contains a list of platform folders. - for (File platformDir : files) { - if (platformDir.isDirectory() && !visited.contains(platformDir)) { - visited.add(platformDir); - - // In the platform directory, we expect a list of abi folders - File[] platformFiles = platformDir.listFiles(); - if (platformFiles != null) { - for (File abiDir : platformFiles) { - if (abiDir.isDirectory() && !visited.contains(abiDir)) { - visited.add(abiDir); - - // Ignore empty directories - File[] abiFiles = abiDir.listFiles(); - if (abiFiles != null && abiFiles.length > 0) { - Properties props = - parseProperties(new File(abiDir, SdkConstants.FN_SOURCE_PROP)); - - try { - Package pkg = SystemImagePackage.createBroken(abiDir, props); - packages.add(pkg); - } catch (Exception e) { - log.error(e, null); - } - } - } - } - } - } - } - } - - /** - * Scan the sources/folders and register valid as well as broken source packages. - */ - private void scanSources(SdkManager sdkManager, - HashSet<File> visited, - ArrayList<Package> packages, - ILogger log) { - File srcRoot = new File(sdkManager.getLocation(), SdkConstants.FD_PKG_SOURCES); - - File[] subDirs = srcRoot.listFiles(); - if (subDirs == null) { - return; - } - - // The sources folder contains a list of platform folders. - for (File platformDir : subDirs) { - if (platformDir.isDirectory() && !visited.contains(platformDir)) { - visited.add(platformDir); - - // Ignore empty directories - File[] srcFiles = platformDir.listFiles(); - if (srcFiles != null && srcFiles.length > 0) { - Properties props = - parseProperties(new File(platformDir, SdkConstants.FN_SOURCE_PROP)); - - try { - Package pkg = SourcePackage.create(platformDir, props); - packages.add(pkg); - } catch (Exception e) { - log.error(e, null); - } - } - } - } - } - - /** - * Try to find a tools package at the given location. - * Returns null if not found. - */ - private Package scanTools(File toolFolder, ILogger log) { - // Can we find some properties? - Properties props = parseProperties(new File(toolFolder, SdkConstants.FN_SOURCE_PROP)); - - // We're not going to check that all tools are present. At the very least - // we should expect to find android and an emulator adapted to the current OS. - boolean hasEmulator = false; - boolean hasAndroid = false; - String android1 = SdkConstants.androidCmdName().replace(".bat", ".exe"); - String android2 = android1.indexOf('.') == -1 ? null : android1.replace(".exe", ".bat"); - File[] files = toolFolder.listFiles(); - if (files != null) { - for (File file : files) { - String name = file.getName(); - if (SdkConstants.FN_EMULATOR.equals(name)) { - hasEmulator = true; - } - if (android1.equals(name) || (android2 != null && android2.equals(name))) { - hasAndroid = true; - } - } - } - - if (!hasAndroid || !hasEmulator) { - return null; - } - - // Create our package. use the properties if we found any. - try { - Package pkg = ToolPackage.create( - null, //source - props, //properties - 0, //revision - null, //license - "Tools", //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - toolFolder.getPath() //archiveOsPath - ); - - return pkg; - } catch (Exception e) { - log.error(e, null); - } - return null; - } - - /** - * Try to find a platform-tools package at the given location. - * Returns null if not found. - */ - private Package scanPlatformTools(File platformToolsFolder, ILogger log) { - // Can we find some properties? - Properties props = parseProperties(new File(platformToolsFolder, - SdkConstants.FN_SOURCE_PROP)); - - // We're not going to check that all tools are present. At the very least - // we should expect to find adb, aidl, aapt and dx (adapted to the current OS). - - if (platformToolsFolder.listFiles() == null) { - // ListFiles is null if the directory doesn't even exist. - // Not going to find anything in there... - return null; - } - - // Create our package. use the properties if we found any. - try { - Package pkg = PlatformToolPackage.create( - null, //source - props, //properties - 0, //revision - null, //license - "Platform Tools", //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - platformToolsFolder.getPath() //archiveOsPath - ); - - return pkg; - } catch (Exception e) { - log.error(e, null); - } - return null; - } - - /** - * Try to find a docs package at the given location. - * Returns null if not found. - */ - private Package scanDoc(File docFolder, ILogger log) { - // Can we find some properties? - Properties props = parseProperties(new File(docFolder, SdkConstants.FN_SOURCE_PROP)); - - // To start with, a doc folder should have an "index.html" to be acceptable. - // We don't actually check the content of the file. - if (new File(docFolder, "index.html").isFile()) { - try { - Package pkg = DocPackage.create( - null, //source - props, //properties - 0, //apiLevel - null, //codename - 0, //revision - null, //license - null, //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - docFolder.getPath() //archiveOsPath - ); - - return pkg; - } catch (Exception e) { - log.error(e, null); - } - } - - return null; - } - - /** - * Parses the given file as properties file if it exists. - * Returns null if the file does not exist, cannot be parsed or has no properties. - */ - private Properties parseProperties(File propsFile) { - FileInputStream fis = null; - try { - if (propsFile.exists()) { - fis = new FileInputStream(propsFile); - - Properties props = new Properties(); - props.load(fis); - - // To be valid, there must be at least one property in it. - if (props.size() > 0) { - return props; - } - } - - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - } - } - } - return null; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/NullTaskMonitor.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/NullTaskMonitor.java deleted file mode 100755 index f69e37d..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/NullTaskMonitor.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.annotations.NonNull; -import com.android.utils.ILogger; -import com.android.utils.NullLogger; - - -/** - * A no-op implementation of the {@link ITaskMonitor} interface. - * <p/> - * This can be passed to methods that require a monitor when the caller doesn't - * have any UI to update or means to report tracked progress. - * A custom {@link ILogger} is used. Clients could use {@link NullLogger} if - * they really don't care about the logging either. - */ -public class NullTaskMonitor implements ITaskMonitor { - - private final ILogger mLog; - - /** - * Creates a no-op {@link ITaskMonitor} that defers logging to the specified - * logger. - * <p/> - * This can be passed to methods that require a monitor when the caller doesn't - * have any UI to update or means to report tracked progress. - * - * @param log An {@link ILogger}. Must not be null. Consider using {@link NullLogger}. - */ - public NullTaskMonitor(ILogger log) { - mLog = log; - } - - @Override - public void setDescription(String format, Object...args) { - // pass - } - - @Override - public void log(String format, Object...args) { - mLog.info(format, args); - } - - @Override - public void logError(String format, Object...args) { - mLog.error(null /*throwable*/, format, args); - } - - @Override - public void logVerbose(String format, Object...args) { - mLog.verbose(format, args); - } - - @Override - public void setProgressMax(int max) { - // pass - } - - @Override - public int getProgressMax() { - return 0; - } - - @Override - public void incProgress(int delta) { - // pass - } - - /** Always return 1. */ - @Override - public int getProgress() { - return 1; - } - - /** Always return false. */ - @Override - public boolean isCancelRequested() { - return false; - } - - @Override - public ITaskMonitor createSubMonitor(int tickCount) { - return this; - } - - /** Always return false. */ - @Override - public boolean displayPrompt(final String title, final String message) { - return false; - } - - /** Always return null. */ - @Override - public UserCredentials displayLoginCredentialsPrompt(String title, String message) { - return null; - } - - // --- ILogger --- - - @Override - public void error(Throwable t, String errorFormat, Object... args) { - mLog.error(t, errorFormat, args); - } - - @Override - public void warning(@NonNull String warningFormat, Object... args) { - mLog.warning(warningFormat, args); - } - - @Override - public void info(@NonNull String msgFormat, Object... args) { - mLog.info(msgFormat, args); - } - - @Override - public void verbose(@NonNull String msgFormat, Object... args) { - mLog.verbose(msgFormat, args); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkStats.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkStats.java deleted file mode 100755 index 0301b5e..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/SdkStats.java +++ /dev/null @@ -1,622 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.io.NonClosingInputStream; -import com.android.sdklib.io.NonClosingInputStream.CloseBehavior; -import com.android.sdklib.repository.SdkStatsConstants; -import com.android.sdklib.util.SparseArray; - -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.UnknownHostException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.SSLKeyException; -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - - -/** - * Retrieves stats on platforms. - * <p/> - * This returns information stored on the repository in a different XML file - * and isn't directly tied to the existence of the listed platforms. - */ -public class SdkStats { - - public static class PlatformStatBase { - private final int mApiLevel; - private final String mVersionName; - private final String mCodeName; - private final float mShare; - - public PlatformStatBase(int apiLevel, - String versionName, - String codeName, - float share) { - mApiLevel = apiLevel; - mVersionName = versionName; - mCodeName = codeName; - mShare = share; - } - - /** The Android API Level for the platform. An int > 0. */ - public int getApiLevel() { - return mApiLevel; - } - - /** The official codename for this platform, for example "Cupcake". */ - public String getCodeName() { - return mCodeName; - } - - /** The official version name of this platform, for example "Android 1.5". */ - public String getVersionName() { - return mVersionName; - } - - /** An approximate share percentage of this platform and all the - * platforms of lower API level. */ - public float getShare() { - return mShare; - } - - /** Returns a string representation of this object, for debugging purposes. */ - @Override - public String toString() { - return String.format("api=%d, code=%s, vers=%s, share=%.1f%%", //$NON-NLS-1$ - mApiLevel, mCodeName, mVersionName, mShare); - } - } - - public static class PlatformStat extends PlatformStatBase { - private final float mAccumShare; - - public PlatformStat(int apiLevel, - String versionName, - String codeName, - float share, - float accumShare) { - super(apiLevel, versionName, codeName, share); - mAccumShare = accumShare; - } - - public PlatformStat(PlatformStatBase base, float accumShare) { - super(base.getApiLevel(), - base.getVersionName(), - base.getCodeName(), - base.getShare()); - mAccumShare = accumShare; - } - - /** The accumulated approximate share percentage of that platform. */ - public float getAccumShare() { - return mAccumShare; - } - - /** Returns a string representation of this object, for debugging purposes. */ - @Override - public String toString() { - return String.format("<Stat %s, accum=%.1f%%>", super.toString(), mAccumShare); - } - } - - private final SparseArray<PlatformStat> mStats = new SparseArray<SdkStats.PlatformStat>(); - - public SdkStats() { - } - - public SparseArray<PlatformStat> getStats() { - return mStats; - } - - public void load(DownloadCache cache, boolean forceHttp, ITaskMonitor monitor) { - - String url = SdkStatsConstants.URL_STATS; - - if (forceHttp) { - url = url.replaceAll("https://", "http://"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - monitor.setProgressMax(5); - monitor.setDescription("Fetching %1$s", url); - monitor.incProgress(1); - - Exception[] exception = new Exception[] { null }; - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - Document validatedDoc = null; - String validatedUri = null; - - InputStream xml = fetchXmlUrl(url, cache, monitor.createSubMonitor(1), exception); - - if (xml != null) { - monitor.setDescription("Validate XML"); - - // Explore the XML to find the potential XML schema version - int version = getXmlSchemaVersion(xml); - - if (version >= 1 && version <= SdkStatsConstants.NS_LATEST_VERSION) { - // This should be a version we can handle. Try to validate it - // and report any error as invalid XML syntax, - - String uri = validateXml(xml, url, version, validationError, validatorFound); - if (uri != null) { - // Validation was successful - validatedDoc = getDocument(xml, monitor); - validatedUri = uri; - - } - } else if (version > SdkStatsConstants.NS_LATEST_VERSION) { - // The schema used is more recent than what is supported by this tool. - // We don't have an upgrade-path support yet, so simply ignore the document. - closeStream(xml); - return; - } - } - - // If any exception was handled during the URL fetch, display it now. - if (exception[0] != null) { - String reason = null; - if (exception[0] instanceof FileNotFoundException) { - // FNF has no useful getMessage, so we need to special handle it. - reason = "File not found"; - } else if (exception[0] instanceof UnknownHostException && - exception[0].getMessage() != null) { - // This has no useful getMessage yet could really use one - reason = String.format("Unknown Host %1$s", exception[0].getMessage()); - } else if (exception[0] instanceof SSLKeyException) { - // That's a common error and we have a pref for it. - reason = "HTTPS SSL error. You might want to force download through HTTP in the settings."; - } else if (exception[0].getMessage() != null) { - reason = exception[0].getMessage(); - } else { - // We don't know what's wrong. Let's give the exception class at least. - reason = String.format("Unknown (%1$s)", exception[0].getClass().getName()); - } - - monitor.logError("Failed to fetch URL %1$s, reason: %2$s", url, reason); - } - - if (validationError[0] != null) { - monitor.logError("%s", validationError[0]); //$NON-NLS-1$ - } - - // Stop here if we failed to validate the XML. We don't want to load it. - if (validatedDoc == null) { - closeStream(xml); - return; - } - - monitor.incProgress(1); - - if (xml != null) { - monitor.setDescription("Parse XML"); - monitor.incProgress(1); - parseStatsDocument(validatedDoc, validatedUri, monitor); - } - - // done - monitor.incProgress(1); - closeStream(xml); - } - - /** - * Fetches the document at the given URL and returns it as a stream. Returns - * null if anything wrong happens. - * - * @param urlString The URL to load, as a string. - * @param monitor {@link ITaskMonitor} related to this URL. - * @param outException If non null, where to store any exception that - * happens during the fetch. - * @see UrlOpener UrlOpener, which handles all URL logic. - */ - private InputStream fetchXmlUrl(String urlString, - DownloadCache cache, - ITaskMonitor monitor, - Exception[] outException) { - try { - InputStream xml = cache.openCachedUrl(urlString, monitor); - if (xml != null) { - xml.mark(500000); - xml = new NonClosingInputStream(xml); - ((NonClosingInputStream) xml).setCloseBehavior(CloseBehavior.RESET); - } - return xml; - } catch (Exception e) { - if (outException != null) { - outException[0] = e; - } - } - - return null; - } - - /** - * Closes the stream, ignore any exception from InputStream.close(). - * If the stream is a NonClosingInputStream, sets it to CloseBehavior.CLOSE first. - */ - private void closeStream(InputStream is) { - if (is != null) { - if (is instanceof NonClosingInputStream) { - ((NonClosingInputStream) is).setCloseBehavior(CloseBehavior.CLOSE); - } - try { - is.close(); - } catch (IOException ignore) {} - } - } - - /** - * Manually parses the root element of the XML to extract the schema version - * at the end of the xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/$N" - * declaration. - * - * @return 1..{@link SdkStatsConstants#NS_LATEST_VERSION} for a valid schema version - * or 0 if no schema could be found. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected int getXmlSchemaVersion(InputStream xml) { - if (xml == null) { - return 0; - } - - // Get an XML document - Document doc = null; - try { - xml.reset(); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(false); - factory.setValidating(false); - - // Parse the old document using a non namespace aware builder - factory.setNamespaceAware(false); - DocumentBuilder builder = factory.newDocumentBuilder(); - - // We don't want the default handler which prints errors to stderr. - builder.setErrorHandler(new ErrorHandler() { - @Override - public void warning(SAXParseException e) throws SAXException { - // pass - } - @Override - public void fatalError(SAXParseException e) throws SAXException { - throw e; - } - @Override - public void error(SAXParseException e) throws SAXException { - throw e; - } - }); - - doc = builder.parse(xml); - - // Prepare a new document using a namespace aware builder - factory.setNamespaceAware(true); - builder = factory.newDocumentBuilder(); - - } catch (Exception e) { - // Failed to reset XML stream - // Failed to get builder factor - // Failed to create XML document builder - // Failed to parse XML document - // Failed to read XML document - } - - if (doc == null) { - return 0; - } - - // Check the root element is an XML with at least the following properties: - // <sdk:sdk-addons-list - // xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/$N"> - // - // Note that we don't have namespace support enabled, we just do it manually. - - Pattern nsPattern = Pattern.compile(SdkStatsConstants.NS_PATTERN); - - String prefix = null; - for (Node child = doc.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - prefix = null; - String name = child.getNodeName(); - int pos = name.indexOf(':'); - if (pos > 0 && pos < name.length() - 1) { - prefix = name.substring(0, pos); - name = name.substring(pos + 1); - } - if (SdkStatsConstants.NODE_SDK_STATS.equals(name)) { - NamedNodeMap attrs = child.getAttributes(); - String xmlns = "xmlns"; //$NON-NLS-1$ - if (prefix != null) { - xmlns += ":" + prefix; //$NON-NLS-1$ - } - Node attr = attrs.getNamedItem(xmlns); - if (attr != null) { - String uri = attr.getNodeValue(); - if (uri != null) { - Matcher m = nsPattern.matcher(uri); - if (m.matches()) { - String version = m.group(1); - try { - return Integer.parseInt(version); - } catch (NumberFormatException e) { - return 0; - } - } - } - } - } - } - } - - return 0; - } - - /** - * Validates this XML against one of the requested SDK Repository schemas. - * If the XML was correctly validated, returns the schema that worked. - * If it doesn't validate, returns null and stores the error in outError[0]. - * If we can't find a validator, returns null and set validatorFound[0] to false. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected String validateXml(InputStream xml, String url, int version, - String[] outError, Boolean[] validatorFound) { - - if (xml == null) { - return null; - } - - try { - Validator validator = getValidator(version); - - if (validator == null) { - validatorFound[0] = Boolean.FALSE; - outError[0] = String.format( - "XML verification failed for %1$s.\nNo suitable XML Schema Validator could be found in your Java environment. Please consider updating your version of Java.", - url); - return null; - } - - validatorFound[0] = Boolean.TRUE; - - // Reset the stream if it supports that operation. - xml.reset(); - - // Validation throws a bunch of possible Exceptions on failure. - validator.validate(new StreamSource(xml)); - return SdkStatsConstants.getSchemaUri(version); - - } catch (SAXParseException e) { - outError[0] = String.format( - "XML verification failed for %1$s.\nLine %2$d:%3$d, Error: %4$s", - url, - e.getLineNumber(), - e.getColumnNumber(), - e.toString()); - - } catch (Exception e) { - outError[0] = String.format( - "XML verification failed for %1$s.\nError: %2$s", - url, - e.toString()); - } - return null; - } - - /** - * Helper method that returns a validator for our XSD, or null if the current Java - * implementation can't process XSD schemas. - * - * @param version The version of the XML Schema. - * See {@link SdkStatsConstants#getXsdStream(int)} - */ - private Validator getValidator(int version) throws SAXException { - InputStream xsdStream = SdkStatsConstants.getXsdStream(version); - try { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - - if (factory == null) { - return null; - } - - // This may throw a SAX Exception if the schema itself is not a valid XSD - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - - Validator validator = schema == null ? null : schema.newValidator(); - - return validator; - } finally { - if (xsdStream != null) { - try { - xsdStream.close(); - } catch (IOException ignore) {} - } - } - } - - /** - * Takes an XML document as a string as parameter and returns a DOM for it. - * - * On error, returns null and prints a (hopefully) useful message on the monitor. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected Document getDocument(InputStream xml, ITaskMonitor monitor) { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(true); - factory.setNamespaceAware(true); - - DocumentBuilder builder = factory.newDocumentBuilder(); - xml.reset(); - Document doc = builder.parse(new InputSource(xml)); - - return doc; - } catch (ParserConfigurationException e) { - monitor.logError("Failed to create XML document builder"); - - } catch (SAXException e) { - monitor.logError("Failed to parse XML document"); - - } catch (IOException e) { - monitor.logError("Failed to read XML document"); - } - - return null; - } - - /** - * Parses all valid platforms found in the XML. - * Changes the stats array returned by {@link #getStats()} - * (also returns the value directly, useful for unti tests.) - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected SparseArray<PlatformStat> parseStatsDocument( - Document doc, - String nsUri, - ITaskMonitor monitor) { - - String baseUrl = System.getenv("SDK_TEST_BASE_URL"); //$NON-NLS-1$ - if (baseUrl != null) { - if (baseUrl.length() <= 0 || !baseUrl.endsWith("/")) { //$NON-NLS-1$ - baseUrl = null; - } - } - - SparseArray<PlatformStatBase> platforms = new SparseArray<SdkStats.PlatformStatBase>(); - int maxApi = 0; - - Node root = getFirstChild(doc, nsUri, SdkStatsConstants.NODE_SDK_STATS); - if (root != null) { - for (Node child = root.getFirstChild(); - child != null; - child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI()) && - child.getLocalName().equals(SdkStatsConstants.NODE_PLATFORM)) { - - try { - Node node = getFirstChild(child, nsUri, SdkStatsConstants.NODE_API_LEVEL); - int apiLevel = Integer.parseInt(node.getTextContent().trim()); - - if (apiLevel < 1) { - // bad API level, ignore it. - continue; - } - - if (platforms.indexOfKey(apiLevel) >= 0) { - // if we already loaded that API, ignore duplicates - continue; - } - - String codeName = - getFirstChild(child, nsUri, SdkStatsConstants.NODE_CODENAME). - getTextContent().trim(); - String versName = - getFirstChild(child, nsUri, SdkStatsConstants.NODE_VERSION). - getTextContent().trim(); - - if (codeName == null || versName == null || - codeName.length() == 0 || versName.length() == 0) { - // bad names. ignore. - continue; - } - - node = getFirstChild(child, nsUri, SdkStatsConstants.NODE_SHARE); - float percent = Float.parseFloat(node.getTextContent().trim()); - - if (percent < 0 || percent > 100) { - // invalid percentage. ignore. - continue; - } - - PlatformStatBase p = new PlatformStatBase( - apiLevel, versName, codeName, percent); - platforms.put(apiLevel, p); - - maxApi = apiLevel > maxApi ? apiLevel : maxApi; - - } catch (Exception ignore) { - // Error parsing this platform. Ignore it. - continue; - } - } - } - } - - mStats.clear(); - - // Compute cumulative share percents & fill in final map - for (int api = 1; api <= maxApi; api++) { - PlatformStatBase p = platforms.get(api); - if (p == null) { - continue; - } - - float sum = p.getShare(); - for (int j = api + 1; j <= maxApi; j++) { - PlatformStatBase pj = platforms.get(j); - if (pj != null) { - sum += pj.getShare(); - } - } - - mStats.put(api, new PlatformStat(p, sum)); - } - - return mStats; - } - - /** - * Returns the first child element with the given XML local name. - * If xmlLocalName is null, returns the very first child element. - */ - private Node getFirstChild(Node node, String nsUri, String xmlLocalName) { - - for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI())) { - if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) { - return child; - } - } - } - - return null; - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/UrlOpener.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/UrlOpener.java deleted file mode 100644 index 52724c7..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/UrlOpener.java +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.utils.Pair; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.ProtocolVersion; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.AuthState; -import org.apache.http.auth.Credentials; -import org.apache.http.auth.NTCredentials; -import org.apache.http.auth.params.AuthPNames; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.params.AuthPolicy; -import org.apache.http.client.protocol.ClientContext; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.ProxySelectorRoutePlanner; -import org.apache.http.message.BasicHttpResponse; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; -import org.apache.http.protocol.BasicHttpContext; -import org.apache.http.protocol.HttpContext; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.FileNotFoundException; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - -/** - * This class holds static methods for downloading URL resources. - * @see #openUrl(String, boolean, ITaskMonitor, Header[]) - * <p/> - * Implementation detail: callers should use {@link DownloadCache} instead of this class. - * {@link DownloadCache#openDirectUrl} is a direct pass-through to {@link UrlOpener} since - * there's no caching. However from an implementation perspective it's still recommended - * to pass down a {@link DownloadCache} instance, which will let us override the implementation - * later on (for testing, for example.) - */ -class UrlOpener { - - private static final boolean DEBUG = - System.getenv("ANDROID_DEBUG_URL_OPENER") != null; //$NON-NLS-1$ - - private static Map<String, UserCredentials> sRealmCache = - new HashMap<String, UserCredentials>(); - - /** Timeout to establish a connection, in milliseconds. */ - private static int sConnectionTimeoutMs; - /** Timeout waiting for data on a socket, in milliseconds. */ - private static int sSocketTimeoutMs; - - static { - if (DEBUG) { - Properties props = System.getProperties(); - for (String key : new String[] { - "http.proxyHost", //$NON-NLS-1$ - "http.proxyPort", //$NON-NLS-1$ - "https.proxyHost", //$NON-NLS-1$ - "https.proxyPort" }) { //$NON-NLS-1$ - String prop = props.getProperty(key); - if (prop != null) { - System.out.printf( - "SdkLib.UrlOpener Java.Prop %s='%s'\n", //$NON-NLS-1$ - key, prop); - } - } - } - - try { - sConnectionTimeoutMs = Integer.parseInt(System.getenv("ANDROID_SDKMAN_CONN_TIMEOUT")); - } catch (Exception ignore) { - sConnectionTimeoutMs = 2 * 60 * 1000; - } - - try { - sSocketTimeoutMs = Integer.parseInt(System.getenv("ANDROID_SDKMAN_READ_TIMEOUT")); - } catch (Exception ignore) { - sSocketTimeoutMs = 1 * 60 * 1000; - } - } - - /** - * This class cannot be instantiated. - * @see #openUrl(String, boolean, ITaskMonitor, Header[]) - */ - private UrlOpener() { - } - - /** - * Opens a URL. It can be a simple URL or one which requires basic - * authentication. - * <p/> - * Tries to access the given URL. If http response is either - * {@code HttpStatus.SC_UNAUTHORIZED} or - * {@code HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED}, asks for - * login/password and tries to authenticate into proxy server and/or URL. - * <p/> - * This implementation relies on the Apache Http Client due to its - * capabilities of proxy/http authentication. <br/> - * Proxy configuration is determined by {@link ProxySelectorRoutePlanner} using the JVM proxy - * settings by default. - * <p/> - * For more information see: <br/> - * - {@code http://hc.apache.org/httpcomponents-client-ga/} <br/> - * - {@code http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/ProxySelectorRoutePlanner.html} - * <p/> - * There's a very simple realm cache implementation. - * Login/Password for each realm are stored in a static {@link Map}. - * Before asking the user the method verifies if the information is already - * available in the memory cache. - * - * @param url the URL string to be opened. - * @param needsMarkResetSupport Indicates the caller <em>must</em> have an input stream that - * supports the mark/reset operations (as indicated by {@link InputStream#markSupported()}. - * Implementation detail: If the original stream does not, it will be fetched and wrapped - * into a {@link ByteArrayInputStream}. This can only work sanely if the resource is a - * small file that can fit in memory. It also means the caller has no chance of showing - * a meaningful download progress. If unsure, callers should set this to false. - * @param monitor {@link ITaskMonitor} to output status. - * @param headers An optional array of HTTP headers to use in the GET request. - * @return Returns a {@link Pair} with {@code first} holding an {@link InputStream} - * and {@code second} holding an {@link HttpResponse}. - * The returned pair is never null and contains - * at least a code; for http requests that provide them the response - * also contains locale, headers and an status line. - * The input stream can be null, especially in case of error. - * The caller must only accept the stream if the response code is 200 or similar. - * @throws IOException Exception thrown when there are problems retrieving - * the URL or its content. - * @throws CanceledByUserException Exception thrown if the user cancels the - * authentication dialog. - */ - static @NonNull Pair<InputStream, HttpResponse> openUrl( - @NonNull String url, - boolean needsMarkResetSupport, - @NonNull ITaskMonitor monitor, - @Nullable Header[] headers) - throws IOException, CanceledByUserException { - - Exception fallbackOnJavaUrlConnect = null; - Pair<InputStream, HttpResponse> result = null; - - try { - result = openWithHttpClient(url, monitor, headers); - - } catch (UnknownHostException e) { - // Host in unknown. No need to even retry with the Url object, - // if it's broken, it's broken. It's already an IOException but - // it could use a better message. - throw new IOException("Unknown Host " + e.getMessage(), e); - - } catch (ClientProtocolException e) { - // We get this when HttpClient fails to accept the current protocol, - // e.g. when processing file:// URLs. - fallbackOnJavaUrlConnect = e; - - } catch (IOException e) { - throw e; - - } catch (CanceledByUserException e) { - // HTTP Basic Auth or NTLM login was canceled by user. - throw e; - - } catch (Exception e) { - if (DEBUG) { - System.out.printf("[HttpClient Error] %s : %s\n", url, e.toString()); - } - - fallbackOnJavaUrlConnect = e; - } - - if (fallbackOnJavaUrlConnect != null) { - // If the protocol is not supported by HttpClient (e.g. file:///), - // revert to the standard java.net.Url.open. - - try { - result = openWithUrl(url, headers); - } catch (IOException e) { - throw e; - } catch (Exception e) { - if (DEBUG && !fallbackOnJavaUrlConnect.equals(e)) { - System.out.printf("[Url Error] %s : %s\n", url, e.toString()); - } - } - } - - // If the caller requires an InputStream that supports mark/reset, let's - // make sure we have such a stream. - if (result != null && needsMarkResetSupport) { - InputStream is = result.getFirst(); - if (is != null) { - if (!is.markSupported()) { - try { - // Consume the whole input stream and offer a byte array stream instead. - // This can only work sanely if the resource is a small file that can - // fit in memory. It also means the caller has no chance of showing - // a meaningful download progress. - InputStream is2 = toByteArrayInputStream(is); - if (is2 != null) { - result = Pair.of(is2, result.getSecond()); - try { - is.close(); - } catch (Exception ignore) {} - } - } catch (Exception e3) { - // Ignore. If this can't work, caller will fail later. - } - } - } - } - - if (result == null) { - // Make up an error code if we don't have one already. - HttpResponse outResponse = new BasicHttpResponse( - new ProtocolVersion("HTTP", 1, 0), //$NON-NLS-1$ - HttpStatus.SC_METHOD_FAILURE, ""); //$NON-NLS-1$; // 420=Method Failure - result = Pair.of(null, outResponse); - } - - return result; - } - - // ByteArrayInputStream is the duct tape of input streams. - private static InputStream toByteArrayInputStream(InputStream is) throws IOException { - int inc = 4096; - int curr = 0; - byte[] result = new byte[inc]; - - int n; - while ((n = is.read(result, curr, result.length - curr)) != -1) { - curr += n; - if (curr == result.length) { - byte[] temp = new byte[curr + inc]; - System.arraycopy(result, 0, temp, 0, curr); - result = temp; - } - } - - return new ByteArrayInputStream(result, 0, curr); - } - - private static Pair<InputStream, HttpResponse> openWithUrl( - String url, - Header[] inHeaders) throws IOException { - URL u = new URL(url); - - URLConnection c = u.openConnection(); - - c.setConnectTimeout(sConnectionTimeoutMs); - c.setReadTimeout(sSocketTimeoutMs); - - if (inHeaders != null) { - for (Header header : inHeaders) { - c.setRequestProperty(header.getName(), header.getValue()); - } - } - - // Trigger the access to the resource - // (at which point setRequestProperty can't be used anymore.) - int code = 200; - - if (c instanceof HttpURLConnection) { - code = ((HttpURLConnection) c).getResponseCode(); - } - - // Get the input stream. That can fail for a file:// that doesn't exist - // in which case we set the response code to 404. - // Also we need a buffered input stream since the caller need to use is.reset(). - InputStream is = null; - try { - is = new BufferedInputStream(c.getInputStream()); - } catch (Exception ignore) { - if (is == null && code == 200) { - code = 404; - } - } - - HttpResponse outResponse = new BasicHttpResponse( - new ProtocolVersion(u.getProtocol(), 1, 0), // make up the protocol version - code, ""); //$NON-NLS-1$; - - Map<String, List<String>> outHeaderMap = c.getHeaderFields(); - - for (Entry<String, List<String>> entry : outHeaderMap.entrySet()) { - String name = entry.getKey(); - if (name != null) { - List<String> values = entry.getValue(); - if (!values.isEmpty()) { - outResponse.setHeader(name, values.get(0)); - } - } - } - - return Pair.of(is, outResponse); - } - - private static @NonNull Pair<InputStream, HttpResponse> openWithHttpClient( - @NonNull String url, - @NonNull ITaskMonitor monitor, - Header[] inHeaders) - throws IOException, ClientProtocolException, CanceledByUserException { - UserCredentials result = null; - String realm = null; - - HttpParams params = new BasicHttpParams(); - HttpConnectionParams.setConnectionTimeout(params, sConnectionTimeoutMs); - HttpConnectionParams.setSoTimeout(params, sSocketTimeoutMs); - - // use the simple one - final DefaultHttpClient httpClient = new DefaultHttpClient(params); - - - // create local execution context - HttpContext localContext = new BasicHttpContext(); - final HttpGet httpGet = new HttpGet(url); - if (inHeaders != null) { - for (Header header : inHeaders) { - httpGet.addHeader(header); - } - } - - // retrieve local java configured network in case there is the need to - // authenticate a proxy - ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner( - httpClient.getConnectionManager().getSchemeRegistry(), - ProxySelector.getDefault()); - httpClient.setRoutePlanner(routePlanner); - - // Set preference order for authentication options. - // In particular, we don't add AuthPolicy.SPNEGO, which is given preference over NTLM in - // servers that support both, as it is more secure. However, we don't seem to handle it - // very well, so we leave it off the list. - // See http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html for - // more info. - List<String> authpref = new ArrayList<String>(); - authpref.add(AuthPolicy.BASIC); - authpref.add(AuthPolicy.DIGEST); - authpref.add(AuthPolicy.NTLM); - httpClient.getParams().setParameter(AuthPNames.PROXY_AUTH_PREF, authpref); - httpClient.getParams().setParameter(AuthPNames.TARGET_AUTH_PREF, authpref); - - if (DEBUG) { - try { - URI uri = new URI(url); - ProxySelector sel = routePlanner.getProxySelector(); - if (sel != null && uri.getScheme().startsWith("httP")) { //$NON-NLS-1$ - List<Proxy> list = sel.select(uri); - System.out.printf( - "SdkLib.UrlOpener:\n Connect to: %s\n Proxy List: %s\n", //$NON-NLS-1$ - url, - list == null ? "(null)" : Arrays.toString(list.toArray()));//$NON-NLS-1$ - } - } catch (Exception e) { - System.out.printf( - "SdkLib.UrlOpener: Failed to get proxy info for %s: %s\n", //$NON-NLS-1$ - url, e.toString()); - } - } - - boolean trying = true; - // loop while the response is being fetched - while (trying) { - // connect and get status code - HttpResponse response = httpClient.execute(httpGet, localContext); - int statusCode = response.getStatusLine().getStatusCode(); - - if (DEBUG) { - System.out.printf(" Status: %d\n", statusCode); //$NON-NLS-1$ - } - - // check whether any authentication is required - AuthState authenticationState = null; - if (statusCode == HttpStatus.SC_UNAUTHORIZED) { - // Target host authentication required - authenticationState = (AuthState) localContext - .getAttribute(ClientContext.TARGET_AUTH_STATE); - } - if (statusCode == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED) { - // Proxy authentication required - authenticationState = (AuthState) localContext - .getAttribute(ClientContext.PROXY_AUTH_STATE); - } - if (statusCode == HttpStatus.SC_OK || statusCode == HttpStatus.SC_NOT_MODIFIED) { - // in case the status is OK and there is a realm and result, - // cache it - if (realm != null && result != null) { - sRealmCache.put(realm, result); - } - } - - // there is the need for authentication - if (authenticationState != null) { - - // get scope and realm - AuthScope authScope = authenticationState.getAuthScope(); - - // If the current realm is different from the last one it means - // a pass was performed successfully to the last URL, therefore - // cache the last realm - if (realm != null && !realm.equals(authScope.getRealm())) { - sRealmCache.put(realm, result); - } - - realm = authScope.getRealm(); - - // in case there is cache for this Realm, use it to authenticate - if (sRealmCache.containsKey(realm)) { - result = sRealmCache.get(realm); - } else { - // since there is no cache, request for login and password - result = monitor.displayLoginCredentialsPrompt("Site Authentication", - "Please login to the following domain: " + realm + - "\n\nServer requiring authentication:\n" + authScope.getHost()); - if (result == null) { - throw new CanceledByUserException("User canceled login dialog."); - } - } - - // retrieve authentication data - String user = result.getUserName(); - String password = result.getPassword(); - String workstation = result.getWorkstation(); - String domain = result.getDomain(); - - // proceed in case there is indeed a user - if (user != null && user.length() > 0) { - Credentials credentials = new NTCredentials(user, password, - workstation, domain); - httpClient.getCredentialsProvider().setCredentials(authScope, credentials); - trying = true; - } else { - trying = false; - } - } else { - trying = false; - } - - HttpEntity entity = response.getEntity(); - - if (entity != null) { - if (trying) { - // in case another pass to the Http Client will be performed, close the entity. - entity.getContent().close(); - } else { - // since no pass to the Http Client is needed, retrieve the - // entity's content. - - // Note: don't use something like a BufferedHttpEntity since it would consume - // all content and store it in memory, resulting in an OutOfMemory exception - // on a large download. - InputStream is = new FilterInputStream(entity.getContent()) { - @Override - public void close() throws IOException { - // Since Http Client is no longer needed, close it. - - // Bug #21167: we need to tell http client to shutdown - // first, otherwise the super.close() would continue - // downloading and not return till complete. - - httpClient.getConnectionManager().shutdown(); - super.close(); - } - }; - - HttpResponse outResponse = new BasicHttpResponse(response.getStatusLine()); - outResponse.setHeaders(response.getAllHeaders()); - outResponse.setLocale(response.getLocale()); - - return Pair.of(is, outResponse); - } - } else if (statusCode == HttpStatus.SC_NOT_MODIFIED) { - // It's ok to not have an entity (e.g. nothing to download) for a 304 - HttpResponse outResponse = new BasicHttpResponse(response.getStatusLine()); - outResponse.setHeaders(response.getAllHeaders()); - outResponse.setLocale(response.getLocale()); - - return Pair.of(null, outResponse); - } - } - - // We get here if we did not succeed. Callers do not expect a null result. - httpClient.getConnectionManager().shutdown(); - throw new FileNotFoundException(url); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/UserCredentials.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/UserCredentials.java deleted file mode 100644 index 16aed79..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/UserCredentials.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -public class UserCredentials { - private final String mUserName; - private final String mPassword; - private final String mWorkstation; - private final String mDomain; - - public UserCredentials(String userName, String password, String workstation, String domain) { - mUserName = userName; - mPassword = password; - mWorkstation = workstation; - mDomain = domain; - } - - public String getUserName() { - return mUserName; - } - - public String getPassword() { - return mPassword; - } - - public String getWorkstation() { - return mWorkstation; - } - - public String getDomain() { - return mDomain; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/Archive.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/Archive.java deleted file mode 100755 index 508911f..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/Archive.java +++ /dev/null @@ -1,504 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.archives; - -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.io.FileOp; - -import java.io.File; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Locale; -import java.util.Properties; - - -/** - * A {@link Archive} is the base class for "something" that can be downloaded from - * the SDK repository. - * <p/> - * A package has some attributes (revision, description) and a list of archives - * which represent the downloadable bits. - * <p/> - * Packages are offered by a {@link SdkSource} (a download site). - * The {@link ArchiveInstaller} takes care of downloading, unpacking and installing an archive. - */ -public class Archive implements IDescription, Comparable<Archive> { - - private static final String PROP_OS = "Archive.Os"; //$NON-NLS-1$ - private static final String PROP_ARCH = "Archive.Arch"; //$NON-NLS-1$ - - /** The checksum type. */ - public enum ChecksumType { - /** A SHA1 checksum, represented as a 40-hex string. */ - SHA1("SHA-1"); //$NON-NLS-1$ - - private final String mAlgorithmName; - - /** - * Constructs a {@link ChecksumType} with the algorigth name - * suitable for {@link MessageDigest#getInstance(String)}. - * <p/> - * These names are officially documented at - * http://java.sun.com/javase/6/docs/technotes/guides/security/StandardNames.html#MessageDigest - */ - private ChecksumType(String algorithmName) { - mAlgorithmName = algorithmName; - } - - /** - * Returns a new {@link MessageDigest} instance for this checksum type. - * @throws NoSuchAlgorithmException if this algorithm is not available. - */ - public MessageDigest getMessageDigest() throws NoSuchAlgorithmException { - return MessageDigest.getInstance(mAlgorithmName); - } - } - - /** The OS that this archive can be downloaded on. */ - public enum Os { - ANY("Any"), - LINUX("Linux"), - MACOSX("MacOS X"), - WINDOWS("Windows"); - - private final String mUiName; - - private Os(String uiName) { - mUiName = uiName; - } - - /** Returns the UI name of the OS. */ - public String getUiName() { - return mUiName; - } - - /** Returns the XML name of the OS. */ - public String getXmlName() { - return toString().toLowerCase(Locale.US); - } - - /** - * Returns the current OS as one of the {@link Os} enum values or null. - */ - public static Os getCurrentOs() { - String os = System.getProperty("os.name"); //$NON-NLS-1$ - if (os.startsWith("Mac")) { //$NON-NLS-1$ - return Os.MACOSX; - - } else if (os.startsWith("Windows")) { //$NON-NLS-1$ - return Os.WINDOWS; - - } else if (os.startsWith("Linux")) { //$NON-NLS-1$ - return Os.LINUX; - } - - return null; - } - - /** Returns true if this OS is compatible with the current one. */ - public boolean isCompatible() { - if (this == ANY) { - return true; - } - - Os os = getCurrentOs(); - return this == os; - } - } - - /** The Architecture that this archive can be downloaded on. */ - public enum Arch { - ANY("Any"), - PPC("PowerPC"), - X86("x86"), - X86_64("x86_64"); - - private final String mUiName; - - private Arch(String uiName) { - mUiName = uiName; - } - - /** Returns the UI name of the architecture. */ - public String getUiName() { - return mUiName; - } - - /** Returns the XML name of the architecture. */ - public String getXmlName() { - return toString().toLowerCase(Locale.US); - } - - /** - * Returns the current architecture as one of the {@link Arch} enum values or null. - */ - public static Arch getCurrentArch() { - // Values listed from http://lopica.sourceforge.net/os.html - String arch = System.getProperty("os.arch"); - - if (arch.equalsIgnoreCase("x86_64") || arch.equalsIgnoreCase("amd64")) { - return Arch.X86_64; - - } else if (arch.equalsIgnoreCase("x86") - || arch.equalsIgnoreCase("i386") - || arch.equalsIgnoreCase("i686")) { - return Arch.X86; - - } else if (arch.equalsIgnoreCase("ppc") || arch.equalsIgnoreCase("PowerPC")) { - return Arch.PPC; - } - - return null; - } - - /** Returns true if this architecture is compatible with the current one. */ - public boolean isCompatible() { - if (this == ANY) { - return true; - } - - Arch arch = getCurrentArch(); - return this == arch; - } - } - - private final Os mOs; - private final Arch mArch; - private final String mUrl; - private final long mSize; - private final String mChecksum; - private final ChecksumType mChecksumType = ChecksumType.SHA1; - private final Package mPackage; - private final String mLocalOsPath; - private final boolean mIsLocal; - - /** - * Creates a new remote archive. - */ - public Archive(Package pkg, Os os, Arch arch, String url, long size, String checksum) { - mPackage = pkg; - mOs = os; - mArch = arch; - mUrl = url == null ? null : url.trim(); - mLocalOsPath = null; - mSize = size; - mChecksum = checksum; - mIsLocal = false; - } - - /** - * Creates a new local archive. - * Uses the properties from props first, if possible. Props can be null. - */ - @VisibleForTesting(visibility=Visibility.PACKAGE) - public Archive(Package pkg, Properties props, Os os, Arch arch, String localOsPath) { - mPackage = pkg; - - mOs = props == null ? os : Os.valueOf( props.getProperty(PROP_OS, os.toString())); - mArch = props == null ? arch : Arch.valueOf(props.getProperty(PROP_ARCH, arch.toString())); - - mUrl = null; - mLocalOsPath = localOsPath; - mSize = 0; - mChecksum = ""; - mIsLocal = localOsPath != null; - } - - /** - * Save the properties of the current archive in the give {@link Properties} object. - * These properties will later be give the constructor that takes a {@link Properties} object. - */ - void saveProperties(Properties props) { - props.setProperty(PROP_OS, mOs.toString()); - props.setProperty(PROP_ARCH, mArch.toString()); - } - - /** - * Returns true if this is a locally installed archive. - * Returns false if this is a remote archive that needs to be downloaded. - */ - public boolean isLocal() { - return mIsLocal; - } - - /** - * Returns the package that created and owns this archive. - * It should generally not be null. - */ - public Package getParentPackage() { - return mPackage; - } - - /** - * Returns the archive size, an int > 0. - * Size will be 0 if this a local installed folder of unknown size. - */ - public long getSize() { - return mSize; - } - - /** - * Returns the SHA1 archive checksum, as a 40-char hex. - * Can be empty but not null for local installed folders. - */ - public String getChecksum() { - return mChecksum; - } - - /** - * Returns the checksum type, always {@link ChecksumType#SHA1} right now. - */ - public ChecksumType getChecksumType() { - return mChecksumType; - } - - /** - * Returns the download archive URL, either absolute or relative to the repository xml. - * Always return null for a local installed folder. - * @see #getLocalOsPath() - */ - public String getUrl() { - return mUrl; - } - - /** - * Returns the local OS folder where a local archive is installed. - * Always return null for remote archives. - * @see #getUrl() - */ - public String getLocalOsPath() { - return mLocalOsPath; - } - - /** - * Returns the archive {@link Os} enum. - * Can be null for a local installed folder on an unknown OS. - */ - public Os getOs() { - return mOs; - } - - /** - * Returns the archive {@link Arch} enum. - * Can be null for a local installed folder on an unknown architecture. - */ - public Arch getArch() { - return mArch; - } - - /** - * Generates a description for this archive of the OS/Arch supported by this archive. - */ - public String getOsDescription() { - String os; - if (mOs == null) { - os = "unknown OS"; - } else if (mOs == Os.ANY) { - os = "any OS"; - } else { - os = mOs.getUiName(); - } - - String arch = ""; //$NON-NLS-1$ - if (mArch != null && mArch != Arch.ANY) { - arch = mArch.getUiName(); - } - - return String.format("%1$s%2$s%3$s", - os, - arch.length() > 0 ? " " : "", //$NON-NLS-2$ - arch); - } - - /** - * Returns the short description of the source, if not null. - * Otherwise returns the default Object toString result. - * <p/> - * This is mostly helpful for debugging. - * For UI display, use the {@link IDescription} interface. - */ - @Override - public String toString() { - String s = getShortDescription(); - if (s != null) { - return s; - } - return super.toString(); - } - - /** - * Generates a short description for this archive. - */ - @Override - public String getShortDescription() { - return String.format("Archive for %1$s", getOsDescription()); - } - - /** - * Generates a longer description for this archive. - */ - @Override - public String getLongDescription() { - return String.format("%1$s\n%2$s\n%3$s", - getShortDescription(), - getSizeDescription(), - getSha1Description()); - } - - public String getSizeDescription() { - long size = getSize(); - String sizeStr; - if (size < 1024) { - sizeStr = String.format("%d Bytes", size); - } else if (size < 1024 * 1024) { - sizeStr = String.format("%d KiB", Math.round(size / 1024.0)); - } else if (size < 1024 * 1024 * 1024) { - sizeStr = String.format("%.1f MiB", - Math.round(10.0 * size / (1024 * 1024.0))/ 10.0); - } else { - sizeStr = String.format("%.1f GiB", - Math.round(10.0 * size / (1024 * 1024 * 1024.0))/ 10.0); - } - - return String.format("Size: %1$s", sizeStr); - } - - public String getSha1Description() { - return String.format("SHA1: %1$s", getChecksum()); - } - - /** - * Returns true if this archive can be installed on the current platform. - */ - public boolean isCompatible() { - return getOs().isCompatible() && getArch().isCompatible(); - } - - /** - * Delete the archive folder if this is a local archive. - */ - public void deleteLocal() { - if (isLocal()) { - new FileOp().deleteFileOrFolder(new File(getLocalOsPath())); - } - } - - /** - * Archives are compared using their {@link Package} ordering. - * - * @see Package#compareTo(Package) - */ - @Override - public int compareTo(Archive rhs) { - if (mPackage != null && rhs != null) { - return mPackage.compareTo(rhs.getParentPackage()); - } - return 0; - } - - /** - * Note: An {@link Archive}'s hash code does NOT depend on the parent {@link Package} hash code. - * <p/> - * {@inheritDoc} - */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((mArch == null) ? 0 : mArch.hashCode()); - result = prime * result + ((mChecksum == null) ? 0 : mChecksum.hashCode()); - result = prime * result + ((mChecksumType == null) ? 0 : mChecksumType.hashCode()); - result = prime * result + (mIsLocal ? 1231 : 1237); - result = prime * result + ((mLocalOsPath == null) ? 0 : mLocalOsPath.hashCode()); - result = prime * result + ((mOs == null) ? 0 : mOs.hashCode()); - result = prime * result + (int) (mSize ^ (mSize >>> 32)); - result = prime * result + ((mUrl == null) ? 0 : mUrl.hashCode()); - return result; - } - - /** - * Note: An {@link Archive}'s equality does NOT depend on the parent {@link Package} equality. - * <p/> - * {@inheritDoc} - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Archive)) { - return false; - } - Archive other = (Archive) obj; - if (mArch == null) { - if (other.mArch != null) { - return false; - } - } else if (!mArch.equals(other.mArch)) { - return false; - } - if (mChecksum == null) { - if (other.mChecksum != null) { - return false; - } - } else if (!mChecksum.equals(other.mChecksum)) { - return false; - } - if (mChecksumType == null) { - if (other.mChecksumType != null) { - return false; - } - } else if (!mChecksumType.equals(other.mChecksumType)) { - return false; - } - if (mIsLocal != other.mIsLocal) { - return false; - } - if (mLocalOsPath == null) { - if (other.mLocalOsPath != null) { - return false; - } - } else if (!mLocalOsPath.equals(other.mLocalOsPath)) { - return false; - } - if (mOs == null) { - if (other.mOs != null) { - return false; - } - } else if (!mOs.equals(other.mOs)) { - return false; - } - if (mSize != other.mSize) { - return false; - } - if (mUrl == null) { - if (other.mUrl != null) { - return false; - } - } else if (!mUrl.equals(other.mUrl)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/ArchiveInstaller.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/ArchiveInstaller.java deleted file mode 100755 index 75e8912..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/ArchiveInstaller.java +++ /dev/null @@ -1,1167 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.archives; - -import com.android.SdkConstants; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.CanceledByUserException; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.io.FileOp; -import com.android.sdklib.io.IFileOp; -import com.android.sdklib.repository.RepoConstants; -import com.android.sdklib.util.GrabProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.IProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.Wait; -import com.android.utils.Pair; - -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.apache.commons.compress.archivers.zip.ZipFile; -import org.apache.http.Header; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.message.BasicHeader; - -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Pattern; - -/** - * Performs the work of installing a given {@link Archive}. - */ -public class ArchiveInstaller { - - private static final String PROP_STATUS_CODE = "StatusCode"; //$NON-NLS-1$ - public static final String ENV_VAR_IGNORE_COMPAT = "ANDROID_SDK_IGNORE_COMPAT"; //$NON-NLS-1$ - - public static final int NUM_MONITOR_INC = 100; - - /** The current {@link FileOp} to use. Never null. */ - private final IFileOp mFileOp; - - /** - * Generates an {@link ArchiveInstaller} that relies on the default {@link FileOp}. - */ - public ArchiveInstaller() { - mFileOp = new FileOp(); - } - - /** - * Generates an {@link ArchiveInstaller} that relies on the given {@link FileOp}. - * - * @param fileUtils An alternate version of {@link FileOp} to use for file operations. - */ - protected ArchiveInstaller(IFileOp fileUtils) { - mFileOp = fileUtils; - } - - /** Returns current {@link FileOp} to use. Never null. */ - protected IFileOp getFileOp() { - return mFileOp; - } - - /** - * Install this {@link ArchiveReplacement}s. - * A "replacement" is composed of the actual new archive to install - * (c.f. {@link ArchiveReplacement#getNewArchive()} and an <em>optional</em> - * archive being replaced (c.f. {@link ArchiveReplacement#getReplaced()}. - * In the case of a new install, the later should be null. - * <p/> - * The new archive to install will be skipped if it is incompatible. - * - * @return True if the archive was installed, false otherwise. - */ - public boolean install(ArchiveReplacement archiveInfo, - String osSdkRoot, - boolean forceHttp, - SdkManager sdkManager, - DownloadCache cache, - ITaskMonitor monitor) { - - Archive newArchive = archiveInfo.getNewArchive(); - Package pkg = newArchive.getParentPackage(); - - String name = pkg.getShortDescription(); - - if (newArchive.isLocal()) { - // This should never happen. - monitor.log("Skipping already installed archive: %1$s for %2$s", - name, - newArchive.getOsDescription()); - return false; - } - - // In detail mode, give us a way to force install of incompatible archives. - boolean checkIsCompatible = System.getenv(ENV_VAR_IGNORE_COMPAT) == null; - - if (checkIsCompatible && !newArchive.isCompatible()) { - monitor.log("Skipping incompatible archive: %1$s for %2$s", - name, - newArchive.getOsDescription()); - return false; - } - - Pair<File, File> files = downloadFile(newArchive, osSdkRoot, cache, monitor, forceHttp); - File tmpFile = files == null ? null : files.getFirst(); - File propsFile = files == null ? null : files.getSecond(); - if (tmpFile != null) { - // Unarchive calls the pre/postInstallHook methods. - if (unarchive(archiveInfo, osSdkRoot, tmpFile, sdkManager, monitor)) { - monitor.log("Installed %1$s", name); - // Delete the temp archive if it exists, only on success - mFileOp.deleteFileOrFolder(tmpFile); - mFileOp.deleteFileOrFolder(propsFile); - return true; - } - } - - return false; - } - - /** - * Downloads an archive and returns the temp file with it. - * Caller is responsible with deleting the temp file when done. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected Pair<File, File> downloadFile(Archive archive, - String osSdkRoot, - DownloadCache cache, - ITaskMonitor monitor, - boolean forceHttp) { - - String pkgName = archive.getParentPackage().getShortDescription(); - monitor.setDescription("Downloading %1$s", pkgName); - monitor.log("Downloading %1$s", pkgName); - - String link = archive.getUrl(); - if (!link.startsWith("http://") //$NON-NLS-1$ - && !link.startsWith("https://") //$NON-NLS-1$ - && !link.startsWith("ftp://")) { //$NON-NLS-1$ - // Make the URL absolute by prepending the source - Package pkg = archive.getParentPackage(); - SdkSource src = pkg.getParentSource(); - if (src == null) { - monitor.logError("Internal error: no source for archive %1$s", pkgName); - return null; - } - - // take the URL to the repository.xml and remove the last component - // to get the base - String repoXml = src.getUrl(); - int pos = repoXml.lastIndexOf('/'); - String base = repoXml.substring(0, pos + 1); - - link = base + link; - } - - if (forceHttp) { - link = link.replaceAll("https://", "http://"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - // Get the basename of the file we're downloading, i.e. the last component - // of the URL - int pos = link.lastIndexOf('/'); - String base = link.substring(pos + 1); - - // Rather than create a real temp file in the system, we simply use our - // temp folder (in the SDK base folder) and use the archive name for the - // download. This allows us to reuse or continue downloads. - - File tmpFolder = getTempFolder(osSdkRoot); - if (!mFileOp.isDirectory(tmpFolder)) { - if (mFileOp.isFile(tmpFolder)) { - mFileOp.deleteFileOrFolder(tmpFolder); - } - if (!mFileOp.mkdirs(tmpFolder)) { - monitor.logError("Failed to create directory %1$s", tmpFolder.getPath()); - return null; - } - } - File tmpFile = new File(tmpFolder, base); - - // property file were we'll keep partial/resume information for reuse. - File propsFile = new File(tmpFolder, base + ".inf"); //$NON-NLS-1$ - - // if the file exists, check its checksum & size. Use it if complete - if (mFileOp.exists(tmpFile)) { - if (mFileOp.length(tmpFile) == archive.getSize()) { - String chksum = ""; //$NON-NLS-1$ - try { - chksum = fileChecksum(archive.getChecksumType().getMessageDigest(), - tmpFile, - monitor); - } catch (NoSuchAlgorithmException e) { - // Ignore. - } - if (chksum.equalsIgnoreCase(archive.getChecksum())) { - // File is good, let's use it. - return Pair.of(tmpFile, propsFile); - } else { - // The file has the right size but the wrong content. - // Just remove it and this will trigger a full download below. - mFileOp.deleteFileOrFolder(tmpFile); - } - } - } - - Header[] resumeHeaders = preparePartialDownload(archive, tmpFile, propsFile); - - if (fetchUrl(archive, resumeHeaders, tmpFile, propsFile, link, pkgName, cache, monitor)) { - // Fetching was successful, let's use this file. - return Pair.of(tmpFile, propsFile); - } - return null; - } - - /** - * Prepares to do a partial/resume download. - * - * @param archive The archive we're trying to download. - * @param tmpFile The destination file to download (e.g. something.zip) - * @param propsFile A properties file generated by the last partial download (e.g. .zip.inf) - * @return Null in case we should perform a full download, or a set of headers - * to resume a partial download. - */ - private Header[] preparePartialDownload(Archive archive, File tmpFile, File propsFile) { - // We need both the destination file and its properties to do a resume. - if (mFileOp.isFile(tmpFile) && mFileOp.isFile(propsFile)) { - // The caller already checked the case were the destination file has the - // right size _and_ checksum, so we know at this point one of them is wrong - // here. - // We can obviously only resume a file if its size is smaller than expected. - if (mFileOp.length(tmpFile) < archive.getSize()) { - Properties props = mFileOp.loadProperties(propsFile); - - List<Header> headers = new ArrayList<Header>(2); - headers.add(new BasicHeader(HttpHeaders.RANGE, - String.format("bytes=%d-", mFileOp.length(tmpFile)))); - - // Don't use the properties if there's not at least a 200 or 206 code from - // the last download. - int status = 0; - try { - status = Integer.parseInt(props.getProperty(PROP_STATUS_CODE)); - } catch (Exception ignore) {} - - if (status == HttpStatus.SC_OK || status == HttpStatus.SC_PARTIAL_CONTENT) { - // Do we have an ETag and/or a Last-Modified? - String etag = props.getProperty(HttpHeaders.ETAG); - String lastMod = props.getProperty(HttpHeaders.LAST_MODIFIED); - - if (etag != null && etag.length() > 0) { - headers.add(new BasicHeader(HttpHeaders.IF_MATCH, etag)); - } else if (lastMod != null && lastMod.length() > 0) { - headers.add(new BasicHeader(HttpHeaders.IF_MATCH, lastMod)); - } - - return headers.toArray(new Header[headers.size()]); - } - } - } - - // Existing file is either of different size or content. - // Remove the existing file and request a full download. - mFileOp.deleteFileOrFolder(tmpFile); - mFileOp.deleteFileOrFolder(propsFile); - - return null; - } - - /** - * Computes the SHA-1 checksum of the content of the given file. - * Returns an empty string on error (rather than null). - */ - private String fileChecksum(MessageDigest digester, File tmpFile, ITaskMonitor monitor) { - InputStream is = null; - try { - is = new FileInputStream(tmpFile); - - byte[] buf = new byte[65536]; - int n; - - while ((n = is.read(buf)) >= 0) { - if (n > 0) { - digester.update(buf, 0, n); - } - } - - return getDigestChecksum(digester); - - } catch (FileNotFoundException e) { - // The FNF message is just the URL. Make it a bit more useful. - monitor.logError("File not found: %1$s", e.getMessage()); - - } catch (Exception e) { - monitor.logError("%1$s", e.getMessage()); //$NON-NLS-1$ - - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException e) { - // pass - } - } - } - - return ""; //$NON-NLS-1$ - } - - /** - * Returns the SHA-1 from a {@link MessageDigest} as an hex string - * that can be compared with {@link Archive#getChecksum()}. - */ - private String getDigestChecksum(MessageDigest digester) { - int n; - // Create an hex string from the digest - byte[] digest = digester.digest(); - n = digest.length; - String hex = "0123456789abcdef"; //$NON-NLS-1$ - char[] hexDigest = new char[n * 2]; - for (int i = 0; i < n; i++) { - int b = digest[i] & 0x0FF; - hexDigest[i*2 + 0] = hex.charAt(b >>> 4); - hexDigest[i*2 + 1] = hex.charAt(b & 0x0f); - } - - return new String(hexDigest); - } - - /** - * Actually performs the download. - * Also computes the SHA1 of the file on the fly. - * <p/> - * Success is defined as downloading as many bytes as was expected and having the same - * SHA1 as expected. Returns true on success or false if any of those checks fail. - * <p/> - * Increments the monitor by {@link #NUM_MONITOR_INC}. - * - * @param archive The archive we're trying to download. - * @param resumeHeaders The headers to use for a partial resume, or null when fetching - * a whole new file. - * @param tmpFile The destination file to download (e.g. something.zip) - * @param propsFile A properties file generated by the last partial download (e.g. .zip.inf) - * @param urlString The URL as a string - * @param pkgName The archive's package name, used for progress output. - * @param cache The {@link DownloadCache} instance to use. - * @param monitor The monitor to output the progress and errors. - * @return True if we fetched the file successfully. - * False if the download failed or was aborted. - */ - private boolean fetchUrl(Archive archive, - Header[] resumeHeaders, - File tmpFile, - File propsFile, - String urlString, - String pkgName, - DownloadCache cache, - ITaskMonitor monitor) { - - FileOutputStream os = null; - InputStream is = null; - int inc_remain = NUM_MONITOR_INC; - try { - Pair<InputStream, HttpResponse> result = - cache.openDirectUrl(urlString, resumeHeaders, monitor); - - is = result.getFirst(); - HttpResponse resp = result.getSecond(); - int status = resp.getStatusLine().getStatusCode(); - if (status == HttpStatus.SC_NOT_FOUND) { - throw new Exception("URL not found."); - } - if (is == null) { - throw new Exception("No content."); - } - - - Properties props = new Properties(); - props.setProperty(PROP_STATUS_CODE, Integer.toString(status)); - if (resp.containsHeader(HttpHeaders.ETAG)) { - props.setProperty(HttpHeaders.ETAG, - resp.getFirstHeader(HttpHeaders.ETAG).getValue()); - } - if (resp.containsHeader(HttpHeaders.LAST_MODIFIED)) { - props.setProperty(HttpHeaders.LAST_MODIFIED, - resp.getFirstHeader(HttpHeaders.LAST_MODIFIED).getValue()); - } - - mFileOp.saveProperties(propsFile, props, "## Android SDK Download."); //$NON-NLS-1$ - - // On success, status can be: - // - 206 (Partial content), if resumeHeaders is not null (we asked for a partial - // download, and we get partial content for that download => we'll need to append - // to the existing file.) - // - 200 (OK) meaning we're getting whole new content from scratch. This can happen - // even if resumeHeaders is not null (typically means the server has a new version - // of the file to serve.) In this case we reset the file and write from scratch. - - boolean append = status == HttpStatus.SC_PARTIAL_CONTENT; - if (status != HttpStatus.SC_OK && !(append && resumeHeaders != null)) { - throw new Exception(String.format("Unexpected HTTP Status %1$d", status)); - } - MessageDigest digester = archive.getChecksumType().getMessageDigest(); - - if (append) { - // Seed the digest with the existing content. - InputStream temp = null; - try { - temp = new FileInputStream(tmpFile); - - byte[] buf = new byte[65536]; - int n; - - while ((n = temp.read(buf)) >= 0) { - if (n > 0) { - digester.update(buf, 0, n); - } - } - } catch (Exception ignore) { - } finally { - if (temp != null) { - try { - temp.close(); - } catch (IOException ignore) {} - } - } - } - - // Open the output stream in append for a resume, or reset for a full download. - os = new FileOutputStream(tmpFile, append); - - byte[] buf = new byte[65536]; - int n; - - long total = 0; - long size = archive.getSize(); - if (append) { - long len = mFileOp.length(tmpFile); - int percent = (int) (len * 100 / size); - size -= len; - monitor.logVerbose( - "Resuming %1$s download at %2$d (%3$d%%)", pkgName, len, percent); - } - long inc = size / NUM_MONITOR_INC; - long next_inc = inc; - - long startMs = System.currentTimeMillis(); - long nextMs = startMs + 2000; // start update after 2 seconds - - while ((n = is.read(buf)) >= 0) { - if (n > 0) { - os.write(buf, 0, n); - digester.update(buf, 0, n); - } - - long timeMs = System.currentTimeMillis(); - - total += n; - if (total >= next_inc) { - monitor.incProgress(1); - inc_remain--; - next_inc += inc; - } - - if (timeMs > nextMs) { - long delta = timeMs - startMs; - if (total > 0 && delta > 0) { - // percent left to download - int percent = (int) (100 * total / size); - // speed in KiB/s - float speed = (float)total / (float)delta * (1000.f / 1024.f); - // time left to download the rest at the current KiB/s rate - int timeLeft = (speed > 1e-3) ? - (int)(((size - total) / 1024.0f) / speed) : - 0; - String timeUnit = "seconds"; - if (timeLeft > 120) { - timeUnit = "minutes"; - timeLeft /= 60; - } - - monitor.setDescription( - "Downloading %1$s (%2$d%%, %3$.0f KiB/s, %4$d %5$s left)", - pkgName, - percent, - speed, - timeLeft, - timeUnit); - } - nextMs = timeMs + 1000; // update every second - } - - if (monitor.isCancelRequested()) { - monitor.log("Download aborted by user at %1$d bytes.", total); - return false; - } - - } - - if (total != size) { - monitor.logError( - "Download finished with wrong size. Expected %1$d bytes, got %2$d bytes.", - size, total); - return false; - } - - // Create an hex string from the digest - String actual = getDigestChecksum(digester); - String expected = archive.getChecksum(); - if (!actual.equalsIgnoreCase(expected)) { - monitor.logError("Download finished with wrong checksum. Expected %1$s, got %2$s.", - expected, actual); - return false; - } - - return true; - - } catch (CanceledByUserException e) { - // HTTP Basic Auth or NTLM login was canceled by user. - // Don't output an error in the log. - - } catch (FileNotFoundException e) { - // The FNF message is just the URL. Make it a bit more useful. - monitor.logError("URL not found: %1$s", e.getMessage()); - - } catch (Exception e) { - monitor.logError("Download interrupted: %1$s", e.getMessage()); //$NON-NLS-1$ - - } finally { - if (os != null) { - try { - os.close(); - } catch (IOException e) { - // pass - } - } - - if (is != null) { - try { - is.close(); - } catch (IOException e) { - // pass - } - } - if (inc_remain > 0) { - monitor.incProgress(inc_remain); - } - } - - return false; - } - - /** - * Install the given archive in the given folder. - */ - private boolean unarchive(ArchiveReplacement archiveInfo, - String osSdkRoot, - File archiveFile, - SdkManager sdkManager, - ITaskMonitor monitor) { - boolean success = false; - Archive newArchive = archiveInfo.getNewArchive(); - Package pkg = newArchive.getParentPackage(); - String pkgName = pkg.getShortDescription(); - monitor.setDescription("Installing %1$s", pkgName); - monitor.log("Installing %1$s", pkgName); - - // Ideally we want to always unzip in a temp folder which name depends on the package - // type (e.g. addon, tools, etc.) and then move the folder to the destination folder. - // If the destination folder exists, it will be renamed and deleted at the very - // end if everything succeeded. This provides a nice atomic swap and should leave the - // original folder untouched in case something wrong (e.g. program crash) in the - // middle of the unzip operation. - // - // However that doesn't work on Windows, we always end up not being able to move the - // new folder. There are actually 2 cases: - // A- A process such as a the explorer is locking the *old* folder or a file inside - // (e.g. adb.exe) - // In this case we really shouldn't be tried to work around it and we need to let - // the user know and let it close apps that access that folder. - // B- A process is locking the *new* folder. Very often this turns to be a file indexer - // or an anti-virus that is busy scanning the new folder that we just unzipped. - // - // So we're going to change the strategy: - // 1- Try to move the old folder to a temp/old folder. This might fail in case of issue A. - // Note: for platform-tools, we can try killing adb first. - // If it still fails, we do nothing and ask the user to terminate apps that can be - // locking that folder. - // 2- Once the old folder is out of the way, we unzip the archive directly into the - // optimal new location. We no longer unzip it in a temp folder and move it since we - // know that's what fails in most of the cases. - // 3- If the unzip fails, remove everything and try to restore the old folder by doing - // a *copy* in place and not a folder move (which will likely fail too). - - String pkgKind = pkg.getClass().getSimpleName(); - - File destFolder = null; - File oldDestFolder = null; - - try { - // -0- Compute destination directory and check install pre-conditions - - destFolder = pkg.getInstallFolder(osSdkRoot, sdkManager); - - if (destFolder == null) { - // this should not seriously happen. - monitor.log("Failed to compute installation directory for %1$s.", pkgName); - return false; - } - - if (!pkg.preInstallHook(newArchive, monitor, osSdkRoot, destFolder)) { - monitor.log("Skipping archive: %1$s", pkgName); - return false; - } - - // -1- move old folder. - - if (mFileOp.exists(destFolder)) { - // Create a new temp/old dir - if (oldDestFolder == null) { - oldDestFolder = getNewTempFolder(osSdkRoot, pkgKind, "old"); //$NON-NLS-1$ - } - if (oldDestFolder == null) { - // this should not seriously happen. - monitor.logError("Failed to find a temp directory in %1$s.", osSdkRoot); - return false; - } - - // Try to move the current dest dir to the temp/old one. Tell the user if it failed. - while(true) { - if (!moveFolder(destFolder, oldDestFolder)) { - monitor.logError("Failed to rename directory %1$s to %2$s.", - destFolder.getPath(), oldDestFolder.getPath()); - - if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) { - boolean tryAgain = true; - - tryAgain = windowsDestDirLocked(osSdkRoot, destFolder, monitor); - - if (tryAgain) { - // loop, trying to rename the temp dir into the destination - continue; - } else { - return false; - } - } - } - break; - } - } - - assert !mFileOp.exists(destFolder); - - // -2- Unzip new content directly in place. - - if (!mFileOp.mkdirs(destFolder)) { - monitor.logError("Failed to create directory %1$s", destFolder.getPath()); - return false; - } - - if (!unzipFolder(archiveInfo, - archiveFile, - destFolder, - monitor)) { - return false; - } - - if (!generateSourceProperties(newArchive, destFolder)) { - monitor.logError("Failed to generate source.properties in directory %1$s", - destFolder.getPath()); - return false; - } - - // In case of success, if we were replacing an archive - // and the older one had a different path, remove it now. - Archive oldArchive = archiveInfo.getReplaced(); - if (oldArchive != null && oldArchive.isLocal()) { - String oldPath = oldArchive.getLocalOsPath(); - File oldFolder = oldPath == null ? null : new File(oldPath); - if (oldFolder == null && oldArchive.getParentPackage() != null) { - oldFolder = oldArchive.getParentPackage().getInstallFolder( - osSdkRoot, sdkManager); - } - if (oldFolder != null && mFileOp.exists(oldFolder) && - !oldFolder.equals(destFolder)) { - monitor.logVerbose("Removing old archive at %1$s", oldFolder.getAbsolutePath()); - mFileOp.deleteFileOrFolder(oldFolder); - } - } - - success = true; - pkg.postInstallHook(newArchive, monitor, destFolder); - return true; - - } finally { - if (!success) { - // In case of failure, we try to restore the old folder content. - if (oldDestFolder != null) { - restoreFolder(oldDestFolder, destFolder); - } - - // We also call the postInstallHool with a null directory to give a chance - // to the archive to cleanup after preInstallHook. - pkg.postInstallHook(newArchive, monitor, null /*installDir*/); - } - - // Cleanup if the unzip folder is still set. - mFileOp.deleteFileOrFolder(oldDestFolder); - } - } - - private boolean windowsDestDirLocked( - String osSdkRoot, - File destFolder, - final ITaskMonitor monitor) { - String msg = null; - - assert SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS; - - File findLockExe = FileOp.append( - osSdkRoot, SdkConstants.FD_TOOLS, SdkConstants.FD_LIB, SdkConstants.FN_FIND_LOCK); - - if (mFileOp.exists(findLockExe)) { - try { - final StringBuilder result = new StringBuilder(); - String command[] = new String[] { - findLockExe.getAbsolutePath(), - destFolder.getAbsolutePath() - }; - Process process = Runtime.getRuntime().exec(command); - int retCode = GrabProcessOutput.grabProcessOutput( - process, - Wait.WAIT_FOR_READERS, - new IProcessOutput() { - @Override - public void out(@Nullable String line) { - if (line != null) { - result.append(line).append("\n"); - } - } - - @Override - public void err(@Nullable String line) { - if (line != null) { - monitor.logError("[find_lock] Error: %1$s", line); - } - } - }); - - if (retCode == 0 && result.length() > 0) { - // TODO create a better dialog - - String found = result.toString().trim(); - monitor.logError("[find_lock] Directory locked by %1$s", found); - - TreeSet<String> apps = new TreeSet<String>(Arrays.asList( - found.split(Pattern.quote(";")))); //$NON-NLS-1$ - StringBuilder appStr = new StringBuilder(); - for (String app : apps) { - appStr.append("\n - ").append(app.trim()); //$NON-NLS-1$ - } - - msg = String.format( - "-= Warning ! =-\n" + - "The following processes: %1$s\n" + - "are locking the following directory: \n" + - " %2$s\n" + - "Please close these applications so that the installation can continue.\n" + - "When ready, press YES to try again.", - appStr.toString(), - destFolder.getPath()); - } - - } catch (Exception e) { - monitor.error(e, "[find_lock failed]"); - } - - - } - - if (msg == null) { - // Old way: simply display a generic text and let user figure it out. - msg = String.format( - "-= Warning ! =-\n" + - "A folder failed to be moved. On Windows this " + - "typically means that a program is using that folder (for " + - "example Windows Explorer or your anti-virus software.)\n" + - "Please momentarily deactivate your anti-virus software or " + - "close any running programs that may be accessing the " + - "directory '%1$s'.\n" + - "When ready, press YES to try again.", - destFolder.getPath()); - } - - boolean tryAgain = monitor.displayPrompt("SDK Manager: failed to install", msg); - return tryAgain; - } - - /** - * Tries to rename/move a folder. - * <p/> - * Contract: - * <ul> - * <li> When we start, oldDir must exist and be a directory. newDir must not exist. </li> - * <li> On successful completion, oldDir must not exists. - * newDir must exist and have the same content. </li> - * <li> On failure completion, oldDir must have the same content as before. - * newDir must not exist. </li> - * </ul> - * <p/> - * The simple "rename" operation on a folder can typically fail on Windows for a variety - * of reason, in fact as soon as a single process holds a reference on a directory. The - * most common case are the Explorer, the system's file indexer, Tortoise SVN cache or - * an anti-virus that are busy indexing a new directory having been created. - * - * @param oldDir The old location to move. It must exist and be a directory. - * @param newDir The new location where to move. It must not exist. - * @return True if the move succeeded. On failure, we try hard to not have touched the old - * directory in order not to loose its content. - */ - private boolean moveFolder(File oldDir, File newDir) { - // This is a simple folder rename that works on Linux/Mac all the time. - // - // On Windows this might fail if an indexer is busy looking at a new directory - // (e.g. right after we unzip our archive), so it fails let's be nice and give - // it a bit of time to succeed. - for (int i = 0; i < 5; i++) { - if (mFileOp.renameTo(oldDir, newDir)) { - return true; - } - try { - Thread.sleep(500 /*ms*/); - } catch (InterruptedException e) { - // ignore - } - } - - return false; - } - - /** - * Unzips a zip file into the given destination directory. - * - * The archive file MUST have a unique "root" folder. - * This root folder is skipped when unarchiving. - */ - @SuppressWarnings("unchecked") - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected boolean unzipFolder( - ArchiveReplacement archiveInfo, - File archiveFile, - File unzipDestFolder, - ITaskMonitor monitor) { - - Archive newArchive = archiveInfo.getNewArchive(); - Package pkg = newArchive.getParentPackage(); - String pkgName = pkg.getShortDescription(); - long compressedSize = newArchive.getSize(); - - ZipFile zipFile = null; - try { - zipFile = new ZipFile(archiveFile); - - // To advance the percent and the progress bar, we don't know the number of - // items left to unzip. However we know the size of the archive and the size of - // each uncompressed item. The zip file format overhead is negligible so that's - // a good approximation. - long incStep = compressedSize / NUM_MONITOR_INC; - long incTotal = 0; - long incCurr = 0; - int lastPercent = 0; - - byte[] buf = new byte[65536]; - - Enumeration<ZipArchiveEntry> entries = zipFile.getEntries(); - while (entries.hasMoreElements()) { - ZipArchiveEntry entry = entries.nextElement(); - - String name = entry.getName(); - - // ZipFile entries should have forward slashes, but not all Zip - // implementations can be expected to do that. - name = name.replace('\\', '/'); - - // Zip entries are always packages in a top-level directory - // (e.g. docs/index.html). However we want to use our top-level - // directory so we drop the first segment of the path name. - int pos = name.indexOf('/'); - if (pos < 0 || pos == name.length() - 1) { - continue; - } else { - name = name.substring(pos + 1); - } - - File destFile = new File(unzipDestFolder, name); - - if (name.endsWith("/")) { //$NON-NLS-1$ - // Create directory if it doesn't exist yet. This allows us to create - // empty directories. - if (!mFileOp.isDirectory(destFile) && !mFileOp.mkdirs(destFile)) { - monitor.logError("Failed to create directory %1$s", - destFile.getPath()); - return false; - } - continue; - } else if (name.indexOf('/') != -1) { - // Otherwise it's a file in a sub-directory. - // Make sure the parent directory has been created. - File parentDir = destFile.getParentFile(); - if (!mFileOp.isDirectory(parentDir)) { - if (!mFileOp.mkdirs(parentDir)) { - monitor.logError("Failed to create directory %1$s", - parentDir.getPath()); - return false; - } - } - } - - FileOutputStream fos = null; - long remains = entry.getSize(); - try { - fos = new FileOutputStream(destFile); - - // Java bug 4040920: do not rely on the input stream EOF and don't - // try to read more than the entry's size. - InputStream entryContent = zipFile.getInputStream(entry); - int n; - while (remains > 0 && - (n = entryContent.read( - buf, 0, (int) Math.min(remains, buf.length))) != -1) { - remains -= n; - if (n > 0) { - fos.write(buf, 0, n); - } - } - } catch (EOFException e) { - monitor.logError("Error uncompressing file %s. Size: %d bytes, Unwritten: %d bytes.", - entry.getName(), entry.getSize(), remains); - throw e; - } finally { - if (fos != null) { - fos.close(); - } - } - - pkg.postUnzipFileHook(newArchive, monitor, mFileOp, destFile, entry); - - // Increment progress bar to match. We update only between files. - for(incTotal += entry.getCompressedSize(); incCurr < incTotal; incCurr += incStep) { - monitor.incProgress(1); - } - - int percent = (int) (100 * incTotal / compressedSize); - if (percent != lastPercent) { - monitor.setDescription("Unzipping %1$s (%2$d%%)", pkgName, percent); - lastPercent = percent; - } - - if (monitor.isCancelRequested()) { - return false; - } - } - - return true; - - } catch (IOException e) { - monitor.logError("Unzip failed: %1$s", e.getMessage()); - - } finally { - if (zipFile != null) { - try { - zipFile.close(); - } catch (IOException e) { - // pass - } - } - } - - return false; - } - - /** - * Returns an unused temp folder path in the form of osBasePath/temp/prefix.suffixNNN. - * <p/> - * This does not actually <em>create</em> the folder. It just scan the base path for - * a free folder name to use and returns the file to use to reference it. - * <p/> - * This operation is not atomic so there's no guarantee the folder can't get - * created in between. This is however unlikely and the caller can assume the - * returned folder does not exist yet. - * <p/> - * Returns null if no such folder can be found (e.g. if all candidates exist, - * which is rather unlikely) or if the base temp folder cannot be created. - */ - private File getNewTempFolder(String osBasePath, String prefix, String suffix) { - File baseTempFolder = getTempFolder(osBasePath); - - if (!mFileOp.isDirectory(baseTempFolder)) { - if (mFileOp.isFile(baseTempFolder)) { - mFileOp.deleteFileOrFolder(baseTempFolder); - } - if (!mFileOp.mkdirs(baseTempFolder)) { - return null; - } - } - - for (int i = 1; i < 100; i++) { - File folder = new File(baseTempFolder, - String.format("%1$s.%2$s%3$02d", prefix, suffix, i)); //$NON-NLS-1$ - if (!mFileOp.exists(folder)) { - return folder; - } - } - return null; - } - - /** - * Returns the single fixed "temp" folder used by the SDK Manager. - * This folder is always at osBasePath/temp. - * <p/> - * This does not actually <em>create</em> the folder. - */ - private File getTempFolder(String osBasePath) { - File baseTempFolder = new File(osBasePath, RepoConstants.FD_TEMP); - return baseTempFolder; - } - - /** - * Generates a source.properties in the destination folder that contains all the infos - * relevant to this archive, this package and the source so that we can reload them - * locally later. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected boolean generateSourceProperties(Archive archive, File unzipDestFolder) { - Properties props = new Properties(); - - archive.saveProperties(props); - - Package pkg = archive.getParentPackage(); - if (pkg != null) { - pkg.saveProperties(props); - } - - return mFileOp.saveProperties( - new File(unzipDestFolder, SdkConstants.FN_SOURCE_PROP), - props, - "## Android Tool: Source of this archive."); //$NON-NLS-1$ - } - - /** - * Recursively restore srcFolder into destFolder by performing a copy of the file - * content rather than rename/moves. - * - * @param srcFolder The source folder to restore. - * @param destFolder The destination folder where to restore. - * @return True if the folder was successfully restored, false if it was not at all or - * only partially restored. - */ - private boolean restoreFolder(File srcFolder, File destFolder) { - boolean result = true; - - // Process sub-folders first - File[] srcFiles = mFileOp.listFiles(srcFolder); - if (srcFiles == null) { - // Source does not exist. That is quite odd. - return false; - } - - if (mFileOp.isFile(destFolder)) { - if (!mFileOp.delete(destFolder)) { - // There's already a file in there where we want a directory and - // we can't delete it. This is rather unexpected. Just give up on - // that folder. - return false; - } - } else if (!mFileOp.isDirectory(destFolder)) { - mFileOp.mkdirs(destFolder); - } - - // Get all the files and dirs of the current destination. - // We are not going to clean up the destination first. - // Instead we'll copy over and just remove any remaining files or directories. - Set<File> destDirs = new HashSet<File>(); - Set<File> destFiles = new HashSet<File>(); - File[] files = mFileOp.listFiles(destFolder); - if (files != null) { - for (File f : files) { - if (mFileOp.isDirectory(f)) { - destDirs.add(f); - } else { - destFiles.add(f); - } - } - } - - // First restore all source directories. - for (File dir : srcFiles) { - if (mFileOp.isDirectory(dir)) { - File d = new File(destFolder, dir.getName()); - destDirs.remove(d); - if (!restoreFolder(dir, d)) { - result = false; - } - } - } - - // Remove any remaining directories not processed above. - for (File dir : destDirs) { - mFileOp.deleteFileOrFolder(dir); - } - - // Copy any source files over to the destination. - for (File file : srcFiles) { - if (mFileOp.isFile(file)) { - File f = new File(destFolder, file.getName()); - destFiles.remove(f); - try { - mFileOp.copyFile(file, f); - } catch (IOException e) { - result = false; - } - } - } - - // Remove any remaining files not processed above. - for (File file : destFiles) { - mFileOp.deleteFileOrFolder(file); - } - - return result; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/ArchiveReplacement.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/ArchiveReplacement.java deleted file mode 100755 index b6570db..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/archives/ArchiveReplacement.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.archives; - -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.packages.Package; - - -/** - * Represents an archive that we want to install and the archive that it is - * going to replace, if any. - */ -public class ArchiveReplacement implements IDescription { - - private final Archive mNewArchive; - private final Archive mReplaced; - - /** - * Creates a new replacement where the {@code newArchive} will replace the - * currently installed {@code replaced} archive. - * When {@code newArchive} is not intended to replace anything (e.g. because - * the user is installing a new package not present on her system yet), then - * {@code replace} shall be null. - * - * @param newArchive A "new archive" to be installed. This is always an archive - * that comes from a remote site. This <em>may</em> be null. - * @param replaced An optional local archive that the new one will replace. - * Can be null if this archive does not replace anything. - */ - public ArchiveReplacement(Archive newArchive, Archive replaced) { - mNewArchive = newArchive; - mReplaced = replaced; - } - - /** - * Returns the "new archive" to be installed. - * This <em>may</em> be null for missing archives. - */ - public Archive getNewArchive() { - return mNewArchive; - } - - /** - * Returns an optional local archive that the new one will replace. - * Can be null if this archive does not replace anything. - */ - public Archive getReplaced() { - return mReplaced; - } - - /** - * Returns the long description of the parent package of the new archive, if not null. - * Otherwise returns an empty string. - */ - @Override - public String getLongDescription() { - if (mNewArchive != null) { - Package p = mNewArchive.getParentPackage(); - if (p != null) { - return p.getLongDescription(); - } - } - return ""; - } - - /** - * Returns the short description of the parent package of the new archive, if not null. - * Otherwise returns an empty string. - */ - @Override - public String getShortDescription() { - if (mNewArchive != null) { - Package p = mNewArchive.getParentPackage(); - if (p != null) { - return p.getShortDescription(); - } - } - return ""; - } - - /** - * Returns the short description of the parent package of the new archive, if not null. - * Otherwise returns the default Object toString result. - * <p/> - * This is mostly helpful for debugging. For UI display, use the {@link IDescription} - * interface. - */ - @Override - public String toString() { - if (mNewArchive != null) { - Package p = mNewArchive.getParentPackage(); - if (p != null) { - return p.getShortDescription(); - } - } - return super.toString(); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/AddonPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/AddonPackage.java deleted file mode 100755 index a388f54..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/AddonPackage.java +++ /dev/null @@ -1,699 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.IAndroidTarget.IOptionalLibrary; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkAddonConstants; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.utils.Pair; - -import org.w3c.dom.Node; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; - -/** - * Represents an add-on XML node in an SDK repository. - */ -public class AddonPackage extends MajorRevisionPackage - implements IAndroidVersionProvider, IPlatformDependency, - IExactApiLevelDependency, ILayoutlibVersion { - - private final String mVendorId; - private final String mVendorDisplay; - private final String mNameId; - private final String mDisplayName; - private final AndroidVersion mVersion; - - /** - * The helper handling the layoutlib version. - */ - private final LayoutlibVersionMixin mLayoutlibVersion; - - /** An add-on library. */ - public static class Lib { - private final String mName; - private final String mDescription; - - public Lib(String name, String description) { - mName = name; - mDescription = description; - } - - public String getName() { - return mName; - } - - public String getDescription() { - return mDescription; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((mDescription == null) ? 0 : mDescription.hashCode()); - result = prime * result + ((mName == null) ? 0 : mName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Lib)) { - return false; - } - Lib other = (Lib) obj; - if (mDescription == null) { - if (other.mDescription != null) { - return false; - } - } else if (!mDescription.equals(other.mDescription)) { - return false; - } - if (mName == null) { - if (other.mName != null) { - return false; - } - } else if (!mName.equals(other.mName)) { - return false; - } - return true; - } - } - - private final Lib[] mLibs; - - /** - * Creates a new add-on package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public AddonPackage( - SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - // --- name id/display --- - // addon-4.xsd introduces the name-id, name-display, vendor-id and vendor-display. - // These are not optional but we still need to support a fallback for older addons - // that only provide name and vendor. If the addon provides neither set of fields, - // it will simply not work as expected. - - String nameId = PackageParserUtils.getXmlString(packageNode, - SdkRepoConstants.NODE_NAME_ID); - String nameDisp = PackageParserUtils.getXmlString(packageNode, - SdkRepoConstants.NODE_NAME_DISPLAY); - String name = PackageParserUtils.getXmlString(packageNode, - SdkRepoConstants.NODE_NAME); - - // The old <name> is equivalent to the new <name-display> - if (nameDisp.length() == 0) { - nameDisp = name; - } - - // For a missing id, we simply use a sanitized version of the display name - if (nameId.length() == 0) { - nameId = sanitizeDisplayToNameId(name.length() > 0 ? name : nameDisp); - } - - assert nameId.length() > 0; - assert nameDisp.length() > 0; - - mNameId = nameId.trim(); - mDisplayName = nameDisp.trim(); - - // --- vendor id/display --- - // Same processing for vendor id vs display - - String vendorId = PackageParserUtils.getXmlString(packageNode, - SdkAddonConstants.NODE_VENDOR_ID); - String vendorDisp = PackageParserUtils.getXmlString(packageNode, - SdkAddonConstants.NODE_VENDOR_DISPLAY); - String vendor = PackageParserUtils.getXmlString(packageNode, - SdkAddonConstants.NODE_VENDOR); - - // The old <vendor> is equivalent to the new <vendor-display> - if (vendorDisp.length() == 0) { - vendorDisp = vendor; - } - - // For a missing id, we simply use a sanitized version of the display vendor - if (vendorId.length() == 0) { - boolean hasVendor = vendor.length() > 0; - vendorId = sanitizeDisplayToNameId(hasVendor ? vendor : vendorDisp); - } - - assert vendorId.length() > 0; - assert vendorDisp.length() > 0; - - mVendorId = vendorId.trim(); - mVendorDisplay = vendorDisp.trim(); - - // --- other attributes - - int apiLevel = - PackageParserUtils.getXmlInt(packageNode, SdkAddonConstants.NODE_API_LEVEL, 0); - mVersion = new AndroidVersion(apiLevel, null /*codeName*/); - - mLibs = parseLibs( - PackageParserUtils.findChildElement(packageNode, SdkAddonConstants.NODE_LIBS)); - - mLayoutlibVersion = new LayoutlibVersionMixin(packageNode); - } - - /** - * Creates a new platform package based on an actual {@link IAndroidTarget} (which - * {@link IAndroidTarget#isPlatform()} false) from the {@link SdkManager}. - * This is used to list local SDK folders in which case there is one archive which - * URL is the actual target location. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public static Package create(IAndroidTarget target, Properties props) { - return new AddonPackage(target, props); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected AddonPackage(IAndroidTarget target, Properties props) { - this(null /*source*/, target, props); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected AddonPackage(SdkSource source, IAndroidTarget target, Properties props) { - super( source, //source - props, //properties - target.getRevision(), //revision - null, //license - target.getDescription(), //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - target.getLocation() //archiveOsPath - ); - - // --- name id/display --- - // addon-4.xsd introduces the name-id, name-display, vendor-id and vendor-display. - // These are not optional but we still need to support a fallback for older addons - // that only provide name and vendor. If the addon provides neither set of fields, - // it will simply not work as expected. - - String nameId = getProperty(props, PkgProps.ADDON_NAME_ID, ""); //$NON-NLS-1$ - String nameDisp = getProperty(props, PkgProps.ADDON_NAME_DISPLAY, ""); //$NON-NLS-1$ - String name = getProperty(props, PkgProps.ADDON_NAME, target.getName()); - - // The old <name> is equivalent to the new <name-display> - if (nameDisp.length() == 0) { - nameDisp = name; - } - - // For a missing id, we simply use a sanitized version of the display name - if (nameId.length() == 0) { - nameId = sanitizeDisplayToNameId(name.length() > 0 ? name : nameDisp); - } - - assert nameId.length() > 0; - assert nameDisp.length() > 0; - - mNameId = nameId.trim(); - mDisplayName = nameDisp.trim(); - - // --- vendor id/display --- - // Same processing for vendor id vs display - - String vendorId = getProperty(props, PkgProps.ADDON_VENDOR_ID, ""); //$NON-NLS-1$ - String vendorDisp = getProperty(props, PkgProps.ADDON_VENDOR_DISPLAY, ""); //$NON-NLS-1$ - String vendor = getProperty(props, PkgProps.ADDON_VENDOR, target.getVendor()); - - // The old <vendor> is equivalent to the new <vendor-display> - if (vendorDisp.length() == 0) { - vendorDisp = vendor; - } - - // For a missing id, we simply use a sanitized version of the display vendor - if (vendorId.length() == 0) { - boolean hasVendor = vendor.length() > 0; - vendorId = sanitizeDisplayToNameId(hasVendor ? vendor : vendorDisp); - } - - assert vendorId.length() > 0; - assert vendorDisp.length() > 0; - - mVendorId = vendorId.trim(); - mVendorDisplay = vendorDisp.trim(); - - // --- other attributes - - mVersion = target.getVersion(); - mLayoutlibVersion = new LayoutlibVersionMixin(props); - - IOptionalLibrary[] optLibs = target.getOptionalLibraries(); - if (optLibs == null || optLibs.length == 0) { - mLibs = new Lib[0]; - } else { - mLibs = new Lib[optLibs.length]; - for (int i = 0; i < optLibs.length; i++) { - mLibs[i] = new Lib(optLibs[i].getName(), optLibs[i].getDescription()); - } - } - } - - /** - * Creates a broken addon which we know failed to load properly. - * - * @param archiveOsPath The absolute OS path of the addon folder. - * @param sourceProps The properties parsed from the addon's source.properties. Can be null. - * @param addonProps The properties parsed from the addon manifest (NOT the source.properties). - * @param error The error indicating why this addon failed to be loaded. - */ - public static Package createBroken( - String archiveOsPath, - Properties sourceProps, - Map<String, String> addonProps, - String error) { - String name = getProperty(sourceProps, - PkgProps.ADDON_NAME_DISPLAY, - getProperty(sourceProps, - PkgProps.ADDON_NAME, - addonProps.get(SdkManager.ADDON_NAME))); - String vendor = getProperty(sourceProps, - PkgProps.ADDON_VENDOR_DISPLAY, - getProperty(sourceProps, - PkgProps.ADDON_VENDOR, - addonProps.get(SdkManager.ADDON_VENDOR))); - String api = addonProps.get(SdkManager.ADDON_API); - String revision = addonProps.get(SdkManager.ADDON_REVISION); - - String shortDesc = String.format("%1$s by %2$s, Android API %3$s, revision %4$s [*]", - name, - vendor, - api, - revision); - - String longDesc = String.format( - "%1$s\n" + - "[*] Addon failed to load: %2$s", - shortDesc, - error); - - int apiLevel = IExactApiLevelDependency.API_LEVEL_INVALID; - - try { - apiLevel = Integer.parseInt(api); - } catch(NumberFormatException e) { - // ignore - } - - return new BrokenPackage(null/*props*/, shortDesc, longDesc, - IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED, - apiLevel, - archiveOsPath); - } - - @Override - public int getExactApiLevel() { - return mVersion.getApiLevel(); - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be given to a constructor that takes a {@link Properties} object. - */ - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - mVersion.saveProperties(props); - mLayoutlibVersion.saveProperties(props); - - props.setProperty(PkgProps.ADDON_NAME_ID, mNameId); - props.setProperty(PkgProps.ADDON_NAME_DISPLAY, mDisplayName); - props.setProperty(PkgProps.ADDON_VENDOR_ID, mVendorId); - props.setProperty(PkgProps.ADDON_VENDOR_DISPLAY, mVendorDisplay); - } - - /** - * Parses a <libs> element. - */ - private Lib[] parseLibs(Node libsNode) { - ArrayList<Lib> libs = new ArrayList<Lib>(); - - if (libsNode != null) { - String nsUri = libsNode.getNamespaceURI(); - for(Node child = libsNode.getFirstChild(); - child != null; - child = child.getNextSibling()) { - - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI()) && - SdkRepoConstants.NODE_LIB.equals(child.getLocalName())) { - libs.add(parseLib(child)); - } - } - } - - return libs.toArray(new Lib[libs.size()]); - } - - /** - * Parses a <lib> element from a <libs> container. - */ - private Lib parseLib(Node libNode) { - return new Lib(PackageParserUtils.getXmlString(libNode, SdkRepoConstants.NODE_NAME), - PackageParserUtils.getXmlString(libNode, SdkRepoConstants.NODE_DESCRIPTION)); - } - - /** Returns the vendor id, a string, for add-on packages. */ - public @NonNull String getVendorId() { - return mVendorId; - } - - /** Returns the vendor, a string for display purposes. */ - public @NonNull String getDisplayVendor() { - return mVendorDisplay; - } - - /** Returns the name id, a string, for add-on packages or for libraries. */ - public @NonNull String getNameId() { - return mNameId; - } - - /** Returns the name, a string for display purposes. */ - public @NonNull String getDisplayName() { - return mDisplayName; - } - - /** - * Returns the version of the platform dependency of this package. - * <p/> - * An add-on has the same {@link AndroidVersion} as the platform it depends on. - */ - @Override @NonNull - public AndroidVersion getAndroidVersion() { - return mVersion; - } - - /** Returns the libs defined in this add-on. Can be an empty array but not null. */ - public @NonNull Lib[] getLibs() { - return mLibs; - } - - /** - * Returns the layoutlib version. - * <p/> - * The first integer is the API of layoublib, which should be > 0. - * It will be equal to {@link ILayoutlibVersion#LAYOUTLIB_API_NOT_SPECIFIED} (0) - * if the layoutlib version isn't specified. - * <p/> - * The second integer is the revision for that given API. It is >= 0 - * and works as a minor revision number, incremented for the same API level. - * - * @since sdk-addon-2.xsd - */ - @Override - public @NonNull Pair<Integer, Integer> getLayoutlibVersion() { - return mLayoutlibVersion.getLayoutlibVersion(); - } - - /** - * Returns a string identifier to install this package from the command line. - * For add-ons, we use "addon-vendor-name-N" where N is the base platform API. - * <p/> - * {@inheritDoc} - */ - @Override - public @NonNull String installId() { - return encodeAddonName(); - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - return String.format("%1$s%2$s", - getDisplayName(), - isObsolete() ? " (Obsolete)" : ""); - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - return String.format("%1$s, Android API %2$s, revision %3$s%4$s", - getDisplayName(), - mVersion.getApiString(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description is whatever the XML contains for the <description> field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - String s = String.format("%1$s, Android API %2$s, revision %3$s%4$s\nBy %5$s", - getDisplayName(), - mVersion.getApiString(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : "", //$NON-NLS-2$ - getDisplayVendor()); - - String d = getDescription(); - if (d != null && d.length() > 0) { - s += '\n' + d; - } - - s += String.format("\nRequires SDK Platform Android API %1$s", - mVersion.getApiString()); - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * An add-on package is typically installed in SDK/add-ons/"addon-name"-"api-level". - * The name needs to be sanitized to be acceptable as a directory name. - * However if we can find a different directory under SDK/add-ons that already - * has this add-ons installed, we'll use that one. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - File addons = new File(osSdkRoot, SdkConstants.FD_ADDONS); - - // First find if this add-on is already installed. If so, reuse the same directory. - for (IAndroidTarget target : sdkManager.getTargets()) { - if (!target.isPlatform() && target.getVersion().equals(mVersion)) { - // Starting with addon-4.xsd, the addon source.properties differentiate - // between ids and display strings. However the addon target which relies - // on the manifest.ini does not so we need to cover both cases. - // TODO fix when we get rid of manifest.ini for addons - if ((target.getName().equals(getNameId()) && - target.getVendor().equals(getVendorId())) || - (target.getName().equals(getDisplayName()) && - target.getVendor().equals(getDisplayVendor()))) { - return new File(target.getLocation()); - } - } - } - - // Compute a folder directory using the addon declared name and vendor strings. - String name = encodeAddonName(); - - for (int i = 0; i < 100; i++) { - String name2 = i == 0 ? name : String.format("%s-%d", name, i); //$NON-NLS-1$ - File folder = new File(addons, name2); - if (!folder.exists()) { - return folder; - } - } - - // We shouldn't really get here. I mean, seriously, we tried hard enough. - return null; - } - - private String encodeAddonName() { - String name = String.format("addon-%s-%s-%s", //$NON-NLS-1$ - getNameId(), getVendorId(), mVersion.getApiString()); - name = name.toLowerCase(Locale.US); - name = name.replaceAll("[^a-z0-9_-]+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - name = name.replaceAll("_+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - return name; - } - - /** - * Computes a sanitized name-id based on an addon name-display. - * This is used to provide compatibility with older addons that lacks the new fields. - * - * @param displayName A name-display field or a old-style name field. - * @return A non-null sanitized name-id that fits in the {@code [a-zA-Z0-9_-]+} pattern. - */ - private String sanitizeDisplayToNameId(String displayName) { - String name = displayName.toLowerCase(Locale.US); - name = name.replaceAll("[^a-z0-9_-]+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - name = name.replaceAll("_+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - - // Trim leading and trailing underscores - if (name.length() > 1) { - name = name.replaceAll("^_+", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (name.length() > 1) { - name = name.replaceAll("_+$", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - return name; - } - - @Override - public boolean sameItemAs(Package pkg) { - if (pkg instanceof AddonPackage) { - AddonPackage newPkg = (AddonPackage)pkg; - - // check they are the same add-on. - if (getNameId().equals(newPkg.getNameId()) && - getAndroidVersion().equals(newPkg.getAndroidVersion())) { - // Check the vendor-id field. - if (getVendorId().equals(newPkg.getVendorId())) { - return true; - } - - // When loading addons from the v3 schema that only had a <vendor> - // field, the vendor field has been converted to vendor-display so - // as a transition mechanism we should test this also. - // TODO: in a couple iterations of the SDK Manager, remove this check - // and only compare using the vendor-id field. - return getDisplayVendor().equals(newPkg.getDisplayVendor()); - } - } - - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((mLayoutlibVersion == null) ? 0 : mLayoutlibVersion.hashCode()); - result = prime * result + Arrays.hashCode(mLibs); - result = prime * result + ((mDisplayName == null) ? 0 : mDisplayName.hashCode()); - result = prime * result + ((mVendorDisplay == null) ? 0 : mVendorDisplay.hashCode()); - result = prime * result + ((mVersion == null) ? 0 : mVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof AddonPackage)) { - return false; - } - AddonPackage other = (AddonPackage) obj; - if (mLayoutlibVersion == null) { - if (other.mLayoutlibVersion != null) { - return false; - } - } else if (!mLayoutlibVersion.equals(other.mLayoutlibVersion)) { - return false; - } - if (!Arrays.equals(mLibs, other.mLibs)) { - return false; - } - if (mNameId == null) { - if (other.mNameId != null) { - return false; - } - } else if (!mNameId.equals(other.mNameId)) { - return false; - } - if (mVendorId == null) { - if (other.mVendorId != null) { - return false; - } - } else if (!mVendorId.equals(other.mVendorId)) { - return false; - } - if (mVersion == null) { - if (other.mVersion != null) { - return false; - } - } else if (!mVersion.equals(other.mVersion)) { - return false; - } - return true; - } - - /** - * For addon packages, we want to add vendor|name to the sorting key - * <em>before<em/> the revision number. - * <p/> - * {@inheritDoc} - */ - @Override - protected String comparisonKey() { - String s = super.comparisonKey(); - int pos = s.indexOf("|r:"); //$NON-NLS-1$ - assert pos > 0; - s = s.substring(0, pos) + - "|vid:" + getVendorId() + //$NON-NLS-1$ - "|nid:" + getNameId() + //$NON-NLS-1$ - s.substring(pos); - return s; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/BrokenPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/BrokenPackage.java deleted file mode 100755 index e2c11a0..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/BrokenPackage.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; - -import java.io.File; -import java.util.Properties; - -/** - * Represents an SDK repository package that is incomplete. - * It has a distinct icon and a specific error that is supposed to help the user on how to fix it. - */ -public class BrokenPackage extends MajorRevisionPackage - implements IExactApiLevelDependency, IMinApiLevelDependency { - - /** - * The minimal API level required by this package, if > 0, - * or {@link #MIN_API_LEVEL_NOT_SPECIFIED} if there is no such requirement. - */ - private final int mMinApiLevel; - - /** - * The exact API level required by this package, if > 0, - * or {@link #API_LEVEL_INVALID} if there is no such requirement. - */ - private final int mExactApiLevel; - - private final String mShortDescription; - private final String mLongDescription; - - /** - * Creates a new "broken" package that represents a package that we failed to load, - * for whatever error indicated in {@code longDescription}. - * There is also an <em>optional</em> API level dependency that can be specified. - * <p/> - * By design, this creates a package with one and only one archive. - */ - BrokenPackage(Properties props, - String shortDescription, - String longDescription, - int minApiLevel, - int exactApiLevel, - String archiveOsPath) { - super( null, //source - props, //properties - 0, //revision will be taken from props - null, //license - longDescription, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - archiveOsPath //archiveOsPath - ); - mShortDescription = shortDescription; - mLongDescription = longDescription; - mMinApiLevel = minApiLevel; - mExactApiLevel = exactApiLevel; - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be given to a constructor that takes a {@link Properties} object. - * <p/> - * Base implementation override: We don't actually save properties for a broken package. - */ - @Override - public void saveProperties(Properties props) { - // Nop. We don't actually save properties for a broken package. - } - - /** - * Returns the minimal API level required by this package, if > 0, - * or {@link #MIN_API_LEVEL_NOT_SPECIFIED} if there is no such requirement. - */ - @Override - public int getMinApiLevel() { - return mMinApiLevel; - } - - /** - * Returns the exact API level required by this package, if > 0, - * or {@link #API_LEVEL_INVALID} if the value was missing. - */ - @Override - public int getExactApiLevel() { - return mExactApiLevel; - } - - /** - * Returns a string identifier to install this package from the command line. - * For broken packages, we return an empty string. These are not installable. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - return ""; //$NON-NLS-1$ - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - return mShortDescription; - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - return mShortDescription; - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description uses what was given to the constructor. - * If it's missing, it will use whatever the XML contains for the <description> field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - - String s = mLongDescription; - if (s != null && s.length() != 0) { - return s; - } - - s = getDescription(); - if (s != null && s.length() != 0) { - return s; - } - return getShortDescription(); - } - - /** - * We should not be attempting to install a broken package. - * - * {@inheritDoc} - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - // We should not be attempting to install a broken package. - return null; - } - - @Override - public boolean sameItemAs(Package pkg) { - if (pkg instanceof BrokenPackage) { - return mShortDescription.equals(((BrokenPackage) pkg).mShortDescription) && - getDescription().equals(pkg.getDescription()) && - getMinApiLevel() == ((BrokenPackage) pkg).getMinApiLevel(); - } - - return false; - } - - @Override - public boolean preInstallHook(Archive archive, - ITaskMonitor monitor, - String osSdkRoot, - File installFolder) { - // Nothing specific to do. - return super.preInstallHook(archive, monitor, osSdkRoot, installFolder); - } - - /** - * Computes a hash of the installed content (in case of successful install.) - * - * {@inheritDoc} - */ - @Override - public void postInstallHook(Archive archive, ITaskMonitor monitor, File installFolder) { - // Nothing specific to do. - super.postInstallHook(archive, monitor, installFolder); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/DocPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/DocPackage.java deleted file mode 100755 index 927d361..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/DocPackage.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Node; - -import java.io.File; -import java.util.Map; -import java.util.Properties; - -/** - * Represents a doc XML node in an SDK repository. - * <p/> - * Note that a doc package has a version and thus implements {@link IAndroidVersionProvider}. - * However there is no mandatory dependency that limits installation so this does not - * implement {@link IPlatformDependency}. - */ -public class DocPackage extends MajorRevisionPackage implements IAndroidVersionProvider { - - private final AndroidVersion mVersion; - - /** - * Creates a new doc package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public DocPackage(SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - int apiLevel = - PackageParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); - String codeName = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); - if (codeName.length() == 0) { - codeName = null; - } - mVersion = new AndroidVersion(apiLevel, codeName); - } - - /** - * Manually create a new package with one archive and the given attributes. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public static Package create(SdkSource source, - Properties props, - int apiLevel, - String codename, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - return new DocPackage(source, props, apiLevel, codename, revision, license, description, - descUrl, archiveOs, archiveArch, archiveOsPath); - } - - private DocPackage(SdkSource source, - Properties props, - int apiLevel, - String codename, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, - props, - revision, - license, - description, - descUrl, - archiveOs, - archiveArch, - archiveOsPath); - mVersion = new AndroidVersion(props, apiLevel, codename); - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be give the constructor that takes a {@link Properties} object. - */ - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - mVersion.saveProperties(props); - } - - /** - * Returns the version, for platform, add-on and doc packages. - * Can be 0 if this is a local package of unknown api-level. - */ - @Override @NonNull - public AndroidVersion getAndroidVersion() { - return mVersion; - } - - /** - * Returns a string identifier to install this package from the command line. - * For docs, we use "doc-N" where N is the API or the preview codename. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - return "doc-" + mVersion.getApiString(); //$NON-NLS-1$ - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - if (mVersion.isPreview()) { - return String.format("Documentation for Android '%1$s' Preview SDK%2$s", - mVersion.getCodename(), - isObsolete() ? " (Obsolete)" : ""); - } else { - return String.format("Documentation for Android SDK%2$s", - mVersion.getApiLevel(), - isObsolete() ? " (Obsolete)" : ""); - } - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - if (mVersion.isPreview()) { - return String.format("Documentation for Android '%1$s' Preview SDK, revision %2$s%3$s", - mVersion.getCodename(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } else { - return String.format("Documentation for Android SDK, API %1$d, revision %2$s%3$s", - mVersion.getApiLevel(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description is whatever the XML contains for the <description> field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - String s = getDescription(); - if (s == null || s.length() == 0) { - s = getShortDescription(); - } - - if (s.indexOf("revision") == -1) { - s += String.format("\nRevision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A "doc" package should always be located in SDK/docs. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - return new File(osSdkRoot, SdkConstants.FD_DOCS); - } - - /** - * Consider doc packages to be the same if they cover the same API level, - * regardless of their revision number. - */ - @Override - public boolean sameItemAs(Package pkg) { - if (pkg instanceof DocPackage) { - AndroidVersion rev2 = ((DocPackage) pkg).getAndroidVersion(); - return this.getAndroidVersion().equals(rev2); - } - - return false; - } - - /** - * {@inheritDoc} - * <hr> - * Doc packages are a bit different since there can only be one doc installed at - * the same time. - * <p/> - * We now consider that docs for different APIs are NOT updates, e.g. doc for API N+1 - * is no longer considered an update for doc API N. - * However docs that have the same API version (API level + codename) are considered - * updates if they have a higher revision number (so 15 rev 2 is an update for 15 rev 1, - * but is not an update for 14 rev 1.) - */ - @Override - public UpdateInfo canBeUpdatedBy(Package replacementPackage) { - // check they are the same kind of object - if (!(replacementPackage instanceof DocPackage)) { - return UpdateInfo.INCOMPATIBLE; - } - - DocPackage replacementDoc = (DocPackage)replacementPackage; - - AndroidVersion replacementVersion = replacementDoc.getAndroidVersion(); - - // Check if they're the same exact (api and codename) - if (replacementVersion.equals(mVersion)) { - // exact same version, so check the revision level - if (replacementPackage.getRevision().compareTo(this.getRevision()) > 0) { - return UpdateInfo.UPDATE; - } - } else { - // not the same version? we check if they have the same api level and the new one - // is a preview, in which case it's also an update (since preview have the api level - // of the _previous_ version.) - if (replacementVersion.getApiLevel() == mVersion.getApiLevel() && - replacementVersion.isPreview()) { - return UpdateInfo.UPDATE; - } - } - - // not an upgrade but not incompatible either. - return UpdateInfo.NOT_UPDATE; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((mVersion == null) ? 0 : mVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof DocPackage)) { - return false; - } - DocPackage other = (DocPackage) obj; - if (mVersion == null) { - if (other.mVersion != null) { - return false; - } - } else if (!mVersion.equals(other.mVersion)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ExtraPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ExtraPackage.java deleted file mode 100755 index 78a2450..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ExtraPackage.java +++ /dev/null @@ -1,751 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.LocalSdkParser; -import com.android.sdklib.internal.repository.NullTaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.RepoConstants; -import com.android.utils.NullLogger; - -import org.w3c.dom.Node; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Pattern; - -/** - * Represents a extra XML node in an SDK repository. - */ -public class ExtraPackage extends MinToolsPackage - implements IMinApiLevelDependency { - - /** - * The extra display name. Used in the UI to represent the package. It can be anything. - */ - private final String mDisplayName; - - /** - * The vendor id name. It is a simple alphanumeric string [a-zA-Z0-9_-]. - */ - private final String mVendorId; - - /** - * The vendor display name. Used in the UI to represent the vendor. It can be anything. - */ - private final String mVendorDisplay; - - /** - * The sub-folder name. It must be a non-empty single-segment path. - */ - private final String mPath; - - /** - * The optional old_paths, if any. If present, this is a list of old "path" values that - * we'd like to migrate to the current "path" name for this extra. - */ - private final String mOldPaths; - - /** - * The minimal API level required by this extra package, if > 0, - * or {@link #MIN_API_LEVEL_NOT_SPECIFIED} if there is no such requirement. - */ - private final int mMinApiLevel; - - /** - * The project-files listed by this extra package. - * The array can be empty but not null. - */ - private final String[] mProjectFiles; - - /** - * Creates a new tool package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public ExtraPackage( - SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - mPath = PackageParserUtils.getXmlString(packageNode, RepoConstants.NODE_PATH); - - // Read name-display, vendor-display and vendor-id, introduced in addon-4.xsd. - // These are not optional, they are mandatory in addon-4 but we still treat them - // as optional so that we can fallback on using <vendor> which was the only one - // defined in addon-3.xsd. - String name = - PackageParserUtils.getXmlString(packageNode, RepoConstants.NODE_NAME_DISPLAY); - String vname = - PackageParserUtils.getXmlString(packageNode, RepoConstants.NODE_VENDOR_DISPLAY); - String vid = - PackageParserUtils.getXmlString(packageNode, RepoConstants.NODE_VENDOR_ID); - - if (vid.length() == 0) { - // If vid is missing, use the old <vendor> attribute. - // Note that in a valid XML, vendor-id cannot be an empty string. - // The only reason vid can be empty is when <vendor-id> is missing, which - // happens in an addon-3 schema, in which case the old <vendor> needs to be used. - String vendor = PackageParserUtils.getXmlString(packageNode, RepoConstants.NODE_VENDOR); - vid = sanitizeLegacyVendor(vendor); - if (vname.length() == 0) { - vname = vendor; - } - } - if (vname.length() == 0) { - // The vendor-display name can be empty, in which case we use the vendor-id. - vname = vid; - } - mVendorDisplay = vname.trim(); - mVendorId = vid.trim(); - - if (name.length() == 0) { - // If name is missing, use the <path> attribute as done in an addon-3 schema. - name = getPrettyName(); - } - mDisplayName = name.trim(); - - mMinApiLevel = PackageParserUtils.getXmlInt( - packageNode, RepoConstants.NODE_MIN_API_LEVEL, MIN_API_LEVEL_NOT_SPECIFIED); - - mProjectFiles = parseProjectFiles( - PackageParserUtils.findChildElement(packageNode, RepoConstants.NODE_PROJECT_FILES)); - - mOldPaths = PackageParserUtils.getXmlString(packageNode, RepoConstants.NODE_OLD_PATHS); - } - - private String[] parseProjectFiles(Node projectFilesNode) { - ArrayList<String> paths = new ArrayList<String>(); - - if (projectFilesNode != null) { - String nsUri = projectFilesNode.getNamespaceURI(); - for(Node child = projectFilesNode.getFirstChild(); - child != null; - child = child.getNextSibling()) { - - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI()) && - RepoConstants.NODE_PATH.equals(child.getLocalName())) { - String path = child.getTextContent(); - if (path != null) { - path = path.trim(); - if (path.length() > 0) { - paths.add(path); - } - } - } - } - } - - return paths.toArray(new String[paths.size()]); - } - - /** - * Manually create a new package with one archive and the given attributes or properties. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public static Package create(SdkSource source, - Properties props, - String vendor, - String path, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - ExtraPackage ep = new ExtraPackage(source, props, vendor, path, revision, license, - description, descUrl, archiveOs, archiveArch, archiveOsPath); - return ep; - } - - /** - * Constructor used to create a mock {@link ExtraPackage}. - * Most of the attributes here are optional. - * When not defined, they will be extracted from the {@code props} properties. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected ExtraPackage(SdkSource source, - Properties props, - String vendorId, - String path, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, - props, - revision, - license, - description, - descUrl, - archiveOs, - archiveArch, - archiveOsPath); - - // The path argument comes before whatever could be in the properties - mPath = path != null ? path : getProperty(props, PkgProps.EXTRA_PATH, path); - - String name = getProperty(props, PkgProps.EXTRA_NAME_DISPLAY, ""); //$NON-NLS-1$ - String vname = getProperty(props, PkgProps.EXTRA_VENDOR_DISPLAY, ""); //$NON-NLS-1$ - String vid = vendorId != null ? vendorId : - getProperty(props, PkgProps.EXTRA_VENDOR_ID, ""); //$NON-NLS-1$ - - if (vid.length() == 0) { - // If vid is missing, use the old <vendor> attribute. - // <vendor> did not exist prior to schema repo-v3 and tools r8. - String vendor = getProperty(props, PkgProps.EXTRA_VENDOR, ""); //$NON-NLS-1$ - vid = sanitizeLegacyVendor(vendor); - if (vname.length() == 0) { - vname = vendor; - } - } - if (vname.length() == 0) { - // The vendor-display name can be empty, in which case we use the vendor-id. - vname = vid; - } - mVendorDisplay = vname.trim(); - mVendorId = vid.trim(); - - if (name.length() == 0) { - // If name is missing, use the <path> attribute as done in an addon-3 schema. - name = getPrettyName(); - } - mDisplayName = name.trim(); - - mOldPaths = getProperty(props, PkgProps.EXTRA_OLD_PATHS, null); - - mMinApiLevel = getPropertyInt(props, PkgProps.EXTRA_MIN_API_LEVEL, - MIN_API_LEVEL_NOT_SPECIFIED); - - String projectFiles = getProperty(props, PkgProps.EXTRA_PROJECT_FILES, null); - ArrayList<String> filePaths = new ArrayList<String>(); - if (projectFiles != null && projectFiles.length() > 0) { - for (String filePath : projectFiles.split(Pattern.quote(File.pathSeparator))) { - filePath = filePath.trim(); - if (filePath.length() > 0) { - filePaths.add(filePath); - } - } - } - mProjectFiles = filePaths.toArray(new String[filePaths.size()]); - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be give the constructor that takes a {@link Properties} object. - */ - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - props.setProperty(PkgProps.EXTRA_PATH, mPath); - props.setProperty(PkgProps.EXTRA_NAME_DISPLAY, mDisplayName); - props.setProperty(PkgProps.EXTRA_VENDOR_DISPLAY, mVendorDisplay); - props.setProperty(PkgProps.EXTRA_VENDOR_ID, mVendorId); - - if (getMinApiLevel() != MIN_API_LEVEL_NOT_SPECIFIED) { - props.setProperty(PkgProps.EXTRA_MIN_API_LEVEL, Integer.toString(getMinApiLevel())); - } - - if (mProjectFiles.length > 0) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < mProjectFiles.length; i++) { - if (i > 0) { - sb.append(File.pathSeparatorChar); - } - sb.append(mProjectFiles[i]); - } - props.setProperty(PkgProps.EXTRA_PROJECT_FILES, sb.toString()); - } - - if (mOldPaths != null && mOldPaths.length() > 0) { - props.setProperty(PkgProps.EXTRA_OLD_PATHS, mOldPaths); - } - } - - /** - * Returns the minimal API level required by this extra package, if > 0, - * or {@link #MIN_API_LEVEL_NOT_SPECIFIED} if there is no such requirement. - */ - @Override - public int getMinApiLevel() { - return mMinApiLevel; - } - - /** - * The project-files listed by this extra package. - * The array can be empty but not null. - * <p/> - * IMPORTANT: directory separators are NOT translated and may not match - * the {@link File#separatorChar} of the current platform. It's up to the - * user to adequately interpret the paths. - * Similarly, no guarantee is made on the validity of the paths. - * Users are expected to apply all usual sanity checks such as removing - * "./" and "../" and making sure these paths don't reference files outside - * of the installed archive. - * - * @since sdk-repository-4.xsd or sdk-addon-2.xsd - */ - public String[] getProjectFiles() { - return mProjectFiles; - } - - /** - * Returns the old_paths, a list of obsolete path names for the extra package. - * <p/> - * These can be used by the installer to migrate an extra package using one of the - * old paths into the new path. - * <p/> - * These can also be used to recognize "old" renamed packages as the same as - * the current one. - * - * @return A list of old paths. Can be empty but not null. - */ - public String[] getOldPaths() { - if (mOldPaths == null || mOldPaths.length() == 0) { - return new String[0]; - } - return mOldPaths.split(";"); //$NON-NLS-1$ - } - - /** - * Returns the sanitized path folder name. It is a single-segment path. - * <p/> - * The package is installed in SDK/extras/vendor_name/path_name. - */ - public String getPath() { - // The XSD specifies the XML vendor and path should only contain [a-zA-Z0-9]+ - // and cannot be empty. Let's be defensive and enforce that anyway since things - // like "____" are still valid values that we don't want to allow. - - // Sanitize the path - String path = mPath.replaceAll("[^a-zA-Z0-9-]+", "_"); //$NON-NLS-1$ - if (path.length() == 0 || path.equals("_")) { //$NON-NLS-1$ - int h = path.hashCode(); - path = String.format("extra%08x", h); //$NON-NLS-1$ - } - - return path; - } - - /** - * Returns the vendor id. - */ - public String getVendorId() { - return mVendorId; - } - - public String getVendorDisplay() { - return mVendorDisplay; - } - - public String getDisplayName() { - return mDisplayName; - } - - /** Transforms the legacy vendor name into a usable vendor id. */ - private String sanitizeLegacyVendor(String vendorDisplay) { - // The XSD specifies the XML vendor and path should only contain [a-zA-Z0-9]+ - // and cannot be empty. Let's be defensive and enforce that anyway since things - // like "____" are still valid values that we don't want to allow. - - if (vendorDisplay != null && vendorDisplay.length() > 0) { - String vendor = vendorDisplay.trim(); - // Sanitize the vendor - vendor = vendor.replaceAll("[^a-zA-Z0-9-]+", "_"); //$NON-NLS-1$ - if (vendor.equals("_")) { //$NON-NLS-1$ - int h = vendor.hashCode(); - vendor = String.format("vendor%08x", h); //$NON-NLS-1$ - } - - return vendor; - } - - return ""; //$NON-NLS-1$ - - } - - /** - * Used to produce a suitable name-display based on the current {@link #mPath} - * and {@link #mVendorDisplay} in addon-3 schemas. - */ - private String getPrettyName() { - String name = mPath; - - // In the past, we used to save the extras in a folder vendor-path, - // and that "vendor" would end up in the path when we reload the extra from - // disk. Detect this and compensate. - if (mVendorDisplay != null && mVendorDisplay.length() > 0) { - if (name.startsWith(mVendorDisplay + "-")) { //$NON-NLS-1$ - name = name.substring(mVendorDisplay.length() + 1); - } - } - - // Uniformize all spaces in the name - if (name != null) { - name = name.replaceAll("[ _\t\f-]+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$ - } - if (name == null || name.length() == 0) { - name = "Unknown Extra"; - } - - if (mVendorDisplay != null && mVendorDisplay.length() > 0) { - name = mVendorDisplay + " " + name; //$NON-NLS-1$ - name = name.replaceAll("[ _\t\f-]+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$ - } - - // Look at all lower case characters in range [1..n-1] and replace them by an upper - // case if they are preceded by a space. Also upper cases the first character of the - // string. - boolean changed = false; - char[] chars = name.toCharArray(); - for (int n = chars.length - 1, i = 0; i < n; i++) { - if (Character.isLowerCase(chars[i]) && (i == 0 || chars[i - 1] == ' ')) { - chars[i] = Character.toUpperCase(chars[i]); - changed = true; - } - } - if (changed) { - name = new String(chars); - } - - // Special case: reformat a few typical acronyms. - name = name.replaceAll(" Usb ", " USB "); //$NON-NLS-1$ - name = name.replaceAll(" Api ", " API "); //$NON-NLS-1$ - - return name; - } - - /** - * Returns a string identifier to install this package from the command line. - * For extras, we use "extra-vendor-path". - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - return String.format("extra-%1$s-%2$s", //$NON-NLS-1$ - getVendorId(), - getPath()); - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - String s = String.format("%1$s%2$s", - getDisplayName(), - isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$ - - return s; - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - String s = String.format("%1$s, revision %2$s%3$s", - getDisplayName(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$ - - return s; - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description is whatever the XML contains for the <description> field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - String s = String.format("%1$s, revision %2$s%3$s\nBy %4$s", - getDisplayName(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : "", //$NON-NLS-2$ - getVendorDisplay()); - - String d = getDescription(); - if (d != null && d.length() > 0) { - s += '\n' + d; - } - - if (!getMinToolsRevision().equals(MIN_TOOLS_REV_NOT_SPECIFIED)) { - s += String.format("\nRequires tools revision %1$s", - getMinToolsRevision().toShortString()); - } - - if (getMinApiLevel() != MIN_API_LEVEL_NOT_SPECIFIED) { - s += String.format("\nRequires SDK Platform Android API %1$s", getMinApiLevel()); - } - - File localPath = getLocalArchivePath(); - if (localPath != null) { - // For a local archive, also put the install path in the long description. - // This should help users locate the extra on their drive. - s += String.format("\nLocation: %1$s", localPath.getAbsolutePath()); - } else { - // For a non-installed archive, indicate where it would be installed. - s += String.format("\nInstall path: %1$s", - getInstallSubFolder(null/*sdk root*/).getPath()); - } - - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A "tool" package should always be located in SDK/tools. - * - * @param osSdkRoot The OS path of the SDK root folder. Must NOT be null. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * Not used in this implementation. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - - // First find if this extra is already installed. If so, reuse the same directory. - LocalSdkParser localParser = new LocalSdkParser(); - Package[] pkgs = localParser.parseSdk( - osSdkRoot, - sdkManager, - LocalSdkParser.PARSE_EXTRAS, - new NullTaskMonitor(NullLogger.getLogger())); - - for (Package pkg : pkgs) { - if (sameItemAs(pkg) && pkg instanceof ExtraPackage) { - File localPath = ((ExtraPackage) pkg).getLocalArchivePath(); - if (localPath != null) { - return localPath; - } - } - } - - return getInstallSubFolder(osSdkRoot); - } - - /** - * Computes the "sub-folder" install path, relative to the given SDK root. - * For an extra package, this is generally ".../extra/vendor-id/path". - * - * @param osSdkRoot The OS path of the SDK root folder if known. - * This CAN be null, in which case the path will start at /extra. - * @return Either /extra/vendor/path or sdk-root/extra/vendor-id/path. - */ - private File getInstallSubFolder(@Nullable String osSdkRoot) { - // The /extras dir at the root of the SDK - File path = new File(osSdkRoot, SdkConstants.FD_EXTRAS); - - String vendor = getVendorId(); - if (vendor != null && vendor.length() > 0) { - path = new File(path, vendor); - } - - String name = getPath(); - if (name != null && name.length() > 0) { - path = new File(path, name); - } - - return path; - } - - @Override - public boolean sameItemAs(Package pkg) { - // Extra packages are similar if they have the same path and vendor - if (pkg instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) pkg; - - String[] epOldPaths = ep.getOldPaths(); - int lenEpOldPaths = epOldPaths.length; - for (int indexEp = -1; indexEp < lenEpOldPaths; indexEp++) { - if (sameVendorAndPath( - mVendorId, mPath, - ep.mVendorId, indexEp < 0 ? ep.mPath : epOldPaths[indexEp])) { - return true; - } - } - - String[] thisOldPaths = getOldPaths(); - int lenThisOldPaths = thisOldPaths.length; - for (int indexThis = -1; indexThis < lenThisOldPaths; indexThis++) { - if (sameVendorAndPath( - mVendorId, indexThis < 0 ? mPath : thisOldPaths[indexThis], - ep.mVendorId, ep.mPath)) { - return true; - } - } - } - - return false; - } - - private static boolean sameVendorAndPath( - String thisVendor, String thisPath, - String otherVendor, String otherPath) { - // To be backward compatible, we need to support the old vendor-path form - // in either the current or the remote package. - // - // The vendor test below needs to account for an old installed package - // (e.g. with an install path of vendor-name) that has then been updated - // in-place and thus when reloaded contains the vendor name in both the - // path and the vendor attributes. - if (otherPath != null && thisPath != null && thisVendor != null) { - if (otherPath.equals(thisVendor + '-' + thisPath) && - (otherVendor == null || - otherVendor.length() == 0 || - otherVendor.equals(thisVendor))) { - return true; - } - } - if (thisPath != null && otherPath != null && otherVendor != null) { - if (thisPath.equals(otherVendor + '-' + otherPath) && - (thisVendor == null || - thisVendor.length() == 0 || - thisVendor.equals(otherVendor))) { - return true; - } - } - - - if (thisPath != null && thisPath.equals(otherPath)) { - if ((thisVendor == null && otherVendor == null) || - (thisVendor != null && thisVendor.equals(otherVendor))) { - return true; - } - } - - return false; - } - - /** - * For extra packages, we want to add vendor|path to the sorting key - * <em>before<em/> the revision number. - * <p/> - * {@inheritDoc} - */ - @Override - protected String comparisonKey() { - String s = super.comparisonKey(); - int pos = s.indexOf("|r:"); //$NON-NLS-1$ - assert pos > 0; - s = s.substring(0, pos) + - "|ve:" + getVendorId() + //$NON-NLS-1$ - "|pa:" + getPath() + //$NON-NLS-1$ - s.substring(pos); - return s; - } - - // --- - - /** - * If this package is installed, returns the install path of the archive if valid. - * Returns null if not installed or if the path does not exist. - */ - private File getLocalArchivePath() { - Archive[] archives = getArchives(); - if (archives.length == 1 && archives[0].isLocal()) { - File path = new File(archives[0].getLocalOsPath()); - if (path.isDirectory()) { - return path; - } - } - - return null; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + mMinApiLevel; - result = prime * result + ((mPath == null) ? 0 : mPath.hashCode()); - result = prime * result + Arrays.hashCode(mProjectFiles); - result = prime * result + ((mVendorDisplay == null) ? 0 : mVendorDisplay.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof ExtraPackage)) { - return false; - } - ExtraPackage other = (ExtraPackage) obj; - if (mMinApiLevel != other.mMinApiLevel) { - return false; - } - if (mPath == null) { - if (other.mPath != null) { - return false; - } - } else if (!mPath.equals(other.mPath)) { - return false; - } - if (!Arrays.equals(mProjectFiles, other.mProjectFiles)) { - return false; - } - if (mVendorDisplay == null) { - if (other.mVendorDisplay != null) { - return false; - } - } else if (!mVendorDisplay.equals(other.mVendorDisplay)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/FullRevision.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/FullRevision.java deleted file mode 100755 index 4c4387b..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/FullRevision.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.annotations.NonNull; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - - -/** - * Package multi-part revision number composed of a tuple - * (major.minor.micro) and an optional preview revision - * (the lack of a preview number indicates it's not a preview - * but a final package.) - * - * @see MajorRevision - */ -public class FullRevision implements Comparable<FullRevision> { - - public static final int MISSING_MAJOR_REV = 0; - public static final int IMPLICIT_MINOR_REV = 0; - public static final int IMPLICIT_MICRO_REV = 0; - public static final int NOT_A_PREVIEW = 0; - - private final static Pattern FULL_REVISION_PATTERN = - // 1=major 2=minor 3=micro 4=preview - Pattern.compile("\\s*([0-9]+)(?:\\.([0-9]+)(?:\\.([0-9]+))?)?\\s*(?:rc([0-9]+))?\\s*"); - - private final int mMajor; - private final int mMinor; - private final int mMicro; - private final int mPreview; - - public FullRevision(int major) { - this(major, 0, 0); - } - - public FullRevision(int major, int minor, int micro) { - this(major, minor, micro, NOT_A_PREVIEW); - } - - public FullRevision(int major, int minor, int micro, int preview) { - mMajor = major; - mMinor = minor; - mMicro = micro; - mPreview = preview; - } - - public int getMajor() { - return mMajor; - } - - public int getMinor() { - return mMinor; - } - - public int getMicro() { - return mMicro; - } - - public boolean isPreview() { - return mPreview > NOT_A_PREVIEW; - } - - public int getPreview() { - return mPreview; - } - - /** - * Parses a string of format "major.minor.micro rcPreview" and returns - * a new {@link FullRevision} for it. All the fields except major are - * optional. - * <p/> - * The parsing is equivalent to the pseudo-BNF/regexp: - * <pre> - * Major/Minor/Micro/Preview := [0-9]+ - * Revision := Major ('.' Minor ('.' Micro)? )? \s* ('rc'Preview)? - * </pre> - * - * @param revision A non-null revision to parse. - * @return A new non-null {@link FullRevision}. - * @throws NumberFormatException if the parsing failed. - */ - public static @NonNull FullRevision parseRevision(@NonNull String revision) - throws NumberFormatException { - - if (revision == null) { - throw new NumberFormatException("revision is <null>"); //$NON-NLS-1$ - } - - Throwable cause = null; - try { - Matcher m = FULL_REVISION_PATTERN.matcher(revision); - if (m != null && m.matches()) { - int major = Integer.parseInt(m.group(1)); - String s = m.group(2); - int minor = s == null ? IMPLICIT_MINOR_REV : Integer.parseInt(s); - s = m.group(3); - int micro = s == null ? IMPLICIT_MICRO_REV : Integer.parseInt(s); - s = m.group(4); - int preview = s == null ? NOT_A_PREVIEW : Integer.parseInt(s); - - return new FullRevision(major, minor, micro, preview); - } - } catch (Throwable t) { - cause = t; - } - - NumberFormatException n = new NumberFormatException( - "Invalid full revision: " + revision); //$NON-NLS-1$ - n.initCause(cause); - throw n; - } - - /** - * Returns the version in a fixed format major.minor.micro - * with an optional "rc preview#". For example it would - * return "18.0.0", "18.1.0" or "18.1.2 rc5". - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(mMajor) - .append('.').append(mMinor) - .append('.').append(mMicro); - - if (mPreview != NOT_A_PREVIEW) { - sb.append(" rc").append(mPreview); - } - - return sb.toString(); - } - - /** - * Returns the version in a dynamic format "major.minor.micro rc#". - * This is similar to {@link #toString()} except it omits minor, micro - * or preview versions when they are zero. - * For example it would return "18 rc1" instead of "18.0.0 rc1", - * or "18.1 rc2" instead of "18.1.0 rc2". - */ - public String toShortString() { - StringBuilder sb = new StringBuilder(); - sb.append(mMajor); - if (mMinor > 0 || mMicro > 0) { - sb.append('.').append(mMinor); - } - if (mMicro > 0) { - sb.append('.').append(mMicro); - } - if (mPreview != NOT_A_PREVIEW) { - sb.append(" rc").append(mPreview); - } - - return sb.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + mMajor; - result = prime * result + mMinor; - result = prime * result + mMicro; - result = prime * result + mPreview; - return result; - } - - @Override - public boolean equals(Object rhs) { - if (this == rhs) { - return true; - } - if (rhs == null) { - return false; - } - if (!(rhs instanceof FullRevision)) { - return false; - } - FullRevision other = (FullRevision) rhs; - if (mMajor != other.mMajor) { - return false; - } - if (mMinor != other.mMinor) { - return false; - } - if (mMicro != other.mMicro) { - return false; - } - if (mPreview != other.mPreview) { - return false; - } - return true; - } - - /** - * Trivial comparison of a version, e.g 17.1.2 < 18.0.0. - * - * Note that preview/release candidate are released before their final version, - * so "18.0.0 rc1" comes below "18.0.0". The best way to think of it as if the - * lack of preview number was "+inf": - * "18.1.2 rc5" => "18.1.2.5" so its less than "18.1.2.+INF" but more than "18.1.1.0" - * and more than "18.1.2.4" - */ - @Override - public int compareTo(FullRevision rhs) { - int delta = mMajor - rhs.mMajor; - if (delta != 0) { - return delta; - } - - delta = mMinor - rhs.mMinor; - if (delta != 0) { - return delta; - } - - delta = mMicro - rhs.mMicro; - if (delta != 0) { - return delta; - } - - int p1 = mPreview == NOT_A_PREVIEW ? Integer.MAX_VALUE : mPreview; - int p2 = rhs.mPreview == NOT_A_PREVIEW ? Integer.MAX_VALUE : rhs.mPreview; - delta = p1 - p2; - return delta; - } - - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/FullRevisionPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/FullRevisionPackage.java deleted file mode 100755 index 88827f5..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/FullRevisionPackage.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Node; - -import java.util.Map; -import java.util.Properties; - -/** - * Represents a package in an SDK repository that has a {@link FullRevision}, - * which is a multi-part revision number (major.minor.micro) and an optional preview revision. - */ -public abstract class FullRevisionPackage extends Package - implements IFullRevisionProvider { - - private final FullRevision mPreviewVersion; - - /** - * Creates a new package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - FullRevisionPackage(SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - mPreviewVersion = PackageParserUtils.parseFullRevisionElement( - PackageParserUtils.findChildElement(packageNode, SdkRepoConstants.NODE_REVISION)); - } - - /** - * Manually create a new package with one archive and the given attributes. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * Properties from props are used first when possible, e.g. if props is non null. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public FullRevisionPackage( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, props, revision, license, description, descUrl, - archiveOs, archiveArch, archiveOsPath); - - String revStr = getProperty(props, PkgProps.PKG_REVISION, null); - - FullRevision rev = null; - if (revStr != null) { - try { - rev = FullRevision.parseRevision(revStr); - } catch (NumberFormatException ignore) {} - } - if (rev == null) { - rev = new FullRevision(revision); - } - - mPreviewVersion = rev; - } - - @Override - public FullRevision getRevision() { - return mPreviewVersion; - } - - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - props.setProperty(PkgProps.PKG_REVISION, mPreviewVersion.toShortString()); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((mPreviewVersion == null) ? 0 : mPreviewVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof FullRevisionPackage)) { - return false; - } - FullRevisionPackage other = (FullRevisionPackage) obj; - if (mPreviewVersion == null) { - if (other.mPreviewVersion != null) { - return false; - } - } else if (!mPreviewVersion.equals(other.mPreviewVersion)) { - return false; - } - return true; - } - - /** - * Computes whether the given package is a suitable update for the current package. - * <p/> - * A specific case here is that a release package can update a preview, whereas - * a preview can only update another preview. - * <p/> - * {@inheritDoc} - */ - @Override - public UpdateInfo canBeUpdatedBy(Package replacementPackage) { - if (replacementPackage == null) { - return UpdateInfo.INCOMPATIBLE; - } - - // check they are the same item, ignoring the preview bit. - if (!sameItemAs(replacementPackage, true /*ignorePreviews*/)) { - return UpdateInfo.INCOMPATIBLE; - } - - // a preview cannot update a non-preview - if (!getRevision().isPreview() && replacementPackage.getRevision().isPreview()) { - return UpdateInfo.INCOMPATIBLE; - } - - // check revision number - if (replacementPackage.getRevision().compareTo(this.getRevision()) > 0) { - return UpdateInfo.UPDATE; - } - - // not an upgrade but not incompatible either. - return UpdateInfo.NOT_UPDATE; - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IAndroidVersionProvider.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IAndroidVersionProvider.java deleted file mode 100755 index 14d6214..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IAndroidVersionProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.annotations.NonNull; -import com.android.sdklib.AndroidVersion; - -/** - * Interface for packages that provide an {@link AndroidVersion}. - * <p/> - * Note that {@link IPlatformDependency} is a similar interface, but with a different semantic. - * The {@link IPlatformDependency} denotes that a given package can only be installed if the - * requested platform is present, whereas this interface denotes that the given package simply - * has a version, which is not necessarily a dependency. - */ -public interface IAndroidVersionProvider { - - /** - * Returns the android version, for platform, add-on and doc packages. - * Can be 0 if this is a local package of unknown api-level. - */ - public abstract @NonNull AndroidVersion getAndroidVersion(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IExactApiLevelDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IExactApiLevelDependency.java deleted file mode 100755 index eaeccdb..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IExactApiLevelDependency.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.repository.RepoConstants; - -/** - * Interface used to decorate a {@link Package} that has a dependency - * on a specific API level, e.g. which XML has a {@code <api-level>} element. - * <p/> - * For example an add-on package requires a platform with an exact API level to be installed - * at the same time. - * This is not the same as {@link IMinApiLevelDependency} which requests that a platform with at - * least the requested API level be present or installed at the same time. - * <p/> - * Such package requires the {@code <api-level>} element. It is not an optional - * property, however it can be invalid. - */ -public interface IExactApiLevelDependency { - - /** - * The value of {@link #getExactApiLevel()} when the {@link RepoConstants#NODE_API_LEVEL} - * was not specified in the XML source. - */ - public static final int API_LEVEL_INVALID = 0; - - /** - * Returns the exact API level required by this package, if > 0, - * or {@link #API_LEVEL_INVALID} if the value was missing. - * <p/> - * This attribute is mandatory and should not be normally missing. - * It can only happen when dealing with an invalid repository XML. - */ - public abstract int getExactApiLevel(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IFullRevisionProvider.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IFullRevisionProvider.java deleted file mode 100755 index e4ec292..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IFullRevisionProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - - - -/** - * Interface for packages that provide a {@link FullRevision}, - * which is a multi-part revision number (major.minor.micro) and an optional preview revision. - * <p/> - * This interface is a tag. It indicates that {@link Package#getRevision()} returns a - * {@link FullRevision} instead of a limited {@link MajorRevision}. <br/> - * The preview version number is available via {@link Package#getRevision()}. - */ -public interface IFullRevisionProvider { - - /** - * Returns whether the give package represents the same item as the current package. - * <p/> - * Two packages are considered the same if they represent the same thing, except for the - * revision number. - * @param pkg the package to compare - * @param ignorePreviews true if 2 packages should be considered the same even if one - * is a preview and the other one is not. - * @return true if the item are the same. - */ - public abstract boolean sameItemAs(Package pkg, boolean ignorePreviews); - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ILayoutlibVersion.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ILayoutlibVersion.java deleted file mode 100755 index 39c1dc2..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ILayoutlibVersion.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.utils.Pair; - -/** - * Interface used to decorate a {@link Package} that provides a version for layout lib. - */ -public interface ILayoutlibVersion { - - public static final int LAYOUTLIB_API_NOT_SPECIFIED = 0; - public static final int LAYOUTLIB_REV_NOT_SPECIFIED = 0; - - /** - * Returns the layoutlib version. Mandatory starting with repository XSD rev 4. - * <p/> - * The first integer is the API of layoublib, which should be > 0. - * It will be equal to {@link #LAYOUTLIB_API_NOT_SPECIFIED} (0) if the layoutlib - * version isn't specified. - * <p/> - * The second integer is the revision for that given API. It is >= 0 - * and works as a minor revision number, incremented for the same API level. - * - * @since sdk-repository-4.xsd - */ - public Pair<Integer, Integer> getLayoutlibVersion(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinApiLevelDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinApiLevelDependency.java deleted file mode 100755 index 8baafe9..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinApiLevelDependency.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.repository.SdkRepoConstants; - -/** - * Interface used to decorate a {@link Package} that has a dependency - * on a minimal API level, e.g. which XML has a <code><min-api-level></code> element. - * <p/> - * A package that has this dependency can only be installed if a platform with at least the - * requested API level is present or installed at the same time. - */ -public interface IMinApiLevelDependency { - - /** - * The value of {@link #getMinApiLevel()} when the {@link SdkRepoConstants#NODE_MIN_API_LEVEL} - * was not specified in the XML source. - */ - public static final int MIN_API_LEVEL_NOT_SPECIFIED = 0; - - /** - * Returns the minimal API level required by this package, if > 0, - * or {@link #MIN_API_LEVEL_NOT_SPECIFIED} if there is no such requirement. - */ - public abstract int getMinApiLevel(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinPlatformToolsDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinPlatformToolsDependency.java deleted file mode 100755 index d17b800..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinPlatformToolsDependency.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.repository.SdkRepoConstants; - -/** - * Interface used to decorate a {@link Package} that has a dependency - * on a minimal platform-tools revision, e.g. which XML has a - * <code><min-platform-tools-rev></code> element. - * <p/> - * A package that has this dependency can only be installed if the requested platform-tools - * revision is present or installed at the same time. - */ -public interface IMinPlatformToolsDependency { - - /** - * The value of {@link #getMinPlatformToolsRevision()} when the - * {@link SdkRepoConstants#NODE_MIN_PLATFORM_TOOLS_REV} was not specified in the XML source. - * Since this is a required attribute in the XML schema, it can only happen when dealing - * with an invalid repository XML. - */ - public static final FullRevision MIN_PLATFORM_TOOLS_REV_INVALID = - new FullRevision(FullRevision.MISSING_MAJOR_REV); - - /** - * The minimal revision of the tools package required by this package if > 0, - * or {@link #MIN_PLATFORM_TOOLS_REV_INVALID} if the value was missing. - * <p/> - * This attribute is mandatory and should not be normally missing. - * It can only happen when dealing with an invalid repository XML. - */ - public abstract FullRevision getMinPlatformToolsRevision(); - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinToolsDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinToolsDependency.java deleted file mode 100755 index 064f1d3..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IMinToolsDependency.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.repository.SdkRepoConstants; - -/** - * Interface used to decorate a {@link Package} that has a dependency - * on a minimal tools revision, e.g. which XML has a <code><min-tools-rev></code> element. - * <p/> - * A package that has this dependency can only be installed if the requested tools revision - * is present or installed at the same time. - */ -public interface IMinToolsDependency { - - /** - * The value of {@link #getMinToolsRevision()} when the - * {@link SdkRepoConstants#NODE_MIN_TOOLS_REV} was not specified in the XML source. - */ - public static final FullRevision MIN_TOOLS_REV_NOT_SPECIFIED = - new FullRevision(FullRevision.MISSING_MAJOR_REV); - - /** - * The minimal revision of the tools package required by this extra package if > 0, - * or {@link #MIN_TOOLS_REV_NOT_SPECIFIED} if there is no such requirement. - */ - public abstract FullRevision getMinToolsRevision(); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IPlatformDependency.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IPlatformDependency.java deleted file mode 100755 index 9665528..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/IPlatformDependency.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.AndroidVersion; - -/** - * Interface used to decorate a {@link Package} that has a dependency - * on a specific platform (API level and/or code name). - * <p/> - * A package that has this dependency can only be installed if a platform with at least the - * requested API level is present or installed at the same time. - * <p/> - * Note that although this interface looks like {@link IAndroidVersionProvider}, it does - * not convey the same semantic since {@link IAndroidVersionProvider} does <em>not</em> - * imply any dependency being a limiting factor as far as installation is concerned. - */ -public interface IPlatformDependency { - - /** Returns the version of the platform dependency of this package. */ - AndroidVersion getAndroidVersion(); - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/LayoutlibVersionMixin.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/LayoutlibVersionMixin.java deleted file mode 100755 index ab9a31e..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/LayoutlibVersionMixin.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.RepoConstants; -import com.android.utils.Pair; - -import org.w3c.dom.Node; - -import java.util.Properties; - -/** - * Helper class to handle the layoutlib version provided by a package. - */ -public class LayoutlibVersionMixin implements ILayoutlibVersion { - - /** - * The layoutlib version. - * The first integer is the API of layoublib, which should be > 0. - * It will be equal to {@link #LAYOUTLIB_API_NOT_SPECIFIED} (0) if the layoutlib - * version isn't specified. - * The second integer is the revision for that given API. It is >= 0 - * and works as a minor revision number, incremented for the same API level. - */ - private final Pair<Integer, Integer> mLayoutlibVersion; - - /** - * Parses an XML node to process the {@code <layoutlib>} element. - * - * The layoutlib element is new in the XSD rev 4, so we need to cope with it missing - * in earlier XMLs. - */ - public LayoutlibVersionMixin(Node pkgNode) { - - int api = LAYOUTLIB_API_NOT_SPECIFIED; - int rev = LAYOUTLIB_REV_NOT_SPECIFIED; - - Node layoutlibNode = - PackageParserUtils.findChildElement(pkgNode, RepoConstants.NODE_LAYOUT_LIB); - - if (layoutlibNode != null) { - api = PackageParserUtils.getXmlInt(layoutlibNode, RepoConstants.NODE_API, 0); - rev = PackageParserUtils.getXmlInt(layoutlibNode, RepoConstants.NODE_REVISION, 0); - } - - mLayoutlibVersion = Pair.of(api, rev); - } - - /** - * Parses the layoutlib version optionally available in the given {@link Properties}. - */ - public LayoutlibVersionMixin(Properties props) { - int layoutlibApi = Package.getPropertyInt(props, PkgProps.LAYOUTLIB_API, - LAYOUTLIB_API_NOT_SPECIFIED); - int layoutlibRev = Package.getPropertyInt(props, PkgProps.LAYOUTLIB_REV, - LAYOUTLIB_REV_NOT_SPECIFIED); - mLayoutlibVersion = Pair.of(layoutlibApi, layoutlibRev); - } - - /** - * Stores the layoutlib version in the given {@link Properties}. - */ - void saveProperties(Properties props) { - if (mLayoutlibVersion.getFirst().intValue() != LAYOUTLIB_API_NOT_SPECIFIED) { - props.setProperty(PkgProps.LAYOUTLIB_API, mLayoutlibVersion.getFirst().toString()); - props.setProperty(PkgProps.LAYOUTLIB_REV, mLayoutlibVersion.getSecond().toString()); - } - } - - /** - * Returns the layoutlib version. - * <p/> - * The first integer is the API of layoublib, which should be > 0. - * It will be equal to {@link #LAYOUTLIB_API_NOT_SPECIFIED} (0) if the layoutlib - * version isn't specified. - * <p/> - * The second integer is the revision for that given API. It is >= 0 - * and works as a minor revision number, incremented for the same API level. - * - * @since sdk-repository-4.xsd and sdk-addon-2.xsd - */ - @Override - public Pair<Integer, Integer> getLayoutlibVersion() { - return mLayoutlibVersion; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((mLayoutlibVersion == null) ? 0 : mLayoutlibVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof LayoutlibVersionMixin)) { - return false; - } - LayoutlibVersionMixin other = (LayoutlibVersionMixin) obj; - if (mLayoutlibVersion == null) { - if (other.mLayoutlibVersion != null) { - return false; - } - } else if (!mLayoutlibVersion.equals(other.mLayoutlibVersion)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MajorRevision.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MajorRevision.java deleted file mode 100755 index ad33ed4..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MajorRevision.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.annotations.NonNull; - - -/** - * Package revision number composed of a <em>single</em> major revision. - * <p/> - * Contrary to a {@link FullRevision}, a {@link MajorRevision} does not - * provide minor, micro and preview revision numbers -- these are all - * set to zero. - */ -public class MajorRevision extends FullRevision { - - public MajorRevision(int major) { - super(major, 0, 0); - } - - @Override - public String toString() { - return super.toShortString(); - } - - /** - * Parses a single-integer string and returns a new {@link MajorRevision} for it. - * - * @param revision A non-null revision to parse. - * @return A new non-null {@link MajorRevision}. - * @throws NumberFormatException if the parsing failed. - */ - public static @NonNull MajorRevision parseRevision(@NonNull String revision) - throws NumberFormatException { - - if (revision == null) { - throw new NumberFormatException("revision is <null>"); //$NON-NLS-1$ - } - - return new MajorRevision(Integer.parseInt(revision.trim())); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MajorRevisionPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MajorRevisionPackage.java deleted file mode 100755 index 4591297..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MajorRevisionPackage.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Node; - -import java.util.Map; -import java.util.Properties; - -/** - * Represents a package in an SDK repository that has a {@link MajorRevision}, - * which is a single major revision number (not minor, micro or previews). - */ -public abstract class MajorRevisionPackage extends Package { - - private final MajorRevision mRevision; - - /** - * Creates a new package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - MajorRevisionPackage(SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - mRevision = new MajorRevision( - PackageParserUtils.getXmlInt(packageNode, SdkRepoConstants.NODE_REVISION, 0)); - } - - /** - * Manually create a new package with one archive and the given attributes. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * Properties from props are used first when possible, e.g. if props is non null. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MajorRevisionPackage( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, props, revision, license, description, descUrl, - archiveOs, archiveArch, archiveOsPath); - - String revStr = getProperty(props, PkgProps.PKG_REVISION, null); - - MajorRevision rev = null; - if (revStr != null) { - try { - rev = MajorRevision.parseRevision(revStr); - } catch (NumberFormatException ignore) {} - } - if (rev == null) { - rev = new MajorRevision(revision); - } - - mRevision = rev; - } - - /** - * Returns the revision, an int > 0, for all packages (platform, add-on, tool, doc). - * Can be 0 if this is a local package of unknown revision. - */ - @Override - public FullRevision getRevision() { - return mRevision; - } - - - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - props.setProperty(PkgProps.PKG_REVISION, mRevision.toString()); - } - - @Override - public UpdateInfo canBeUpdatedBy(Package replacementPackage) { - if (replacementPackage == null) { - return UpdateInfo.INCOMPATIBLE; - } - - // check they are the same item. - if (!sameItemAs(replacementPackage)) { - return UpdateInfo.INCOMPATIBLE; - } - - // check revision number - if (replacementPackage.getRevision().compareTo(this.getRevision()) > 0) { - return UpdateInfo.UPDATE; - } - - // not an upgrade but not incompatible either. - return UpdateInfo.NOT_UPDATE; - } - - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MinToolsPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MinToolsPackage.java deleted file mode 100755 index a608a3c..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/MinToolsPackage.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Node; - -import java.util.Map; -import java.util.Properties; - -/** - * Represents an XML node in an SDK repository that has a min-tools-rev requirement. - */ -public abstract class MinToolsPackage extends MajorRevisionPackage implements IMinToolsDependency { - - /** - * The minimal revision of the tools package required by this extra package, if > 0, - * or {@link #MIN_TOOLS_REV_NOT_SPECIFIED} if there is no such requirement. - */ - private final FullRevision mMinToolsRevision; - - /** - * Creates a new package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - MinToolsPackage(SdkSource source, Node packageNode, String nsUri, Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - mMinToolsRevision = PackageParserUtils.parseFullRevisionElement( - PackageParserUtils.findChildElement(packageNode, SdkRepoConstants.NODE_MIN_TOOLS_REV)); - } - - /** - * Manually create a new package with one archive and the given attributes. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * Properties from props are used first when possible, e.g. if props is non null. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MinToolsPackage( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, props, revision, license, description, descUrl, - archiveOs, archiveArch, archiveOsPath); - - String revStr = getProperty(props, PkgProps.MIN_TOOLS_REV, null); - - FullRevision rev = MIN_TOOLS_REV_NOT_SPECIFIED; - if (revStr != null) { - try { - rev = FullRevision.parseRevision(revStr); - } catch (NumberFormatException ignore) {} - } - - mMinToolsRevision = rev; - } - - /** - * The minimal revision of the tools package required by this extra package, if > 0, - * or {@link #MIN_TOOLS_REV_NOT_SPECIFIED} if there is no such requirement. - */ - @Override - public FullRevision getMinToolsRevision() { - return mMinToolsRevision; - } - - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - if (!getMinToolsRevision().equals(MIN_TOOLS_REV_NOT_SPECIFIED)) { - props.setProperty(PkgProps.MIN_TOOLS_REV, getMinToolsRevision().toShortString()); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((mMinToolsRevision == null) ? 0 : mMinToolsRevision.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof MinToolsPackage)) { - return false; - } - MinToolsPackage other = (MinToolsPackage) obj; - if (mMinToolsRevision == null) { - if (other.mMinToolsRevision != null) { - return false; - } - } else if (!mMinToolsRevision.equals(other.mMinToolsRevision)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/Package.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/Package.java deleted file mode 100755 index feab109..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/Package.java +++ /dev/null @@ -1,823 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkAddonSource; -import com.android.sdklib.internal.repository.sources.SdkRepoSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.io.IFileOp; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkAddonConstants; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.w3c.dom.Node; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Map; -import java.util.Properties; - -/** - * A {@link Package} is the base class for "something" that can be downloaded from - * the SDK repository. - * <p/> - * A package has some attributes (revision, description) and a list of archives - * which represent the downloadable bits. - * <p/> - * Packages are contained by a {@link SdkSource} (a download site). - * <p/> - * Derived classes must implement the {@link IDescription} methods. - */ -public abstract class Package implements IDescription, Comparable<Package> { - - private final String mObsolete; - private final String mLicense; - private final String mDescription; - private final String mDescUrl; - private final String mReleaseNote; - private final String mReleaseUrl; - private final Archive[] mArchives; - private final SdkSource mSource; - - - // figure if we'll need to set the unix permissions - private static final boolean sUsingUnixPerm = - SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN || - SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_LINUX; - - - /** - * Enum for the result of {@link Package#canBeUpdatedBy(Package)}. This used so that we can - * differentiate between a package that is totally incompatible, and one that is the same item - * but just not an update. - * @see #canBeUpdatedBy(Package) - */ - public static enum UpdateInfo { - /** Means that the 2 packages are not the same thing */ - INCOMPATIBLE, - /** Means that the 2 packages are the same thing but one does not upgrade the other. - * </p> - * TODO: this name is confusing. We need to dig deeper. */ - NOT_UPDATE, - /** Means that the 2 packages are the same thing, and one is the upgrade of the other */ - UPDATE; - } - - /** - * Creates a new package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - Package(SdkSource source, Node packageNode, String nsUri, Map<String,String> licenses) { - mSource = source; - mDescription = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_DESCRIPTION); - mDescUrl = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_DESC_URL); - mReleaseNote = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_RELEASE_NOTE); - mReleaseUrl = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_RELEASE_URL); - mObsolete = - PackageParserUtils.getOptionalXmlString(packageNode, SdkRepoConstants.NODE_OBSOLETE); - - mLicense = parseLicense(packageNode, licenses); - mArchives = parseArchives( - PackageParserUtils.findChildElement(packageNode, SdkRepoConstants.NODE_ARCHIVES)); - } - - /** - * Manually create a new package with one archive and the given attributes. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * Properties from props are used first when possible, e.g. if props is non null. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public Package( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - - if (description == null) { - description = ""; - } - if (descUrl == null) { - descUrl = ""; - } - - mLicense = getProperty(props, PkgProps.PKG_LICENSE, license); - mDescription = getProperty(props, PkgProps.PKG_DESC, description); - mDescUrl = getProperty(props, PkgProps.PKG_DESC_URL, descUrl); - mReleaseNote = getProperty(props, PkgProps.PKG_RELEASE_NOTE, ""); //$NON-NLS-1$ - mReleaseUrl = getProperty(props, PkgProps.PKG_RELEASE_URL, ""); //$NON-NLS-1$ - mObsolete = getProperty(props, PkgProps.PKG_OBSOLETE, null); - - // If source is null and we can find a source URL in the properties, generate - // a dummy source just to store the URL. This allows us to easily remember where - // a package comes from. - String srcUrl = getProperty(props, PkgProps.PKG_SOURCE_URL, null); - if (props != null && source == null && srcUrl != null) { - // Both Addon and Extra packages can come from an addon source. - // For Extras, we can tell by looking at the source URL. - if (this instanceof AddonPackage || - ((this instanceof ExtraPackage) && - srcUrl.endsWith(SdkAddonConstants.URL_DEFAULT_FILENAME))) { - source = new SdkAddonSource(srcUrl, null /*uiName*/); - } else { - source = new SdkRepoSource(srcUrl, null /*uiName*/); - } - } - mSource = source; - - assert archiveOsPath != null; - mArchives = initializeArchives(props, archiveOs, archiveArch, archiveOsPath); - } - - /** - * Called by the constructor to get the initial {@link #mArchives} array. - * <p/> - * This is invoked by the local-package constructor and allows mock testing - * classes to override the archives created. - * This is an <em>implementation</em> details and clients must <em>not</em> - * rely on this. - * - * @return Always return a non-null array. The array may be empty. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected Archive[] initializeArchives( - Properties props, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - return new Archive[] { - new Archive(this, - props, - archiveOs, - archiveArch, - archiveOsPath) }; - } - - /** - * Utility method that returns a property from a {@link Properties} object. - * Returns the default value if props is null or if the property is not defined. - * - * @param props The {@link Properties} to search into. - * If null, the default value is returned. - * @param propKey The name of the property. Must not be null. - * @param defaultValue The default value to return if {@code props} is null or if the - * key is not found. Can be null. - * @return The string value of the given key in the properties, or null if the key - * isn't found or if {@code props} is null. - */ - @Nullable - static String getProperty( - @Nullable Properties props, - @NonNull String propKey, - @Nullable String defaultValue) { - if (props == null) { - return defaultValue; - } - return props.getProperty(propKey, defaultValue); - } - - /** - * Utility method that returns an integer property from a {@link Properties} object. - * Returns the default value if props is null or if the property is not defined or - * cannot be parsed to an integer. - * - * @param props The {@link Properties} to search into. - * If null, the default value is returned. - * @param propKey The name of the property. Must not be null. - * @param defaultValue The default value to return if {@code props} is null or if the - * key is not found. Can be null. - * @return The integer value of the given key in the properties, or the {@code defaultValue}. - */ - static int getPropertyInt( - @Nullable Properties props, - @NonNull String propKey, - int defaultValue) { - String s = props != null ? props.getProperty(propKey, null) : null; - if (s != null) { - try { - return Integer.parseInt(s); - } catch (Exception ignore) {} - } - return defaultValue; - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be give the constructor that takes a {@link Properties} object. - */ - public void saveProperties(Properties props) { - if (mLicense != null && mLicense.length() > 0) { - props.setProperty(PkgProps.PKG_LICENSE, mLicense); - } - if (mDescription != null && mDescription.length() > 0) { - props.setProperty(PkgProps.PKG_DESC, mDescription); - } - if (mDescUrl != null && mDescUrl.length() > 0) { - props.setProperty(PkgProps.PKG_DESC_URL, mDescUrl); - } - - if (mReleaseNote != null && mReleaseNote.length() > 0) { - props.setProperty(PkgProps.PKG_RELEASE_NOTE, mReleaseNote); - } - if (mReleaseUrl != null && mReleaseUrl.length() > 0) { - props.setProperty(PkgProps.PKG_RELEASE_URL, mReleaseUrl); - } - if (mObsolete != null) { - props.setProperty(PkgProps.PKG_OBSOLETE, mObsolete); - } - if (mSource != null) { - props.setProperty(PkgProps.PKG_SOURCE_URL, mSource.getUrl()); - } - } - - /** - * Parses the uses-licence node of this package, if any, and returns the license - * definition if there's one. Returns null if there's no uses-license element or no - * license of this name defined. - */ - private String parseLicense(Node packageNode, Map<String, String> licenses) { - Node usesLicense = - PackageParserUtils.findChildElement(packageNode, SdkRepoConstants.NODE_USES_LICENSE); - if (usesLicense != null) { - Node ref = usesLicense.getAttributes().getNamedItem(SdkRepoConstants.ATTR_REF); - if (ref != null) { - String licenseRef = ref.getNodeValue(); - return licenses.get(licenseRef); - } - } - return null; - } - - /** - * Parses an XML node to process the <archives> element. - * Always return a non-null array. The array may be empty. - */ - private Archive[] parseArchives(Node archivesNode) { - ArrayList<Archive> archives = new ArrayList<Archive>(); - - if (archivesNode != null) { - String nsUri = archivesNode.getNamespaceURI(); - for(Node child = archivesNode.getFirstChild(); - child != null; - child = child.getNextSibling()) { - - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI()) && - SdkRepoConstants.NODE_ARCHIVE.equals(child.getLocalName())) { - archives.add(parseArchive(child)); - } - } - } - - return archives.toArray(new Archive[archives.size()]); - } - - /** - * Parses one <archive> element from an <archives> container. - */ - private Archive parseArchive(Node archiveNode) { - Archive a = new Archive( - this, - (Os) PackageParserUtils.getEnumAttribute( - archiveNode, SdkRepoConstants.ATTR_OS, Os.values(), null), - (Arch) PackageParserUtils.getEnumAttribute( - archiveNode, SdkRepoConstants.ATTR_ARCH, Arch.values(), Arch.ANY), - PackageParserUtils.getXmlString(archiveNode, SdkRepoConstants.NODE_URL), - PackageParserUtils.getXmlLong (archiveNode, SdkRepoConstants.NODE_SIZE, 0), - PackageParserUtils.getXmlString(archiveNode, SdkRepoConstants.NODE_CHECKSUM) - ); - - return a; - } - - /** - * Returns the source that created (and owns) this package. Can be null. - */ - public SdkSource getParentSource() { - return mSource; - } - - /** - * Returns true if the package is deemed obsolete, that is it contains an - * actual <code><obsolete></code> element. - */ - public boolean isObsolete() { - return mObsolete != null; - } - - /** - * Returns the revision, an int > 0, for all packages (platform, add-on, tool, doc). - * Can be 0 if this is a local package of unknown revision. - */ - public abstract FullRevision getRevision(); - - /** - * Returns the optional description for all packages (platform, add-on, tool, doc) or - * for a lib. It is null if the element has not been specified in the repository XML. - */ - public String getLicense() { - return mLicense; - } - - /** - * Returns the optional description for all packages (platform, add-on, tool, doc) or - * for a lib. Can be empty but not null. - */ - public String getDescription() { - return mDescription; - } - - /** - * Returns the optional description URL for all packages (platform, add-on, tool, doc). - * Can be empty but not null. - */ - public String getDescUrl() { - return mDescUrl; - } - - /** - * Returns the optional release note for all packages (platform, add-on, tool, doc) or - * for a lib. Can be empty but not null. - */ - public String getReleaseNote() { - return mReleaseNote; - } - - /** - * Returns the optional release note URL for all packages (platform, add-on, tool, doc). - * Can be empty but not null. - */ - public String getReleaseNoteUrl() { - return mReleaseUrl; - } - - /** - * Returns the archives defined in this package. - * Can be an empty array but not null. - */ - public Archive[] getArchives() { - return mArchives; - } - - /** - * Returns true if this package contains the exact given archive. - * Important: This compares object references, not object equality. - */ - public boolean hasArchive(Archive archive) { - for (Archive a : mArchives) { - if (a == archive) { - return true; - } - } - return false; - } - - /** - * Returns whether the {@link Package} has at least one {@link Archive} compatible with - * the host platform. - */ - public boolean hasCompatibleArchive() { - for (Archive archive : mArchives) { - if (archive.isCompatible()) { - return true; - } - } - - return false; - } - - /** - * Returns a short, reasonably unique string identifier that can be used - * to identify this package when installing from the command-line interface. - * {@code 'android list sdk'} will show these IDs and then in turn they can - * be provided to {@code 'android update sdk --no-ui --filter'} to select - * some specific packages. - * <p/> - * The identifiers must have the following properties: <br/> - * - They must contain only simple alphanumeric characters. <br/> - * - Commas, whitespace and any special character that could be obviously problematic - * to a shell interface should be avoided (so dash/underscore are OK, but things - * like colon, pipe or dollar should be avoided.) <br/> - * - The name must be consistent across calls and reasonably unique for the package - * type. Collisions can occur but should be rare. <br/> - * - Different package types should have a clearly different name pattern. <br/> - * - The revision number should not be included, as this would prevent updates - * from being automated (which is the whole point.) <br/> - * - It must remain reasonably human readable. <br/> - * - If no such id can exist (for example for a local package that cannot be installed) - * then an empty string should be returned. Don't return null. - * <p/> - * Important: This is <em>not</em> a strong unique identifier for the package. - * If you need a strong unique identifier, you should use {@link #comparisonKey()} - * and the {@link Comparable} interface. - */ - public abstract String installId(); - - /** - * Returns the short description of the source, if not null. - * Otherwise returns the default Object toString result. - * <p/> - * This is mostly helpful for debugging. - * For UI display, use the {@link IDescription} interface. - */ - @Override - public String toString() { - String s = getShortDescription(); - if (s != null) { - return s; - } - return super.toString(); - } - - /** - * Returns a description of this package that is suitable for a list display. - * Should not be empty. Must never be null. - * <p/> - * Note that this is the "base" name for the package - * with no specific revision nor API mentionned. - * In contrast, {@link #getShortDescription()} should be used if you want more details - * such as the package revision number or the API, if applicable. - */ - public abstract String getListDescription(); - - /** - * Returns a short description for an {@link IDescription}. - * Can be empty but not null. - */ - @Override - public abstract String getShortDescription(); - - /** - * Returns a long description for an {@link IDescription}. - * Can be empty but not null. - */ - @Override - public String getLongDescription() { - StringBuilder sb = new StringBuilder(); - - String s = getDescription(); - if (s != null) { - sb.append(s); - } - if (sb.length() > 0) { - sb.append("\n"); - } - - sb.append(String.format("Revision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : "")); - - s = getDescUrl(); - if (s != null && s.length() > 0) { - sb.append(String.format("\n\nMore information at %1$s", s)); - } - - s = getReleaseNote(); - if (s != null && s.length() > 0) { - sb.append("\n\nRelease note:\n").append(s); - } - - s = getReleaseNoteUrl(); - if (s != null && s.length() > 0) { - sb.append("\nRelease note URL: ").append(s); - } - - return sb.toString(); - } - - /** - * A package is local (that is 'installed locally') if it contains a single - * archive that is local. If not local, it's a remote package, only available - * on a remote source for download and installation. - */ - public boolean isLocal() { - return mArchives.length == 1 && mArchives[0].isLocal(); - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * Some types of packages install in a fix location, for example docs and tools. - * In this case the returned folder may already exist with a different archive installed - * at the desired location. <br/> - * For other packages types, such as add-on or platform, the folder name is only partially - * relevant to determine the content and thus a real check will be done to provide an - * existing or new folder depending on the current content of the SDK. - * <p/> - * Note that the installer *will* create all directories returned here just before - * installation so this method must not attempt to create them. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - public abstract File getInstallFolder(String osSdkRoot, SdkManager sdkManager); - - /** - * Hook called right before an archive is installed. The archive has already - * been downloaded successfully and will be installed in the directory specified by - * <var>installFolder</var> when this call returns. - * <p/> - * The hook lets the package decide if installation of this specific archive should - * be continue. The installer will still install the remaining packages if possible. - * <p/> - * The base implementation always return true. - * <p/> - * Note that the installer *will* create all directories specified by - * {@link #getInstallFolder} just before installation, so they must not be - * created here. This is also called before the previous install dir is removed - * so the previous content is still there during upgrade. - * - * @param archive The archive that will be installed - * @param monitor The {@link ITaskMonitor} to display errors. - * @param osSdkRoot The OS path of the SDK root folder. - * @param installFolder The folder where the archive will be installed. Note that this - * is <em>not</em> the folder where the archive was temporary - * unzipped. The installFolder, if it exists, contains the old - * archive that will soon be replaced by the new one. - * @return True if installing this archive shall continue, false if it should be skipped. - */ - public boolean preInstallHook(Archive archive, ITaskMonitor monitor, - String osSdkRoot, File installFolder) { - // Nothing to do in base class. - return true; - } - - /** - * Hook called right after a file has been unzipped (during an install). - * <p/> - * The base class implementation makes sure to properly adjust set executable - * permission on Linux and MacOS system if the zip entry was marked as +x. - * - * @param archive The archive that is being installed. - * @param monitor The {@link ITaskMonitor} to display errors. - * @param fileOp The {@link IFileOp} used by the archive installer. - * @param unzippedFile The file that has just been unzipped in the install temp directory. - * @param zipEntry The {@link ZipArchiveEntry} that has just been unzipped. - */ - public void postUnzipFileHook( - Archive archive, - ITaskMonitor monitor, - IFileOp fileOp, - File unzippedFile, - ZipArchiveEntry zipEntry) { - - // if needed set the permissions. - if (sUsingUnixPerm && fileOp.isFile(unzippedFile)) { - // get the mode and test if it contains the executable bit - int mode = zipEntry.getUnixMode(); - if ((mode & 0111) != 0) { - try { - fileOp.setExecutablePermission(unzippedFile); - } catch (IOException ignore) {} - } - } - - } - - /** - * Hook called right after an archive has been installed. - * - * @param archive The archive that has been installed. - * @param monitor The {@link ITaskMonitor} to display errors. - * @param installFolder The folder where the archive was successfully installed. - * Null if the installation failed, in case the archive needs to - * do some cleanup after <code>preInstallHook</code>. - */ - public void postInstallHook(Archive archive, ITaskMonitor monitor, File installFolder) { - // Nothing to do in base class. - } - - /** - * Returns whether the give package represents the same item as the current package. - * <p/> - * Two packages are considered the same if they represent the same thing, except for the - * revision number. - * @param pkg the package to compare. - * @return true if the item as equivalent. - */ - public abstract boolean sameItemAs(Package pkg); - - /** - * Computes whether the given package is a suitable update for the current package. - * <p/> - * An update is just that: a new package that supersedes the current one. If the new - * package does not represent the same item or if it has the same or lower revision as the - * current one, it's not an update. - * - * @param replacementPackage The potential replacement package. - * @return One of the {@link UpdateInfo} values. - * - * @see #sameItemAs(Package) - */ - public abstract UpdateInfo canBeUpdatedBy(Package replacementPackage); - - /** - * Returns an ordering <b>suitable for display</b> like this: <br/> - * - Tools <br/> - * - Platform-Tools <br/> - * - Docs. <br/> - * - Platform n preview <br/> - * - Platform n <br/> - * - Platform n-1 <br/> - * - Samples packages <br/> - * - Add-on based on n preview <br/> - * - Add-on based on n <br/> - * - Add-on based on n-1 <br/> - * - Extra packages <br/> - * <p/> - * Important: this must NOT be used to compare if two packages are the same thing. - * This is achieved by {@link #sameItemAs(Package)} or {@link #canBeUpdatedBy(Package)}. - * <p/> - * The order done here is suitable for display, and this may not be the appropriate - * order when comparing whether packages are equal or of greater revision -- if you need - * to compare revisions, then use {@link #getRevision()}{@code .compareTo(rev)} directly. - * <p/> - * This {@link #compareTo(Package)} method is purely an implementation detail to - * perform the right ordering of the packages in the list of available or installed packages. - * <p/> - * <em>Important</em>: Derived classes should consider overriding {@link #comparisonKey()} - * instead of this method. - */ - @Override - public int compareTo(Package other) { - String s1 = this.comparisonKey(); - String s2 = other.comparisonKey(); - - int r = s1.compareTo(s2); - return r; - } - - /** - * Computes a comparison key for each package used by {@link #compareTo(Package)}. - * The key is a string. - * The base package class return a string that encodes the package type, - * the revision number and the platform version, if applicable, in the form: - * <pre> - * t:N|v:NNNN.P|r:NNNN| - * </pre> - * All fields must start by a "letter colon" prefix and end with a vertical pipe (|, ASCII 124). - * <p/> - * The string format <em>may</em> change between releases and clients should not - * store them outside of the session or expect them to be consistent between - * different releases. They are purely an internal implementation details of the - * {@link #compareTo(Package)} method. - * <p/> - * Derived classes should get the string from the super class and then append - * or <em>insert</em> their own |-separated content. - * For example an extra vendor name & path can be inserted before the revision - * number, since it has more sorting weight. - */ - protected String comparisonKey() { - - StringBuilder sb = new StringBuilder(); - - sb.append("t:"); //$NON-NLS-1$ - if (this instanceof ToolPackage) { - sb.append(0); - } else if (this instanceof PlatformToolPackage) { - sb.append(1); - } else if (this instanceof DocPackage) { - sb.append(2); - } else if (this instanceof PlatformPackage) { - sb.append(3); - } else if (this instanceof SamplePackage) { - sb.append(4); - } else if (this instanceof SystemImagePackage) { - sb.append(5); - } else if (this instanceof AddonPackage) { - sb.append(6); - } else { - // extras and everything else - sb.append(9); - } - - - // We insert the package version here because it is more important - // than the revision number. - // In the list display, we want package version to be sorted - // top-down, so we'll use 10k-api as the sorting key. The day we - // reach 10k APIs, we'll need to revisit this. - sb.append("|v:"); //$NON-NLS-1$ - if (this instanceof IAndroidVersionProvider) { - AndroidVersion v = ((IAndroidVersionProvider) this).getAndroidVersion(); - - sb.append(String.format("%1$04d.%2$d", //$NON-NLS-1$ - 10000 - v.getApiLevel(), - v.isPreview() ? 1 : 0 - )); - } - - // Append revision number - sb.append("|r:"); //$NON-NLS-1$ - FullRevision rev = getRevision(); - sb.append(rev.getMajor()).append('.') - .append(rev.getMinor()).append('.') - .append(rev.getMicro()).append('.'); - // Hack: When comparing packages for installation purposes, we want to treat - // "final releases" packages as more important than rc/preview packages. - // However like for the API level above, when sorting for list display purposes - // we want the final release package listed before its rc/preview packages. - if (rev.isPreview()) { - sb.append(rev.getPreview()); - } else { - sb.append('0'); // 0=Final (!preview), to make "18.0" < "18.1" (18 Final < 18 RC1) - } - - sb.append('|'); - return sb.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(mArchives); - result = prime * result + ((mObsolete == null) ? 0 : mObsolete.hashCode()); - result = prime * result + getRevision().hashCode(); - result = prime * result + ((mSource == null) ? 0 : mSource.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof Package)) { - return false; - } - Package other = (Package) obj; - if (!Arrays.equals(mArchives, other.mArchives)) { - return false; - } - if (mObsolete == null) { - if (other.mObsolete != null) { - return false; - } - } else if (!mObsolete.equals(other.mObsolete)) { - return false; - } - if (!getRevision().equals(other.getRevision())) { - return false; - } - if (mSource == null) { - if (other.mSource != null) { - return false; - } - } else if (!mSource.equals(other.mSource)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PackageParserUtils.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PackageParserUtils.java deleted file mode 100755 index a6986e1..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PackageParserUtils.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Node; - -/** - * Misc utilities to help extracting elements and attributes out of an XML document. - */ -public class PackageParserUtils { - - /** - * Parses a full revision element such as <revision> or <min-tools-rev>. - * This supports both the single-integer format as well as the full revision - * format with major/minor/micro/preview sub-elements. - * - * @param revisionNode The node to parse. - * @return A new {@link FullRevision}. If parsing failed, major is set to - * {@link FullRevision#MISSING_MAJOR_REV}. - */ - public static FullRevision parseFullRevisionElement(Node revisionNode) { - // This needs to support two modes: - // - For repository XSD >= 7, <revision> contains sub-elements such as <major> or <minor>. - // - Otherwise for repository XSD < 7, <revision> contains an integer. - // The <major> element is mandatory, so it's easy to distinguish between both cases. - int major = FullRevision.MISSING_MAJOR_REV, - minor = FullRevision.IMPLICIT_MINOR_REV, - micro = FullRevision.IMPLICIT_MICRO_REV, - preview = FullRevision.NOT_A_PREVIEW; - - if (revisionNode != null) { - if (PackageParserUtils.findChildElement(revisionNode, - SdkRepoConstants.NODE_MAJOR_REV) != null) { - // <revision> has a <major> sub-element, so it's a repository XSD >= 7. - major = PackageParserUtils.getXmlInt(revisionNode, - SdkRepoConstants.NODE_MAJOR_REV, FullRevision.MISSING_MAJOR_REV); - minor = PackageParserUtils.getXmlInt(revisionNode, - SdkRepoConstants.NODE_MINOR_REV, FullRevision.IMPLICIT_MINOR_REV); - micro = PackageParserUtils.getXmlInt(revisionNode, - SdkRepoConstants.NODE_MICRO_REV, FullRevision.IMPLICIT_MICRO_REV); - preview = PackageParserUtils.getXmlInt(revisionNode, - SdkRepoConstants.NODE_PREVIEW, FullRevision.NOT_A_PREVIEW); - } else { - try { - String majorStr = revisionNode.getTextContent().trim(); - major = Integer.parseInt(majorStr); - } catch (Exception e) { - } - } - } - - return new FullRevision(major, minor, micro, preview); - } - - /** - * Returns the first child element with the given XML local name. - * If xmlLocalName is null, returns the very first child element. - */ - public static Node findChildElement(Node node, String xmlLocalName) { - if (node != null) { - String nsUri = node.getNamespaceURI(); - for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI())) { - if (xmlLocalName == null || xmlLocalName.equals(child.getLocalName())) { - return child; - } - } - } - } - return null; - } - - /** - * Retrieves the value of that XML element as a string. - * Returns an empty string whether the element is missing or empty, - * so you can't tell the difference. - * <p/> - * Note: use {@link #getOptionalXmlString(Node, String)} if you need to know when the - * element is missing versus empty. - * - * @param node The XML <em>parent</em> node to parse. - * @param xmlLocalName The XML local name to find in the parent node. - * @return The text content of the element. Returns an empty string whether the element - * is missing or empty, so you can't tell the difference. - */ - public static String getXmlString(Node node, String xmlLocalName) { - Node child = findChildElement(node, xmlLocalName); - - return child == null ? "" : child.getTextContent(); //$NON-NLS-1$ - } - - /** - * Retrieves the value of that XML element as a string. - * Returns null when the element is missing, so you can tell between a missing element - * and an empty one. - * <p/> - * Note: use {@link #getXmlString(Node, String)} if you don't need to know when the - * element is missing versus empty. - * - * @param node The XML <em>parent</em> node to parse. - * @param xmlLocalName The XML local name to find in the parent node. - * @return The text content of the element. Returns null when the element is missing. - * Returns an empty string whether the element is present but empty. - */ - public static String getOptionalXmlString(Node node, String xmlLocalName) { - Node child = findChildElement(node, xmlLocalName); - - return child == null ? null : child.getTextContent(); //$NON-NLS-1$ - } - - /** - * Retrieves the value of that XML element as an integer. - * Returns the default value when the element is missing or is not an integer. - */ - public static int getXmlInt(Node node, String xmlLocalName, int defaultValue) { - String s = getXmlString(node, xmlLocalName); - try { - return Integer.parseInt(s); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - /** - * Retrieves the value of that XML element as a long. - * Returns the default value when the element is missing or is not an integer. - */ - public static long getXmlLong(Node node, String xmlLocalName, long defaultValue) { - String s = getXmlString(node, xmlLocalName); - try { - return Long.parseLong(s); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - /** - * Retrieve an attribute which value must match one of the given enums using a - * case-insensitive name match. - * - * Returns defaultValue if the attribute does not exist or its value does not match - * the given enum values. - */ - public static Object getEnumAttribute( - Node archiveNode, - String attrName, - Object[] values, - Object defaultValue) { - - Node attr = archiveNode.getAttributes().getNamedItem(attrName); - if (attr != null) { - String found = attr.getNodeValue(); - for (Object value : values) { - if (value.toString().equalsIgnoreCase(found)) { - return value; - } - } - } - - return defaultValue; - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PlatformPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PlatformPackage.java deleted file mode 100755 index 71d91ef..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PlatformPackage.java +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.utils.Pair; - -import org.w3c.dom.Node; - -import java.io.File; -import java.util.Map; -import java.util.Properties; - -/** - * Represents a platform XML node in an SDK repository. - */ -public class PlatformPackage extends MinToolsPackage - implements IAndroidVersionProvider, ILayoutlibVersion { - - /** The package version, for platform, add-on and doc packages. */ - private final AndroidVersion mVersion; - - /** The version, a string, for platform packages. */ - private final String mVersionName; - - /** The ABI of the system-image included in this platform. Can be null but not empty. */ - private final String mIncludedAbi; - - /** The helper handling the layoutlib version. */ - private final LayoutlibVersionMixin mLayoutlibVersion; - - /** - * Creates a new platform package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public PlatformPackage( - SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - mVersionName = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_VERSION); - - int apiLevel = - PackageParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); - String codeName = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); - if (codeName.length() == 0) { - codeName = null; - } - mVersion = new AndroidVersion(apiLevel, codeName); - - mIncludedAbi = PackageParserUtils.getOptionalXmlString(packageNode, - SdkRepoConstants.NODE_ABI_INCLUDED); - - mLayoutlibVersion = new LayoutlibVersionMixin(packageNode); - } - - /** - * Creates a new platform package based on an actual {@link IAndroidTarget} (which - * must have {@link IAndroidTarget#isPlatform()} true) from the {@link SdkManager}. - * This is used to list local SDK folders in which case there is one archive which - * URL is the actual target location. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public static Package create(IAndroidTarget target, Properties props) { - return new PlatformPackage(target, props); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected PlatformPackage(IAndroidTarget target, Properties props) { - this(null /*source*/, target, props); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected PlatformPackage(SdkSource source, IAndroidTarget target, Properties props) { - super( source, //source - props, //properties - target.getRevision(), //revision - null, //license - target.getDescription(), //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - target.getLocation() //archiveOsPath - ); - - mVersion = target.getVersion(); - mVersionName = target.getVersionName(); - mLayoutlibVersion = new LayoutlibVersionMixin(props); - mIncludedAbi = props == null ? null : props.getProperty(PkgProps.PLATFORM_INCLUDED_ABI); - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be given to a constructor that takes a {@link Properties} object. - */ - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - mVersion.saveProperties(props); - mLayoutlibVersion.saveProperties(props); - - if (mVersionName != null) { - props.setProperty(PkgProps.PLATFORM_VERSION, mVersionName); - } - - if (mIncludedAbi != null) { - props.setProperty(PkgProps.PLATFORM_INCLUDED_ABI, mIncludedAbi); - } - - } - - /** Returns the version, a string, for platform packages. */ - public String getVersionName() { - return mVersionName; - } - - /** Returns the package version, for platform, add-on and doc packages. */ - @Override @NonNull - public AndroidVersion getAndroidVersion() { - return mVersion; - } - - /** - * Returns the ABI of the system-image included in this platform. - * - * @return Null if the platform does not include any system-image. - * Otherwise should be a valid non-empty ABI string (e.g. "x86" or "armeabi-v7a"). - */ - public String getIncludedAbi() { - return mIncludedAbi; - } - - /** - * Returns the layoutlib version. Mandatory starting with repository XSD rev 4. - * <p/> - * The first integer is the API of layoublib, which should be > 0. - * It will be equal to {@link ILayoutlibVersion#LAYOUTLIB_API_NOT_SPECIFIED} (0) - * if the layoutlib version isn't specified. - * <p/> - * The second integer is the revision for that given API. It is >= 0 - * and works as a minor revision number, incremented for the same API level. - * - * @since sdk-repository-4.xsd - */ - @Override - public Pair<Integer, Integer> getLayoutlibVersion() { - return mLayoutlibVersion.getLayoutlibVersion(); - } - - /** - * Returns a string identifier to install this package from the command line. - * For platforms, we use "android-N" where N is the API or the preview codename. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - return "android-" + mVersion.getApiString(); //$NON-NLS-1$ - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - String s; - - if (mVersion.isPreview()) { - s = String.format("SDK Platform Android %1$s Preview%2$s", - getVersionName(), - isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$ - } else { - s = String.format("SDK Platform Android %1$s%2$s", - getVersionName(), - isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$ - } - - return s; - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - String s; - - if (mVersion.isPreview()) { - s = String.format("SDK Platform Android %1$s Preview, revision %2$s%3$s", - getVersionName(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$ - } else { - s = String.format("SDK Platform Android %1$s, API %2$d, revision %3$s%4$s", - getVersionName(), - mVersion.getApiLevel(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); //$NON-NLS-2$ - } - - return s; - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description is whatever the XML contains for the <description> field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - String s = getDescription(); - if (s == null || s.length() == 0) { - s = getShortDescription(); - } - - if (s.indexOf("revision") == -1) { - s += String.format("\nRevision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A platform package is typically installed in SDK/platforms/android-"version". - * However if we can find a different directory under SDK/platform that already - * has this platform version installed, we'll use that one. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - - // First find if this platform is already installed. If so, reuse the same directory. - for (IAndroidTarget target : sdkManager.getTargets()) { - if (target.isPlatform() && target.getVersion().equals(mVersion)) { - return new File(target.getLocation()); - } - } - - File platforms = new File(osSdkRoot, SdkConstants.FD_PLATFORMS); - File folder = new File(platforms, - String.format("android-%s", getAndroidVersion().getApiString())); //$NON-NLS-1$ - - return folder; - } - - @Override - public boolean sameItemAs(Package pkg) { - if (pkg instanceof PlatformPackage) { - PlatformPackage newPkg = (PlatformPackage)pkg; - - // check they are the same version. - return newPkg.getAndroidVersion().equals(this.getAndroidVersion()); - } - - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + - ((mLayoutlibVersion == null) ? 0 : mLayoutlibVersion.hashCode()); - result = prime * result + ((mVersion == null) ? 0 : mVersion.hashCode()); - result = prime * result + ((mVersionName == null) ? 0 : mVersionName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof PlatformPackage)) { - return false; - } - PlatformPackage other = (PlatformPackage) obj; - if (mLayoutlibVersion == null) { - if (other.mLayoutlibVersion != null) { - return false; - } - } else if (!mLayoutlibVersion.equals(other.mLayoutlibVersion)) { - return false; - } - if (mVersion == null) { - if (other.mVersion != null) { - return false; - } - } else if (!mVersion.equals(other.mVersion)) { - return false; - } - if (mVersionName == null) { - if (other.mVersionName != null) { - return false; - } - } else if (!mVersionName.equals(other.mVersionName)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PlatformToolPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PlatformToolPackage.java deleted file mode 100755 index c46e940..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/PlatformToolPackage.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.AdbWrapper; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; - -import org.w3c.dom.Node; - -import java.io.File; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -/** - * Represents a platform-tool XML node in an SDK repository. - */ -public class PlatformToolPackage extends FullRevisionPackage { - - /** The value returned by {@link PlatformToolPackage#installId()}. */ - public static final String INSTALL_ID = "platform-tools"; //$NON-NLS-1$ - /** The value returned by {@link PlatformToolPackage#installId()}. */ - public static final String INSTALL_ID_PREVIEW = "platform-tools-preview"; //$NON-NLS-1$ - - /** - * Creates a new platform-tool package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public PlatformToolPackage(SdkSource source, Node packageNode, - String nsUri, Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - } - - /** - * Manually create a new package with one archive and the given attributes or properties. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public static Package create( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - - PlatformToolPackage ptp = new PlatformToolPackage(source, props, revision, license, - description, descUrl, archiveOs, archiveArch, archiveOsPath); - - File platformToolsFolder = new File(archiveOsPath); - String error = null; - if (!platformToolsFolder.isDirectory()) { - error = "platform-tools folder is missing"; - } else { - File[] files = platformToolsFolder.listFiles(); - if (files == null || files.length == 0) { - error = "platform-tools folder is empty"; - } else { - Set<String> names = new HashSet<String>(); - for (File file : files) { - names.add(file.getName()); - } - for (String name : new String[] { SdkConstants.FN_ADB, - SdkConstants.FN_AAPT, - SdkConstants.FN_AIDL, - SdkConstants.FN_DX } ) { - if (!names.contains(name)) { - if (error == null) { - error = "platform-tools folder is missing "; - } else { - error += ", "; - } - error += name; - } - } - } - } - - if (error != null) { - String shortDesc = ptp.getShortDescription() + " [*]"; //$NON-NLS-1$ - - String longDesc = String.format( - "Broken Platform-Tools Package: %1$s\n" + - "[*] Package cannot be used due to error: %2$s", - description, - error); - - BrokenPackage ba = new BrokenPackage(props, shortDesc, longDesc, - IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED, - IExactApiLevelDependency.API_LEVEL_INVALID, - archiveOsPath); - return ba; - } - - - return ptp; - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected PlatformToolPackage( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, - props, - revision, - license, - description, - descUrl, - archiveOs, - archiveArch, - archiveOsPath); - } - - /** - * Returns a string identifier to install this package from the command line. - * For platform-tools, we use "platform-tools" or "platform-tools-preview" since - * this package type is unique. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - if (getRevision().isPreview()) { - return INSTALL_ID_PREVIEW; - } else { - return INSTALL_ID; - } - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - return String.format("Android SDK Platform-tools%1$s", - isObsolete() ? " (Obsolete)" : ""); - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - return String.format("Android SDK Platform-tools, revision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - /** Returns a long description for an {@link IDescription}. */ - @Override - public String getLongDescription() { - String s = getDescription(); - if (s == null || s.length() == 0) { - s = getShortDescription(); - } - - if (s.indexOf("revision") == -1) { - s += String.format("\nRevision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A "tool" package should always be located in SDK/tools. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - return new File(osSdkRoot, SdkConstants.FD_PLATFORM_TOOLS); - } - - /** - * Check whether 2 platform-tool packages are the same <em>and</em> have the - * same preview bit. - */ - @Override - public boolean sameItemAs(Package pkg) { - return sameItemAs(pkg, false /*ignorePreviews*/); - } - - @Override - public boolean sameItemAs(Package pkg, boolean ignorePreviews) { - // only one platform-tool package so any platform-tool package is the same item. - if (pkg instanceof PlatformToolPackage) { - if (ignorePreviews) { - return true; - } else { - // however previews can only match previews by default, unless we ignore that check. - return ((PlatformToolPackage) pkg).getRevision().isPreview() == - getRevision().isPreview(); - } - } - return false; - } - - /** - * Hook called right before an archive is installed. - * This is used here to stop ADB before trying to replace the platform-tool package. - * - * @param archive The archive that will be installed - * @param monitor The {@link ITaskMonitor} to display errors. - * @param osSdkRoot The OS path of the SDK root folder. - * @param installFolder The folder where the archive will be installed. Note that this - * is <em>not</em> the folder where the archive was temporary - * unzipped. The installFolder, if it exists, contains the old - * archive that will soon be replaced by the new one. - * @return True if installing this archive shall continue, false if it should be skipped. - */ - @Override - public boolean preInstallHook(Archive archive, ITaskMonitor monitor, - String osSdkRoot, File installFolder) { - AdbWrapper aw = new AdbWrapper(osSdkRoot, monitor); - aw.stopAdb(); - return super.preInstallHook(archive, monitor, osSdkRoot, installFolder); - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SamplePackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SamplePackage.java deleted file mode 100755 index 06eabb9..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SamplePackage.java +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.AndroidVersion.AndroidVersionException; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.io.IFileOp; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.w3c.dom.Node; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Map; -import java.util.Properties; - -/** - * Represents a sample XML node in an SDK repository. - */ -public class SamplePackage extends MinToolsPackage - implements IAndroidVersionProvider, IMinApiLevelDependency { - - /** The matching platform version. */ - private final AndroidVersion mVersion; - - /** - * The minimal API level required by this extra package, if > 0, - * or {@link #MIN_API_LEVEL_NOT_SPECIFIED} if there is no such requirement. - */ - private final int mMinApiLevel; - - /** - * Creates a new sample package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public SamplePackage(SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - int apiLevel = - PackageParserUtils.getXmlInt (packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); - String codeName = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); - if (codeName.length() == 0) { - codeName = null; - } - mVersion = new AndroidVersion(apiLevel, codeName); - - mMinApiLevel = PackageParserUtils.getXmlInt(packageNode, - SdkRepoConstants.NODE_MIN_API_LEVEL, - MIN_API_LEVEL_NOT_SPECIFIED); - } - - /** - * Creates a new sample package based on an actual {@link IAndroidTarget} (which - * must have {@link IAndroidTarget#isPlatform()} true) from the {@link SdkManager}. - * <p/> - * The target <em>must</em> have an existing sample directory that uses the /samples - * root form rather than the old form where the samples dir was located under the - * platform dir. - * <p/> - * This is used to list local SDK folders in which case there is one archive which - * URL is the actual samples path location. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public static Package create(IAndroidTarget target, Properties props) { - return new SamplePackage(target, props); - } - - private SamplePackage(IAndroidTarget target, Properties props) { - super( null, //source - props, //properties - 0, //revision will be taken from props - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - target.getPath(IAndroidTarget.SAMPLES) //archiveOsPath - ); - - mVersion = target.getVersion(); - - mMinApiLevel = getPropertyInt(props, PkgProps.SAMPLE_MIN_API_LEVEL, - MIN_API_LEVEL_NOT_SPECIFIED); - } - - /** - * Creates a new sample package from an actual directory path and previously - * saved properties. - * <p/> - * This is used to list local SDK folders in which case there is one archive which - * URL is the actual samples path location. - * <p/> - * By design, this creates a package with one and only one archive. - * - * @throws AndroidVersionException if the {@link AndroidVersion} can't be restored - * from properties. - */ - public static Package create(String archiveOsPath, Properties props) - throws AndroidVersionException { - return new SamplePackage(archiveOsPath, props); - } - - private SamplePackage(String archiveOsPath, Properties props) throws AndroidVersionException { - super(null, //source - props, //properties - 0, //revision will be taken from props - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - archiveOsPath //archiveOsPath - ); - - mVersion = new AndroidVersion(props); - - mMinApiLevel = getPropertyInt(props, PkgProps.SAMPLE_MIN_API_LEVEL, - MIN_API_LEVEL_NOT_SPECIFIED); - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be given to a constructor that takes a {@link Properties} object. - */ - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - mVersion.saveProperties(props); - - if (getMinApiLevel() != MIN_API_LEVEL_NOT_SPECIFIED) { - props.setProperty(PkgProps.SAMPLE_MIN_API_LEVEL, Integer.toString(getMinApiLevel())); - } - } - - /** - * Returns the minimal API level required by this extra package, if > 0, - * or {@link #MIN_API_LEVEL_NOT_SPECIFIED} if there is no such requirement. - */ - @Override - public int getMinApiLevel() { - return mMinApiLevel; - } - - /** Returns the matching platform version. */ - @Override @NonNull - public AndroidVersion getAndroidVersion() { - return mVersion; - } - - /** - * Returns a string identifier to install this package from the command line. - * For samples, we use "sample-N" where N is the API or the preview codename. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - return "sample-" + mVersion.getApiString(); //$NON-NLS-1$ - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - String s = String.format("Samples for SDK API %1$s%2$s%3$s", - mVersion.getApiString(), - mVersion.isPreview() ? " Preview" : "", - isObsolete() ? " (Obsolete)" : ""); - return s; - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - String s = String.format("Samples for SDK API %1$s%2$s, revision %3$s%4$s", - mVersion.getApiString(), - mVersion.isPreview() ? " Preview" : "", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - return s; - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description is whatever the XML contains for the <description> field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - String s = getDescription(); - if (s == null || s.length() == 0) { - s = getShortDescription(); - } - - if (s.indexOf("revision") == -1) { - s += String.format("\nRevision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A sample package is typically installed in SDK/samples/android-"version". - * However if we can find a different directory that already has this sample - * version installed, we'll use that one. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - - // The /samples dir at the root of the SDK - File samplesRoot = new File(osSdkRoot, SdkConstants.FD_SAMPLES); - - // First find if this sample is already installed. If so, reuse the same directory. - for (IAndroidTarget target : sdkManager.getTargets()) { - if (target.isPlatform() && - target.getVersion().equals(mVersion)) { - String p = target.getPath(IAndroidTarget.SAMPLES); - File f = new File(p); - if (f.isDirectory()) { - // We *only* use this directory if it's using the "new" location - // under SDK/samples. We explicitly do not reuse the "old" location - // under SDK/platform/android-N/samples. - if (f.getParentFile().equals(samplesRoot)) { - return f; - } - } - } - } - - // Otherwise, get a suitable default - File folder = new File(samplesRoot, - String.format("android-%s", getAndroidVersion().getApiString())); //$NON-NLS-1$ - - for (int n = 1; folder.exists(); n++) { - // Keep trying till we find an unused directory. - folder = new File(samplesRoot, - String.format("android-%s_%d", getAndroidVersion().getApiString(), n)); //$NON-NLS-1$ - } - - return folder; - } - - @Override - public boolean sameItemAs(Package pkg) { - if (pkg instanceof SamplePackage) { - SamplePackage newPkg = (SamplePackage)pkg; - - // check they are the same version. - return newPkg.getAndroidVersion().equals(this.getAndroidVersion()); - } - - return false; - } - - /** - * Makes sure the base /samples folder exists before installing. - * - * {@inheritDoc} - */ - @Override - public boolean preInstallHook(Archive archive, - ITaskMonitor monitor, - String osSdkRoot, - File installFolder) { - - if (installFolder != null && installFolder.isDirectory()) { - // Get the hash computed during the last installation - String storedHash = readContentHash(installFolder); - if (storedHash != null && storedHash.length() > 0) { - - // Get the hash of the folder now - String currentHash = computeContentHash(installFolder); - - if (!storedHash.equals(currentHash)) { - // The hashes differ. The content was modified. - // Ask the user if we should still wipe the old samples. - - String pkgName = archive.getParentPackage().getShortDescription(); - - String msg = String.format( - "-= Warning ! =-\n" + - "You are about to replace the content of the folder:\n " + - " %1$s\n" + - "by the new package:\n" + - " %2$s.\n" + - "\n" + - "However it seems that the content of the existing samples " + - "has been modified since it was last installed. Are you sure " + - "you want to DELETE the existing samples? This cannot be undone.\n" + - "Please select YES to delete the existing sample and replace them " + - "by the new ones.\n" + - "Please select NO to skip this package. You can always install it later.", - installFolder.getAbsolutePath(), - pkgName); - - // Returns true if we can wipe & replace. - return monitor.displayPrompt("SDK Manager: overwrite samples?", msg); - } - } - } - - // The default is to allow installation - return super.preInstallHook(archive, monitor, osSdkRoot, installFolder); - } - - /** - * Computes a hash of the installed content (in case of successful install.) - * - * {@inheritDoc} - */ - @Override - public void postInstallHook(Archive archive, ITaskMonitor monitor, File installFolder) { - super.postInstallHook(archive, monitor, installFolder); - - if (installFolder != null) { - String h = computeContentHash(installFolder); - saveContentHash(installFolder, h); - } - } - - /** - * Set all the files from a sample package as read-only so that - * users don't end up modifying sources by mistake in Eclipse - * (samples are copied if using the NPW > Create from sample.) - */ - @Override - public void postUnzipFileHook( - Archive archive, - ITaskMonitor monitor, - IFileOp fileOp, - File unzippedFile, - ZipArchiveEntry zipEntry) { - super.postUnzipFileHook(archive, monitor, fileOp, unzippedFile, zipEntry); - - if (fileOp.isFile(unzippedFile) && - !SdkConstants.FN_SOURCE_PROP.equals(unzippedFile.getName())) { - fileOp.setReadOnly(unzippedFile); - } - } - - /** - * Reads the hash from the properties file, if it exists. - * Returns null if something goes wrong, e.g. there's no property file or - * it doesn't contain our hash. Returns an empty string if the hash wasn't - * correctly computed last time by {@link #saveContentHash(File, String)}. - */ - private String readContentHash(File folder) { - Properties props = new Properties(); - - FileInputStream fis = null; - try { - File f = new File(folder, SdkConstants.FN_CONTENT_HASH_PROP); - if (f.isFile()) { - fis = new FileInputStream(f); - props.load(fis); - return props.getProperty("content-hash", null); //$NON-NLS-1$ - } - } catch (Exception e) { - // ignore - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - } - } - } - - return null; - } - - /** - * Saves the hash using a properties file - */ - private void saveContentHash(File folder, String hash) { - Properties props = new Properties(); - - props.setProperty("content-hash", hash == null ? "" : hash); //$NON-NLS-1$ //$NON-NLS-2$ - - FileOutputStream fos = null; - try { - File f = new File(folder, SdkConstants.FN_CONTENT_HASH_PROP); - fos = new FileOutputStream(f); - props.store( fos, "## Android - hash of this archive."); //$NON-NLS-1$ - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - } - } - } - } - - /** - * Computes a hash of the files names and sizes installed in the folder - * using the SHA-1 digest. - * Returns null if the digest algorithm is not available. - */ - private String computeContentHash(File installFolder) { - MessageDigest md = null; - try { - // SHA-1 is a standard algorithm. - // http://java.sun.com/j2se/1.4.2/docs/guide/security/CryptoSpec.html#AppB - md = MessageDigest.getInstance("SHA-1"); //$NON-NLS-1$ - } catch (NoSuchAlgorithmException e) { - // We're unlikely to get there unless this JVM is not spec conforming - // in which case there won't be any hash available. - } - - if (md != null) { - hashDirectoryContent(installFolder, md); - return getDigestHexString(md); - } - - return null; - } - - /** - * Computes a hash of the *content* of this directory. The hash only uses - * the files names and the file sizes. - */ - private void hashDirectoryContent(File folder, MessageDigest md) { - if (folder == null || md == null || !folder.isDirectory()) { - return; - } - - for (File f : folder.listFiles()) { - if (f.isDirectory()) { - hashDirectoryContent(f, md); - - } else { - String name = f.getName(); - - // Skip the file we use to store the content hash - if (name == null || SdkConstants.FN_CONTENT_HASH_PROP.equals(name)) { - continue; - } - - try { - md.update(name.getBytes("UTF-8")); //$NON-NLS-1$ - } catch (UnsupportedEncodingException e) { - // There is no valid reason for UTF-8 to be unsupported. Ignore. - } - try { - long len = f.length(); - md.update((byte) (len & 0x0FF)); - md.update((byte) ((len >> 8) & 0x0FF)); - md.update((byte) ((len >> 16) & 0x0FF)); - md.update((byte) ((len >> 24) & 0x0FF)); - - } catch (SecurityException e) { - // Might happen if file is not readable. Ignore. - } - } - } - } - - /** - * Returns a digest as an hex string. - */ - private String getDigestHexString(MessageDigest digester) { - // Create an hex string from the digest - byte[] digest = digester.digest(); - int n = digest.length; - String hex = "0123456789abcdef"; //$NON-NLS-1$ - char[] hexDigest = new char[n * 2]; - for (int i = 0; i < n; i++) { - int b = digest[i] & 0x0FF; - hexDigest[i*2 + 0] = hex.charAt(b >>> 4); - hexDigest[i*2 + 1] = hex.charAt(b & 0x0f); - } - - return new String(hexDigest); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SourcePackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SourcePackage.java deleted file mode 100755 index fb38f40..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SourcePackage.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.AndroidVersion.AndroidVersionException; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.io.IFileOp; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.w3c.dom.Node; - -import java.io.File; -import java.util.Map; -import java.util.Properties; - -/** - * Represents a source XML node in an SDK repository. - * <p/> - * Note that a source package has a version and thus implements {@link IAndroidVersionProvider}. - * However there is no mandatory dependency that limits installation so this does not - * implement {@link IPlatformDependency}. - */ -public class SourcePackage extends MajorRevisionPackage implements IAndroidVersionProvider { - - /** The package version, for platform, add-on and doc packages. */ - private final AndroidVersion mVersion; - - /** - * Creates a new source package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public SourcePackage(SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - int apiLevel = - PackageParserUtils.getXmlInt(packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); - String codeName = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); - if (codeName.length() == 0) { - codeName = null; - } - mVersion = new AndroidVersion(apiLevel, codeName); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected SourcePackage( - AndroidVersion platformVersion, - int revision, - Properties props, - String localOsPath) { - this(null /*source*/, platformVersion, revision, props, localOsPath); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected SourcePackage( - SdkSource source, - AndroidVersion platformVersion, - int revision, - Properties props, - String localOsPath) { - super( source, //source - props, //properties - revision, //revision - null, //license - null, //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - localOsPath //archiveOsPath - ); - mVersion = platformVersion; - } - - /** - * Creates either a valid {@link SourcePackage} or a {@link BrokenPackage}. - * <p/> - * If the source directory contains valid properties, this creates a new {@link SourcePackage} - * with the android version listed in the properties. - * Otherwise returns a new {@link BrokenPackage} with some explanation on what failed. - * - * @param srcDir The SDK/sources/android-N folder - * @param props The properties located in {@code srcDir} or null if not found. - * @return A new {@link SourcePackage} or a new {@link BrokenPackage}. - */ - public static Package create(File srcDir, Properties props) { - AndroidVersion version = null; - String error = null; - - // Try to load the android version from the sources.props. - // If we don't find them, it would explain why this package is broken. - if (props == null) { - error = String.format("Missing file %1$s", SdkConstants.FN_SOURCE_PROP); - } else { - try { - version = new AndroidVersion(props); - // The constructor will extract the revision from the properties - // and it will not consider a missing revision as being fatal. - return new SourcePackage(version, 0 /*revision*/, props, srcDir.getAbsolutePath()); - } catch (AndroidVersionException e) { - error = String.format("Invalid file %1$s: %2$s", - SdkConstants.FN_SOURCE_PROP, - e.getMessage()); - } - } - - if (version == null) { - try { - // Try to parse the first number out of the platform folder name. - // This is just a wild guess in case we can create a broken package using that info. - String platform = srcDir.getParentFile().getName(); - platform = platform.replaceAll("[^0-9]+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$ - int pos = platform.indexOf(' '); - if (pos >= 0) { - platform = platform.substring(0, pos); - } - int apiLevel = Integer.parseInt(platform); - version = new AndroidVersion(apiLevel, null /*codename*/); - } catch (Exception ignore) { - } - } - - StringBuilder sb = new StringBuilder("Broken Source Package"); - if (version != null) { - sb.append(String.format(", API %1$s", version.getApiString())); - } - - String shortDesc = sb.toString(); - - if (error != null) { - sb.append('\n').append(error); - } - - String longDesc = sb.toString(); - - return new BrokenPackage(props, shortDesc, longDesc, - IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED, - version==null ? IExactApiLevelDependency.API_LEVEL_INVALID : version.getApiLevel(), - srcDir.getAbsolutePath()); - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be given to a constructor that takes a {@link Properties} object. - */ - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - mVersion.saveProperties(props); - } - - /** - * Returns the android version of this package. - */ - @Override @NonNull - public AndroidVersion getAndroidVersion() { - return mVersion; - } - - /** - * Returns a string identifier to install this package from the command line. - * For sources, we use "source-N" where N is the API or the preview codename. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - return "source-" + mVersion.getApiString(); //$NON-NLS-1$ - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - if (mVersion.isPreview()) { - return String.format("Sources for Android '%1$s' Preview SDK%2$s", - mVersion.getCodename(), - isObsolete() ? " (Obsolete)" : ""); - } else { - return String.format("Sources for Android SDK%2$s", - mVersion.getApiLevel(), - isObsolete() ? " (Obsolete)" : ""); - } - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - if (mVersion.isPreview()) { - return String.format("Sources for Android '%1$s' Preview SDK, revision %2$s%3$s", - mVersion.getCodename(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } else { - return String.format("Sources for Android SDK, API %1$d, revision %2$s%3$s", - mVersion.getApiLevel(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description is whatever the XML contains for the {@code description} field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - String s = getDescription(); - if (s == null || s.length() == 0) { - s = getShortDescription(); - } - - if (s.indexOf("revision") == -1) { - s += String.format("\nRevision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A sources package is typically installed in SDK/sources/platform. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - File folder = new File(osSdkRoot, SdkConstants.FD_PKG_SOURCES); - folder = new File(folder, "android-" + mVersion.getApiString()); //$NON-NLS-1$ - return folder; - } - - /** - * Set all the files from a source package as read-only - * so that users don't end up modifying sources by mistake in Eclipse. - */ - @Override - public void postUnzipFileHook( - Archive archive, - ITaskMonitor monitor, - IFileOp fileOp, - File unzippedFile, - ZipArchiveEntry zipEntry) { - super.postUnzipFileHook(archive, monitor, fileOp, unzippedFile, zipEntry); - - if (fileOp.isFile(unzippedFile) && - !SdkConstants.FN_SOURCE_PROP.equals(unzippedFile.getName())) { - fileOp.setReadOnly(unzippedFile); - } - } - - @Override - public boolean sameItemAs(Package pkg) { - if (pkg instanceof SourcePackage) { - SourcePackage newPkg = (SourcePackage)pkg; - - // check they are the same version. - return getAndroidVersion().equals(newPkg.getAndroidVersion()); - } - - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((mVersion == null) ? 0 : mVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof SourcePackage)) { - return false; - } - SourcePackage other = (SourcePackage) obj; - if (mVersion == null) { - if (other.mVersion != null) { - return false; - } - } else if (!mVersion.equals(other.mVersion)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SystemImagePackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SystemImagePackage.java deleted file mode 100755 index 69335a5..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/SystemImagePackage.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.AndroidVersion.AndroidVersionException; -import com.android.sdklib.SdkManager; -import com.android.sdklib.SystemImage; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Node; - -import java.io.File; -import java.util.Locale; -import java.util.Map; -import java.util.Properties; - -/** - * Represents a system-image XML node in an SDK repository. - */ -public class SystemImagePackage extends MajorRevisionPackage - implements IAndroidVersionProvider, IPlatformDependency { - - /** The package version, for platform, add-on and doc packages. */ - private final AndroidVersion mVersion; - - /** The ABI of the system-image. Must not be null nor empty. */ - private final String mAbi; - - /** - * Creates a new system-image package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public SystemImagePackage(SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - int apiLevel = - PackageParserUtils.getXmlInt(packageNode, SdkRepoConstants.NODE_API_LEVEL, 0); - String codeName = - PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_CODENAME); - if (codeName.length() == 0) { - codeName = null; - } - mVersion = new AndroidVersion(apiLevel, codeName); - - mAbi = PackageParserUtils.getXmlString(packageNode, SdkRepoConstants.NODE_ABI); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - public SystemImagePackage( - AndroidVersion platformVersion, - int revision, - String abi, - Properties props, - String localOsPath) { - this(null /*source*/, platformVersion, revision, abi, props, localOsPath); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected SystemImagePackage( - SdkSource source, - AndroidVersion platformVersion, - int revision, - String abi, - Properties props, - String localOsPath) { - super( source, //source - props, //properties - revision, //revision - null, //license - null, //description - null, //descUrl - Os.getCurrentOs(), //archiveOs - Arch.getCurrentArch(), //archiveArch - localOsPath //archiveOsPath - ); - mVersion = platformVersion; - if (abi == null && props != null) { - abi = props.getProperty(PkgProps.SYS_IMG_ABI); - } - assert abi != null : "To use this SystemImagePackage constructor you must pass an ABI as a parameter or as a PROP_ABI property"; - mAbi = abi; - } - - /** - * Creates a {@link BrokenPackage} representing a system image that failed to load - * with the regular {@link SdkManager} workflow. - * - * @param abiDir The SDK/system-images/android-N/abi folder - * @param props The properties located in {@code abiDir} or null if not found. - * @return A new {@link BrokenPackage} that represents this installed package. - */ - public static Package createBroken(File abiDir, Properties props) { - AndroidVersion version = null; - String abiType = abiDir.getName(); - String error = null; - - // Try to load the android version & ABI from the sources.props. - // If we don't find them, it would explain why this package is broken. - if (props == null) { - error = String.format("Missing file %1$s", SdkConstants.FN_SOURCE_PROP); - } else { - try { - version = new AndroidVersion(props); - - String abi = props.getProperty(PkgProps.SYS_IMG_ABI); - if (abi != null) { - abiType = abi; - } else { - error = String.format("Invalid file %1$s: Missing property %2$s", - SdkConstants.FN_SOURCE_PROP, - PkgProps.SYS_IMG_ABI); - } - } catch (AndroidVersionException e) { - error = String.format("Invalid file %1$s: %2$s", - SdkConstants.FN_SOURCE_PROP, - e.getMessage()); - } - } - - if (version == null) { - try { - // Try to parse the first number out of the platform folder name. - String platform = abiDir.getParentFile().getName(); - platform = platform.replaceAll("[^0-9]+", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$ - int pos = platform.indexOf(' '); - if (pos >= 0) { - platform = platform.substring(0, pos); - } - int apiLevel = Integer.parseInt(platform); - version = new AndroidVersion(apiLevel, null /*codename*/); - } catch (Exception ignore) { - } - } - - StringBuilder sb = new StringBuilder( - String.format("Broken %1$s System Image", getAbiDisplayNameInternal(abiType))); - if (version != null) { - sb.append(String.format(", API %1$s", version.getApiString())); - } - - String shortDesc = sb.toString(); - - if (error != null) { - sb.append('\n').append(error); - } - - String longDesc = sb.toString(); - - return new BrokenPackage(props, shortDesc, longDesc, - IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED, - version==null ? IExactApiLevelDependency.API_LEVEL_INVALID : version.getApiLevel(), - abiDir.getAbsolutePath()); - } - - /** - * Save the properties of the current packages in the given {@link Properties} object. - * These properties will later be given to a constructor that takes a {@link Properties} object. - */ - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - mVersion.saveProperties(props); - props.setProperty(PkgProps.SYS_IMG_ABI, mAbi); - } - - /** Returns the ABI of the system-image. Cannot be null nor empty. */ - public String getAbi() { - return mAbi; - } - - /** Returns a display-friendly name for the ABI of the system-image. */ - public String getAbiDisplayName() { - return getAbiDisplayNameInternal(mAbi); - } - - private static String getAbiDisplayNameInternal(String abi) { - return abi.replace("armeabi", "ARM EABI") //$NON-NLS-1$ //$NON-NLS-2$ - .replace("x86", "Intel x86 Atom") //$NON-NLS-1$ //$NON-NLS-2$ - .replace("mips", "MIPS") //$NON-NLS-1$ //$NON-NLS-2$ - .replace("-", " "); //$NON-NLS-1$ //$NON-NLS-2$ - } - - /** - * Returns the version of the platform dependency of this package. - * <p/> - * A system-image has the same {@link AndroidVersion} as the platform it depends on. - */ - @Override @NonNull - public AndroidVersion getAndroidVersion() { - return mVersion; - } - - /** - * Returns a string identifier to install this package from the command line. - * For system images, we use "sysimg-N" where N is the API or the preview codename. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - return "sysimg-" + mVersion.getApiString(); //$NON-NLS-1$ - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - return String.format("%1$s System Image%2$s", - getAbiDisplayName(), - isObsolete() ? " (Obsolete)" : ""); - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - return String.format("%1$s System Image, Android API %2$s, revision %3$s%4$s", - getAbiDisplayName(), - mVersion.getApiString(), - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - /** - * Returns a long description for an {@link IDescription}. - * - * The long description is whatever the XML contains for the {@code description} field, - * or the short description if the former is empty. - */ - @Override - public String getLongDescription() { - String s = getDescription(); - if (s == null || s.length() == 0) { - s = getShortDescription(); - } - - if (s.indexOf("revision") == -1) { - s += String.format("\nRevision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - s += String.format("\nRequires SDK Platform Android API %1$s", - mVersion.getApiString()); - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A system-image package is typically installed in SDK/systems/platform/abi. - * The name needs to be sanitized to be acceptable as a directory name. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - File folder = new File(osSdkRoot, SdkConstants.FD_SYSTEM_IMAGES); - folder = new File(folder, SystemImage.ANDROID_PREFIX + mVersion.getApiString()); - - // Computes a folder directory using the sanitized abi string. - String abi = mAbi; - abi = abi.toLowerCase(Locale.US); - abi = abi.replaceAll("[^a-z0-9_-]+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - abi = abi.replaceAll("_+", "_"); //$NON-NLS-1$ //$NON-NLS-2$ - - folder = new File(folder, abi); - return folder; - } - - @Override - public boolean sameItemAs(Package pkg) { - if (pkg instanceof SystemImagePackage) { - SystemImagePackage newPkg = (SystemImagePackage)pkg; - - // check they are the same abi and version. - return getAbi().equals(newPkg.getAbi()) && - getAndroidVersion().equals(newPkg.getAndroidVersion()); - } - - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((mAbi == null) ? 0 : mAbi.hashCode()); - result = prime * result + ((mVersion == null) ? 0 : mVersion.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof SystemImagePackage)) { - return false; - } - SystemImagePackage other = (SystemImagePackage) obj; - if (mAbi == null) { - if (other.mAbi != null) { - return false; - } - } else if (!mAbi.equals(other.mAbi)) { - return false; - } - if (mVersion == null) { - if (other.mVersion != null) { - return false; - } - } else if (!mVersion.equals(other.mVersion)) { - return false; - } - return true; - } - - /** - * For sys img packages, we want to add abi to the sorting key - * <em>before<em/> the revision number. - * <p/> - * {@inheritDoc} - */ - @Override - protected String comparisonKey() { - String s = super.comparisonKey(); - int pos = s.indexOf("|r:"); //$NON-NLS-1$ - assert pos > 0; - s = s.substring(0, pos) + - "|abi:" + getAbiDisplayName() + //$NON-NLS-1$ - s.substring(pos); - return s; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ToolPackage.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ToolPackage.java deleted file mode 100755 index 8084c6b..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/packages/ToolPackage.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.sdklib.util.GrabProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.IProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.Wait; - -import org.w3c.dom.Node; - -import java.io.File; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Represents a tool XML node in an SDK repository. - */ -public class ToolPackage extends FullRevisionPackage implements IMinPlatformToolsDependency { - - /** The value returned by {@link ToolPackage#installId()}. */ - public static final String INSTALL_ID = "tools"; //$NON-NLS-1$ - /** The value returned by {@link ToolPackage#installId()}. */ - private static final String INSTALL_ID_PREVIEW = "tools-preview"; //$NON-NLS-1$ - - /** - * The minimal revision of the platform-tools package required by this package - * or {@link #MIN_PLATFORM_TOOLS_REV_INVALID} if the value was missing. - */ - private final FullRevision mMinPlatformToolsRevision; - - /** - * Creates a new tool package from the attributes and elements of the given XML node. - * This constructor should throw an exception if the package cannot be created. - * - * @param source The {@link SdkSource} where this is loaded from. - * @param packageNode The XML element being parsed. - * @param nsUri The namespace URI of the originating XML document, to be able to deal with - * parameters that vary according to the originating XML schema. - * @param licenses The licenses loaded from the XML originating document. - */ - public ToolPackage(SdkSource source, - Node packageNode, - String nsUri, - Map<String,String> licenses) { - super(source, packageNode, nsUri, licenses); - - mMinPlatformToolsRevision = PackageParserUtils.parseFullRevisionElement( - PackageParserUtils.findChildElement(packageNode, - SdkRepoConstants.NODE_MIN_PLATFORM_TOOLS_REV)); - - if (mMinPlatformToolsRevision.equals(MIN_PLATFORM_TOOLS_REV_INVALID)) { - // This revision number is mandatory starting with sdk-repository-3.xsd - // and did not exist before. Complain if the URI has level >= 3. - - boolean needRevision = false; - - Pattern nsPattern = Pattern.compile(SdkRepoConstants.NS_PATTERN); - Matcher m = nsPattern.matcher(nsUri); - if (m.matches()) { - String version = m.group(1); - try { - needRevision = Integer.parseInt(version) >= 3; - } catch (NumberFormatException e) { - // ignore. needRevision defaults to false - } - } - - if (needRevision) { - throw new IllegalArgumentException( - String.format("Missing %1$s element in %2$s package", - SdkRepoConstants.NODE_MIN_PLATFORM_TOOLS_REV, - SdkRepoConstants.NODE_PLATFORM_TOOL)); - } - } - } - - /** - * Manually create a new package with one archive and the given attributes or properties. - * This is used to create packages from local directories in which case there must be - * one archive which URL is the actual target location. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public static Package create( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - return new ToolPackage(source, props, revision, license, description, - descUrl, archiveOs, archiveArch, archiveOsPath); - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected ToolPackage( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, - props, - revision, - license, - description, - descUrl, - archiveOs, - archiveArch, - archiveOsPath); - - String revStr = getProperty(props, PkgProps.MIN_PLATFORM_TOOLS_REV, null); - - FullRevision rev = MIN_PLATFORM_TOOLS_REV_INVALID; - if (revStr != null) { - try { - rev = FullRevision.parseRevision(revStr); - } catch (NumberFormatException ignore) {} - } - - mMinPlatformToolsRevision = rev; - } - - /** - * The minimal revision of the tools package required by this package if > 0, - * or {@link #MIN_PLATFORM_TOOLS_REV_INVALID} if the value was missing. - * <p/> - * This attribute is mandatory and should not be normally missing. - */ - @Override - public FullRevision getMinPlatformToolsRevision() { - return mMinPlatformToolsRevision; - } - - /** - * Returns a string identifier to install this package from the command line. - * For tools, we use "tools" or "tools-preview" since this package is unique. - * <p/> - * {@inheritDoc} - */ - @Override - public String installId() { - if (getRevision().isPreview()) { - return INSTALL_ID_PREVIEW; - } else { - return INSTALL_ID; - } - } - - /** - * Returns a description of this package that is suitable for a list display. - * <p/> - * {@inheritDoc} - */ - @Override - public String getListDescription() { - return String.format("Android SDK Tools%1$s", - isObsolete() ? " (Obsolete)" : ""); - } - - /** - * Returns a short description for an {@link IDescription}. - */ - @Override - public String getShortDescription() { - return String.format("Android SDK Tools, revision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - /** Returns a long description for an {@link IDescription}. */ - @Override - public String getLongDescription() { - String s = getDescription(); - if (s == null || s.length() == 0) { - s = getShortDescription(); - } - - if (s.indexOf("revision") == -1) { - s += String.format("\nRevision %1$s%2$s", - getRevision().toShortString(), - isObsolete() ? " (Obsolete)" : ""); - } - - return s; - } - - /** - * Computes a potential installation folder if an archive of this package were - * to be installed right away in the given SDK root. - * <p/> - * A "tool" package should always be located in SDK/tools. - * - * @param osSdkRoot The OS path of the SDK root folder. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @return A new {@link File} corresponding to the directory to use to install this package. - */ - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - return new File(osSdkRoot, SdkConstants.FD_TOOLS); - } - - /** - * Check whether 2 tool packages are the same <em>and</em> have the - * same preview bit. - */ - @Override - public boolean sameItemAs(Package pkg) { - // Only one tool package so any tool package is the same item - return sameItemAs(pkg, false /*ignorePreviews*/); - } - - @Override - public boolean sameItemAs(Package pkg, boolean ignorePreviews) { - // only one tool package so any tool package is the same item. - if (pkg instanceof ToolPackage) { - if (ignorePreviews) { - return true; - } else { - // however previews can only match previews by default, unless we ignore that check. - return ((ToolPackage) pkg).getRevision().isPreview() == - getRevision().isPreview(); - } - } - return false; - } - - @Override - public void saveProperties(Properties props) { - super.saveProperties(props); - - if (!getMinPlatformToolsRevision().equals(MIN_PLATFORM_TOOLS_REV_INVALID)) { - props.setProperty(PkgProps.MIN_PLATFORM_TOOLS_REV, - getMinPlatformToolsRevision().toShortString()); - } - } - - /** - * The tool package executes tools/lib/post_tools_install[.bat|.sh] - * {@inheritDoc} - */ - @Override - public void postInstallHook(Archive archive, final ITaskMonitor monitor, File installFolder) { - super.postInstallHook(archive, monitor, installFolder); - - if (installFolder == null) { - return; - } - - File libDir = new File(installFolder, SdkConstants.FD_LIB); - if (!libDir.isDirectory()) { - return; - } - - String scriptName = "post_tools_install"; //$NON-NLS-1$ - String shell = ""; //$NON-NLS-1$ - if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) { - shell = "cmd.exe /c "; //$NON-NLS-1$ - scriptName += ".bat"; //$NON-NLS-1$ - } else { - scriptName += ".sh"; //$NON-NLS-1$ - } - - File scriptFile = new File(libDir, scriptName); - if (!scriptFile.isFile()) { - return; - } - - int status = -1; - - try { - Process proc = Runtime.getRuntime().exec( - shell + scriptName, // command - null, // environment - libDir); // working dir - - final String tag = scriptName; - status = GrabProcessOutput.grabProcessOutput( - proc, - Wait.WAIT_FOR_PROCESS, - new IProcessOutput() { - @Override - public void out(@Nullable String line) { - if (line != null) { - monitor.log("[%1$s] %2$s", tag, line); - } - } - - @Override - public void err(@Nullable String line) { - if (line != null) { - monitor.logError("[%1$s] Error: %2$s", tag, line); - } - } - }); - - } catch (Exception e) { - monitor.logError("Exception: %s", e.toString()); - } - - if (status != 0) { - monitor.logError("Failed to execute %s", scriptName); - return; - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result - + ((mMinPlatformToolsRevision == null) ? 0 : mMinPlatformToolsRevision.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof ToolPackage)) { - return false; - } - ToolPackage other = (ToolPackage) obj; - if (mMinPlatformToolsRevision == null) { - if (other.mMinPlatformToolsRevision != null) { - return false; - } - } else if (!mMinPlatformToolsRevision.equals(other.mMinPlatformToolsRevision)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java deleted file mode 100755 index 98bfc5a..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkAddonSource.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.annotations.Nullable; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.repository.SdkAddonConstants; - -import org.w3c.dom.Document; - -import java.io.InputStream; - - -/** - * An sdk-addon source, i.e. a download site for addons and extra packages. - * A repository describes one or more {@link Package}s available for download. - */ -public class SdkAddonSource extends SdkSource { - - /** - * Constructs a new source for the given repository URL. - * @param url The source URL. Cannot be null. If the URL ends with a /, the default - * addon.xml filename will be appended automatically. - * @param uiName The UI-visible name of the source. Can be null. - */ - public SdkAddonSource(String url, String uiName) { - super(url, uiName); - } - - /** - * Returns true if this is an addon source. - * We only load addons and extras from these sources. - */ - @Override - public boolean isAddonSource() { - return true; - } - - /** - * Returns true if this is a system-image source. - * We only load system-images from these sources. - */ - @Override - public boolean isSysImgSource() { - return false; - } - - - @Override - protected String[] getDefaultXmlFileUrls() { - return new String[] { SdkAddonConstants.URL_DEFAULT_FILENAME }; - } - - @Override - protected int getNsLatestVersion() { - return SdkAddonConstants.NS_LATEST_VERSION; - } - - @Override - protected String getNsUri() { - return SdkAddonConstants.NS_URI; - } - - @Override - protected String getNsPattern() { - return SdkAddonConstants.NS_PATTERN; - } - - @Override - protected String getSchemaUri(int version) { - return SdkAddonConstants.getSchemaUri(version); - } - - @Override - protected String getRootElementName() { - return SdkAddonConstants.NODE_SDK_ADDON; - } - - @Override - protected InputStream getXsdStream(int version) { - return SdkAddonConstants.getXsdStream(version); - } - - /** - * This kind of schema does not support forward-evolution of the <tool> element. - * - * @param xml The input XML stream. Can be null. - * @return Always null. - * @null This implementation always return null. - */ - @Override - protected Document findAlternateToolsXml(@Nullable InputStream xml) { - return null; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java deleted file mode 100755 index 09913ed..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkRepoSource.java +++ /dev/null @@ -1,524 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.annotations.Nullable; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.PackageParserUtils; -import com.android.sdklib.repository.RepoConstants; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.Text; -import org.xml.sax.ErrorHandler; - -import java.io.IOException; -import java.io.InputStream; -import java.util.regex.Pattern; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - - -/** - * An sdk-repository source, i.e. a download site. - * A repository describes one or more {@link Package}s available for download. - */ -public class SdkRepoSource extends SdkSource { - - /** - * Constructs a new source for the given repository URL. - * @param url The source URL. Cannot be null. If the URL ends with a /, the default - * repository.xml filename will be appended automatically. - * @param uiName The UI-visible name of the source. Can be null. - */ - public SdkRepoSource(String url, String uiName) { - super(url, uiName); - } - - /** - * Returns true if this is an addon source. - * We only load addons and extras from these sources. - */ - @Override - public boolean isAddonSource() { - return false; - } - - /** - * Returns true if this is a system-image source. - * We only load system-images from these sources. - */ - @Override - public boolean isSysImgSource() { - return false; - } - - private static String[] sDefaults = null; // lazily allocated in getDefaultXmlFileUrls - - @Override - protected String[] getDefaultXmlFileUrls() { - if (sDefaults == null) { - sDefaults = new String[SdkRepoConstants.NS_LATEST_VERSION - - SdkRepoConstants.NS_SERVER_MIN_VERSION - + 2]; - int k = 0; - for (int i = SdkRepoConstants.NS_LATEST_VERSION; - i >= SdkRepoConstants.NS_SERVER_MIN_VERSION; - i--) { - sDefaults[k++] = String.format(SdkRepoConstants.URL_FILENAME_PATTERN, i); - } - sDefaults[k++] = SdkRepoConstants.URL_DEFAULT_FILENAME; - assert k == sDefaults.length; - } - - return sDefaults; - } - - @Override - protected int getNsLatestVersion() { - return SdkRepoConstants.NS_LATEST_VERSION; - } - - @Override - protected String getNsUri() { - return SdkRepoConstants.NS_URI; - } - - @Override - protected String getNsPattern() { - return SdkRepoConstants.NS_PATTERN; - } - - @Override - protected String getSchemaUri(int version) { - return SdkRepoConstants.getSchemaUri(version); - } - - @Override - protected String getRootElementName() { - return SdkRepoConstants.NODE_SDK_REPOSITORY; - } - - @Override - protected InputStream getXsdStream(int version) { - return SdkRepoConstants.getXsdStream(version); - } - - /** - * The purpose of this method is to support forward evolution of our schema. - * <p/> - * At this point, we know that xml does not point to any schema that this version of - * the tool knows how to process, so it's not one of the possible 1..N versions of our - * XSD schema. - * <p/> - * We thus try to interpret the byte stream as a possible XML stream. It may not be - * one at all in the first place. If it looks anything line an XML schema, we try to - * find its <tool> and the <platform-tools> elements. If we find any, - * we recreate a suitable document that conforms to what we expect from our XSD schema - * with only those elements. - * <p/> - * To be valid, the <tool> and the <platform-tools> elements must have at - * least one <archive> compatible with this platform. - * <p/> - * Starting the sdk-repository schema v3, <tools> has a <min-platform-tools-rev> - * node, so technically the corresponding XML schema will be usable only if there's a - * <platform-tools> with the request revision number. We don't enforce that here, as - * this is done at install time. - * <p/> - * If we don't find anything suitable, we drop the whole thing. - * - * @param xml The input XML stream. Can be null. - * @return Either a new XML document conforming to our schema with at least one <tool> - * and <platform-tools> element or null. - * @throws IOException if InputStream.reset() fails - * @null Can return null on failure. - */ - @Override - protected Document findAlternateToolsXml(@Nullable InputStream xml) throws IOException { - return findAlternateToolsXml(xml, null /*errorHandler*/); - } - - /** - * An alternate version of {@link #findAlternateToolsXml(InputStream)} that allows - * the caller to specify the XML error handler. The default from the underlying Java - * XML Xerces parser will dump to stdout/stderr, which is not convenient during unit tests. - * - * @param xml The input XML stream. Can be null. - * @param errorHandler An optional XML error handler. If null, the default will be used. - * @return Either a new XML document conforming to our schema with at least one <tool> - * and <platform-tools> element or null. - * @throws IOException if InputStream.reset() fails - * @null Can return null on failure. - * @see #findAlternateToolsXml(InputStream) findAlternateToolsXml() provides more details. - */ - protected Document findAlternateToolsXml( - @Nullable InputStream xml, - @Nullable ErrorHandler errorHandler) - throws IOException { - if (xml == null) { - return null; - } - - // Reset the stream if it supports that operation. - assert xml.markSupported(); - xml.reset(); - - // Get an XML document - - Document oldDoc = null; - Document newDoc = null; - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(false); - factory.setValidating(false); - - // Parse the old document using a non namespace aware builder - factory.setNamespaceAware(false); - DocumentBuilder builder = factory.newDocumentBuilder(); - - if (errorHandler != null) { - builder.setErrorHandler(errorHandler); - } - - oldDoc = builder.parse(xml); - - // Prepare a new document using a namespace aware builder - factory.setNamespaceAware(true); - builder = factory.newDocumentBuilder(); - newDoc = builder.newDocument(); - - } catch (Exception e) { - // Failed to get builder factor - // Failed to create XML document builder - // Failed to parse XML document - // Failed to read XML document - } - - if (oldDoc == null || newDoc == null) { - return null; - } - - - // Check the root element is an XML with at least the following properties: - // <sdk:sdk-repository - // xmlns:sdk="http://schemas.android.com/sdk/android/repository/$N"> - // - // Note that we don't have namespace support enabled, we just do it manually. - - Pattern nsPattern = Pattern.compile(getNsPattern()); - - Node oldRoot = null; - String prefix = null; - for (Node child = oldDoc.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - prefix = null; - String name = child.getNodeName(); - int pos = name.indexOf(':'); - if (pos > 0 && pos < name.length() - 1) { - prefix = name.substring(0, pos); - name = name.substring(pos + 1); - } - if (SdkRepoConstants.NODE_SDK_REPOSITORY.equals(name)) { - NamedNodeMap attrs = child.getAttributes(); - String xmlns = "xmlns"; //$NON-NLS-1$ - if (prefix != null) { - xmlns += ":" + prefix; //$NON-NLS-1$ - } - Node attr = attrs.getNamedItem(xmlns); - if (attr != null) { - String uri = attr.getNodeValue(); - if (uri != null && nsPattern.matcher(uri).matches()) { - oldRoot = child; - break; - } - } - } - } - } - - // we must have found the root node, and it must have an XML namespace prefix. - if (oldRoot == null || prefix == null || prefix.length() == 0) { - return null; - } - - final String ns = getNsUri(); - Element newRoot = newDoc.createElementNS(ns, getRootElementName()); - newRoot.setPrefix(prefix); - newDoc.appendChild(newRoot); - int numTool = 0; - - // Find any inner <tool> or <platform-tool> nodes and extract their required parameters - - String[] elementNames = { - SdkRepoConstants.NODE_TOOL, - SdkRepoConstants.NODE_PLATFORM_TOOL, - SdkRepoConstants.NODE_LICENSE - }; - - Element element = null; - while ((element = findChild(oldRoot, element, prefix, elementNames)) != null) { - boolean isElementValid = false; - - String name = element.getLocalName(); - if (name == null) { - name = element.getNodeName(); - - int pos = name.indexOf(':'); - if (pos > 0 && pos < name.length() - 1) { - name = name.substring(pos + 1); - } - } - - // To be valid, the tool or platform-tool element must have: - // - a <revision> element with a number - // - a <min-platform-tools-rev> element with a number for a <tool> element - // - an <archives> element with one or more <archive> elements inside - // - one of the <archive> elements must have an "os" and "arch" attributes - // compatible with the current platform. Only keep the first such element found. - // - the <archive> element must contain a <size>, a <checksum> and a <url>. - // - none of the above for a license element - - if (SdkRepoConstants.NODE_LICENSE.equals(name)) { - isElementValid = true; - - } else { - try { - Node revision = findChild(element, null, prefix, RepoConstants.NODE_REVISION); - Node archives = findChild(element, null, prefix, RepoConstants.NODE_ARCHIVES); - - if (revision == null || archives == null) { - continue; - } - - // check revision contains a number - try { - String content = revision.getTextContent(); - content = content.trim(); - int rev = Integer.parseInt(content); - if (rev < 1) { - continue; - } - } catch (NumberFormatException ignore) { - continue; - } - - if (SdkRepoConstants.NODE_TOOL.equals(name)) { - Node minPTRev = findChild(element, null, prefix, - RepoConstants.NODE_MIN_PLATFORM_TOOLS_REV); - - if (minPTRev == null) { - continue; - } - - // check min-platform-tools-rev contains a number - try { - String content = minPTRev.getTextContent(); - content = content.trim(); - int rev = Integer.parseInt(content); - if (rev < 1) { - continue; - } - } catch (NumberFormatException ignore) { - continue; - } - } - - Node archive = null; - while ((archive = findChild(archives, - archive, - prefix, - RepoConstants.NODE_ARCHIVE)) != null) { - try { - Os os = (Os) PackageParserUtils.getEnumAttribute(archive, - RepoConstants.ATTR_OS, - Os.values(), - null /*default*/); - Arch arch = (Arch) PackageParserUtils.getEnumAttribute(archive, - RepoConstants.ATTR_ARCH, - Arch.values(), - Arch.ANY); - if (os == null || !os.isCompatible() || - arch == null || !arch.isCompatible()) { - continue; - } - - Node node = findChild(archive, null, prefix, RepoConstants.NODE_URL); - String url = node == null ? null : node.getTextContent().trim(); - if (url == null || url.length() == 0) { - continue; - } - - node = findChild(archive, null, prefix, RepoConstants.NODE_SIZE); - long size = 0; - try { - size = Long.parseLong(node.getTextContent()); - } catch (Exception e) { - // pass - } - if (size < 1) { - continue; - } - - node = findChild(archive, null, prefix, RepoConstants.NODE_CHECKSUM); - // double check that the checksum element contains a type=sha1 attribute - if (node == null) { - continue; - } - NamedNodeMap attrs = node.getAttributes(); - Node typeNode = attrs.getNamedItem(RepoConstants.ATTR_TYPE); - if (typeNode == null || - !RepoConstants.ATTR_TYPE.equals(typeNode.getNodeName()) || - !RepoConstants.SHA1_TYPE.equals(typeNode.getNodeValue())) { - continue; - } - String sha1 = node == null ? null : node.getTextContent().trim(); - if (sha1 == null || - sha1.length() != RepoConstants.SHA1_CHECKSUM_LEN) { - continue; - } - - isElementValid = true; - - } catch (Exception ignore1) { - // pass - } - } // while <archive> - } catch (Exception ignore2) { - // For debugging it is useful to re-throw the exception. - // For end-users, not so much. It would be nice to make it - // happen automatically during unit tests. - if (System.getenv("TESTING") != null) { - throw new RuntimeException(ignore2); - } - } - } - - if (isElementValid) { - duplicateNode(newRoot, element, SdkRepoConstants.NS_URI, prefix); - numTool++; - } - } // while <tool> - - return numTool > 0 ? newDoc : null; - } - - /** - * Helper method used by {@link #findAlternateToolsXml(InputStream)} to find a given - * element child in a root XML node. - */ - private Element findChild(Node rootNode, Node after, String prefix, String[] nodeNames) { - for (int i = 0; i < nodeNames.length; i++) { - if (nodeNames[i].indexOf(':') < 0) { - nodeNames[i] = prefix + ":" + nodeNames[i]; - } - } - Node child = after == null ? rootNode.getFirstChild() : after.getNextSibling(); - for(; child != null; child = child.getNextSibling()) { - if (child.getNodeType() != Node.ELEMENT_NODE) { - continue; - } - for (String nodeName : nodeNames) { - if (nodeName.equals(child.getNodeName())) { - return (Element) child; - } - } - } - return null; - } - - /** - * Helper method used by {@link #findAlternateToolsXml(InputStream)} to find a given - * element child in a root XML node. - */ - private Node findChild(Node rootNode, Node after, String prefix, String nodeName) { - return findChild(rootNode, after, prefix, new String[] { nodeName }); - } - - /** - * Helper method used by {@link #findAlternateToolsXml(InputStream)} to duplicate a node - * and attach it to the given root in the new document. - */ - private Element duplicateNode(Element newRootNode, Element oldNode, - String namespaceUri, String prefix) { - // The implementation here is more or less equivalent to - // - // newRoot.appendChild(newDoc.importNode(oldNode, deep=true)) - // - // except we can't just use importNode() since we need to deal with the fact - // that the old document is not namespace-aware yet the new one is. - - Document newDoc = newRootNode.getOwnerDocument(); - Element newNode = null; - - String nodeName = oldNode.getNodeName(); - int pos = nodeName.indexOf(':'); - if (pos > 0 && pos < nodeName.length() - 1) { - nodeName = nodeName.substring(pos + 1); - newNode = newDoc.createElementNS(namespaceUri, nodeName); - newNode.setPrefix(prefix); - } else { - newNode = newDoc.createElement(nodeName); - } - - newRootNode.appendChild(newNode); - - // Merge in all the attributes - NamedNodeMap attrs = oldNode.getAttributes(); - for (int i = 0; i < attrs.getLength(); i++) { - Attr attr = (Attr) attrs.item(i); - Attr newAttr = null; - - String attrName = attr.getNodeName(); - pos = attrName.indexOf(':'); - if (pos > 0 && pos < attrName.length() - 1) { - attrName = attrName.substring(pos + 1); - newAttr = newDoc.createAttributeNS(namespaceUri, attrName); - newAttr.setPrefix(prefix); - } else { - newAttr = newDoc.createAttribute(attrName); - } - - newAttr.setNodeValue(attr.getNodeValue()); - - if (pos > 0) { - newNode.getAttributes().setNamedItemNS(newAttr); - } else { - newNode.getAttributes().setNamedItem(newAttr); - } - } - - // Merge all child elements and texts - for (Node child = oldNode.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - duplicateNode(newNode, (Element) child, namespaceUri, prefix); - - } else if (child.getNodeType() == Node.TEXT_NODE) { - Text newText = newDoc.createTextNode(child.getNodeValue()); - newNode.appendChild(newText); - } - } - - return newNode; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java deleted file mode 100755 index 2558e71..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSource.java +++ /dev/null @@ -1,991 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.sdklib.internal.repository.CanceledByUserException; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.packages.AddonPackage; -import com.android.sdklib.internal.repository.packages.DocPackage; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.internal.repository.packages.SamplePackage; -import com.android.sdklib.internal.repository.packages.SourcePackage; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.sdklib.io.NonClosingInputStream; -import com.android.sdklib.io.NonClosingInputStream.CloseBehavior; -import com.android.sdklib.repository.RepoConstants; -import com.android.sdklib.repository.SdkAddonConstants; -import com.android.sdklib.repository.SdkRepoConstants; - -import org.w3c.dom.Document; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.SSLKeyException; -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -/** - * An sdk-addon or sdk-repository source, i.e. a download site. - * It may be a full repository or an add-on only repository. - * A repository describes one or {@link Package}s available for download. - */ -public abstract class SdkSource implements IDescription, Comparable<SdkSource> { - - private String mUrl; - - private Package[] mPackages; - private String mDescription; - private String mFetchError; - private final String mUiName; - - private static final SdkSourceProperties sSourcesProps = new SdkSourceProperties(); - - /** - * Constructs a new source for the given repository URL. - * @param url The source URL. Cannot be null. If the URL ends with a /, the default - * repository.xml filename will be appended automatically. - * @param uiName The UI-visible name of the source. Can be null. - */ - public SdkSource(String url, String uiName) { - - // URLs should not be null and should not have whitespace. - if (url == null) { - url = ""; - } - url = url.trim(); - - // if the URL ends with a /, it must be "directory" resource, - // in which case we automatically add the default file that will - // looked for. This way it will be obvious to the user which - // resource we are actually trying to fetch. - if (url.endsWith("/")) { //$NON-NLS-1$ - String[] names = getDefaultXmlFileUrls(); - if (names.length > 0) { - url += names[0]; - } - } - - if (uiName == null) { - uiName = sSourcesProps.getProperty(SdkSourceProperties.KEY_NAME, url, null); - } else { - sSourcesProps.setProperty(SdkSourceProperties.KEY_NAME, url, uiName); - } - - mUrl = url; - mUiName = uiName; - setDefaultDescription(); - } - - /** - * Returns true if this is an addon source. - * We only load addons and extras from these sources. - */ - public abstract boolean isAddonSource(); - - /** - * Returns true if this is a system-image source. - * We only load system-images from these sources. - */ - public abstract boolean isSysImgSource(); - - - /** - * Returns the basename of the default URLs to try to download the - * XML manifest. - * E.g. this is typically SdkRepoConstants.URL_DEFAULT_XML_FILE - * or SdkAddonConstants.URL_DEFAULT_XML_FILE - */ - protected abstract String[] getDefaultXmlFileUrls(); - - /** Returns SdkRepoConstants.NS_LATEST_VERSION or SdkAddonConstants.NS_LATEST_VERSION. */ - protected abstract int getNsLatestVersion(); - - /** Returns SdkRepoConstants.NS_URI or SdkAddonConstants.NS_URI. */ - protected abstract String getNsUri(); - - /** Returns SdkRepoConstants.NS_PATTERN or SdkAddonConstants.NS_PATTERN. */ - protected abstract String getNsPattern(); - - /** Returns SdkRepoConstants.getSchemaUri() or SdkAddonConstants.getSchemaUri(). */ - protected abstract String getSchemaUri(int version); - - /* Returns SdkRepoConstants.NODE_SDK_REPOSITORY or SdkAddonConstants.NODE_SDK_ADDON. */ - protected abstract String getRootElementName(); - - /** Returns SdkRepoConstants.getXsdStream() or SdkAddonConstants.getXsdStream(). */ - protected abstract InputStream getXsdStream(int version); - - /** - * In case we fail to load an XML, examine the XML to see if it matches a <b>future</b> - * schema that as at least a <code>tools</code> node that we could load to update the - * SDK Manager. - * - * @param xml The input XML stream. Can be null. - * @return Null on failure, otherwise returns an XML DOM with just the tools we - * need to update this SDK Manager. - * @null Can return null on failure. - */ - protected abstract Document findAlternateToolsXml(@Nullable InputStream xml) - throws IOException; - - /** - * Two repo source are equal if they have the same URL. - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof SdkSource) { - SdkSource rs = (SdkSource) obj; - return rs.getUrl().equals(this.getUrl()); - } - return false; - } - - @Override - public int hashCode() { - return mUrl.hashCode(); - } - - /** - * Implementation of the {@link Comparable} interface. - * Simply compares the URL using the string's default ordering. - */ - @Override - public int compareTo(SdkSource rhs) { - return this.getUrl().compareTo(rhs.getUrl()); - } - - /** - * Returns the UI-visible name of the source. Can be null. - */ - public String getUiName() { - return mUiName; - } - - /** Returns the URL of the XML file for this source. */ - public String getUrl() { - return mUrl; - } - - /** - * Returns the list of known packages found by the last call to load(). - * This is null when the source hasn't been loaded yet -- caller should - * then call {@link #load} to load the packages. - */ - public Package[] getPackages() { - return mPackages; - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected void setPackages(Package[] packages) { - mPackages = packages; - - if (mPackages != null) { - // Order the packages. - Arrays.sort(mPackages, null); - } - } - - /** - * Clear the internal packages list. After this call, {@link #getPackages()} will return - * null till load() is called. - */ - public void clearPackages() { - setPackages(null); - } - - /** - * Indicates if the source is enabled. - * <p/> - * A 3rd-party add-on source can be disabled by the user to prevent from loading it. - * - * @return True if the source is enabled (default is true). - */ - public boolean isEnabled() { - // A URL is enabled if it's not in the disabled list. - return sSourcesProps.getProperty(SdkSourceProperties.KEY_DISABLED, mUrl, null) == null; - } - - /** - * Changes whether the source is marked as enabled. - * <p/> - * When <em>changing</em> the enable state, the current package list is purged - * and the next {@code load} will either return an empty list (if disabled) or - * the actual package list (if enabled.) - * - * @param enabled True for the source to be enabled (can be loaded), false otherwise. - */ - public void setEnabled(boolean enabled) { - if (enabled != isEnabled()) { - // First we clear the current package list, which will force the - // next load() to actually set the package list as desired. - clearPackages(); - - sSourcesProps.setProperty(SdkSourceProperties.KEY_DISABLED, mUrl, - enabled ? null /*remove*/ : "disabled"); //$NON-NLS-1$ - } - } - - /** - * Returns the short description of the source, if not null. - * Otherwise returns the default Object toString result. - * <p/> - * This is mostly helpful for debugging. - * For UI display, use the {@link IDescription} interface. - */ - @Override - public String toString() { - String s = getShortDescription(); - if (s != null) { - return s; - } - return super.toString(); - } - - @Override - public String getShortDescription() { - - if (mUiName != null && mUiName.length() > 0) { - - String host = "malformed URL"; - - try { - URL u = new URL(mUrl); - host = u.getHost(); - } catch (MalformedURLException e) { - } - - return String.format("%1$s (%2$s)", mUiName, host); - - } - return mUrl; - } - - @Override - public String getLongDescription() { - // Note: in a normal workflow, mDescription is filled by setDefaultDescription(). - // However for packages made by unit tests or such, this can be null. - return mDescription == null ? "" : mDescription; //$NON-NLS-1$ - } - - /** - * Returns the last fetch error description. - * If there was no error, returns null. - */ - public String getFetchError() { - return mFetchError; - } - - /** - * Tries to fetch the repository index for the given URL and updates the package list. - * When a source is disabled, this create an empty non-null package list. - * <p/> - * Callers can get the package list using {@link #getPackages()} after this. It will be - * null in case of error, in which case {@link #getFetchError()} can be used to an - * error message. - */ - public void load(DownloadCache cache, ITaskMonitor monitor, boolean forceHttp) { - - setDefaultDescription(); - monitor.setProgressMax(7); - - if (!isEnabled()) { - setPackages(new Package[0]); - mDescription += "\nSource is disabled."; - monitor.incProgress(7); - return; - } - - String url = mUrl; - if (forceHttp) { - url = url.replaceAll("https://", "http://"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - monitor.setDescription("Fetching URL: %1$s", url); - monitor.incProgress(1); - - mFetchError = null; - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - Exception[] exception = new Exception[] { null }; - Document validatedDoc = null; - boolean usingAlternateXml = false; - boolean usingAlternateUrl = false; - String validatedUri = null; - - String[] defaultNames = getDefaultXmlFileUrls(); - String firstDefaultName = defaultNames.length > 0 ? defaultNames[0] : ""; - - InputStream xml = fetchXmlUrl(url, cache, monitor.createSubMonitor(1), exception); - if (xml != null) { - int version = getXmlSchemaVersion(xml); - if (version == 0) { - closeStream(xml); - xml = null; - } - } - - // FIXME: this is a quick fix to support an alternate upgrade path. - // The whole logic below needs to be updated. - if (xml == null && defaultNames.length > 0) { - ITaskMonitor subMonitor = monitor.createSubMonitor(1); - subMonitor.setProgressMax(defaultNames.length); - - String baseUrl = url; - if (!baseUrl.endsWith("/")) { - int pos = baseUrl.lastIndexOf('/'); - if (pos > 0) { - baseUrl = baseUrl.substring(0, pos + 1); - } - } - - for (String name : defaultNames) { - String newUrl = baseUrl + name; - if (newUrl.equals(url)) { - continue; - } - xml = fetchXmlUrl(newUrl, cache, subMonitor.createSubMonitor(1), exception); - if (xml != null) { - int version = getXmlSchemaVersion(xml); - if (version == 0) { - closeStream(xml); - xml = null; - } else { - url = newUrl; - subMonitor.incProgress( - subMonitor.getProgressMax() - subMonitor.getProgress()); - break; - } - } - } - } else { - monitor.incProgress(1); - } - - // If the original URL can't be fetched - // and the URL doesn't explicitly end with our filename - // and it wasn't an HTTP authentication operation canceled by the user - // then make another tentative after changing the URL. - if (xml == null - && !url.endsWith(firstDefaultName) - && !(exception[0] instanceof CanceledByUserException)) { - if (!url.endsWith("/")) { //$NON-NLS-1$ - url += "/"; //$NON-NLS-1$ - } - url += firstDefaultName; - - xml = fetchXmlUrl(url, cache, monitor.createSubMonitor(1), exception); - usingAlternateUrl = true; - } else { - monitor.incProgress(1); - } - - // FIXME this needs to revisited. - if (xml != null) { - monitor.setDescription("Validate XML: %1$s", url); - - ITaskMonitor subMonitor = monitor.createSubMonitor(2); - subMonitor.setProgressMax(2); - for (int tryOtherUrl = 0; tryOtherUrl < 2; tryOtherUrl++) { - // Explore the XML to find the potential XML schema version - int version = getXmlSchemaVersion(xml); - - if (version >= 1 && version <= getNsLatestVersion()) { - // This should be a version we can handle. Try to validate it - // and report any error as invalid XML syntax, - - String uri = validateXml(xml, url, version, validationError, validatorFound); - if (uri != null) { - // Validation was successful - validatedDoc = getDocument(xml, monitor); - validatedUri = uri; - - if (usingAlternateUrl && validatedDoc != null) { - // If the second tentative succeeded, indicate it in the console - // with the URL that worked. - monitor.log("Repository found at %1$s", url); - - // Keep the modified URL - mUrl = url; - } - } else if (validatorFound[0].equals(Boolean.FALSE)) { - // Validation failed because this JVM lacks a proper XML Validator - mFetchError = validationError[0]; - } else { - // We got a validator but validation failed. We know there's - // what looks like a suitable root element with a suitable XMLNS - // so it must be a genuine error of an XML not conforming to the schema. - } - } else if (version > getNsLatestVersion()) { - // The schema used is more recent than what is supported by this tool. - // Tell the user to upgrade, pointing him to the right version of the tool - // package. - - try { - validatedDoc = findAlternateToolsXml(xml); - } catch (IOException e) { - // Failed, will be handled below. - } - if (validatedDoc != null) { - validationError[0] = null; // remove error from XML validation - validatedUri = getNsUri(); - usingAlternateXml = true; - } - - } else if (version < 1 && tryOtherUrl == 0 && !usingAlternateUrl) { - // This is obviously not one of our documents. - mFetchError = String.format( - "Failed to validate the XML for the repository at URL '%1$s'", - url); - - // If we haven't already tried the alternate URL, let's do it now. - // We don't capture any fetch exception that happen during the second - // fetch in order to avoid hidding any previous fetch errors. - if (!url.endsWith(firstDefaultName)) { - if (!url.endsWith("/")) { //$NON-NLS-1$ - url += "/"; //$NON-NLS-1$ - } - url += firstDefaultName; - - closeStream(xml); - xml = fetchXmlUrl(url, cache, subMonitor.createSubMonitor(1), - null /* outException */); - subMonitor.incProgress(1); - // Loop to try the alternative document - if (xml != null) { - usingAlternateUrl = true; - continue; - } - } - } else if (version < 1 && usingAlternateUrl && mFetchError == null) { - // The alternate URL is obviously not a valid XML either. - // We only report the error if we failed to produce one earlier. - mFetchError = String.format( - "Failed to validate the XML for the repository at URL '%1$s'", - url); - } - - // If we get here either we succeeded or we ran out of alternatives. - break; - } - } - - // If any exception was handled during the URL fetch, display it now. - if (exception[0] != null) { - mFetchError = "Failed to fetch URL"; - - String reason = null; - if (exception[0] instanceof FileNotFoundException) { - // FNF has no useful getMessage, so we need to special handle it. - reason = "File not found"; - mFetchError += ": " + reason; - } else if (exception[0] instanceof SSLKeyException) { - // That's a common error and we have a pref for it. - reason = "HTTPS SSL error. You might want to force download through HTTP in the settings."; - mFetchError += ": HTTPS SSL error"; - } else if (exception[0].getMessage() != null) { - reason = - exception[0].getClass().getSimpleName().replace("Exception", "") //$NON-NLS-1$ //$NON-NLS-2$ - + ' ' - + exception[0].getMessage(); - } else { - reason = exception[0].toString(); - } - - monitor.logError("Failed to fetch URL %1$s, reason: %2$s", url, reason); - } - - if (validationError[0] != null) { - monitor.logError("%s", validationError[0]); //$NON-NLS-1$ - } - - // Stop here if we failed to validate the XML. We don't want to load it. - if (validatedDoc == null) { - return; - } - - if (usingAlternateXml) { - // We found something using the "alternate" XML schema (that is the one made up - // to support schema upgrades). That means the user can only install the tools - // and needs to upgrade them before it download more stuff. - - // Is the manager running from inside ADT? - // We check that com.android.ide.eclipse.adt.AdtPlugin exists using reflection. - - boolean isADT = false; - try { - Class<?> adt = Class.forName("com.android.ide.eclipse.adt.AdtPlugin"); //$NON-NLS-1$ - isADT = (adt != null); - } catch (ClassNotFoundException e) { - // pass - } - - String info; - if (isADT) { - info = "This repository requires a more recent version of ADT. Please update the Eclipse Android plugin."; - mDescription = "This repository requires a more recent version of ADT, the Eclipse Android plugin.\nYou must update it before you can see other new packages."; - - } else { - info = "This repository requires a more recent version of the Tools. Please update."; - mDescription = "This repository requires a more recent version of the Tools.\nYou must update it before you can see other new packages."; - } - - mFetchError = mFetchError == null ? info : mFetchError + ". " + info; - } - - monitor.incProgress(1); - - if (xml != null) { - monitor.setDescription("Parse XML: %1$s", url); - monitor.incProgress(1); - parsePackages(validatedDoc, validatedUri, monitor); - if (mPackages == null || mPackages.length == 0) { - mDescription += "\nNo packages found."; - } else if (mPackages.length == 1) { - mDescription += "\nOne package found."; - } else { - mDescription += String.format("\n%1$d packages found.", mPackages.length); - } - } - - // done - monitor.incProgress(1); - closeStream(xml); - } - - private void setDefaultDescription() { - if (isAddonSource()) { - String desc = ""; - - if (mUiName != null) { - desc += "Add-on Provider: " + mUiName; - desc += "\n"; - } - desc += "Add-on URL: " + mUrl; - - mDescription = desc; - } else { - mDescription = String.format("SDK Source: %1$s", mUrl); - } - } - - /** - * Fetches the document at the given URL and returns it as a string. Returns - * null if anything wrong happens and write errors to the monitor. - * - * @param urlString The URL to load, as a string. - * @param monitor {@link ITaskMonitor} related to this URL. - * @param outException If non null, where to store any exception that - * happens during the fetch. - */ - private InputStream fetchXmlUrl(String urlString, - DownloadCache cache, - ITaskMonitor monitor, - Exception[] outException) { - try { - InputStream xml = cache.openCachedUrl(urlString, monitor); - if (xml != null) { - xml.mark(500000); - xml = new NonClosingInputStream(xml); - ((NonClosingInputStream) xml).setCloseBehavior(CloseBehavior.RESET); - } - return xml; - } catch (Exception e) { - if (outException != null) { - outException[0] = e; - } - } - - return null; - } - - /** - * Closes the stream, ignore any exception from InputStream.close(). - * If the stream is a NonClosingInputStream, sets it to CloseBehavior.CLOSE first. - */ - private void closeStream(InputStream is) { - if (is != null) { - if (is instanceof NonClosingInputStream) { - ((NonClosingInputStream) is).setCloseBehavior(CloseBehavior.CLOSE); - } - try { - is.close(); - } catch (IOException ignore) {} - } - } - - /** - * Validates this XML against one of the requested SDK Repository schemas. - * If the XML was correctly validated, returns the schema that worked. - * If it doesn't validate, returns null and stores the error in outError[0]. - * If we can't find a validator, returns null and set validatorFound[0] to false. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected String validateXml(InputStream xml, String url, int version, - String[] outError, Boolean[] validatorFound) { - - if (xml == null) { - return null; - } - - try { - Validator validator = getValidator(version); - - if (validator == null) { - validatorFound[0] = Boolean.FALSE; - outError[0] = String.format( - "XML verification failed for %1$s.\nNo suitable XML Schema Validator could be found in your Java environment. Please consider updating your version of Java.", - url); - return null; - } - - validatorFound[0] = Boolean.TRUE; - - // Reset the stream if it supports that operation. - assert xml.markSupported(); - xml.reset(); - - // Validation throws a bunch of possible Exceptions on failure. - validator.validate(new StreamSource(xml)); - return getSchemaUri(version); - - } catch (SAXParseException e) { - outError[0] = String.format( - "XML verification failed for %1$s.\nLine %2$d:%3$d, Error: %4$s", - url, - e.getLineNumber(), - e.getColumnNumber(), - e.toString()); - - } catch (Exception e) { - outError[0] = String.format( - "XML verification failed for %1$s.\nError: %2$s", - url, - e.toString()); - } - return null; - } - - /** - * Manually parses the root element of the XML to extract the schema version - * at the end of the xmlns:sdk="http://schemas.android.com/sdk/android/repository/$N" - * declaration. - * - * @return 1..{@link SdkRepoConstants#NS_LATEST_VERSION} for a valid schema version - * or 0 if no schema could be found. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected int getXmlSchemaVersion(InputStream xml) { - if (xml == null) { - return 0; - } - - // Get an XML document - Document doc = null; - try { - assert xml.markSupported(); - xml.reset(); - - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(false); - factory.setValidating(false); - - // Parse the old document using a non namespace aware builder - factory.setNamespaceAware(false); - DocumentBuilder builder = factory.newDocumentBuilder(); - - // We don't want the default handler which prints errors to stderr. - builder.setErrorHandler(new ErrorHandler() { - @Override - public void warning(SAXParseException e) throws SAXException { - // pass - } - @Override - public void fatalError(SAXParseException e) throws SAXException { - throw e; - } - @Override - public void error(SAXParseException e) throws SAXException { - throw e; - } - }); - - doc = builder.parse(xml); - - // Prepare a new document using a namespace aware builder - factory.setNamespaceAware(true); - builder = factory.newDocumentBuilder(); - - } catch (Exception e) { - // Failed to reset XML stream - // Failed to get builder factor - // Failed to create XML document builder - // Failed to parse XML document - // Failed to read XML document - } - - if (doc == null) { - return 0; - } - - // Check the root element is an XML with at least the following properties: - // <sdk:sdk-repository - // xmlns:sdk="http://schemas.android.com/sdk/android/repository/$N"> - // - // Note that we don't have namespace support enabled, we just do it manually. - - Pattern nsPattern = Pattern.compile(getNsPattern()); - - String prefix = null; - for (Node child = doc.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE) { - prefix = null; - String name = child.getNodeName(); - int pos = name.indexOf(':'); - if (pos > 0 && pos < name.length() - 1) { - prefix = name.substring(0, pos); - name = name.substring(pos + 1); - } - if (getRootElementName().equals(name)) { - NamedNodeMap attrs = child.getAttributes(); - String xmlns = "xmlns"; //$NON-NLS-1$ - if (prefix != null) { - xmlns += ":" + prefix; //$NON-NLS-1$ - } - Node attr = attrs.getNamedItem(xmlns); - if (attr != null) { - String uri = attr.getNodeValue(); - if (uri != null) { - Matcher m = nsPattern.matcher(uri); - if (m.matches()) { - String version = m.group(1); - try { - return Integer.parseInt(version); - } catch (NumberFormatException e) { - return 0; - } - } - } - } - } - } - } - - return 0; - } - - /** - * Helper method that returns a validator for our XSD, or null if the current Java - * implementation can't process XSD schemas. - * - * @param version The version of the XML Schema. - * See {@link SdkRepoConstants#getXsdStream(int)} - */ - private Validator getValidator(int version) throws SAXException { - InputStream xsdStream = getXsdStream(version); - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - - if (factory == null) { - return null; - } - - // This may throw a SAX Exception if the schema itself is not a valid XSD - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - - Validator validator = schema == null ? null : schema.newValidator(); - - // We don't want the default handler, which by default dumps errors to stderr. - validator.setErrorHandler(new ErrorHandler() { - @Override - public void warning(SAXParseException e) throws SAXException { - // pass - } - @Override - public void fatalError(SAXParseException e) throws SAXException { - throw e; - } - @Override - public void error(SAXParseException e) throws SAXException { - throw e; - } - }); - - return validator; - } - - /** - * Parse all packages defined in the SDK Repository XML and creates - * a new mPackages array with them. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected boolean parsePackages(Document doc, String nsUri, ITaskMonitor monitor) { - - Node root = getFirstChild(doc, nsUri, getRootElementName()); - if (root != null) { - - ArrayList<Package> packages = new ArrayList<Package>(); - - // Parse license definitions - HashMap<String, String> licenses = new HashMap<String, String>(); - for (Node child = root.getFirstChild(); - child != null; - child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI()) && - child.getLocalName().equals(RepoConstants.NODE_LICENSE)) { - Node id = child.getAttributes().getNamedItem(RepoConstants.ATTR_ID); - if (id != null) { - licenses.put(id.getNodeValue(), child.getTextContent()); - } - } - } - - // Parse packages - for (Node child = root.getFirstChild(); - child != null; - child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI())) { - String name = child.getLocalName(); - Package p = null; - - try { - // We can load addon and extra packages from all sources, either - // internal or user sources. - if (SdkAddonConstants.NODE_ADD_ON.equals(name)) { - p = new AddonPackage(this, child, nsUri, licenses); - - } else if (SdkAddonConstants.NODE_EXTRA.equals(name)) { - p = new ExtraPackage(this, child, nsUri, licenses); - - } else if (!isAddonSource()) { - // We only load platform, doc and tool packages from internal - // sources, never from user sources. - if (SdkRepoConstants.NODE_PLATFORM.equals(name)) { - p = new PlatformPackage(this, child, nsUri, licenses); - } else if (SdkRepoConstants.NODE_DOC.equals(name)) { - p = new DocPackage(this, child, nsUri, licenses); - } else if (SdkRepoConstants.NODE_TOOL.equals(name)) { - p = new ToolPackage(this, child, nsUri, licenses); - } else if (SdkRepoConstants.NODE_PLATFORM_TOOL.equals(name)) { - p = new PlatformToolPackage(this, child, nsUri, licenses); - } else if (SdkRepoConstants.NODE_SAMPLE.equals(name)) { - p = new SamplePackage(this, child, nsUri, licenses); - } else if (SdkRepoConstants.NODE_SYSTEM_IMAGE.equals(name)) { - p = new SystemImagePackage(this, child, nsUri, licenses); - } else if (SdkRepoConstants.NODE_SOURCE.equals(name)) { - p = new SourcePackage(this, child, nsUri, licenses); - } - } - - if (p != null) { - packages.add(p); - monitor.logVerbose("Found %1$s", p.getShortDescription()); - } - } catch (Exception e) { - // Ignore invalid packages - monitor.logError("Ignoring invalid %1$s element: %2$s", name, e.toString()); - } - } - } - - setPackages(packages.toArray(new Package[packages.size()])); - - return true; - } - - return false; - } - - /** - * Returns the first child element with the given XML local name. - * If xmlLocalName is null, returns the very first child element. - */ - private Node getFirstChild(Node node, String nsUri, String xmlLocalName) { - - for(Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { - if (child.getNodeType() == Node.ELEMENT_NODE && - nsUri.equals(child.getNamespaceURI())) { - if (xmlLocalName == null || child.getLocalName().equals(xmlLocalName)) { - return child; - } - } - } - - return null; - } - - /** - * Takes an XML document as a string as parameter and returns a DOM for it. - * - * On error, returns null and prints a (hopefully) useful message on the monitor. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected Document getDocument(InputStream xml, ITaskMonitor monitor) { - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - factory.setIgnoringComments(true); - factory.setNamespaceAware(true); - - DocumentBuilder builder = factory.newDocumentBuilder(); - assert xml.markSupported(); - xml.reset(); - Document doc = builder.parse(new InputSource(xml)); - - return doc; - } catch (ParserConfigurationException e) { - monitor.logError("Failed to create XML document builder"); - - } catch (SAXException e) { - monitor.logError("Failed to parse XML document"); - - } catch (IOException e) { - monitor.logError("Failed to read XML document"); - } - - return null; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSourceCategory.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSourceCategory.java deleted file mode 100755 index 5272cd5..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSourceCategory.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.sdklib.internal.repository.IDescription; - - -/** - * The category of a given {@link SdkSource} (which represents a download site). - */ -public enum SdkSourceCategory implements IDescription { - - /** - * The default canonical and official Android repository. - */ - ANDROID_REPO("Android Repository", true), - - /** - * Repositories contributed by the SDK_UPDATER_URLS env var, - * only used for local debugging. - */ - GETENV_REPOS("Custom Repositories", false), - - /** - * All third-party add-ons fetched from the Android repository. - */ - ADDONS_3RD_PARTY("Third party Add-ons", true), - - /** - * All add-ons contributed locally by the user via the "Add Add-on Site" button. - */ - USER_ADDONS("User Add-ons", false), - - /** - * Add-ons contributed by the SDK_UPDATER_USER_URLS env var, - * only used for local debugging. - */ - GETENV_ADDONS("Custom Add-ons", false); - - - private final String mUiName; - private final boolean mAlwaysDisplay; - - private SdkSourceCategory(String uiName, boolean alwaysDisplay) { - mUiName = uiName; - mAlwaysDisplay = alwaysDisplay; - } - - /** - * Returns the UI-visible name of the cateogry. Displayed in the available package tree. - * Cannot be null nor empty. - */ - public String getUiName() { - return mUiName; - } - - /** - * True if this category must always be displayed by the available package tree, even - * if empty. - * When false, the category must not be displayed when empty. - */ - public boolean getAlwaysDisplay() { - return mAlwaysDisplay; - } - - @Override - public String getLongDescription() { - return getUiName(); - } - - @Override - public String getShortDescription() { - return getUiName(); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSourceProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSourceProperties.java deleted file mode 100755 index cdd428f..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSourceProperties.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Properties; - -/** - * Properties for individual sources which are persisted by a local settings file. - * <p/> - * All instances of {@link SdkSourceProperties} share the same singleton storage. - * The persisted setting file is loaded as necessary, however callers must persist - * it at some point by calling {@link #save()}. - */ -public class SdkSourceProperties { - - /** - * An internal file version number, in case we want to change the format later. - */ - private static final String KEY_VERSION = "@version@"; //$NON-NLS-1$ - /** - * The last known UI name of the source. - */ - public static final String KEY_NAME = "@name@"; //$NON-NLS-1$ - /** - * A non-null string if the source is disabled. Null if the source is enabled. - */ - public static final String KEY_DISABLED = "@disabled@"; //$NON-NLS-1$ - - private static final Properties sSourcesProperties = new Properties(); - private static final String SRC_FILENAME = "sites-settings.cfg"; //$NON-NLS-1$ - - private static boolean sModified = false; - - public SdkSourceProperties() { - } - - public void save() { - synchronized (sSourcesProperties) { - if (sModified && !sSourcesProperties.isEmpty()) { - saveLocked(); - sModified = false; - } - } - } - - /** - * Retrieves a property for the given source URL and the given key type. - * <p/> - * Implementation detail: this loads the persistent settings file as needed. - * - * @param key The kind of property to retrieve for that source URL. - * @param sourceUrl The source URL. - * @param defaultValue The default value to return, if the property isn't found. Can be null. - * @return The non-null string property for the key/sourceUrl or the default value. - */ - @Nullable - public String getProperty(@NonNull String key, - @NonNull String sourceUrl, - @Nullable String defaultValue) { - String value = defaultValue; - - synchronized (sSourcesProperties) { - if (sSourcesProperties.isEmpty()) { - loadLocked(); - } - - value = sSourcesProperties.getProperty(key + sourceUrl, defaultValue); - } - - return value; - } - - /** - * Sets or remove a property for the given source URL and the given key type. - * <p/> - * Implementation detail: this does <em>not</em> save the persistent settings file. - * Somehow the caller will need to call the {@link #save()} method later. - * - * @param key The kind of property to retrieve for that source URL. - * @param sourceUrl The source URL. - * @param value The new value to set (if non null) or null to remove an existing property. - */ - public void setProperty(String key, String sourceUrl, String value) { - synchronized (sSourcesProperties) { - if (sSourcesProperties.isEmpty()) { - loadLocked(); - } - - key += sourceUrl; - - String old = sSourcesProperties.getProperty(key); - if (value == null) { - if (old != null) { - sSourcesProperties.remove(key); - sModified = true; - } - } else if (old == null || !old.equals(value)) { - sSourcesProperties.setProperty(key, value); - sModified = true; - } - } - } - - /** - * Returns an internal string representation of the underlying Properties map, - * sorted by ascending keys. Useful for debugging and testing purposes only. - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder("<SdkSourceProperties"); //$NON-NLS-1$ - synchronized (sSourcesProperties) { - List<Object> keys = Collections.list(sSourcesProperties.keys()); - Collections.sort(keys, new Comparator<Object>() { - @Override - public int compare(Object o1, Object o2) { - return o1.toString().compareTo(o2.toString()); - }}); - - for (Object key : keys) { - sb.append('\n').append(key) - .append(" = ").append(sSourcesProperties.get(key)); //$NON-NLS-1$ - } - } - sb.append('>'); - return sb.toString(); - } - - /** Load state from persistent file. Expects sSourcesProperties to be synchronized. */ - private void loadLocked() { - // Load state from persistent file - if (loadProperties()) { - // If it lacks our magic version key, don't use it - if (sSourcesProperties.getProperty(KEY_VERSION) == null) { - sSourcesProperties.clear(); - } - - sModified = false; - } - - if (sSourcesProperties.isEmpty()) { - // Nothing was loaded. Initialize the storage with a version - // identified. This isn't currently checked back, but we might - // want it later if we decide to change the way this works. - // The version key is choosen on purpose to not match any valid URL. - sSourcesProperties.setProperty(KEY_VERSION, "1"); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - /** - * Load properties from default file. Extracted so that it can be mocked in tests. - * - * @return True if actually loaded the file. False if there was an IO error or no - * file and nothing was loaded. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected boolean loadProperties() { - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SRC_FILENAME); - if (f.exists()) { - FileInputStream fis = null; - try { - fis = new FileInputStream(f); - sSourcesProperties.load(fis); - } catch (IOException ignore) { - // nop - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException ignore) {} - } - } - - return true; - } - } catch (AndroidLocationException ignore) { - // nop - } - return false; - } - - /** - * Save file to disk. Expects sSourcesProperties to be synchronized. - * Made accessible for testing purposes. - * For public usage, please use {@link #save()} instead. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected void saveLocked() { - // Persist it to the file - FileOutputStream fos = null; - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SRC_FILENAME); - - fos = new FileOutputStream(f); - - sSourcesProperties.store(fos,"## Sites Settings for Android SDK Manager");//$NON-NLS-1$ - - } catch (AndroidLocationException ignore) { - // nop - } catch (IOException ignore) { - // nop - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException ignore) {} - } - } - } - - /** Empty current property list. Made accessible for testing purposes. */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected void clear() { - synchronized (sSourcesProperties) { - sSourcesProperties.clear(); - sModified = false; - } - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSources.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSources.java deleted file mode 100755 index c89df5e..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSources.java +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.repository.SdkSysImgConstants; -import com.android.utils.ILogger; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.Iterator; -import java.util.Properties; -import java.util.Map.Entry; - -/** - * A list of sdk-repository and sdk-addon sources, sorted by {@link SdkSourceCategory}. - */ -public class SdkSources { - - private static final String KEY_COUNT = "count"; - - private static final String KEY_SRC = "src"; - - private static final String SRC_FILENAME = "repositories.cfg"; //$NON-NLS-1$ - - private final EnumMap<SdkSourceCategory, ArrayList<SdkSource>> mSources = - new EnumMap<SdkSourceCategory, ArrayList<SdkSource>>(SdkSourceCategory.class); - - private ArrayList<Runnable> mChangeListeners; // lazily initialized - - - public SdkSources() { - } - - /** - * Adds a new source to the Sources list. - * <p/> - * Implementation detail: {@link SdkSources} doesn't invoke {@link #notifyChangeListeners()} - * directly. Callers who use {@code add()} are responsible for notifying the listeners once - * they are done modifying the sources list. The intent is to notify the listeners only once - * at the end, not for every single addition. - */ - public void add(SdkSourceCategory category, SdkSource source) { - synchronized (mSources) { - ArrayList<SdkSource> list = mSources.get(category); - if (list == null) { - list = new ArrayList<SdkSource>(); - mSources.put(category, list); - } - - list.add(source); - } - } - - /** - * Removes a source from the Sources list. - * <p/> - * Callers who remove entries are responsible for notifying the listeners using - * {@link #notifyChangeListeners()} once they are done modifying the sources list. - */ - public void remove(SdkSource source) { - synchronized (mSources) { - Iterator<Entry<SdkSourceCategory, ArrayList<SdkSource>>> it = - mSources.entrySet().iterator(); - while (it.hasNext()) { - Entry<SdkSourceCategory, ArrayList<SdkSource>> entry = it.next(); - ArrayList<SdkSource> list = entry.getValue(); - - if (list.remove(source)) { - if (list.isEmpty()) { - // remove the entry since the source list became empty - it.remove(); - } - } - } - } - } - - /** - * Removes all the sources in the given category. - * <p/> - * Callers who remove entries are responsible for notifying the listeners using - * {@link #notifyChangeListeners()} once they are done modifying the sources list. - */ - public void removeAll(SdkSourceCategory category) { - synchronized (mSources) { - mSources.remove(category); - } - } - - /** - * Returns a set of all categories that must be displayed. This includes all - * categories that are to be always displayed as well as all categories which - * have at least one source. - * Might return a empty array, but never returns null. - */ - public SdkSourceCategory[] getCategories() { - ArrayList<SdkSourceCategory> cats = new ArrayList<SdkSourceCategory>(); - - for (SdkSourceCategory cat : SdkSourceCategory.values()) { - if (cat.getAlwaysDisplay()) { - cats.add(cat); - } else { - synchronized (mSources) { - ArrayList<SdkSource> list = mSources.get(cat); - if (list != null && !list.isEmpty()) { - cats.add(cat); - } - } - } - } - - return cats.toArray(new SdkSourceCategory[cats.size()]); - } - - /** - * Returns a new array of sources attached to the given category. - * Might return an empty array, but never returns null. - */ - public SdkSource[] getSources(SdkSourceCategory category) { - synchronized (mSources) { - ArrayList<SdkSource> list = mSources.get(category); - if (list == null) { - return new SdkSource[0]; - } else { - return list.toArray(new SdkSource[list.size()]); - } - } - } - - /** - * Returns an array of the sources across all categories. This is never null. - */ - public SdkSource[] getAllSources() { - synchronized (mSources) { - int n = 0; - - for (ArrayList<SdkSource> list : mSources.values()) { - n += list.size(); - } - - SdkSource[] sources = new SdkSource[n]; - - int i = 0; - for (ArrayList<SdkSource> list : mSources.values()) { - for (SdkSource source : list) { - sources[i++] = source; - } - } - - return sources; - } - } - - /** - * Each source keeps a local cache of whatever it loaded recently. - * This calls {@link SdkSource#clearPackages()} on all the available sources, - * and the next call to {@link SdkSource#getPackages()} will actually reload - * the remote package list. - */ - public void clearAllPackages() { - synchronized (mSources) { - for (ArrayList<SdkSource> list : mSources.values()) { - for (SdkSource source : list) { - source.clearPackages(); - } - } - } - } - - /** - * Returns the category of a given source, or null if the source is unknown. - * <p/> - * Note that this method uses object identity to find a given source, and does - * not identify sources by their URL like {@link #hasSourceUrl(SdkSource)} does. - * <p/> - * The search is O(N), which should be acceptable on the expectedly small source list. - */ - public SdkSourceCategory getCategory(SdkSource source) { - if (source != null) { - synchronized (mSources) { - for (Entry<SdkSourceCategory, ArrayList<SdkSource>> entry : mSources.entrySet()) { - if (entry.getValue().contains(source)) { - return entry.getKey(); - } - } - } - } - return null; - } - - /** - * Returns true if there's already a similar source in the sources list - * under any category. - * <p/> - * Important: The match is NOT done on object identity. - * Instead, this searches for a <em>similar</em> source, based on - * {@link SdkSource#equals(Object)} which compares the source URLs. - * <p/> - * The search is O(N), which should be acceptable on the expectedly small source list. - */ - public boolean hasSourceUrl(SdkSource source) { - synchronized (mSources) { - for (ArrayList<SdkSource> list : mSources.values()) { - for (SdkSource s : list) { - if (s.equals(source)) { - return true; - } - } - } - return false; - } - } - - /** - * Returns true if there's already a similar source in the sources list - * under the specified category. - * <p/> - * Important: The match is NOT done on object identity. - * Instead, this searches for a <em>similar</em> source, based on - * {@link SdkSource#equals(Object)} which compares the source URLs. - * <p/> - * The search is O(N), which should be acceptable on the expectedly small source list. - */ - public boolean hasSourceUrl(SdkSourceCategory category, SdkSource source) { - synchronized (mSources) { - ArrayList<SdkSource> list = mSources.get(category); - if (list != null) { - for (SdkSource s : list) { - if (s.equals(source)) { - return true; - } - } - } - return false; - } - } - - /** - * Loads all user sources. This <em>replaces</em> all existing user sources - * by the ones from the property file. - * <p/> - * This calls {@link #notifyChangeListeners()} at the end of the operation. - */ - public void loadUserAddons(ILogger log) { - // Implementation detail: synchronize on the sources list to make sure that - // a- the source list doesn't change while we load/save it, and most important - // b- to make sure it's not being saved while loaded or the reverse. - // In most cases we do these operation from the UI thread so it's not really - // that necessary. This is more a protection in case of someone calls this - // from a worker thread by mistake. - synchronized (mSources) { - // Remove all existing user sources - removeAll(SdkSourceCategory.USER_ADDONS); - - // Load new user sources from property file - FileInputStream fis = null; - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SRC_FILENAME); - if (f.exists()) { - fis = new FileInputStream(f); - - Properties props = new Properties(); - props.load(fis); - - int count = Integer.parseInt(props.getProperty(KEY_COUNT, "0")); - - for (int i = 0; i < count; i++) { - String url = props.getProperty(String.format("%s%02d", KEY_SRC, i)); //$NON-NLS-1$ - if (url != null) { - // FIXME: this code originally only dealt with add-on XML sources. - // Now we'd like it to deal with system-image sources too, but we - // don't know which kind of object it is (at least not without - // trying to fetch it.) As a temporary workaround, just take a - // guess based on the leaf URI name. However ideally what we can - // simply do is add a checkbox "is system-image XML" in the user - // dialog and pass this info down here. Another alternative is to - // make a "dynamic" source object that tries to guess its type once - // the URI has been fetched. - SdkSource s; - if (url.endsWith(SdkSysImgConstants.URL_DEFAULT_FILENAME)) { - s = new SdkSysImgSource(url, null/*uiName*/); - } else { - s = new SdkAddonSource(url, null/*uiName*/); - } - if (!hasSourceUrl(s)) { - add(SdkSourceCategory.USER_ADDONS, s); - } - } - } - } - - } catch (NumberFormatException e) { - log.error(e, null); - - } catch (AndroidLocationException e) { - log.error(e, null); - - } catch (IOException e) { - log.error(e, null); - - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - } - } - } - } - notifyChangeListeners(); - } - - /** - * Saves all the user sources. - * @param log Logger. Cannot be null. - */ - public void saveUserAddons(ILogger log) { - // See the implementation detail note in loadUserAddons() about the synchronization. - synchronized (mSources) { - FileOutputStream fos = null; - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SRC_FILENAME); - - fos = new FileOutputStream(f); - - Properties props = new Properties(); - - int count = 0; - for (SdkSource s : getSources(SdkSourceCategory.USER_ADDONS)) { - props.setProperty(String.format("%s%02d", KEY_SRC, count), //$NON-NLS-1$ - s.getUrl()); - count++; - } - props.setProperty(KEY_COUNT, Integer.toString(count)); - - props.store( fos, "## User Sources for Android SDK Manager"); //$NON-NLS-1$ - - } catch (AndroidLocationException e) { - log.error(e, null); - - } catch (IOException e) { - log.error(e, null); - - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - } - } - } - } - } - - /** - * Adds a listener that will be notified when the sources list has changed. - * - * @param changeListener A non-null listener to add. Ignored if already present. - * @see SdkSources#notifyChangeListeners() - */ - public void addChangeListener(Runnable changeListener) { - assert changeListener != null; - if (mChangeListeners == null) { - mChangeListeners = new ArrayList<Runnable>(); - } - synchronized (mChangeListeners) { - if (changeListener != null && !mChangeListeners.contains(changeListener)) { - mChangeListeners.add(changeListener); - } - } - } - - /** - * Removes a listener from the list of listeners to notify when the sources change. - * - * @param changeListener A listener to remove. Ignored if not previously added. - */ - public void removeChangeListener(Runnable changeListener) { - if (mChangeListeners != null && changeListener != null) { - synchronized (mChangeListeners) { - mChangeListeners.remove(changeListener); - } - } - } - - /** - * Invoke all the registered change listeners, if any. - * <p/> - * This <em>may</em> be called from a worker thread, in which case the runnable - * should take care of only updating UI from a main thread. - */ - public void notifyChangeListeners() { - if (mChangeListeners == null) { - return; - } - synchronized (mChangeListeners) { - for (Runnable runnable : mChangeListeners) { - try { - runnable.run(); - } catch (Throwable ignore) { - assert ignore == null : - "A SdkSource.ChangeListener failed with an exception: " + ignore.toString(); - } - } - } - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java deleted file mode 100755 index 7909bff..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/sources/SdkSysImgSource.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.annotations.Nullable; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.repository.SdkSysImgConstants; - -import org.w3c.dom.Document; - -import java.io.InputStream; - - -/** - * An sdk-sys-img source, i.e. a download site for system-image packages. - * A repository describes one or more {@link Package}s available for download. - */ -public class SdkSysImgSource extends SdkSource { - - /** - * Constructs a new source for the given repository URL. - * @param url The source URL. Cannot be null. If the URL ends with a /, the default - * sys-img.xml filename will be appended automatically. - * @param uiName The UI-visible name of the source. Can be null. - */ - public SdkSysImgSource(String url, String uiName) { - super(url, uiName); - } - - /** - * Returns true if this is an addon source. - * We only load addons and extras from these sources. - */ - @Override - public boolean isAddonSource() { - return false; - } - - /** - * Returns true if this is a system-image source. - * We only load system-images from these sources. - */ - @Override - public boolean isSysImgSource() { - return true; - } - - - @Override - protected String[] getDefaultXmlFileUrls() { - return new String[] { SdkSysImgConstants.URL_DEFAULT_FILENAME }; - } - - @Override - protected int getNsLatestVersion() { - return SdkSysImgConstants.NS_LATEST_VERSION; - } - - @Override - protected String getNsUri() { - return SdkSysImgConstants.NS_URI; - } - - @Override - protected String getNsPattern() { - return SdkSysImgConstants.NS_PATTERN; - } - - @Override - protected String getSchemaUri(int version) { - return SdkSysImgConstants.getSchemaUri(version); - } - - @Override - protected String getRootElementName() { - return SdkSysImgConstants.NODE_SDK_SYS_IMG; - } - - @Override - protected InputStream getXsdStream(int version) { - return SdkSysImgConstants.getXsdStream(version); - } - - /** - * This kind of schema does not support forward-evolution of the <tool> element. - * - * @param xml The input XML stream. Can be null. - * @return Always null. - * @null This implementation always return null. - */ - @Override - protected Document findAlternateToolsXml(@Nullable InputStream xml) { - return null; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/io/FileOp.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/io/FileOp.java deleted file mode 100755 index 7bbe54f..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/io/FileOp.java +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.io; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Properties; - - -/** - * Wraps some common {@link File} operations on files and folders. - * <p/> - * This makes it possible to override/mock/stub some file operations in unit tests. - */ -public class FileOp implements IFileOp { - - /** - * Reflection method for File.setExecutable(boolean, boolean). Only present in Java 6. - */ - private static Method sFileSetExecutable = null; - - /** - * Parameters to call File.setExecutable through reflection. - */ - private final static Object[] sFileSetExecutableParams = new Object[] { - Boolean.TRUE, Boolean.FALSE }; - - // static initialization of sFileSetExecutable. - static { - try { - sFileSetExecutable = File.class.getMethod("setExecutable", //$NON-NLS-1$ - boolean.class, boolean.class); - - } catch (SecurityException e) { - // do nothing we'll use chdmod instead - } catch (NoSuchMethodException e) { - // do nothing we'll use chdmod instead - } - } - - /** - * Appends the given {@code segments} to the {@code base} file. - * - * @param base A base file, non-null. - * @param segments Individual folder or filename segments to append to the base file. - * @return A new file representing the concatenation of the base path with all the segments. - */ - public static File append(File base, String...segments) { - for (String segment : segments) { - base = new File(base, segment); - } - return base; - } - - /** - * Appends the given {@code segments} to the {@code base} file. - * - * @param base A base file path, non-empty and non-null. - * @param segments Individual folder or filename segments to append to the base path. - * @return A new file representing the concatenation of the base path with all the segments. - */ - public static File append(String base, String...segments) { - return append(new File(base), segments); - } - - /** - * Helper to delete a file or a directory. - * For a directory, recursively deletes all of its content. - * Files that cannot be deleted right away are marked for deletion on exit. - * It's ok for the file or folder to not exist at all. - * The argument can be null. - */ - @Override - public void deleteFileOrFolder(File fileOrFolder) { - if (fileOrFolder != null) { - if (isDirectory(fileOrFolder)) { - // Must delete content recursively first - File[] files = fileOrFolder.listFiles(); - if (files != null) { - for (File item : files) { - deleteFileOrFolder(item); - } - } - } - - // Don't try to delete it if it doesn't exist. - if (!exists(fileOrFolder)) { - return; - } - - if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) { - // Trying to delete a resource on windows might fail if there's a file - // indexer locking the resource. Generally retrying will be enough to - // make it work. - // - // Try for half a second before giving up. - - for (int i = 0; i < 5; i++) { - if (fileOrFolder.delete()) { - return; - } - - try { - Thread.sleep(100 /*ms*/); - } catch (InterruptedException e) { - // Ignore. - } - } - - fileOrFolder.deleteOnExit(); - - } else { - // On Linux or Mac, just straight deleting it should just work. - - if (!fileOrFolder.delete()) { - fileOrFolder.deleteOnExit(); - } - } - } - } - - /** - * Sets the executable Unix permission (+x) on a file or folder. - * <p/> - * This attempts to use File#setExecutable through reflection if - * it's available. - * If this is not available, this invokes a chmod exec instead, - * so there is no guarantee of it being fast. - * <p/> - * Caller must make sure to not invoke this under Windows. - * - * @param file The file to set permissions on. - * @throws IOException If an I/O error occurs - */ - @Override - public void setExecutablePermission(File file) throws IOException { - - if (sFileSetExecutable != null) { - try { - sFileSetExecutable.invoke(file, sFileSetExecutableParams); - return; - } catch (IllegalArgumentException e) { - // we'll run chmod below - } catch (IllegalAccessException e) { - // we'll run chmod below - } catch (InvocationTargetException e) { - // we'll run chmod below - } - } - - Runtime.getRuntime().exec(new String[] { - "chmod", "+x", file.getAbsolutePath() //$NON-NLS-1$ //$NON-NLS-2$ - }); - } - - /** - * {@inheritDoc} - */ - @Override - public void setReadOnly(File file) { - file.setReadOnly(); - } - - /** - * Copies a binary file. - * - * @param source the source file to copy. - * @param dest the destination file to write. - * @throws FileNotFoundException if the source file doesn't exist. - * @throws IOException if there's a problem reading or writing the file. - */ - @Override - public void copyFile(File source, File dest) throws IOException { - byte[] buffer = new byte[8192]; - - FileInputStream fis = null; - FileOutputStream fos = null; - try { - fis = new FileInputStream(source); - fos = new FileOutputStream(dest); - - int read; - while ((read = fis.read(buffer)) != -1) { - fos.write(buffer, 0, read); - } - - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - // Ignore. - } - } - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - // Ignore. - } - } - } - } - - /** - * Checks whether 2 binary files are the same. - * - * @param source the source file to copy - * @param destination the destination file to write - * @throws FileNotFoundException if the source files don't exist. - * @throws IOException if there's a problem reading the files. - */ - @Override - public boolean isSameFile(File source, File destination) throws IOException { - - if (source.length() != destination.length()) { - return false; - } - - FileInputStream fis1 = null; - FileInputStream fis2 = null; - - try { - fis1 = new FileInputStream(source); - fis2 = new FileInputStream(destination); - - byte[] buffer1 = new byte[8192]; - byte[] buffer2 = new byte[8192]; - - int read1; - while ((read1 = fis1.read(buffer1)) != -1) { - int read2 = 0; - while (read2 < read1) { - int n = fis2.read(buffer2, read2, read1 - read2); - if (n == -1) { - break; - } - } - - if (read2 != read1) { - return false; - } - - if (!Arrays.equals(buffer1, buffer2)) { - return false; - } - } - } finally { - if (fis2 != null) { - try { - fis2.close(); - } catch (IOException e) { - // ignore - } - } - if (fis1 != null) { - try { - fis1.close(); - } catch (IOException e) { - // ignore - } - } - } - - return true; - } - - /** Invokes {@link File#isFile()} on the given {@code file}. */ - @Override - public boolean isFile(File file) { - return file.isFile(); - } - - /** Invokes {@link File#isDirectory()} on the given {@code file}. */ - @Override - public boolean isDirectory(File file) { - return file.isDirectory(); - } - - /** Invokes {@link File#exists()} on the given {@code file}. */ - @Override - public boolean exists(File file) { - return file.exists(); - } - - /** Invokes {@link File#length()} on the given {@code file}. */ - @Override - public long length(File file) { - return file.length(); - } - - /** - * Invokes {@link File#delete()} on the given {@code file}. - * Note: for a recursive folder version, consider {@link #deleteFileOrFolder(File)}. - */ - @Override - public boolean delete(File file) { - return file.delete(); - } - - /** Invokes {@link File#mkdirs()} on the given {@code file}. */ - @Override - public boolean mkdirs(File file) { - return file.mkdirs(); - } - - /** Invokes {@link File#listFiles()} on the given {@code file}. */ - @Override - public File[] listFiles(File file) { - return file.listFiles(); - } - - /** Invokes {@link File#renameTo(File)} on the given files. */ - @Override - public boolean renameTo(File oldFile, File newFile) { - return oldFile.renameTo(newFile); - } - - /** Creates a new {@link FileOutputStream} for the given {@code file}. */ - @Override - public OutputStream newFileOutputStream(File file) throws FileNotFoundException { - return new FileOutputStream(file); - } - - @Override - public @NonNull Properties loadProperties(@NonNull File file) { - Properties props = new Properties(); - FileInputStream fis = null; - try { - fis = new FileInputStream(file); - props.load(fis); - } catch (IOException ignore) { - } finally { - if (fis != null) { - try { - fis.close(); - } catch (Exception ignore) {} - } - } - return props; - } - - @Override - public boolean saveProperties(@NonNull File file, @NonNull Properties props, - @NonNull String comments) { - OutputStream fos = null; - try { - fos = newFileOutputStream(file); - - props.store(fos, comments); - return true; - } catch (IOException ignore) { - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - } - } - } - - return false; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/io/IFileOp.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/io/IFileOp.java deleted file mode 100755 index 5b131d5..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/io/IFileOp.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.io; - -import com.android.annotations.NonNull; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Properties; - - -/** - * Wraps some common {@link File} operations on files and folders. - * <p/> - * This makes it possible to override/mock/stub some file operations in unit tests. - */ -public interface IFileOp { - - /** - * Helper to delete a file or a directory. - * For a directory, recursively deletes all of its content. - * Files that cannot be deleted right away are marked for deletion on exit. - * It's ok for the file or folder to not exist at all. - * The argument can be null. - */ - public abstract void deleteFileOrFolder(File fileOrFolder); - - /** - * Sets the executable Unix permission (+x) on a file or folder. - * <p/> - * This attempts to use File#setExecutable through reflection if - * it's available. - * If this is not available, this invokes a chmod exec instead, - * so there is no guarantee of it being fast. - * <p/> - * Caller must make sure to not invoke this under Windows. - * - * @param file The file to set permissions on. - * @throws IOException If an I/O error occurs - */ - public abstract void setExecutablePermission(File file) throws IOException; - - /** - * Sets the file or directory as read-only. - * - * @param file The file or directory to set permissions on. - */ - public abstract void setReadOnly(File file); - - /** - * Copies a binary file. - * - * @param source the source file to copy. - * @param dest the destination file to write. - * @throws FileNotFoundException if the source file doesn't exist. - * @throws IOException if there's a problem reading or writing the file. - */ - public abstract void copyFile(File source, File dest) throws IOException; - - /** - * Checks whether 2 binary files are the same. - * - * @param source the source file to copy - * @param destination the destination file to write - * @throws FileNotFoundException if the source files don't exist. - * @throws IOException if there's a problem reading the files. - */ - public abstract boolean isSameFile(File source, File destination) - throws IOException; - - /** Invokes {@link File#exists()} on the given {@code file}. */ - public abstract boolean exists(File file); - - /** Invokes {@link File#isFile()} on the given {@code file}. */ - public abstract boolean isFile(File file); - - /** Invokes {@link File#isDirectory()} on the given {@code file}. */ - public abstract boolean isDirectory(File file); - - /** Invokes {@link File#length()} on the given {@code file}. */ - public abstract long length(File file); - - /** - * Invokes {@link File#delete()} on the given {@code file}. - * Note: for a recursive folder version, consider {@link #deleteFileOrFolder(File)}. - */ - public abstract boolean delete(File file); - - /** Invokes {@link File#mkdirs()} on the given {@code file}. */ - public abstract boolean mkdirs(File file); - - /** Invokes {@link File#listFiles()} on the given {@code file}. */ - public abstract File[] listFiles(File file); - - /** Invokes {@link File#renameTo(File)} on the given files. */ - public abstract boolean renameTo(File oldDir, File newDir); - - /** Creates a new {@link FileOutputStream} for the given {@code file}. */ - public abstract OutputStream newFileOutputStream(File file) throws FileNotFoundException; - - /** - * Load {@link Properties} from a file. Returns an empty property set on error. - * - * @param file A non-null file to load from. File may not exist. - * @return A new {@link Properties} with the properties loaded from the file, - * or an empty property set in case of error. - */ - public @NonNull Properties loadProperties(@NonNull File file); - - /** - * Saves (write, store) the given {@link Properties} into the given {@link File}. - * - * @param file A non-null file to write to. - * @param props The properties to write. - * @param comments A non-null description of the properly list, written in the file. - * @return True if the properties could be saved, false otherwise. - */ - public boolean saveProperties( - @NonNull File file, - @NonNull Properties props, - @NonNull String comments); -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/io/NonClosingInputStream.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/io/NonClosingInputStream.java deleted file mode 100755 index 470b706..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/io/NonClosingInputStream.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.io; - -import com.android.annotations.NonNull; - -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; - - -/** - * Wraps an {@link InputStream} to change its closing behavior: - * this makes it possible to ignore close operations or have them perform a - * {@link InputStream#reset()} instead (if supported by the underlying stream) - * or plain ignored. - */ -public class NonClosingInputStream extends FilterInputStream { - - private final InputStream mInputStream; - private CloseBehavior mCloseBehavior = CloseBehavior.CLOSE; - - public enum CloseBehavior { - /** - * The behavior of {@link NonClosingInputStream#close()} is to close the - * underlying input stream. This is the default. - */ - CLOSE, - /** - * The behavior of {@link NonClosingInputStream#close()} is to ignore the - * close request and do nothing. - */ - IGNORE, - /** - * The behavior of {@link NonClosingInputStream#close()} is to call - * {@link InputStream#reset()} on the underlying stream. This will - * only succeed if the underlying stream supports it, e.g. it must - * have {@link InputStream#markSupported()} return true <em>and</em> - * the caller should have called {@link InputStream#mark(int)} at some - * point before. - */ - RESET - } - - /** - * Wraps an existing stream into this filtering stream. - * @param in A non-null input stream. - */ - public NonClosingInputStream(@NonNull InputStream in) { - super(in); - mInputStream = in; - } - - /** - * Returns the current {@link CloseBehavior}. - * @return the current {@link CloseBehavior}. Never null. - */ - public @NonNull CloseBehavior getCloseBehavior() { - return mCloseBehavior; - } - - /** - * Changes the current {@link CloseBehavior}. - * - * @param closeBehavior A new non-null {@link CloseBehavior}. - * @return Self for chaining. - */ - public NonClosingInputStream setCloseBehavior(@NonNull CloseBehavior closeBehavior) { - mCloseBehavior = closeBehavior; - return this; - } - - /** - * Performs the requested {@code close()} operation, depending on the current - * {@link CloseBehavior}. - */ - @Override - public void close() throws IOException { - switch (mCloseBehavior) { - case IGNORE: - break; - case RESET: - mInputStream.reset(); - break; - case CLOSE: - mInputStream.close(); - break; - } - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/PkgProps.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/PkgProps.java deleted file mode 100755 index 68d7119..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/PkgProps.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - - - -/** - * Public constants used by the repository when saving {@code source.properties} - * files in local packages. - * <p/> - * These constants are public and part of the SDK Manager public API. - * Once published we can't change them arbitrarily since various parts - * of our build process depend on them. - */ -public class PkgProps { - - // Base Package - public static final String PKG_REVISION = "Pkg.Revision"; //$NON-NLS-1$ - public static final String PKG_LICENSE = "Pkg.License"; //$NON-NLS-1$ - public static final String PKG_DESC = "Pkg.Desc"; //$NON-NLS-1$ - public static final String PKG_DESC_URL = "Pkg.DescUrl"; //$NON-NLS-1$ - public static final String PKG_RELEASE_NOTE = "Pkg.RelNote"; //$NON-NLS-1$ - public static final String PKG_RELEASE_URL = "Pkg.RelNoteUrl"; //$NON-NLS-1$ - public static final String PKG_SOURCE_URL = "Pkg.SourceUrl"; //$NON-NLS-1$ - public static final String PKG_OBSOLETE = "Pkg.Obsolete"; //$NON-NLS-1$ - - // AndroidVersion - - public static final String VERSION_API_LEVEL = "AndroidVersion.ApiLevel";//$NON-NLS-1$ - /** Code name of the platform if the platform is not final */ - public static final String VERSION_CODENAME = "AndroidVersion.CodeName";//$NON-NLS-1$ - - - // AddonPackage - - public static final String ADDON_NAME = "Addon.Name"; //$NON-NLS-1$ - public static final String ADDON_NAME_ID = "Addon.NameId"; //$NON-NLS-1$ - public static final String ADDON_NAME_DISPLAY = "Addon.NameDisplay"; //$NON-NLS-1$ - - public static final String ADDON_VENDOR = "Addon.Vendor"; //$NON-NLS-1$ - public static final String ADDON_VENDOR_ID = "Addon.VendorId"; //$NON-NLS-1$ - public static final String ADDON_VENDOR_DISPLAY = "Addon.VendorDisplay"; //$NON-NLS-1$ - - // DocPackage - - // ExtraPackage - - public static final String EXTRA_PATH = "Extra.Path"; //$NON-NLS-1$ - public static final String EXTRA_OLD_PATHS = "Extra.OldPaths"; //$NON-NLS-1$ - public static final String EXTRA_MIN_API_LEVEL = "Extra.MinApiLevel"; //$NON-NLS-1$ - public static final String EXTRA_PROJECT_FILES = "Extra.ProjectFiles"; //$NON-NLS-1$ - public static final String EXTRA_VENDOR = "Extra.Vendor"; //$NON-NLS-1$ - public static final String EXTRA_VENDOR_ID = "Extra.VendorId"; //$NON-NLS-1$ - public static final String EXTRA_VENDOR_DISPLAY = "Extra.VendorDisplay"; //$NON-NLS-1$ - public static final String EXTRA_NAME_DISPLAY = "Extra.NameDisplay"; //$NON-NLS-1$ - - // ILayoutlibVersion - - public static final String LAYOUTLIB_API = "Layoutlib.Api"; //$NON-NLS-1$ - public static final String LAYOUTLIB_REV = "Layoutlib.Revision"; //$NON-NLS-1$ - - // MinToolsPackage - - public static final String MIN_TOOLS_REV = "Platform.MinToolsRev"; //$NON-NLS-1$ - - // PlatformPackage - - public static final String PLATFORM_VERSION = "Platform.Version"; //$NON-NLS-1$ - /** Code name of the platform. This has no bearing on the package being a preview or not. */ - public static final String PLATFORM_CODENAME = "Platform.CodeName"; //$NON-NLS-1$ - public static final String PLATFORM_INCLUDED_ABI = "Platform.Included.Abi"; //$NON-NLS-1$ - - // ToolPackage - - public static final String MIN_PLATFORM_TOOLS_REV = "Platform.MinPlatformToolsRev";//$NON-NLS-1$ - - - // SamplePackage - - public static final String SAMPLE_MIN_API_LEVEL = "Sample.MinApiLevel"; //$NON-NLS-1$ - - // SystemImagePackage - - public static final String SYS_IMG_ABI = "SystemImage.Abi"; //$NON-NLS-1$ -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/README.txt b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/README.txt deleted file mode 100755 index e6e0f63..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/README.txt +++ /dev/null @@ -1,25 +0,0 @@ -This directory contains the XML Schemas (XSD) used by the Android SDK Repository. - -The repository exports all the packages that compose the SDK as well as -various manifest that define what is available in the repository. -The XML schemas available here allows clients to validate the manifests. - -TODO: -- overview of schemas -- principles of design -- principles of evolution vs revision numbers -- naming convention -- using by "make sdk_repo" - - -Naming Convention ------------------ - -Repository schemas are named sdk-type-N.xsd where -- type is either addon, addons-list or repository. -- N is the schema revision number, starting at 1 and increment with each revision. - -Schemas can also be named -sdk-type-N.xsd. -The dash prefix means this schema is a *future* schema that is not yet -used in production. This allows the repository to test future schemas -before they are deployed. diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java deleted file mode 100755 index 3fdfc91..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/RepoConstants.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - -import java.io.InputStream; - - - -/** - * Public constants common to the sdk-repository and sdk-addon XML Schemas. - */ -public class RepoConstants { - - /** The license definition. */ - public static final String NODE_LICENSE = "license"; //$NON-NLS-1$ - /** The optional uses-license for all packages or for a lib. */ - public static final String NODE_USES_LICENSE = "uses-license"; //$NON-NLS-1$ - /** The revision, an int > 0, for all packages. */ - public static final String NODE_REVISION = "revision"; //$NON-NLS-1$ - /** The optional description for all packages or for a lib. */ - public static final String NODE_DESCRIPTION = "description"; //$NON-NLS-1$ - /** The optional description URL for all packages. */ - public static final String NODE_DESC_URL = "desc-url"; //$NON-NLS-1$ - /** The optional release note for all packages. */ - public static final String NODE_RELEASE_NOTE = "release-note"; //$NON-NLS-1$ - /** The optional release note URL for all packages. */ - public static final String NODE_RELEASE_URL = "release-url"; //$NON-NLS-1$ - /** The optional obsolete qualifier for all packages. */ - public static final String NODE_OBSOLETE = "obsolete"; //$NON-NLS-1$ - /** The optional project-files provided by extra packages. */ - public static final String NODE_PROJECT_FILES = "project-files"; //$NON-NLS-1$ - - /** A system-image package. */ - public static final String NODE_SYSTEM_IMAGE = "system-image"; //$NON-NLS-1$ - - /* An included-ABI element for a system-image package. */ - public static final String NODE_ABI_INCLUDED = "included-abi"; //$NON-NLS-1$ - /* An ABI element for a system-image package. */ - public static final String NODE_ABI = "abi"; //$NON-NLS-1$ - - /** The optional minimal tools revision required by platform & extra packages. */ - public static final String NODE_MIN_TOOLS_REV = "min-tools-rev"; //$NON-NLS-1$ - /** The optional minimal platform-tools revision required by tool packages. */ - public static final String NODE_MIN_PLATFORM_TOOLS_REV = "min-platform-tools-rev"; //$NON-NLS-1$ - /** The optional minimal API level required by extra packages. */ - public static final String NODE_MIN_API_LEVEL = "min-api-level"; //$NON-NLS-1$ - - /** The version, a string, for platform packages. */ - public static final String NODE_VERSION = "version"; //$NON-NLS-1$ - /** The api-level, an int > 0, for platform, add-on and doc packages. */ - public static final String NODE_API_LEVEL = "api-level"; //$NON-NLS-1$ - /** The codename, a string, for platform packages. */ - public static final String NODE_CODENAME = "codename"; //$NON-NLS-1$ - /** The *old* vendor, a string, for add-on and extra packages. - * Replaced by {@link #NODE_VENDOR_DISPLAY} and {@link #NODE_VENDOR_ID} in addon-v4.xsd. */ - public static final String NODE_VENDOR = "vendor"; //$NON-NLS-1$ - /** The vendor display string, for add-on and extra packages. */ - public static final String NODE_VENDOR_DISPLAY = "vendor-display"; //$NON-NLS-1$ - /** The unique vendor id string, for add-on and extra packages. */ - public static final String NODE_VENDOR_ID = "vendor-id"; //$NON-NLS-1$ - /** The name, a string, for add-on packages or for libraries. - * Replaced by {@link #NODE_NAME_DISPLAY} and {@link #NODE_NAME_ID} in addon-v4.xsd. */ - public static final String NODE_NAME = "name"; //$NON-NLS-1$ - /** The name display string, for add-on packages or for libraries. */ - public static final String NODE_NAME_DISPLAY = "name-display"; //$NON-NLS-1$ - /** The unique name id string, for add-on packages or for libraries. */ - public static final String NODE_NAME_ID = "name-id"; //$NON-NLS-1$ - - - /** A layoutlib package. */ - public static final String NODE_LAYOUT_LIB = "layoutlib"; //$NON-NLS-1$ - /** The API integer for a layoutlib element. */ - public static final String NODE_API = "api"; //$NON-NLS-1$ - - /** The libs container, optional for an add-on. */ - public static final String NODE_LIBS = "libs"; //$NON-NLS-1$ - /** A lib element in a libs container. */ - public static final String NODE_LIB = "lib"; //$NON-NLS-1$ - - /** The path segment, a string, for extra packages. */ - public static final String NODE_PATH = "path"; //$NON-NLS-1$ - - /** The old_path segments, a string, for extra packages. */ - public static final String NODE_OLD_PATHS = "old-paths"; //$NON-NLS-1$ - - /** The archives container, for all packages. */ - public static final String NODE_ARCHIVES = "archives"; //$NON-NLS-1$ - /** An archive element, for the archives container. */ - public static final String NODE_ARCHIVE = "archive"; //$NON-NLS-1$ - - /** An archive size, an int > 0. */ - public static final String NODE_SIZE = "size"; //$NON-NLS-1$ - /** A sha1 archive checksum, as a 40-char hex. */ - public static final String NODE_CHECKSUM = "checksum"; //$NON-NLS-1$ - /** A download archive URL, either absolute or relative to the repository xml. */ - public static final String NODE_URL = "url"; //$NON-NLS-1$ - - /** An archive checksum type, mandatory. */ - public static final String ATTR_TYPE = "type"; //$NON-NLS-1$ - /** An archive OS attribute, mandatory. */ - public static final String ATTR_OS = "os"; //$NON-NLS-1$ - /** An optional archive Architecture attribute. */ - public static final String ATTR_ARCH = "arch"; //$NON-NLS-1$ - - /** A license definition ID. */ - public static final String ATTR_ID = "id"; //$NON-NLS-1$ - /** A license reference. */ - public static final String ATTR_REF = "ref"; //$NON-NLS-1$ - - /** Type of a sha1 checksum. */ - public static final String SHA1_TYPE = "sha1"; //$NON-NLS-1$ - - /** Length of a string representing a SHA1 checksum; always 40 characters long. */ - public static final int SHA1_CHECKSUM_LEN = 40; - - /** - * Temporary folder used to hold downloads and extract archives during installation. - * This folder will be located in the SDK. - */ - public static final String FD_TEMP = "temp"; //$NON-NLS-1$ - - /** - * Returns a stream to the requested XML Schema. - * This is an internal helper. Users of the library should call - * {@link SdkRepoConstants#getXsdStream(String, int)} or - * {@link SdkAddonConstants#getXsdStream(String, int)}. - * - * @param rootElement The root of the filename of the XML schema. - * This is by convention the same as the root element declared by the schema. - * @param version The XML schema revision number, an integer >= 1. - * @return An {@link InputStream} object for the local XSD file or - * null if there is no schema for the requested version. - * @see SdkRepoConstants#getXsdStream(int) - * @see SdkAddonConstants#getXsdStream(int) - */ - protected static InputStream getXsdStream(String rootElement, int version) { - String filename = String.format("%1$s-%2$d.xsd", rootElement, version); //$NON-NLS-1$ - - InputStream stream = null; - try { - stream = RepoConstants.class.getResourceAsStream(filename); - } catch (Exception e) { - // Some implementations seem to return null on failure, - // others throw an exception. We want to return null. - } - if (stream == null) { - // Try the alternate schemas that are not published yet. - // This allows us to internally test with new schemas before the - // public repository uses it. - filename = String.format("-%1$s-%2$d.xsd", rootElement, version); //$NON-NLS-1$ - try { - stream = RepoConstants.class.getResourceAsStream(filename); - } catch (Exception e) { - // Some implementations seem to return null on failure, - // others throw an exception. We want to return null. - } - } - - return stream; - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonConstants.java deleted file mode 100755 index 4af2276..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonConstants.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - - -import com.android.sdklib.internal.repository.sources.SdkSource; - -import java.io.InputStream; - -/** - * Public constants for the sdk-addon XML Schema. - */ -public class SdkAddonConstants extends RepoConstants { - - /** - * The default name looked for by {@link SdkSource} when trying to load an - * sdk-addon XML if the URL doesn't match an existing resource. - */ - public static final String URL_DEFAULT_FILENAME = "addon.xml"; //$NON-NLS-1$ - - /** The base of our sdk-addon XML namespace. */ - private static final String NS_BASE = - "http://schemas.android.com/sdk/android/addon/"; //$NON-NLS-1$ - - /** - * The pattern of our sdk-addon XML namespace. - * Matcher's group(1) is the schema version (integer). - */ - public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ - - /** - * The latest version of the sdk-addon XML Schema. - * Valid version numbers are between 1 and this number, included. - */ - public static final int NS_LATEST_VERSION = 5; - - /** The XML namespace of the latest sdk-addon XML. */ - public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION); - - /** The root sdk-addon element */ - public static final String NODE_SDK_ADDON = "sdk-addon"; //$NON-NLS-1$ - - /** An add-on package. */ - public static final String NODE_ADD_ON = "add-on"; //$NON-NLS-1$ - - /** An extra package. */ - public static final String NODE_EXTRA = "extra"; //$NON-NLS-1$ - - /** - * List of possible nodes in a repository XML. Used to populate options automatically - * in the no-GUI mode. - */ - public static final String[] NODES = { - NODE_ADD_ON, - NODE_EXTRA - }; - - /** - * Returns a stream to the requested {@code sdk-addon} XML Schema. - * - * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. - * @return An {@link InputStream} object for the local XSD file or - * null if there is no schema for the requested version. - */ - public static InputStream getXsdStream(int version) { - return getXsdStream(NODE_SDK_ADDON, version); - } - - /** - * Returns the URI of the sdk-addon schema for the given version number. - * @param version Between 1 and {@link #NS_LATEST_VERSION} included. - */ - public static String getSchemaUri(int version) { - return String.format(NS_BASE + "%d", version); //$NON-NLS-1$ - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java deleted file mode 100755 index 4f6b897..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkAddonsListConstants.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - - -import java.io.InputStream; - -/** - * Public constants for the sdk-addons-list XML Schema. - */ -public class SdkAddonsListConstants { - - /** The base of our sdk-addons-list XML namespace. */ - private static final String NS_BASE = - "http://schemas.android.com/sdk/android/addons-list/"; //$NON-NLS-1$ - - /** - * The pattern of our sdk-addons-list XML namespace. - * Matcher's group(1) is the schema version (integer). - */ - public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ - - /** The latest version of the sdk-addons-list XML Schema. - * Valid version numbers are between 1 and this number, included. */ - public static final int NS_LATEST_VERSION = 2; - - /** The XML namespace of the latest sdk-addons-list XML. */ - public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION); - - - /** The canonical URL filename for addons-list XML files. */ - public static final String URL_DEFAULT_FILENAME = getDefaultName(NS_LATEST_VERSION); - - /** The URL where to find the official addons list fle. */ - public static final String URL_ADDON_LIST = - SdkRepoConstants.URL_GOOGLE_SDK_SITE + URL_DEFAULT_FILENAME; - - - - /** The root sdk-addons-list element */ - public static final String NODE_SDK_ADDONS_LIST = "sdk-addons-list"; //$NON-NLS-1$ - - /** An add-on site. */ - public static final String NODE_ADDON_SITE = "addon-site"; //$NON-NLS-1$ - - /** A system image site. */ - public static final String NODE_SYS_IMG_SITE = "sys-img-site"; //$NON-NLS-1$ - - /** The UI-visible name of the add-on site. */ - public static final String NODE_NAME = "name"; //$NON-NLS-1$ - - /** - * The URL of the site. - * <p/> - * This can be either the exact URL of the an XML resource conforming - * to the latest sdk-addon-N.xsd schema, or it can be the URL of a - * 'directory', in which case the manager will look for a resource - * named 'addon.xml' at this location. - * <p/> - * Examples: - * <pre> - * http://www.example.com/android/my_addons.xml - * or - * http://www.example.com/android/ - * </pre> - * In the second example, the manager will actually look for - * http://www.example.com/android/addon.xml - */ - public static final String NODE_URL = "url"; //$NON-NLS-1$ - - /** - * Returns a stream to the requested sdk-addon XML Schema. - * - * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. - * @return An {@link InputStream} object for the local XSD file or - * null if there is no schema for the requested version. - */ - public static InputStream getXsdStream(int version) { - String filename = String.format("sdk-addons-list-%d.xsd", version); //$NON-NLS-1$ - return SdkAddonsListConstants.class.getResourceAsStream(filename); - } - - /** - * Returns the URI of the sdk-addon schema for the given version number. - * @param version Between 1 and {@link #NS_LATEST_VERSION} included. - */ - public static String getSchemaUri(int version) { - return String.format(NS_BASE + "%d", version); //$NON-NLS-1$ - } - - public static String getDefaultName(int version) { - return String.format("addons_list-%1$d.xml", version); //$NON-NLS-1$ - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java deleted file mode 100755 index 48c9b25..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkRepoConstants.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - - -import com.android.sdklib.internal.repository.sources.SdkSource; - -import java.io.InputStream; - -/** - * Public constants for the sdk-repository XML Schema. - */ -public class SdkRepoConstants extends RepoConstants { - - /** - * The latest version of the sdk-repository XML Schema. - * Valid version numbers are between 1 and this number, included. - */ - public static final int NS_LATEST_VERSION = 7; - - /** - * The min version of the sdk-repository XML Schema we'll try to load. - * When looking for a repository-N.xml on the server, we'll check from - * {@link #NS_LATEST_VERSION} down to this revision. - * We only introduced the "repository-N.xml" pattern start with revision - * 5, so we know that <em>our</em> server will never contain a repository - * XML with a schema version lower than this one. - */ - public static final int NS_SERVER_MIN_VERSION = 5; - - /** - * The URL of the official Google sdk-repository site. - * The URL ends with a /, allowing easy concatenation. - * */ - public static final String URL_GOOGLE_SDK_SITE = - "https://dl-ssl.google.com/android/repository/"; //$NON-NLS-1$ - - /** - * The default name looked for by {@link SdkSource} when trying to load an - * sdk-repository XML if the URL doesn't match an existing resource. - */ - public static final String URL_DEFAULT_FILENAME = "repository.xml"; //$NON-NLS-1$ - - /** - * The pattern name looked by {@link SdkSource} when trying to load - * an sdk-repository XML that is specific to a given XSD revision. - * <p/> - * This must be used with {@link String#format(String, Object...)} with - * one integer parameter between 1 and {@link #NS_LATEST_VERSION}. - */ - public static final String URL_FILENAME_PATTERN = "repository-%1$d.xml"; //$NON-NLS-1$ - - /** The base of our sdk-repository XML namespace. */ - private static final String NS_BASE = - "http://schemas.android.com/sdk/android/repository/"; //$NON-NLS-1$ - - /** - * The pattern of our sdk-repository XML namespace. - * Matcher's group(1) is the schema version (integer). - */ - public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ - - /** The XML namespace of the latest sdk-repository XML. */ - public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION); - - /** The root sdk-repository element */ - public static final String NODE_SDK_REPOSITORY = "sdk-repository"; //$NON-NLS-1$ - - /* The major revision for tool and platform-tool package - * (the full revision number is revision.minor.micro + preview#.) - * Mandatory int > 0. 0 when missing, which should not happen in - * a valid document. */ - public static final String NODE_MAJOR_REV = "major"; //$NON-NLS-1$ - /* The minor revision for tool and platform-tool package - * (the full revision number is revision.minor.micro + preview#.) - * Optional int >= 0. Implied to be 0 when missing. */ - public static final String NODE_MINOR_REV = "minor"; //$NON-NLS-1$ - /* The micro revision for tool and platform-tool package - * (the full revision number is revision.minor.micro + preview#.) - * Optional int >= 0. Implied to be 0 when missing. */ - public static final String NODE_MICRO_REV = "micro"; //$NON-NLS-1$ - /* The preview revision for tool and platform-tool package. - * Int > 0, only present for "preview / release candidate" packages. */ - public static final String NODE_PREVIEW = "preview"; //$NON-NLS-1$ - - /** A platform package. */ - public static final String NODE_PLATFORM = "platform"; //$NON-NLS-1$ - /** A tool package. */ - public static final String NODE_TOOL = "tool"; //$NON-NLS-1$ - /** A platform-tool package. */ - public static final String NODE_PLATFORM_TOOL = "platform-tool"; //$NON-NLS-1$ - /** A doc package. */ - public static final String NODE_DOC = "doc"; //$NON-NLS-1$ - /** A sample package. */ - public static final String NODE_SAMPLE = "sample"; //$NON-NLS-1$ - /** A source package. */ - public static final String NODE_SOURCE = "source"; //$NON-NLS-1$ - - - /** - * List of possible nodes in a repository XML. Used to populate options automatically - * in the no-GUI mode. - */ - public static final String[] NODES = { - NODE_PLATFORM, - NODE_SYSTEM_IMAGE, - NODE_TOOL, - NODE_PLATFORM_TOOL, - NODE_DOC, - NODE_SAMPLE, - NODE_SOURCE, - }; - - /** - * Returns a stream to the requested {@code sdk-repository} XML Schema. - * - * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. - * @return An {@link InputStream} object for the local XSD file or - * null if there is no schema for the requested version. - */ - public static InputStream getXsdStream(int version) { - return getXsdStream(NODE_SDK_REPOSITORY, version); - } - - /** - * Returns the URI of the SDK Repository schema for the given version number. - * @param version Between 1 and {@link #NS_LATEST_VERSION} included. - */ - public static String getSchemaUri(int version) { - return String.format(NS_BASE + "%d", version); //$NON-NLS-1$ - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkStatsConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkStatsConstants.java deleted file mode 100755 index 22f8aa2..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkStatsConstants.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - - -import java.io.InputStream; - -/** - * Public constants for the sdk-stats XML Schema. - */ -public class SdkStatsConstants { - - /** The canonical URL filename for addons-list XML files. */ - public static final String URL_DEFAULT_FILENAME = "stats-1.xml"; //$NON-NLS-1$ - - /** The URL where to find the official addons list fle. */ - public static final String URL_STATS = - SdkRepoConstants.URL_GOOGLE_SDK_SITE + URL_DEFAULT_FILENAME; - - /** The base of our sdk-addons-list XML namespace. */ - private static final String NS_BASE = - "http://schemas.android.com/sdk/android/stats/"; //$NON-NLS-1$ - - /** - * The pattern of our sdk-stats XML namespace. - * Matcher's group(1) is the schema version (integer). - */ - public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ - - /** The latest version of the sdk-stats XML Schema. - * Valid version numbers are between 1 and this number, included. */ - public static final int NS_LATEST_VERSION = 1; - - /** The XML namespace of the latest sdk-stats XML. */ - public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION); - - /** The root sdk-stats element */ - public static final String NODE_SDK_STATS = "sdk-stats"; //$NON-NLS-1$ - - /** A platform stat. */ - public static final String NODE_PLATFORM = "platform"; //$NON-NLS-1$ - - /** The Android API Level for the platform. An int > 0. */ - public static final String NODE_API_LEVEL = "api-level"; //$NON-NLS-1$ - - /** The official codename for this platform, for example "Cupcake". */ - public static final String NODE_CODENAME = "codename"; //$NON-NLS-1$ - - /** The official version name of this platform, for example "Android 1.5". */ - public static final String NODE_VERSION = "version"; //$NON-NLS-1$ - - /** - * The <em>approximate</em> share percentage of that platform. - * See the caveat in sdk-stats-1.xsd about value freshness and accuracy. - */ - public static final String NODE_SHARE = "share"; //$NON-NLS-1$ - - /** - * Returns a stream to the requested sdk-stats XML Schema. - * - * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. - * @return An {@link InputStream} object for the local XSD file or - * null if there is no schema for the requested version. - */ - public static InputStream getXsdStream(int version) { - String filename = String.format("sdk-stats-%d.xsd", version); //$NON-NLS-1$ - return SdkStatsConstants.class.getResourceAsStream(filename); - } - - /** - * Returns the URI of the sdk-stats schema for the given version number. - * @param version Between 1 and {@link #NS_LATEST_VERSION} included. - */ - public static String getSchemaUri(int version) { - return String.format(NS_BASE + "%d", version); //$NON-NLS-1$ - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java deleted file mode 100755 index ba3017f..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/SdkSysImgConstants.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - - -import com.android.sdklib.internal.repository.sources.SdkSource; - -import java.io.InputStream; - -/** - * Public constants for the sdk-sys-img XML Schema. - */ -public class SdkSysImgConstants extends RepoConstants { - - /** - * The default name looked for by {@link SdkSource} when trying to load an - * sdk-sys-img XML if the URL doesn't match an existing resource. - */ - public static final String URL_DEFAULT_FILENAME = "sys-img.xml"; //$NON-NLS-1$ - - /** The base of our sdk-sys-img XML namespace. */ - private static final String NS_BASE = - "http://schemas.android.com/sdk/android/sys-img/"; //$NON-NLS-1$ - - /** - * The pattern of our sdk-sys-img XML namespace. - * Matcher's group(1) is the schema version (integer). - */ - public static final String NS_PATTERN = NS_BASE + "([1-9][0-9]*)"; //$NON-NLS-1$ - - /** - * The latest version of the sdk-sys-img XML Schema. - * Valid version numbers are between 1 and this number, included. - */ - public static final int NS_LATEST_VERSION = 1; - - /** The XML namespace of the latest sdk-sys-img XML. */ - public static final String NS_URI = getSchemaUri(NS_LATEST_VERSION); - - /** The root sdk-sys-img element */ - public static final String NODE_SDK_SYS_IMG = "sdk-sys-img"; //$NON-NLS-1$ - - /** - * List of possible nodes in a repository XML. Used to populate options automatically - * in the no-GUI mode. - */ - public static final String[] NODES = { - NODE_SYSTEM_IMAGE, - }; - - /** - * Returns a stream to the requested {@code sdk-sys-img} XML Schema. - * - * @param version Between 1 and {@link #NS_LATEST_VERSION}, included. - * @return An {@link InputStream} object for the local XSD file or - * null if there is no schema for the requested version. - */ - public static InputStream getXsdStream(int version) { - return getXsdStream(NODE_SDK_SYS_IMG, version); - } - - /** - * Returns the URI of the sdk-sys-img schema for the given version number. - * @param version Between 1 and {@link #NS_LATEST_VERSION} included. - */ - public static String getSchemaUri(int version) { - return String.format(NS_BASE + "%d", version); //$NON-NLS-1$ - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-1.xsd deleted file mode 100755 index 1d53313..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-1.xsd +++ /dev/null @@ -1,295 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/addon/1" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/addon/1" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android Addon repository is a web site that contains an "addon.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r8. It is split out of the - main SDK Repository XML Schema and can only contain <addon> and - <extra> packages. - --> - - <xsd:element name="sdk-addon" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="add-on" type="sdk:addonType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK Add-on package. --> - - <xsd:complexType name="addonType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The name of the add-on. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The vendor of the add-on. --> - <xsd:element name="vendor" type="xsd:normalizedString" /> - <!-- The Android API Level for the add-on. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- Note: Add-ons do not support 'codename' (a.k.a. API previews). --> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An add-on can declare 0 or more libraries. --> - - <xsd:element name="libs"> - <xsd:complexType> - <xsd:sequence minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="lib"> - <xsd:complexType> - <xsd:all> - <!-- The name of the library. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The optional description of this add-on library. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - </xsd:element> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/vendor/path. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - - <!-- The install path top folder name. It must not be empty. - The segments "add-ons", "docs", "platforms", "platform-tools", "temp" - and "tools" are reserved and cannot be used. - --> - <xsd:element name="vendor" type="sdk:segmentType" /> - - <!-- The install path sub-folder name. It must not be empty. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. It must not be empty. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-2.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-2.xsd deleted file mode 100755 index 27fae8b..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-2.xsd +++ /dev/null @@ -1,361 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/addon/2" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/addon/2" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android Addon repository is a web site that contains an "addon.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r8. It is split out of the - main SDK Repository XML Schema and can only contain <addon> and - <extra> packages. - - - v2 is used by the SDK Updater in Tools r12. - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <addon> element now has an optional <layoutlib> that indicates the API - and revision of the layout library for this particular add-on, if any. - --> - - <xsd:element name="sdk-addon" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="add-on" type="sdk:addonType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK Add-on package. --> - - <xsd:complexType name="addonType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The name of the add-on. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The vendor of the add-on. --> - <xsd:element name="vendor" type="xsd:normalizedString" /> - <!-- The Android API Level for the add-on. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- Note: Add-ons do not support 'codenames' (a.k.a. API previews). --> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- An add-on can declare 0 or more libraries. - This element is mandatory but it can be empty. - --> - - <xsd:element name="libs"> - <xsd:complexType> - <xsd:sequence minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="lib"> - <xsd:complexType> - <xsd:all> - <!-- The name of the library. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The optional description of this add-on library. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - </xsd:element> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- Optional information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a layout library used by an addon. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in an addon. - .</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/vendor/path. - - Important implementation detail: this element is duplicated in the - sdk-repository-N.xsd schema and must be kept in sync there. This is - simpler than trying to use some kind of of include or to request - that clients use a third XML schema for common parts. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - - <!-- The install path top folder name. It must not be empty. - The segments "add-ons", "docs", "platforms", "platform-tools", "temp" - and "tools" are reserved and cannot be used. - --> - <xsd:element name="vendor" type="sdk:segmentType" /> - - <!-- The install path sub-folder name. It must not be empty. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- A list of project files contributed by this package. Optional. --> - <xsd:element name="project-files" type="sdk:projectFilesType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. It must not be empty. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-3.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-3.xsd deleted file mode 100755 index ccd00c2..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-3.xsd +++ /dev/null @@ -1,381 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/addon/3" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/addon/3" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android Addon repository is a web site that contains an "addon.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r8. It is split out of the - main SDK Repository XML Schema and can only contain <addon> and - <extra> packages. - - - v2 is used by the SDK Updater in Tools r12. - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <addon> element now has an optional <layoutlib> that indicates the API - and revision of the layout library for this particular add-on, if any. - - - v3 is used by the SDK Updater in Tools R14: - - <extra> now has an <old-paths> element, a ;-separated list of old paths that - should be detected and migrated to the new <path> for that package. - --> - - <xsd:element name="sdk-addon" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="add-on" type="sdk:addonType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK Add-on package. --> - - <xsd:complexType name="addonType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The name of the add-on. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The vendor of the add-on. --> - <xsd:element name="vendor" type="xsd:normalizedString" /> - <!-- The Android API Level for the add-on. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- Note: Add-ons do not support 'codenames' (a.k.a. API previews). --> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- An add-on can declare 0 or more libraries. - This element is mandatory but it can be empty. - --> - - <xsd:element name="libs"> - <xsd:complexType> - <xsd:sequence minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="lib"> - <xsd:complexType> - <xsd:all> - <!-- The name of the library. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The optional description of this add-on library. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - </xsd:element> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- Optional information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a layout library used by an addon. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in an addon. - .</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/vendor/path. - - Important implementation detail: this element is duplicated in the - sdk-repository-N.xsd schema and must be kept in sync there. This is - simpler than trying to use some kind of of include or to request - that clients use a third XML schema for common parts. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - - <!-- The install path top folder name. It must not be empty. - The segments "add-ons", "docs", "platforms", "platform-tools", "temp" - and "tools" are reserved and cannot be used. - --> - <xsd:element name="vendor" type="sdk:segmentType" /> - - <!-- The install path sub-folder name. It must not be empty. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- A semi-colon separated list of "obsolete" path names which are equivalent - to the current 'path' name. When a package is seen using an old-paths' name, - the package manager will try to upgrade it to the new path. --> - <xsd:element name="old-paths" type="sdk:segmentListType" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- A list of project files contributed by this package. Optional. --> - <xsd:element name="project-files" type="sdk:projectFilesType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. It must not be empty. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:simpleType name="segmentListType"> - <xsd:annotation> - <xsd:documentation> - A semi-colon separated list of a segmentTypes. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_;]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-4.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-4.xsd deleted file mode 100755 index c31efbf..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-4.xsd +++ /dev/null @@ -1,417 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/addon/4" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/addon/4" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android Addon repository is a web site that contains an "addon.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r8. It is split out of the - main SDK Repository XML Schema and can only contain <addon> and - <extra> packages. - - - v2 is used by the SDK Updater in Tools r12. - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <addon> element now has an optional <layoutlib> that indicates the API - and revision of the layout library for this particular add-on, if any. - - - v3 is used by the SDK Manager in Tools r14: - - <extra> now has an <old-paths> element, a ;-separated list of old paths that - should be detected and migrated to the new <path> for that package. - - - v4 is used by the SDK Manager in Tools r18: - - <extra> and <addon> are not in the Repository XSD v6 anymore. - - <extra> get a new field <name-display>, which is used by the SDK Manager to - customize the name of the extra in the list display. The single <vendor> - field becomes <vendor-id> and <vendor-display>, the id being used internally - and the display in the UI. - - <addon> does the same, where <name> is replaced by <name-id> and <name-display> - and <vendor> is replaced by <vendor-id> and <vendor-display>. - --> - - <xsd:element name="sdk-addon" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="add-on" type="sdk:addonType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK Add-on package. --> - - <xsd:complexType name="addonType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The internal name id of the add-on. Must be unique per vendor. --> - <xsd:element name="name-id" type="sdk:idType" /> - <!-- The displayed name of the add-on. --> - <xsd:element name="name-display" type="xsd:normalizedString" /> - - <!-- The internal vendor id of the add-on. Must be unique amongst vendors. --> - <xsd:element name="vendor-id" type="sdk:idType" /> - <!-- The displayed vendor name of the add-on. --> - <xsd:element name="vendor-display" type="xsd:normalizedString" /> - - <!-- The Android API Level for the add-on. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- Note: Add-ons do not support 'codenames' (a.k.a. API previews). --> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- An add-on can declare 0 or more libraries. - This element is mandatory but it can be empty. - --> - - <xsd:element name="libs"> - <xsd:complexType> - <xsd:sequence minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="lib"> - <xsd:complexType> - <xsd:all> - <!-- The name of the library. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The optional description of this add-on library. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - </xsd:element> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. - DEPRECATED. TODO remove in sdk-addon-5. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- Optional information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <xsd:simpleType name="idType"> - <xsd:annotation> - <xsd:documentation> - An ID string for an addon/extra name-id or vendor-id - can only be simple alphanumeric string. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_-]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a layout library used by an addon. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in an addon. - .</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/extras/vendor/path. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The displayed name of the extra. --> - <xsd:element name="name-display" type="xsd:normalizedString" /> - - <!-- The internal vendor id of the extra. Must be unique amongst vendors. --> - <xsd:element name="vendor-id" type="sdk:idType" /> - <!-- The displayed vendor name of the extra. --> - <xsd:element name="vendor-display" type="xsd:normalizedString" /> - - <!-- The install path sub-folder name. It must not be empty. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- A semi-colon separated list of "obsolete" path names which are equivalent - to the current 'path' name. When a package is seen using an old-paths' name, - the package manager will try to upgrade it to the new path. --> - <xsd:element name="old-paths" type="sdk:segmentListType" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- A list of project files contributed by this package. Optional. --> - <xsd:element name="project-files" type="sdk:projectFilesType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. It must not be empty. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:simpleType name="segmentListType"> - <xsd:annotation> - <xsd:documentation> - A semi-colon separated list of a segmentTypes. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_;]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-5.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-5.xsd deleted file mode 100755 index 546b00d..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addon-5.xsd +++ /dev/null @@ -1,442 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/addon/5" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/addon/5" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android Addon repository is a web site that contains an "addon.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r8. It is split out of the - main SDK Repository XML Schema and can only contain <addon> and - <extra> packages. - - - v2 is used by the SDK Updater in Tools r12. - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <addon> element now has an optional <layoutlib> that indicates the API - and revision of the layout library for this particular add-on, if any. - - - v3 is used by the SDK Manager in Tools r14: - - <extra> now has an <old-paths> element, a ;-separated list of old paths that - should be detected and migrated to the new <path> for that package. - - - v4 is used by the SDK Manager in Tools r18: - - <extra> and <addon> are not in the Repository XSD v6 anymore. - - <extra> get a new field <name-display>, which is used by the SDK Manager to - customize the name of the extra in the list display. The single <vendor> - field becomes <vendor-id> and <vendor-display>, the id being used internally - and the display in the UI. - - <addon> does the same, where <name> is replaced by <name-id> and <name-display> - and <vendor> is replaced by <vendor-id> and <vendor-display>. - - - v5 is used by the SDK Manager in Tools r20: - - The <beta-rc> element is no longer supported. It was never implemented anyway. - - For <tool> and <platform-tool> packages, the <revision> element becomes a - a "full revision" element with <major>, <minor>, <micro> and <preview> sub-elements. - - <min-tools-rev> for <extra> becomes a full revision element. - --> - - <xsd:element name="sdk-addon" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="add-on" type="sdk:addonType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - - <!-- The definition of an SDK Add-on package. --> - - <xsd:complexType name="addonType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The internal name id of the add-on. Must be unique per vendor. --> - <xsd:element name="name-id" type="sdk:idType" /> - <!-- The displayed name of the add-on. --> - <xsd:element name="name-display" type="xsd:normalizedString" /> - - <!-- The internal vendor id of the add-on. Must be unique amongst vendors. --> - <xsd:element name="vendor-id" type="sdk:idType" /> - <!-- The displayed vendor name of the add-on. --> - <xsd:element name="vendor-display" type="xsd:normalizedString" /> - - <!-- The Android API Level for the add-on. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- Note: Add-ons do not support 'codenames' (a.k.a. API previews). --> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- An add-on can declare 0 or more libraries. - This element is mandatory but it can be empty. - --> - - <xsd:element name="libs"> - <xsd:complexType> - <xsd:sequence minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="lib"> - <xsd:complexType> - <xsd:all> - <!-- The name of the library. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The optional description of this add-on library. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - </xsd:element> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- Optional information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <xsd:simpleType name="idType"> - <xsd:annotation> - <xsd:documentation> - An ID string for an addon/extra name-id or vendor-id - can only be simple alphanumeric string. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_-]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a layout library used by an addon. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in an addon. - .</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/extras/vendor/path. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The displayed name of the extra. --> - <xsd:element name="name-display" type="xsd:normalizedString" /> - - <!-- The internal vendor id of the extra. Must be unique amongst vendors. --> - <xsd:element name="vendor-id" type="sdk:idType" /> - <!-- The displayed vendor name of the extra. --> - <xsd:element name="vendor-display" type="xsd:normalizedString" /> - - <!-- The install path sub-folder name. It must not be empty. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- A semi-colon separated list of "obsolete" path names which are equivalent - to the current 'path' name. When a package is seen using an old-paths' name, - the package manager will try to upgrade it to the new path. --> - <xsd:element name="old-paths" type="sdk:segmentListType" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be a revision element. --> - <xsd:element name="min-tools-rev" type="sdk:revisionType" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- A list of project files contributed by this package. Optional. --> - <xsd:element name="project-files" type="sdk:projectFilesType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- A full revision, with a major.minor.micro and an optional preview number. - The major number is mandatory, the other elements are optional. - --> - - <xsd:complexType name="revisionType"> - <xsd:annotation> - <xsd:documentation> - A full revision, with a major.minor.micro and an - optional preview number. The major number is mandatory. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The major revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="major" type="xsd:positiveInteger" /> - <!-- The minor revision, an int >= 0, incremented each time a new - minor package is generated. Assumed to be 0 if missing. --> - <xsd:element name="minor" type="xsd:nonNegativeInteger" minOccurs="0" /> - <!-- The micro revision, an int >= 0, incremented each time a new - buf fix is generated. Assumed to be 0 if missing. --> - <xsd:element name="micro" type="xsd:nonNegativeInteger" minOccurs="0" /> - <!-- The preview/release candidate revision, an int > 0, - incremented each time a new preview is generated. - Not present for final releases. --> - <xsd:element name="preview" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. It must not be empty. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:simpleType name="segmentListType"> - <xsd:annotation> - <xsd:documentation> - A semi-colon separated list of a segmentTypes. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_;]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd deleted file mode 100755 index 176fb60..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-1.xsd +++ /dev/null @@ -1,71 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/addons-list/1" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sa1="http://schemas.android.com/sdk/android/addons-list/1" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- - A simple list of add-ons sites that is loaded by default by the SDK Manager. - --> - - <xsd:element name="sdk-addons-list" type="sa1:addonsListType" /> - - <xsd:complexType name="addonsListType"> - <xsd:annotation> - <xsd:documentation> - A simple list of add-ons site. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="addon-site" type="sa1:addonSiteType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an Add-on Site. --> - - <xsd:complexType name="addonSiteType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on site.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The URL of the site. - - This can be either the exact URL of the an XML resource conforming - to the latest sdk-addon-N.xsd schema, or it can be the URL of a - 'directory', in which case the manager will look for a resource - named 'addon.xml' at this location. - - Examples: - http://www.example.com/android/my_addons.xml - or - http://www.example.com/android/ - - In the second example, the manager will actually look for: - http://www.example.com/android/addon.xml - --> - <xsd:element name="url" type="xsd:token" /> - - <!-- The UI-visible name of the add-on. --> - <xsd:element name="name" type="xsd:normalizedString" /> - </xsd:all> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd deleted file mode 100755 index dde7214..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-addons-list-2.xsd +++ /dev/null @@ -1,106 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/addons-list/2" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sa1="http://schemas.android.com/sdk/android/addons-list/2" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- - A simple list of add-ons sites that is loaded by default by the SDK Manager. - - - v1: Defines <addon-site> - - v2: Adds support for <sys-img-site> - --> - - <xsd:element name="sdk-addons-list" type="sa1:addonsListType" /> - - <xsd:complexType name="addonsListType"> - <xsd:annotation> - <xsd:documentation> - A simple list of add-ons site. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="addon-site" type="sa1:addonSiteType" /> - <xsd:element name="sys-img-site" type="sa1:sysImgSiteType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an Add-on Site. --> - - <xsd:complexType name="addonSiteType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on site.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The URL of the site. - - This can be either the exact URL of the an XML resource conforming - to the latest sdk-addon-N.xsd schema, or it can be the URL of a - 'directory', in which case the manager will look for a resource - named 'addon.xml' at this location. - - Examples: - http://www.example.com/android/my_addons.xml - or - http://www.example.com/android/ - - In the second example, the manager will actually look for: - http://www.example.com/android/addon.xml - --> - <xsd:element name="url" type="xsd:token" /> - - <!-- The UI-visible name of the add-on site. --> - <xsd:element name="name" type="xsd:normalizedString" /> - - </xsd:all> - </xsd:complexType> - - <!-- The definition of an Sys-Img Site. --> - - <xsd:complexType name="sysImgSiteType"> - <xsd:annotation> - <xsd:documentation>An SDK sys-img site.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The URL of the site. - - This can be either the exact URL of the an XML resource conforming - to the latest sdk-sys-img-N.xsd schema, or it can be the URL of a - 'directory', in which case the manager will look for a resource - named 'sysimg.xml' at this location. - - Examples: - http://www.example.com/android/my_sys_img.xml - or - http://www.example.com/android/ - - In the second example, the manager will actually look for: - http://www.example.com/android/sysimg.xml - --> - <xsd:element name="url" type="xsd:token" /> - - <!-- The UI-visible name of the sys-img site. --> - <xsd:element name="name" type="xsd:normalizedString" /> - - </xsd:all> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-1.xsd deleted file mode 100755 index 38ec309..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-1.xsd +++ /dev/null @@ -1,381 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/repository/1" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/repository/1" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android SDK repository is a web site that contains a "repository.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r3 and Tools r4. - --> - - <xsd:element name="sdk-repository"> - <xsd:annotation> - <xsd:documentation> - The repository contains collections of downloadable packages. - </xsd:documentation> - </xsd:annotation> - - <xsd:complexType> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - - <!-- The definition of an SDK platform package. --> - - <xsd:element name="platform"> - <xsd:annotation> - <xsd:documentation>An SDK platform package.</xsd:documentation> - </xsd:annotation> - <xsd:complexType> - <xsd:all> - <!-- The Android platform version. It is string such as "1.0". --> - <xsd:element name="version" type="xsd:normalizedString" /> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - - - <!-- The definition of an SDK Add-on package. --> - - <xsd:element name="add-on"> - <xsd:annotation> - <xsd:documentation>An SDK add-on package.</xsd:documentation> - </xsd:annotation> - <xsd:complexType> - <xsd:all> - <!-- The name of the add-on. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The vendor of the add-on. --> - <xsd:element name="vendor" type="xsd:normalizedString" /> - <!-- The Android API Level for the add-on. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- Note: Add-ons do not support 'codename' (a.k.a. API previews). --> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An add-on can declare 0 or more libraries. --> - - <xsd:element name="libs"> - <xsd:complexType> - <xsd:sequence minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="lib"> - <xsd:complexType> - <xsd:all> - <!-- The name of the library. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The optional description of this add-on library. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - </xsd:element> - </xsd:all> - </xsd:complexType> - </xsd:element> - - - <!-- The definition of an SDK tool package. --> - - <xsd:element name="tool"> - <xsd:annotation> - <xsd:documentation>An SDK tool package.</xsd:documentation> - </xsd:annotation> - <xsd:complexType> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - - - <!-- The definition of an SDK doc package. --> - - <xsd:element name="doc"> - <xsd:annotation> - <xsd:documentation>An SDK doc package.</xsd:documentation> - </xsd:annotation> - <xsd:complexType> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content and specifies in which fixed root directory it must be - installed. - --> - - <xsd:element name="extra"> - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" - content and specifies in which fixed root directory it must be - installed. - The paths "add-ons", "platforms", "tools" and "docs" are - reserved and cannot be used. - </xsd:documentation> - </xsd:annotation> - <xsd:complexType> - <xsd:all> - <!-- The install folder name. It must be a single-segment path. - The paths "add-ons", "platforms", "tools" and "docs" are - reserved and cannot be used. - --> - <xsd:element name="path"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[^/\\]+"/> - </xsd:restriction> - </xsd:simpleType> - </xsd:element> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:licenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:element name="license"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:complexType> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - </xsd:element> - </xsd:choice> - </xsd:complexType> - </xsd:element> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-2.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-2.xsd deleted file mode 100755 index ecadc3f..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-2.xsd +++ /dev/null @@ -1,438 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/repository/2" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sr2="http://schemas.android.com/sdk/android/repository/2" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android SDK repository is a web site that contains a "repository.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r3 and r4. - - v2 is used by the SDK Updater in Tools r5: - - new <sample> repository type. - - new <obsolete> in all repository types. - --> - - <xsd:element name="sdk-repository" type="sr2:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="platform" type="sr2:platformType" /> - <xsd:element name="add-on" type="sr2:addonType" /> - <xsd:element name="tool" type="sr2:toolType" /> - <xsd:element name="doc" type="sr2:docType" /> - <xsd:element name="sample" type="sr2:sampleType" /> - <xsd:element name="extra" type="sr2:extraType" /> - <xsd:element name="license" type="sr2:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK platform package. --> - - <xsd:complexType name="platformType"> - <xsd:annotation> - <xsd:documentation>An SDK platform package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android platform version. It is string such as "1.0". --> - <xsd:element name="version" type="xsd:normalizedString" /> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sr2:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sr2:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK Add-on package. --> - - <xsd:complexType name="addonType"> - <xsd:annotation> - <xsd:documentation>An SDK add-on package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The name of the add-on. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The vendor of the add-on. --> - <xsd:element name="vendor" type="xsd:normalizedString" /> - <!-- The Android API Level for the add-on. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- Note: Add-ons do not support 'codename' (a.k.a. API previews). --> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sr2:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sr2:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An add-on can declare 0 or more libraries. --> - - <xsd:element name="libs"> - <xsd:complexType> - <xsd:sequence minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="lib"> - <xsd:complexType> - <xsd:all> - <!-- The name of the library. --> - <xsd:element name="name" type="xsd:normalizedString" /> - <!-- The optional description of this add-on library. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - </xsd:element> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK tool package. --> - - <xsd:complexType name="toolType" > - <xsd:annotation> - <xsd:documentation>An SDK tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sr2:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sr2:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK doc package. --> - - <xsd:complexType name="docType" > - <xsd:annotation> - <xsd:documentation>An SDK doc package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sr2:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sr2:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK sample package. --> - - <xsd:complexType name="sampleType" > - <xsd:annotation> - <xsd:documentation>An SDK sample package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sr2:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sr2:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content and specifies in which fixed root directory it must be - installed. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" - content and specifies in which fixed root directory it must be - installed. - The paths "add-ons", "platforms", "tools" and "docs" are - reserved and cannot be used. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The install folder name. It must be a single-segment path. - The paths "add-ons", "platforms", "tools" and "docs" are - reserved and cannot be used. - --> - <xsd:element name="path"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[^/\\]+"/> - </xsd:restriction> - </xsd:simpleType> - </xsd:element> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sr2:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sr2:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sr2:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sr2:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-3.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-3.xsd deleted file mode 100755 index 75d8541..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-3.xsd +++ /dev/null @@ -1,436 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/repository/3" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/repository/3" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android SDK repository is a web site that contains a "repository.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r3 and r4. - - - v2 is used by the SDK Updater in Tools r5: - - It introduces a new <sample> repository type. Previously samples - were included in the <platform> packages. Instead this package is used - and and the samples are installed in $SDK/samples. - - All repository types have a new <obsolete> node. It works as a marker - to indicate the package is obsolete and should not be selected by default. - The UI also hides these out by default. - - - v3 is used by the SDK Updater in Tools r8: - - It introduces a new <platform-tool> repository type. Previously platform-specific - tools were included in the <platform> packages. Instead this package is used - and platform-specific tools are installed in $SDK/platform-tools - - There's a new element <min-platform-tools-rev> in <tool>. The tool package now - requires that at least some minimal version of <platform-tool> be installed. - - It removes the <addon> repository type, which is now in its own XML Schema. - --> - - <xsd:element name="sdk-repository" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="platform" type="sdk:platformType" /> - <xsd:element name="tool" type="sdk:toolType" /> - <xsd:element name="platform-tool" type="sdk:platformToolType" /> - <xsd:element name="doc" type="sdk:docType" /> - <xsd:element name="sample" type="sdk:sampleType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK platform package. --> - - <xsd:complexType name="platformType"> - <xsd:annotation> - <xsd:documentation>An SDK platform package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android platform version. It is string such as "1.0". --> - <xsd:element name="version" type="xsd:normalizedString" /> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK tool package. --> - - <xsd:complexType name="toolType" > - <xsd:annotation> - <xsd:documentation>An SDK tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- The minimal revision of platform-tools required by this package. - Mandatory. Must be an int > 0. --> - <xsd:element name="min-platform-tools-rev" type="xsd:positiveInteger" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK platform-tool package. --> - - <xsd:complexType name="platformToolType" > - <xsd:annotation> - <xsd:documentation>An SDK platform-tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK doc package. --> - - <xsd:complexType name="docType" > - <xsd:annotation> - <xsd:documentation>An SDK doc package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK sample package. --> - - <xsd:complexType name="sampleType" > - <xsd:annotation> - <xsd:documentation>An SDK sample package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/vendor/path. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - - <!-- The install path top folder name. - The segments "add-ons", "docs", "platforms", "platform-tools", "temp" - and "tools" are reserved and cannot be used. - --> - <xsd:element name="vendor" type="sdk:segmentType" /> - - <!-- The install path sub-folder name. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-4.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-4.xsd deleted file mode 100755 index 9b14772..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-4.xsd +++ /dev/null @@ -1,500 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/repository/4" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/repository/4" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android SDK repository is a web site that contains a "repository.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r3 and r4. - - - v2 is used by the SDK Updater in Tools r5: - - It introduces a new <sample> repository type. Previously samples - were included in the <platform> packages. Instead this package is used - and and the samples are installed in $SDK/samples. - - All repository types have a new <obsolete> node. It works as a marker - to indicate the package is obsolete and should not be selected by default. - The UI also hides these out by default. - - - v3 is used by the SDK Updater in Tools r8: - - It introduces a new <platform-tool> repository type. Previously platform-specific - tools were included in the <platform> packages. Instead this package is used - and platform-specific tools are installed in $SDK/platform-tools - - There's a new element <min-platform-tools-rev> in <tool>. The tool package now - requires that at least some minimal version of <platform-tool> be installed. - - It removes the <addon> repository type, which is now in its own XML Schema. - - - v4 is used by the SDK Updater in Tools r12: - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <platform> element now has a mandatory <layoutlib> that indicates the API - and revision of that layout library for this particular platform. - --> - - <xsd:element name="sdk-repository" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="platform" type="sdk:platformType" /> - <xsd:element name="tool" type="sdk:toolType" /> - <xsd:element name="platform-tool" type="sdk:platformToolType" /> - <xsd:element name="doc" type="sdk:docType" /> - <xsd:element name="sample" type="sdk:sampleType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK platform package. --> - - <xsd:complexType name="platformType"> - <xsd:annotation> - <xsd:documentation>An SDK platform package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android platform version. It is string such as "1.0". --> - <xsd:element name="version" type="xsd:normalizedString" /> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- Information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a layout library used by a platform. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK tool package. --> - - <xsd:complexType name="toolType" > - <xsd:annotation> - <xsd:documentation>An SDK tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- The minimal revision of platform-tools required by this package. - Mandatory. Must be an int > 0. --> - <xsd:element name="min-platform-tools-rev" type="xsd:positiveInteger" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK platform-tool package. --> - - <xsd:complexType name="platformToolType" > - <xsd:annotation> - <xsd:documentation>An SDK platform-tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK doc package. --> - - <xsd:complexType name="docType" > - <xsd:annotation> - <xsd:documentation>An SDK doc package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK sample package. --> - - <xsd:complexType name="sampleType" > - <xsd:annotation> - <xsd:documentation>An SDK sample package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/vendor/path. - - Important implementation detail: this element is duplicated in the - sdk-addon-N.xsd schema and must be kept in sync there. This is - simpler than trying to use some kind of of include or to request - that clients use a third XML schema for common parts. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - - <!-- The install path top folder name. - The segments "add-ons", "docs", "platforms", "platform-tools", "temp" - and "tools" are reserved and cannot be used. - --> - <xsd:element name="vendor" type="sdk:segmentType" /> - - <!-- The install path sub-folder name. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- A list of project files contributed by this package. Optional. --> - <xsd:element name="project-files" type="sdk:projectFilesType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-5.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-5.xsd deleted file mode 100755 index ae8275f..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-5.xsd +++ /dev/null @@ -1,624 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/repository/5" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/repository/5" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android SDK repository is a web site that contains a "repository.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r3 and r4. - - - v2 is used by the SDK Updater in Tools r5: - - It introduces a new <sample> repository type. Previously samples - were included in the <platform> packages. Instead this package is used - and and the samples are installed in $SDK/samples. - - All repository types have a new <obsolete> node. It works as a marker - to indicate the package is obsolete and should not be selected by default. - The UI also hides these out by default. - - - v3 is used by the SDK Updater in Tools r8: - - It introduces a new <platform-tool> repository type. Previously platform-specific - tools were included in the <platform> packages. Instead this package is used - and platform-specific tools are installed in $SDK/platform-tools - - There's a new element <min-platform-tools-rev> in <tool>. The tool package now - requires that at least some minimal version of <platform-tool> be installed. - - It removes the <addon> repository type, which is now in its own XML Schema. - - - v4 is used by the SDK Updater in Tools r12: - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <platform> element now has a mandatory <layoutlib> that indicates the API - and revision of that layout library for this particular platform. - - - v5 is used by the SDK Updater in Tools R14: - - <extra> now has an <old-paths> element, a ;-separated list of old paths that - should be detected and migrated to the new <path> for that package. - - <platform> has a new optional <abi-included> that describes the ABI of the - system image included in the platform, if any. - - New <system-image> package type, to store system images outside of <platform>s. - - New <source> package type. - --> - - <xsd:element name="sdk-repository" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="platform" type="sdk:platformType" /> - <xsd:element name="system-image" type="sdk:systemImageType" /> - <xsd:element name="source" type="sdk:sourceType" /> - <xsd:element name="tool" type="sdk:toolType" /> - <xsd:element name="platform-tool" type="sdk:platformToolType" /> - <xsd:element name="doc" type="sdk:docType" /> - <xsd:element name="sample" type="sdk:sampleType" /> - <xsd:element name="extra" type="sdk:extraType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK platform package. --> - - <xsd:complexType name="platformType"> - <xsd:annotation> - <xsd:documentation>An SDK platform package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android platform version. It is string such as "1.0". --> - <xsd:element name="version" type="xsd:normalizedString" /> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- Information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- The ABI of the system image *included* in this platform, if any. - When the field is present, it means the platform already embeds one - system image. A platform can also have any number of external - <system-image> associated with it. --> - <xsd:element name="included-abi" type="sdk:abiType" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a layout library used by a platform. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a system image used by a platform. --> - - <xsd:complexType name="systemImageType" > - <xsd:annotation> - <xsd:documentation> - System Image for a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- api-level + codename identifies the platform to which this system image belongs. --> - - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- The ABI of the system emulated by this image. --> - <xsd:element name="abi" type="sdk:abiType" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - </xsd:all> - </xsd:complexType> - - <!-- The definition of the ABI supported by a platform's system image. --> - - <xsd:simpleType name="abiType"> - <xsd:annotation> - <xsd:documentation>The ABI of a platform's system image.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="armeabi" /> - <xsd:enumeration value="armeabi-v7a" /> - <xsd:enumeration value="x86" /> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a source package. --> - - <xsd:complexType name="sourceType" > - <xsd:annotation> - <xsd:documentation> - Sources for a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- api-level + codename identifies the platform to which this source belongs. --> - - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK tool package. --> - - <xsd:complexType name="toolType" > - <xsd:annotation> - <xsd:documentation>An SDK tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- The minimal revision of platform-tools required by this package. - Mandatory. Must be an int > 0. --> - <xsd:element name="min-platform-tools-rev" type="xsd:positiveInteger" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK platform-tool package. --> - - <xsd:complexType name="platformToolType" > - <xsd:annotation> - <xsd:documentation>An SDK platform-tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK doc package. --> - - <xsd:complexType name="docType" > - <xsd:annotation> - <xsd:documentation>An SDK doc package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK sample package. --> - - <xsd:complexType name="sampleType" > - <xsd:annotation> - <xsd:documentation>An SDK sample package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK extra package. This kind of package is for - "free" content. Such packages are installed in SDK/vendor/path. - - Important implementation detail: this element is duplicated in the - sdk-addon-N.xsd schema and must be kept in sync there. This is - simpler than trying to use some kind of of include or to request - that clients use a third XML schema for common parts. - --> - - <xsd:complexType name="extraType" > - <xsd:annotation> - <xsd:documentation> - An SDK extra package. This kind of package is for "free" content. - Such packages are installed in SDK/vendor/path. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - - <!-- The install path top folder name. - The segments "add-ons", "docs", "platforms", "platform-tools", "temp" - and "tools" are reserved and cannot be used. - --> - <xsd:element name="vendor" type="sdk:segmentType" /> - - <!-- The install path sub-folder name. --> - <xsd:element name="path" type="sdk:segmentType" /> - - <!-- A semi-colon separated list of "obsolete" path names which are equivalent - to the current 'path' name. When a package is seen using an old-paths' name, - the package manager will try to upgrade it to the new path. --> - <xsd:element name="old-paths" type="sdk:segmentListType" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - <!-- The minimal API level required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-api-level" type="xsd:positiveInteger" minOccurs="0" /> - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- A list of project files contributed by this package. Optional. --> - <xsd:element name="project-files" type="sdk:projectFilesType" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:simpleType name="segmentListType"> - <xsd:annotation> - <xsd:documentation> - A semi-colon separated list of a segmentTypes. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_;]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-6.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-6.xsd deleted file mode 100755 index bccce69..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-6.xsd +++ /dev/null @@ -1,608 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/repository/6" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/repository/6" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android SDK repository is a web site that contains a "repository.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r3 and r4. - - - v2 is used by the SDK Updater in Tools r5: - - It introduces a new <sample> repository type. Previously samples - were included in the <platform> packages. Instead this package is used - and and the samples are installed in $SDK/samples. - - All repository types have a new <obsolete> node. It works as a marker - to indicate the package is obsolete and should not be selected by default. - The UI also hides these out by default. - - - v3 is used by the SDK Updater in Tools r8: - - It introduces a new <platform-tool> repository type. Previously platform-specific - tools were included in the <platform> packages. Instead this package is used - and platform-specific tools are installed in $SDK/platform-tools - - There's a new element <min-platform-tools-rev> in <tool>. The tool package now - requires that at least some minimal version of <platform-tool> be installed. - - It removes the <addon> repository type, which is now in its own XML Schema. - - - v4 is used by the SDK Updater in Tools r12: - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <platform> element now has a mandatory <layoutlib> that indicates the API - and revision of that layout library for this particular platform. - - - v5 is used by the SDK Manager in Tools r14: - - <extra> now has an <old-paths> element, a ;-separated list of old paths that - should be detected and migrated to the new <path> for that package. - - <platform> has a new optional <abi-included> that describes the ABI of the - system image included in the platform, if any. - - New <system-image> package type, to store system images outside of <platform>s. - - New <source> package type. - - - v6 is used by the SDK Manager in Tools r18: - - <extra> packages are removed. They are served only by the addon XML. - - <platform>, <system-image>, <source>, <tool>, <platform-tool>, <doc> - and <sample> get a new optional field <beta-rc> which can be used to indicate - the package is a Beta Release Candidate and not a final release. - --> - - <xsd:element name="sdk-repository" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="platform" type="sdk:platformType" /> - <xsd:element name="system-image" type="sdk:systemImageType" /> - <xsd:element name="source" type="sdk:sourceType" /> - <xsd:element name="tool" type="sdk:toolType" /> - <xsd:element name="platform-tool" type="sdk:platformToolType" /> - <xsd:element name="doc" type="sdk:docType" /> - <xsd:element name="sample" type="sdk:sampleType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK platform package. --> - - <xsd:complexType name="platformType"> - <xsd:annotation> - <xsd:documentation>An SDK platform package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android platform version. It is string such as "1.0". --> - <xsd:element name="version" type="xsd:normalizedString" /> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- Information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - <!-- The ABI of the system image *included* in this platform, if any. - When the field is present, it means the platform already embeds one - system image. A platform can also have any number of external - <system-image> associated with it. --> - <xsd:element name="included-abi" type="sdk:abiType" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a layout library used by a platform. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a system image used by a platform. --> - - <xsd:complexType name="systemImageType" > - <xsd:annotation> - <xsd:documentation> - System Image for a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- api-level + codename identifies the platform to which this system image belongs. --> - - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- The ABI of the system emulated by this image. --> - <xsd:element name="abi" type="sdk:abiType" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - <!-- The definition of the ABI supported by a platform's system image. --> - - <xsd:simpleType name="abiType"> - <xsd:annotation> - <xsd:documentation>The ABI of a platform's system image.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="armeabi" /> - <xsd:enumeration value="armeabi-v7a" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="mips" /> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a source package. --> - - <xsd:complexType name="sourceType" > - <xsd:annotation> - <xsd:documentation> - Sources for a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- api-level + codename identifies the platform to which this source belongs. --> - - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK tool package. --> - - <xsd:complexType name="toolType" > - <xsd:annotation> - <xsd:documentation>An SDK tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- The minimal revision of platform-tools required by this package. - Mandatory. Must be an int > 0. --> - <xsd:element name="min-platform-tools-rev" type="xsd:positiveInteger" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK platform-tool package. --> - - <xsd:complexType name="platformToolType" > - <xsd:annotation> - <xsd:documentation>An SDK platform-tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK doc package. --> - - <xsd:complexType name="docType" > - <xsd:annotation> - <xsd:documentation>An SDK doc package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK sample package. --> - - <xsd:complexType name="sampleType" > - <xsd:annotation> - <xsd:documentation>An SDK sample package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be an int > 0. --> - <xsd:element name="min-tools-rev" type="xsd:positiveInteger" minOccurs="0" /> - - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - - <!-- An optional element indicating the package is a beta/preview. - When present, it indicates the release-candidate number. - When the element is absent, it indicates this is a released package. --> - <xsd:element name="beta-rc" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:simpleType name="segmentListType"> - <xsd:annotation> - <xsd:documentation> - A semi-colon separated list of a segmentTypes. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_;]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-7.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-7.xsd deleted file mode 100755 index ea18070..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-repository-7.xsd +++ /dev/null @@ -1,612 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/repository/7" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/repository/7" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android SDK repository is a web site that contains a "repository.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r3 and r4. - - - v2 is used by the SDK Updater in Tools r5: - - It introduces a new <sample> repository type. Previously samples - were included in the <platform> packages. Instead this package is used - and and the samples are installed in $SDK/samples. - - All repository types have a new <obsolete> node. It works as a marker - to indicate the package is obsolete and should not be selected by default. - The UI also hides these out by default. - - - v3 is used by the SDK Updater in Tools r8: - - It introduces a new <platform-tool> repository type. Previously platform-specific - tools were included in the <platform> packages. Instead this package is used - and platform-specific tools are installed in $SDK/platform-tools - - There's a new element <min-platform-tools-rev> in <tool>. The tool package now - requires that at least some minimal version of <platform-tool> be installed. - - It removes the <addon> repository type, which is now in its own XML Schema. - - - v4 is used by the SDK Updater in Tools r12: - - <extra> element now has a <project-files> element that contains 1 or - or more <path>, each indicating the relative path of a file that this package - can contribute to installed projects. - - <platform> element now has a mandatory <layoutlib> that indicates the API - and revision of that layout library for this particular platform. - - - v5 is used by the SDK Manager in Tools r14: - - <extra> now has an <old-paths> element, a ;-separated list of old paths that - should be detected and migrated to the new <path> for that package. - - <platform> has a new optional <abi-included> that describes the ABI of the - system image included in the platform, if any. - - New <system-image> package type, to store system images outside of <platform>s. - - New <source> package type. - - - v6 is used by the SDK Manager in Tools r18: - - <extra> packages are removed. They are served only by the addon XML. - - <platform>, <system-image>, <source>, <tool>, <platform-tool>, <doc> - and <sample> get a new optional field <beta-rc> which can be used to indicate - the package is a Beta Release Candidate and not a final release. - - - v7 is used by the SDK Manager in Tools r20: - - For <tool> and <platform-tool> packages, the <revision> element becomes a - a "full revision" element with <major>, <minor>, <micro> and <preview> sub-elements. - - The <beta-rc> element is no longer supported, it is replaced by - <revision> -> <preview> and is only for <tool> and <platform-tool> packages. - - <min-tools-rev> and <min-platform-tools-rev> also become a full revision element. - --> - - <xsd:element name="sdk-repository" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable packages. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="platform" type="sdk:platformType" /> - <xsd:element name="system-image" type="sdk:systemImageType" /> - <xsd:element name="source" type="sdk:sourceType" /> - <xsd:element name="tool" type="sdk:toolType" /> - <xsd:element name="platform-tool" type="sdk:platformToolType" /> - <xsd:element name="doc" type="sdk:docType" /> - <xsd:element name="sample" type="sdk:sampleType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - <!-- The definition of an SDK platform package. --> - - <xsd:complexType name="platformType"> - <xsd:annotation> - <xsd:documentation>An SDK platform package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android platform version. It is string such as "1.0". --> - <xsd:element name="version" type="xsd:normalizedString" /> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- Information on the layoutlib packaged in this platform. --> - <xsd:element name="layoutlib" type="sdk:layoutlibType" /> - - <!-- optional elements --> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be a revision element. --> - <xsd:element name="min-tools-rev" type="sdk:revisionType" minOccurs="0" /> - - <!-- The ABI of the system image *included* in this platform, if any. - When the field is present, it means the platform already embeds one - system image. A platform can also have any number of external - <system-image> associated with it. --> - <xsd:element name="included-abi" type="sdk:abiType" minOccurs="0" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a layout library used by a platform. --> - - <xsd:complexType name="layoutlibType" > - <xsd:annotation> - <xsd:documentation> - Version information for a layoutlib included in a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The layoutlib API level, an int > 0, - incremented with each new incompatible lib. --> - <xsd:element name="api" type="xsd:positiveInteger" /> - <!-- The incremental minor revision for that API, e.g. in case of bug fixes. - Optional. An int >= 0, assumed to be 0 if the element is missing. --> - <xsd:element name="revision" type="xsd:nonNegativeInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a system image used by a platform. --> - - <xsd:complexType name="systemImageType" > - <xsd:annotation> - <xsd:documentation> - System Image for a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- api-level + codename identifies the platform to which this system image belongs. --> - - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- The ABI of the system emulated by this image. --> - <xsd:element name="abi" type="sdk:abiType" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of the ABI supported by a platform's system image. --> - - <xsd:simpleType name="abiType"> - <xsd:annotation> - <xsd:documentation>The ABI of a platform's system image.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="armeabi" /> - <xsd:enumeration value="armeabi-v7a" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="mips" /> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a source package. --> - - <xsd:complexType name="sourceType" > - <xsd:annotation> - <xsd:documentation> - Sources for a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- api-level + codename identifies the platform to which this source belongs. --> - - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK tool package. --> - - <xsd:complexType name="toolType" > - <xsd:annotation> - <xsd:documentation>An SDK tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The full revision (major.minor.micro.preview), incremented each - time a new package is generated. --> - <xsd:element name="revision" type="sdk:revisionType" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- The minimal revision of platform-tools required by this package. - Mandatory. Must be a revision element. --> - <xsd:element name="min-platform-tools-rev" type="sdk:revisionType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK platform-tool package. --> - - <xsd:complexType name="platformToolType" > - <xsd:annotation> - <xsd:documentation>An SDK platform-tool package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The full revision (major.minor.micro.preview), incremented each - time a new package is generated. --> - <xsd:element name="revision" type="sdk:revisionType" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK doc package. --> - - <xsd:complexType name="docType" > - <xsd:annotation> - <xsd:documentation>An SDK doc package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of an SDK sample package. --> - - <xsd:complexType name="sampleType" > - <xsd:annotation> - <xsd:documentation>An SDK sample package.</xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the documentation. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this doc, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - <!-- The minimal revision of tools required by this package. - Optional. If present, must be a revision element. --> - <xsd:element name="min-tools-rev" type="sdk:revisionType" minOccurs="0" /> - - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of a path segment used by the extra element. --> - - <xsd:simpleType name="segmentType"> - <xsd:annotation> - <xsd:documentation> - One path segment for the install path of an extra element. - It must be a single-segment path. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_]+"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:simpleType name="segmentListType"> - <xsd:annotation> - <xsd:documentation> - A semi-colon separated list of a segmentTypes. - </xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:pattern value="[a-zA-Z0-9_;]+"/> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- A full revision, with a major.minor.micro and an optional preview number. - The major number is mandatory, the other elements are optional. - --> - - <xsd:complexType name="revisionType"> - <xsd:annotation> - <xsd:documentation> - A full revision, with a major.minor.micro and an - optional preview number. The major number is mandatory. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The major revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="major" type="xsd:positiveInteger" /> - <!-- The minor revision, an int >= 0, incremented each time a new - minor package is generated. Assumed to be 0 if missing. --> - <xsd:element name="minor" type="xsd:nonNegativeInteger" minOccurs="0" /> - <!-- The micro revision, an int >= 0, incremented each time a new - buf fix is generated. Assumed to be 0 if missing. --> - <xsd:element name="micro" type="xsd:nonNegativeInteger" minOccurs="0" /> - <!-- The preview/release candidate revision, an int > 0, - incremented each time a new preview is generated. - Not present for final releases. --> - <xsd:element name="preview" type="xsd:positiveInteger" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - --> - - <xsd:complexType name="projectFilesType"> - <xsd:annotation> - <xsd:documentation> - A collection of file paths available in an <extra> package - that can be installed in an Android project. - If present, the <project-files> collection must contain at least one path. - Each path is relative to the root directory of the package. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One JAR Path, relative to the root folder of the package. --> - <xsd:element name="path" type="xsd:string" /> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-stats-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-stats-1.xsd deleted file mode 100755 index 2944b12..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-stats-1.xsd +++ /dev/null @@ -1,96 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/stats/1" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:ast="http://schemas.android.com/sdk/android/stats/1" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- - A simple list of platforms provided by the SDK Manager and some - statistics on them, namely the market share percentage for that - platform. - This can be used by the SDK Manager or the ADT New Project Wizard - to give users an idea of the relative install base of platforms. - - Scope, Caveat & Limitation: - The "share percentage" corresponds to the Platform Versions table - from the SDK Dashboard as seen at - http://developer.android.com/resources/dashboard/platform-versions.html - However the data is not automatically generated and there is NO - freshness implied. The values may or may not be up-to-date and it is - most likely they will only get refreshed when there's a significant - change that affects the usage of the SDK tools. - - => The data is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES - OR CONDITIONS OF ANY KIND, either express or implied. - --> - - <xsd:element name="sdk-stats" type="ast:platformsListType" /> - - <xsd:complexType name="platformsListType"> - <xsd:annotation> - <xsd:documentation> - A simple list of platform stats. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="platform" type="ast:platformType" /> - </xsd:choice> - </xsd:complexType> - - - <!-- The definition of stats for a platform. --> - - <xsd:complexType name="platformType"> - <xsd:annotation> - <xsd:documentation>Stats information for a given Android platform. - The api-level acts as a key, and it is epxected there should only - be one platform listed with the same API-level. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - - <!-- The official codename for this platform, for example "Cupcake". --> - <xsd:element name="codename" type="xsd:normalizedString" /> - - <!-- The official version name of this platform, for example "Android 1.5". --> - <xsd:element name="version" type="xsd:normalizedString" /> - - <!-- An approximate share percentage of this platform. --> - <xsd:element name="share" type="ast:percent" /> - </xsd:all> - </xsd:complexType> - - - <!-- A decimal percentage, between 0.0 and 100.0% --> - - <xsd:simpleType name="percent" id="percent"> - <xsd:annotation> - <xsd:documentation>A decimal percentage, between 0.0 and 100.0%.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:decimal"> - <xsd:minInclusive value="0"/> - <xsd:maxInclusive value="100"/> - </xsd:restriction> - </xsd:simpleType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd b/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd deleted file mode 100755 index a19aa49..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/repository/sdk-sys-img-1.xsd +++ /dev/null @@ -1,229 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<xsd:schema - targetNamespace="http://schemas.android.com/sdk/android/sys-img/1" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:sdk="http://schemas.android.com/sdk/android/sys-img/1" - elementFormDefault="qualified" - attributeFormDefault="unqualified" - version="1"> - - <!-- The repository contains a collection of downloadable items known as - "packages". Each package has a type and various attributes and contains - a list of file "archives" that can be downloaded for specific OSes. - - An Android Addon repository is a web site that contains an "addon.xml" - file that conforms to this XML Schema. - - History: - - v1 is used by the SDK Updater in Tools r20. It is split out of the - main SDK Repository XML Schema and can only contain <system-image> packages. - --> - - <xsd:element name="sdk-sys-img" type="sdk:repositoryType" /> - - <xsd:complexType name="repositoryType"> - <xsd:annotation> - <xsd:documentation> - The repository contains a collection of downloadable system images. - </xsd:documentation> - </xsd:annotation> - <xsd:choice minOccurs="0" maxOccurs="unbounded"> - <xsd:element name="system-image" type="sdk:systemImageType" /> - <xsd:element name="license" type="sdk:licenseType" /> - </xsd:choice> - </xsd:complexType> - - - <!-- The definition of a system image used by a platform. --> - - <xsd:complexType name="systemImageType" > - <xsd:annotation> - <xsd:documentation> - System Image for a platform. - </xsd:documentation> - </xsd:annotation> - <xsd:all> - <!-- api-level+codename identifies the platform to which this system image belongs. --> - - <!-- The Android API Level for the platform. An int > 0. --> - <xsd:element name="api-level" type="xsd:positiveInteger" /> - <!-- The optional codename for this platform, if it's a preview. --> - <xsd:element name="codename" type="xsd:string" minOccurs="0" /> - - <!-- The revision, an int > 0, incremented each time a new - package is generated. --> - <xsd:element name="revision" type="xsd:positiveInteger" /> - - <!-- The ABI of the system emulated by this image. --> - <xsd:element name="abi" type="sdk:abiType" /> - - <!-- The optional license of this package. If present, users will have - to agree to it before downloading. --> - <xsd:element name="uses-license" type="sdk:usesLicenseType" minOccurs="0" /> - <!-- The optional description of this package. --> - <xsd:element name="description" type="xsd:string" minOccurs="0" /> - <!-- The optional description URL of this package --> - <xsd:element name="desc-url" type="xsd:token" minOccurs="0" /> - <!-- The optional release note for this package. --> - <xsd:element name="release-note" type="xsd:string" minOccurs="0" /> - <!-- The optional release note URL of this package --> - <xsd:element name="release-url" type="xsd:token" minOccurs="0" /> - - <!-- A list of file archives for this package. --> - <xsd:element name="archives" type="sdk:archivesType" /> - - <!-- An optional element indicating the package is obsolete. - The string content is however currently not defined and ignored. --> - <xsd:element name="obsolete" type="xsd:string" minOccurs="0" /> - </xsd:all> - </xsd:complexType> - - - <!-- The definition of the ABI supported by a platform's system image. --> - - <xsd:simpleType name="abiType"> - <xsd:annotation> - <xsd:documentation>The ABI of a platform's system image.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="armeabi" /> - <xsd:enumeration value="armeabi-v7a" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="mips" /> - </xsd:restriction> - </xsd:simpleType> - - - <!-- The definition of a license to be referenced by the uses-license element. --> - - <xsd:complexType name="licenseType"> - <xsd:annotation> - <xsd:documentation> - A license definition. Such a license must be used later as a reference - using a uses-license element in one of the package elements. - </xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="xsd:string"> - <xsd:attribute name="id" type="xsd:ID" /> - <xsd:attribute name="type" type="xsd:token" fixed="text" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - - - <!-- Type describing the license used by a package. - The license MUST be defined using a license node and referenced - using the ref attribute of the license element inside a package. - --> - - <xsd:complexType name="usesLicenseType"> - <xsd:annotation> - <xsd:documentation> - Describes the license used by a package. The license MUST be defined - using a license node and referenced using the ref attribute of the - license element inside a package. - </xsd:documentation> - </xsd:annotation> - <xsd:attribute name="ref" type="xsd:IDREF" /> - </xsd:complexType> - - - <!-- A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository elements and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - --> - - <xsd:complexType name="archivesType"> - <xsd:annotation> - <xsd:documentation> - A collection of files that can be downloaded for a given architecture. - The <archives> node is mandatory in the repository packages and the - collection must have at least one <archive> declared. - Each archive is a zip file that will be unzipped in a location that depends - on its package type. - </xsd:documentation> - </xsd:annotation> - <xsd:sequence minOccurs="1" maxOccurs="unbounded"> - <!-- One archive file --> - <xsd:element name="archive"> - <xsd:complexType> - <!-- Properties of the archive file --> - <xsd:all> - <!-- The size in bytes of the archive to download. --> - <xsd:element name="size" type="xsd:positiveInteger" /> - <!-- The checksum of the archive file. --> - <xsd:element name="checksum" type="sdk:checksumType" /> - <!-- The URL is an absolute URL if it starts with http://, https:// - or ftp://. Otherwise it is relative to the parent directory that - contains this repository.xml --> - <xsd:element name="url" type="xsd:token" /> - </xsd:all> - - <!-- Attributes that identify the OS and architecture --> - <xsd:attribute name="os" use="required"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="linux" /> - <xsd:enumeration value="macosx" /> - <xsd:enumeration value="windows" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - <xsd:attribute name="arch" use="optional"> - <xsd:simpleType> - <xsd:restriction base="xsd:token"> - <xsd:enumeration value="any" /> - <xsd:enumeration value="ppc" /> - <xsd:enumeration value="x86" /> - <xsd:enumeration value="x86_64" /> - </xsd:restriction> - </xsd:simpleType> - </xsd:attribute> - </xsd:complexType> - </xsd:element> - </xsd:sequence> - </xsd:complexType> - - - <!-- The definition of a file checksum --> - - <xsd:simpleType name="sha1Number"> - <xsd:annotation> - <xsd:documentation>A SHA1 checksum.</xsd:documentation> - </xsd:annotation> - <xsd:restriction base="xsd:string"> - <xsd:pattern value="([0-9a-fA-F]){40}"/> - </xsd:restriction> - </xsd:simpleType> - - <xsd:complexType name="checksumType"> - <xsd:annotation> - <xsd:documentation>A file checksum, currently only SHA1.</xsd:documentation> - </xsd:annotation> - <xsd:simpleContent> - <xsd:extension base="sdk:sha1Number"> - <xsd:attribute name="type" type="xsd:token" fixed="sha1" /> - </xsd:extension> - </xsd:simpleContent> - </xsd:complexType> - -</xsd:schema> diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/ArrayUtils.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/util/ArrayUtils.java deleted file mode 100644 index 20f9c01..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/ArrayUtils.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - -import java.lang.reflect.Array; - -// XXX these should be changed to reflect the actual memory allocator we use. -// it looks like right now objects want to be powers of 2 minus 8 -// and the array size eats another 4 bytes - -/** - * ArrayUtils contains some methods that you can call to find out - * the most efficient increments by which to grow arrays. - */ -/* package */ class ArrayUtils -{ - private static Object[] EMPTY = new Object[0]; - private static final int CACHE_SIZE = 73; - private static Object[] sCache = new Object[CACHE_SIZE]; - - private ArrayUtils() { /* cannot be instantiated */ } - - public static int idealByteArraySize(int need) { - for (int i = 4; i < 32; i++) - if (need <= (1 << i) - 12) - return (1 << i) - 12; - - return need; - } - - public static int idealBooleanArraySize(int need) { - return idealByteArraySize(need); - } - - public static int idealShortArraySize(int need) { - return idealByteArraySize(need * 2) / 2; - } - - public static int idealCharArraySize(int need) { - return idealByteArraySize(need * 2) / 2; - } - - public static int idealIntArraySize(int need) { - return idealByteArraySize(need * 4) / 4; - } - - public static int idealFloatArraySize(int need) { - return idealByteArraySize(need * 4) / 4; - } - - public static int idealObjectArraySize(int need) { - return idealByteArraySize(need * 4) / 4; - } - - public static int idealLongArraySize(int need) { - return idealByteArraySize(need * 8) / 8; - } - - /** - * Checks if the beginnings of two byte arrays are equal. - * - * @param array1 the first byte array - * @param array2 the second byte array - * @param length the number of bytes to check - * @return true if they're equal, false otherwise - */ - public static boolean equals(byte[] array1, byte[] array2, int length) { - if (array1 == array2) { - return true; - } - if (array1 == null || array2 == null || array1.length < length || array2.length < length) { - return false; - } - for (int i = 0; i < length; i++) { - if (array1[i] != array2[i]) { - return false; - } - } - return true; - } - - /** - * Returns an empty array of the specified type. The intent is that - * it will return the same empty array every time to avoid reallocation, - * although this is not guaranteed. - */ - @SuppressWarnings("unchecked") - public static <T> T[] emptyArray(Class<T> kind) { - if (kind == Object.class) { - return (T[]) EMPTY; - } - - int bucket = ((System.identityHashCode(kind) / 8) & 0x7FFFFFFF) % CACHE_SIZE; - Object cache = sCache[bucket]; - - if (cache == null || cache.getClass().getComponentType() != kind) { - cache = Array.newInstance(kind, 0); - sCache[bucket] = cache; - - // Log.e("cache", "new empty " + kind.getName() + " at " + bucket); - } - - return (T[]) cache; - } - - /** - * Checks that value is present as at least one of the elements of the array. - * @param array the array to check in - * @param value the value to check for - * @return true if the value is present in the array - */ - public static <T> boolean contains(T[] array, T value) { - for (T element : array) { - if (element == null) { - if (value == null) return true; - } else { - if (value != null && element.equals(value)) return true; - } - } - return false; - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/CommandLineParser.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/util/CommandLineParser.java deleted file mode 100644 index 3a86ea7..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/CommandLineParser.java +++ /dev/null @@ -1,968 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.utils.ILogger; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map.Entry; - -/** - * Parses the command-line and stores flags needed or requested. - * <p/> - * This is a base class. To be useful you want to: - * <ul> - * <li>override it. - * <li>pass an action array to the constructor. - * <li>define flags for your actions. - * </ul> - * <p/> - * To use, call {@link #parseArgs(String[])} and then - * call {@link #getValue(String, String, String)}. - */ -public class CommandLineParser { - - /* - * Steps needed to add a new action: - * - Each action is defined as a "verb object" followed by parameters. - * - Either reuse a VERB_ constant or define a new one. - * - Either reuse an OBJECT_ constant or define a new one. - * - Add a new entry to mAction with a one-line help summary. - * - In the constructor, add a define() call for each parameter (either mandatory - * or optional) for the given action. - */ - - /** Internal verb name for internally hidden flags. */ - public final static String GLOBAL_FLAG_VERB = "@@internal@@"; //$NON-NLS-1$ - - /** String to use when the verb doesn't need any object. */ - public final static String NO_VERB_OBJECT = ""; //$NON-NLS-1$ - - /** The global help flag. */ - public static final String KEY_HELP = "help"; - /** The global verbose flag. */ - public static final String KEY_VERBOSE = "verbose"; - /** The global silent flag. */ - public static final String KEY_SILENT = "silent"; - - /** Verb requested by the user. Null if none specified, which will be an error. */ - private String mVerbRequested; - /** Direct object requested by the user. Can be null. */ - private String mDirectObjectRequested; - - /** - * Action definitions. - * <p/> - * This list serves two purposes: first it is used to know which verb/object - * actions are acceptable on the command-line; second it provides a summary - * for each action that is printed in the help. - * <p/> - * Each entry is a string array with: - * <ul> - * <li> the verb. - * <li> a direct object (use {@link #NO_VERB_OBJECT} if there's no object). - * <li> a description. - * <li> an alternate form for the object (e.g. plural). - * </ul> - */ - private final String[][] mActions; - - private static final int ACTION_VERB_INDEX = 0; - private static final int ACTION_OBJECT_INDEX = 1; - private static final int ACTION_DESC_INDEX = 2; - private static final int ACTION_ALT_OBJECT_INDEX = 3; - - /** - * The map of all defined arguments. - * <p/> - * The key is a string "verb/directObject/longName". - */ - private final HashMap<String, Arg> mArguments = new HashMap<String, Arg>(); - /** Logger */ - private final ILogger mLog; - - /** - * Constructs a new command-line processor. - * - * @param logger An SDK logger object. Must not be null. - * @param actions The list of actions recognized on the command-line. - * See the javadoc of {@link #mActions} for more details. - * - * @see #mActions - */ - public CommandLineParser(ILogger logger, String[][] actions) { - mLog = logger; - mActions = actions; - - /* - * usage should fit in 80 columns, including the space to print the options: - * " -v --verbose 7890123456789012345678901234567890123456789012345678901234567890" - */ - - define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "v", KEY_VERBOSE, - "Verbose mode, shows errors, warnings and all messages.", - false); - define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "s", KEY_SILENT, - "Silent mode, shows errors only.", - false); - define(Mode.BOOLEAN, false, GLOBAL_FLAG_VERB, NO_VERB_OBJECT, "h", KEY_HELP, - "Help on a specific command.", - false); - } - - /** - * Indicates if this command-line can work when no verb is specified. - * The default is false, which generates an error when no verb/object is specified. - * Derived implementations can set this to true if they can deal with a lack - * of verb/action. - */ - public boolean acceptLackOfVerb() { - return false; - } - - - //------------------ - // Helpers to get flags values - - /** Helper that returns true if --verbose was requested. */ - public boolean isVerbose() { - return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_VERBOSE)).booleanValue(); - } - - /** Helper that returns true if --silent was requested. */ - public boolean isSilent() { - return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_SILENT)).booleanValue(); - } - - /** Helper that returns true if --help was requested. */ - public boolean isHelpRequested() { - return ((Boolean) getValue(GLOBAL_FLAG_VERB, NO_VERB_OBJECT, KEY_HELP)).booleanValue(); - } - - /** Returns the verb name from the command-line. Can be null. */ - public String getVerb() { - return mVerbRequested; - } - - /** Returns the direct object name from the command-line. Can be null. */ - public String getDirectObject() { - return mDirectObjectRequested; - } - - //------------------ - - /** - * Raw access to parsed parameter values. - * <p/> - * The default is to scan all parameters. Parameters that have been explicitly set on the - * command line are returned first. Otherwise one with a non-null value is returned. - * <p/> - * Both a verb and a direct object filter can be specified. When they are non-null they limit - * the scope of the search. - * <p/> - * If nothing has been found, return the last default value seen matching the filter. - * - * @param verb The verb name, including {@link #GLOBAL_FLAG_VERB}. If null, all possible - * verbs that match the direct object condition will be examined and the first - * value set will be used. - * @param directObject The direct object name, including {@link #NO_VERB_OBJECT}. If null, - * all possible direct objects that match the verb condition will be examined and - * the first value set will be used. - * @param longFlagName The long flag name for the given action. Mandatory. Cannot be null. - * @return The current value object stored in the parameter, which depends on the argument mode. - */ - public Object getValue(String verb, String directObject, String longFlagName) { - - if (verb != null && directObject != null) { - String key = verb + '/' + directObject + '/' + longFlagName; - Arg arg = mArguments.get(key); - return arg.getCurrentValue(); - } - - Object lastDefault = null; - for (Arg arg : mArguments.values()) { - if (arg.getLongArg().equals(longFlagName)) { - if (verb == null || arg.getVerb().equals(verb)) { - if (directObject == null || arg.getDirectObject().equals(directObject)) { - if (arg.isInCommandLine()) { - return arg.getCurrentValue(); - } - if (arg.getCurrentValue() != null) { - lastDefault = arg.getCurrentValue(); - } - } - } - } - } - - return lastDefault; - } - - /** - * Internal setter for raw parameter value. - * @param verb The verb name, including {@link #GLOBAL_FLAG_VERB}. - * @param directObject The direct object name, including {@link #NO_VERB_OBJECT}. - * @param longFlagName The long flag name for the given action. - * @param value The new current value object stored in the parameter, which depends on the - * argument mode. - */ - protected void setValue(String verb, String directObject, String longFlagName, Object value) { - String key = verb + '/' + directObject + '/' + longFlagName; - Arg arg = mArguments.get(key); - arg.setCurrentValue(value); - } - - /** - * Parses the command-line arguments. - * <p/> - * This method will exit and not return if a parsing error arise. - * - * @param args The arguments typically received by a main method. - */ - public void parseArgs(String[] args) { - String errorMsg = null; - String verb = null; - String directObject = null; - - try { - int n = args.length; - for (int i = 0; i < n; i++) { - Arg arg = null; - String a = args[i]; - if (a.startsWith("--")) { //$NON-NLS-1$ - arg = findLongArg(verb, directObject, a.substring(2)); - } else if (a.startsWith("-")) { //$NON-NLS-1$ - arg = findShortArg(verb, directObject, a.substring(1)); - } - - // No matching argument name found - if (arg == null) { - // Does it looks like a dashed parameter? - if (a.startsWith("-")) { //$NON-NLS-1$ - if (verb == null || directObject == null) { - // It looks like a dashed parameter and we don't have a a verb/object - // set yet, the parameter was just given too early. - - errorMsg = String.format( - "Flag '%1$s' is not a valid global flag. Did you mean to specify it after the verb/object name?", - a); - return; - } else { - // It looks like a dashed parameter but it is unknown by this - // verb-object combination - - errorMsg = String.format( - "Flag '%1$s' is not valid for '%2$s %3$s'.", - a, verb, directObject); - return; - } - } - - if (verb == null) { - // Fill verb first. Find it. - for (String[] actionDesc : mActions) { - if (actionDesc[ACTION_VERB_INDEX].equals(a)) { - verb = a; - break; - } - } - - // Error if it was not a valid verb - if (verb == null) { - errorMsg = String.format( - "Expected verb after global parameters but found '%1$s' instead.", - a); - return; - } - - } else if (directObject == null) { - // Then fill the direct object. Find it. - for (String[] actionDesc : mActions) { - if (actionDesc[ACTION_VERB_INDEX].equals(verb)) { - if (actionDesc[ACTION_OBJECT_INDEX].equals(a)) { - directObject = a; - break; - } else if (actionDesc.length > ACTION_ALT_OBJECT_INDEX && - actionDesc[ACTION_ALT_OBJECT_INDEX].equals(a)) { - // if the alternate form exist and is used, we internally - // only memorize the default direct object form. - directObject = actionDesc[ACTION_OBJECT_INDEX]; - break; - } - } - } - - // Error if it was not a valid object for that verb - if (directObject == null) { - errorMsg = String.format( - "Expected verb after global parameters but found '%1$s' instead.", - a); - return; - - } - } else { - // The argument is not a dashed parameter and we already - // have a verb/object. Must be some extra unknown argument. - errorMsg = String.format( - "Argument '%1$s' is not recognized.", - a); - } - } else if (arg != null) { - // This argument was present on the command line - arg.setInCommandLine(true); - - // Process keyword - Object error = null; - if (arg.getMode().needsExtra()) { - if (i+1 >= n) { - errorMsg = String.format("Missing argument for flag %1$s.", a); - return; - } - - while (i+1 < n) { - String b = args[i+1]; - - if (arg.getMode() != Mode.STRING_ARRAY) { - // We never accept something that looks like a valid argument - // unless we see -- first - Arg dummyArg = null; - if (b.startsWith("--")) { //$NON-NLS-1$ - dummyArg = findLongArg(verb, directObject, b.substring(2)); - } else if (b.startsWith("-")) { //$NON-NLS-1$ - dummyArg = findShortArg(verb, directObject, b.substring(1)); - } - if (dummyArg != null) { - errorMsg = String.format( - "Oops, it looks like you didn't provide an argument for '%1$s'.\n'%2$s' was found instead.", - a, b); - return; - } - } - - error = arg.getMode().process(arg, b); - if (error == Accept.CONTINUE) { - i++; - } else if (error == Accept.ACCEPT_AND_STOP) { - i++; - break; - } else if (error == Accept.REJECT_AND_STOP) { - break; - } else if (error instanceof String) { - // We stop because of an error - break; - } - } - } else { - error = arg.getMode().process(arg, null); - - if (isHelpRequested()) { - // The --help flag was requested. We'll continue the usual processing - // so that we can find the optional verb/object words. Those will be - // used to print specific help. - // Setting a non-null error message triggers printing the help, however - // there is no specific error to print. - errorMsg = ""; //$NON-NLS-1$ - } - } - - if (error instanceof String) { - errorMsg = String.format("Invalid usage for flag %1$s: %2$s.", a, error); - return; - } - } - } - - if (errorMsg == null) { - if (verb == null && !acceptLackOfVerb()) { - errorMsg = "Missing verb name."; - } else if (verb != null) { - if (directObject == null) { - // Make sure this verb has an optional direct object - for (String[] actionDesc : mActions) { - if (actionDesc[ACTION_VERB_INDEX].equals(verb) && - actionDesc[ACTION_OBJECT_INDEX].equals(NO_VERB_OBJECT)) { - directObject = NO_VERB_OBJECT; - break; - } - } - - if (directObject == null) { - errorMsg = String.format("Missing object name for verb '%1$s'.", verb); - return; - } - } - - // Validate that all mandatory arguments are non-null for this action - String missing = null; - boolean plural = false; - for (Entry<String, Arg> entry : mArguments.entrySet()) { - Arg arg = entry.getValue(); - if (arg.getVerb().equals(verb) && - arg.getDirectObject().equals(directObject)) { - if (arg.isMandatory() && arg.getCurrentValue() == null) { - if (missing == null) { - missing = "--" + arg.getLongArg(); //$NON-NLS-1$ - } else { - missing += ", --" + arg.getLongArg(); //$NON-NLS-1$ - plural = true; - } - } - } - } - - if (missing != null) { - errorMsg = String.format( - "The %1$s %2$s must be defined for action '%3$s %4$s'", - plural ? "parameters" : "parameter", - missing, - verb, - directObject); - } - - mVerbRequested = verb; - mDirectObjectRequested = directObject; - } - } - } finally { - if (errorMsg != null) { - printHelpAndExitForAction(verb, directObject, errorMsg); - } - } - } - - /** - * Finds an {@link Arg} given an action name and a long flag name. - * @return The {@link Arg} found or null. - */ - protected Arg findLongArg(String verb, String directObject, String longName) { - if (verb == null) { - verb = GLOBAL_FLAG_VERB; - } - if (directObject == null) { - directObject = NO_VERB_OBJECT; - } - String key = verb + '/' + directObject + '/' + longName; //$NON-NLS-1$ - return mArguments.get(key); - } - - /** - * Finds an {@link Arg} given an action name and a short flag name. - * @return The {@link Arg} found or null. - */ - protected Arg findShortArg(String verb, String directObject, String shortName) { - if (verb == null) { - verb = GLOBAL_FLAG_VERB; - } - if (directObject == null) { - directObject = NO_VERB_OBJECT; - } - - for (Entry<String, Arg> entry : mArguments.entrySet()) { - Arg arg = entry.getValue(); - if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) { - if (shortName.equals(arg.getShortArg())) { - return arg; - } - } - } - - return null; - } - - /** - * Prints the help/usage and exits. - * - * @param errorFormat Optional error message to print prior to usage using String.format - * @param args Arguments for String.format - */ - public void printHelpAndExit(String errorFormat, Object... args) { - printHelpAndExitForAction(null /*verb*/, null /*directObject*/, errorFormat, args); - } - - /** - * Prints the help/usage and exits. - * - * @param verb If null, displays help for all verbs. If not null, display help only - * for that specific verb. In all cases also displays general usage and action list. - * @param directObject If null, displays help for all verb objects. - * If not null, displays help only for that specific action - * In all cases also display general usage and action list. - * @param errorFormat Optional error message to print prior to usage using String.format - * @param args Arguments for String.format - */ - public void printHelpAndExitForAction(String verb, String directObject, - String errorFormat, Object... args) { - if (errorFormat != null && errorFormat.length() > 0) { - stderr(errorFormat, args); - } - - /* - * usage should fit in 80 columns - * 12345678901234567890123456789012345678901234567890123456789012345678901234567890 - */ - stdout("\n" + - "Usage:\n" + - " android [global options] %s [action options]\n" + - "\n" + - "Global options:", - verb == null ? "action" : - verb + (directObject == null ? "" : " " + directObject)); //$NON-NLS-1$ - listOptions(GLOBAL_FLAG_VERB, NO_VERB_OBJECT); - - if (verb == null || directObject == null) { - stdout("\nValid actions are composed of a verb and an optional direct object:"); - for (String[] action : mActions) { - if (verb == null || verb.equals(action[ACTION_VERB_INDEX])) { - stdout("- %1$6s %2$-13s: %3$s", - action[ACTION_VERB_INDEX], - action[ACTION_OBJECT_INDEX], - action[ACTION_DESC_INDEX]); - } - } - } - - // Only print details if a verb/object is requested - if (verb != null) { - for (String[] action : mActions) { - if (verb == null || verb.equals(action[ACTION_VERB_INDEX])) { - if (directObject == null || directObject.equals(action[ACTION_OBJECT_INDEX])) { - stdout("\nAction \"%1$s %2$s\":", - action[ACTION_VERB_INDEX], - action[ACTION_OBJECT_INDEX]); - stdout(" %1$s", action[ACTION_DESC_INDEX]); - stdout("Options:"); - listOptions(action[ACTION_VERB_INDEX], action[ACTION_OBJECT_INDEX]); - } - } - } - } - - exit(); - } - - /** - * Internal helper to print all the option flags for a given action name. - */ - protected void listOptions(String verb, String directObject) { - int numOptions = 0; - int longArgLen = 8; - - for (Entry<String, Arg> entry : mArguments.entrySet()) { - Arg arg = entry.getValue(); - if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) { - int n = arg.getLongArg().length(); - if (n > longArgLen) { - longArgLen = n; - } - } - } - - for (Entry<String, Arg> entry : mArguments.entrySet()) { - Arg arg = entry.getValue(); - if (arg.getVerb().equals(verb) && arg.getDirectObject().equals(directObject)) { - - String value = ""; //$NON-NLS-1$ - String required = ""; //$NON-NLS-1$ - if (arg.isMandatory()) { - required = " [required]"; - - } else { - if (arg.getDefaultValue() instanceof String[]) { - for (String v : (String[]) arg.getDefaultValue()) { - if (value.length() > 0) { - value += ", "; - } - value += v; - } - } else if (arg.getDefaultValue() != null) { - Object v = arg.getDefaultValue(); - if (arg.getMode() != Mode.BOOLEAN || v.equals(Boolean.TRUE)) { - value = v.toString(); - } - } - if (value.length() > 0) { - value = " [Default: " + value + "]"; - } - } - - // Java doesn't support * for printf variable width, so we'll insert the long arg - // width "manually" in the printf format string. - String longArgWidth = Integer.toString(longArgLen + 2); - - // Print a line in the form " -1_letter_arg --long_arg description" - // where either the 1-letter arg or the long arg are optional. - String output = String.format( - " %1$-2s %2$-" + longArgWidth + "s: %3$s%4$s%5$s", //$NON-NLS-1$ //$NON-NLS-2$ - arg.getShortArg().length() > 0 ? - "-" + arg.getShortArg() : //$NON-NLS-1$ - "", //$NON-NLS-1$ - arg.getLongArg().length() > 0 ? - "--" + arg.getLongArg() : //$NON-NLS-1$ - "", //$NON-NLS-1$ - arg.getDescription(), - value, - required); - stdout(output); - numOptions++; - } - } - - if (numOptions == 0) { - stdout(" No options"); - } - } - - //---- - - private static enum Accept { - CONTINUE, - ACCEPT_AND_STOP, - REJECT_AND_STOP, - } - - /** - * The mode of an argument specifies the type of variable it represents, - * whether an extra parameter is required after the flag and how to parse it. - */ - public static enum Mode { - /** Argument value is a Boolean. Default value is a Boolean. */ - BOOLEAN { - @Override - public boolean needsExtra() { - return false; - } - @Override - public Object process(Arg arg, String extra) { - // Toggle the current value - arg.setCurrentValue(! ((Boolean) arg.getCurrentValue()).booleanValue()); - return Accept.ACCEPT_AND_STOP; - } - }, - - /** Argument value is an Integer. Default value is an Integer. */ - INTEGER { - @Override - public boolean needsExtra() { - return true; - } - @Override - public Object process(Arg arg, String extra) { - try { - arg.setCurrentValue(Integer.parseInt(extra)); - return null; - } catch (NumberFormatException e) { - return String.format("Failed to parse '%1$s' as an integer: %2$s", extra, - e.getMessage()); - } - } - }, - - /** Argument value is a String. Default value is a String[]. */ - ENUM { - @Override - public boolean needsExtra() { - return true; - } - @Override - public Object process(Arg arg, String extra) { - StringBuilder desc = new StringBuilder(); - String[] values = (String[]) arg.getDefaultValue(); - for (String value : values) { - if (value.equals(extra)) { - arg.setCurrentValue(extra); - return Accept.ACCEPT_AND_STOP; - } - - if (desc.length() != 0) { - desc.append(", "); - } - desc.append(value); - } - - return String.format("'%1$s' is not one of %2$s", extra, desc.toString()); - } - }, - - /** Argument value is a String. Default value is a null. */ - STRING { - @Override - public boolean needsExtra() { - return true; - } - @Override - public Object process(Arg arg, String extra) { - arg.setCurrentValue(extra); - return Accept.ACCEPT_AND_STOP; - } - }, - - /** Argument value is a {@link List}<String>. Default value is an empty list. */ - STRING_ARRAY { - @Override - public boolean needsExtra() { - return true; - } - @Override - public Object process(Arg arg, String extra) { - // For simplification, a string array doesn't accept something that - // starts with a dash unless a pure -- was seen before. - if (extra != null) { - Object v = arg.getCurrentValue(); - if (v == null) { - ArrayList<String> a = new ArrayList<String>(); - arg.setCurrentValue(a); - v = a; - } - if (v instanceof List<?>) { - @SuppressWarnings("unchecked") List<String> a = (List<String>) v; - - if (extra.equals("--") || - !extra.startsWith("-") || - (extra.startsWith("-") && a.contains("--"))) { - a.add(extra); - return Accept.CONTINUE; - } else if (a.isEmpty()) { - return "No values provided"; - } - } - } - return Accept.REJECT_AND_STOP; - } - }; - - /** - * Returns true if this mode requires an extra parameter. - */ - public abstract boolean needsExtra(); - - /** - * Processes the flag for this argument. - * - * @param arg The argument being processed. - * @param extra The extra parameter. Null if {@link #needsExtra()} returned false. - * @return {@link Accept#CONTINUE} if this argument can use multiple values and - * wishes to receive more. - * Or {@link Accept#ACCEPT_AND_STOP} if this was the last value accepted by the argument. - * Or {@link Accept#REJECT_AND_STOP} if this was value was reject and the argument - * stops accepting new values with no error. - * Or a string in case of error. - * Never returns null. - */ - public abstract Object process(Arg arg, String extra); - } - - /** - * An argument accepted by the command-line, also called "a flag". - * Arguments must have a short version (one letter), a long version name and a description. - * They can have a default value, or it can be null. - * Depending on the {@link Mode}, the default value can be a Boolean, an Integer, a String - * or a String array (in which case the first item is the current by default.) - */ - static class Arg { - /** Verb for that argument. Never null. */ - private final String mVerb; - /** Direct Object for that argument. Never null, but can be empty string. */ - private final String mDirectObject; - /** The 1-letter short name of the argument, e.g. -v. */ - private final String mShortName; - /** The long name of the argument, e.g. --verbose. */ - private final String mLongName; - /** A description. Never null. */ - private final String mDescription; - /** A default value. Can be null. */ - private final Object mDefaultValue; - /** The argument mode (type + process method). Never null. */ - private final Mode mMode; - /** True if this argument is mandatory for this verb/directobject. */ - private final boolean mMandatory; - /** Current value. Initially set to the default value. */ - private Object mCurrentValue; - /** True if the argument has been used on the command line. */ - private boolean mInCommandLine; - - /** - * Creates a new argument flag description. - * - * @param mode The {@link Mode} for the argument. - * @param mandatory True if this argument is mandatory for this action. - * @param verb The verb name. Never null. Can be {@link CommandLineParser#GLOBAL_FLAG_VERB}. - * @param directObject The action name. Can be {@link CommandLineParser#NO_VERB_OBJECT}. - * @param shortName The one-letter short argument name. Can be empty but not null. - * @param longName The long argument name. Can be empty but not null. - * @param description The description. Cannot be null. - * @param defaultValue The default value (or values), which depends on the selected - * {@link Mode}. Can be null. - */ - public Arg(Mode mode, - boolean mandatory, - @NonNull String verb, - @NonNull String directObject, - @NonNull String shortName, - @NonNull String longName, - @NonNull String description, - @Nullable Object defaultValue) { - mMode = mode; - mMandatory = mandatory; - mVerb = verb; - mDirectObject = directObject; - mShortName = shortName; - mLongName = longName; - mDescription = description; - mDefaultValue = defaultValue; - mInCommandLine = false; - if (defaultValue instanceof String[]) { - mCurrentValue = ((String[])defaultValue)[0]; - } else { - mCurrentValue = mDefaultValue; - } - } - - /** Return true if this argument is mandatory for this verb/directobject. */ - public boolean isMandatory() { - return mMandatory; - } - - /** Returns the 1-letter short name of the argument, e.g. -v. */ - public String getShortArg() { - return mShortName; - } - - /** Returns the long name of the argument, e.g. --verbose. */ - public String getLongArg() { - return mLongName; - } - - /** Returns the description. Never null. */ - public String getDescription() { - return mDescription; - } - - /** Returns the verb for that argument. Never null. */ - public String getVerb() { - return mVerb; - } - - /** Returns the direct Object for that argument. Never null, but can be empty string. */ - public String getDirectObject() { - return mDirectObject; - } - - /** Returns the default value. Can be null. */ - public Object getDefaultValue() { - return mDefaultValue; - } - - /** Returns the current value. Initially set to the default value. Can be null. */ - public Object getCurrentValue() { - return mCurrentValue; - } - - /** Sets the current value. Can be null. */ - public void setCurrentValue(Object currentValue) { - mCurrentValue = currentValue; - } - - /** Returns the argument mode (type + process method). Never null. */ - public Mode getMode() { - return mMode; - } - - /** Returns true if the argument has been used on the command line. */ - public boolean isInCommandLine() { - return mInCommandLine; - } - - /** Sets if the argument has been used on the command line. */ - public void setInCommandLine(boolean inCommandLine) { - mInCommandLine = inCommandLine; - } - } - - /** - * Internal helper to define a new argument for a give action. - * - * @param mode The {@link Mode} for the argument. - * @param mandatory The argument is required (never if {@link Mode#BOOLEAN}) - * @param verb The verb name. Never null. Can be {@link CommandLineParser#GLOBAL_FLAG_VERB}. - * @param directObject The action name. Can be {@link CommandLineParser#NO_VERB_OBJECT}. - * @param shortName The one-letter short argument name. Can be empty but not null. - * @param longName The long argument name. Can be empty but not null. - * @param description The description. Cannot be null. - * @param defaultValue The default value (or values), which depends on the selected - * {@link Mode}. - */ - protected void define(Mode mode, - boolean mandatory, - @NonNull String verb, - @NonNull String directObject, - @NonNull String shortName, - @NonNull String longName, - @NonNull String description, - @Nullable Object defaultValue) { - assert verb != null; - assert(!(mandatory && mode == Mode.BOOLEAN)); // a boolean mode cannot be mandatory - - // We should always have at least a short or long name, ideally both but never none. - assert shortName != null; - assert longName != null; - assert shortName.length() > 0 || longName.length() > 0; - - if (directObject == null) { - directObject = NO_VERB_OBJECT; - } - - String key = verb + '/' + directObject + '/' + longName; - mArguments.put(key, new Arg(mode, mandatory, - verb, directObject, shortName, longName, description, defaultValue)); - } - - /** - * Exits in case of error. - * This is protected so that it can be overridden in unit tests. - */ - protected void exit() { - System.exit(1); - } - - /** - * Prints a line to stdout. - * This is protected so that it can be overridden in unit tests. - * - * @param format The string to be formatted. Cannot be null. - * @param args Format arguments. - */ - protected void stdout(String format, Object...args) { - String output = String.format(format, args); - output = LineUtil.reflowLine(output); - mLog.info("%s\n", output); //$NON-NLS-1$ - } - - /** - * Prints a line to stderr. - * This is protected so that it can be overridden in unit tests. - * - * @param format The string to be formatted. Cannot be null. - * @param args Format arguments. - */ - protected void stderr(String format, Object...args) { - mLog.error(null, format, args); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/FormatUtils.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/util/FormatUtils.java deleted file mode 100755 index fc9258c..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/FormatUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - -import com.android.annotations.NonNull; - -/** - * Helper methods to do some format conversions. - */ -public abstract class FormatUtils { - - /** - * Converts a byte size to a human readable string, - * for example "3 MiB", "1020 Bytes" or "1.2 GiB". - * - * @param size The byte size to convert. - * @return A new non-null string, with the size expressed in either Bytes - * or KiB or MiB or GiB. - */ - public static @NonNull String byteSizeToString(long size) { - String sizeStr; - - if (size < 1024) { - sizeStr = String.format("%d Bytes", size); - } else if (size < 1024 * 1024) { - sizeStr = String.format("%d KiB", Math.round(size / 1024.0)); - } else if (size < 1024 * 1024 * 1024) { - sizeStr = String.format("%.1f MiB", - Math.round(10.0 * size / (1024 * 1024.0))/ 10.0); - } else { - sizeStr = String.format("%.1f GiB", - Math.round(10.0 * size / (1024 * 1024 * 1024.0))/ 10.0); - } - - return sizeStr; - } - -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/GrabProcessOutput.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/util/GrabProcessOutput.java deleted file mode 100755 index 2935493..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/GrabProcessOutput.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; - -public class GrabProcessOutput { - - public enum Wait { - /** - * Doesn't wait for the exec to complete. - * This still monitors the output but does not wait for the process to finish. - * In this mode the process return code is unknown and always 0. - */ - ASYNC, - /** - * This waits for the process to finish. - * In this mode, {@link GrabProcessOutput#grabProcessOutput} returns the - * error code from the process. - * In some rare cases and depending on the OS, the process might not have - * finished dumping data into stdout/stderr. - * <p/> - * Use this when you don't particularly care for the output but instead - * care for the return code of the executed process. - */ - WAIT_FOR_PROCESS, - /** - * This waits for the process to finish <em>and</em> for the stdout/stderr - * threads to complete. - * In this mode, {@link GrabProcessOutput#grabProcessOutput} returns the - * error code from the process. - * <p/> - * Use this one when capturing all the output from the process is important. - */ - WAIT_FOR_READERS, - } - - public interface IProcessOutput { - /** - * Processes an stdout message line. - * @param line The stdout message line. Null when the reader reached the end of stdout. - */ - public void out(@Nullable String line); - /** - * Processes an stderr message line. - * @param line The stderr message line. Null when the reader reached the end of stderr. - */ - public void err(@Nullable String line); - } - - /** - * Get the stderr/stdout outputs of a process and return when the process is done. - * Both <b>must</b> be read or the process will block on windows. - * - * @param process The process to get the ouput from. - * @param output Optional object to capture stdout/stderr. - * Note that on Windows capturing the output is not optional. If output is null - * the stdout/stderr will be captured and discarded. - * @param waitMode Whether to wait for the process and/or the readers to finish. - * @return the process return code. - * @throws InterruptedException if {@link Process#waitFor()} was interrupted. - */ - public static int grabProcessOutput( - @NonNull final Process process, - Wait waitMode, - @Nullable final IProcessOutput output) throws InterruptedException { - // read the lines as they come. if null is returned, it's - // because the process finished - Thread threadErr = new Thread("stderr") { - @Override - public void run() { - // create a buffer to read the stderr output - InputStreamReader is = new InputStreamReader(process.getErrorStream()); - BufferedReader errReader = new BufferedReader(is); - - try { - while (true) { - String line = errReader.readLine(); - if (output != null) { - output.err(line); - } - if (line == null) { - break; - } - } - } catch (IOException e) { - // do nothing. - } - } - }; - - Thread threadOut = new Thread("stdout") { - @Override - public void run() { - InputStreamReader is = new InputStreamReader(process.getInputStream()); - BufferedReader outReader = new BufferedReader(is); - - try { - while (true) { - String line = outReader.readLine(); - if (output != null) { - output.out(line); - } - if (line == null) { - break; - } - } - } catch (IOException e) { - // do nothing. - } - } - }; - - threadErr.start(); - threadOut.start(); - - if (waitMode == Wait.ASYNC) { - return 0; - } - - // it looks like on windows process#waitFor() can return - // before the thread have filled the arrays, so we wait for both threads and the - // process itself. - if (waitMode == Wait.WAIT_FOR_READERS) { - try { - threadErr.join(); - } catch (InterruptedException e) { - } - try { - threadOut.join(); - } catch (InterruptedException e) { - } - } - - // get the return code from the process - return process.waitFor(); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/LineUtil.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/util/LineUtil.java deleted file mode 100755 index c42bd0d..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/LineUtil.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - - -public abstract class LineUtil { - - /** - * Reformats a line so that it fits in 78 characters max. - * <p/> - * When wrapping the second line and following, prefix the string with a number of - * spaces. This will use the first colon (:) to determine the prefix size - * or use 4 as a minimum if there are no colons in the string. - * - * @param line The line to reflow. Must be non-null. - * @return A new line to print as-is, that contains \n as needed. - */ - public static String reflowLine(String line) { - final int maxLen = 78; - - // Most of time the line will fit in the given length and this will be a no-op - int n = line.length(); - int cr = line.indexOf('\n'); - if (n <= maxLen && (cr == -1 || cr == n - 1)) { - return line; - } - - int prefixSize = line.indexOf(':') + 1; - // If there' some spacing after the colon, use the same when wrapping - if (prefixSize > 0 && prefixSize < maxLen) { - while(prefixSize < n && line.charAt(prefixSize) == ' ') { - prefixSize++; - } - } else { - prefixSize = 4; - } - String prefix = String.format( - "%-" + Integer.toString(prefixSize) + "s", //$NON-NLS-1$ //$NON-NLS-2$ - " "); //$NON-NLS-1$ - - StringBuilder output = new StringBuilder(n + prefixSize); - - while (n > 0) { - cr = line.indexOf('\n'); - if (n <= maxLen && (cr == -1 || cr == n - 1)) { - output.append(line); - break; - } - - // Line is longer than the max length, find the first character before and after - // the whitespace where we want to break the line. - int posNext = maxLen; - if (cr != -1 && cr != n - 1 && cr <= posNext) { - posNext = cr + 1; - while (posNext < n && line.charAt(posNext) == '\n') { - posNext++; - } - } - while (posNext < n && line.charAt(posNext) == ' ') { - posNext++; - } - while (posNext > 0) { - char c = line.charAt(posNext - 1); - if (c != ' ' && c != '\n') { - posNext--; - } else { - break; - } - } - - if (posNext == 0 || (posNext >= n && maxLen < n)) { - // We found no whitespace separator. This should generally not occur. - posNext = maxLen; - } - int posPrev = posNext; - while (posPrev > 0) { - char c = line.charAt(posPrev - 1); - if (c == ' ' || c == '\n') { - posPrev--; - } else { - break; - } - } - - output.append(line.substring(0, posPrev)).append('\n'); - line = prefix + line.substring(posNext); - n = line.length(); - } - - return output.toString(); - } - - /** - * Formats the string using {@link String#format(String, Object...)} - * and then returns the result of {@link #reflowLine(String)}. - * - * @param format The string format. - * @param params The parameters for the string format. - * @return The result of {@link #reflowLine(String)} on the formatted string. - */ - public static String reformatLine(String format, Object...params) { - return reflowLine(String.format(format, params)); - } -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/SparseArray.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/util/SparseArray.java deleted file mode 100644 index f0693fe..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/SparseArray.java +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - - -/** - * SparseArrays map integers to Objects. Unlike a normal array of Objects, - * there can be gaps in the indices. It is intended to be more efficient - * than using a HashMap to map Integers to Objects. - */ -public class SparseArray<E> { - private static final Object DELETED = new Object(); - private boolean mGarbage = false; - - /** - * Creates a new SparseArray containing no mappings. - */ - public SparseArray() { - this(10); - } - - /** - * Creates a new SparseArray containing no mappings that will not - * require any additional memory allocation to store the specified - * number of mappings. - */ - public SparseArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); - - mKeys = new int[initialCapacity]; - mValues = new Object[initialCapacity]; - mSize = 0; - } - - /** - * Gets the Object mapped from the specified key, or <code>null</code> - * if no such mapping has been made. - */ - public E get(int key) { - return get(key, null); - } - - /** - * Gets the Object mapped from the specified key, or the specified Object - * if no such mapping has been made. - */ - @SuppressWarnings("unchecked") - public E get(int key, E valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i < 0 || mValues[i] == DELETED) { - return valueIfKeyNotFound; - } else { - return (E) mValues[i]; - } - } - - /** - * Removes the mapping from the specified key, if there was any. - */ - public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - if (mValues[i] != DELETED) { - mValues[i] = DELETED; - mGarbage = true; - } - } - } - - /** - * Alias for {@link #delete(int)}. - */ - public void remove(int key) { - delete(key); - } - - private void gc() { - // Log.e("SparseArray", "gc start with " + mSize); - - int n = mSize; - int o = 0; - int[] keys = mKeys; - Object[] values = mValues; - - for (int i = 0; i < n; i++) { - Object val = values[i]; - - if (val != DELETED) { - if (i != o) { - keys[o] = keys[i]; - values[o] = val; - } - - o++; - } - } - - mGarbage = false; - mSize = o; - - // Log.e("SparseArray", "gc end with " + mSize); - } - - /** - * Adds a mapping from the specified key to the specified value, - * replacing the previous mapping from the specified key if there - * was one. - */ - public void put(int key, E value) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - mValues[i] = value; - } else { - i = ~i; - - if (i < mSize && mValues[i] == DELETED) { - mKeys[i] = key; - mValues[i] = value; - return; - } - - if (mGarbage && mSize >= mKeys.length) { - gc(); - - // Search again because indices may have changed. - i = ~binarySearch(mKeys, 0, mSize, key); - } - - if (mSize >= mKeys.length) { - int n = ArrayUtils.idealIntArraySize(mSize + 1); - - int[] nkeys = new int[n]; - Object[] nvalues = new Object[n]; - - // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - if (mSize - i != 0) { - // Log.e("SparseArray", "move " + (mSize - i)); - System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i); - System.arraycopy(mValues, i, mValues, i + 1, mSize - i); - } - - mKeys[i] = key; - mValues[i] = value; - mSize++; - } - } - - /** - * Returns the number of key-value mappings that this SparseArray - * currently stores. - */ - public int size() { - if (mGarbage) { - gc(); - } - - return mSize; - } - - /** - * Given an index in the range <code>0...size()-1</code>, returns - * the key from the <code>index</code>th key-value mapping that this - * SparseArray stores. - */ - public int keyAt(int index) { - if (mGarbage) { - gc(); - } - - return mKeys[index]; - } - - /** - * Given an index in the range <code>0...size()-1</code>, returns - * the value from the <code>index</code>th key-value mapping that this - * SparseArray stores. - */ - @SuppressWarnings("unchecked") - public E valueAt(int index) { - if (mGarbage) { - gc(); - } - - return (E) mValues[index]; - } - - /** - * Given an index in the range <code>0...size()-1</code>, sets a new - * value for the <code>index</code>th key-value mapping that this - * SparseArray stores. - */ - public void setValueAt(int index, E value) { - if (mGarbage) { - gc(); - } - - mValues[index] = value; - } - - /** - * Returns the index for which {@link #keyAt} would return the - * specified key, or a negative number if the specified - * key is not mapped. - */ - public int indexOfKey(int key) { - if (mGarbage) { - gc(); - } - - return binarySearch(mKeys, 0, mSize, key); - } - - /** - * Returns an index for which {@link #valueAt} would return the - * specified key, or a negative number if no keys map to the - * specified value. - * Beware that this is a linear search, unlike lookups by key, - * and that multiple keys can map to the same value and this will - * find only one of them. - */ - public int indexOfValue(E value) { - if (mGarbage) { - gc(); - } - - for (int i = 0; i < mSize; i++) - if (mValues[i] == value) - return i; - - return -1; - } - - /** - * Removes all key-value mappings from this SparseArray. - */ - public void clear() { - int n = mSize; - Object[] values = mValues; - - for (int i = 0; i < n; i++) { - values[i] = null; - } - - mSize = 0; - mGarbage = false; - } - - /** - * Puts a key/value pair into the array, optimizing for the case where - * the key is greater than all existing keys in the array. - */ - public void append(int key, E value) { - if (mSize != 0 && key <= mKeys[mSize - 1]) { - put(key, value); - return; - } - - if (mGarbage && mSize >= mKeys.length) { - gc(); - } - - int pos = mSize; - if (pos >= mKeys.length) { - int n = ArrayUtils.idealIntArraySize(pos + 1); - - int[] nkeys = new int[n]; - Object[] nvalues = new Object[n]; - - // Log.e("SparseArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - mKeys[pos] = key; - mValues[pos] = value; - mSize = pos + 1; - } - - public SparseArray<E> getUnmodifiable() { - final SparseArray<E> mStorage = this; - return new SparseArray<E>() { - - @Override - public E get(int key) { - return mStorage.get(key); - } - - @Override - public E get(int key, E valueIfKeyNotFound) { - return mStorage.get(key, valueIfKeyNotFound); - } - - @Override - public void delete(int key) { - throw new UnsupportedOperationException(); - } - - @Override - public void remove(int key) { - throw new UnsupportedOperationException(); - } - - @Override - public void put(int key, E value) { - throw new UnsupportedOperationException(); - } - - @Override - public int size() { - return mStorage.size(); - } - - @Override - public int keyAt(int index) { - return mStorage.keyAt(index); - } - - @Override - public E valueAt(int index) { - return mStorage.valueAt(index); - } - - @Override - public void setValueAt(int index, E value) { - throw new UnsupportedOperationException(); - } - - @Override - public int indexOfKey(int key) { - return mStorage.indexOfKey(key); - } - - @Override - public int indexOfValue(E value) { - return mStorage.indexOfValue(value); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public void append(int key, E value) { - throw new UnsupportedOperationException(); - } - - }; - } - - private static int binarySearch(int[] a, int start, int len, int key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; - } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; - } - - private int[] mKeys; - private Object[] mValues; - private int mSize; -} diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/SparseIntArray.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/util/SparseIntArray.java deleted file mode 100644 index 9573566..0000000 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/util/SparseIntArray.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - - -/** - * SparseIntArrays map integers to integers. Unlike a normal array of integers, - * there can be gaps in the indices. It is intended to be more efficient - * than using a HashMap to map Integers to Integers. - */ -public class SparseIntArray { - /** - * Creates a new SparseIntArray containing no mappings. - */ - public SparseIntArray() { - this(10); - } - - /** - * Creates a new SparseIntArray containing no mappings that will not - * require any additional memory allocation to store the specified - * number of mappings. - */ - public SparseIntArray(int initialCapacity) { - initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity); - - mKeys = new int[initialCapacity]; - mValues = new int[initialCapacity]; - mSize = 0; - } - - /** - * Gets the int mapped from the specified key, or <code>0</code> - * if no such mapping has been made. - */ - public int get(int key) { - return get(key, 0); - } - - /** - * Gets the int mapped from the specified key, or the specified value - * if no such mapping has been made. - */ - public int get(int key, int valueIfKeyNotFound) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i < 0) { - return valueIfKeyNotFound; - } else { - return mValues[i]; - } - } - - /** - * Removes the mapping from the specified key, if there was any. - */ - public void delete(int key) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - removeAt(i); - } - } - - /** - * Removes the mapping at the given index. - */ - public void removeAt(int index) { - System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1)); - System.arraycopy(mValues, index + 1, mValues, index, mSize - (index + 1)); - mSize--; - } - - /** - * Adds a mapping from the specified key to the specified value, - * replacing the previous mapping from the specified key if there - * was one. - */ - public void put(int key, int value) { - int i = binarySearch(mKeys, 0, mSize, key); - - if (i >= 0) { - mValues[i] = value; - } else { - i = ~i; - - if (mSize >= mKeys.length) { - int n = ArrayUtils.idealIntArraySize(mSize + 1); - - int[] nkeys = new int[n]; - int[] nvalues = new int[n]; - - // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - if (mSize - i != 0) { - // Log.e("SparseIntArray", "move " + (mSize - i)); - System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i); - System.arraycopy(mValues, i, mValues, i + 1, mSize - i); - } - - mKeys[i] = key; - mValues[i] = value; - mSize++; - } - } - - /** - * Returns the number of key-value mappings that this SparseIntArray - * currently stores. - */ - public int size() { - return mSize; - } - - /** - * Given an index in the range <code>0...size()-1</code>, returns - * the key from the <code>index</code>th key-value mapping that this - * SparseIntArray stores. - */ - public int keyAt(int index) { - return mKeys[index]; - } - - /** - * Given an index in the range <code>0...size()-1</code>, returns - * the value from the <code>index</code>th key-value mapping that this - * SparseIntArray stores. - */ - public int valueAt(int index) { - return mValues[index]; - } - - /** - * Returns the index for which {@link #keyAt} would return the - * specified key, or a negative number if the specified - * key is not mapped. - */ - public int indexOfKey(int key) { - return binarySearch(mKeys, 0, mSize, key); - } - - /** - * Returns an index for which {@link #valueAt} would return the - * specified key, or a negative number if no keys map to the - * specified value. - * Beware that this is a linear search, unlike lookups by key, - * and that multiple keys can map to the same value and this will - * find only one of them. - */ - public int indexOfValue(int value) { - for (int i = 0; i < mSize; i++) - if (mValues[i] == value) - return i; - - return -1; - } - - /** - * Removes all key-value mappings from this SparseIntArray. - */ - public void clear() { - mSize = 0; - } - - /** - * Puts a key/value pair into the array, optimizing for the case where - * the key is greater than all existing keys in the array. - */ - public void append(int key, int value) { - if (mSize != 0 && key <= mKeys[mSize - 1]) { - put(key, value); - return; - } - - int pos = mSize; - if (pos >= mKeys.length) { - int n = ArrayUtils.idealIntArraySize(pos + 1); - - int[] nkeys = new int[n]; - int[] nvalues = new int[n]; - - // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n); - System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length); - System.arraycopy(mValues, 0, nvalues, 0, mValues.length); - - mKeys = nkeys; - mValues = nvalues; - } - - mKeys[pos] = key; - mValues[pos] = value; - mSize = pos + 1; - } - - private static int binarySearch(int[] a, int start, int len, int key) { - int high = start + len, low = start - 1, guess; - - while (high - low > 1) { - guess = (high + low) / 2; - - if (a[guess] < key) - low = guess; - else - high = guess; - } - - if (high == start + len) - return ~(start + len); - else if (a[high] == key) - return high; - else - return ~high; - } - - private int[] mKeys; - private int[] mValues; - private int mSize; -} diff --git a/sdkmanager/libs/sdklib/tests/Android.mk b/sdkmanager/libs/sdklib/tests/Android.mk deleted file mode 100644 index c758cda..0000000 --- a/sdkmanager/libs/sdklib/tests/Android.mk +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2011 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -# Only compile source java files in this lib. -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_JAVA_RESOURCE_DIRS := src - -LOCAL_MODULE := sdklib-tests -LOCAL_MODULE_TAGS := optional - -LOCAL_JAVA_LIBRARIES := sdklib junit dvlib-tests - -include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/AndroidVersionTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/AndroidVersionTest.java deleted file mode 100755 index 5270bd1..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/AndroidVersionTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import junit.framework.TestCase; - -/** - * Unit tests for {@link AndroidVersion}. - */ -public class AndroidVersionTest extends TestCase { - - public final void testAndroidVersion() { - AndroidVersion v = new AndroidVersion(1, " CODENAME "); - assertEquals(1, v.getApiLevel()); - assertEquals("CODENAME", v.getApiString()); - assertTrue(v.isPreview()); - assertEquals("CODENAME", v.getCodename()); - assertEquals("CODENAME".hashCode(), v.hashCode()); - assertEquals("API 1, CODENAME preview", v.toString()); - - v = new AndroidVersion(15, "REL"); - assertEquals(15, v.getApiLevel()); - assertEquals("15", v.getApiString()); - assertFalse(v.isPreview()); - assertNull(v.getCodename()); - assertTrue(v.equals(15)); - assertEquals(15, v.hashCode()); - assertEquals("API 15", v.toString()); - - v = new AndroidVersion(15, null); - assertEquals(15, v.getApiLevel()); - assertEquals("15", v.getApiString()); - assertFalse(v.isPreview()); - assertNull(v.getCodename()); - assertTrue(v.equals(15)); - assertEquals(15, v.hashCode()); - assertEquals("API 15", v.toString()); - - // An empty codename is like a null codename - v = new AndroidVersion(15, " "); - assertFalse(v.isPreview()); - assertNull(v.getCodename()); - assertEquals("15", v.getApiString()); - - v = new AndroidVersion(15, ""); - assertFalse(v.isPreview()); - assertNull(v.getCodename()); - assertEquals("15", v.getApiString()); - - assertTrue(v.isGreaterOrEqualThan(0)); - assertTrue(v.isGreaterOrEqualThan(14)); - assertTrue(v.isGreaterOrEqualThan(15)); - assertFalse(v.isGreaterOrEqualThan(16)); - assertFalse(v.isGreaterOrEqualThan(Integer.MAX_VALUE)); - } - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/LayoutlibVersionTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/LayoutlibVersionTest.java deleted file mode 100755 index 0c197aa..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/LayoutlibVersionTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - -import com.android.sdklib.SdkManager.LayoutlibVersion; - -import junit.framework.TestCase; - -/** - * Unit test for {@link LayoutlibVersion}. - */ -public class LayoutlibVersionTest extends TestCase { - - public void testLayoutlibVersion_create() { - LayoutlibVersion lv = new LayoutlibVersion(1, 2); - assertEquals(1, lv.getApi()); - assertEquals(2, lv.getRevision()); - } - - public void testLayoutlibVersion_compare() { - assertTrue(new LayoutlibVersion(1, 1).compareTo(new LayoutlibVersion(1, 1)) == 0); - assertTrue(new LayoutlibVersion(1, 2).compareTo(new LayoutlibVersion(1, 1)) > 0); - assertTrue(new LayoutlibVersion(1, 1).compareTo(new LayoutlibVersion(1, 2)) < 0); - assertTrue(new LayoutlibVersion(2, 2).compareTo(new LayoutlibVersion(1, 3)) > 0); - - // the lack of an API (== 0) naturally sorts as the lowest value possible. - assertTrue(new LayoutlibVersion(0, 1).compareTo(new LayoutlibVersion(0, 2)) < 0); - assertTrue(new LayoutlibVersion(0, 1).compareTo(new LayoutlibVersion(1, 2)) < 0); - assertTrue(new LayoutlibVersion(0, 3).compareTo(new LayoutlibVersion(1, 2)) < 0); - assertTrue(new LayoutlibVersion(1, 2).compareTo(new LayoutlibVersion(0, 3)) > 0); - - // if we lack the revision number, we don't use it in comparison - assertTrue(new LayoutlibVersion(2, 0).compareTo(new LayoutlibVersion(2, 2)) == 0); - assertTrue(new LayoutlibVersion(2, 2).compareTo(new LayoutlibVersion(2, 0)) == 0); - } - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/SdkManagerTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/SdkManagerTest.java deleted file mode 100755 index 487a96a..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/SdkManagerTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - - -import com.android.SdkConstants; -import com.android.sdklib.ISystemImage.LocationType; -import com.android.sdklib.SdkManager.LayoutlibVersion; - -import java.util.Arrays; -import java.util.regex.Pattern; - -public class SdkManagerTest extends SdkManagerTestCase { - - @SuppressWarnings("deprecation") - public void testSdkManager_LayoutlibVersion() { - SdkManager sdkman = getSdkManager(); - IAndroidTarget t = sdkman.getTargets()[0]; - - assertTrue(t instanceof PlatformTarget); - - LayoutlibVersion lv = ((PlatformTarget) t).getLayoutlibVersion(); - assertNotNull(lv); - assertEquals(5, lv.getApi()); - assertEquals(2, lv.getRevision()); - - assertSame(lv, sdkman.getMaxLayoutlibVersion()); - } - - public void testSdkManager_SystemImage() throws Exception { - SdkManager sdkman = getSdkManager(); - assertEquals("[PlatformTarget API 0 rev 1]", Arrays.toString(sdkman.getTargets())); - IAndroidTarget t = sdkman.getTargets()[0]; - - // By default SdkManagerTestCase creates an SDK with one platform containing - // a legacy armeabi system image. - assertEquals( - "[SystemImage ABI=armeabi, location in platform legacy='$SDK/platforms/v0_0/images']", - cleanPath(sdkman, Arrays.toString(t.getSystemImages()))); - - // Now add a few "platform subfolders" system images and reload the SDK. - // This disables the "legacy" mode, which means that although the armeabi - // target from above is present, it is no longer visible. - - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_PLATFORM_SUBFOLDER, SdkConstants.ABI_ARMEABI_V7A)); - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_PLATFORM_SUBFOLDER, SdkConstants.ABI_INTEL_ATOM)); - - sdkman.reloadSdk(getLog()); - assertEquals("[PlatformTarget API 0 rev 1]", Arrays.toString(sdkman.getTargets())); - t = sdkman.getTargets()[0]; - - assertEquals( - "[SystemImage ABI=armeabi-v7a, location in platform subfolder='$SDK/platforms/v0_0/images/armeabi-v7a', " + - "SystemImage ABI=x86, location in platform subfolder='$SDK/platforms/v0_0/images/x86']", - cleanPath(sdkman, Arrays.toString(t.getSystemImages()))); - - // Now add arm + arm v7a images using the new SDK/system-images. - // The x86 one from the platform subfolder is still visible. - // The armeabi one from the legacy folder is overridden by the new one. - // The armeabi-v7a one from the platform subfolder is overridden by the new one. - - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_SYSTEM_IMAGE, SdkConstants.ABI_ARMEABI)); - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_SYSTEM_IMAGE, SdkConstants.ABI_ARMEABI_V7A)); - - sdkman.reloadSdk(getLog()); - assertEquals("[PlatformTarget API 0 rev 1]", Arrays.toString(sdkman.getTargets())); - t = sdkman.getTargets()[0]; - - assertEquals( - "[SystemImage ABI=armeabi, location in system image='$SDK/system-images/android-0/armeabi', " + - "SystemImage ABI=armeabi-v7a, location in system image='$SDK/system-images/android-0/armeabi-v7a', " + - "SystemImage ABI=x86, location in platform subfolder='$SDK/platforms/v0_0/images/x86']", - cleanPath(sdkman, Arrays.toString(t.getSystemImages()))); - } - - public void testSdkManager_SystemImage_LegacyOverride() throws Exception { - SdkManager sdkman = getSdkManager(); - assertEquals("[PlatformTarget API 0 rev 1]", Arrays.toString(sdkman.getTargets())); - IAndroidTarget t = sdkman.getTargets()[0]; - - // By default SdkManagerTestCase creates an SDK with one platform containing - // a legacy armeabi system image. - assertEquals( - "[SystemImage ABI=armeabi, location in platform legacy='$SDK/platforms/v0_0/images']", - cleanPath(sdkman, Arrays.toString(t.getSystemImages()))); - - // Now add a different ABI system image in the new system-images folder. - // This does not hide the legacy one as long as the ABI type is different - // (to contrast: having at least one sub-folder in the platform's legacy images folder - // will hide the legacy system image. Whereas this does not happen with the new type.) - - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_SYSTEM_IMAGE, SdkConstants.ABI_INTEL_ATOM)); - - sdkman.reloadSdk(getLog()); - assertEquals("[PlatformTarget API 0 rev 1]", Arrays.toString(sdkman.getTargets())); - t = sdkman.getTargets()[0]; - - assertEquals( - "[SystemImage ABI=armeabi, location in platform legacy='$SDK/platforms/v0_0/images', " + - "SystemImage ABI=x86, location in system image='$SDK/system-images/android-0/x86']", - cleanPath(sdkman, Arrays.toString(t.getSystemImages()))); - - // Now if we have one new system-image using the same ABI type, it will override the - // legacy one. This gives us a good path for updates. - - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_SYSTEM_IMAGE, SdkConstants.ABI_ARMEABI)); - - - sdkman.reloadSdk(getLog()); - assertEquals("[PlatformTarget API 0 rev 1]", Arrays.toString(sdkman.getTargets())); - t = sdkman.getTargets()[0]; - - assertEquals( - "[SystemImage ABI=armeabi, location in system image='$SDK/system-images/android-0/armeabi', " + - "SystemImage ABI=x86, location in system image='$SDK/system-images/android-0/x86']", - cleanPath(sdkman, Arrays.toString(t.getSystemImages()))); - } - - /** - * Sanitizes the paths used when testing results. - * <p/> - * The system image text representation contains the absolute path to the SDK. - * However the SDK path is actually a randomized location. - * We clean it by replacing it by the constant '$SDK'. - * Also all the Windows path separators are converted to unix-like / separators. - */ - private String cleanPath(SdkManager sdkman, String string) { - return string - .replaceAll(Pattern.quote(sdkman.getLocation()), "\\$SDK") //$NON-NLS-1$ - .replace('\\', '/'); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/SdkManagerTestCase.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/SdkManagerTestCase.java deleted file mode 100755 index 86a555a..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/SdkManagerTestCase.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib; - - -import com.android.SdkConstants; -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.io.FileOp; -import com.android.sdklib.mock.MockLog; -import com.android.sdklib.repository.PkgProps; -import com.android.utils.ILogger; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; - -import junit.framework.TestCase; - -/** - * Test case that allocates a temporary SDK, a temporary AVD base folder - * with an SdkManager and an AvdManager that points to them. - */ -public class SdkManagerTestCase extends TestCase { - - private File mFakeSdk; - private MockLog mLog; - private SdkManager mSdkManager; - private TmpAvdManager mAvdManager; - - /** Returns the {@link MockLog} for this test case. */ - public MockLog getLog() { - return mLog; - } - - /** Returns the {@link SdkManager} for this test case. */ - public SdkManager getSdkManager() { - return mSdkManager; - } - - /** Returns the {@link AvdManager} for this test case. */ - public TmpAvdManager getAvdManager() { - return mAvdManager; - } - - /** - * Sets up a {@link MockLog}, a fake SDK in a temporary directory - * and an AVD Manager pointing to an initially-empty AVD directory. - */ - @Override - public void setUp() throws Exception { - mLog = new MockLog(); - mFakeSdk = makeFakeSdk(); - mSdkManager = SdkManager.createManager(mFakeSdk.getAbsolutePath(), mLog); - assertNotNull("SdkManager location was invalid", mSdkManager); - - mAvdManager = new TmpAvdManager(mSdkManager, mLog); - } - - /** - * Removes the temporary SDK and AVD directories. - */ - @Override - public void tearDown() throws Exception { - deleteDir(mFakeSdk); - } - - /** - * A empty test method to placate the JUnit test runner, which doesn't - * like TestCase classes with no test methods. - */ - public void testPlaceholder() { - } - - /** - * An {@link AvdManager} that uses a temporary directory - * located <em>inside</em> the SDK directory for testing. - * The AVD list should be initially empty. - */ - protected static class TmpAvdManager extends AvdManager { - - /* - * Implementation detail: - * - When the super.AvdManager constructor is invoked, it will invoke - * the buildAvdFilesList() to fill the initial AVD list, which will in - * turn call getBaseAvdFolder(). - * - That's why mTmpAvdRoot is initialized in getAvdRoot() rather than - * in the constructor, since we can't initialize fields before the super() - * call. - */ - - /** - * AVD Root, initialized "lazily" when the AVD root is first requested. - */ - private File mTmpAvdRoot; - - public TmpAvdManager(SdkManager sdkManager, ILogger log) throws AndroidLocationException { - super(sdkManager, log); - } - - @Override - public String getBaseAvdFolder() throws AndroidLocationException { - if (mTmpAvdRoot == null) { - mTmpAvdRoot = new File(getSdkManager().getLocation(), "tmp_avds"); - mTmpAvdRoot.mkdirs(); - } - return mTmpAvdRoot.getAbsolutePath(); - } - } - - /** - * Build enough of a skeleton SDK to make the tests pass. - * <p/> - * Ideally this wouldn't touch the file system but the current - * structure of the SdkManager and AvdManager makes this difficult. - * - * @return Path to the temporary SDK root - * @throws IOException - */ - private File makeFakeSdk() throws IOException { - // First we create a temp file to "reserve" the temp directory name we want to use. - File sdkDir = File.createTempFile( - this.getClass().getSimpleName() + '_' + this.getName(), null); - // Then erase the file and make the directory - sdkDir.delete(); - sdkDir.mkdirs(); - - AndroidLocation.resetFolder(); - File addonsDir = new File(sdkDir, SdkConstants.FD_ADDONS); - addonsDir.mkdir(); - - File toolsDir = new File(sdkDir, SdkConstants.OS_SDK_TOOLS_FOLDER); - toolsDir.mkdir(); - new File(toolsDir, SdkConstants.androidCmdName()).createNewFile(); - new File(toolsDir, SdkConstants.FN_EMULATOR).createNewFile(); - - // TODO makePlatformTools with at least a source props - - File toolsLibEmuDir = new File(sdkDir, SdkConstants.OS_SDK_TOOLS_LIB_FOLDER + "emulator"); - toolsLibEmuDir.mkdirs(); - new File(toolsLibEmuDir, "snapshots.img").createNewFile(); - File platformsDir = new File(sdkDir, SdkConstants.FD_PLATFORMS); - - // Creating a fake target here on down - File targetDir = makeFakeTargetInternal(platformsDir); - - File imagesDir = new File(targetDir, "images"); - makeFakeSysImgInternal(imagesDir, SdkConstants.ABI_ARMEABI); - - makeFakeSkinInternal(targetDir); - makeFakeSourceInternal(sdkDir); - return sdkDir; - } - - /** - * Creates the system image folder and places a fake userdata.img in it. - * - * @param systemImage A system image with a valid location. - * @throws IOException if the file fails to be created. - */ - protected void makeSystemImageFolder(ISystemImage systemImage) throws IOException { - File imagesDir = systemImage.getLocation(); - imagesDir.mkdirs(); - - makeFakeSysImgInternal(imagesDir, systemImage.getAbiType()); - } - - //---- - - /** Utility used by {@link #makeFakeSdk()} to create a fake target with API 0, rev 0. */ - private File makeFakeTargetInternal(File platformsDir) throws IOException { - File targetDir = new File(platformsDir, "v0_0"); - targetDir.mkdirs(); - new File(targetDir, SdkConstants.FN_FRAMEWORK_LIBRARY).createNewFile(); - new File(targetDir, SdkConstants.FN_FRAMEWORK_AIDL).createNewFile(); - - File sourceProp = new File(targetDir, SdkConstants.FN_SOURCE_PROP); - sourceProp.createNewFile(); - FileWriter out = new FileWriter(sourceProp); - out.write(PkgProps.LAYOUTLIB_API + "=5\n"); - out.write(PkgProps.LAYOUTLIB_REV + "=2\n"); - out.close(); - - File buildProp = new File(targetDir, SdkConstants.FN_BUILD_PROP); - out = new FileWriter(buildProp); - out.write(SdkManager.PROP_VERSION_RELEASE + "=0.0\n"); - out.write(SdkManager.PROP_VERSION_SDK + "=0\n"); - out.write(SdkManager.PROP_VERSION_CODENAME + "=REL\n"); - out.close(); - return targetDir; - } - - /** Utility to create a fake sys image in the given folder. */ - private void makeFakeSysImgInternal(File imagesDir, String abiType) throws IOException { - imagesDir.mkdirs(); - new File(imagesDir, "userdata.img").createNewFile(); - - File sourceProp = new File(imagesDir, SdkConstants.FN_SOURCE_PROP); - sourceProp.createNewFile(); - FileWriter out = new FileWriter(sourceProp); - out.write(PkgProps.VERSION_API_LEVEL + "=0\n"); - out.write(PkgProps.SYS_IMG_ABI + "=" + abiType + "\n"); - out.close(); - } - - /** Utility to make a fake skin for the given target */ - private void makeFakeSkinInternal(File targetDir) { - FileOp.append(targetDir, "skins", "HVGA").mkdirs(); - } - - /** Utility to create a fake source with a few files in the given sdk folder. */ - private void makeFakeSourceInternal(File sdkDir) throws IOException { - File sourcesDir = FileOp.append(sdkDir, SdkConstants.FD_PKG_SOURCES, "android-0"); - sourcesDir.mkdirs(); - - File sourceProp = new File(sourcesDir, SdkConstants.FN_SOURCE_PROP); - sourceProp.createNewFile(); - FileWriter out = new FileWriter(sourceProp); - out.write(PkgProps.VERSION_API_LEVEL + "=0\n"); - out.close(); - - File dir1 = FileOp.append(sourcesDir, "src", "com", "android"); - dir1.mkdirs(); - FileOp.append(dir1, "File1.java").createNewFile(); - FileOp.append(dir1, "File2.java").createNewFile(); - - FileOp.append(sourcesDir, "res", "values").mkdirs(); - FileOp.append(sourcesDir, "res", "values", "styles.xml").createNewFile(); - } - - /** - * Recursive delete directory. Mostly for fake SDKs. - * - * @param root directory to delete - */ - private void deleteDir(File root) { - if (root.exists()) { - for (File file : root.listFiles()) { - if (file.isDirectory()) { - deleteDir(file); - } else { - file.delete(); - } - } - root.delete(); - } - } - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/devices/DeviceParserTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/devices/DeviceParserTest.java deleted file mode 100644 index f24fbda..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/devices/DeviceParserTest.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import junit.framework.TestCase; - -import org.xml.sax.SAXParseException; - -import com.android.dvlib.DeviceSchemaTest; -import com.android.resources.Density; -import com.android.resources.Keyboard; -import com.android.resources.KeyboardState; -import com.android.resources.Navigation; -import com.android.resources.NavigationState; -import com.android.resources.ScreenOrientation; -import com.android.resources.ScreenRatio; -import com.android.resources.ScreenSize; -import com.android.resources.TouchScreen; -import com.android.sdklib.devices.Storage.Unit; - -public class DeviceParserTest extends TestCase { - - public void testValidDevices() throws Exception { - InputStream devicesFile = DeviceSchemaTest.class.getResourceAsStream("devices_minimal.xml"); - List<Device> devices = DeviceParser.parse(devicesFile); - assertEquals("Parsing devices_minimal.xml produces the wrong number of devices", 1, - devices.size()); - - Device device = devices.get(0); - assertEquals("Galaxy Nexus", device.getName()); - assertEquals("Samsung", device.getManufacturer()); - - // Test Meta information - Meta meta = device.getMeta(); - assertFalse(meta.hasIconSixtyFour()); - assertFalse(meta.hasIconSixteen()); - assertFalse(meta.hasFrame()); - - // Test Hardware information - Hardware hw = device.getDefaultHardware(); - Screen screen = hw.getScreen(); - assertEquals(screen.getSize(), ScreenSize.NORMAL); - assertEquals(4.65, screen.getDiagonalLength()); - assertEquals(Density.XHIGH, screen.getPixelDensity()); - assertEquals(ScreenRatio.LONG, screen.getRatio()); - assertEquals(720, screen.getXDimension()); - assertEquals(1280, screen.getYDimension()); - assertEquals(316.0, screen.getXdpi()); - assertEquals(316.0, screen.getYdpi()); - assertEquals(Multitouch.JAZZ_HANDS, screen.getMultitouch()); - assertEquals(TouchScreen.FINGER, screen.getMechanism()); - assertEquals(ScreenType.CAPACITIVE, screen.getScreenType()); - Set<Network> networks = hw.getNetworking(); - assertTrue(networks.contains(Network.BLUETOOTH)); - assertTrue(networks.contains(Network.WIFI)); - assertTrue(networks.contains(Network.NFC)); - Set<Sensor> sensors = hw.getSensors(); - assertTrue(sensors.contains(Sensor.ACCELEROMETER)); - assertTrue(sensors.contains(Sensor.BAROMETER)); - assertTrue(sensors.contains(Sensor.GYROSCOPE)); - assertTrue(sensors.contains(Sensor.COMPASS)); - assertTrue(sensors.contains(Sensor.GPS)); - assertTrue(sensors.contains(Sensor.PROXIMITY_SENSOR)); - assertTrue(hw.hasMic()); - assertEquals(2, hw.getCameras().size()); - Camera c = hw.getCamera(CameraLocation.FRONT); - assertTrue(c != null); - assertEquals(c.getLocation(), CameraLocation.FRONT); - assertFalse(c.hasFlash()); - assertTrue(c.hasAutofocus()); - c = hw.getCamera(CameraLocation.BACK); - assertTrue(c != null); - assertEquals(c.getLocation(), CameraLocation.BACK); - assertTrue(c.hasFlash()); - assertTrue(c.hasAutofocus()); - assertEquals(Keyboard.NOKEY, hw.getKeyboard()); - assertEquals(Navigation.NONAV, hw.getNav()); - assertEquals(new Storage(1, Unit.GiB), hw.getRam()); - assertEquals(ButtonType.SOFT, hw.getButtonType()); - List<Storage> storage = hw.getInternalStorage(); - assertEquals(1, storage.size()); - assertEquals(new Storage(16, Unit.GiB), storage.get(0)); - storage = hw.getRemovableStorage(); - assertEquals(0, storage.size()); - assertEquals("OMAP 4460", hw.getCpu()); - assertEquals("PowerVR SGX540", hw.getGpu()); - Set<Abi> abis = hw.getSupportedAbis(); - assertEquals(2, abis.size()); - assertTrue(abis.contains(Abi.ARMEABI)); - assertTrue(abis.contains(Abi.ARMEABI_V7A)); - assertEquals(0, hw.getSupportedUiModes().size()); - assertEquals(PowerType.BATTERY, hw.getChargeType()); - - // Test Software - assertEquals(1, device.getAllSoftware().size()); - Software sw = device.getSoftware(15); - assertEquals(15, sw.getMaxSdkLevel()); - assertEquals(15, sw.getMinSdkLevel()); - assertTrue(sw.hasLiveWallpaperSupport()); - assertEquals(12, sw.getBluetoothProfiles().size()); - assertTrue(sw.getBluetoothProfiles().contains(BluetoothProfile.A2DP)); - assertEquals("2.0", sw.getGlVersion()); - assertEquals(29, sw.getGlExtensions().size()); - assertTrue(sw.getGlExtensions().contains("GL_OES_depth24")); - - // Test States - assertEquals(2, device.getAllStates().size()); - State s = device.getDefaultState(); - assertEquals("Portrait", s.getName()); - assertTrue(s.isDefaultState()); - assertEquals("The phone in portrait view", s.getDescription()); - assertEquals(ScreenOrientation.PORTRAIT, s.getOrientation()); - assertEquals(KeyboardState.SOFT, s.getKeyState()); - assertEquals(NavigationState.HIDDEN, s.getNavState()); - s = device.getState("Landscape"); - assertEquals("Landscape", s.getName()); - assertFalse(s.isDefaultState()); - assertEquals(ScreenOrientation.LANDSCAPE, s.getOrientation()); - } - - public void testApiRange() throws Exception { - Map<String, String> replacements = new HashMap<String, String>(); - replacements.put("api-level", "1-"); - InputStream stream = DeviceSchemaTest.getReplacedStream(replacements); - List<Device> devices = DeviceParser.parse(stream); - assertEquals(1, devices.size()); - Device device = devices.get(0); - assertTrue(device.getSoftware(1) != null); - assertTrue(device.getSoftware(2) != null); - assertTrue(device.getSoftware(0) == null); - replacements.put("api-level", "-2"); - stream = DeviceSchemaTest.getReplacedStream(replacements); - device = DeviceParser.parse(stream).get(0); - assertTrue(device.getSoftware(2) != null); - assertTrue(device.getSoftware(3) == null); - replacements.put("api-level", "1-2"); - stream = DeviceSchemaTest.getReplacedStream(replacements); - device = DeviceParser.parse(stream).get(0); - assertTrue(device.getSoftware(0) == null); - assertTrue(device.getSoftware(1) != null); - assertTrue(device.getSoftware(2) != null); - assertTrue(device.getSoftware(3) == null); - replacements.put("api-level", "-"); - stream = DeviceSchemaTest.getReplacedStream(replacements); - device = DeviceParser.parse(stream).get(0); - assertTrue(device.getSoftware(0) != null); - assertTrue(device.getSoftware(15) != null); - } - - public void testBadNetworking() throws Exception { - Map<String, String> replacements = new HashMap<String, String>(); - replacements.put("networking", "NFD"); - InputStream stream = DeviceSchemaTest.getReplacedStream(replacements); - try { - List<Device> devices = DeviceParser.parse(stream); - assertEquals(1, devices.size()); - assertEquals(0, devices.get(0).getDefaultHardware().getNetworking().size()); - fail(); - } catch (SAXParseException e) { - assertTrue(e.getMessage().startsWith("cvc-enumeration-valid: Value 'NFD'")); - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/devices/DeviceWriterTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/devices/DeviceWriterTest.java deleted file mode 100644 index 2b8474e..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/devices/DeviceWriterTest.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.devices; - -import com.android.dvlib.DeviceSchemaTest; - -import junit.framework.TestCase; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class DeviceWriterTest extends TestCase { - - public void testWriteIsValid() throws Exception { - InputStream devicesFile = - DeviceSchemaTest.class.getResourceAsStream("devices.xml"); - List<Device> devices = DeviceParser.parse(devicesFile); - assertEquals("Parsed devices contained an un expected number of devices", - 2, devices.size()); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceWriter.writeToXml(baos, devices); - List<Device> writtenDevices = DeviceParser.parse( - new ByteArrayInputStream(baos.toString().getBytes())); - assertEquals("Writing and reparsing returns a different number of devices", - devices.size(), writtenDevices.size()); - for (int i = 0; i < devices.size(); i++){ - assertEquals(devices.get(i), writtenDevices.get(i)); - } - } - - public void testApiLowerBound() throws Exception { - Map<String, String> replacements = new HashMap<String, String>(); - replacements.put("api-level", "1-"); - InputStream stream = DeviceSchemaTest.getReplacedStream(replacements); - List<Device> devices = DeviceParser.parse(stream); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceWriter.writeToXml(baos, devices); - List<Device> writtenDevices = DeviceParser.parse( - new ByteArrayInputStream(baos.toString().getBytes())); - assertEquals("Writing and reparsing returns a different number of devices", - devices.size(), writtenDevices.size()); - for (int i = 0; i < devices.size(); i++){ - assertEquals(devices.get(i), writtenDevices.get(i)); - } - } - - public void testApiUpperBound() throws Exception { - Map<String, String> replacements = new HashMap<String, String>(); - replacements.put("api-level", "-10"); - InputStream stream = DeviceSchemaTest.getReplacedStream(replacements); - List<Device> devices = DeviceParser.parse(stream); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceWriter.writeToXml(baos, devices); - List<Device> writtenDevices = DeviceParser.parse( - new ByteArrayInputStream(baos.toString().getBytes())); - assertEquals("Writing and reparsing returns a different number of devices", - devices.size(), writtenDevices.size()); - for (int i = 0; i < devices.size(); i++){ - assertEquals(devices.get(i), writtenDevices.get(i)); - } - } - - public void testApiNeitherBound() throws Exception { - Map<String, String> replacements = new HashMap<String, String>(); - replacements.put("api-level", "-"); - InputStream stream = DeviceSchemaTest.getReplacedStream(replacements); - List<Device> devices = DeviceParser.parse(stream); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceWriter.writeToXml(baos, devices); - List<Device> writtenDevices = DeviceParser.parse( - new ByteArrayInputStream(baos.toString().getBytes())); - assertEquals("Writing and reparsing returns a different number of devices", - devices.size(), writtenDevices.size()); - for (int i = 0; i < devices.size(); i++){ - assertEquals(devices.get(i), writtenDevices.get(i)); - } - } - - public void testApiBothBound() throws Exception { - Map<String, String> replacements = new HashMap<String, String>(); - replacements.put("api-level", "9-10"); - InputStream stream = DeviceSchemaTest.getReplacedStream(replacements); - List<Device> devices = DeviceParser.parse(stream); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceWriter.writeToXml(baos, devices); - List<Device> writtenDevices = DeviceParser.parse( - new ByteArrayInputStream(baos.toString().getBytes())); - assertEquals("Writing and reparsing returns a different number of devices", - devices.size(), writtenDevices.size()); - for (int i = 0; i < devices.size(); i++){ - assertEquals(devices.get(i), writtenDevices.get(i)); - } - } - public void testApiSingle() throws Exception { - Map<String, String> replacements = new HashMap<String, String>(); - replacements.put("api-level", "10"); - InputStream stream = DeviceSchemaTest.getReplacedStream(replacements); - List<Device> devices = DeviceParser.parse(stream); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceWriter.writeToXml(baos, devices); - List<Device> writtenDevices = DeviceParser.parse( - new ByteArrayInputStream(baos.toString().getBytes())); - assertEquals("Writing and reparsing returns a different number of devices", - devices.size(), writtenDevices.size()); - for (int i = 0; i < devices.size(); i++){ - assertEquals(devices.get(i), writtenDevices.get(i)); - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/build/DebugKeyProviderTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/build/DebugKeyProviderTest.java deleted file mode 100755 index ead66ee..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/build/DebugKeyProviderTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.build; - -import com.android.sdklib.internal.build.DebugKeyProvider.IKeyGenOutput; - -import java.io.File; -import java.security.PrivateKey; -import java.security.cert.X509Certificate; -import java.util.Calendar; - -import junit.framework.TestCase; - -public class DebugKeyProviderTest extends TestCase { - - private File mTmpFile; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - // We want to allocate a new tmp file but not have it actually exist - mTmpFile = File.createTempFile(this.getClass().getSimpleName(), ".keystore"); - assertTrue(mTmpFile.delete()); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - if (mTmpFile != null) { - if (!mTmpFile.delete()) { - mTmpFile.deleteOnExit(); - } - mTmpFile = null; - } - } - - public void testCreateAndCheckKey() throws Exception { - String osPath = mTmpFile.getAbsolutePath(); - - KeygenOutput keygenOutput = new KeygenOutput(); - - // "now" is just slightly before the key was created - long now = System.currentTimeMillis(); - - DebugKeyProvider provider; - try { - provider = new DebugKeyProvider(osPath, null /*storeType*/, keygenOutput); - } catch (Throwable t) { - // In case we get any kind of exception, rewrap it to make sure we output - // the path used. - String msg = String.format("%1$s in %2$s\n%3$s", - t.getClass().getSimpleName(), osPath, t.toString()); - throw new Exception(msg, t); - } - assertNotNull(provider); - - assertEquals("", keygenOutput.getOut()); - assertEquals("", keygenOutput.getErr()); - - PrivateKey key = provider.getDebugKey(); - assertNotNull(key); - - X509Certificate certificate = (X509Certificate) provider.getCertificate(); - assertNotNull(certificate); - - // The "not-after" (a.k.a. expiration) date should be after "now" - Calendar c = Calendar.getInstance(); - c.setTimeInMillis(now); - assertTrue(certificate.getNotAfter().compareTo(c.getTime()) > 0); - - // It should be valid after 1 year from now (adjust by a second since the 'now' time - // doesn't exactly match the creation time... 1 second should be enough.) - c.add(Calendar.DAY_OF_YEAR, 365); - c.add(Calendar.SECOND, -1); - assertTrue("1 year expiration failed", - certificate.getNotAfter().compareTo(c.getTime()) > 0); - - // and 30 years from now - c.add(Calendar.DAY_OF_YEAR, 29 * 365); - assertTrue("30 year expiration failed", - certificate.getNotAfter().compareTo(c.getTime()) > 0); - - // however expiration date should be passed in 30 years + 1 hour - c.add(Calendar.HOUR, 1); - assertFalse("30 year and 1 hour expiration failed", - certificate.getNotAfter().compareTo(c.getTime()) > 0); - } - - private static class KeygenOutput implements IKeyGenOutput { - private String mOut = ""; //$NON-NLS-1$ - private String mErr = ""; //$NON-NLS-1$ - - @Override - public void out(String message) { - mOut += message + "\n"; //$NON-NLS-1$ - } - - @Override - public void err(String message) { - mErr += message + "\n"; //$NON-NLS-1$ - } - - public String getOut() { - return mOut; - } - - public String getErr() { - return mErr; - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java deleted file mode 100755 index f62533d..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/AddonsListFetcherTest.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.sdklib.internal.repository.AddonsListFetcher.Site; -import com.android.sdklib.repository.SdkAddonsListConstants; - -import org.w3c.dom.Document; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -import junit.framework.TestCase; - -/** - * Tests for {@link AddonsListFetcher} - */ -public class AddonsListFetcherTest extends TestCase { - - /** - * An internal helper class to give us visibility to the protected members we want - * to test. - */ - private static class MockAddonsListFetcher extends AddonsListFetcher { - - public Site[] _parseAddonsList(Document doc, - String nsUri, - String baseUrl, - ITaskMonitor monitor) { - return super.parseAddonsList(doc, nsUri, baseUrl, monitor); - } - - public int _getXmlSchemaVersion(InputStream xml) { - return super.getXmlSchemaVersion(xml); - } - - public String _validateXml(InputStream xml, - String url, - int version, - String[] outError, - Boolean[] validatorFound) { - return super.validateXml(xml, url, version, outError, validatorFound); - } - - public Document _getDocument(InputStream xml, ITaskMonitor monitor) { - return super.getDocument(xml, monitor); - } - - } - - private MockAddonsListFetcher mFetcher; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mFetcher = new MockAddonsListFetcher(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - mFetcher = null; - } - - /** - * Validate we can load a valid addon schema version 1 - */ - public void testLoadSample_1() throws Exception { - InputStream xmlStream = - getTestResource("/com/android/sdklib/testdata/addons_list_sample_1.xml"); - - // guess the version from the XML document - int version = mFetcher._getXmlSchemaVersion(xmlStream); - assertEquals(1, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://addons_list.xml"; - - String uri = mFetcher._validateXml( - xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkAddonsListConstants.getSchemaUri(1), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mFetcher._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the sites - Site[] result = mFetcher._parseAddonsList(doc, uri, "http://base/url/", monitor); - - assertEquals("", monitor.getCapturedDescriptions()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - assertEquals("", monitor.getCapturedVerboseLog()); - - // check the sites we found... - // The XML file is UTF-8 so we support character sets (but the Java source file is - // not, so we use the \\u notation to create the Unicode String) - assertEquals( - "[<ADDON_SITE URL='http://www.example.com/my_addons.xml' Name='My Example Add-ons.'>, " + - "<ADDON_SITE URL='http://www.example.co.jp/addons.xml' Name='\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002'>, " + - "<ADDON_SITE URL='http://www.example.com/' Name='Example of directory URL.'>, " + - "<ADDON_SITE URL='http://base/url/relative_url.xml' Name='Relative URL.'>]", - Arrays.toString(result)); - assertEquals(4, result.length); - } - - /** - * Validate we can load a valid addon schema version 2 - */ - public void testLoadSample_2() throws Exception { - InputStream xmlStream = - getTestResource("/com/android/sdklib/testdata/addons_list_sample_2.xml"); - - // guess the version from the XML document - int version = mFetcher._getXmlSchemaVersion(xmlStream); - assertEquals(2, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://addons_list.xml"; - - String uri = mFetcher._validateXml( - xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkAddonsListConstants.getSchemaUri(2), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mFetcher._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the sites - Site[] result = mFetcher._parseAddonsList(doc, uri, "http://base/url/", monitor); - - assertEquals("", monitor.getCapturedDescriptions()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - assertEquals("", monitor.getCapturedVerboseLog()); - - // check the sites we found... - // The XML file is UTF-8 so we support character sets (but the Java source file is - // not, so we use the \\u notation to create the Unicode String) - assertEquals( - "[<ADDON_SITE URL='http://www.example.com/my_addons.xml' Name='My Example Add-ons.'>, " + - "<ADDON_SITE URL='http://www.example.co.jp/addons.xml' Name='\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002'>, " + - "<ADDON_SITE URL='http://www.example.com/' Name='Example of directory URL.'>, " + - "<SYS_IMG_SITE URL='http://www.example.com/' Name='Example of sys-img URL using the default xml filename.'>, " + - "<SYS_IMG_SITE URL='http://www.example.com/specific_file.xml' Name='Example of sys-img URL using a specific xml filename.'>, " + - "<ADDON_SITE URL='http://base/url/relative/url.xml' Name='Relative URL.'>]", - Arrays.toString(result)); - assertEquals(6, result.length); - } - - // IMPORTANT: Each time you add a test here for a new version, you should - // also add a test in ValidateAddonsListXmlTest. - - /** - * Returns an SdkLib file resource as a {@link ByteArrayInputStream}, - * which has the advantage that we can use {@link InputStream#reset()} on it - * at any time to read it multiple times. - * <p/> - * The default for getResourceAsStream() is to return a {@link FileInputStream} that - * does not support reset(), yet we need it in the tested code. - * - * @throws IOException if some I/O read fails - */ - private ByteArrayInputStream getTestResource(String filename) throws IOException { - InputStream xmlStream = this.getClass().getResourceAsStream(filename); - - try { - byte[] data = new byte[8192]; - int offset = 0; - int n; - - while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) { - offset += n; - - if (offset == data.length) { - byte[] newData = new byte[offset + 8192]; - System.arraycopy(data, 0, newData, 0, offset); - data = newData; - } - } - - return new ByteArrayInputStream(data, 0, offset); - } finally { - if (xmlStream != null) { - xmlStream.close(); - } - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/LocalSdkParserTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/LocalSdkParserTest.java deleted file mode 100755 index 4989ec3..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/LocalSdkParserTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.SdkConstants; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISystemImage.LocationType; -import com.android.sdklib.SdkManager; -import com.android.sdklib.SdkManagerTestCase; -import com.android.sdklib.SystemImage; - -import java.util.Arrays; - -public class LocalSdkParserTest extends SdkManagerTestCase { - - public void testLocalSdkParser_SystemImages() throws Exception { - SdkManager sdkman = getSdkManager(); - LocalSdkParser parser = new LocalSdkParser(); - MockMonitor monitor = new MockMonitor(); - - // By default SdkManagerTestCase creates an SDK with one platform containing - // a legacy armeabi system image (this is not a separate system image package) - - assertEquals( - "[Android SDK Tools, revision 0, " + - "SDK Platform Android 0.0, API 0, revision 1, " + - "Sources for Android SDK, API 0, revision 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), sdkman, monitor))); - - assertEquals( - "[SDK Platform Android 0.0, API 0, revision 1, " + - "Sources for Android SDK, API 0, revision 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), - sdkman, - LocalSdkParser.PARSE_PLATFORMS | LocalSdkParser.PARSE_SOURCES, - monitor))); - - assertEquals( - "[SDK Platform Android 0.0, API 0, revision 1]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), - sdkman, - LocalSdkParser.PARSE_PLATFORMS, - monitor))); - - assertEquals( - "[Sources for Android SDK, API 0, revision 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), - sdkman, - LocalSdkParser.PARSE_SOURCES, - monitor))); - - assertEquals( - "[Android SDK Tools, revision 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), - sdkman, - LocalSdkParser.PARSE_TOOLS, - monitor))); - - // Now add a few "platform subfolders" system images and reload the SDK. - // This disables the "legacy" mode but it still doesn't create any system image package - - IAndroidTarget t = sdkman.getTargets()[0]; - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_PLATFORM_SUBFOLDER, SdkConstants.ABI_ARMEABI_V7A)); - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_PLATFORM_SUBFOLDER, SdkConstants.ABI_INTEL_ATOM)); - - sdkman.reloadSdk(getLog()); - t = sdkman.getTargets()[0]; - - assertEquals( - "[Android SDK Tools, revision 0, " + - "SDK Platform Android 0.0, API 0, revision 1, " + - "Sources for Android SDK, API 0, revision 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), sdkman, monitor))); - - // Now add arm + arm v7a images using the new SDK/system-images. - // The local parser will find the 2 system image packages which are associated - // with the PlatformTarger in the SdkManager. - - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_SYSTEM_IMAGE, SdkConstants.ABI_ARMEABI)); - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_SYSTEM_IMAGE, SdkConstants.ABI_ARMEABI_V7A)); - - sdkman.reloadSdk(getLog()); - - assertEquals( - "[Android SDK Tools, revision 0, " + - "SDK Platform Android 0.0, API 0, revision 1, " + - "ARM EABI v7a System Image, Android API 0, revision 0, " + - "ARM EABI System Image, Android API 0, revision 0, " + - "Sources for Android SDK, API 0, revision 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), sdkman, monitor))); - - // Now add an x86 image using the new SDK/system-images. - // Now this time we do NOT reload the SdkManager instance. Instead the parser - // will find an unused system image and load it as a "broken package". - - makeSystemImageFolder(new SystemImage( - sdkman, t, LocationType.IN_SYSTEM_IMAGE, SdkConstants.ABI_INTEL_ATOM)); - - assertEquals( - "[Android SDK Tools, revision 0, " + - "SDK Platform Android 0.0, API 0, revision 1, " + - "ARM EABI v7a System Image, Android API 0, revision 0, " + - "ARM EABI System Image, Android API 0, revision 0, " + - "Sources for Android SDK, API 0, revision 0, " + - "Broken Intel x86 Atom System Image, API 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), sdkman, monitor))); - - assertEquals( - "[Android SDK Tools, revision 0, " + - "SDK Platform Android 0.0, API 0, revision 1, " + - "ARM EABI v7a System Image, Android API 0, revision 0, " + - "ARM EABI System Image, Android API 0, revision 0, " + - "Sources for Android SDK, API 0, revision 0, " + - "Broken Intel x86 Atom System Image, API 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), - sdkman, - LocalSdkParser.PARSE_ALL, - monitor))); - - assertEquals( - "[SDK Platform Android 0.0, API 0, revision 1, " + - "ARM EABI v7a System Image, Android API 0, revision 0, " + - "ARM EABI System Image, Android API 0, revision 0, " + - "Sources for Android SDK, API 0, revision 0, " + - "Broken Intel x86 Atom System Image, API 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), - sdkman, - LocalSdkParser.PARSE_PLATFORMS | // platform also loads system-images - LocalSdkParser.PARSE_SOURCES, - monitor))); - - assertEquals( - "[Sources for Android SDK, API 0, revision 0]", - Arrays.toString(parser.parseSdk(sdkman.getLocation(), - sdkman, - LocalSdkParser.PARSE_SOURCES, - monitor))); - } - -} - diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockEmptySdkManager.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockEmptySdkManager.java deleted file mode 100755 index be1fb29..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockEmptySdkManager.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.SdkManager; - -/** - * An invalid SDK Manager, just good enough to avoid passing a null reference. - */ -public class MockEmptySdkManager extends SdkManager { - public MockEmptySdkManager(String osSdkPath) { - super(osSdkPath); - setTargets(new IAndroidTarget[0]); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockMonitor.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockMonitor.java deleted file mode 100755 index 72e7d93..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockMonitor.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.annotations.NonNull; - -/** - * Mock implementation of {@link ITaskMonitor} that simply captures - * the output in local strings. Does not provide any UI and has no - * support for creating sub-monitors. - */ -public class MockMonitor implements ITaskMonitor { - - String mCapturedLog = ""; //$NON-NLS-1$ - String mCapturedErrorLog = ""; //$NON-NLS-1$ - String mCapturedVerboseLog = ""; //$NON-NLS-1$ - String mCapturedDescriptions = ""; //$NON-NLS-1$ - - public String getCapturedLog() { - return mCapturedLog; - } - - public String getCapturedErrorLog() { - return mCapturedErrorLog; - } - - public String getCapturedVerboseLog() { - return mCapturedVerboseLog; - } - - public String getCapturedDescriptions() { - return mCapturedDescriptions; - } - - @Override - public void log(String format, Object... args) { - mCapturedLog += String.format(format, args) + "\n"; //$NON-NLS-1$ - } - - @Override - public void logError(String format, Object... args) { - mCapturedErrorLog += String.format(format, args) + "\n"; //$NON-NLS-1$ - } - - @Override - public void logVerbose(String format, Object... args) { - mCapturedVerboseLog += String.format(format, args) + "\n"; //$NON-NLS-1$ - } - - @Override - public void setProgressMax(int max) { - } - - @Override - public int getProgressMax() { - return 0; - } - - @Override - public void setDescription(String format, Object... args) { - mCapturedDescriptions += String.format(format, args) + "\n"; //$NON-NLS-1$ - } - - @Override - public boolean isCancelRequested() { - return false; - } - - @Override - public void incProgress(int delta) { - } - - @Override - public int getProgress() { - return 0; - } - - @Override - public boolean displayPrompt(String title, String message) { - return false; - } - - @Override - public ITaskMonitor createSubMonitor(int tickCount) { - return null; - } - - @Override - public void error(Throwable t, String errorFormat, Object... args) { - } - - @Override - public void info(@NonNull String msgFormat, Object... args) { - } - - @Override - public void verbose(@NonNull String msgFormat, Object... args) { - } - - @Override - public void warning(@NonNull String warningFormat, Object... args) { - } - - @Override - public UserCredentials displayLoginCredentialsPrompt(String title, String message) { - return null; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockPlatformTarget.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockPlatformTarget.java deleted file mode 100755 index 1d9bb7b..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/MockPlatformTarget.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.SdkConstants; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISystemImage; -import com.android.sdklib.ISystemImage.LocationType; -import com.android.sdklib.SystemImage; -import com.android.sdklib.io.FileOp; - -import java.util.Map; - -/** - * A mock PlatformTarget. - * This reimplements the minimum needed from the interface for our limited testing needs. - */ -public class MockPlatformTarget implements IAndroidTarget { - - private final int mApiLevel; - private final int mRevision; - private ISystemImage[] mSystemImages; - - public MockPlatformTarget(int apiLevel, int revision) { - mApiLevel = apiLevel; - mRevision = revision; - } - - @Override - public String getClasspathName() { - return getName(); - } - - @Override - public String getShortClasspathName() { - return getName(); - } - - @Override - public String getDefaultSkin() { - return null; - } - - @Override - public String getDescription() { - return getName(); - } - - @Override - public String getFullName() { - return getName(); - } - - @Override - public ISystemImage[] getSystemImages() { - if (mSystemImages == null) { - SystemImage si = new SystemImage( - FileOp.append(getLocation(), SdkConstants.OS_IMAGES_FOLDER), - LocationType.IN_PLATFORM_LEGACY, - SdkConstants.ABI_ARMEABI); - mSystemImages = new SystemImage[] { si }; - } - return mSystemImages; - } - - @Override - public ISystemImage getSystemImage(String abiType) { - if (SdkConstants.ABI_ARMEABI.equals(abiType)) { - return getSystemImages()[0]; - } - return null; - } - - @Override - public String getLocation() { - return "/sdk/platforms/android-" + getVersion().getApiString(); - } - - @Override - public IOptionalLibrary[] getOptionalLibraries() { - return null; - } - - @Override - public IAndroidTarget getParent() { - return null; - } - - @Override - public String getPath(int pathId) { - throw new UnsupportedOperationException("Implement this as needed for tests"); - } - - @Override - public String[] getPlatformLibraries() { - return null; - } - - @Override - public String getProperty(String name) { - return null; - } - - @Override - public Integer getProperty(String name, Integer defaultValue) { - return defaultValue; - } - - @Override - public Boolean getProperty(String name, Boolean defaultValue) { - return defaultValue; - } - - @Override - public Map<String, String> getProperties() { - return null; - } - - @Override - public int getRevision() { - return mRevision; - } - - @Override - public String[] getSkins() { - return null; - } - - @Override - public int getUsbVendorId() { - return 0; - } - - /** - * Returns a vendor that depends on the parent *platform* API. - * This works well in Unit Tests where we'll typically have different - * platforms as unique identifiers. - */ - @Override - public String getVendor() { - return "vendor " + Integer.toString(mApiLevel); - } - - /** - * Create a synthetic name using the target API level. - */ - @Override - public String getName() { - return "platform r" + Integer.toString(mApiLevel); - } - - @Override - public AndroidVersion getVersion() { - return new AndroidVersion(mApiLevel, null /*codename*/); - } - - @Override - public String getVersionName() { - return String.format("android-%1$d", mApiLevel); - } - - @Override - public String hashString() { - return getVersionName(); - } - - /** Returns true for a platform. */ - @Override - public boolean isPlatform() { - return true; - } - - @Override - public boolean canRunOn(IAndroidTarget target) { - throw new UnsupportedOperationException("Implement this as needed for tests"); - } - - @Override - public int compareTo(IAndroidTarget o) { - throw new UnsupportedOperationException("Implement this as needed for tests"); - } - - @Override - public boolean hasRenderingLibrary() { - return false; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/SdkStatsTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/SdkStatsTest.java deleted file mode 100755 index baff6f9..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/SdkStatsTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository; - -import com.android.sdklib.internal.repository.SdkStats.PlatformStat; -import com.android.sdklib.repository.SdkStatsConstants; -import com.android.sdklib.util.SparseArray; - -import org.w3c.dom.Document; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -import junit.framework.TestCase; - -/** - * Tests for {@link SdkStats} - */ -public class SdkStatsTest extends TestCase { - - /** - * An internal helper class to give us visibility to the protected members we want - * to test. - */ - private static class MockSdkStats extends SdkStats { - - public SparseArray<PlatformStat> _parseStatsDocument(Document doc, - String nsUri, - ITaskMonitor monitor) { - return super.parseStatsDocument(doc, nsUri, monitor); - } - - public int _getXmlSchemaVersion(InputStream xml) { - return super.getXmlSchemaVersion(xml); - } - - public String _validateXml(InputStream xml, String url, int version, - String[] outError, Boolean[] validatorFound) { - return super.validateXml(xml, url, version, outError, validatorFound); - } - - public Document _getDocument(InputStream xml, ITaskMonitor monitor) { - return super.getDocument(xml, monitor); - } - - } - - private MockSdkStats mStats; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mStats = new MockSdkStats(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - mStats = null; - } - - /** - * Validate we can still load a valid addon schema version 1 - */ - public void testLoadSample_1() throws Exception { - InputStream xmlStream = - getTestResource("/com/android/sdklib/testdata/stats_sample_1.xml"); - - // guess the version from the XML document - int version = mStats._getXmlSchemaVersion(xmlStream); - assertEquals(1, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://stats.xml"; - - String uri = mStats._validateXml( - xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkStatsConstants.getSchemaUri(1), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mStats._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the sites - SparseArray<PlatformStat> result = mStats._parseStatsDocument(doc, uri, monitor); - - assertEquals("", monitor.getCapturedDescriptions()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - assertEquals("", monitor.getCapturedVerboseLog()); - - // check what we found - assertEquals(3, result.size()); - int len = result.size(); - - int[] keys = new int[len]; - PlatformStat[] stats = new PlatformStat[len]; - for (int i = 0; i < len; i++) { - keys[i] = result.keyAt(i); - stats[i] = result.valueAt(i); - } - - assertEquals( - "[3, 5, 42]", - Arrays.toString(keys)); - - assertEquals( - "[<Stat api=3, code=Vanilla, vers=Android 0.5, share=0.1%, accum=100.0%>, " + - "<Stat api=5, code=Coffee, vers=Android 42.0, share=25.8%, accum=99.9%>, " + - "<Stat api=42, code=Chocolate, vers=Android 32.64, share=74.1%, accum=74.1%>]", - Arrays.toString(stats)); - } - - /** - * Returns an SdkLib file resource as a {@link ByteArrayInputStream}, - * which has the advantage that we can use {@link InputStream#reset()} on it - * at any time to read it multiple times. - * <p/> - * The default for getResourceAsStream() is to return a {@link FileInputStream} that - * does not support reset(), yet we need it in the tested code. - * - * @throws IOException if some I/O read fails - */ - private ByteArrayInputStream getTestResource(String filename) throws IOException { - InputStream xmlStream = this.getClass().getResourceAsStream(filename); - - try { - byte[] data = new byte[8192]; - int offset = 0; - int n; - - while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) { - offset += n; - - if (offset == data.length) { - byte[] newData = new byte[offset + 8192]; - System.arraycopy(data, 0, newData, 0, offset); - data = newData; - } - } - - return new ByteArrayInputStream(data, 0, offset); - } finally { - if (xmlStream != null) { - xmlStream.close(); - } - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/archives/ArchiveInstallerTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/archives/ArchiveInstallerTest.java deleted file mode 100755 index b0b3f03..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/archives/ArchiveInstallerTest.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.archives; - -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.MockEmptySdkManager; -import com.android.sdklib.internal.repository.MockMonitor; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.MockEmptyPackage; -import com.android.sdklib.internal.repository.packages.MockExtraPackage; -import com.android.sdklib.internal.repository.sources.SdkRepoSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.io.IFileOp; -import com.android.sdklib.io.MockFileOp; -import com.android.sdklib.repository.PkgProps; -import com.android.utils.Pair; - -import java.io.File; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Pattern; - -import junit.framework.TestCase; - -/** - * Unit tests for {@link ArchiveInstaller}. - */ -public class ArchiveInstallerTest extends TestCase { - - private MockMonitor mMon; - private String mSdkRoot; - private MockFileOp mFile; - private MockArchiveInstaller mArchInst; - private MockEmptySdkManager mSdkMan; - - private class MockArchiveInstaller extends ArchiveInstaller { - - private Map<Archive, File> mDownloadMap = new HashMap<Archive, File>(); - - public MockArchiveInstaller(IFileOp fileUtils) { - super(fileUtils); - } - - public void setDownloadResponse(Archive archive, File response) { - mDownloadMap.put(archive, response); - } - - @Override - protected Pair<File, File> downloadFile( - Archive archive, - String osSdkRoot, - DownloadCache cache, - ITaskMonitor monitor, - boolean forceHttp) { - File file = mDownloadMap.get(archive); - // register the file as "created" - ArchiveInstallerTest.this.mFile.recordExistingFile(file); - return Pair.of(file, null); - } - - @Override - protected boolean unzipFolder( - ArchiveReplacement archiveInfo, - File archiveFile, - File unzipDestFolder, - ITaskMonitor monitor) { - // Claim the unzip works if the input archiveFile is one we know about - // and the destination actually exists. - - if (getFileOp().isDirectory(unzipDestFolder) && - mDownloadMap.values().contains(archiveFile)) { - return true; - } - - return false; - } - - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - mFile = new MockFileOp(); - mArchInst = new MockArchiveInstaller(mFile); - mSdkRoot = "/sdk"; - mSdkMan = new MockEmptySdkManager(mSdkRoot); - mMon = new MockMonitor(); - } - - // ---- - - /** Test we don't try to install a local archive. */ - public void testInstall_SkipLocalArchive() throws Exception { - MockEmptyPackage p = new MockEmptyPackage("testPkg"); - ArchiveReplacement ar = new ArchiveReplacement(p.getArchives()[0], null /*replaced*/); - - assertFalse(mArchInst.install(ar, mSdkRoot, false /*forceHttp*/, mSdkMan, - null /*UrlCache*/, mMon)); - assertTrue(mMon.getCapturedLog().indexOf("Skipping already installed archive") != -1); - } - - /** Test we can install a simple new archive. */ - public void testInstall_NewArchive() throws Exception { - SdkSource src1 = new SdkRepoSource("http://repo.example.com/url", "repo1"); - MockEmptyPackage p = createRemoteEmptyPackage(src1, "testPkg"); - ArchiveReplacement ar = new ArchiveReplacement(p.getArchives()[0], null /*replaced*/); - - // associate the File that will be "downloaded" for this archive - mArchInst.setDownloadResponse( - p.getArchives()[0], createFile("/sdk", "tmp", "download1.zip")); - - assertTrue(mArchInst.install(ar, mSdkRoot, false /*forceHttp*/, mSdkMan, - null /*UrlCache*/, mMon)); - - // check what was created - assertEquals( - "[/sdk/mock/testPkg/source.properties]", - Arrays.toString(mFile.getExistingFiles())); - - assertEquals( - "[/, /sdk, /sdk/mock, /sdk/mock/testPkg]", - Arrays.toString(mFile.getExistingFolders())); - - assertEquals( - "[</sdk/mock/testPkg/source.properties: '### Android Tool: Source of this archive.\n" + - "#...date...\n" + - "Archive.Os=ANY\n" + - "Pkg.Revision=0\n" + - "Archive.Arch=ANY\n" + - "Pkg.SourceUrl=http\\://repo.example.com/url\n" + - "'>]", - stripDate(Arrays.toString(mFile.getOutputStreams()))); - - assertEquals( - "Installing 'testPkg'\n" + - "Installed 'testPkg'\n", - mMon.getCapturedLog()); - } - - /** Test we can replace and rename an Extra package. */ - public void testInstall_InstallExtraArchive() throws Exception { - SdkSource src1 = new SdkRepoSource("http://repo.example.com/url", "repo1"); - - MockExtraPackage newPkg = createRemoteExtraPackage(src1, "vendor1", "oldPath", 2, 1); - MockExtraPackage oldPkg = new MockExtraPackage(src1, "vendor1", "oldPath", 1, 1); - - // old pkg is installed, so its directory & files exists - mFile.recordExistingFile("/sdk/extras/vendor1/oldPath/source.properties"); - mFile.recordExistingFolder("/sdk/extras/vendor1/oldPath"); - - ArchiveReplacement ar = new ArchiveReplacement( - newPkg.getArchives()[0], - oldPkg.getArchives()[0]); - - // associate the File that will be "downloaded" for this archive - mArchInst.setDownloadResponse( - newPkg.getArchives()[0], createFile("/sdk", "tmp", "download1.zip")); - - assertTrue(mArchInst.install(ar, mSdkRoot, false /*forceHttp*/, mSdkMan, - null /*UrlCache*/, mMon)); - - // check what was created - assertEquals( - "[/sdk/extras/vendor1/oldPath/source.properties]", - Arrays.toString(mFile.getExistingFiles())); - - // This created the /sdk/temp folder to put the oldPath package whilst we unzipped - // the new one. The oldPath dir was then cleaned up but we still leave the root - // temp dir around. - assertEquals( - "[/, /sdk, /sdk/extras, /sdk/extras/vendor1, /sdk/extras/vendor1/oldPath, /sdk/temp]", - Arrays.toString(mFile.getExistingFolders())); - - assertEquals( - ( - "[</sdk/extras/vendor1/oldPath/source.properties: " + - "'### Android Tool: Source of this archive.\n" + - "#...date...\n" + - "Extra.VendorDisplay=vendor1\n" + - "Pkg.Desc=desc\n" + - "Extra.Path=oldPath\n" + - "Archive.Arch=ANY\n" + - "Pkg.DescUrl=url\n" + - "Extra.NameDisplay=Vendor1 OldPath\n" + - "Archive.Os=ANY\n" + - "Pkg.SourceUrl=http\\://repo.example.com/url\n" + - "Pkg.Revision=2\n" + - "Extra.VendorId=vendor1\n" + - "'>]"), - stripDate(Arrays.toString(mFile.getOutputStreams()))); - - assertEquals( - "Installing Vendor1 OldPath, revision 2\n" + - "Installed Vendor1 OldPath, revision 2\n", - mMon.getCapturedLog()); - } - - /** Test we can replace and rename an Extra package. */ - public void testInstall_InstallRenamedExtraArchive() throws Exception { - SdkSource src1 = new SdkRepoSource("http://repo.example.com/url", "repo1"); - - MockExtraPackage newPkg = createRemoteExtraPackage( - src1, - "vendor1", - "newPath", - "oldPath", - 2, // revision - 1); // min_platform_tools_rev - ExtraPackage oldPkg = (ExtraPackage) ExtraPackage.create( - src1, // source - null, // props - "vendor1", // vendor - "oldPath", // path - 1, // revision - null, // license - null, // description - null, // descUrl - Os.ANY, // archiveOs - Arch.ANY, // archiveArch - "/sdk/extras/vendor1/oldPath" // archiveOsPath - ); - - // old pkg is installed, so its directory & files exists - mFile.recordExistingFile("/sdk/extras/vendor1/oldPath/source.properties"); - mFile.recordExistingFolder("/sdk/extras/vendor1/oldPath"); - - ArchiveReplacement ar = new ArchiveReplacement( - newPkg.getArchives()[0], - oldPkg.getArchives()[0]); - - // associate the File that will be "downloaded" for this archive - mArchInst.setDownloadResponse( - newPkg.getArchives()[0], createFile("/sdk", "tmp", "download1.zip")); - - assertTrue(mArchInst.install(ar, mSdkRoot, false /*forceHttp*/, mSdkMan, - null /*UrlCache*/, mMon)); - - // check what was created - assertEquals( - "[/sdk/extras/vendor1/newPath/source.properties]", - Arrays.toString(mFile.getExistingFiles())); - - // oldPath directory has been deleted, we only have newPath now. - // No sdk/temp dir was created since we didn't have to move the old package dir out - // of the way. - assertEquals( - "[/, /sdk, /sdk/extras, /sdk/extras/vendor1, /sdk/extras/vendor1/newPath]", - Arrays.toString(mFile.getExistingFolders())); - - assertEquals( - ( - "[</sdk/extras/vendor1/newPath/source.properties: " + - "'### Android Tool: Source of this archive.\n" + - "#...date...\n" + - "Extra.VendorDisplay=vendor1\n" + - "Pkg.Desc=desc\n" + - "Extra.OldPaths=oldPath\n" + - "Extra.Path=newPath\n" + - "Archive.Arch=ANY\n" + - "Pkg.DescUrl=url\n" + - "Extra.NameDisplay=Vendor1 NewPath\n" + - "Archive.Os=ANY\n" + - "Pkg.SourceUrl=http\\://repo.example.com/url\n" + - "Pkg.Revision=2\n" + - "Extra.VendorId=vendor1\n" + - "'>]"), - stripDate(Arrays.toString(mFile.getOutputStreams()))); - - assertEquals( - "Installing Vendor1 NewPath, revision 2\n" + - "Installed Vendor1 NewPath, revision 2\n", - mMon.getCapturedLog()); - } - - // ---- - - /** - * Helper creator method to create a {@link MockEmptyPackage} with no local - * archive associated. - */ - private static MockEmptyPackage createRemoteEmptyPackage(SdkSource source, String testHandle) { - return new MockEmptyPackage(source, testHandle, 0 /*revision*/) { - @Override - protected Archive[] initializeArchives( - Properties props, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - // Create one remote archive for this package - return new Archive[] { - new Archive( - this, - Os.ANY, - Arch.ANY, - "http://some.source/some_url", - 1234, // size - "abcdef") // sha1 - }; - } - }; - } - - /** - * Helper creator method to create a {@link MockExtraPackage} with no local - * archive associated. - */ - private static MockExtraPackage createRemoteExtraPackage( - SdkSource source, - String vendor, - String path, - int revision, - int min_platform_tools_rev) { - return new MockExtraPackage(source, vendor, path, revision, min_platform_tools_rev) { - @Override - protected Archive[] initializeArchives( - Properties props, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - // Create one remote archive for this package - return new Archive[] { - new Archive( - this, - Os.ANY, - Arch.ANY, - "http://some.source/some_url", - 1234, // size - "abcdef") // sha1 - }; - } - }; - } - - /** - * Helper creator method to create a {@link MockExtraPackage} with no local - * archive associated and a specific oldPaths attribute. - */ - private static MockExtraPackage createRemoteExtraPackage( - SdkSource source, - String vendor, - String newPath, - String oldPaths, - int revision, - int min_platform_tools_rev) { - Properties props = new Properties(); - props.setProperty(PkgProps.EXTRA_OLD_PATHS, oldPaths); - props.setProperty(PkgProps.MIN_PLATFORM_TOOLS_REV, - Integer.toString((min_platform_tools_rev))); - return new MockExtraPackage(source, props, vendor, newPath, revision) { - @Override - protected Archive[] initializeArchives( - Properties props2, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - // Create one remote archive for this package - return new Archive[] { - new Archive( - this, - Os.ANY, - Arch.ANY, - "http://some.source/some_url", - 1234, // size - "abcdef") // sha1 - }; - } - }; - } - - private File createFile(String...segments) { - File f = null; - for (String segment : segments) { - if (f == null) { - f = new File(segment); - } else { - f = new File(f, segment); - } - } - - return f; - } - - /** - * Strips the second line of the string. - * The source.properties generated by Java contain the generation data on the - * second line and this is of course not suitable for unit tests. - */ - private String stripDate(String string) { - // We know it's a date if it looks like: - // \n # ... YYYY\n - Pattern p = Pattern.compile("\n#[^#][^\n]*[0-9]{4}\\w*\n", Pattern.DOTALL); - string = p.matcher(string.replaceAll("\r\n", "\n")).replaceAll("\n#...date...\n"); - return string; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/archives/ArchiveTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/archives/ArchiveTest.java deleted file mode 100755 index c0ae718..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/archives/ArchiveTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.archives; - -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; - -import junit.framework.TestCase; - -public class ArchiveTest extends TestCase { - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public void testShortDescription() throws Exception { - Archive a = new Archive( - null, //pkg, - Os.WINDOWS, //os - Arch.ANY, //arch, - null, //url - 0, //size - null); //checksum - assertEquals("Archive for Windows", a.getShortDescription()); - - a = new Archive( - null, //pkg, - Os.LINUX, //os - Arch.ANY, //arch, - null, //url - 0, //size - null); //checksum - assertEquals("Archive for Linux", a.getShortDescription()); - - a = new Archive( - null, //pkg, - Os.MACOSX, //os - Arch.ANY, //arch, - null, //url - 0, //size - null); //checksum - assertEquals("Archive for MacOS X", a.getShortDescription()); - - a = new Archive( - null, //pkg, - Os.ANY, //os - Arch.ANY, //arch, - null, //url - 0, //size - null); //checksum - assertEquals("Archive for any OS", a.getShortDescription()); - } - - public void testLongDescription() throws Exception { - Archive a = new Archive( - null, //pkg, - Os.WINDOWS, //os - Arch.ANY, //arch, - null, //url - 900, //size - "1234567890ABCDEF"); //checksum - assertEquals( - "Archive for Windows\n" + - "Size: 900 Bytes\n" + - "SHA1: 1234567890ABCDEF", - a.getLongDescription()); - - a = new Archive(null, Os.WINDOWS, Arch.ANY, null, 1100, "1234567890ABCDEF"); - assertEquals( - "Archive for Windows\n" + - "Size: 1 KiB\n" + - "SHA1: 1234567890ABCDEF", - a.getLongDescription()); - - a = new Archive(null, Os.WINDOWS, Arch.ANY, null, 1900, "1234567890ABCDEF"); - assertEquals( - "Archive for Windows\n" + - "Size: 2 KiB\n" + - "SHA1: 1234567890ABCDEF", - a.getLongDescription()); - - a = new Archive(null, Os.WINDOWS, Arch.ANY, null, (long)2e6, "1234567890ABCDEF"); - assertEquals( - "Archive for Windows\n" + - "Size: 1.9 MiB\n" + - "SHA1: 1234567890ABCDEF", - a.getLongDescription()); - - a = new Archive(null, Os.WINDOWS, Arch.ANY, null, (long)19e6, "1234567890ABCDEF"); - assertEquals( - "Archive for Windows\n" + - "Size: 18.1 MiB\n" + - "SHA1: 1234567890ABCDEF", - a.getLongDescription()); - - a = new Archive(null, Os.WINDOWS, Arch.ANY, null, (long)18e9, "1234567890ABCDEF"); - assertEquals( - "Archive for Windows\n" + - "Size: 16.8 GiB\n" + - "SHA1: 1234567890ABCDEF", - a.getLongDescription()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/BrokenPackageTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/BrokenPackageTest.java deleted file mode 100755 index 92a04c4..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/BrokenPackageTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.packages.BrokenPackage; - -import junit.framework.TestCase; - -public class BrokenPackageTest extends TestCase { - - private BrokenPackage m; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - m = new BrokenPackage(null /*props*/, - "short description", - "long description", - 12, // min api level - 13, // exact api level - "os/path"); - - } - - public final void testGetShortDescription() { - assertEquals("short description", m.getShortDescription()); - } - - public final void testGetLongDescription() { - assertEquals("long description", m.getLongDescription()); - } - - public final void testGetMinApiLevel() { - assertEquals(12, m.getMinApiLevel()); - } - - public final void testGetExactApiLevel() { - assertEquals(13, m.getExactApiLevel()); - } - - public void testInstallId() { - assertEquals("", m.installId()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/ExtraPackageTest_v3.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/ExtraPackageTest_v3.java deleted file mode 100755 index 6102f13..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/ExtraPackageTest_v3.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.repository.PkgProps; - -import java.io.File; -import java.util.Arrays; -import java.util.Properties; - -/** - * Tests {@link ExtraPackage} using anddon-3.xsd: it has a {@code <path>} and {@code <vendor>}. - * (it lacks name-display, vendor-id and vendor-display with are in addon-4.xsd) - */ -public class ExtraPackageTest_v3 extends MinToolsPackageTest { - - private static final char PS = File.pathSeparatorChar; - - private ExtraPackage createExtraPackage(Properties props) { - ExtraPackage p = (ExtraPackage) ExtraPackage.create( - null, //source - props, - null, //vendor - null, //path - -1, //revision - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - "/local/archive/path" //archiveOsPath - ); - return p; - } - - /** Properties used to "load" the package. When saved, they become different. */ - private Properties createLoadedProps() { - Properties props = super.createProps(); - - // ExtraPackage properties - props.setProperty(PkgProps.EXTRA_VENDOR, "vendor"); - props.setProperty(PkgProps.EXTRA_PATH, "the_path"); - props.setProperty(PkgProps.EXTRA_OLD_PATHS, "old_path1;oldpath2"); - props.setProperty(PkgProps.EXTRA_MIN_API_LEVEL, "11"); - props.setProperty(PkgProps.EXTRA_PROJECT_FILES, - "path1.jar" + PS + "dir2/jar 2.jar" + PS + "dir/3/path"); - - return props; - } - - /** Properties saved by the package. They differ from loaded ones in name and vendor. */ - private Properties createSavedProps() { - Properties props = super.createProps(); - - // ExtraPackage properties - props.setProperty(PkgProps.EXTRA_VENDOR_ID, "vendor"); - props.setProperty(PkgProps.EXTRA_VENDOR_DISPLAY, "vendor"); - props.setProperty(PkgProps.EXTRA_NAME_DISPLAY, "Vendor The Path"); - props.setProperty(PkgProps.EXTRA_PATH, "the_path"); - props.setProperty(PkgProps.EXTRA_OLD_PATHS, "old_path1;oldpath2"); - props.setProperty(PkgProps.EXTRA_MIN_API_LEVEL, "11"); - props.setProperty(PkgProps.EXTRA_PROJECT_FILES, - "path1.jar" + PS + "dir2/jar 2.jar" + PS + "dir/3/path"); - - return props; - } - - protected void testCreatedExtraPackage(ExtraPackage p) { - super.testCreatedPackage(p); - - // Package properties - // vendor becomes both vendor-id and vendor-display - assertEquals("vendor", p.getVendorId()); - assertEquals("vendor", p.getVendorDisplay()); - assertEquals("the_path", p.getPath()); - // path and vendor are combined in the default display name - assertEquals("Vendor The Path", p.getDisplayName()); - assertEquals("[old_path1, oldpath2]", Arrays.toString(p.getOldPaths())); - assertEquals(11, p.getMinApiLevel()); - assertEquals( - "[path1.jar, dir2/jar 2.jar, dir/3/path]", - Arrays.toString(p.getProjectFiles())); - } - - // ---- - - @Override - public final void testCreate() { - Properties props = createLoadedProps(); - ExtraPackage p = createExtraPackage(props); - - testCreatedExtraPackage(p); - } - - @Override - public void testSaveProperties() { - Properties props = createLoadedProps(); - ExtraPackage p = createExtraPackage(props); - - Properties props2 = new Properties(); - p.saveProperties(props2); - - assertEquals(props2, createSavedProps()); - } - - public void testSameItemAs() { - Properties props1 = createLoadedProps(); - ExtraPackage p1 = createExtraPackage(props1); - assertTrue(p1.sameItemAs(p1)); - - // different vendor, same path - Properties props2 = new Properties(props1); - props2.setProperty(PkgProps.EXTRA_VENDOR, "vendor2"); - ExtraPackage p2 = createExtraPackage(props2); - assertFalse(p1.sameItemAs(p2)); - assertFalse(p2.sameItemAs(p1)); - - // different vendor, different path - props2.setProperty(PkgProps.EXTRA_PATH, "new_path2"); - p2 = createExtraPackage(props2); - assertFalse(p1.sameItemAs(p2)); - assertFalse(p2.sameItemAs(p1)); - - // same vendor, but single path using the old paths from p1 - Properties props3 = new Properties(props1); - props3.setProperty(PkgProps.EXTRA_OLD_PATHS, ""); - props3.setProperty(PkgProps.EXTRA_PATH, "old_path1"); - ExtraPackage p3 = createExtraPackage(props3); - assertTrue(p1.sameItemAs(p3)); - assertTrue(p3.sameItemAs(p1)); - - props3.setProperty(PkgProps.EXTRA_PATH, "oldpath2"); - p3 = createExtraPackage(props3); - assertTrue(p1.sameItemAs(p3)); - assertTrue(p3.sameItemAs(p1)); - - // same vendor, different old paths but there's a path=>old_path match - Properties props4 = new Properties(props1); - props4.setProperty(PkgProps.EXTRA_OLD_PATHS, "new_path4;new_path5"); - props4.setProperty(PkgProps.EXTRA_PATH, "old_path1"); - ExtraPackage p4 = createExtraPackage(props4); - assertTrue(p1.sameItemAs(p4)); - assertTrue(p4.sameItemAs(p1)); - - // same vendor, incompatible paths - Properties props5 = new Properties(props1); - // and the only match is between old_paths, which doesn't count. - props5.setProperty(PkgProps.EXTRA_OLD_PATHS, "old_path1;new_path5"); - props5.setProperty(PkgProps.EXTRA_PATH, "new_path4"); - ExtraPackage p5 = createExtraPackage(props5); - assertFalse(p1.sameItemAs(p5)); - assertFalse(p5.sameItemAs(p1)); - } - - public void testInstallId() { - Properties props = createLoadedProps(); - ExtraPackage p = createExtraPackage(props); - - assertEquals("extra-vendor-the_path", p.installId()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/ExtraPackageTest_v4.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/ExtraPackageTest_v4.java deleted file mode 100755 index eff3020..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/ExtraPackageTest_v4.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.repository.PkgProps; - -import java.io.File; -import java.util.Arrays; -import java.util.Properties; - -/** - * Tests {@link ExtraPackage} using anddon-4.xsd: - * it has name-display, vendor-id and vendor-display. - */ -public class ExtraPackageTest_v4 extends MinToolsPackageTest { - - private static final char PS = File.pathSeparatorChar; - - private ExtraPackage createExtraPackage(Properties props) { - ExtraPackage p = (ExtraPackage) ExtraPackage.create( - null, //source - props, - null, //vendor - null, //path - -1, //revision - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - "/local/archive/path" //archiveOsPath - ); - return p; - } - - @Override - protected Properties createProps() { - Properties props = super.createProps(); - - // ExtraPackage properties - props.setProperty(PkgProps.EXTRA_VENDOR_ID, "the_vendor"); - props.setProperty(PkgProps.EXTRA_VENDOR_DISPLAY, "The Company, Inc."); - props.setProperty(PkgProps.EXTRA_NAME_DISPLAY, "Some Extra Package"); - props.setProperty(PkgProps.EXTRA_PATH, "the_path"); - props.setProperty(PkgProps.EXTRA_OLD_PATHS, "old_path1;oldpath2"); - props.setProperty(PkgProps.EXTRA_MIN_API_LEVEL, "11"); - props.setProperty(PkgProps.EXTRA_PROJECT_FILES, - "path1.jar" + PS + "dir2/jar 2.jar" + PS + "dir/3/path"); - - return props; - } - - protected void testCreatedExtraPackage(ExtraPackage p) { - super.testCreatedPackage(p); - - // Package properties - assertEquals("the_vendor", p.getVendorId()); - assertEquals("The Company, Inc.", p.getVendorDisplay()); - assertEquals("Some Extra Package", p.getDisplayName()); - assertEquals("the_path", p.getPath()); - assertEquals("[old_path1, oldpath2]", Arrays.toString(p.getOldPaths())); - assertEquals(11, p.getMinApiLevel()); - assertEquals( - "[path1.jar, dir2/jar 2.jar, dir/3/path]", - Arrays.toString(p.getProjectFiles())); - } - - // ---- - - @Override - public final void testCreate() { - Properties props = createProps(); - ExtraPackage p = createExtraPackage(props); - - testCreatedExtraPackage(p); - } - - @Override - public void testSaveProperties() { - Properties props = createProps(); - ExtraPackage p = createExtraPackage(props); - - Properties props2 = new Properties(); - p.saveProperties(props2); - - assertEquals(props2, props); - } - - public void testSameItemAs() { - Properties props1 = createProps(); - ExtraPackage p1 = createExtraPackage(props1); - assertTrue(p1.sameItemAs(p1)); - - // different vendor, same path - Properties props2 = new Properties(props1); - props2.setProperty(PkgProps.EXTRA_VENDOR_ID, "vendor2"); - props2.setProperty(PkgProps.EXTRA_VENDOR_DISPLAY, "Another Vendor Name"); - ExtraPackage p2 = createExtraPackage(props2); - assertFalse(p1.sameItemAs(p2)); - assertFalse(p2.sameItemAs(p1)); - - // different vendor, different path - props2.setProperty(PkgProps.EXTRA_PATH, "new_path2"); - p2 = createExtraPackage(props2); - assertFalse(p1.sameItemAs(p2)); - assertFalse(p2.sameItemAs(p1)); - - // same vendor, but single path using the old paths from p1 - Properties props3 = new Properties(props1); - props3.setProperty(PkgProps.EXTRA_OLD_PATHS, ""); - props3.setProperty(PkgProps.EXTRA_PATH, "old_path1"); - ExtraPackage p3 = createExtraPackage(props3); - assertTrue(p1.sameItemAs(p3)); - assertTrue(p3.sameItemAs(p1)); - - props3.setProperty(PkgProps.EXTRA_PATH, "oldpath2"); - p3 = createExtraPackage(props3); - assertTrue(p1.sameItemAs(p3)); - assertTrue(p3.sameItemAs(p1)); - - // same vendor, different old paths but there's a path=>old_path match - Properties props4 = new Properties(props1); - props4.setProperty(PkgProps.EXTRA_OLD_PATHS, "new_path4;new_path5"); - props4.setProperty(PkgProps.EXTRA_PATH, "old_path1"); - ExtraPackage p4 = createExtraPackage(props4); - assertTrue(p1.sameItemAs(p4)); - assertTrue(p4.sameItemAs(p1)); - - // same vendor, incompatible paths - Properties props5 = new Properties(props1); - // and the only match is between old_paths, which doesn't count. - props5.setProperty(PkgProps.EXTRA_OLD_PATHS, "old_path1;new_path5"); - props5.setProperty(PkgProps.EXTRA_PATH, "new_path4"); - ExtraPackage p5 = createExtraPackage(props5); - assertFalse(p1.sameItemAs(p5)); - assertFalse(p5.sameItemAs(p1)); - } - - public void testInstallId() { - Properties props = createProps(); - ExtraPackage p = createExtraPackage(props); - - assertEquals("extra-the_vendor-the_path", p.installId()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/FullRevisionPackageTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/FullRevisionPackageTest.java deleted file mode 100755 index 9bf2703..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/FullRevisionPackageTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.repository.PkgProps; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Properties; - -import junit.framework.TestCase; - -public class FullRevisionPackageTest extends TestCase { - - /** - * Helper that creates the {@link Properties} from a {@link FullRevision} - * as expected by {@link FullRevisionPackage}. - */ - public static Properties createProps(FullRevision revision) { - Properties props = new Properties(); - if (revision != null) { - props.setProperty(PkgProps.PKG_REVISION, revision.toString()); - } - return props; - } - - public void testCompareTo() throws Exception { - // Test order of full revision packages. - // - // Note that Package.compareTo() is designed to return the desired - // ordering for a list display and as such a final/release package - // needs to be listed before its rc/preview package. - // - // This differs from the order used by FullRevision.compareTo(). - - ArrayList<Package> list = new ArrayList<Package>(); - - list.add(new MockToolPackage(null, new FullRevision(1, 0, 0, 0), 8)); - list.add(new MockToolPackage(null, new FullRevision(1, 0, 0, 1), 8)); - list.add(new MockToolPackage(null, new FullRevision(1, 0, 1, 0), 8)); - list.add(new MockToolPackage(null, new FullRevision(1, 0, 1, 1), 8)); - list.add(new MockToolPackage(null, new FullRevision(1, 1, 0, 0), 8)); - list.add(new MockToolPackage(null, new FullRevision(1, 1, 0, 1), 8)); - list.add(new MockToolPackage(null, new FullRevision(2, 1, 1, 0), 8)); - list.add(new MockToolPackage(null, new FullRevision(2, 1, 1, 1), 8)); - - Collections.sort(list); - - assertEquals( - "[Android SDK Tools, revision 1, " + - "Android SDK Tools, revision 1 rc1, " + - "Android SDK Tools, revision 1.0.1, " + - "Android SDK Tools, revision 1.0.1 rc1, " + - "Android SDK Tools, revision 1.1, " + - "Android SDK Tools, revision 1.1 rc1, " + - "Android SDK Tools, revision 2.1.1, " + - "Android SDK Tools, revision 2.1.1 rc1]", - Arrays.toString(list.toArray())); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/FullRevisionTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/FullRevisionTest.java deleted file mode 100755 index d072d05..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/FullRevisionTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import junit.framework.TestCase; - -public class FullRevisionTest extends TestCase { - - public final void testFullRevision() { - FullRevision p = new FullRevision(5); - assertEquals(5, p.getMajor()); - assertEquals(FullRevision.IMPLICIT_MINOR_REV, p.getMinor()); - assertEquals(FullRevision.IMPLICIT_MICRO_REV, p.getMicro()); - assertEquals(FullRevision.NOT_A_PREVIEW, p.getPreview()); - assertFalse (p.isPreview()); - assertEquals("5", p.toShortString()); - assertEquals(p, FullRevision.parseRevision("5")); - assertEquals("5.0.0", p.toString()); - assertEquals(p, FullRevision.parseRevision("5.0.0")); - - p = new FullRevision(5, 0, 0, 6); - assertEquals(5, p.getMajor()); - assertEquals(FullRevision.IMPLICIT_MINOR_REV, p.getMinor()); - assertEquals(FullRevision.IMPLICIT_MICRO_REV, p.getMicro()); - assertEquals(6, p.getPreview()); - assertTrue (p.isPreview()); - assertEquals("5 rc6", p.toShortString()); - assertEquals(p, FullRevision.parseRevision("5 rc6")); - assertEquals("5.0.0 rc6", p.toString()); - assertEquals(p, FullRevision.parseRevision("5.0.0 rc6")); - - p = new FullRevision(6, 7, 0); - assertEquals(6, p.getMajor()); - assertEquals(7, p.getMinor()); - assertEquals(0, p.getMicro()); - assertEquals(0, p.getPreview()); - assertFalse (p.isPreview()); - assertEquals("6.7", p.toShortString()); - assertEquals(p, FullRevision.parseRevision("6.7")); - assertEquals("6.7.0", p.toString()); - assertEquals(p, FullRevision.parseRevision("6.7.0")); - - p = new FullRevision(10, 11, 12, FullRevision.NOT_A_PREVIEW); - assertEquals(10, p.getMajor()); - assertEquals(11, p.getMinor()); - assertEquals(12, p.getMicro()); - assertEquals(0, p.getPreview()); - assertFalse (p.isPreview()); - assertEquals("10.11.12", p.toShortString()); - assertEquals("10.11.12", p.toString()); - assertEquals(p, FullRevision.parseRevision("10.11.12")); - - p = new FullRevision(10, 11, 12, 13); - assertEquals(10, p.getMajor()); - assertEquals(11, p.getMinor()); - assertEquals(12, p.getMicro()); - assertEquals(13, p.getPreview()); - assertTrue (p.isPreview()); - assertEquals("10.11.12 rc13", p.toShortString()); - assertEquals("10.11.12 rc13", p.toString()); - assertEquals(p, FullRevision.parseRevision("10.11.12 rc13")); - assertEquals(p, FullRevision.parseRevision(" 10.11.12 rc13")); - assertEquals(p, FullRevision.parseRevision("10.11.12 rc13 ")); - assertEquals(p, FullRevision.parseRevision(" 10.11.12 rc13 ")); - } - - public final void testParseError() { - String errorMsg = null; - try { - FullRevision.parseRevision("not a number"); - fail("FullRevision.parseRevision should thrown NumberFormatException"); - } catch (NumberFormatException e) { - errorMsg = e.getMessage(); - } - assertEquals("Invalid full revision: not a number", errorMsg); - - errorMsg = null; - try { - FullRevision.parseRevision("5 .6 .7"); - fail("FullRevision.parseRevision should thrown NumberFormatException"); - } catch (NumberFormatException e) { - errorMsg = e.getMessage(); - } - assertEquals("Invalid full revision: 5 .6 .7", errorMsg); - - errorMsg = null; - try { - FullRevision.parseRevision("5.0.0 preview 1"); - fail("FullRevision.parseRevision should thrown NumberFormatException"); - } catch (NumberFormatException e) { - errorMsg = e.getMessage(); - } - assertEquals("Invalid full revision: 5.0.0 preview 1", errorMsg); - - errorMsg = null; - try { - FullRevision.parseRevision(" 5.1.2 rc 42 "); - fail("FullRevision.parseRevision should thrown NumberFormatException"); - } catch (NumberFormatException e) { - errorMsg = e.getMessage(); - } - assertEquals("Invalid full revision: 5.1.2 rc 42 ", errorMsg); - } - - public final void testCompareTo() { - FullRevision s4 = new FullRevision(4); - FullRevision i4 = new FullRevision(4); - FullRevision g5 = new FullRevision(5, 1, 0, 6); - FullRevision y5 = new FullRevision(5); - FullRevision c5 = new FullRevision(5, 1, 0, 6); - FullRevision o5 = new FullRevision(5, 0, 0, 7); - FullRevision p5 = new FullRevision(5, 1, 0, 0); - - assertEquals(s4, i4); // 4.0.0-0 == 4.0.0-0 - assertEquals(g5, c5); // 5.1.0-6 == 5.1.0-6 - - assertFalse(y5.equals(p5)); // 5.0.0-0 != 5.1.0-0 - assertFalse(g5.equals(p5)); // 5.1.0-6 != 5.1.0-0 - assertTrue (s4.compareTo(i4) == 0); // 4.0.0-0 == 4.0.0-0 - assertTrue (s4.compareTo(y5) < 0); // 4.0.0-0 < 5.0.0-0 - assertTrue (y5.compareTo(y5) == 0); // 5.0.0-0 == 5.0.0-0 - assertTrue (y5.compareTo(p5) < 0); // 5.0.0-0 < 5.1.0-0 - assertTrue (o5.compareTo(y5) < 0); // 5.0.0-7 < 5.0.0-0 - assertTrue (p5.compareTo(p5) == 0); // 5.1.0-0 == 5.1.0-0 - assertTrue (c5.compareTo(p5) < 0); // 5.1.0-6 < 5.1.0-0 - assertTrue (p5.compareTo(c5) > 0); // 5.1.0-0 > 5.1.0-6 - assertTrue (p5.compareTo(o5) > 0); // 5.1.0-0 > 5.0.0-7 - assertTrue (c5.compareTo(o5) > 0); // 5.1.0-6 > 5.0.0-7 - assertTrue (o5.compareTo(o5) == 0); // 5.0.0-7 > 5.0.0-7 - } - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MajorRevisionTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MajorRevisionTest.java deleted file mode 100755 index b77caad..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MajorRevisionTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import junit.framework.TestCase; - -public class MajorRevisionTest extends TestCase { - - public final void testMajorRevision() { - MajorRevision p = new MajorRevision(5); - assertEquals(5, p.getMajor()); - assertEquals(FullRevision.IMPLICIT_MINOR_REV, p.getMinor()); - assertEquals(FullRevision.IMPLICIT_MICRO_REV, p.getMicro()); - assertEquals(FullRevision.NOT_A_PREVIEW, p.getPreview()); - assertFalse (p.isPreview()); - assertEquals("5", p.toShortString()); - assertEquals(p, MajorRevision.parseRevision("5")); - assertEquals("5", p.toString()); - - assertEquals(new FullRevision(5, 0, 0, 0), p); - } - - public final void testParseError() { - String errorMsg = null; - try { - MajorRevision.parseRevision("5.0.0"); - fail("MajorRevision.parseRevision should thrown NumberFormatException"); - } catch (NumberFormatException e) { - errorMsg = e.getMessage(); - } - assertEquals("For input string: \"5.0.0\"", errorMsg); - } - - public final void testCompareTo() { - MajorRevision s4 = new MajorRevision(4); - MajorRevision i4 = new MajorRevision(4); - FullRevision g5 = new FullRevision (5, 1, 0, 6); - MajorRevision y5 = new MajorRevision(5); - FullRevision c5 = new FullRevision (5, 1, 0, 6); - FullRevision o5 = new FullRevision (5, 0, 0, 7); - FullRevision p5 = new FullRevision (5, 1, 0, 0); - - assertEquals(s4, i4); // 4.0.0-0 == 4.0.0-0 - assertEquals(g5, c5); // 5.1.0-6 == 5.1.0-6 - - assertFalse(y5.equals(p5)); // 5.0.0-0 != 5.1.0-0 - assertFalse(g5.equals(p5)); // 5.1.0-6 != 5.1.0-0 - assertTrue (s4.compareTo(i4) == 0); // 4.0.0-0 == 4.0.0-0 - assertTrue (s4.compareTo(y5) < 0); // 4.0.0-0 < 5.0.0-0 - assertTrue (y5.compareTo(y5) == 0); // 5.0.0-0 == 5.0.0-0 - assertTrue (y5.compareTo(p5) < 0); // 5.0.0-0 < 5.1.0-0 - assertTrue (o5.compareTo(y5) < 0); // 5.0.0-7 < 5.0.0-0 - assertTrue (p5.compareTo(p5) == 0); // 5.1.0-0 == 5.1.0-0 - assertTrue (c5.compareTo(p5) < 0); // 5.1.0-6 < 5.1.0-0 - assertTrue (p5.compareTo(c5) > 0); // 5.1.0-0 > 5.1.0-6 - assertTrue (p5.compareTo(o5) > 0); // 5.1.0-0 > 5.0.0-7 - assertTrue (c5.compareTo(o5) > 0); // 5.1.0-6 > 5.0.0-7 - assertTrue (o5.compareTo(o5) == 0); // 5.0.0-7 > 5.0.0-7 - } - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MinToolsPackageTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MinToolsPackageTest.java deleted file mode 100755 index adffe2e..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MinToolsPackageTest.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.MinToolsPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; - -import java.io.File; -import java.util.Properties; - -public class MinToolsPackageTest extends PackageTest { - - /** Local class used to test the abstract MinToolsPackage class */ - protected static class MockMinToolsPackage extends MinToolsPackage { - public MockMinToolsPackage( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, - props, - revision, - license, - description, - descUrl, - archiveOs, - archiveArch, - archiveOsPath); - } - - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public String getListDescription() { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public String getShortDescription() { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public boolean sameItemAs(Package pkg) { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public String installId() { - return ""; //$NON-NLS-1$ - } - } - - @Override - public void testCreate() { - Properties props = createProps(); - - MockMinToolsPackage p = new MockMinToolsPackage( - null, //source - props, - -1, //revision - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - LOCAL_ARCHIVE_PATH - ); - - testCreatedPackage(p); - } - - @Override - public void testSaveProperties() { - Properties props = createProps(); - - MockMinToolsPackage p = new MockMinToolsPackage( - null, //source - props, - -1, //revision - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - LOCAL_ARCHIVE_PATH - ); - - Properties props2 = new Properties(); - p.saveProperties(props2); - - assertEquals(props2, props); - } - - @Override - protected Properties createProps() { - Properties props = super.createProps(); - - // MinToolsPackage properties - props.setProperty(PkgProps.MIN_TOOLS_REV, "3.0.1"); - - return props; - } - - protected void testCreatedMinToolsPackage(MockMinToolsPackage p) { - super.testCreatedPackage(p); - - // MinToolsPackage properties - assertEquals("3.0.1", p.getMinToolsRevision().toShortString()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockAddonPackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockAddonPackage.java deleted file mode 100755 index 7a52e7d..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockAddonPackage.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.SdkConstants; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISystemImage; -import com.android.sdklib.ISystemImage.LocationType; -import com.android.sdklib.SystemImage; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.io.FileOp; -import com.android.sdklib.repository.PkgProps; - -import java.util.Map; -import java.util.Properties; - -/** - * A mock {@link AddonPackage} for testing. - * - * By design, this package contains one and only one archive. - */ -public class MockAddonPackage extends AddonPackage { - - /** - * Creates a {@link MockAddonTarget} with the requested base platform and addon revision - * and then a {@link MockAddonPackage} wrapping it and a default name of "addon". - * - * By design, this package contains one and only one archive. - */ - public MockAddonPackage(MockPlatformPackage basePlatform, int revision) { - this("addon", basePlatform, revision); //$NON-NLS-1$ - } - - /** - * Creates a {@link MockAddonTarget} with the requested base platform and addon revision - * and then a {@link MockAddonPackage} wrapping it. - * - * By design, this package contains one and only one archive. - */ - public MockAddonPackage(String name, MockPlatformPackage basePlatform, int revision) { - super(new MockAddonTarget(name, basePlatform.getTarget(), revision), null /*props*/); - } - - public MockAddonPackage( - SdkSource source, - String name, - MockPlatformPackage basePlatform, - int revision) { - super(source, - new MockAddonTarget(name, basePlatform.getTarget(), revision), - createProperties(name, basePlatform.getTarget())); - } - - private static Properties createProperties(String name, IAndroidTarget baseTarget) { - String vendor = baseTarget.getVendor(); - Properties props = new Properties(); - props.setProperty(PkgProps.ADDON_NAME_ID, name); - props.setProperty(PkgProps.ADDON_NAME_DISPLAY, - String.format("The %1$s from %2$s", //$NON-NLS-1$ - name, vendor)); - props.setProperty(PkgProps.ADDON_VENDOR_ID, - String.format("vendor-id-%1$s", vendor)); //$NON-NLS-1$ - props.setProperty(PkgProps.ADDON_VENDOR_DISPLAY, - String.format("The %1$s", vendor)); //$NON-NLS-1$ - return props; - } - - /** - * A mock AddonTarget. - * This reimplements the minimum needed from the interface for our limited testing needs. - */ - static class MockAddonTarget implements IAndroidTarget { - - private final IAndroidTarget mParentTarget; - private final int mRevision; - private final String mName; - private ISystemImage[] mSystemImages; - - public MockAddonTarget(String name, IAndroidTarget parentTarget, int revision) { - mName = name; - mParentTarget = parentTarget; - mRevision = revision; - } - - @Override - public String getClasspathName() { - return getName(); - } - - @Override - public String getShortClasspathName() { - return getName(); - } - - @Override - public String getDefaultSkin() { - return null; - } - - @Override - public String getDescription() { - return getName(); - } - - @Override - public String getFullName() { - return getName(); - } - - @Override - public ISystemImage[] getSystemImages() { - if (mSystemImages == null) { - SystemImage si = new SystemImage( - FileOp.append(getLocation(), SdkConstants.OS_IMAGES_FOLDER), - LocationType.IN_PLATFORM_LEGACY, - SdkConstants.ABI_ARMEABI); - mSystemImages = new SystemImage[] { si }; - } - return mSystemImages; - } - - @Override - public ISystemImage getSystemImage(String abiType) { - if (SdkConstants.ABI_ARMEABI.equals(abiType)) { - return getSystemImages()[0]; - } - return null; - } - - @Override - public String getLocation() { - return "/sdk/add-ons/addon-" + mName; - } - - @Override - public IOptionalLibrary[] getOptionalLibraries() { - return null; - } - - @Override - public IAndroidTarget getParent() { - return mParentTarget; - } - - @Override - public String getPath(int pathId) { - throw new UnsupportedOperationException("Implement this as needed for tests"); - } - - @Override - public String[] getPlatformLibraries() { - return null; - } - - @Override - public String getProperty(String name) { - return null; - } - - @Override - public Integer getProperty(String name, Integer defaultValue) { - return defaultValue; - } - - @Override - public Boolean getProperty(String name, Boolean defaultValue) { - return defaultValue; - } - - @Override - public Map<String, String> getProperties() { - return null; - } - - @Override - public int getRevision() { - return mRevision; - } - - @Override - public String[] getSkins() { - return null; - } - - @Override - public int getUsbVendorId() { - return 0; - } - - @Override - public AndroidVersion getVersion() { - return mParentTarget.getVersion(); - } - - @Override - public String getName() { - return mName; - } - - @Override - public String getVendor() { - return mParentTarget.getVendor(); - } - - @Override - public String getVersionName() { - return String.format("mock-addon-%1$d", getVersion().getApiLevel()); - } - - @Override - public String hashString() { - return getVersionName(); - } - - /** Returns false for an addon. */ - @Override - public boolean isPlatform() { - return false; - } - - @Override - public boolean canRunOn(IAndroidTarget target) { - throw new UnsupportedOperationException("Implement this as needed for tests"); - } - - @Override - public int compareTo(IAndroidTarget o) { - throw new UnsupportedOperationException("Implement this as needed for tests"); - } - - @Override - public boolean hasRenderingLibrary() { - return false; - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockBrokenPackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockBrokenPackage.java deleted file mode 100755 index e78e796..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockBrokenPackage.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.packages.BrokenPackage; - - -/** - * A mock {@link BrokenPackage} for testing. - * <p/> - * By design, this package contains one and only one archive. - */ -public class MockBrokenPackage extends BrokenPackage { - - public MockBrokenPackage(int minApiLevel, int exactApiLevel) { - this(createDesription(minApiLevel, exactApiLevel), // short description - createDesription(minApiLevel, exactApiLevel), // long description - minApiLevel, - exactApiLevel); - } - - private static String createDesription(int minApiLevel, int exactApiLevel) { - String s = "Broken package"; - s += exactApiLevel == BrokenPackage.API_LEVEL_INVALID ? " (No API level)" : - String.format(" for API %d", exactApiLevel); - s += minApiLevel == BrokenPackage.MIN_API_LEVEL_NOT_SPECIFIED ? "" : - String.format(", min API %d", minApiLevel); - return s; - } - - public MockBrokenPackage( - String shortDescription, - String longDescription, - int minApiLevel, - int exactApiLevel) { - super(null /*props*/, - shortDescription, - longDescription, - minApiLevel, - exactApiLevel, - "/sdk/broken/package" /*osPath*/); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockEmptyPackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockEmptyPackage.java deleted file mode 100755 index 70f57b4..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockEmptyPackage.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; - -import java.io.File; -import java.util.Properties; - -/** - * A mock empty package, of no particular subpackage type. - * {@link #sameItemAs(Package)} will return true if these packages have the same handle. - */ -public class MockEmptyPackage extends MajorRevisionPackage { - private final String mTestHandle; - - /** - * Creates a new {@link MockEmptyPackage} with a local archive. - * - * @param testHandle The comparison handle for {@link #sameItemAs(Package)}. - */ - public MockEmptyPackage(String testHandle) { - super( - null /*source*/, - null /*props*/, - 0 /*revision*/, - null /*license*/, - null /*description*/, - null /*descUrl*/, - Os.ANY /*archiveOs*/, - Arch.ANY /*archiveArch*/, - "/sdk/tmp/empty_pkg" /*archiveOsPath*/ - ); - mTestHandle = testHandle; - } - - /** - * Creates a new {@link MockEmptyPackage} with a local archive. - * - * @param testHandle The comparison handle for {@link #sameItemAs(Package)}. - * @param revision The revision of the package, printed in the short description. - */ - public MockEmptyPackage(String testHandle, int revision) { - super( - null /*source*/, - null /*props*/, - revision, - null /*license*/, - null /*description*/, - null /*descUrl*/, - Os.ANY /*archiveOs*/, - Arch.ANY /*archiveArch*/, - "/sdk/tmp/empty_pkg" /*archiveOsPath*/ - ); - mTestHandle = testHandle; - } - - /** - * Creates a new {@link MockEmptyPackage} with a local archive. - * - * @param source The source associate with this package. - * @param testHandle The comparison handle for {@link #sameItemAs(Package)}. - * @param revision The revision of the package, printed in the short description. - */ - public MockEmptyPackage(SdkSource source, String testHandle, int revision) { - super( - source, - null /*props*/, - revision, - null /*license*/, - null /*description*/, - null /*descUrl*/, - Os.ANY /*archiveOs*/, - Arch.ANY /*archiveArch*/, - "/sdk/tmp/empty_pkg" /*archiveOsPath*/ - ); - mTestHandle = testHandle; - } - - @Override - protected Archive[] initializeArchives( - Properties props, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - return new Archive[] { - new Archive(this, props, archiveOs, archiveArch, archiveOsPath) { - @Override - public String toString() { - return mTestHandle; - } - } }; - } - - public Archive getLocalArchive() { - return getArchives()[0]; - } - - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - return new File(new File(osSdkRoot, "mock"), mTestHandle); - } - - @Override - public String installId() { - return "mock-empty-" + mTestHandle; //$NON-NLS-1$ - } - - @Override - public String getListDescription() { - return this.getClass().getSimpleName(); - } - - @Override - public String getShortDescription() { - StringBuilder sb = new StringBuilder(this.getClass().getSimpleName()); - sb.append(" '").append(mTestHandle).append('\''); - if (getRevision().getMajor() > 0) { - sb.append(" rev=").append(getRevision()); - } - return sb.toString(); - } - - /** Returns true if these packages have the same handle. */ - @Override - public boolean sameItemAs(Package pkg) { - return (pkg instanceof MockEmptyPackage) && - mTestHandle.equals(((MockEmptyPackage) pkg).mTestHandle); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((mTestHandle == null) ? 0 : mTestHandle.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!super.equals(obj)) { - return false; - } - if (!(obj instanceof MockEmptyPackage)) { - return false; - } - MockEmptyPackage other = (MockEmptyPackage) obj; - if (mTestHandle == null) { - if (other.mTestHandle != null) { - return false; - } - } else if (!mTestHandle.equals(other.mTestHandle)) { - return false; - } - return true; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockExtraPackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockExtraPackage.java deleted file mode 100755 index ca5a6cf..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockExtraPackage.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; - -import java.util.Properties; - -/** - * A mock {@link ExtraPackage} for testing. - * - * By design, this package contains one and only one archive. - */ -public class MockExtraPackage extends ExtraPackage { - - /** - * Creates a {@link MockExtraPackage} with the given revision and hardcoded defaults - * for everything else. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MockExtraPackage(String vendor, String path, int revision, int min_platform_tools_rev) { - this(null /*source*/, vendor, path, revision, min_platform_tools_rev); - } - - public MockExtraPackage( - SdkSource source, - Properties props, - String vendor, - String path, - int revision) { - super( - source, - props, // props, - vendor, - path, - revision, - null, // license, - "desc", // description, - "url", // descUrl, - Os.getCurrentOs(), // archiveOs, - Arch.getCurrentArch(), // archiveArch, - "foo" // archiveOsPath - ); - } - - public MockExtraPackage( - SdkSource source, - String vendor, - String path, - int revision, - int min_platform_tools_rev) { - this(source, createProps(min_platform_tools_rev), vendor, path, revision); - } - - private static Properties createProps(int min_platform_tools_rev) { - Properties props = new Properties(); - props.setProperty(PkgProps.MIN_PLATFORM_TOOLS_REV, - Integer.toString((min_platform_tools_rev))); - return props; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockPlatformPackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockPlatformPackage.java deleted file mode 100755 index 1d70ba9..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockPlatformPackage.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.internal.repository.MockPlatformTarget; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; - -import java.util.Properties; - -/** - * A mock {@link PlatformPackage} for testing. - * - * By design, this package contains one and only one archive. - */ -public class MockPlatformPackage extends PlatformPackage { - - private final IAndroidTarget mTarget; - - /** - * Creates a {@link MockPlatformTarget} with the requested API and revision - * and then a {@link MockPlatformPackage} wrapping it. - * - * By design, this package contains one and only one archive. - */ - public MockPlatformPackage(int apiLevel, int revision) { - this(null /*source*/, new MockPlatformTarget(apiLevel, revision), null /*props*/); - } - - /** - * Creates a {@link MockPlatformTarget} with the requested API and revision - * and then a {@link MockPlatformPackage} wrapping it. - * - * Also sets the min-tools-rev of the platform. - * - * By design, this package contains one and only one archive. - */ - public MockPlatformPackage(int apiLevel, int revision, int min_tools_rev) { - this(null /*source*/, - new MockPlatformTarget(apiLevel, revision), - createProps(min_tools_rev)); - } - - public MockPlatformPackage(SdkSource source, int apiLevel, int revision, int min_tools_rev) { - this(source, new MockPlatformTarget(apiLevel, revision), createProps(min_tools_rev)); - } - - /** A little trick to be able to capture the target new after passing it to the super. */ - private MockPlatformPackage(SdkSource source, IAndroidTarget target, Properties props) { - super(source, target, props); - mTarget = target; - } - - private static Properties createProps(int min_tools_rev) { - Properties props = new Properties(); - props.setProperty(PkgProps.MIN_TOOLS_REV, Integer.toString((min_tools_rev))); - return props; - } - - public IAndroidTarget getTarget() { - return mTarget; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockPlatformToolPackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockPlatformToolPackage.java deleted file mode 100755 index b11c991..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockPlatformToolPackage.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.sources.SdkSource; - -/** - * A mock {@link PlatformToolPackage} for testing. - * - * By design, this package contains one and only one archive. - */ -public class MockPlatformToolPackage extends PlatformToolPackage { - - /** - * Creates a {@link MockPlatformToolPackage} with the given revision and hardcoded defaults - * for everything else. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MockPlatformToolPackage(int revision) { - this(null /*source*/, revision); - } - - /** - * Creates a {@link MockPlatformToolPackage} with the given revision and hardcoded defaults - * for everything else. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MockPlatformToolPackage(SdkSource source, int revision) { - super( - source, // source, - null, // props, - revision, - null, // license, - "desc", // description, - "url", // descUrl, - Os.getCurrentOs(), // archiveOs, - Arch.getCurrentArch(), // archiveArch, - "foo" // archiveOsPath - ); - } - - /** - * Creates a {@link MockPlatformToolPackage} with the given revision and hardcoded defaults - * for everything else. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MockPlatformToolPackage(SdkSource source, FullRevision revision) { - super( - source, // source, - FullRevisionPackageTest.createProps(revision), // props, - revision.getMajor(), - null, // license, - "desc", // description, - "url", // descUrl, - Os.getCurrentOs(), // archiveOs, - Arch.getCurrentArch(), // archiveArch, - "foo" // archiveOsPath - ); - } -} - diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockSourcePackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockSourcePackage.java deleted file mode 100755 index 4c129a3..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockSourcePackage.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.internal.repository.packages.SourcePackage; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.internal.repository.sources.SdkSource; - - -/** - * A mock {@link SystemImagePackage} for testing. - * - * By design, this package contains one and only one archive. - */ -public class MockSourcePackage extends SourcePackage { - /** - * Creates a {@link MockSourcePackage} using the given base platform version - * and package revision. - * - * By design, this package contains one and only one archive. - */ - public MockSourcePackage(AndroidVersion version, int revision) { - super(version, - revision, - null /*props*/, - String.format("/sdk/sources/android-%s", version.getApiString())); - } - - /** - * Creates a {@link MockSourcePackage} using the given version, - * sdk source and package revision. - * - * By design, this package contains one and only one archive. - */ - public MockSourcePackage( - SdkSource source, - AndroidVersion version, - int revision) { - super(source, - version, - revision, - null /*props*/, - String.format("/sdk/sources/android-%s", version.getApiString())); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockSystemImagePackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockSystemImagePackage.java deleted file mode 100755 index 3c7baec..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockSystemImagePackage.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.internal.repository.sources.SdkSource; - - -/** - * A mock {@link SystemImagePackage} for testing. - * - * By design, this package contains one and only one archive. - */ -public class MockSystemImagePackage extends SystemImagePackage { - /** - * Creates a {@link MockSystemImagePackage} using the given base platform version - * and package revision. - * - * By design, this package contains one and only one archive. - */ - public MockSystemImagePackage(MockPlatformPackage basePlatform, int revision, String abi) { - super(basePlatform.getAndroidVersion(), - revision, - abi, - null /*props*/, - String.format("/sdk/system-images/android-%s/%s", - basePlatform.getAndroidVersion().getApiString(), abi)); - } - - /** - * Creates a {@link MockSystemImagePackage} using the given base platform version, - * sdk source and package revision. - * - * By design, this package contains one and only one archive. - */ - public MockSystemImagePackage( - SdkSource source, - MockPlatformPackage basePlatform, - int revision, - String abi) { - super(source, - basePlatform.getAndroidVersion(), - revision, - abi, - null /*props*/, - String.format("/sdk/system-images/android-%s/%s", - basePlatform.getAndroidVersion().getApiString(), abi)); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockToolPackage.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockToolPackage.java deleted file mode 100755 index 32711d6..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/MockToolPackage.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; - -import java.util.Properties; - -/** - * A mock {@link ToolPackage} for testing. - * - * By design, this package contains one and only one archive. - */ -public class MockToolPackage extends ToolPackage { - - /** - * Creates a {@link MockToolPackage} with the given revision and hardcoded defaults - * for everything else. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MockToolPackage(int revision, int min_platform_tools_rev) { - this(null /*source*/, revision, min_platform_tools_rev); - } - - /** - * Creates a {@link MockToolPackage} with the given revision and hardcoded defaults - * for everything else. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MockToolPackage(SdkSource source, int revision, int minPlatformToolsRev) { - super( - source, // source, - createProps(null /*version*/, minPlatformToolsRev), // props, - revision, - null, // license, - "desc", // description, - "url", // descUrl, - Os.getCurrentOs(), // archiveOs, - Arch.getCurrentArch(), // archiveArch, - "foo" // archiveOsPath - ); - } - - /** - * Creates a {@link MockToolPackage} with the given revision and hardcoded defaults - * for everything else. - * <p/> - * By design, this creates a package with one and only one archive. - */ - public MockToolPackage( - SdkSource source, - FullRevision revision, - int minPlatformToolsRev) { - super( - source, // source, - createProps(revision, minPlatformToolsRev), // props, - revision.getMajor(), - null, // license, - "desc", // description, - "url", // descUrl, - Os.getCurrentOs(), // archiveOs, - Arch.getCurrentArch(), // archiveArch, - "foo" // archiveOsPath - ); - } - - private static Properties createProps(FullRevision revision, int minPlatformToolsRev) { - Properties props = FullRevisionPackageTest.createProps(revision); - props.setProperty(PkgProps.MIN_PLATFORM_TOOLS_REV, - Integer.toString((minPlatformToolsRev))); - return props; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/PackageTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/PackageTest.java deleted file mode 100755 index f4d7b56..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/PackageTest.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.BrokenPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkRepoSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Properties; - -import junit.framework.TestCase; - -public class PackageTest extends TestCase { - - protected static final String LOCAL_ARCHIVE_PATH = "/local/archive/path"; - - /** Local class used to test the abstract Package class */ - protected static class MockPackage extends MajorRevisionPackage { - public MockPackage( - SdkSource source, - Properties props, - int revision, - String license, - String description, - String descUrl, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - super(source, - props, - revision, - license, - description, - descUrl, - archiveOs, - archiveArch, - archiveOsPath); - } - - @Override - public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public String getListDescription() { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public String getShortDescription() { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public boolean sameItemAs(Package pkg) { - throw new UnsupportedOperationException("abstract method not used in test"); //$NON-NLS-1$ - } - - @Override - public String installId() { - return "mock-pkg"; //$NON-NLS-1$ - } - } - - public void testCreate() throws Exception { - Properties props = createProps(); - - Package p = new MockPackage( - null, //source - props, - -1, //revision - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - LOCAL_ARCHIVE_PATH //archiveOsPath - ); - - testCreatedPackage(p); - } - - public void testSaveProperties() throws Exception { - Properties props = createProps(); - - Package p = new MockPackage( - null, //source - props, - -1, //revision - null, //license - null, //description - null, //descUrl - Os.ANY, //archiveOs - Arch.ANY, //archiveArch - LOCAL_ARCHIVE_PATH //archiveOsPath - ); - - Properties props2 = new Properties(); - p.saveProperties(props2); - - assertEquals(props2, props); - } - - /** - * Sets the properties used by {@link #testCreate()} and - * {@link #testSaveProperties()}. - * This is protected and used by derived classes to perform - * a similar creation test. - */ - protected Properties createProps() { - Properties props = new Properties(); - - // Package properties - props.setProperty(PkgProps.PKG_REVISION, "42"); - props.setProperty(PkgProps.PKG_LICENSE, "The License"); - props.setProperty(PkgProps.PKG_DESC, "Some description."); - props.setProperty(PkgProps.PKG_DESC_URL, "http://description/url"); - props.setProperty(PkgProps.PKG_RELEASE_NOTE, "Release Note"); - props.setProperty(PkgProps.PKG_RELEASE_URL, "http://release/note"); - props.setProperty(PkgProps.PKG_SOURCE_URL, "http://source/url"); - props.setProperty(PkgProps.PKG_OBSOLETE, "true"); - return props; - } - - /** - * Tests the values set via {@link #createProps()} after the - * package has been created in {@link #testCreate()}. - * This is protected and used by derived classes to perform - * a similar creation test. - */ - protected void testCreatedPackage(Package p) { - // Package properties - assertEquals("42", p.getRevision().toShortString()); - assertEquals("The License", p.getLicense()); - assertEquals("Some description.", p.getDescription()); - assertEquals("http://description/url", p.getDescUrl()); - assertEquals("Release Note", p.getReleaseNote()); - assertEquals("http://release/note", p.getReleaseNoteUrl()); - assertEquals(new SdkRepoSource("http://source/url", null /*uiName*/), p.getParentSource()); - assertTrue(p.isObsolete()); - - assertNotNull(p.getArchives()); - assertEquals(1, p.getArchives().length); - Archive a = p.getArchives()[0]; - assertNotNull(a); - assertEquals(Os.ANY, a.getOs()); - assertEquals(Arch.ANY, a.getArch()); - assertEquals(LOCAL_ARCHIVE_PATH, a.getLocalOsPath()); - } - - // ---- - - public void testCompareTo() throws Exception { - ArrayList<Package> list = new ArrayList<Package>(); - MockPlatformPackage p1; - - list.add(p1 = new MockPlatformPackage(1, 2)); - list.add(new MockAddonPackage(p1, 3)); - list.add(new MockSystemImagePackage(p1, 4, "x86")); - list.add(new MockBrokenPackage(BrokenPackage.MIN_API_LEVEL_NOT_SPECIFIED, 1)); - list.add(new MockExtraPackage("vendor", "path", 5, 6)); - list.add(new MockToolPackage(7, 8)); - - Collections.sort(list); - - assertEquals( - "[Android SDK Tools, revision 7, " + - "SDK Platform Android android-1, API 1, revision 2, " + - "Intel x86 Atom System Image, Android API 1, revision 4, " + - "addon, Android API 1, revision 3, " + - "Broken package for API 1, " + - "Vendor Path, revision 5]", - Arrays.toString(list.toArray())); - } - - public void testGetPropertyInt() { - Properties p = new Properties(); - - assertEquals(42, Package.getPropertyInt(p, "key", 42)); - - p.setProperty("key", ""); - assertEquals(43, Package.getPropertyInt(p, "key", 43)); - - p.setProperty("key", "I am not a number"); - assertEquals(44, Package.getPropertyInt(p, "key", 44)); - - p.setProperty("key", "6"); - assertEquals(6, Package.getPropertyInt(p, "key", 45)); - } - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/PlatformPackageTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/PlatformPackageTest.java deleted file mode 100755 index acb57ee..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/PlatformPackageTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.internal.repository.MockPlatformTarget; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.repository.PkgProps; - -import java.util.Properties; - -public class PlatformPackageTest extends MinToolsPackageTest { - - /** - * PlatformPackage implicitly generates a local archive wrapper - * that matches the current platform OS and architecture. Since this - * is not convenient for testing, this class overrides it to always - * create archives for any OS and any architecture. - */ - private static class PlatformPackageWithFakeArchive extends PlatformPackage { - protected PlatformPackageWithFakeArchive(IAndroidTarget target, Properties props) { - super(target, props); - } - - @Override - protected Archive[] initializeArchives( - Properties props, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - assert archiveOs == Os.getCurrentOs(); - assert archiveArch == Arch.getCurrentArch(); - return super.initializeArchives(props, Os.ANY, Arch.ANY, LOCAL_ARCHIVE_PATH); - } - } - - private PlatformPackage createPlatformPackage(Properties props) { - PlatformPackage p = new PlatformPackageWithFakeArchive( - new MockPlatformTarget(5 /*apiLevel*/, 1 /*revision*/), - props); - - return p; - } - - @Override - protected Properties createProps() { - Properties props = super.createProps(); - - // PlatformPackage properties - props.setProperty(PkgProps.VERSION_API_LEVEL, "5"); - props.setProperty(PkgProps.PLATFORM_VERSION, "android-5"); - props.setProperty(PkgProps.PLATFORM_INCLUDED_ABI, "armeabi"); - - return props; - } - - protected void testCreatedPlatformPackage(PlatformPackage p) { - super.testCreatedPackage(p); - - // Package properties - assertEquals("API 5", p.getAndroidVersion().toString()); - assertEquals("armeabi", p.getIncludedAbi()); - } - - // ---- - - @Override - public final void testCreate() { - Properties props = createProps(); - PlatformPackage p = createPlatformPackage(props); - - testCreatedPlatformPackage(p); - } - - @Override - public void testSaveProperties() { - Properties props = createProps(); - PlatformPackage p = createPlatformPackage(props); - - Properties props2 = new Properties(); - p.saveProperties(props2); - - assertEquals(props2.toString(), props.toString()); - assertEquals(props2, props); - } - - public void testInstallId() { - Properties props = createProps(); - PlatformPackage p = createPlatformPackage(props); - - assertEquals("android-5", p.installId()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/SourcePackageTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/SourcePackageTest.java deleted file mode 100755 index d87eab3..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/SourcePackageTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.AndroidVersion.AndroidVersionException; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.SourcePackage; -import com.android.sdklib.repository.PkgProps; - -import java.util.Properties; - -public class SourcePackageTest extends PackageTest { - - /** - * SourcePackageTest implicitly generates a local archive wrapper - * that matches the current platform OS and architecture. Since this - * is not convenient for testing, this class overrides it to always - * create archives for any OS and any architecture. - */ - private static class SourcePackageFakeArchive extends SourcePackage { - protected SourcePackageFakeArchive( - AndroidVersion platformVersion, - int revision, - Properties props) { - super(platformVersion, - revision, - props, - String.format("/sdk/sources/android-%s", platformVersion.getApiString())); - } - - @Override - protected Archive[] initializeArchives( - Properties props, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - assert archiveOs == Os.getCurrentOs(); - assert archiveArch == Arch.getCurrentArch(); - return super.initializeArchives(props, Os.ANY, Arch.ANY, LOCAL_ARCHIVE_PATH); - } - } - - private SourcePackage createSourcePackageTest(Properties props) throws AndroidVersionException { - SourcePackage p = new SourcePackageFakeArchive( - new AndroidVersion(props), - 1 /*revision*/, - props); - return p; - } - - @Override - protected Properties createProps() { - Properties props = super.createProps(); - - // SourcePackageTest properties - props.setProperty(PkgProps.VERSION_API_LEVEL, "5"); - - return props; - } - - protected void testCreatedSourcePackageTest(SourcePackage p) { - super.testCreatedPackage(p); - - // SourcePackageTest properties - assertEquals("API 5", p.getAndroidVersion().toString()); - } - - // ---- - - @Override - public final void testCreate() throws Exception { - Properties props = createProps(); - SourcePackage p = createSourcePackageTest(props); - - testCreatedSourcePackageTest(p); - } - - @Override - public void testSaveProperties() throws Exception { - Properties props = createProps(); - SourcePackage p = createSourcePackageTest(props); - - Properties props2 = new Properties(); - p.saveProperties(props2); - - assertEquals(props2, props); - } - - public void testSameItemAs() throws Exception { - Properties props1 = createProps(); - SourcePackage p1 = createSourcePackageTest(props1); - assertTrue(p1.sameItemAs(p1)); - - // different version - Properties props2 = new Properties(props1); - props2.setProperty(PkgProps.VERSION_API_LEVEL, "6"); - SourcePackage p2 = createSourcePackageTest(props2); - assertFalse(p1.sameItemAs(p2)); - assertFalse(p2.sameItemAs(p1)); - } - - public void testInstallId() throws Exception { - Properties props = createProps(); - SourcePackage p = createSourcePackageTest(props); - - assertEquals("source-5", p.installId()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/SystemImagePackageTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/SystemImagePackageTest.java deleted file mode 100755 index c32b81f..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/packages/SystemImagePackageTest.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.packages; - -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.AndroidVersion.AndroidVersionException; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.Archive.Arch; -import com.android.sdklib.internal.repository.archives.Archive.Os; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.repository.PkgProps; - -import java.util.Properties; - -public class SystemImagePackageTest extends PackageTest { - - /** - * SystemImagePackage implicitly generates a local archive wrapper - * that matches the current platform OS and architecture. Since this - * is not convenient for testing, this class overrides it to always - * create archives for any OS and any architecture. - */ - private static class SysImgPackageFakeArchive extends SystemImagePackage { - protected SysImgPackageFakeArchive( - AndroidVersion platformVersion, - int revision, - String abi, - Properties props) { - super(platformVersion, - revision, - abi, - props, - String.format("/sdk/system-images/android-%s/%s", - platformVersion.getApiString(), abi)); - } - - @Override - protected Archive[] initializeArchives( - Properties props, - Os archiveOs, - Arch archiveArch, - String archiveOsPath) { - assert archiveOs == Os.getCurrentOs(); - assert archiveArch == Arch.getCurrentArch(); - return super.initializeArchives(props, Os.ANY, Arch.ANY, LOCAL_ARCHIVE_PATH); - } - } - - private SystemImagePackage createSystemImagePackage(Properties props) - throws AndroidVersionException { - SystemImagePackage p = new SysImgPackageFakeArchive( - new AndroidVersion(props), - 1 /*revision*/, - null /*abi*/, - props); - return p; - } - - @Override - protected Properties createProps() { - Properties props = super.createProps(); - - // SystemImagePackage properties - props.setProperty(PkgProps.VERSION_API_LEVEL, "5"); - props.setProperty(PkgProps.SYS_IMG_ABI, "armeabi-v7a"); - - return props; - } - - protected void testCreatedSystemImagePackage(SystemImagePackage p) { - super.testCreatedPackage(p); - - // SystemImagePackage properties - assertEquals("API 5", p.getAndroidVersion().toString()); - assertEquals("armeabi-v7a", p.getAbi()); - } - - // ---- - - @Override - public final void testCreate() throws Exception { - Properties props = createProps(); - SystemImagePackage p = createSystemImagePackage(props); - - testCreatedSystemImagePackage(p); - } - - @Override - public void testSaveProperties() throws Exception { - Properties props = createProps(); - SystemImagePackage p = createSystemImagePackage(props); - - Properties props2 = new Properties(); - p.saveProperties(props2); - - assertEquals(props2, props); - } - - public void testSameItemAs() throws Exception { - Properties props1 = createProps(); - SystemImagePackage p1 = createSystemImagePackage(props1); - assertTrue(p1.sameItemAs(p1)); - - // different abi, same version - Properties props2 = new Properties(props1); - props2.setProperty(PkgProps.SYS_IMG_ABI, "x86"); - SystemImagePackage p2 = createSystemImagePackage(props2); - assertFalse(p1.sameItemAs(p2)); - assertFalse(p2.sameItemAs(p1)); - - // different abi, different version - props2.setProperty(PkgProps.VERSION_API_LEVEL, "6"); - p2 = createSystemImagePackage(props2); - assertFalse(p1.sameItemAs(p2)); - assertFalse(p2.sameItemAs(p1)); - - // same abi, different version - Properties props3 = new Properties(props1); - props3.setProperty(PkgProps.VERSION_API_LEVEL, "6"); - SystemImagePackage p3 = createSystemImagePackage(props3); - assertFalse(p1.sameItemAs(p3)); - assertFalse(p3.sameItemAs(p1)); - } - - public void testInstallId() throws Exception { - Properties props = createProps(); - SystemImagePackage p = createSystemImagePackage(props); - - assertEquals("sysimg-5", p.installId()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java deleted file mode 100755 index 046cd1d..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkAddonSourceTest.java +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.MockEmptySdkManager; -import com.android.sdklib.internal.repository.MockMonitor; -import com.android.sdklib.internal.repository.packages.AddonPackage; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.IMinToolsDependency; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkAddonSource; -import com.android.sdklib.repository.SdkAddonConstants; -import com.android.utils.Pair; - -import org.w3c.dom.Document; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; - -import junit.framework.TestCase; - -/** - * Tests for {@link SdkAddonSource}. - */ -public class SdkAddonSourceTest extends TestCase { - - /** - * An internal helper class to give us visibility to the protected members we want - * to test. - */ - private static class MockSdkAddonSource extends SdkAddonSource { - public MockSdkAddonSource() { - super("fake-url", null /*uiName*/); - } - - public Document _findAlternateToolsXml(InputStream xml) { - return super.findAlternateToolsXml(xml); - } - - public boolean _parsePackages(Document doc, String nsUri, ITaskMonitor monitor) { - return super.parsePackages(doc, nsUri, monitor); - } - - public int _getXmlSchemaVersion(InputStream xml) { - return super.getXmlSchemaVersion(xml); - } - - public String _validateXml(InputStream xml, String url, int version, - String[] outError, Boolean[] validatorFound) { - return super.validateXml(xml, url, version, outError, validatorFound); - } - - public Document _getDocument(InputStream xml, ITaskMonitor monitor) { - return super.getDocument(xml, monitor); - } - - } - - private MockSdkAddonSource mSource; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mSource = new MockSdkAddonSource(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - mSource = null; - } - - public void testFindAlternateToolsXml_Errors() throws Exception { - // Support null as input - Document result = mSource._findAlternateToolsXml(null); - assertNull(result); - - // Support an empty input - String str = ""; - ByteArrayInputStream input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertNull(result); - - // Support a random string as input - str = "Some random string, not even HTML nor XML"; - input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertNull(result); - - // Support an HTML input, e.g. a typical 404 document as returned by DL - str = "<html><head> " + - "<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"> " + - "<title>404 Not Found</title> " + "<style><!--" + "body {font-family: arial,sans-serif}" + - "div.nav { ... blah blah more css here ... color: green}" + - "//--></style> " + "<script><!--" + "var rc=404;" + "//-->" + "</script> " + "</head> " + - "<body text=#000000 bgcolor=#ffffff> " + - "<table border=0 cellpadding=2 cellspacing=0 width=100%><tr><td rowspan=3 width=1% nowrap> " + - "<b><font face=times color=#0039b6 size=10>G</font><font face=times color=#c41200 size=10>o</font><font face=times color=#f3c518 size=10>o</font><font face=times color=#0039b6 size=10>g</font><font face=times color=#30a72f size=10>l</font><font face=times color=#c41200 size=10>e</font> </b> " + - "<td> </td></tr> " + - "<tr><td bgcolor=\"#3366cc\"><font face=arial,sans-serif color=\"#ffffff\"><b>Error</b></td></tr> " + - "<tr><td> </td></tr></table> " + "<blockquote> " + "<H1>Not Found</H1> " + - "The requested URL <code>/404</code> was not found on this server." + " " + "<p> " + - "</blockquote> " + - "<table width=100% cellpadding=0 cellspacing=0><tr><td bgcolor=\"#3366cc\"><img alt=\"\" width=1 height=4></td></tr></table> " + - "</body></html> "; - input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertNull(result); - - // Support some random XML document, totally unrelated to our sdk-repository schema - str = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + - "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"" + - " package=\"some.cool.app\" android:versionName=\"1.6.04\" android:versionCode=\"1604\">" + - " <application android:label=\"@string/app_name\" android:icon=\"@drawable/icon\"/>" + - "</manifest>"; - input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertNull(result); - } - - /** - * Validate that findAlternateToolsXml doesn't work for addon even - * when trying to load a valid addon xml. - */ - public void testFindAlternateToolsXml_1() throws Exception { - InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_1.xml"); - - Document result = mSource._findAlternateToolsXml(xmlStream); - assertNull(result); - } - - /** - * Validate we can load a valid add-on schema version 1 - */ - public void testLoadAddonXml_1() throws Exception { - InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_1.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(1, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkAddonConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkAddonConstants.getSchemaUri(1), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found My First add-on, Android API 1, revision 1\n" + - "Found My Second add-on, Android API 2, revision 42\n" + - "Found This add-on has no libraries, Android API 4, revision 3\n" + - "Found G USB Driver, revision 43 (Obsolete)\n" + - "Found Android Vendor Extra API Dep, revision 2 (Obsolete)\n" + - "Found Unknown Extra, revision 2 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 11 packages with each at least - // one archive. - Package[] pkgs = mSource.getPackages(); - assertEquals(6, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the extra packages path, vendor, install folder - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - extraPaths.add(ep.getPath()); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - } - } - assertEquals( - "[extra_api_dep, usb_driver, extra0000005f]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[android_vendor/android_vendor, " + - "g/g, " + - "vendor0000005f/____]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - ("[SDK/extras/android_vendor/extra_api_dep, " + - "SDK/extras/g/usb_driver, " + - "SDK/extras/vendor0000005f/extra0000005f]").replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - } - - /** - * Validate we can still load a valid add-on schema version 2 - */ - public void testLoadAddonXml_2() throws Exception { - InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_2.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(2, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkAddonConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkAddonConstants.getSchemaUri(2), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found My First add-on, Android API 1, revision 1\n" + - "Found My Second add-on, Android API 2, revision 42\n" + - "Found This add-on has no libraries, Android API 4, revision 3\n" + - "Found G USB Driver, revision 43 (Obsolete)\n" + - "Found Android Vendor Extra API Dep, revision 2 (Obsolete)\n" + - "Found Unknown Extra, revision 2 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 11 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(6, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the layoutlib of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - for (Package p : pkgs) { - if (p instanceof AddonPackage) { - layoutlibVers.add(((AddonPackage) p).getLayoutlibVersion()); - } - } - assertEquals( - "[Pair [first=3, second=42], " + // for #3 "This add-on has no libraries" - "Pair [first=0, second=0], " + // for #2 "My Second add-on" - "Pair [first=5, second=0]]", // for #1 "My First add-on" - Arrays.toString(layoutlibVers.toArray())); - - - // Check the extra packages path, vendor, install folder - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - extraPaths.add(ep.getPath()); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - } - } - assertEquals( - "[extra_api_dep, usb_driver, extra0000005f]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[android_vendor/android_vendor, " + - "g/g, " + - "vendor0000005f/____]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - ("[SDK/extras/android_vendor/extra_api_dep, " + - "SDK/extras/g/usb_driver, " + - "SDK/extras/vendor0000005f/extra0000005f]").replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - } - - /** - * Validate we can load a valid add-on schema version 3 - */ - public void testLoadAddonXml_3() throws Exception { - InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_3.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(3, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkAddonConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkAddonConstants.getSchemaUri(3), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found My First add-on, Android API 1, revision 1\n" + - "Found My Second add-on, Android API 2, revision 42\n" + - "Found This add-on has no libraries, Android API 4, revision 3\n" + - "Found G USB Driver, revision 43 (Obsolete)\n" + - "Found Android Vendor Extra API Dep, revision 2 (Obsolete)\n" + - "Found Unknown Extra, revision 2 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 6 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(6, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the layoutlib of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - for (Package p : pkgs) { - if (p instanceof AddonPackage) { - layoutlibVers.add(((AddonPackage) p).getLayoutlibVersion()); - } - } - assertEquals( - "[Pair [first=3, second=42], " + // for #3 "This add-on has no libraries" - "Pair [first=0, second=0], " + // for #2 "My Second add-on" - "Pair [first=5, second=0]]", // for #1 "My First add-on" - Arrays.toString(layoutlibVers.toArray())); - - - // Check the extra packages: path, vendor, install folder, old-paths - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - ArrayList<ArrayList<String>> extraFilePaths = new ArrayList<ArrayList<String>>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - // combine path and old-paths in the form "path [old_path1, old_path2]" - extraPaths.add(ep.getPath() + " " + Arrays.toString(ep.getOldPaths())); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - - ArrayList<String> filePaths = new ArrayList<String>(); - for (String filePath : ep.getProjectFiles()) { - filePaths.add(filePath); - } - extraFilePaths.add(filePaths); - } - } - assertEquals( - "[extra_api_dep [path1, old_path2, oldPath3], " + - "usb_driver [], " + - "extra0000005f []]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[android_vendor/android_vendor, " + - "g/g, " + - "vendor0000005f/____]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - ("[SDK/extras/android_vendor/extra_api_dep, " + - "SDK/extras/g/usb_driver, " + - "SDK/extras/vendor0000005f/extra0000005f]").replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - assertEquals( - "[[v8/veggies_8.jar, root.jar, dir1/dir 2 with space/mylib.jar], " + - "[], " + - "[]]", - Arrays.toString(extraFilePaths.toArray())); - } - - /** - * Validate we can load a valid add-on schema version 4 - */ - public void testLoadAddonXml_4() throws Exception { - InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_4.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(4, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkAddonConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkAddonConstants.getSchemaUri(4), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found My First add-on, Android API 1, revision 1\n" + - "Found My Second add-on, Android API 2, revision 42\n" + - "Found This add-on has no libraries, Android API 4, revision 3\n" + - "Found Random name, not an id!, revision 43 (Obsolete)\n" + - "Found Yet another extra, by Android, revision 2\n" + - "Found . -..- - .-. .-, revision 2 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 6 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(6, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the addon packages: vendor/name id vs display - ArrayList<String> addonNames = new ArrayList<String>(); - ArrayList<String> addonVendors = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof AddonPackage) { - AddonPackage ap = (AddonPackage) p; - addonNames.add(ap.getNameId() + "/" + ap.getDisplayName()); - addonVendors.add(ap.getVendorId() + "/" + ap.getDisplayVendor()); - } - } - // Addons are sorted by addon/vendor id and thus their order differs from the - // XML or the parsed package list. - assertEquals( - "[no_libs/This add-on has no libraries, " + - "My_Second_add-on/My Second add-on, " + - "My_First_add-on/My First add-on]", - Arrays.toString(addonNames.toArray())); - assertEquals( - "[Joe_Bar/Joe Bar, " + - "John_Deer/John Deer, " + - "John_Doe/John Doe]", - Arrays.toString(addonVendors.toArray())); - - // Check the layoutlib of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - for (Package p : pkgs) { - if (p instanceof AddonPackage) { - layoutlibVers.add(((AddonPackage) p).getLayoutlibVersion()); - } - } - assertEquals( - "[Pair [first=3, second=42], " + // for #3 "This add-on has no libraries" - "Pair [first=0, second=0], " + // for #2 "My Second add-on" - "Pair [first=5, second=0]]", // for #1 "My First add-on" - Arrays.toString(layoutlibVers.toArray())); - - - // Check the extra packages: path, vendor, install folder, old-paths - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - ArrayList<ArrayList<String>> extraFilePaths = new ArrayList<ArrayList<String>>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - // combine path and old-paths in the form "path [old_path1, old_path2]" - extraPaths.add(ep.getPath() + " " + Arrays.toString(ep.getOldPaths())); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - - ArrayList<String> filePaths = new ArrayList<String>(); - for (String filePath : ep.getProjectFiles()) { - filePaths.add(filePath); - } - extraFilePaths.add(filePaths); - } - } - // Extras are sorted by vendor-id/path and thus their order differs from the - // XML or the parsed package list. - assertEquals( - "[extra0000005f [], " + // for extra #3 - "extra_api_dep [path1, old_path2, oldPath3], " + // for extra #2 - "usb_driver []]", // for extra #1 - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[____/____, " + - "android_vendor/Android Vendor, " + - "cyclop/The big bus]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - ("[SDK/extras/____/extra0000005f, " + - "SDK/extras/android_vendor/extra_api_dep, " + - "SDK/extras/cyclop/usb_driver]").replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - assertEquals( - "[[], " + - "[v8/veggies_8.jar, root.jar, dir1/dir 2 with space/mylib.jar], " + - "[]]", - Arrays.toString(extraFilePaths.toArray())); - } - - /** - * Validate we can load a valid add-on schema version 5 - */ - public void testLoadAddonXml_5() throws Exception { - InputStream xmlStream = getTestResource("/com/android/sdklib/testdata/addon_sample_5.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(5, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkAddonConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkAddonConstants.getSchemaUri(5), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found My First add-on, Android API 1, revision 1\n" + - "Found My Second add-on, Android API 2, revision 42\n" + - "Found This add-on has no libraries, Android API 4, revision 3\n" + - "Found Random name, not an id!, revision 43 (Obsolete)\n" + - "Found Yet another extra, by Android, revision 2\n" + - "Found . -..- - .-. .-, revision 2 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 6 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(6, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the addon packages: vendor/name id vs display - ArrayList<String> addonNames = new ArrayList<String>(); - ArrayList<String> addonVendors = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof AddonPackage) { - AddonPackage ap = (AddonPackage) p; - addonNames.add(ap.getNameId() + "/" + ap.getDisplayName()); - addonVendors.add(ap.getVendorId() + "/" + ap.getDisplayVendor()); - } - } - // Addons are sorted by addon/vendor id and thus their order differs from the - // XML or the parsed package list. - assertEquals( - "[no_libs/This add-on has no libraries, " + - "My_Second_add-on/My Second add-on, " + - "My_First_add-on/My First add-on]", - Arrays.toString(addonNames.toArray())); - assertEquals( - "[Joe_Bar/Joe Bar, " + - "John_Deer/John Deer, " + - "John_Doe/John Doe]", - Arrays.toString(addonVendors.toArray())); - - // Check the layoutlib of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - for (Package p : pkgs) { - if (p instanceof AddonPackage) { - layoutlibVers.add(((AddonPackage) p).getLayoutlibVersion()); - } - } - assertEquals( - "[Pair [first=3, second=42], " + // for #3 "This add-on has no libraries" - "Pair [first=0, second=0], " + // for #2 "My Second add-on" - "Pair [first=5, second=0]]", // for #1 "My First add-on" - Arrays.toString(layoutlibVers.toArray())); - - - // Check the extra packages: path, vendor, install folder, old-paths - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - ArrayList<ArrayList<String>> extraFilePaths = new ArrayList<ArrayList<String>>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - // combine path and old-paths in the form "path [old_path1, old_path2]" - extraPaths.add(ep.getPath() + " " + Arrays.toString(ep.getOldPaths())); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - - ArrayList<String> filePaths = new ArrayList<String>(); - for (String filePath : ep.getProjectFiles()) { - filePaths.add(filePath); - } - extraFilePaths.add(filePaths); - } - } - // Extras are sorted by vendor-id/path and thus their order differs from the - // XML or the parsed package list. - assertEquals( - "[extra0000005f [], " + // for extra #3 - "extra_api_dep [path1, old_path2, oldPath3], " + // for extra #2 - "usb_driver []]", // for extra #1 - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[____/____, " + - "android_vendor/Android Vendor, " + - "cyclop/The big bus]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - ("[SDK/extras/____/extra0000005f, " + - "SDK/extras/android_vendor/extra_api_dep, " + - "SDK/extras/cyclop/usb_driver]").replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - assertEquals( - "[[], " + - "[v8/veggies_8.jar, root.jar, dir1/dir 2 with space/mylib.jar], " + - "[]]", - Arrays.toString(extraFilePaths.toArray())); - - - // Check the min-tools-rev - ArrayList<String> minToolsRevs = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof IMinToolsDependency) { - minToolsRevs.add(p.getListDescription() + ": " + - ((IMinToolsDependency) p).getMinToolsRevision().toShortString()); - } - } - assertEquals( - "[. -..- - .-. .- (Obsolete): 3.0.1, " + - "Yet another extra, by Android: 3, " + - "Random name, not an id! (Obsolete): 3.2.1 rc42]", - Arrays.toString(minToolsRevs.toArray())); - } - - /** - * Returns an SdkLib file resource as a {@link ByteArrayInputStream}, - * which has the advantage that we can use {@link InputStream#reset()} on it - * at any time to read it multiple times. - * <p/> - * The default for getResourceAsStream() is to return a {@link FileInputStream} that - * does not support reset(), yet we need it in the tested code. - * - * @throws IOException if some I/O read fails - */ - private ByteArrayInputStream getTestResource(String filename) throws IOException { - InputStream xmlStream = this.getClass().getResourceAsStream(filename); - - try { - byte[] data = new byte[8192]; - int offset = 0; - int n; - - while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) { - offset += n; - - if (offset == data.length) { - byte[] newData = new byte[offset + 8192]; - System.arraycopy(data, 0, newData, 0, offset); - data = newData; - } - } - - return new ByteArrayInputStream(data, 0, offset); - } finally { - if (xmlStream != null) { - xmlStream.close(); - } - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkRepoSourceTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkRepoSourceTest.java deleted file mode 100755 index 9df0bfd..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkRepoSourceTest.java +++ /dev/null @@ -1,1063 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.MockEmptySdkManager; -import com.android.sdklib.internal.repository.MockMonitor; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.IMinPlatformToolsDependency; -import com.android.sdklib.internal.repository.packages.IMinToolsDependency; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.internal.repository.packages.SourcePackage; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.sdklib.internal.repository.sources.SdkRepoSource; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.utils.Pair; - -import org.w3c.dom.Document; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; - -import junit.framework.TestCase; - -/** - * Tests for {@link SdkRepoSource} - */ -public class SdkRepoSourceTest extends TestCase { - - /** - * An internal helper class to give us visibility to the protected members we want - * to test. - */ - private static class MockSdkRepoSource extends SdkRepoSource { - public MockSdkRepoSource() { - super("fake-url", null /*uiName*/); - } - - /** - * Returns a pair of Document (which can be null) and the captured stdout/stderr output - * (which is the empty string by default). - */ - public Pair<Document, String> _findAlternateToolsXml(InputStream xml) throws IOException { - - final StringBuilder output = new StringBuilder(); - Document doc = super.findAlternateToolsXml(xml, new ErrorHandler() { - @Override - public void warning(SAXParseException exception) throws SAXException { - output.append("WARN: " + exception.getMessage()).append('\n'); - } - - @Override - public void fatalError(SAXParseException exception) throws SAXException { - output.append("FATAL: " + exception.getMessage()).append('\n'); - } - - @Override - public void error(SAXParseException exception) throws SAXException { - output.append("ERROR: " + exception.getMessage()).append('\n'); - } - }); - - return Pair.of(doc, output.toString()); - } - - public boolean _parsePackages(Document doc, String nsUri, ITaskMonitor monitor) { - return super.parsePackages(doc, nsUri, monitor); - } - - public int _getXmlSchemaVersion(InputStream xml) { - return super.getXmlSchemaVersion(xml); - } - - public String _validateXml(InputStream xml, String url, int version, - String[] outError, Boolean[] validatorFound) { - return super.validateXml(xml, url, version, outError, validatorFound); - } - - public Document _getDocument(InputStream xml, ITaskMonitor monitor) { - return super.getDocument(xml, monitor); - } - - } - - private MockSdkRepoSource mSource; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mSource = new MockSdkRepoSource(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - mSource = null; - } - - public void testFindAlternateToolsXml_Errors() throws Exception { - // Support null as input - Pair<Document, String> result = mSource._findAlternateToolsXml(null); - assertEquals(Pair.of((Document) null, ""), result); - - // Support an empty input - String str = ""; - ByteArrayInputStream input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertEquals( - Pair.of((Document) null, "FATAL: Premature end of file.\n"), - result); - - // Support a random string as input - str = "Some random string, not even HTML nor XML"; - input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertEquals( - Pair.of((Document) null, "FATAL: Content is not allowed in prolog.\n"), - result); - - // Support an HTML input, e.g. a typical 404 document as returned by DL - str = "<html><head> " + - "<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"> " + - "<title>404 Not Found</title> " + "<style><!--" + "body {font-family: arial,sans-serif}" + - "div.nav { ... blah blah more css here ... color: green}" + - "//--></style> " + "<script><!--" + "var rc=404;" + "//-->" + "</script> " + "</head> " + - "<body text=#000000 bgcolor=#ffffff> " + - "<table border=0 cellpadding=2 cellspacing=0 width=100%><tr><td rowspan=3 width=1% nowrap> " + - "<b><font face=times color=#0039b6 size=10>G</font><font face=times color=#c41200 size=10>o</font><font face=times color=#f3c518 size=10>o</font><font face=times color=#0039b6 size=10>g</font><font face=times color=#30a72f size=10>l</font><font face=times color=#c41200 size=10>e</font> </b> " + - "<td> </td></tr> " + - "<tr><td bgcolor=\"#3366cc\"><font face=arial,sans-serif color=\"#ffffff\"><b>Error</b></td></tr> " + - "<tr><td> </td></tr></table> " + "<blockquote> " + "<H1>Not Found</H1> " + - "The requested URL <code>/404</code> was not found on this server." + " " + "<p> " + - "</blockquote> " + - "<table width=100% cellpadding=0 cellspacing=0><tr><td bgcolor=\"#3366cc\"><img alt=\"\" width=1 height=4></td></tr></table> " + - "</body></html> "; - input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertEquals( - Pair.of((Document) null, "FATAL: The element type \"meta\" must be terminated by the matching end-tag \"</meta>\".\n"), - result); - - // Support some random XML document, totally unrelated to our sdk-repository schema - str = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + - "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"" + - " package=\"some.cool.app\" android:versionName=\"1.6.04\" android:versionCode=\"1604\">" + - " <application android:label=\"@string/app_name\" android:icon=\"@drawable/icon\"/>" + - "</manifest>"; - input = new ByteArrayInputStream(str.getBytes()); - result = mSource._findAlternateToolsXml(input); - assertEquals(Pair.of((Document) null, ""), result); - } - - /** - * Validate we can load a new schema version 3 using the "alternate future tool" mode. - */ - public void testFindAlternateToolsXml_3() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_3.xml"); - - Pair<Document, String> result = mSource._findAlternateToolsXml(xmlStream); - assertNotNull(result.getFirst()); - assertEquals("", result.getSecond()); - MockMonitor monitor = new MockMonitor(); - assertTrue(mSource._parsePackages(result.getFirst(), SdkRepoConstants.NS_URI, monitor)); - - assertEquals("Found Android SDK Tools, revision 1\n" + - "Found Android SDK Tools, revision 42\n" + - "Found Android SDK Platform-tools, revision 3\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 2 tool packages and 1 - // platform-tools package, with at least 1 archive each. - Package[] pkgs = mSource.getPackages(); - assertEquals(3, pkgs.length); - for (Package p : pkgs) { - assertTrue((p instanceof ToolPackage) || (p instanceof PlatformToolPackage)); - assertTrue(p.getArchives().length >= 1); - } - } - - /** - * Validate we can still load an old repository in schema version 1 - */ - public void testLoadXml_1() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_1.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(1, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkRepoConstants.getSchemaUri(1), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + - "Found Documentation for Android SDK, API 1, revision 1\n" + - "Found My First add-on, Android API 1, revision 1\n" + - "Found SDK Platform Android 1.1, API 2, revision 12\n" + - "Found My Second add-on, Android API 2, revision 42\n" + - "Found SDK Platform Android Pastry Preview, revision 3\n" + - "Found Android SDK Tools, revision 1\n" + - "Found Documentation for Android SDK, API 2, revision 42\n" + - "Found Android SDK Tools, revision 42\n" + - "Found This add-on has no libraries, Android API 4, revision 3\n" + - "Found Usb Driver, revision 43\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 11 packages with each at least - // one archive. - Package[] pkgs = mSource.getPackages(); - assertEquals(11, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the extra packages path, vendor, install folder - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - extraPaths.add(ep.getPath()); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - } - } - assertEquals( - "[usb_driver]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[/]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - "[SDK/extras/usb_driver]".replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - } - - /** - * Validate we can still load an old repository in schema version 2 - */ - public void testLoadXml_2() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_2.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(2, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkRepoConstants.getSchemaUri(2), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + - "Found Documentation for Android SDK, API 1, revision 1\n" + - "Found My First add-on, Android API 1, revision 1\n" + - "Found SDK Platform Android 1.1, API 2, revision 12\n" + - "Found My Second add-on, Android API 2, revision 42\n" + - "Found SDK Platform Android Pastry Preview, revision 3\n" + - "Found Android SDK Tools, revision 1\n" + - "Found Documentation for Android SDK, API 2, revision 42\n" + - "Found Android SDK Tools, revision 42\n" + - "Found This add-on has no libraries, Android API 4, revision 3\n" + - "Found Usb Driver, revision 43 (Obsolete)\n" + - "Found Extra API Dep, revision 2 (Obsolete)\n" + - "Found Samples for SDK API 14, revision 24 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 13 packages with each at least - // one archive. - Package[] pkgs = mSource.getPackages(); - assertEquals(13, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the extra packages path, vendor, install folder - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - extraPaths.add(ep.getPath()); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - } - } - assertEquals( - "[extra_api_dep, usb_driver]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[/, /]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - "[SDK/extras/extra_api_dep, SDK/extras/usb_driver]".replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - } - - /** - * Validate what we can load from repository in schema version 3 - */ - public void testLoadXml_3() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_3.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(3, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkRepoConstants.getSchemaUri(3), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + - "Found Documentation for Android SDK, API 1, revision 1\n" + - "Found SDK Platform Android 1.1, API 2, revision 12\n" + - "Found SDK Platform Android Pastry Preview, revision 3\n" + - "Found Android SDK Tools, revision 1\n" + - "Found Documentation for Android SDK, API 2, revision 42\n" + - "Found Android SDK Tools, revision 42\n" + - "Found Android SDK Platform-tools, revision 3\n" + - "Found A USB Driver, revision 43 (Obsolete)\n" + - "Found Android Vendor Extra API Dep, revision 2 (Obsolete)\n" + - "Found Samples for SDK API 14, revision 24 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 13 packages with each at least - // one archive. - Package[] pkgs = mSource.getPackages(); - assertEquals(11, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the extra packages path, vendor, install folder - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - extraPaths.add(ep.getPath()); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - } - } - assertEquals( - "[extra_api_dep, usb_driver]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[android_vendor/android_vendor, a/a]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - "[SDK/extras/android_vendor/extra_api_dep, SDK/extras/a/usb_driver]" - .replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - } - - /** - * Validate what we can load from repository in schema version 4 - */ - public void testLoadXml_4() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_4.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(4, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkRepoConstants.getSchemaUri(4), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + - "Found Documentation for Android SDK, API 1, revision 1\n" + - "Found SDK Platform Android 1.1, API 2, revision 12\n" + - "Found SDK Platform Android Pastry Preview, revision 3\n" + - "Found Android SDK Tools, revision 1\n" + - "Found Documentation for Android SDK, API 2, revision 42\n" + - "Found Android SDK Tools, revision 42\n" + - "Found Android SDK Platform-tools, revision 3\n" + - "Found A USB Driver, revision 43 (Obsolete)\n" + - "Found Android Vendor Extra API Dep, revision 2 (Obsolete)\n" + - "Found Samples for SDK API 14, revision 24 (Obsolete)\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 13 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(11, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the layoutlib of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - for (Package p : pkgs) { - if (p instanceof PlatformPackage) { - layoutlibVers.add(((PlatformPackage) p).getLayoutlibVersion()); - } - } - assertEquals( - "[Pair [first=1, second=0], " + // platform API 5 preview - "Pair [first=5, second=31415], " + // platform API 2 - "Pair [first=5, second=0]]", // platform API 1 - Arrays.toString(layoutlibVers.toArray())); - - // Check the extra packages path, vendor, install folder and project-files - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - ArrayList<ArrayList<String>> extraFilePaths = new ArrayList<ArrayList<String>>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - extraPaths.add(ep.getPath()); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - - ArrayList<String> filePaths = new ArrayList<String>(); - for (String filePath : ep.getProjectFiles()) { - filePaths.add(filePath); - } - extraFilePaths.add(filePaths); - } - } - assertEquals( - "[extra_api_dep, usb_driver]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[android_vendor/android_vendor, a/a]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - "[SDK/extras/android_vendor/extra_api_dep, SDK/extras/a/usb_driver]" - .replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - assertEquals( - "[[v8/veggies_8.jar, readme.txt, dir1/dir 2 with space/mylib.jar], " + - "[]]", - Arrays.toString(extraFilePaths.toArray())); - } - - /** - * Validate what we can load from repository in schema version 5 - */ - public void testLoadXml_5() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_5.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(5, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkRepoConstants.getSchemaUri(5), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + - "Found Documentation for Android SDK, API 1, revision 1\n" + - "Found Sources for Android SDK, API 1, revision 1\n" + - "Found SDK Platform Android 1.1, API 2, revision 12\n" + - "Found Intel x86 Atom System Image, Android API 2, revision 1\n" + - "Found ARM EABI v7a System Image, Android API 2, revision 2\n" + - "Found Sources for Android SDK, API 2, revision 2\n" + - "Found SDK Platform Android Pastry Preview, revision 3\n" + - "Found Android SDK Tools, revision 1\n" + - "Found Documentation for Android SDK, API 2, revision 42\n" + - "Found Android SDK Tools, revision 42\n" + - "Found Android SDK Platform-tools, revision 3\n" + - "Found A USB Driver, revision 43 (Obsolete)\n" + - "Found Android Vendor Extra API Dep, revision 2 (Obsolete)\n" + - "Found Samples for SDK API 14, revision 24 (Obsolete)\n" + - "Found ARM EABI System Image, Android API 42, revision 12\n" + - "Found Sources for Android SDK, API 42, revision 12\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 13 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(17, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the layoutlib & included-abi of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - ArrayList<String> includedAbi = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof PlatformPackage) { - layoutlibVers.add(((PlatformPackage) p).getLayoutlibVersion()); - String abi = ((PlatformPackage) p).getIncludedAbi(); - includedAbi.add(abi == null ? "(null)" : abi); - } - } - assertEquals( - "[Pair [first=1, second=0], " + // platform API 5 preview - "Pair [first=5, second=31415], " + // platform API 2 - "Pair [first=5, second=0]]", // platform API 1 - Arrays.toString(layoutlibVers.toArray())); - assertEquals( - "[(null), " + // platform API 5 preview - "x86, " + // platform API 2 - "armeabi]", // platform API 1 - Arrays.toString(includedAbi.toArray())); - - // Check the extra packages path, vendor, install folder, project-files, old-paths - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - ArrayList<ArrayList<String>> extraFilePaths = new ArrayList<ArrayList<String>>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - // combine path and old-paths in the form "path [old_path1, old_path2]" - extraPaths.add(ep.getPath() + " " + Arrays.toString(ep.getOldPaths())); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - - ArrayList<String> filePaths = new ArrayList<String>(); - for (String filePath : ep.getProjectFiles()) { - filePaths.add(filePath); - } - extraFilePaths.add(filePaths); - } - } - assertEquals( - "[extra_api_dep [path1, old_path2, oldPath3], " + - "usb_driver []]", - Arrays.toString(extraPaths.toArray())); - assertEquals( - "[android_vendor/android_vendor, " + - "a/a]", - Arrays.toString(extraVendors.toArray())); - assertEquals( - ("[SDK/extras/android_vendor/extra_api_dep, " + - "SDK/extras/a/usb_driver]").replace('/', File.separatorChar), - Arrays.toString(extraInstall.toArray())); - assertEquals( - "[[v8/veggies_8.jar, readme.txt, dir1/dir 2 with space/mylib.jar], " + - "[]]", - Arrays.toString(extraFilePaths.toArray())); - - // Check the system-image packages - ArrayList<String> sysImgVersionAbi = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof SystemImagePackage) { - SystemImagePackage sip = (SystemImagePackage) p; - String v = sip.getAndroidVersion().getApiString(); - String a = sip.getAbi(); - sysImgVersionAbi.add(String.format("%1$s %2$s", v, a)); //$NON-NLS-1$ - } - } - assertEquals( - "[42 armeabi, " + - "2 armeabi-v7a, " + - "2 x86]", - Arrays.toString(sysImgVersionAbi.toArray())); - - // Check the source packages - ArrayList<String> sourceVersion = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof SourcePackage) { - SourcePackage sp = (SourcePackage) p; - String v = sp.getAndroidVersion().getApiString(); - sourceVersion.add(v); - } - } - assertEquals( - "[42, 2, 1]", - Arrays.toString(sourceVersion.toArray())); - } - - /** - * Validate what we can load from repository in schema version 6 - */ - public void testLoadXml_6() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_6.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(6, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkRepoConstants.getSchemaUri(6), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + - "Found Documentation for Android SDK, API 1, revision 1\n" + - "Found Sources for Android SDK, API 1, revision 1\n" + - "Found SDK Platform Android 1.1, API 2, revision 12\n" + - "Found Intel x86 Atom System Image, Android API 2, revision 1\n" + - "Found ARM EABI v7a System Image, Android API 2, revision 2\n" + - "Found Sources for Android SDK, API 2, revision 2\n" + - "Found SDK Platform Android Pastry Preview, revision 3\n" + - "Found Android SDK Tools, revision 1\n" + - "Found Documentation for Android SDK, API 2, revision 42\n" + - "Found Android SDK Tools, revision 42\n" + - "Found Android SDK Platform-tools, revision 3\n" + - "Found Samples for SDK API 14, revision 24 (Obsolete)\n" + - "Found ARM EABI System Image, Android API 42, revision 12\n" + - "Found MIPS System Image, Android API 42, revision 12\n" + - "Found Sources for Android SDK, API 42, revision 12\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 13 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(16, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the layoutlib & included-abi of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - ArrayList<String> includedAbi = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof PlatformPackage) { - layoutlibVers.add(((PlatformPackage) p).getLayoutlibVersion()); - String abi = ((PlatformPackage) p).getIncludedAbi(); - includedAbi.add(abi == null ? "(null)" : abi); - } - } - assertEquals( - "[Pair [first=1, second=0], " + // platform API 5 preview - "Pair [first=5, second=31415], " + // platform API 2 - "Pair [first=5, second=0]]", // platform API 1 - Arrays.toString(layoutlibVers.toArray())); - assertEquals( - "[(null), " + // platform API 5 preview - "x86, " + // platform API 2 - "armeabi]", // platform API 1 - Arrays.toString(includedAbi.toArray())); - - // Check the extra packages path, vendor, install folder, project-files, old-paths - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - ArrayList<ArrayList<String>> extraFilePaths = new ArrayList<ArrayList<String>>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - // combine path and old-paths in the form "path [old_path1, old_path2]" - extraPaths.add(ep.getPath() + " " + Arrays.toString(ep.getOldPaths())); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - - ArrayList<String> filePaths = new ArrayList<String>(); - for (String filePath : ep.getProjectFiles()) { - filePaths.add(filePath); - } - extraFilePaths.add(filePaths); - } - } - - // There are no extra packages anymore in repository-6 - assertEquals("[]", Arrays.toString(extraPaths.toArray())); - assertEquals("[]", Arrays.toString(extraVendors.toArray())); - assertEquals("[]", Arrays.toString(extraInstall.toArray())); - assertEquals("[]", Arrays.toString(extraFilePaths.toArray())); - - // Check the system-image packages - ArrayList<String> sysImgVersionAbi = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof SystemImagePackage) { - SystemImagePackage sip = (SystemImagePackage) p; - String v = sip.getAndroidVersion().getApiString(); - String a = sip.getAbi(); - sysImgVersionAbi.add(String.format("%1$s %2$s", v, a)); //$NON-NLS-1$ - } - } - assertEquals( - "[42 armeabi, " + - "42 mips, " + - "2 armeabi-v7a, " + - "2 x86]", - Arrays.toString(sysImgVersionAbi.toArray())); - - // Check the source packages - ArrayList<String> sourceVersion = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof SourcePackage) { - SourcePackage sp = (SourcePackage) p; - String v = sp.getAndroidVersion().getApiString(); - sourceVersion.add(v); - } - } - assertEquals( - "[42, 2, 1]", - Arrays.toString(sourceVersion.toArray())); - } - - /** - * Validate what we can load from repository in schema version 6 - */ - public void testLoadXml_7() throws Exception { - InputStream xmlStream = getTestResource( - "/com/android/sdklib/testdata/repository_sample_7.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(7, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkRepoConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkRepoConstants.getSchemaUri(7), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals("Found SDK Platform Android 1.0, API 1, revision 3\n" + - "Found Documentation for Android SDK, API 1, revision 1\n" + - "Found Sources for Android SDK, API 1, revision 1\n" + - "Found SDK Platform Android 1.1, API 2, revision 12\n" + - "Found Intel x86 Atom System Image, Android API 2, revision 1\n" + - "Found ARM EABI v7a System Image, Android API 2, revision 2\n" + - "Found Sources for Android SDK, API 2, revision 2\n" + - "Found SDK Platform Android Pastry Preview, revision 3\n" + - "Found Android SDK Tools, revision 1.2.3 rc4\n" + - "Found Documentation for Android SDK, API 2, revision 42\n" + - "Found Android SDK Tools, revision 42\n" + - "Found Android SDK Platform-tools, revision 3 rc5\n" + - "Found Samples for SDK API 14, revision 24 (Obsolete)\n" + - "Found Samples for SDK API 14, revision 25 (Obsolete)\n" + - "Found ARM EABI System Image, Android API 42, revision 12\n" + - "Found MIPS System Image, Android API 42, revision 12\n" + - "Found Sources for Android SDK, API 42, revision 12\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... we expected to find 13 packages with each at least - // one archive. - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - Package[] pkgs = mSource.getPackages(); - - assertEquals(17, pkgs.length); - for (Package p : pkgs) { - assertTrue(p.getArchives().length >= 1); - } - - // Check the layoutlib & included-abi of the platform packages. - ArrayList<Pair<Integer, Integer>> layoutlibVers = new ArrayList<Pair<Integer,Integer>>(); - ArrayList<String> includedAbi = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof PlatformPackage) { - layoutlibVers.add(((PlatformPackage) p).getLayoutlibVersion()); - String abi = ((PlatformPackage) p).getIncludedAbi(); - includedAbi.add(abi == null ? "(null)" : abi); - } - } - assertEquals( - "[Pair [first=1, second=0], " + // platform API 5 preview - "Pair [first=5, second=31415], " + // platform API 2 - "Pair [first=5, second=0]]", // platform API 1 - Arrays.toString(layoutlibVers.toArray())); - assertEquals( - "[(null), " + // platform API 5 preview - "x86, " + // platform API 2 - "armeabi]", // platform API 1 - Arrays.toString(includedAbi.toArray())); - - // Check the extra packages path, vendor, install folder, project-files, old-paths - - final String osSdkPath = "SDK"; - final SdkManager sdkManager = new MockEmptySdkManager(osSdkPath); - - ArrayList<String> extraPaths = new ArrayList<String>(); - ArrayList<String> extraVendors = new ArrayList<String>(); - ArrayList<File> extraInstall = new ArrayList<File>(); - ArrayList<ArrayList<String>> extraFilePaths = new ArrayList<ArrayList<String>>(); - for (Package p : pkgs) { - if (p instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) p; - // combine path and old-paths in the form "path [old_path1, old_path2]" - extraPaths.add(ep.getPath() + " " + Arrays.toString(ep.getOldPaths())); - extraVendors.add(ep.getVendorId() + "/" + ep.getVendorDisplay()); - extraInstall.add(ep.getInstallFolder(osSdkPath, sdkManager)); - - ArrayList<String> filePaths = new ArrayList<String>(); - for (String filePath : ep.getProjectFiles()) { - filePaths.add(filePath); - } - extraFilePaths.add(filePaths); - } - } - - // There are no extra packages anymore in repository-6 - assertEquals("[]", Arrays.toString(extraPaths.toArray())); - assertEquals("[]", Arrays.toString(extraVendors.toArray())); - assertEquals("[]", Arrays.toString(extraInstall.toArray())); - assertEquals("[]", Arrays.toString(extraFilePaths.toArray())); - - - // Check the system-image packages - ArrayList<String> sysImgVersionAbi = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof SystemImagePackage) { - SystemImagePackage sip = (SystemImagePackage) p; - String v = sip.getAndroidVersion().getApiString(); - String a = sip.getAbi(); - sysImgVersionAbi.add(String.format("%1$s %2$s", v, a)); //$NON-NLS-1$ - } - } - assertEquals( - "[42 armeabi, " + - "42 mips, " + - "2 armeabi-v7a, " + - "2 x86]", - Arrays.toString(sysImgVersionAbi.toArray())); - - - // Check the source packages - ArrayList<String> sourceVersion = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof SourcePackage) { - SourcePackage sp = (SourcePackage) p; - String v = sp.getAndroidVersion().getApiString(); - sourceVersion.add(v); - } - } - assertEquals( - "[42, 2, 1]", - Arrays.toString(sourceVersion.toArray())); - - - // Check the min-tools-rev - ArrayList<String> minToolsRevs = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof IMinToolsDependency) { - minToolsRevs.add(p.getListDescription() + ": " + - ((IMinToolsDependency) p).getMinToolsRevision().toShortString()); - } - } - assertEquals( - "[SDK Platform Android Pastry Preview: 0, " + - "SDK Platform Android 1.1: 0, " + - "SDK Platform Android 1.0: 2.0.1, " + - "Samples for SDK API 14 (Obsolete): 5, " + - "Samples for SDK API 14 (Obsolete): 5.1.2 rc3]", - Arrays.toString(minToolsRevs.toArray())); - - - // Check the min-platform-tools-rev - ArrayList<String> minPlatToolsRevs = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof IMinPlatformToolsDependency) { - minPlatToolsRevs.add(p.getListDescription() + ": " + - ((IMinPlatformToolsDependency) p).getMinPlatformToolsRevision().toShortString()); - } - } - assertEquals( - "[Android SDK Tools: 4, " + - "Android SDK Tools: 4 rc5]", - Arrays.toString(minPlatToolsRevs.toArray())); - } - - /** - * Returns an SdkLib file resource as a {@link ByteArrayInputStream}, - * which has the advantage that we can use {@link InputStream#reset()} on it - * at any time to read it multiple times. - * <p/> - * The default for getResourceAsStream() is to return a {@link FileInputStream} that - * does not support reset(), yet we need it in the tested code. - * - * @throws IOException if some I/O read fails - */ - private ByteArrayInputStream getTestResource(String filename) throws IOException { - InputStream xmlStream = this.getClass().getResourceAsStream(filename); - - try { - byte[] data = new byte[8192]; - int offset = 0; - int n; - - while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) { - offset += n; - - if (offset == data.length) { - byte[] newData = new byte[offset + 8192]; - System.arraycopy(data, 0, newData, 0, offset); - data = newData; - } - } - - return new ByteArrayInputStream(data, 0, offset); - } finally { - if (xmlStream != null) { - xmlStream.close(); - } - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSourcePropertiesTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSourcePropertiesTest.java deleted file mode 100755 index 6313e69..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSourcePropertiesTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - - -import com.android.sdklib.internal.repository.sources.SdkSourceProperties; - -import junit.framework.TestCase; - -public class SdkSourcePropertiesTest extends TestCase { - - private static class MockSdkSourceProperties extends SdkSourceProperties { - private int mLoadCount; - private int mSaveCount; - - public MockSdkSourceProperties() { - clear(); - } - - public int getLoadCount() { - return mLoadCount; - } - - public int getSaveCount() { - return mSaveCount; - } - - @Override - protected boolean loadProperties() { - // Don't actually load anthing. - mLoadCount++; - return false; - } - - @Override - protected void saveLocked() { - // Don't actually save anything. - mSaveCount++; - } - } - - @Override - protected void setUp() throws Exception { - super.setUp(); - } - - public final void testSdkSourceProperties() { - MockSdkSourceProperties m = new MockSdkSourceProperties(); - - assertEquals(0, m.getLoadCount()); - assertEquals(0, m.getSaveCount()); - assertEquals( - "<SdkSourceProperties>", - m.toString()); - - assertNull(m.getProperty(SdkSourceProperties.KEY_DISABLED, "http://example.com/1", null)); - assertEquals("None", - m.getProperty(SdkSourceProperties.KEY_NAME, "http://example.com/2", "None")); - assertEquals(1, m.getLoadCount()); - assertEquals(0, m.getSaveCount()); - assertEquals( - "<SdkSourceProperties\n" + - "@version@ = 1>", - m.toString()); - - m.setProperty(SdkSourceProperties.KEY_DISABLED, "http://example.com/1", "disabled"); - assertEquals("disabled", - m.getProperty(SdkSourceProperties.KEY_DISABLED, "http://example.com/1", "None")); - assertNull(m.getProperty(SdkSourceProperties.KEY_NAME, "http://example.com/1", null)); - assertEquals( - "<SdkSourceProperties\n" + - "@disabled@http://example.com/1 = disabled\n" + - "@version@ = 1>", - m.toString()); - - m.setProperty(SdkSourceProperties.KEY_NAME, "http://example.com/2", "Site Name"); - assertEquals("Site Name", - m.getProperty(SdkSourceProperties.KEY_NAME, "http://example.com/2", null)); - assertNull(m.getProperty(SdkSourceProperties.KEY_DISABLED, "http://example.com/2", null)); - assertEquals(1, m.getLoadCount()); - assertEquals(0, m.getSaveCount()); - assertEquals( - "<SdkSourceProperties\n" + - "@disabled@http://example.com/1 = disabled\n" + - "@name@http://example.com/2 = Site Name\n" + - "@version@ = 1>", - m.toString()); - - m.save(); - assertEquals(1, m.getSaveCount()); - - // saving a 2nd time doesn't do anything if no property has been modified - m.save(); - assertEquals(1, m.getSaveCount()); - - // setting things to the same value doesn't actually mark the properties as modified - m.setProperty(SdkSourceProperties.KEY_DISABLED, "http://example.com/1", "disabled"); - m.setProperty(SdkSourceProperties.KEY_NAME, "http://example.com/2", "Site Name"); - m.save(); - assertEquals(1, m.getSaveCount()); - - m.setProperty(SdkSourceProperties.KEY_DISABLED, "http://example.com/1", "not disabled"); - m.setProperty(SdkSourceProperties.KEY_NAME, "http://example.com/2", "New Name"); - assertEquals( - "<SdkSourceProperties\n" + - "@disabled@http://example.com/1 = not disabled\n" + - "@name@http://example.com/2 = New Name\n" + - "@version@ = 1>", - m.toString()); - m.save(); - assertEquals(2, m.getSaveCount()); - - // setting a value to null deletes it - m.setProperty(SdkSourceProperties.KEY_NAME, "http://example.com/2", null); - assertEquals( - "<SdkSourceProperties\n" + - "@disabled@http://example.com/1 = not disabled\n" + - "@version@ = 1>", - m.toString()); - - m.save(); - assertEquals(1, m.getLoadCount()); - assertEquals(3, m.getSaveCount()); - } - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java deleted file mode 100755 index c080d11..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/internal/repository/sources/SdkSysImgSourceTest.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.internal.repository.sources; - -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.MockMonitor; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.repository.SdkSysImgConstants; - -import org.w3c.dom.Document; - -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; - -import junit.framework.TestCase; - -/** - * Tests for {@link SdkSysImgSource}. - */ -public class SdkSysImgSourceTest extends TestCase { - - /** - * An internal helper class to give us visibility to the protected members we want - * to test. - */ - private static class MockSdkSysImgSource extends SdkSysImgSource { - public MockSdkSysImgSource() { - super("fake-url", null /*uiName*/); - } - - public Document _findAlternateToolsXml(InputStream xml) { - return super.findAlternateToolsXml(xml); - } - - public boolean _parsePackages(Document doc, String nsUri, ITaskMonitor monitor) { - return super.parsePackages(doc, nsUri, monitor); - } - - public int _getXmlSchemaVersion(InputStream xml) { - return super.getXmlSchemaVersion(xml); - } - - public String _validateXml(InputStream xml, String url, int version, - String[] outError, Boolean[] validatorFound) { - return super.validateXml(xml, url, version, outError, validatorFound); - } - - public Document _getDocument(InputStream xml, ITaskMonitor monitor) { - return super.getDocument(xml, monitor); - } - - } - - private MockSdkSysImgSource mSource; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - mSource = new MockSdkSysImgSource(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - - mSource = null; - } - - /** - * Validate that findAlternateToolsXml doesn't work for this source even - * when trying to load a valid xml. That's because finding alternate tools - * is not supported by this kind of source. - */ - public void testFindAlternateToolsXml_1() throws Exception { - InputStream xmlStream = - getTestResource("/com/android/sdklib/testdata/sys_img_sample_1.xml"); - - Document result = mSource._findAlternateToolsXml(xmlStream); - assertNull(result); - } - - /** - * Validate we can load a valid schema version 1 - */ - public void testLoadSysImgXml_1() throws Exception { - InputStream xmlStream = - getTestResource("/com/android/sdklib/testdata/sys_img_sample_1.xml"); - - // guess the version from the XML document - int version = mSource._getXmlSchemaVersion(xmlStream); - assertEquals(1, version); - - Boolean[] validatorFound = new Boolean[] { Boolean.FALSE }; - String[] validationError = new String[] { null }; - String url = "not-a-valid-url://" + SdkSysImgConstants.URL_DEFAULT_FILENAME; - - String uri = mSource._validateXml(xmlStream, url, version, validationError, validatorFound); - assertEquals(Boolean.TRUE, validatorFound[0]); - assertEquals(null, validationError[0]); - assertEquals(SdkSysImgConstants.getSchemaUri(1), uri); - - // Validation was successful, load the document - MockMonitor monitor = new MockMonitor(); - Document doc = mSource._getDocument(xmlStream, monitor); - assertNotNull(doc); - - // Get the packages - assertTrue(mSource._parsePackages(doc, uri, monitor)); - - assertEquals( - "Found Intel x86 Atom System Image, Android API 2, revision 1\n" + - "Found ARM EABI v7a System Image, Android API 2, revision 2\n" + - "Found ARM EABI System Image, Android API 42, revision 12\n" + - "Found MIPS System Image, Android API 42, revision 12\n", - monitor.getCapturedVerboseLog()); - assertEquals("", monitor.getCapturedLog()); - assertEquals("", monitor.getCapturedErrorLog()); - - // check the packages we found... - // Note the order doesn't necessary match the one from the - // assertEquald(getCapturedVerboseLog) because packages are sorted using the - // Packages' sorting order, e.g. all platforms are sorted by descending API level, etc. - - Package[] pkgs = mSource.getPackages(); - - assertEquals(4, pkgs.length); - for (Package p : pkgs) { - // We expected to find packages with each at least one archive. - assertTrue(p.getArchives().length >= 1); - // And only system images are supported by this source - assertTrue(p instanceof SystemImagePackage); - } - - // Check the system-image packages - ArrayList<String> sysImgVersionAbi = new ArrayList<String>(); - for (Package p : pkgs) { - if (p instanceof SystemImagePackage) { - SystemImagePackage sip = (SystemImagePackage) p; - String v = sip.getAndroidVersion().getApiString(); - String a = sip.getAbi(); - sysImgVersionAbi.add(String.format("%1$s %2$s", v, a)); //$NON-NLS-1$ - } - } - assertEquals( - "[42 armeabi, " + - "42 mips, " + - "2 armeabi-v7a, " + - "2 x86]", - Arrays.toString(sysImgVersionAbi.toArray())); - - } - - - //----- - - /** - * Returns an SdkLib file resource as a {@link ByteArrayInputStream}, - * which has the advantage that we can use {@link InputStream#reset()} on it - * at any time to read it multiple times. - * <p/> - * The default for getResourceAsStream() is to return a {@link FileInputStream} that - * does not support reset(), yet we need it in the tested code. - * - * @throws IOException if some I/O read fails - */ - private ByteArrayInputStream getTestResource(String filename) throws IOException { - InputStream xmlStream = this.getClass().getResourceAsStream(filename); - - try { - byte[] data = new byte[8192]; - int offset = 0; - int n; - - while ((n = xmlStream.read(data, offset, data.length - offset)) != -1) { - offset += n; - - if (offset == data.length) { - byte[] newData = new byte[offset + 8192]; - System.arraycopy(data, 0, newData, 0, offset); - data = newData; - } - } - - return new ByteArrayInputStream(data, 0, offset); - } finally { - if (xmlStream != null) { - xmlStream.close(); - } - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/io/MockFileOp.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/io/MockFileOp.java deleted file mode 100755 index cbe5fdd..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/io/MockFileOp.java +++ /dev/null @@ -1,469 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.io; - -import com.android.SdkConstants; -import com.android.annotations.NonNull; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - - -/** - * Mock version of {@link FileOp} that wraps some common {@link File} - * operations on files and folders. - * <p/> - * This version does not perform any file operation. Instead it records a textual - * representation of all the file operations performed. - * <p/> - * To avoid cross-platform path issues (e.g. Windows path), the methods here should - * always use rooted (aka absolute) unix-looking paths, e.g. "/dir1/dir2/file3". - * When processing {@link File}, you can convert them using {@link #getAgnosticAbsPath(File)}. - */ -public class MockFileOp implements IFileOp { - - private final Set<String> mExistinfFiles = new TreeSet<String>(); - private final Set<String> mExistinfFolders = new TreeSet<String>(); - private final List<StringOutputStream> mOutputStreams = new ArrayList<StringOutputStream>(); - - public MockFileOp() { - } - - /** Resets the internal state, as if the object had been newly created. */ - public void reset() { - mExistinfFiles.clear(); - mExistinfFolders.clear(); - } - - public String getAgnosticAbsPath(File file) { - return getAgnosticAbsPath(file.getAbsolutePath()); - } - - public String getAgnosticAbsPath(String path) { - if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) { - // Try to convert the windows-looking path to a unix-looking one - path = path.replace('\\', '/'); - path = path.replace("C:", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } - return path; - } - - /** - * Records a new absolute file path. - * Parent folders are not automatically created. - */ - public void recordExistingFile(File file) { - mExistinfFiles.add(getAgnosticAbsPath(file)); - } - - /** - * Records a new absolute file path. - * Parent folders are not automatically created. - * <p/> - * The syntax should always look "unix-like", e.g. "/dir/file". - * On Windows that means you'll want to use {@link #getAgnosticAbsPath(File)}. - * @param absFilePath A unix-like file path, e.g. "/dir/file" - */ - public void recordExistingFile(String absFilePath) { - mExistinfFiles.add(absFilePath); - } - - /** - * Records a new absolute folder path. - * Parent folders are not automatically created. - */ - public void recordExistingFolder(File folder) { - mExistinfFolders.add(getAgnosticAbsPath(folder)); - } - - /** - * Records a new absolute folder path. - * Parent folders are not automatically created. - * <p/> - * The syntax should always look "unix-like", e.g. "/dir/file". - * On Windows that means you'll want to use {@link #getAgnosticAbsPath(File)}. - * @param absFolderPath A unix-like folder path, e.g. "/dir/file" - */ - public void recordExistingFolder(String absFolderPath) { - mExistinfFolders.add(absFolderPath); - } - - /** - * Returns the list of paths added using {@link #recordExistingFile(String)} - * and eventually updated by {@link #delete(File)} operations. - * <p/> - * The returned list is sorted by alphabetic absolute path string. - */ - public String[] getExistingFiles() { - return mExistinfFiles.toArray(new String[mExistinfFiles.size()]); - } - - /** - * Returns the list of folder paths added using {@link #recordExistingFolder(String)} - * and eventually updated {@link #delete(File)} or {@link #mkdirs(File)} operations. - * <p/> - * The returned list is sorted by alphabetic absolute path string. - */ - public String[] getExistingFolders() { - return mExistinfFolders.toArray(new String[mExistinfFolders.size()]); - } - - /** - * Returns the {@link StringOutputStream#toString()} as an array, in creation order. - * Array can be empty but not null. - */ - public String[] getOutputStreams() { - int n = mOutputStreams.size(); - String[] result = new String[n]; - for (int i = 0; i < n; i++) { - result[i] = mOutputStreams.get(i).toString(); - } - return result; - } - - /** - * Helper to delete a file or a directory. - * For a directory, recursively deletes all of its content. - * Files that cannot be deleted right away are marked for deletion on exit. - * The argument can be null. - */ - @Override - public void deleteFileOrFolder(File fileOrFolder) { - if (fileOrFolder != null) { - if (isDirectory(fileOrFolder)) { - // Must delete content recursively first - for (File item : listFiles(fileOrFolder)) { - deleteFileOrFolder(item); - } - } - delete(fileOrFolder); - } - } - - /** - * {@inheritDoc} - * <p/> - * <em>Note: this mock version does nothing.</em> - */ - @Override - public void setExecutablePermission(File file) throws IOException { - // pass - } - - /** - * {@inheritDoc} - * <p/> - * <em>Note: this mock version does nothing.</em> - */ - @Override - public void setReadOnly(File file) { - // pass - } - - /** - * {@inheritDoc} - * <p/> - * <em>Note: this mock version does nothing.</em> - */ - @Override - public void copyFile(File source, File dest) throws IOException { - // pass - } - - /** - * Checks whether 2 binary files are the same. - * - * @param source the source file to copy - * @param destination the destination file to write - * @throws FileNotFoundException if the source files don't exist. - * @throws IOException if there's a problem reading the files. - */ - @Override - public boolean isSameFile(File source, File destination) throws IOException { - throw new UnsupportedOperationException("MockFileUtils.isSameFile is not supported."); //$NON-NLS-1$ - } - - /** Invokes {@link File#isFile()} on the given {@code file}. */ - @Override - public boolean isFile(File file) { - String path = getAgnosticAbsPath(file); - return mExistinfFiles.contains(path); - } - - /** Invokes {@link File#isDirectory()} on the given {@code file}. */ - @Override - public boolean isDirectory(File file) { - String path = getAgnosticAbsPath(file); - if (mExistinfFolders.contains(path)) { - return true; - } - - // If we defined a file or folder as a child of the requested file path, - // then the directory exists implicitely. - Pattern pathRE = Pattern.compile( - Pattern.quote(path + (path.endsWith("/") ? "" : '/')) + //$NON-NLS-1$ //$NON-NLS-2$ - ".*"); //$NON-NLS-1$ - - for (String folder : mExistinfFolders) { - if (pathRE.matcher(folder).matches()) { - return true; - } - } - for (String filePath : mExistinfFiles) { - if (pathRE.matcher(filePath).matches()) { - return true; - } - } - - return false; - } - - /** Invokes {@link File#exists()} on the given {@code file}. */ - @Override - public boolean exists(File file) { - return isFile(file) || isDirectory(file); - } - - /** Invokes {@link File#length()} on the given {@code file}. */ - @Override - public long length(File file) { - throw new UnsupportedOperationException("MockFileUtils.length is not supported."); //$NON-NLS-1$ - } - - @Override - public boolean delete(File file) { - String path = getAgnosticAbsPath(file); - - if (mExistinfFiles.remove(path)) { - return true; - } - - boolean hasSubfiles = false; - for (String folder : mExistinfFolders) { - if (folder.startsWith(path) && !folder.equals(path)) { - // the File.delete operation is not recursive and would fail to remove - // a root dir that is not empty. - return false; - } - } - if (!hasSubfiles) { - for (String filePath : mExistinfFiles) { - if (filePath.startsWith(path) && !filePath.equals(path)) { - // the File.delete operation is not recursive and would fail to remove - // a root dir that is not empty. - return false; - } - } - } - - return mExistinfFolders.remove(path); - } - - /** Invokes {@link File#mkdirs()} on the given {@code file}. */ - @Override - public boolean mkdirs(File file) { - for (; file != null; file = file.getParentFile()) { - String path = getAgnosticAbsPath(file); - mExistinfFolders.add(path); - } - return true; - } - - /** - * Invokes {@link File#listFiles()} on the given {@code file}. - * The returned list is sorted by alphabetic absolute path string. - */ - @Override - public File[] listFiles(File file) { - TreeSet<File> files = new TreeSet<File>(); - - String path = getAgnosticAbsPath(file); - Pattern pathRE = Pattern.compile( - Pattern.quote(path + (path.endsWith("/") ? "" : '/')) + //$NON-NLS-1$ //$NON-NLS-2$ - ".*"); //$NON-NLS-1$ - - for (String folder : mExistinfFolders) { - if (pathRE.matcher(folder).matches()) { - files.add(new File(folder)); - } - } - for (String filePath : mExistinfFiles) { - if (pathRE.matcher(filePath).matches()) { - files.add(new File(filePath)); - } - } - return files.toArray(new File[files.size()]); - } - - /** Invokes {@link File#renameTo(File)} on the given files. */ - @Override - public boolean renameTo(File oldFile, File newFile) { - boolean renamed = false; - - String oldPath = getAgnosticAbsPath(oldFile); - String newPath = getAgnosticAbsPath(newFile); - Pattern pathRE = Pattern.compile( - "^(" + Pattern.quote(oldPath) + //$NON-NLS-1$ - ")($|/.*)"); //$NON-NLS-1$ - - Set<String> newStrings = new HashSet<String>(); - for (Iterator<String> it = mExistinfFolders.iterator(); it.hasNext(); ) { - String folder = it.next(); - Matcher m = pathRE.matcher(folder); - if (m.matches()) { - it.remove(); - String newFolder = newPath + m.group(2); - newStrings.add(newFolder); - renamed = true; - } - } - mExistinfFolders.addAll(newStrings); - newStrings.clear(); - - for (Iterator<String> it = mExistinfFiles.iterator(); it.hasNext(); ) { - String filePath = it.next(); - Matcher m = pathRE.matcher(filePath); - if (m.matches()) { - it.remove(); - String newFilePath = newPath + m.group(2); - newStrings.add(newFilePath); - renamed = true; - } - } - mExistinfFiles.addAll(newStrings); - - return renamed; - } - - /** - * {@inheritDoc} - * <p/> - * <em>TODO: we might want to overload this to read mock properties instead of a real file.</em> - */ - @Override - public @NonNull Properties loadProperties(@NonNull File file) { - Properties props = new Properties(); - FileInputStream fis = null; - try { - fis = new FileInputStream(file); - props.load(fis); - } catch (IOException ignore) { - } finally { - if (fis != null) { - try { - fis.close(); - } catch (Exception ignore) {} - } - } - return props; - } - - /** - * {@inheritDoc} - * <p/> - * <em>Note that this uses the mock version of {@link #newFileOutputStream(File)} and thus - * records the write rather than actually performing it.</em> - */ - @Override - public boolean saveProperties(@NonNull File file, @NonNull Properties props, - @NonNull String comments) { - OutputStream fos = null; - try { - fos = newFileOutputStream(file); - - props.store(fos, comments); - return true; - } catch (IOException ignore) { - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - } - } - } - - return false; - } - - /** - * Returns an OutputStream that will capture the bytes written and associate - * them with the given file. - */ - @Override - public OutputStream newFileOutputStream(File file) throws FileNotFoundException { - StringOutputStream os = new StringOutputStream(file); - mOutputStreams.add(os); - return os; - } - - /** - * An {@link OutputStream} that will capture the stream as an UTF-8 string once properly closed - * and associate it to the given {@link File}. - */ - public class StringOutputStream extends ByteArrayOutputStream { - private String mData; - private final File mFile; - - public StringOutputStream(File file) { - mFile = file; - recordExistingFile(file); - } - - public File getFile() { - return mFile; - } - - /** Can be null if the stream has never been properly closed. */ - public String getData() { - return mData; - } - - /** Once the stream is properly closed, convert the byte array to an UTF-8 string */ - @Override - public void close() throws IOException { - super.close(); - mData = new String(toByteArray(), "UTF-8"); //$NON-NLS-1$ - } - - /** Returns a string representation suitable for unit tests validation. */ - @Override - public synchronized String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('<').append(getAgnosticAbsPath(mFile)).append(": "); //$NON-NLS-1$ - if (mData == null) { - sb.append("(stream not closed properly)>"); //$NON-NLS-1$ - } else { - sb.append('\'').append(mData).append("'>"); //$NON-NLS-1$ - } - return sb.toString(); - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/io/MockFileOpTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/io/MockFileOpTest.java deleted file mode 100755 index 8fb1784..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/io/MockFileOpTest.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.io; - -import java.io.File; -import java.io.OutputStream; -import java.util.Arrays; - -import junit.framework.TestCase; - -/** - * Unit-test for the {@link MockFileOp}, which is a mock of {@link FileOp} that doesn't - * touch the file system. Just testing the test. - */ -public class MockFileOpTest extends TestCase { - - private MockFileOp m; - - @Override - protected void setUp() throws Exception { - super.setUp(); - m = new MockFileOp(); - } - - private File createFile(String...segments) { - File f = null; - for (String segment : segments) { - if (f == null) { - f = new File(segment); - } else { - f = new File(f, segment); - } - } - - return f; - } - - public void testIsFile() { - File f1 = createFile("/dir1", "file1"); - assertFalse(m.isFile(f1)); - - m.recordExistingFile("/dir1/file1"); - assertTrue(m.isFile(f1)); - - assertEquals( - "[/dir1/file1]", - Arrays.toString(m.getExistingFiles())); - } - - public void testIsDirectory() { - File d4 = createFile("/dir1", "dir2", "dir3", "dir4"); - File f7 = createFile("/dir1", "dir2", "dir6", "file7"); - assertFalse(m.isDirectory(d4)); - - m.recordExistingFolder("/dir1/dir2/dir3/dir4"); - m.recordExistingFile("/dir1/dir2/dir6/file7"); - assertTrue(m.isDirectory(d4)); - assertFalse(m.isDirectory(f7)); - - // any intermediate directory exists implicitly - assertTrue(m.isDirectory(createFile("/"))); - assertTrue(m.isDirectory(createFile("/dir1"))); - assertTrue(m.isDirectory(createFile("/dir1", "dir2"))); - assertTrue(m.isDirectory(createFile("/dir1", "dir2", "dir3"))); - assertTrue(m.isDirectory(createFile("/dir1", "dir2", "dir6"))); - - assertEquals( - "[/dir1/dir2/dir3/dir4]", - Arrays.toString(m.getExistingFolders())); - } - - public void testDelete() { - m.recordExistingFolder("/dir1"); - m.recordExistingFile("/dir1/file1"); - m.recordExistingFile("/dir1/file2"); - - assertEquals( - "[/dir1/file1, /dir1/file2]", - Arrays.toString(m.getExistingFiles())); - - assertTrue(m.delete(createFile("/dir1", "file1"))); - assertFalse(m.delete(createFile("/dir1", "file3"))); - assertFalse(m.delete(createFile("/dir2", "file2"))); - assertEquals( - "[/dir1/file2]", - Arrays.toString(m.getExistingFiles())); - - // deleting a directory with files in it fails - assertFalse(m.delete(createFile("/dir1"))); - // but it works if the directory is empty - assertTrue(m.delete(createFile("/dir1", "file2"))); - assertTrue(m.delete(createFile("/dir1"))); - } - - public void testListFiles() { - m.recordExistingFolder("/dir1"); - m.recordExistingFile("/dir1/file1"); - m.recordExistingFile("/dir1/file2"); - m.recordExistingFile("/dir1/dir2/file3"); - m.recordExistingFile("/dir4/file4"); - - assertEquals( - "[]", - m.getAgnosticAbsPath(Arrays.toString(m.listFiles(createFile("/not_a_dir"))))); - - assertEquals( - "[/dir1/dir2/file3]", - m.getAgnosticAbsPath(Arrays.toString(m.listFiles(createFile("/dir1", "dir2"))))); - - assertEquals( - "[/dir1/dir2/file3, /dir1/file1, /dir1/file2]", - m.getAgnosticAbsPath(Arrays.toString(m.listFiles(createFile("/dir1"))))); - } - - public void testMkDirs() { - assertEquals("[]", Arrays.toString(m.getExistingFolders())); - - assertTrue(m.mkdirs(createFile("/dir1"))); - assertEquals("[/, /dir1]", Arrays.toString(m.getExistingFolders())); - - m.recordExistingFolder("/dir1"); - assertEquals("[/, /dir1]", Arrays.toString(m.getExistingFolders())); - - assertTrue(m.mkdirs(createFile("/dir1/dir2/dir3"))); - assertEquals( - "[/, /dir1, /dir1/dir2, /dir1/dir2/dir3]", - Arrays.toString(m.getExistingFolders())); - } - - public void testRenameTo() { - m.recordExistingFile("/dir1/dir2/dir6/file7"); - m.recordExistingFolder("/dir1/dir2/dir3/dir4"); - - assertEquals("[/dir1/dir2/dir6/file7]", Arrays.toString(m.getExistingFiles())); - assertEquals("[/dir1/dir2/dir3/dir4]", Arrays.toString(m.getExistingFolders())); - - assertTrue(m.renameTo(createFile("/dir1", "dir2"), createFile("/dir1", "newDir2"))); - assertEquals("[/dir1/newDir2/dir6/file7]", Arrays.toString(m.getExistingFiles())); - assertEquals("[/dir1/newDir2/dir3/dir4]", Arrays.toString(m.getExistingFolders())); - - assertTrue(m.renameTo( - createFile("/dir1", "newDir2", "dir6", "file7"), - createFile("/dir1", "newDir2", "dir6", "newFile7"))); - assertTrue(m.renameTo( - createFile("/dir1", "newDir2", "dir3", "dir4"), - createFile("/dir1", "newDir2", "dir3", "newDir4"))); - assertEquals("[/dir1/newDir2/dir6/newFile7]", Arrays.toString(m.getExistingFiles())); - assertEquals("[/dir1/newDir2/dir3/newDir4]", Arrays.toString(m.getExistingFolders())); - } - - public void testNewFileOutputStream() throws Exception { - assertEquals("[]", Arrays.toString(m.getOutputStreams())); - - File f = createFile("/dir1", "dir2", "simple ascii"); - OutputStream os = m.newFileOutputStream(f); - assertNotNull(os); - os.write("regular ascii".getBytes("UTF-8")); - os.close(); - - f = createFile("/dir1", "dir2", "utf-8 test"); - os = m.newFileOutputStream(f); - assertNotNull(os); - os.write("nihongo in UTF-8: 日本語".getBytes("UTF-8")); - os.close(); - - f = createFile("/dir1", "dir2", "forgot to close"); - os = m.newFileOutputStream(f); - assertNotNull(os); - os.write("wrote stuff but not closing the stream".getBytes("UTF-8")); - - assertEquals( - "[</dir1/dir2/simple ascii: 'regular ascii'>, " + - "</dir1/dir2/utf-8 test: 'nihongo in UTF-8: 日本語'>, " + - "</dir1/dir2/forgot to close: (stream not closed properly)>]", - Arrays.toString(m.getOutputStreams())); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/mock/MockLog.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/mock/MockLog.java deleted file mode 100644 index f2e30d2..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/mock/MockLog.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.mock; - -import com.android.annotations.NonNull; -import com.android.utils.ILogger; - -import java.util.ArrayList; -import java.util.Formatter; -import java.util.List; - -/** - * An instance of {@link ILogger} that captures all messages to an internal list. - * Messages can be retrieved later using {@link #toString()}. - * Useful for unit-tests. - */ -public class MockLog implements ILogger { - private ArrayList<String> mMessages = new ArrayList<String>(); - - private void add(String code, String format, Object... args) { - Formatter formatter = new Formatter(); - mMessages.add(formatter.format(code + format, args).toString()); - formatter.close(); - } - - @Override - public void warning(@NonNull String format, Object... args) { - add("W ", format, args); - } - - @Override - public void info(@NonNull String format, Object... args) { - add("P ", format, args); - } - - @Override - public void verbose(@NonNull String format, Object... args) { - add("V ", format, args); - } - - @Override - public void error(Throwable t, String format, Object... args) { - if (t != null) { - add("T", "%s", t.toString()); - } - add("E ", format, args); - } - - @Override - public String toString() { - return mMessages.toString(); - } - - @NonNull - public List<String> getMessages() { - return mMessages; - } - - public void clear() { - mMessages.clear(); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/CaptureErrorHandler.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/CaptureErrorHandler.java deleted file mode 100755 index dccec59..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/CaptureErrorHandler.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -/** - * A SAX error handler that captures the errors and warnings. - * This allows us to capture *all* errors and just not get an exception on the first one. - */ -class CaptureErrorHandler implements ErrorHandler { - - private String mWarnings = ""; - private String mErrors = ""; - - public String getErrors() { - return mErrors; - } - - public String getWarnings() { - return mWarnings; - } - - /** - * Verifies if the handler captures some errors or warnings. - * Prints them on stderr. - * Also fails the unit test if any error was generated. - */ - public void verify() { - if (mWarnings.length() > 0) { - System.err.println(mWarnings); - } - - if (mErrors.length() > 0) { - System.err.println(mErrors); - junit.framework.Assert.fail(mErrors); - } - } - - /** - * @throws SAXException - */ - @Override - public void error(SAXParseException ex) throws SAXException { - mErrors += "Error: " + ex.getMessage() + "\n"; - } - - /** - * @throws SAXException - */ - @Override - public void fatalError(SAXParseException ex) throws SAXException { - mErrors += "Fatal Error: " + ex.getMessage() + "\n"; - } - - /** - * @throws SAXException - */ - @Override - public void warning(SAXParseException ex) throws SAXException { - mWarnings += "Warning: " + ex.getMessage() + "\n"; - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java deleted file mode 100755 index ea56e0b..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonXmlTest.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - -import com.android.annotations.Nullable; - -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import java.io.InputStream; -import java.io.StringReader; - -import javax.xml.XMLConstants; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import junit.framework.TestCase; - -/** - * Tests local validation of an SDK Addon sample XMLs using an XML Schema validator. - */ -public class ValidateAddonXmlTest extends TestCase { - - private static String OPEN_TAG_ADDON = - "<r:sdk-addon xmlns:r=\"http://schemas.android.com/sdk/android/addon/" + - Integer.toString(SdkAddonConstants.NS_LATEST_VERSION) + - "\">"; - private static String CLOSE_TAG_ADDON = "</r:sdk-addon>"; - - // --- Helpers ------------ - - /** - * Helper method that returns a validator for our Addon XSD - * - * @param version The version number, in range {@code 1..NS_LATEST_VERSION} - * @param handler A {@link CaptureErrorHandler}. If null the default will be used, - * which will most likely print errors to stderr. - */ - private Validator getAddonValidator(int version, @Nullable CaptureErrorHandler handler) - throws SAXException { - Validator validator = null; - InputStream xsdStream = SdkAddonConstants.getXsdStream(version); - if (xsdStream != null) { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - validator = schema.newValidator(); - if (handler != null) { - validator.setErrorHandler(handler); - } - } - - return validator; - } - - /** An helper that validates a string against an expected regexp. */ - private void assertRegex(String expectedRegexp, String actualString) { - assertNotNull(actualString); - assertTrue( - String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n", - expectedRegexp, actualString), - actualString.matches(expectedRegexp)); - } - - // --- Tests ------------ - - /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */ - public void testAddonLatestVersionNumber() throws Exception { - CaptureErrorHandler handler = new CaptureErrorHandler(); - - // There should be a schema matching NS_LATEST_VERSION - assertNotNull(getAddonValidator(SdkAddonConstants.NS_LATEST_VERSION, handler)); - - // There should NOT be a schema with NS_LATEST_VERSION+1 - assertNull( - String.format( - "There's an ADDON XSD at version %d but SdkAddonConstants.NS_LATEST_VERSION is still set to %d.", - SdkAddonConstants.NS_LATEST_VERSION + 1, - SdkAddonConstants.NS_LATEST_VERSION), - getAddonValidator(SdkAddonConstants.NS_LATEST_VERSION + 1, handler)); - } - - /** Validate a valid sample using namespace version 1 using an InputStream */ - public void testValidateLocalAddonFile1() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/addon_sample_1.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getAddonValidator(1, handler); - validator.validate(source); - handler.verify(); - } - - /** Validate a valid sample using namespace version 2 using an InputStream */ - public void testValidateLocalAddonFile2() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/addon_sample_2.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getAddonValidator(2, handler); - validator.validate(source); - handler.verify(); - } - - /** Validate a valid sample using namespace version 3 using an InputStream */ - public void testValidateLocalAddonFile3() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/addon_sample_3.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getAddonValidator(3, handler); - validator.validate(source); - handler.verify(); - } - - /** Validate a valid sample using namespace version 4 using an InputStream */ - public void testValidateLocalAddonFile4() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/addon_sample_4.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getAddonValidator(4, handler); - validator.validate(source); - handler.verify(); - } - - // IMPORTANT: each time you add a test here, you should add a corresponding - // test in SdkAddonSourceTest to validate the XML content is parsed correctly. - - // ---- - - /** - * An addon does not support a codename. - * There used to be a typo in the repository.XSD versions 1-2 & the addon XSD versions 1-2 - * where addons had an optional element 'codename'. This was a typo and it's been fixed. - */ - public void testAddonCodename() throws Exception { - // we define a license named "lic1" and then reference "lic2" instead - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_ADDON + - "<r:license id=\"lic1\"> some license </r:license> " + - "<r:add-on> <r:uses-license ref=\"lic1\" /> <r:revision>1</r:revision> " + - "<r:name-id>AddonName</r:name-id> <r:name-display>The Addon Name</r:name-display> " + - "<r:vendor-id>AddonVendor</r:vendor-id> <r:vendor-display>The Addon Vendor</r:vendor-display> " + - "<r:api-level>42</r:api-level> " + - "<r:codename>Addons do not support codenames</r:codenames> " + - "<r:libs><r:lib><r:name>com.example.LibName</r:name></r:lib></r:libs> " + - "<r:archives> <r:archive os=\"any\"> <r:size>1</r:size> <r:checksum>2822ae37115ebf13412bbef91339ee0d9454525e</r:checksum> " + - "<r:url>url</r:url> </r:archive> </r:archives> </r:add-on>" + - CLOSE_TAG_ADDON; - - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getAddonValidator(SdkAddonConstants.NS_LATEST_VERSION, null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'r:codename'.*", - e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); - } - - /** A document with a slash in an extra path. */ - public void testExtraPathWithSlash() throws Exception { - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_ADDON + - "<r:extra> <r:revision>1</r:revision> <r:path>path/cannot\\contain\\segments</r:path> " + - "<r:archives> <r:archive os=\"any\"> <r:size>1</r:size> <r:checksum>2822ae37115ebf13412bbef91339ee0d9454525e</r:checksum> " + - "<r:url>url</r:url> </r:archive> </r:archives> </r:extra>" + - CLOSE_TAG_ADDON; - - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getAddonValidator(SdkAddonConstants.NS_LATEST_VERSION, null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-pattern-valid: Value 'path/cannot\\\\contain\\\\segments' is not facet-valid with respect to pattern.*", - e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java deleted file mode 100755 index 0461c67..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateAddonsListXmlTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - -import com.android.annotations.Nullable; - -import org.xml.sax.SAXException; - -import java.io.InputStream; - -import javax.xml.XMLConstants; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import junit.framework.TestCase; - -/** - * Tests local validation of an SDK Addon-List sample XMLs using an XML Schema validator. - */ -public class ValidateAddonsListXmlTest extends TestCase { - - // --- Helpers ------------ - - /** - * Helper method that returns a validator for our Addons-List XSD - * - * @param version The version number, in range {@code 1..NS_LATEST_VERSION} - * @param handler A {@link CaptureErrorHandler}. If null the default will be used, - * which will most likely print errors to stderr. - */ - private Validator getValidator(int version, @Nullable CaptureErrorHandler handler) - throws SAXException { - Validator validator = null; - InputStream xsdStream = SdkAddonsListConstants.getXsdStream(version); - if (xsdStream != null) { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - validator = schema.newValidator(); - if (handler != null) { - validator.setErrorHandler(handler); - } - } - - return validator; - } - - // --- Tests ------------ - - /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */ - public void testAddonLatestVersionNumber() throws Exception { - CaptureErrorHandler handler = new CaptureErrorHandler(); - - // There should be a schema matching NS_LATEST_VERSION - assertNotNull(getValidator(SdkAddonsListConstants.NS_LATEST_VERSION, handler)); - - // There should NOT be a schema with NS_LATEST_VERSION+1 - assertNull( - String.format( - "There's an ADDON XSD at version %d but SdkAddonsListConstants.NS_LATEST_VERSION is still set to %d.", - SdkAddonsListConstants.NS_LATEST_VERSION + 1, - SdkAddonsListConstants.NS_LATEST_VERSION), - getValidator(SdkAddonsListConstants.NS_LATEST_VERSION + 1, handler)); - } - - /** Validate a valid sample using namespace version 1 using an InputStream */ - public void testValidateLocalAddonFile1() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/addons_list_sample_1.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getValidator(1, handler); - validator.validate(source); - handler.verify(); - } - - /** Validate a valid sample using namespace version 2 using an InputStream */ - public void testValidateLocalAddonFile2() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/addons_list_sample_2.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getValidator(2, handler); - validator.validate(source); - handler.verify(); - } - - // IMPORTANT: each time you add a test here, you should add a corresponding - // test in AddonsListFetcherTest to validate the XML content is parsed correctly. -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java deleted file mode 100755 index bdc450c..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateRepositoryXmlTest.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - -import com.android.annotations.Nullable; - -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import java.io.InputStream; -import java.io.StringReader; - -import javax.xml.XMLConstants; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import junit.framework.TestCase; - -/** - * Tests local validation of an SDK Repository sample XMLs using an XML Schema validator. - * - * References: - * http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html - */ -public class ValidateRepositoryXmlTest extends TestCase { - - private static String OPEN_TAG_REPO = - "<r:sdk-repository xmlns:r=\"http://schemas.android.com/sdk/android/repository/" + - Integer.toString(SdkRepoConstants.NS_LATEST_VERSION) + - "\">"; - private static String CLOSE_TAG_REPO = "</r:sdk-repository>"; - - // --- Helpers ------------ - - /** - * Helper method that returns a validator for our Repository XSD - * - * @param version The version number, in range {@code 1..NS_LATEST_VERSION} - * @param handler A {@link CaptureErrorHandler}. If null the default will be used, - * which will most likely print errors to stderr. - */ - private Validator getRepoValidator(int version, @Nullable CaptureErrorHandler handler) - throws SAXException { - Validator validator = null; - InputStream xsdStream = SdkRepoConstants.getXsdStream(version); - if (xsdStream != null) { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - validator = schema.newValidator(); - - if (handler != null) { - validator.setErrorHandler(handler); - } - } - - return validator; - } - - /** An helper that validates a string against an expected regexp. */ - private void assertRegex(String expectedRegexp, String actualString) { - assertNotNull(actualString); - assertTrue( - String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n", - expectedRegexp, actualString), - actualString.matches(expectedRegexp)); - } - - // --- Tests ------------ - - /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */ - public void testRepoLatestVersionNumber() throws Exception { - CaptureErrorHandler handler = new CaptureErrorHandler(); - - // There should be a schema matching NS_LATEST_VERSION - assertNotNull(getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, handler)); - - // There should NOT be a schema with NS_LATEST_VERSION+1 - assertNull( - String.format( - "There's a REPO XSD at version %d but SdkRepoConstants.NS_LATEST_VERSION is still set to %d.", - SdkRepoConstants.NS_LATEST_VERSION + 1, - SdkRepoConstants.NS_LATEST_VERSION), - getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION + 1, handler)); - } - - /** Validate a valid sample using namespace version 1 using an InputStream */ - public void testValidateLocalRepositoryFile1() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_1.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(1, handler); - validator.validate(source); - handler.verify(); - } - - /** Validate a valid sample using namespace version 2 using an InputStream */ - public void testValidateLocalRepositoryFile2() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_2.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(2, handler); - validator.validate(source); - handler.verify(); - } - - /** Validate a valid sample using namespace version 3 using an InputStream */ - public void testValidateLocalRepositoryFile3() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_3.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(3, handler); - validator.validate(source); - handler.verify(); - } - - /** Validate a valid sample using namespace version 4 using an InputStream */ - public void testValidateLocalRepositoryFile4() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_4.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(4, handler); - validator.validate(source); - handler.verify(); - - } - - /** Validate a valid sample using namespace version 5 using an InputStream */ - public void testValidateLocalRepositoryFile5() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_5.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(5, handler); - validator.validate(source); - handler.verify(); - - } - - /** Validate a valid sample using namespace version 5 using an InputStream */ - public void testValidateLocalRepositoryFile6() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_6.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(6, handler); - validator.validate(source); - handler.verify(); - - } - - /** Validate a valid sample using namespace version 5 using an InputStream */ - public void testValidateLocalRepositoryFile7() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/repository_sample_7.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(7, handler); - validator.validate(source); - handler.verify(); - - } - - // IMPORTANT: each time you add a test here, you should add a corresponding - // test in SdkRepoSourceTest to validate the XML content is parsed correctly. - - - // --- - - /** A document should at least have a root to be valid */ - public void testEmptyXml() throws Exception { - String document = "<?xml version=\"1.0\"?>"; - - Source source = new StreamSource(new StringReader(document)); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, handler); - - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect to get this specific exception message - assertRegex("Premature end of file.*", e.getMessage()); - return; - } - // We shouldn't get here - handler.verify(); - fail(); - } - - /** A document with a root element containing no platform, addon, etc., is valid. */ - public void testEmptyRootXml() throws Exception { - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_REPO + - CLOSE_TAG_REPO; - - Source source = new StreamSource(new StringReader(document)); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, handler); - validator.validate(source); - handler.verify(); - } - - /** A document with an unknown element. */ - public void testUnknownContentXml() throws Exception { - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_REPO + - "<r:unknown />" + - CLOSE_TAG_REPO; - - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse expression referring to this grammar rule - assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); - } - - /** A document with an incomplete element. */ - public void testIncompleteContentXml() throws Exception { - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_REPO + - "<r:platform> <r:api-level>1</r:api-level> <r:libs /> </r:platform>" + - CLOSE_TAG_REPO; - - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); - } - - /** A document with a wrong type element. */ - public void testWrongTypeContentXml() throws Exception { - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_REPO + - "<r:platform> <r:api-level>NotAnInteger</r:api-level> <r:libs /> </r:platform>" + - CLOSE_TAG_REPO; - - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-datatype-valid.1.2.1: 'NotAnInteger' is not a valid value.*", - e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); - } - - /** A document with an unknown license id. */ - public void testLicenseIdNotFound() throws Exception { - // we define a license named "lic1" and then reference "lic2" instead - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_REPO + - "<r:license id=\"lic1\"> some license </r:license> " + - "<r:tool> <r:uses-license ref=\"lic2\" /> <r:revision> <r:major>1</r:major> </r:revision> " + - "<r:min-platform-tools-rev> <r:major>1</r:major> </r:min-platform-tools-rev> " + - "<r:archives> <r:archive os=\"any\"> <r:size>1</r:size> <r:checksum>2822ae37115ebf13412bbef91339ee0d9454525e</r:checksum> " + - "<r:url>url</r:url> </r:archive> </r:archives> </r:tool>" + - CLOSE_TAG_REPO; - - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-id.1: There is no ID/IDREF binding for IDREF 'lic2'.*", - e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); - } - - /** The latest XSD repository-6 should fail when an 'extra' is present. */ - public void testExtraPathWithSlash() throws Exception { - String document = "<?xml version=\"1.0\"?>" + - OPEN_TAG_REPO + - "<r:extra> <r:revision>1</r:revision> <r:path>path</r:path> " + - "<r:archives> <r:archive os=\"any\"> <r:size>1</r:size> <r:checksum>2822ae37115ebf13412bbef91339ee0d9454525e</r:checksum> " + - "<r:url>url</r:url> </r:archive> </r:archives> </r:extra>" + - CLOSE_TAG_REPO; - - Source source = new StreamSource(new StringReader(document)); - - // don't capture the validator errors, we want it to fail and catch the exception - Validator validator = getRepoValidator(SdkRepoConstants.NS_LATEST_VERSION, null); - try { - validator.validate(source); - } catch (SAXParseException e) { - // We expect a parse error referring to this grammar rule - assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'r:extra'.*", - e.getMessage()); - return; - } - // If we get here, the validator has not failed as we expected it to. - fail(); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java deleted file mode 100755 index fe7b1e8..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/repository/ValidateSysImgXmlTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.eclipse.org/org/documents/epl-v10.php - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.repository; - -import com.android.annotations.Nullable; - -import org.xml.sax.SAXException; - -import java.io.InputStream; - -import javax.xml.XMLConstants; -import javax.xml.transform.Source; -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; -import javax.xml.validation.Validator; - -import junit.framework.TestCase; - -/** - * Tests local validation of an SDK Repository sample XMLs using an XML Schema validator. - * - * References: - * http://www.ibm.com/developerworks/xml/library/x-javaxmlvalidapi.html - */ -public class ValidateSysImgXmlTest extends TestCase { - - // --- Helpers ------------ - - /** - * Helper method that returns a validator for our Repository XSD - * - * @param version The version number, in range {@code 1..NS_LATEST_VERSION} - * @param handler A {@link CaptureErrorHandler}. If null the default will be used, - * which will most likely print errors to stderr. - */ - private Validator getValidator(int version, @Nullable CaptureErrorHandler handler) - throws SAXException { - Validator validator = null; - InputStream xsdStream = SdkSysImgConstants.getXsdStream(version); - if (xsdStream != null) { - SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = factory.newSchema(new StreamSource(xsdStream)); - validator = schema.newValidator(); - - if (handler != null) { - validator.setErrorHandler(handler); - } - } - - return validator; - } - - // --- Tests ------------ - - /** Validates that NS_LATEST_VERSION points to the max available XSD schema. */ - public void testSysImgLatestVersionNumber() throws Exception { - CaptureErrorHandler handler = new CaptureErrorHandler(); - - // There should be a schema matching NS_LATEST_VERSION - assertNotNull(getValidator(SdkSysImgConstants.NS_LATEST_VERSION, handler)); - - // There should NOT be a schema with NS_LATEST_VERSION+1 - assertNull( - String.format( - "There's a REPO XSD at version %d but SdkSysImgConstants.NS_LATEST_VERSION is still set to %d.", - SdkSysImgConstants.NS_LATEST_VERSION + 1, - SdkSysImgConstants.NS_LATEST_VERSION), - getValidator(SdkSysImgConstants.NS_LATEST_VERSION + 1, handler)); - } - - /** Validate a valid sample using namespace version 1 using an InputStream */ - public void testValidateLocalRepositoryFile1() throws Exception { - InputStream xmlStream = this.getClass().getResourceAsStream( - "/com/android/sdklib/testdata/sys_img_sample_1.xml"); - Source source = new StreamSource(xmlStream); - - CaptureErrorHandler handler = new CaptureErrorHandler(); - Validator validator = getValidator(1, handler); - validator.validate(source); - handler.verify(); - } - - // IMPORTANT: each time you add a test here, you should add a corresponding - // test in SdkSysImgSourceTest to validate the XML content is parsed correctly. - -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-instrumentation.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-instrumentation.xml deleted file mode 100644 index f1dce67..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-instrumentation.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.AndroidProject.tests"> - - <!-- - This declares that this app uses the instrumentation test runner targeting - the package of com.android.samples. To run the tests use the command: - "adb shell am instrument -w com.android.samples.tests/android.test.InstrumentationTestRunner" - --> - <instrumentation android:name="android.test.InstrumentationTestRunner" - android:targetPackage="com.android.AndroidProject" - android:label="Sample test for deployment."/> - - <application> - <uses-library android:name="android.test.runner" /> - </application> - <uses-sdk android:minSdkVersion="foo"/> - -</manifest> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-testapp.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-testapp.xml deleted file mode 100644 index f55b4e0..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-testapp.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.testapp" android:versionCode="42" - android:versionName="1.42"> - <application android:icon="@drawable/icon"> - <activity android:name="com.android.testapp.MainActivity" - android:label="@string/app_name"> - <intent-filter> - <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> - <uses-library android:name="android.test.runner" - android:required="false" /> - <uses-library android:name="android.test.runner2" /> - </application> - <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="8" /> - <supports-screens android:resizeable="true" - android:smallScreens="true" android:anyDensity="true" - android:largeScreens="true" android:normalScreens="true" /> - <uses-configuration android:reqKeyboardType="twelvekey" - android:reqTouchScreen="finger" android:reqFiveWayNav="true" - android:reqHardKeyboard="true" android:reqNavigation="nonav" /> - <uses-feature android:glEsVersion="0x00020001" /> - <uses-feature android:name="com.foo.feature" /> - <instrumentation android:name="android.test.InstrumentationTestRunner" - android:targetPackage="com.example.android.apis" android:label="Tests for Api Demos." /> -</manifest> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-testapp2.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-testapp2.xml deleted file mode 100644 index d5bcac7..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/AndroidManifest-testapp2.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.testapp" android:versionCode="42" - android:versionName="1.42"> - <application android:icon="@drawable/icon"/> - <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="8" /> - <supports-screens android:largeScreens="false" /> -</manifest> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_1.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_1.xml deleted file mode 100755 index d761d73..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_1.xml +++ /dev/null @@ -1,164 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-addon - xmlns:sdk="http://schemas.android.com/sdk/android/addon/1"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:add-on> - <sdk:name>My First add-on</sdk:name> - <sdk:api-level>1</sdk:api-level> - <sdk:vendor>John Doe</sdk:vendor> - <sdk:revision>1</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <!-- sdk:description is optional, name is not --> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - </sdk:add-on> - - <sdk:add-on> - <sdk:name>My Second add-on</sdk:name> - <sdk:api-level>2</sdk:api-level> - <sdk:vendor>John Deer</sdk:vendor> - <sdk:revision>42</sdk:revision> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:uses-license ref="license2" /> - </sdk:add-on> - - <sdk:add-on> - <sdk:uses-license ref="license2" /> - <sdk:name>This add-on has no libraries</sdk:name> - <sdk:api-level>4</sdk:api-level> - <sdk:vendor>Joe Bar</sdk:vendor> - <sdk:revision>3</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs /> - </sdk:add-on> - - <sdk:extra> - <sdk:vendor>g</sdk:vendor> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>android_vendor</sdk:vendor> - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>____</sdk:vendor> - <sdk:path>____</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - </sdk:extra> - -</sdk:sdk-addon> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_2.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_2.xml deleted file mode 100755 index 1033c15..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_2.xml +++ /dev/null @@ -1,179 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-addon - xmlns:sdk="http://schemas.android.com/sdk/android/addon/2"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:add-on> - <sdk:name>My First add-on</sdk:name> - <sdk:api-level>1</sdk:api-level> - <sdk:vendor>John Doe</sdk:vendor> - <sdk:revision>1</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <!-- sdk:description is optional, name is not --> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:add-on> - <sdk:name>My Second add-on</sdk:name> - <sdk:api-level>2</sdk:api-level> - <sdk:vendor>John Deer</sdk:vendor> - <sdk:revision>42</sdk:revision> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:uses-license ref="license2" /> - <!-- No layoutlib element in this package. It's optional. --> - </sdk:add-on> - - <sdk:add-on> - <sdk:uses-license ref="license2" /> - <sdk:name>This add-on has no libraries</sdk:name> - <sdk:api-level>4</sdk:api-level> - <sdk:vendor>Joe Bar</sdk:vendor> - <sdk:revision>3</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs /> - <sdk:layoutlib> - <sdk:api>3</sdk:api> - <sdk:revision>42</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:extra> - <sdk:vendor>g</sdk:vendor> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>android_vendor</sdk:vendor> - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <sdk:project-files> - <sdk:path>v8/veggies_8.jar</sdk:path> - <sdk:path>root.jar</sdk:path> - <sdk:path>dir1/dir 2 with space/mylib.jar</sdk:path> - </sdk:project-files> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>____</sdk:vendor> - <sdk:path>____</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <!-- No project-files element in this package. --> - </sdk:extra> - -</sdk:sdk-addon> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_3.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_3.xml deleted file mode 100755 index 568cec1..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_3.xml +++ /dev/null @@ -1,180 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-addon - xmlns:sdk="http://schemas.android.com/sdk/android/addon/3"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:add-on> - <sdk:name>My First add-on</sdk:name> - <sdk:api-level>1</sdk:api-level> - <sdk:vendor>John Doe</sdk:vendor> - <sdk:revision>1</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <!-- sdk:description is optional, name is not --> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:add-on> - <sdk:name>My Second add-on</sdk:name> - <sdk:api-level>2</sdk:api-level> - <sdk:vendor>John Deer</sdk:vendor> - <sdk:revision>42</sdk:revision> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:uses-license ref="license2" /> - <!-- No layoutlib element in this package. It's optional. --> - </sdk:add-on> - - <sdk:add-on> - <sdk:uses-license ref="license2" /> - <sdk:name>This add-on has no libraries</sdk:name> - <sdk:api-level>4</sdk:api-level> - <sdk:vendor>Joe Bar</sdk:vendor> - <sdk:revision>3</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs /> - <sdk:layoutlib> - <sdk:api>3</sdk:api> - <sdk:revision>42</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:extra> - <sdk:vendor>g</sdk:vendor> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>android_vendor</sdk:vendor> - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <sdk:project-files> - <sdk:path>v8/veggies_8.jar</sdk:path> - <sdk:path>root.jar</sdk:path> - <sdk:path>dir1/dir 2 with space/mylib.jar</sdk:path> - </sdk:project-files> - <sdk:old-paths>path1;old_path2;oldPath3</sdk:old-paths> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>____</sdk:vendor> - <sdk:path>____</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <!-- No project-files element in this package. --> - </sdk:extra> - -</sdk:sdk-addon> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_4.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_4.xml deleted file mode 100755 index 6fba439..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_4.xml +++ /dev/null @@ -1,203 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-addon - xmlns:sdk="http://schemas.android.com/sdk/android/addon/4"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:add-on> - <sdk:name-id>My_First_add-on</sdk:name-id> - <sdk:name-display>My First add-on</sdk:name-display> - - <sdk:vendor-id>John_Doe</sdk:vendor-id> - <sdk:vendor-display>John Doe</sdk:vendor-display> - - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <!-- sdk:description is optional, name is not --> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:add-on> - <sdk:name-id>My_Second_add-on</sdk:name-id> - <sdk:name-display>My Second add-on</sdk:name-display> - - <sdk:vendor-id>John_Deer</sdk:vendor-id> - <sdk:vendor-display>John Deer</sdk:vendor-display> - - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:uses-license ref="license2" /> - <!-- No layoutlib element in this package. It's optional. --> - </sdk:add-on> - - <sdk:add-on> - <sdk:name-id>no_libs</sdk:name-id> - <sdk:name-display>This add-on has no libraries</sdk:name-display> - - <sdk:vendor-id>Joe_Bar</sdk:vendor-id> - <sdk:vendor-display>Joe Bar</sdk:vendor-display> - - <sdk:uses-license ref="license2" /> - <sdk:api-level>4</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs /> - <sdk:layoutlib> - <sdk:api>3</sdk:api> - <sdk:revision>42</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:extra> - <sdk:name-display>Random name, not an id!</sdk:name-display> - - <sdk:vendor-id>cyclop</sdk:vendor-id> - <sdk:vendor-display>The big bus</sdk:vendor-display> - - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - </sdk:extra> - - <sdk:extra> - <sdk:name-display>Yet another extra, by Android</sdk:name-display> - - <sdk:vendor-id>android_vendor</sdk:vendor-id> - <sdk:vendor-display>Android Vendor</sdk:vendor-display> - - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:project-files> - <sdk:path>v8/veggies_8.jar</sdk:path> - <sdk:path>root.jar</sdk:path> - <sdk:path>dir1/dir 2 with space/mylib.jar</sdk:path> - </sdk:project-files> - <sdk:old-paths>path1;old_path2;oldPath3</sdk:old-paths> - </sdk:extra> - - <sdk:extra> - <sdk:name-display>. -..- - .-. .-</sdk:name-display> - - <sdk:vendor-id>____</sdk:vendor-id> - <sdk:vendor-display>____</sdk:vendor-display> - - <sdk:path>____</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <!-- No project-files element in this package. --> - </sdk:extra> - -</sdk:sdk-addon> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_5.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_5.xml deleted file mode 100755 index 47b37be..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addon_sample_5.xml +++ /dev/null @@ -1,214 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-addon - xmlns:sdk="http://schemas.android.com/sdk/android/addon/5"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:add-on> - <sdk:name-id>My_First_add-on</sdk:name-id> - <sdk:name-display>My First add-on</sdk:name-display> - - <sdk:vendor-id>John_Doe</sdk:vendor-id> - <sdk:vendor-display>John Doe</sdk:vendor-display> - - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <!-- sdk:description is optional, name is not --> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:add-on> - <sdk:name-id>My_Second_add-on</sdk:name-id> - <sdk:name-display>My Second add-on</sdk:name-display> - - <sdk:vendor-id>John_Deer</sdk:vendor-id> - <sdk:vendor-display>John Deer</sdk:vendor-display> - - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:uses-license ref="license2" /> - <!-- No layoutlib element in this package. It's optional. --> - </sdk:add-on> - - <sdk:add-on> - <sdk:name-id>no_libs</sdk:name-id> - <sdk:name-display>This add-on has no libraries</sdk:name-display> - - <sdk:vendor-id>Joe_Bar</sdk:vendor-id> - <sdk:vendor-display>Joe Bar</sdk:vendor-display> - - <sdk:uses-license ref="license2" /> - <sdk:api-level>4</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs /> - <sdk:layoutlib> - <sdk:api>3</sdk:api> - <sdk:revision>42</sdk:revision> - </sdk:layoutlib> - </sdk:add-on> - - <sdk:extra> - <sdk:name-display>Random name, not an id!</sdk:name-display> - - <sdk:vendor-id>cyclop</sdk:vendor-id> - <sdk:vendor-display>The big bus</sdk:vendor-display> - - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev> - <sdk:major>3</sdk:major> - <sdk:minor>2</sdk:minor> - <sdk:micro>1</sdk:micro> - <sdk:preview>42</sdk:preview> - </sdk:min-tools-rev> - <sdk:obsolete/> - </sdk:extra> - - <sdk:extra> - <sdk:name-display>Yet another extra, by Android</sdk:name-display> - - <sdk:vendor-id>android_vendor</sdk:vendor-id> - <sdk:vendor-display>Android Vendor</sdk:vendor-display> - - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev> - <sdk:major>3</sdk:major> - </sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:project-files> - <sdk:path>v8/veggies_8.jar</sdk:path> - <sdk:path>root.jar</sdk:path> - <sdk:path>dir1/dir 2 with space/mylib.jar</sdk:path> - </sdk:project-files> - <sdk:old-paths>path1;old_path2;oldPath3</sdk:old-paths> - </sdk:extra> - - <sdk:extra> - <sdk:name-display>. -..- - .-. .-</sdk:name-display> - - <sdk:vendor-id>____</sdk:vendor-id> - <sdk:vendor-display>____</sdk:vendor-display> - - <sdk:path>____</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev> - <sdk:major>3</sdk:major> - <!-- no minor, assumed to be 0 --> - <sdk:micro>1</sdk:micro> - </sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <!-- No project-files element in this package. --> - </sdk:extra> - -</sdk:sdk-addon> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_1.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_1.xml deleted file mode 100755 index 5ea5cb8..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_1.xml +++ /dev/null @@ -1,43 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-addons-list - xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/1"> - - <sdk:addon-site> - <sdk:url>http://www.example.com/my_addons.xml</sdk:url> - <sdk:name> <!-- we'll ignore leading/trailing spacing --> - My Example Add-ons. - </sdk:name> - </sdk:addon-site> - - <sdk:addon-site> - <sdk:url>http://www.example.co.jp/addons.xml</sdk:url> - <!-- this file is UTF-8 so we support character sets --> - <sdk:name>ありがとうございます。</sdk:name> - </sdk:addon-site> - - <sdk:addon-site> - <sdk:url>http://www.example.com/</sdk:url> - <sdk:name>Example of directory URL.</sdk:name> - </sdk:addon-site> - - <sdk:addon-site> - <sdk:url>relative_url.xml</sdk:url> - <sdk:name>Relative URL.</sdk:name> - </sdk:addon-site> - -</sdk:sdk-addons-list> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml deleted file mode 100755 index ef72b2c..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/addons_list_sample_2.xml +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-addons-list - xmlns:sdk="http://schemas.android.com/sdk/android/addons-list/2"> - - <sdk:addon-site> - <sdk:url>http://www.example.com/my_addons.xml</sdk:url> - <sdk:name> <!-- we'll ignore leading/trailing spacing --> - My Example Add-ons. - </sdk:name> - </sdk:addon-site> - - <sdk:addon-site> - <sdk:url>http://www.example.co.jp/addons.xml</sdk:url> - <!-- this file is UTF-8 so we support character sets --> - <sdk:name>ありがとうございます。</sdk:name> - </sdk:addon-site> - - <sdk:addon-site> - <sdk:url>http://www.example.com/</sdk:url> - <sdk:name>Example of directory URL.</sdk:name> - </sdk:addon-site> - - <sdk:sys-img-site> - <sdk:url>http://www.example.com/</sdk:url> - <sdk:name>Example of sys-img URL using the default xml filename.</sdk:name> - </sdk:sys-img-site> - - <sdk:sys-img-site> - <sdk:url>http://www.example.com/specific_file.xml</sdk:url> - <sdk:name>Example of sys-img URL using a specific xml filename.</sdk:name> - </sdk:sys-img-site> - - <sdk:addon-site> - <sdk:url>relative/url.xml</sdk:url> - <sdk:name>Relative URL.</sdk:name> - </sdk:addon-site> - -</sdk:sdk-addons-list> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_1.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_1.xml deleted file mode 100755 index 7e2bc36..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_1.xml +++ /dev/null @@ -1,274 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-repository - xmlns:sdk="http://schemas.android.com/sdk/android/repository/1"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:platform> - <sdk:version>1.0</sdk:version> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <sdk:release-note>This is an optional release note - for this package. It's a free multi-line text. - </sdk:release-note> - <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url> - <sdk:min-tools-rev>2</sdk:min-tools-rev> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:doc> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <!-- the license element is not mandatory. --> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:add-on> - <sdk:name>My First add-on</sdk:name> - <sdk:api-level>1</sdk:api-level> - <sdk:vendor>John Doe</sdk:vendor> - <sdk:revision>1</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <!-- sdk:description is optional, name is not --> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - </sdk:add-on> - - <sdk:platform> - <sdk:version>1.1</sdk:version> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:uses-license ref="license1" /> - <!-- sdk:description and sdk:desc-url are optional --> - <sdk:archives> - <sdk:archive os="windows"> - <!-- arch attribute is optional --> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="ppc"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86_64"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:add-on> - <sdk:name>My Second add-on</sdk:name> - <sdk:api-level>2</sdk:api-level> - <sdk:vendor>John Deer</sdk:vendor> - <sdk:revision>42</sdk:revision> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:uses-license ref="license2" /> - </sdk:add-on> - - <sdk:platform> - <sdk:version>Pastry</sdk:version> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Pastry</sdk:codename> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Preview version for Pastry</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:tool> - <sdk:revision>1</sdk:revision> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/tools1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:doc> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:tool> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:add-on> - <sdk:uses-license ref="license2" /> - <sdk:name>This add-on has no libraries</sdk:name> - <sdk:api-level>4</sdk:api-level> - <sdk:vendor>Joe Bar</sdk:vendor> - <sdk:revision>3</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs /> - </sdk:add-on> - - <sdk:extra> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - </sdk:extra> - -</sdk:sdk-repository> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_2.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_2.xml deleted file mode 100755 index 6b2d679..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_2.xml +++ /dev/null @@ -1,309 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-repository - xmlns:sdk="http://schemas.android.com/sdk/android/repository/2"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:platform> - <sdk:version>1.0</sdk:version> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <sdk:release-note>This is an optional release note - for this package. It's a free multi-line text. - </sdk:release-note> - <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url> - <sdk:min-tools-rev>2</sdk:min-tools-rev> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:doc> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <!-- the license element is not mandatory. --> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:add-on> - <sdk:name>My First add-on</sdk:name> - <sdk:api-level>1</sdk:api-level> - <sdk:vendor>John Doe</sdk:vendor> - <sdk:revision>1</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/myfirstaddon</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/add-ons/first.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <!-- sdk:description is optional, name is not --> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - </sdk:add-on> - - <sdk:platform> - <sdk:version>1.1</sdk:version> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:uses-license ref="license1" /> - <!-- sdk:description and sdk:desc-url are optional --> - <sdk:archives> - <sdk:archive os="windows"> - <!-- arch attribute is optional --> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="ppc"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86_64"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:add-on> - <sdk:name>My Second add-on</sdk:name> - <sdk:api-level>2</sdk:api-level> - <sdk:vendor>John Deer</sdk:vendor> - <sdk:revision>42</sdk:revision> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/second-42-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:libs> - <sdk:lib> - <sdk:name>android.blah.somelib</sdk:name> - <sdk:description>The description for this library.</sdk:description> - </sdk:lib> - <sdk:lib> - <sdk:name>com.android.mymaps</sdk:name> - </sdk:lib> - </sdk:libs> - <sdk:uses-license ref="license2" /> - </sdk:add-on> - - <sdk:platform> - <sdk:version>Pastry</sdk:version> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Pastry</sdk:codename> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Preview version for Pastry</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:tool> - <sdk:revision>1</sdk:revision> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/tools1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:doc> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:tool> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:add-on> - <sdk:uses-license ref="license2" /> - <sdk:name>This add-on has no libraries</sdk:name> - <sdk:api-level>4</sdk:api-level> - <sdk:vendor>Joe Bar</sdk:vendor> - <sdk:revision>3</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/imnotanarchiveimadoctorjim.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <!-- The libs node is mandatory, however it can be empty. --> - <sdk:libs /> - </sdk:add-on> - - <sdk:extra> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - </sdk:extra> - - <sdk:extra> - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - </sdk:extra> - - <sdk:sample> - <sdk:api-level>14</sdk:api-level> - <sdk:revision>24</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65537</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/sample_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some sample package</sdk:description> - <sdk:desc-url>http://www.example.com/sample.html</sdk:desc-url> - <sdk:min-tools-rev>5</sdk:min-tools-rev> - <sdk:obsolete>This is obsolete</sdk:obsolete> - </sdk:sample> - -</sdk:sdk-repository> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_3.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_3.xml deleted file mode 100755 index 05a9c79..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_3.xml +++ /dev/null @@ -1,261 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-repository - xmlns:sdk="http://schemas.android.com/sdk/android/repository/3"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:platform> - <sdk:version>1.0</sdk:version> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <sdk:release-note>This is an optional release note - for this package. It's a free multi-line text. - </sdk:release-note> - <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url> - <sdk:min-tools-rev>2</sdk:min-tools-rev> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:doc> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <!-- the license element is not mandatory. --> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:platform> - <sdk:version>1.1</sdk:version> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:uses-license ref="license1" /> - <!-- sdk:description and sdk:desc-url are optional --> - <sdk:archives> - <sdk:archive os="windows"> - <!-- arch attribute is optional --> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="ppc"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86_64"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:platform> - <sdk:version>Pastry</sdk:version> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Pastry</sdk:codename> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Preview version for Pastry</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform> - - <sdk:tool> - <sdk:revision>1</sdk:revision> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>4</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/tools1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:doc> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:tool> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>3</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:platform-tool> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform-tool> - - <sdk:extra> - <sdk:vendor>a</sdk:vendor> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>android_vendor</sdk:vendor> - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - </sdk:extra> - - <sdk:sample> - <sdk:api-level>14</sdk:api-level> - <sdk:revision>24</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65537</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/sample_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some sample package</sdk:description> - <sdk:desc-url>http://www.example.com/sample.html</sdk:desc-url> - <sdk:min-tools-rev>5</sdk:min-tools-rev> - <sdk:obsolete>This is obsolete</sdk:obsolete> - </sdk:sample> - -</sdk:sdk-repository> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_4.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_4.xml deleted file mode 100755 index f68b033..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_4.xml +++ /dev/null @@ -1,278 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-repository - xmlns:sdk="http://schemas.android.com/sdk/android/repository/4"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:platform> - <sdk:version>1.0</sdk:version> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <sdk:release-note>This is an optional release note - for this package. It's a free multi-line text. - </sdk:release-note> - <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url> - <sdk:min-tools-rev>2</sdk:min-tools-rev> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - </sdk:platform> - - <sdk:doc> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <!-- the license element is not mandatory. --> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:platform> - <sdk:version>1.1</sdk:version> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:uses-license ref="license1" /> - <!-- sdk:description and sdk:desc-url are optional --> - <sdk:archives> - <sdk:archive os="windows"> - <!-- arch attribute is optional --> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="ppc"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86_64"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>31415</sdk:revision> - </sdk:layoutlib> - </sdk:platform> - - <sdk:platform> - <sdk:version>Pastry</sdk:version> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Pastry</sdk:codename> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Preview version for Pastry</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>1</sdk:api> - </sdk:layoutlib> - </sdk:platform> - - <sdk:tool> - <sdk:revision>1</sdk:revision> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>4</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/tools1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:doc> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:tool> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>3</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:platform-tool> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform-tool> - - <sdk:extra> - <sdk:vendor>a</sdk:vendor> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - <!-- no project-files in this USB driver package. --> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>android_vendor</sdk:vendor> - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <sdk:project-files> - <sdk:path>v8/veggies_8.jar</sdk:path> - <sdk:path>readme.txt</sdk:path> - <sdk:path>dir1/dir 2 with space/mylib.jar</sdk:path> - </sdk:project-files> - </sdk:extra> - - <sdk:sample> - <sdk:api-level>14</sdk:api-level> - <sdk:revision>24</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65537</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/sample_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some sample package</sdk:description> - <sdk:desc-url>http://www.example.com/sample.html</sdk:desc-url> - <sdk:min-tools-rev>5</sdk:min-tools-rev> - <sdk:obsolete>This is obsolete</sdk:obsolete> - </sdk:sample> - -</sdk:sdk-repository> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_5.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_5.xml deleted file mode 100755 index 471550e..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_5.xml +++ /dev/null @@ -1,356 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-repository - xmlns:sdk="http://schemas.android.com/sdk/android/repository/5"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:platform> - <sdk:version>1.0</sdk:version> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <sdk:release-note>This is an optional release note - for this package. It's a free multi-line text. - </sdk:release-note> - <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url> - <sdk:min-tools-rev>2</sdk:min-tools-rev> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - <sdk:included-abi>armeabi</sdk:included-abi> - </sdk:platform> - - <sdk:doc> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <!-- the license element is not mandatory. --> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:source> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65535</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/sources1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - - <sdk:platform> - <sdk:version>1.1</sdk:version> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:uses-license ref="license1" /> - <!-- sdk:description and sdk:desc-url are optional --> - <sdk:archives> - <sdk:archive os="windows"> - <!-- arch attribute is optional --> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="ppc"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86_64"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>31415</sdk:revision> - </sdk:layoutlib> - <sdk:included-abi>x86</sdk:included-abi> - </sdk:platform> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:abi>x86</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65535</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/x86/image1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>2</sdk:revision> - <sdk:abi>armeabi-v7a</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65534</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/armv7/image2.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:source> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65534</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/sources2.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - - <sdk:platform> - <sdk:version>Pastry</sdk:version> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Pastry</sdk:codename> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Preview version for Pastry</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>1</sdk:api> - </sdk:layoutlib> - </sdk:platform> - - <sdk:tool> - <sdk:revision>1</sdk:revision> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>4</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/tools1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:doc> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:tool> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>3</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:platform-tool> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform-tool> - - <sdk:extra> - <sdk:vendor>a</sdk:vendor> - <sdk:path>usb_driver</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>43</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extraduff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>An Extra package for the USB driver, it will install in $SDK/usb_driver</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:obsolete/> - <!-- no project-files in this USB driver package. --> - </sdk:extra> - - <sdk:extra> - <sdk:vendor>android_vendor</sdk:vendor> - <sdk:path>extra_api_dep</sdk:path> - <sdk:uses-license ref="license2" /> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/extra_mega_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some extra package that has a min-api-level of 42</sdk:description> - <sdk:desc-url>http://www.example.com/extra.html</sdk:desc-url> - <sdk:min-tools-rev>3</sdk:min-tools-rev> - <sdk:min-api-level>42</sdk:min-api-level> - <sdk:obsolete></sdk:obsolete> - <sdk:project-files> - <sdk:path>v8/veggies_8.jar</sdk:path> - <sdk:path>readme.txt</sdk:path> - <sdk:path>dir1/dir 2 with space/mylib.jar</sdk:path> - </sdk:project-files> - <sdk:old-paths>path1;old_path2;oldPath3</sdk:old-paths> - </sdk:extra> - - <sdk:sample> - <sdk:api-level>14</sdk:api-level> - <sdk:revision>24</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65537</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/sample_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some sample package</sdk:description> - <sdk:desc-url>http://www.example.com/sample.html</sdk:desc-url> - <sdk:min-tools-rev>5</sdk:min-tools-rev> - <sdk:obsolete>This is obsolete</sdk:obsolete> - </sdk:sample> - - <sdk:system-image> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:abi>armeabi</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>1234</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/86/image12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:source> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>1234</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/source12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - -</sdk:sdk-repository> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_6.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_6.xml deleted file mode 100755 index 12be591..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_6.xml +++ /dev/null @@ -1,325 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-repository - xmlns:sdk="http://schemas.android.com/sdk/android/repository/6"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:platform> - <sdk:version>1.0</sdk:version> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <sdk:release-note>This is an optional release note - for this package. It's a free multi-line text. - </sdk:release-note> - <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url> - <sdk:min-tools-rev>2</sdk:min-tools-rev> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - <sdk:included-abi>armeabi</sdk:included-abi> - </sdk:platform> - - <sdk:doc> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <!-- the license element is not mandatory. --> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:source> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65535</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/sources1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - - <sdk:platform> - <sdk:version>1.1</sdk:version> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:uses-license ref="license1" /> - <!-- sdk:description and sdk:desc-url are optional --> - <sdk:archives> - <sdk:archive os="windows"> - <!-- arch attribute is optional --> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="ppc"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86_64"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>31415</sdk:revision> - </sdk:layoutlib> - <sdk:included-abi>x86</sdk:included-abi> - </sdk:platform> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:abi>x86</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65535</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/x86/image1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>2</sdk:revision> - <sdk:abi>armeabi-v7a</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65534</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/armv7/image2.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:source> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65534</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/sources2.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - - <sdk:platform> - <sdk:version>Pastry</sdk:version> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Pastry</sdk:codename> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Preview version for Pastry</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>1</sdk:api> - </sdk:layoutlib> - </sdk:platform> - - <sdk:tool> - <sdk:revision>1</sdk:revision> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>4</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/tools1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:doc> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:tool> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev>3</sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:platform-tool> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform-tool> - - <sdk:sample> - <sdk:api-level>14</sdk:api-level> - <sdk:revision>24</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65537</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/sample_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some sample package</sdk:description> - <sdk:desc-url>http://www.example.com/sample.html</sdk:desc-url> - <sdk:min-tools-rev>5</sdk:min-tools-rev> - <sdk:obsolete>This is obsolete</sdk:obsolete> - </sdk:sample> - - <sdk:system-image> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:abi>armeabi</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>1234</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/86/image12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:abi>mips</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>12345</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/mips/image12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:source> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>1234</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/source12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - -</sdk:sdk-repository> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_7.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_7.xml deleted file mode 100755 index 401521b..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/repository_sample_7.xml +++ /dev/null @@ -1,371 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-repository - xmlns:sdk="http://schemas.android.com/sdk/android/repository/7"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <!-- Inner elements must be either platform, add-on, doc or tool. - There can be 0 or more of each, in any order. --> - - <sdk:platform> - <sdk:version>1.0</sdk:version> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <sdk:release-note>This is an optional release note - for this package. It's a free multi-line text. - </sdk:release-note> - <sdk:release-url>http://some/url/for/the/release/note.html</sdk:release-url> - <sdk:min-tools-rev> - <sdk:major>2</sdk:major> - <!-- minor is missing and equivalent to 0 --> - <sdk:micro>1</sdk:micro> - </sdk:min-tools-rev> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>0</sdk:revision> - </sdk:layoutlib> - <sdk:included-abi>armeabi</sdk:included-abi> - </sdk:platform> - - <sdk:doc> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <!-- the license element is not mandatory. --> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/docs.html</sdk:desc-url> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/docs/docs1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:source> - <sdk:api-level>1</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65535</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/sources1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - - <sdk:platform> - <sdk:version>1.1</sdk:version> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:uses-license ref="license1" /> - <!-- sdk:description and sdk:desc-url are optional --> - <sdk:archives> - <sdk:archive os="windows"> - <!-- arch attribute is optional --> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-win.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="macosx" arch="ppc"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-mac.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="linux" arch="x86_64"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-2-12-linux.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>5</sdk:api> - <sdk:revision>31415</sdk:revision> - </sdk:layoutlib> - <sdk:included-abi>x86</sdk:included-abi> - </sdk:platform> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:abi>x86</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65535</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/x86/image1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>2</sdk:revision> - <sdk:abi>armeabi-v7a</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65534</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/armv7/image2.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:source> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>2</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65534</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/sources2.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - - <sdk:platform> - <sdk:version>Pastry</sdk:version> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Pastry</sdk:codename> - <sdk:revision>3</sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:description>Preview version for Pastry</sdk:description> - <sdk:desc-url>http://www.example.com/platform1.html</sdk:desc-url> - <!-- The archives node is mandatory and it cannot be empty. --> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/plat1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:layoutlib> - <sdk:api>1</sdk:api> - </sdk:layoutlib> - </sdk:platform> - - <sdk:tool> - <sdk:revision> - <sdk:major>1</sdk:major> - <sdk:minor>2</sdk:minor> - <sdk:micro>3</sdk:micro> - <sdk:preview>4</sdk:preview> - </sdk:revision> - <sdk:description>Some optional description</sdk:description> - <sdk:desc-url>http://www.example.com/tools.html</sdk:desc-url> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev> - <sdk:major>4</sdk:major> - </sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>http://www.example.com/files/tools1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:doc> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>42</sdk:revision> - <sdk:uses-license ref="license2" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/docs2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:doc> - - <sdk:tool> - <sdk:revision> - <sdk:major>42</sdk:major> - </sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:min-platform-tools-rev> - <sdk:major>4</sdk:major> - <sdk:minor>0</sdk:minor> - <sdk:micro>0</sdk:micro> - <sdk:preview>5</sdk:preview> - </sdk:min-platform-tools-rev> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">2822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:tool> - - <sdk:platform-tool> - <sdk:revision> - <sdk:major>3</sdk:major> - <sdk:minor>0</sdk:minor> - <sdk:micro>0</sdk:micro> - <sdk:preview>5</sdk:preview> - </sdk:revision> - <sdk:uses-license ref="license1" /> - <sdk:archives> - <sdk:archive os="windows"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools/2.zip</sdk:url> - </sdk:archive> - <sdk:archive os="linux"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-linux.tar.bz2</sdk:url> - </sdk:archive> - <sdk:archive os="macosx"> - <sdk:size>65536</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/platform-tools2-mac.tar.bz2</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:platform-tool> - - <sdk:sample> - <sdk:api-level>14</sdk:api-level> - <sdk:revision>24</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65537</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/sample_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some sample package</sdk:description> - <sdk:desc-url>http://www.example.com/sample.html</sdk:desc-url> - <sdk:min-tools-rev> - <sdk:major>5</sdk:major> - </sdk:min-tools-rev> - <sdk:obsolete>This is obsolete</sdk:obsolete> - </sdk:sample> - - <sdk:sample> - <sdk:api-level>14</sdk:api-level> - <sdk:revision>25</sdk:revision> - <sdk:archives> - <sdk:archive os="any" arch="any"> - <sdk:size>65537</sdk:size> - <sdk:checksum type="sha1">3822ae37115ebf13412bbef91339ee0d9454525e</sdk:checksum> - <sdk:url>distrib/sample_duff.zip</sdk:url> - </sdk:archive> - </sdk:archives> - <sdk:description>Some sample package</sdk:description> - <sdk:desc-url>http://www.example.com/sample.html</sdk:desc-url> - <sdk:min-tools-rev> - <sdk:major>5</sdk:major> - <sdk:minor>1</sdk:minor> - <sdk:micro>2</sdk:micro> - <sdk:preview>3</sdk:preview> - </sdk:min-tools-rev> - <sdk:obsolete>This is obsolete</sdk:obsolete> - </sdk:sample> - - <sdk:system-image> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:abi>armeabi</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>1234</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/86/image12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:abi>mips</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>12345</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/mips/image12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:source> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>1234</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/source12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:source> - -</sdk:sdk-repository> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/stats_sample_1.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/stats_sample_1.xml deleted file mode 100755 index 344b8a5..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/stats_sample_1.xml +++ /dev/null @@ -1,48 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-stats - xmlns:sdk="http://schemas.android.com/sdk/android/stats/1"> - - <sdk:platform> - <sdk:api-level>3</sdk:api-level> - <sdk:codename>Vanilla</sdk:codename> - <sdk:version>Android 0.5</sdk:version> - <sdk:share>0.1</sdk:share> - </sdk:platform> - - <sdk:platform> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Coffee</sdk:codename> - <sdk:version>Android 42.0</sdk:version> - <sdk:share>25.8</sdk:share> - </sdk:platform> - - <sdk:platform> - <sdk:api-level>42</sdk:api-level> - <sdk:codename>Chocolate</sdk:codename> - <sdk:version>Android 32.64</sdk:version> - <sdk:share>74.1</sdk:share> - </sdk:platform> - - <sdk:platform> - <sdk:api-level>5</sdk:api-level> - <sdk:codename>Ignored</sdk:codename> - <sdk:version>API 5 was already seen above</sdk:version> - <sdk:share>99.9</sdk:share> - </sdk:platform> - -</sdk:sdk-stats> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml deleted file mode 100755 index 6196db4..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/testdata/sys_img_sample_1.xml +++ /dev/null @@ -1,83 +0,0 @@ -<?xml version="1.0"?> -<!-- - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. ---> -<sdk:sdk-sys-img - xmlns:sdk="http://schemas.android.com/sdk/android/sys-img/1"> - - <!-- Define a couple of licenses. These will be referenced by uses-license later. --> - - <sdk:license type="text" id="license1"> - This is the license - for this platform. - </sdk:license> - - <sdk:license id="license2"> - Licenses are only of type 'text' right now, so this is implied. - </sdk:license> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>1</sdk:revision> - <sdk:abi>x86</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65535</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/x86/image1.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>2</sdk:api-level> - <sdk:revision>2</sdk:revision> - <sdk:abi>armeabi-v7a</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>65534</sdk:size> - <sdk:checksum type="sha1">1234ae37115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat1/armv7/image2.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:abi>armeabi</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>1234</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/86/image12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - - <sdk:system-image> - <sdk:api-level>42</sdk:api-level> - <sdk:revision>12</sdk:revision> - <sdk:abi>mips</sdk:abi> - <sdk:archives> - <sdk:archive os="any"> - <sdk:size>12345</sdk:size> - <sdk:checksum type="sha1">12345637115ebf13412bbef91339ee0d94541234</sdk:checksum> - <sdk:url>http://www.example.com/plat42/mips/image12.zip</sdk:url> - </sdk:archive> - </sdk:archives> - </sdk:system-image> - -</sdk:sdk-sys-img> diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/BSPatchTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/BSPatchTest.java deleted file mode 100755 index 6c6c405..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/BSPatchTest.java +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - -import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; - -import junit.framework.TestCase; - - -public class BSPatchTest extends TestCase { - - // $ bsdiff file1 file2 diff-1-2.patch - // $ hexdump -v -e '1/1 "0x%02x, "' diff-1-2.patch - - public void testBSPatch1() throws Exception { - byte[] file1 = toSignedBytes(new short[] { - 0x62, 0x73, 0x64, 0x69, 0x66, 0x66, 0x20, 0x69, 0x73, 0x20, - 0x61, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x20, 0x66, 0x6f, 0x72, - 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x67, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x69, - 0x6e, 0x67, 0x20, 0x70, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, - 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, - 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a - }); - - byte[] file2 = toSignedBytes(new short[] { - 0x62, 0x73, 0x64, 0x69, 0x66, 0x66, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x62, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, - 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, - 0x79, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x61, - 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a, - }); - - byte[] patch = toSignedBytes(new short[] { - 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34, 0x30, 0x35, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, - 0x53, 0x59, 0x93, 0x0d, 0x6a, 0xae, 0x00, 0x00, 0x0c, 0x68, - 0x40, 0x58, 0xa8, 0x02, 0x00, 0x04, 0x00, 0x40, 0x00, 0x20, - 0x00, 0x21, 0x88, 0x19, 0x08, 0x32, 0x62, 0x1b, 0xde, 0xbc, - 0x24, 0x08, 0xe9, 0x45, 0x3c, 0x5d, 0xc9, 0x14, 0xe1, 0x42, - 0x42, 0x4c, 0x35, 0xaa, 0xb8, 0x42, 0x5a, 0x68, 0x39, 0x31, - 0x41, 0x59, 0x26, 0x53, 0x59, 0x05, 0xb6, 0xa3, 0x63, 0x00, - 0x00, 0x00, 0x48, 0x00, 0x40, 0x00, 0x00, 0x80, 0x20, 0x00, - 0x21, 0x00, 0x82, 0x83, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, - 0x05, 0xb6, 0xa3, 0x63, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, - 0x59, 0x26, 0x53, 0x59, 0xdb, 0x41, 0x22, 0x6f, 0x00, 0x00, - 0x01, 0x91, 0x80, 0x40, 0x00, 0x3e, 0x45, 0xdc, 0x00, 0x20, - 0x00, 0x22, 0x9a, 0x19, 0x32, 0x7a, 0x7a, 0xa1, 0x00, 0x00, - 0x21, 0xe2, 0xf8, 0x98, 0x42, 0x13, 0x3c, 0xec, 0x35, 0x5f, - 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0xdb, 0x41, 0x22, 0x6f - }); - - byte[] expected = file2; - byte[] actual = patchFile(file1, patch); - - assertEquals(toDiffString(expected, actual), - Arrays.toString(expected), Arrays.toString(actual)); - } - - public void testBSPatch2() throws Exception { - byte[] file1 = toSignedBytes(new short[] { - 0x62, 0x73, 0x64, 0x69, 0x66, 0x66, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x62, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, - 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, - 0x79, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x61, - 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, - 0x67, 0x79, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x62, 0x73, 0x64, - 0x69, 0x66, 0x66, 0x2f, 0x0a, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x67, 0x65, - 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x70, 0x70, - 0x6c, 0x79, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, - 0x77, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, - 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a - }); - - byte[] file2 = toSignedBytes(new short[] { - 0x62, 0x73, 0x64, 0x69, 0x66, 0x66, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x62, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, - 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, - 0x79, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x61, - 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a, - 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x3a, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x61, 0x20, - 0x70, 0x61, 0x74, 0x63, 0x68, 0x20, 0x62, 0x65, 0x74, 0x77, - 0x65, 0x65, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x62, 0x69, - 0x6e, 0x61, 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, - 0x2e, 0x0a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x6f, - 0x6c, 0x6f, 0x67, 0x79, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x62, - 0x73, 0x64, 0x69, 0x66, 0x66, 0x2f, 0x0a, 0x42, 0x53, 0x44, - 0x20, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x2c, 0x20, - 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, - 0x32, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x30, 0x30, 0x35, 0x20, - 0x43, 0x6f, 0x6c, 0x69, 0x6e, 0x20, 0x50, 0x65, 0x72, 0x63, - 0x69, 0x76, 0x61, 0x6c, 0x0a, - }); - - byte[] patch = toSignedBytes(new short[] { - 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34, 0x30, 0x3e, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, - 0x53, 0x59, 0x3f, 0xa6, 0x07, 0x42, 0x00, 0x00, 0x14, 0x5d, - 0x40, 0x58, 0x08, 0x08, 0x00, 0xc8, 0x02, 0x00, 0x00, 0xa0, - 0x00, 0x40, 0x00, 0x20, 0x00, 0x21, 0xa4, 0x69, 0x84, 0xfd, - 0x41, 0x03, 0x40, 0xd0, 0x22, 0xef, 0xe1, 0x49, 0x33, 0x02, - 0xce, 0x2e, 0xe6, 0x8b, 0xb9, 0x22, 0x9c, 0x28, 0x48, 0x1f, - 0xd3, 0x03, 0xa1, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, - 0x59, 0x26, 0x53, 0x59, 0x58, 0xc3, 0x04, 0xf0, 0x00, 0x00, - 0x00, 0x40, 0x10, 0x40, 0x00, 0x00, 0x02, 0x20, 0x00, 0x21, - 0x00, 0x82, 0x83, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x58, - 0xc3, 0x04, 0xf0, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, - 0x26, 0x53, 0x59, 0x26, 0xc7, 0xbc, 0x09, 0x00, 0x00, 0x08, - 0x5f, 0x80, 0x00, 0x10, 0x40, 0x06, 0x5a, 0x00, 0x1c, 0x00, - 0x48, 0x00, 0x2a, 0xe5, 0xdd, 0x20, 0x20, 0x00, 0x31, 0x46, - 0x86, 0x80, 0x00, 0x00, 0x1a, 0xa6, 0x26, 0x40, 0xfd, 0x50, - 0x34, 0x79, 0x27, 0x92, 0x78, 0xda, 0x4d, 0x37, 0xa9, 0x20, - 0x8d, 0x8c, 0x41, 0x90, 0xea, 0x1c, 0x3a, 0xb3, 0xaa, 0x63, - 0x64, 0xa4, 0x27, 0x6d, 0x5b, 0x2a, 0xfc, 0x25, 0x1b, 0xab, - 0xd2, 0xff, 0x8b, 0xb9, 0x22, 0x9c, 0x28, 0x48, 0x13, 0x63, - 0xde, 0x04, 0x80 - }); - - byte[] expected = file2; - byte[] actual = patchFile(file1, patch); - - assertEquals(toDiffString(expected, actual), - Arrays.toString(expected), Arrays.toString(actual)); - } - - public void testBSPatch3() throws Exception { - byte[] file1 = toSignedBytes(new short[] { - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, - 0x67, 0x79, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x62, 0x73, 0x64, - 0x69, 0x66, 0x66, 0x2f, 0x0a, 0x42, 0x69, 0x6e, 0x61, 0x72, - 0x79, 0x20, 0x64, 0x69, 0x66, 0x66, 0x2f, 0x70, 0x61, 0x74, - 0x63, 0x68, 0x20, 0x75, 0x74, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x0a, 0x53, 0x48, 0x41, 0x31, 0x3a, 0x20, 0x37, 0x32, 0x63, - 0x35, 0x37, 0x34, 0x33, 0x34, 0x62, 0x64, 0x64, 0x34, 0x63, - 0x33, 0x38, 0x33, 0x63, 0x36, 0x39, 0x62, 0x62, 0x30, 0x66, - 0x61, 0x64, 0x34, 0x32, 0x33, 0x35, 0x37, 0x38, 0x35, 0x32, - 0x32, 0x63, 0x64, 0x30, 0x64, 0x33, 0x61, 0x0a, 0x53, 0x48, - 0x41, 0x32, 0x35, 0x36, 0x3a, 0x20, 0x61, 0x62, 0x62, 0x64, - 0x32, 0x32, 0x30, 0x39, 0x33, 0x38, 0x35, 0x65, 0x38, 0x65, - 0x38, 0x38, 0x30, 0x61, 0x64, 0x64, 0x30, 0x62, 0x37, 0x38, - 0x31, 0x37, 0x37, 0x38, 0x64, 0x65, 0x64, 0x34, 0x39, 0x65, - 0x31, 0x30, 0x61, 0x36, 0x66, 0x30, 0x63, 0x37, 0x39, 0x39, - 0x64, 0x33, 0x32, 0x36, 0x61, 0x36, 0x61, 0x65, 0x36, 0x37, - 0x30, 0x33, 0x36, 0x39, 0x36, 0x38, 0x66, 0x62, 0x31, 0x64, - 0x0a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, - 0x74, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x61, - 0x20, 0x70, 0x61, 0x74, 0x63, 0x68, 0x20, 0x62, 0x65, 0x74, - 0x77, 0x65, 0x65, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x20, 0x62, - 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x0a, 0x20, 0x62, 0x73, 0x64, 0x69, 0x66, 0x66, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x62, 0x73, 0x70, 0x61, 0x74, 0x63, - 0x68, 0x20, 0x61, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x6c, - 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, - 0x70, 0x70, 0x6c, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, - 0x74, 0x63, 0x68, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, - 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x2e, 0x0a - }); - - byte[] file2 = toSignedBytes(new short[] { - 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x64, 0x69, 0x66, - 0x66, 0x2f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x20, 0x75, 0x74, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x0a, 0x48, 0x6f, 0x6d, 0x65, - 0x70, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x64, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, - 0x79, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x62, 0x73, 0x64, 0x69, - 0x66, 0x66, 0x2f, 0x0a, 0x53, 0x48, 0x41, 0x31, 0x3a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x37, 0x32, 0x63, - 0x35, 0x37, 0x34, 0x33, 0x34, 0x62, 0x64, 0x64, 0x34, 0x63, - 0x33, 0x38, 0x33, 0x63, 0x36, 0x39, 0x62, 0x62, 0x30, 0x66, - 0x61, 0x64, 0x34, 0x32, 0x33, 0x35, 0x37, 0x38, 0x35, 0x32, - 0x32, 0x63, 0x64, 0x30, 0x64, 0x33, 0x61, 0x0a, 0x53, 0x48, - 0x41, 0x32, 0x35, 0x36, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x61, 0x62, 0x62, 0x64, 0x32, 0x32, 0x30, 0x39, 0x33, - 0x38, 0x35, 0x65, 0x38, 0x65, 0x38, 0x38, 0x30, 0x61, 0x64, - 0x64, 0x30, 0x62, 0x37, 0x38, 0x31, 0x37, 0x37, 0x38, 0x64, - 0x65, 0x64, 0x34, 0x39, 0x65, 0x31, 0x30, 0x61, 0x36, 0x66, - 0x30, 0x63, 0x37, 0x39, 0x39, 0x64, 0x33, 0x32, 0x36, 0x61, - 0x36, 0x61, 0x65, 0x36, 0x37, 0x30, 0x33, 0x36, 0x39, 0x36, - 0x38, 0x66, 0x62, 0x31, 0x64, 0x0a, 0x44, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x2f, 0x61, 0x70, - 0x70, 0x6c, 0x79, 0x20, 0x61, 0x20, 0x70, 0x61, 0x74, 0x63, - 0x68, 0x20, 0x62, 0x65, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x20, - 0x74, 0x77, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, - 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x62, 0x73, 0x64, 0x69, 0x66, 0x66, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x62, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x20, 0x61, - 0x72, 0x65, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x66, - 0x6f, 0x72, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, - 0x67, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, - 0x79, 0x69, 0x6e, 0x67, 0x20, 0x70, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x61, - 0x72, 0x79, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a, - }); - - byte[] patch = toSignedBytes(new short[] { - 0x42, 0x53, 0x44, 0x49, 0x46, 0x46, 0x34, 0x30, 0x48, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26, - 0x53, 0x59, 0xea, 0x1c, 0x55, 0x4e, 0x00, 0x00, 0x07, 0xfa, - 0x40, 0x7c, 0x0e, 0x00, 0x10, 0x88, 0x00, 0x10, 0x02, 0x20, - 0x00, 0x40, 0x00, 0x20, 0x00, 0x21, 0x29, 0xa8, 0x00, 0x6d, - 0x42, 0x98, 0x00, 0x09, 0x9a, 0x99, 0xcc, 0xb7, 0x2b, 0xcd, - 0xf7, 0x1e, 0x00, 0x86, 0x22, 0x21, 0x09, 0x25, 0x14, 0xc5, - 0x0e, 0xd4, 0x61, 0xf1, 0x77, 0x24, 0x53, 0x85, 0x09, 0x0e, - 0xa1, 0xc5, 0x54, 0xe0, 0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, - 0x59, 0x26, 0x53, 0x59, 0xb2, 0xea, 0xe3, 0xb5, 0x00, 0x00, - 0x00, 0xc8, 0x00, 0xc0, 0x00, 0x00, 0x02, 0x00, 0x08, 0x20, - 0x00, 0x21, 0x26, 0x41, 0x98, 0xa8, 0x0e, 0x2e, 0xe4, 0x8a, - 0x70, 0xa1, 0x21, 0x65, 0xd5, 0xc7, 0x6a, 0x42, 0x5a, 0x68, - 0x39, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x99, 0x1b, 0x67, - 0xdb, 0x00, 0x00, 0x07, 0xff, 0x80, 0x40, 0x00, 0x10, 0x00, - 0x40, 0x00, 0x20, 0x10, 0x20, 0x40, 0x08, 0x00, 0x22, 0x82, - 0xc0, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x06, 0x81, 0x33, - 0x50, 0xc3, 0x00, 0x20, 0x73, 0xb3, 0x44, 0x9c, 0xfd, 0xde, - 0x1f, 0x68, 0xbb, 0x92, 0x29, 0xc2, 0x84, 0x84, 0xc8, 0xdb, - 0x3e, 0xd8 - }); - - byte[] expected = file2; - byte[] actual = patchFile(file1, patch); - - assertEquals(toDiffString(expected, actual), - Arrays.toString(expected), Arrays.toString(actual)); - } - - private String toDiffString(byte[] a1, byte[] a2) { - StringBuilder sb = new StringBuilder(); - int n1 = a1.length; - int n2 = a2.length; - boolean was_same = false; - - for (int i = 0; i < n1; i++) { - boolean same = i > 1 && - i+2 < n1 && - i+2 < n2 && - a1[i+0] == a2[i+0] && - a1[i+1] == a2[i+1] && - a1[i+2] == a2[i+2]; - if (!same) { - if (i >= n2) { - sb.append(String.format("[%1$3d] %2$02x %2$c | -- -\n", i, a1[i])); - } else { - sb.append(String.format("[%1$3d] %2$02x %2$c | %3$02x %3$c\n", i, a1[i], a2[i])); - } - } else if (!was_same) { - sb.append(String.format("[%1$3d] ...\n", i)); - } - was_same = same; - } - for (int i = n1; i < n2; i++) { - sb.append(String.format("[%1$3d] -- - | %2$02x %2$c\n", i, a2[i])); - } - - return sb.toString(); - } - - /** - * Work around the lack of unsigned bytes in java by providing an initialization - * array where each short is in the range 0..0xFF and converting it to signed bytes. - * - * unsigned byte: 0..127 => signed java byte: 0..127 - * unsigned byte: 128..255 => signed java byte: -128..-1 - * - * unsigned to signed java: (unsigned - 256) if unsigned > 127 - * signed java to unsigned: (256 + signed) if signed < 0 - */ - private byte[] toSignedBytes(short[] s) { - int n = s.length; - byte[] b = new byte[n]; - for (int i = 0; i < n; i++) { - short v = s[i]; - b[i] = v < 128 ? (byte)v : (byte)(v - 256); - } - return b; - } - - @SuppressWarnings("unused") - private byte toSigned(int unsigned) { - return unsigned < 128 ? (byte)unsigned : (byte)(unsigned - 256); - } - - private short toUnsigned(byte signed) { - if (signed >= 0) { - return signed; - } else { - return (short) ((short) 256 + signed); - } - } - - /** - * Patches the binary "file1" using the bsdiff/bspatch "patch" data. - * This implements bspatch.c in Java. - * - * Reference: http://www.daemonology.net/bsdiff/ <br/> - * Based on bspatch.c as identified by <br/> - * {@code $FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59:06 cperciva Exp $} - * (BSD license, Copyright 2003-2005 Colin Percival) - * - * @param file1 The base file to be patched. - * @param patch The binary patch to apply to base file. - * @return A new byte array representing the patched file. - * @throws PatchException when the patch header is invalid. - * @throws IOException if the BZIP2 decoder fails. - */ - private byte[] patchFile(byte[] file1, byte[] patch) throws PatchException, IOException { - /* - File format: - 0 8 "BSDIFF40" - 8 8 X - 16 8 Y - 24 8 sizeof(newfile) - 32 X bzip2(control block) - 32+X Y bzip2(diff block) - 32+X+Y ??? bzip2(extra block) - with control block a set of triples (x,y,z) meaning "add x bytes - from oldfile to x bytes from the diff block; copy y bytes from the - extra block; seek forwards in oldfile by z bytes". - */ - - /* Read header */ - if (patch.length < 32) { - throw new PatchException("Header.len < 32"); - } - byte[] header = patch; - - /* Check for appropriate magic */ - if (header[0] != 'B' || header[1] != 'S' || header[2] != 'D' || header[3] != 'I' || - header[4] != 'F' || header[5] != 'F' || header[6] != '4' || header[7] != '0') { - throw new PatchException("Invalid header signature"); - } - - /* Read lengths from header */ - long bzctrllen = offtin(header, 8); - long bzdatalen = offtin(header, 16); - long newsize = offtin(header, 24); - if (bzctrllen < 0 || bzdatalen < 0 || newsize < 0) { - throw new PatchException("Invalid header lengths"); - } - - // Note: bspatch uses long lengths everywhere; - // however new byte[] doesn't support that and we don't expect to - // have 2GB+ file sizes to diff any time soon so let's - // do a first implementation that only supports 2^32 sizes. - - /* Read embedded files using Apache Common Compress' BZIP2 */ - InputStream cpfbz2 = readBzip2Data(patch, 32, bzctrllen); - InputStream dpfbz2 = readBzip2Data(patch, 32 + bzctrllen, bzdatalen); - InputStream epfbz2 = readBzip2Data(patch, 32 + bzctrllen + bzdatalen, -1); - - int oldsize = file1.length; - byte[] old = file1; - - byte[] _new = new byte[(int) newsize]; - - long ctrl[] = new long[3]; - byte buf[] = new byte[8]; - long oldpos = 0; - long newpos = 0; - while (newpos < newsize) { - long lenread; - - /* Read control data */ - for(int i = 0; i <= 2; i++) { - lenread = BZ2_bzRead(cpfbz2, buf, 0, 8); - if (lenread < 8) { - throw new PatchException("Failed to read control data") ; - } - ctrl[i] = offtin(buf, 0); - }; - - /* Sanity-check */ - if (newpos + ctrl[0] > newsize) { - throw new PatchException("Sanity check failed") ; - } - - /* Read diff string */ - lenread = BZ2_bzRead(dpfbz2, _new, newpos, ctrl[0]); - if (lenread < ctrl[0]) { - throw new PatchException("Failed to read diff data") ; - } - - /* Add old data to diff string */ - for (int i = 0; i < ctrl[0]; i++) { - if (oldpos + i >= 0 && oldpos + i < oldsize) { - _new[(int) (newpos + i)] += old[(int) (oldpos + i)]; - } - } - - /* Adjust pointers */ - newpos += ctrl[0]; - oldpos += ctrl[0]; - - /* Sanity-check */ - if (newpos + ctrl[1] > newsize) { - throw new PatchException("Sanity check failed") ; - } - - /* Read extra string */ - lenread = BZ2_bzRead(epfbz2, _new, newpos, ctrl[1]); - if (lenread < ctrl[1]) { - throw new PatchException("Failed to read extra data") ; - } - - /* Adjust pointers */ - newpos += ctrl[1]; - oldpos += ctrl[2]; - } - - /* Clean up the bzip2 reads */ - cpfbz2.close(); - dpfbz2.close(); - epfbz2.close(); - - /* Write the new file */ - // nop - - return _new; - } - - private long offtin(byte[] header, int offset) { - long y = 0; - - offset += 7; - y = header[offset] & 0x7F; - boolean sign = (header[offset] & 0x80) != 0; - for (int i = 6; i >= 0; i--) { - y = y * 256 + toUnsigned(header[--offset]); - } - - if (sign) { - y = -y; - } - - return y; - } - - /** - * Decode a BZIP2 data block starting at the given offset. - * - * @param data The binary data of the file. - * @param offset The index where the file begins - * @param length The length to read. Use -1 to mean "up to the end". - * @return A new decoded byte array. - * @throws IOException when the BZIP2 decompression fails. - */ - private InputStream readBzip2Data(byte[] data, long offset, long length) throws IOException { - if (length == -1) { - length = data.length - offset; - } - ByteArrayInputStream is = new ByteArrayInputStream(data, (int) offset, (int) length); - BZip2CompressorInputStream bis = new BZip2CompressorInputStream(is); - return bis; - } - - /** - * Reads the {@code length} next bytes from the bzip2 input stream. - * - * @param bzip2is The input stream to read from. - * @param dest The destination buffer to fill. - * @param length The length to read in bytes. - * @return The number of bytes read. - * @throws IOException If there's not enough data to read. - */ - private long BZ2_bzRead(InputStream bzip2is, byte[] dest, long offset, long length) - throws IOException { - for (long i = 0; i < length; ) { - int len = bzip2is.read(dest, (int) (offset + i), (int) (length - i)); - if (len == -1) { - throw new IOException("Bzip2 EOF"); - } - i += len; - } - return length; - } - - - @SuppressWarnings("serial") - static class PatchException extends Exception { - public PatchException() { - super("Corrupt patch"); - } - public PatchException(String msg) { - super("Corrupt patch: " + msg); - } - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/CommandLineParserTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/CommandLineParserTest.java deleted file mode 100644 index 7d8a01f..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/CommandLineParserTest.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - -import com.android.utils.ILogger; -import com.android.utils.StdLogger; - -import java.util.Arrays; -import java.util.List; - -import junit.framework.TestCase; - - -public class CommandLineParserTest extends TestCase { - - private StdLogger mLog; - - /** - * A mock version of the {@link CommandLineParser} class that does not - * exits and captures its stdout/stderr output. - */ - public static class MockCommandLineProcessor extends CommandLineParser { - private boolean mExitCalled; - private boolean mHelpCalled; - private String mStdOut = ""; - private String mStdErr = ""; - - public MockCommandLineProcessor(ILogger logger) { - super(logger, - new String[][] { - { "verb1", "action1", "Some action" }, - { "verb1", "action2", "Another action" }, - { "verb2", NO_VERB_OBJECT, "Action with string array" }, - }); - define(Mode.STRING, false /*mandatory*/, - "verb1", "action1", "1", "first", "non-mandatory flag", null); - define(Mode.STRING, true /*mandatory*/, - "verb1", "action1", "2", "second", "mandatory flag", null); - - define(Mode.STRING, true /*mandatory*/, - "verb2", NO_VERB_OBJECT, "1", "first", "1st mandatory flag", null); - define(Mode.STRING_ARRAY, true /*mandatory*/, - "verb2", NO_VERB_OBJECT, "2", "second", "2nd mandatory flag", null); - define(Mode.STRING, true /*mandatory*/, - "verb2", NO_VERB_OBJECT, "3", "third", "3rd mandatory flag", null); - } - - @Override - public void printHelpAndExitForAction(String verb, String directObject, - String errorFormat, Object... args) { - mHelpCalled = true; - super.printHelpAndExitForAction(verb, directObject, errorFormat, args); - } - - @Override - protected void exit() { - mExitCalled = true; - } - - @Override - protected void stdout(String format, Object... args) { - String s = String.format(format, args); - mStdOut += s + "\n"; - // don't call super to avoid printing stuff - } - - @Override - protected void stderr(String format, Object... args) { - String s = String.format(format, args); - mStdErr += s + "\n"; - // don't call super to avoid printing stuff - } - - public boolean wasHelpCalled() { - return mHelpCalled; - } - - public boolean wasExitCalled() { - return mExitCalled; - } - - public String getStdOut() { - return mStdOut; - } - - public String getStdErr() { - return mStdErr; - } - } - - @Override - protected void setUp() throws Exception { - mLog = new StdLogger(StdLogger.Level.VERBOSE); - super.setUp(); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testPrintHelpAndExit() { - MockCommandLineProcessor c = new MockCommandLineProcessor(mLog); - assertFalse(c.wasExitCalled()); - assertFalse(c.wasHelpCalled()); - assertTrue(c.getStdOut().equals("")); - assertTrue(c.getStdErr().equals("")); - c.printHelpAndExit(null); - assertTrue(c.getStdOut().indexOf("-v") != -1); - assertTrue(c.getStdOut().indexOf("--verbose") != -1); - assertTrue(c.getStdErr().equals("")); - assertTrue(c.wasExitCalled()); - - c = new MockCommandLineProcessor(mLog); - assertFalse(c.wasExitCalled()); - assertTrue(c.getStdOut().equals("")); - assertTrue(c.getStdErr().indexOf("Missing parameter") == -1); - - c.printHelpAndExit("Missing %s", "parameter"); - assertTrue(c.wasExitCalled()); - assertFalse(c.getStdOut().equals("")); - assertTrue(c.getStdErr().indexOf("Missing parameter") != -1); - } - - public void testVerbose() { - MockCommandLineProcessor c = new MockCommandLineProcessor(mLog); - - assertFalse(c.isVerbose()); - c.parseArgs(new String[] { "-v" }); - assertTrue(c.isVerbose()); - assertTrue(c.wasExitCalled()); - assertTrue(c.wasHelpCalled()); - assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1); - - c = new MockCommandLineProcessor(mLog); - c.parseArgs(new String[] { "--verbose" }); - assertTrue(c.isVerbose()); - assertTrue(c.wasExitCalled()); - assertTrue(c.wasHelpCalled()); - assertTrue(c.getStdErr().indexOf("Missing verb name.") != -1); - } - - public void testHelp() { - MockCommandLineProcessor c = new MockCommandLineProcessor(mLog); - - c.parseArgs(new String[] { "-h" }); - assertTrue(c.wasExitCalled()); - assertTrue(c.wasHelpCalled()); - assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1); - - c = new MockCommandLineProcessor(mLog); - c.parseArgs(new String[] { "--help" }); - assertTrue(c.wasExitCalled()); - assertTrue(c.wasHelpCalled()); - assertTrue(c.getStdErr().indexOf("Missing verb name.") == -1); - } - - public void testMandatory() { - MockCommandLineProcessor c = new MockCommandLineProcessor(mLog); - - c.parseArgs(new String[] { "verb1", "action1", "-1", "value1", "-2", "value2" }); - assertFalse(c.wasExitCalled()); - assertFalse(c.wasHelpCalled()); - assertEquals("", c.getStdErr()); - assertEquals("value1", c.getValue("verb1", "action1", "first")); - assertEquals("value2", c.getValue("verb1", "action1", "second")); - - c = new MockCommandLineProcessor(mLog); - c.parseArgs(new String[] { "verb1", "action1", "-2", "value2" }); - assertFalse(c.wasExitCalled()); - assertFalse(c.wasHelpCalled()); - assertEquals("", c.getStdErr()); - assertEquals(null, c.getValue("verb1", "action1", "first")); - assertEquals("value2", c.getValue("verb1", "action1", "second")); - - c = new MockCommandLineProcessor(mLog); - c.parseArgs(new String[] { "verb1", "action1" }); - assertTrue(c.wasExitCalled()); - assertTrue(c.wasHelpCalled()); - assertTrue(c.getStdErr().indexOf("must be defined") != -1); - assertEquals(null, c.getValue("verb1", "action1", "first")); - assertEquals(null, c.getValue("verb1", "action1", "second")); - } - - public void testStringArray() { - MockCommandLineProcessor c = new MockCommandLineProcessor(mLog); - - c.parseArgs(new String[] { "verb2", - "-1", "value1", - "-2", "value2_a", "value2_b", "value2_c", "value2_d", - "-3", "value3" }); - assertFalse(c.wasExitCalled()); - assertFalse(c.wasHelpCalled()); - assertEquals("", c.getStdErr()); - assertEquals("value1", c.getValue("verb2", null, "first")); - assertTrue(c.getValue("verb2", null, "second") instanceof List<?>); - assertEquals("[value2_a, value2_b, value2_c, value2_d]", - Arrays.toString(((List<?>) c.getValue("verb2", null, "second")).toArray())); - assertEquals("value3", c.getValue("verb2", null, "third")); - } - - public void testStringArray_DashDash() { - MockCommandLineProcessor c = new MockCommandLineProcessor(mLog); - - // Use -- to tell argument -2 it can absorb any argument, including dashed ones. - // Logically -2 must be the last argument and -1/-3 must be placed before it. - c.parseArgs(new String[] { "verb2", - "-1", "value1", - "-3", "value3", - "-2", "value2_a", "--", "-value2_b", "--value2_c", "value2_d" }); - assertFalse(c.wasExitCalled()); - assertFalse(c.wasHelpCalled()); - assertEquals("", c.getStdErr()); - assertEquals("value1", c.getValue("verb2", null, "first")); - assertTrue(c.getValue("verb2", null, "second") instanceof List<?>); - assertEquals("[value2_a, --, -value2_b, --value2_c, value2_d]", - Arrays.toString(((List<?>) c.getValue("verb2", null, "second")).toArray())); - assertEquals("value3", c.getValue("verb2", null, "third")); - } - - public void testStringArray_EmptyStringArray() { - MockCommandLineProcessor c = new MockCommandLineProcessor(mLog); - - c.parseArgs(new String[] { "verb2", - "-1", "value1", - "-2", - "-3", "value3" }); - assertTrue(c.wasExitCalled()); - assertTrue(c.wasHelpCalled()); - assertEquals("Invalid usage for flag -2: No values provided.", c.getStdErr().trim()); - } -} diff --git a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/LineUtilTest.java b/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/LineUtilTest.java deleted file mode 100755 index 213efc2..0000000 --- a/sdkmanager/libs/sdklib/tests/src/com/android/sdklib/util/LineUtilTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdklib.util; - -import com.android.sdklib.util.LineUtil; - -import junit.framework.TestCase; - - -public class LineUtilTest extends TestCase { - - public void testReflowLine() { - boolean gotNpe = false; - try { - LineUtil.reflowLine(null); - } catch(NullPointerException e) { - gotNpe = true; - } finally { - assertTrue(gotNpe); - } - - assertEquals("", LineUtil.reflowLine("")); - - assertEquals("1234567", LineUtil.reflowLine("1234567")); - - assertEquals( - "-- verbose, -v: This description for this flag fits in exactly 78 characters.", - LineUtil.reflowLine("-- verbose, -v: This description for this flag fits in exactly 78 characters.")); - - assertEquals( - "--verbose, -v : This description for this flag fits in more than 78\n" + - " characters and needs to wrap up at the colon.", - LineUtil.reflowLine("--verbose, -v : This description for this flag fits in more than 78 characters and needs to wrap up at the colon.")); - - assertEquals( - "If the line needs to wrap but there's no colon marker, the line will just wrap\n" + - " with 4 spaces.", - LineUtil.reflowLine("If the line needs to wrap but there's no colon marker, the line will just wrap with 4 spaces.")); - - assertEquals( - "--blah: More than 78 characters and lots of\n" + - " spaces. ", - LineUtil.reflowLine("--blah: More than 78 characters and lots of spaces. ")); - - assertEquals( - "In this case the colon is at the very end of the string and it's not going to\n" + - " wrap as expected:", - LineUtil.reflowLine("In this case the colon is at the very end of the string and it's not going to wrap as expected:")); - - assertEquals( - "--flag:In-this-case-there-is-no-whitespace-and-wrapping-will-cut-just-at-the-7\n" + - " 8-mark.", - LineUtil.reflowLine("--flag:In-this-case-there-is-no-whitespace-and-wrapping-will-cut-just-at-the-78-mark.")); - - assertEquals( - "Desc: This line is split in 2.\n" + - " The second line must align at the colon and yet still wrap as expected\n" + - " if it doesn't fit properly.\n" + - " The end.", - LineUtil.reflowLine("Desc: This line is split in 2.\nThe second line must align at the colon and yet still wrap as expected if it doesn't fit properly.\nThe end.")); - - assertEquals( - "Desc: This line is split in 2\n" + - " even though it doesn't need to wrap.", - LineUtil.reflowLine("Desc: This line is split in 2\n\n\n\n\n\neven though it doesn't need to wrap.")); - - } -} diff --git a/sdkmanager/libs/sdkuilib/.classpath b/sdkmanager/libs/sdkuilib/.classpath deleted file mode 100644 index 90f452f..0000000 --- a/sdkmanager/libs/sdkuilib/.classpath +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<classpath> - <classpathentry excluding="**/Android.mk" kind="src" path="src"/> - <classpathentry excluding="**/Android.mk" kind="src" path="tests"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> - <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/> - <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> - <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/swtmenubar.jar" sourcepath="/ANDROID_SRC/sdk/swtmenubar/src"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.core.commands_3.6.0.I20100512-1500.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.equinox.common_3.6.0.v20100503.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/eclipse/org.eclipse.jface_3.6.2.M20110210-1200.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/commons-codec-1.4.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/commons-logging-1.1.1.jar"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/httpclient-4.1.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/http-client/src/httpcomponents-client-4.1.1-src.zip"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/httpcore-4.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/http-client/src/httpcomponents-core-4.1-src.zip"/> - <classpathentry kind="var" path="ANDROID_SRC/prebuilts/tools/common/http-client/httpmime-4.1.1.jar" sourcepath="/ANDROID_SRC/prebuilts/tools/common/http-client/src/httpcomponents-client-4.1.1-src.zip"/> - <classpathentry kind="var" path="ANDROID_OUT_FRAMEWORK/swt.jar"/> - <classpathentry combineaccessrules="false" kind="src" path="/layoutlib_api"/> - <classpathentry combineaccessrules="false" kind="src" path="/common"/> - <classpathentry kind="output" path="bin"/> -</classpath> diff --git a/sdkmanager/libs/sdkuilib/.project b/sdkmanager/libs/sdkuilib/.project deleted file mode 100644 index 0fc6a73..0000000 --- a/sdkmanager/libs/sdkuilib/.project +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>SdkUiLib</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
diff --git a/sdkmanager/libs/sdkuilib/.settings/org.eclipse.jdt.core.prefs b/sdkmanager/libs/sdkuilib/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index d11c211..0000000 --- a/sdkmanager/libs/sdkuilib/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,98 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore -org.eclipse.jdt.core.compiler.annotation.nonnull=com.android.annotations.NonNull -org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=com.android.annotations.NonNullByDefault -org.eclipse.jdt.core.compiler.annotation.nonnullisdefault=disabled -org.eclipse.jdt.core.compiler.annotation.nullable=com.android.annotations.Nullable -org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled -org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.debug.lineNumber=generate -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning -org.eclipse.jdt.core.compiler.problem.assertIdentifier=error -org.eclipse.jdt.core.compiler.problem.autoboxing=ignore -org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning -org.eclipse.jdt.core.compiler.problem.deadCode=warning -org.eclipse.jdt.core.compiler.problem.deprecation=warning -org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled -org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled -org.eclipse.jdt.core.compiler.problem.discouragedReference=warning -org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore -org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning -org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled -org.eclipse.jdt.core.compiler.problem.fieldHiding=warning -org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning -org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning -org.eclipse.jdt.core.compiler.problem.forbiddenReference=error -org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning -org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled -org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning -org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore -org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore -org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning -org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning -org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore -org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning -org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled -org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error -org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled -org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning -org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore -org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning -org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning -org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore -org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error -org.eclipse.jdt.core.compiler.problem.nullReference=error -org.eclipse.jdt.core.compiler.problem.nullSpecInsufficientInfo=warning -org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore -org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning -org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore -org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning -org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning -org.eclipse.jdt.core.compiler.problem.potentialNullSpecViolation=error -org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=warning -org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning -org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning -org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore -org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore -org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning -org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore -org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore -org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled -org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning -org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled -org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled -org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning -org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled -org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning -org.eclipse.jdt.core.compiler.problem.unclosedCloseable=error -org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore -org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning -org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore -org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning -org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled -org.eclipse.jdt.core.compiler.problem.unusedImport=warning -org.eclipse.jdt.core.compiler.problem.unusedLabel=warning -org.eclipse.jdt.core.compiler.problem.unusedLocal=warning -org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning -org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore -org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled -org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled -org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning -org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning -org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 diff --git a/sdkmanager/libs/sdkuilib/.settings/org.eclipse.jdt.ui.prefs b/sdkmanager/libs/sdkuilib/.settings/org.eclipse.jdt.ui.prefs deleted file mode 100755 index cc5f0a2..0000000 --- a/sdkmanager/libs/sdkuilib/.settings/org.eclipse.jdt.ui.prefs +++ /dev/null @@ -1,55 +0,0 @@ -#Tue Aug 07 12:32:25 PDT 2012 -eclipse.preferences.version=1 -editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true -sp_cleanup.add_default_serial_version_id=true -sp_cleanup.add_generated_serial_version_id=false -sp_cleanup.add_missing_annotations=false -sp_cleanup.add_missing_deprecated_annotations=true -sp_cleanup.add_missing_methods=false -sp_cleanup.add_missing_nls_tags=false -sp_cleanup.add_missing_override_annotations=true -sp_cleanup.add_missing_override_annotations_interface_methods=false -sp_cleanup.add_serial_version_id=false -sp_cleanup.always_use_blocks=true -sp_cleanup.always_use_parentheses_in_expressions=false -sp_cleanup.always_use_this_for_non_static_field_access=false -sp_cleanup.always_use_this_for_non_static_method_access=false -sp_cleanup.convert_to_enhanced_for_loop=false -sp_cleanup.correct_indentation=false -sp_cleanup.format_source_code=false -sp_cleanup.format_source_code_changes_only=false -sp_cleanup.make_local_variable_final=false -sp_cleanup.make_parameters_final=false -sp_cleanup.make_private_fields_final=true -sp_cleanup.make_type_abstract_if_missing_method=false -sp_cleanup.make_variable_declarations_final=false -sp_cleanup.never_use_blocks=false -sp_cleanup.never_use_parentheses_in_expressions=true -sp_cleanup.on_save_use_additional_actions=true -sp_cleanup.organize_imports=true -sp_cleanup.qualify_static_field_accesses_with_declaring_class=false -sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true -sp_cleanup.qualify_static_member_accesses_with_declaring_class=false -sp_cleanup.qualify_static_method_accesses_with_declaring_class=false -sp_cleanup.remove_private_constructors=true -sp_cleanup.remove_trailing_whitespaces=true -sp_cleanup.remove_trailing_whitespaces_all=true -sp_cleanup.remove_trailing_whitespaces_ignore_empty=false -sp_cleanup.remove_unnecessary_casts=false -sp_cleanup.remove_unnecessary_nls_tags=false -sp_cleanup.remove_unused_imports=false -sp_cleanup.remove_unused_local_variables=false -sp_cleanup.remove_unused_private_fields=true -sp_cleanup.remove_unused_private_members=false -sp_cleanup.remove_unused_private_methods=true -sp_cleanup.remove_unused_private_types=true -sp_cleanup.sort_members=false -sp_cleanup.sort_members_all=false -sp_cleanup.use_blocks=false -sp_cleanup.use_blocks_only_for_return_and_throw=false -sp_cleanup.use_parentheses_in_expressions=false -sp_cleanup.use_this_for_non_static_field_access=false -sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true -sp_cleanup.use_this_for_non_static_method_access=false -sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true diff --git a/sdkmanager/libs/sdkuilib/Android.mk b/sdkmanager/libs/sdkuilib/Android.mk deleted file mode 100644 index 9406fdf..0000000 --- a/sdkmanager/libs/sdkuilib/Android.mk +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_JAVA_RESOURCE_DIRS := src - -# IMPORTANT: if you add a new dependency here, please make sure -# to also check the following file: -# sdkmanager/app/etc/android.bat -# (Note: there is no manifest.txt for sdkuilib.) -LOCAL_JAVA_LIBRARIES := \ - common \ - commons-codec-1.4 \ - commons-compress-1.0 \ - commons-logging-1.1.1 \ - httpclient-4.1.1 \ - httpcore-4.1 \ - httpmime-4.1.1 \ - org.eclipse.jface_3.6.2.M20110210-1200 \ - org.eclipse.equinox.common_3.6.0.v20100503 \ - org.eclipse.core.commands_3.6.0.I20100512-1500 \ - sdklib \ - layoutlib_api \ - swt \ - swtmenubar - -LOCAL_MODULE := sdkuilib - -LOCAL_JAR_MANIFEST := etc/manifest.txt - -include $(BUILD_HOST_JAVA_LIBRARY) - - - -# Build all sub-directories -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/sdkmanager/libs/sdkuilib/NOTICE b/sdkmanager/libs/sdkuilib/NOTICE deleted file mode 100644 index c5b1efa..0000000 --- a/sdkmanager/libs/sdkuilib/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/sdkmanager/libs/sdkuilib/README b/sdkmanager/libs/sdkuilib/README deleted file mode 100644 index dee4a24..0000000 --- a/sdkmanager/libs/sdkuilib/README +++ /dev/null @@ -1,45 +0,0 @@ -Using the Eclipse project SdkUiLib ----------------------------------- - -1- sdkuilib requires SWT to compile. - -SWT is available in the tree under prebuild/<platform>/swt - -Because the build path cannot contain relative path that are not inside the project directory, -the .classpath file references a user library called ANDROID_SWT. - -In order to compile the project: -- Open Preferences > Java > Build Path > User Libraries -- Create a new user library named ANDROID_SWT -- Add the following 4 JAR files: - - - prebuilt/<platform>/swt/swt.jar - - prebuilt/common/eclipse/org.eclipse.core.commands_3.*.jar - - prebuilt/common/eclipse/org.eclipse.equinox.common_3.*.jar - - prebuilt/common/eclipse/org.eclipse.jface_3.*.jar - - -2- sdkuilib also requires the compiled swtmenubar library. - -Build the swtmenubar library: -$ cd $TOP (top of Android tree) -$ . build/envsetup.sh && lunch sdk-eng -$ sdk/eclipse/scripts/create_sdkman_symlinks.sh - -Define a classpath variable in Eclipse: -- Open Preferences > Java > Build Path > Classpath Variables -- Create a new classpath variable named ANDROID_OUT_FRAMEWORK -- Set its folder value to <Android tree>/out/host/<platform>/framework -- Create a new classpath variable named ANDROID_SRC -- Set its folder value to <Android tree> - -You might need to clean the SdkUiLib project (Project > Clean...) after -you add the new classpath variable, otherwise previous errors might not -go away automatically. - -The ANDROID_SRC part should be optional. It allows you to have access to -the SwtMenuBar generic parts from the Java editor. - - --- -EOF diff --git a/sdkmanager/libs/sdkuilib/etc/manifest.txt b/sdkmanager/libs/sdkuilib/etc/manifest.txt deleted file mode 100644 index 37def3a..0000000 --- a/sdkmanager/libs/sdkuilib/etc/manifest.txt +++ /dev/null @@ -1 +0,0 @@ -Class-Path: sdklib.jar layoutlib_api.jar common.jar commons-compress-1.0.jar httpclient-4.1.1.jar httpcore-4.1.jar httpmime-4.1.1.jar commons-logging-1.1.1.jar commons-codec-1.4.jar swtmenubar.jar swt.jar org.eclipse.jface_3.6.2.M20110210-1200.jar org.eclipse.equinox.common_3.6.0.v20100503.jar org.eclipse.core.commands_3.6.0.I20100512-1500.jar diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AboutDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AboutDialog.java deleted file mode 100755 index 717890b..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/AboutDialog.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - - -import com.android.SdkConstants; -import com.android.sdklib.io.FileOp; -import com.android.sdklib.repository.PkgProps; -import com.android.sdklib.repository.SdkAddonConstants; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Properties; - -public class AboutDialog extends UpdaterBaseDialog { - - public AboutDialog(Shell parentShell, UpdaterData updaterData) { - super(parentShell, updaterData, "About" /*title*/); - assert updaterData != null; - } - - @Override - protected void createContents() { - super.createContents(); - Shell shell = getShell(); - shell.setMinimumSize(new Point(450, 150)); - shell.setSize(450, 150); - - GridLayoutBuilder.create(shell).columns(3); - - Label logo = new Label(shell, SWT.NONE); - ImageFactory imgf = getUpdaterData() == null ? null : getUpdaterData().getImageFactory(); - Image image = imgf == null ? null : imgf.getImageByName("sdkman_logo_128.png"); - if (image != null) logo.setImage(image); - - Label label = new Label(shell, SWT.NONE); - GridDataBuilder.create(label).hFill().hGrab().hSpan(2);; - label.setText(String.format( - "Android SDK Manager.\n" + - "Revision %1$s\n" + - "Add-on XML Schema #%2$d\n" + - "Repository XML Schema #%3$d\n" + - // TODO: update with new year date (search this to find other occurrences to update) - "Copyright (C) 2009-2012 The Android Open Source Project.", - getRevision(), - SdkAddonConstants.NS_LATEST_VERSION, - SdkRepoConstants.NS_LATEST_VERSION)); - - Label filler = new Label(shell, SWT.NONE); - GridDataBuilder.create(filler).fill().grab().hSpan(2); - - createCloseButton(); - } - - @Override - protected void checkSubclass() { - // Disable the check that prevents subclassing of SWT components - } - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - // End of hiding from SWT Designer - //$hide<<$ - - private String getRevision() { - Properties p = new Properties(); - try{ - File sourceProp = FileOp.append(getUpdaterData().getOsSdkRoot(), - SdkConstants.FD_TOOLS, - SdkConstants.FN_SOURCE_PROP); - FileInputStream fis = null; - try { - fis = new FileInputStream(sourceProp); - p.load(fis); - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException ignore) { - } - } - } - - String revision = p.getProperty(PkgProps.PKG_REVISION); - if (revision != null) { - return revision; - } - } catch (IOException e) { - } - - return "?"; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ArchiveInfo.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ArchiveInfo.java deleted file mode 100755 index 2c509ca..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ArchiveInfo.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.ArchiveReplacement; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * Represents an archive that we want to install. - * Note that the installer deals with archives whereas the user mostly sees packages - * but as far as we are concerned for installation there's a 1-to-1 mapping. - * <p/> - * A new archive is always a remote archive that needs to be downloaded and then - * installed. It can replace an existing local one. It can also depends on another - * (new or local) archive, which means the dependent archive needs to be successfully - * installed first. Finally this archive can also be a dependency for another one. - * <p/> - * The accepted and rejected flags are used by {@link SdkUpdaterChooserDialog} to follow - * user choices. The installer should never install something that is not accepted. - * <p/> - * <em>Note</em>: There is currently no logic to support more than one level of - * dependency, either here or in the {@link SdkUpdaterChooserDialog}, since we currently - * have no need for it. - * - * @see ArchiveInfo#ArchiveInfo(Archive, Archive, ArchiveInfo[]) - */ -class ArchiveInfo extends ArchiveReplacement implements Comparable<ArchiveInfo> { - - private final ArchiveInfo[] mDependsOn; - private final ArrayList<ArchiveInfo> mDependencyFor = new ArrayList<ArchiveInfo>(); - private boolean mAccepted; - private boolean mRejected; - - /** - * Creates a new replacement where the {@code newArchive} will replace the - * currently installed {@code replaced} archive. - * When {@code newArchive} is not intended to replace anything (e.g. because - * the user is installing a new package not present on her system yet), then - * {@code replace} shall be null. - * - * @param newArchive A "new archive" to be installed. This is always an archive - * that comes from a remote site. This <em>may</em> be null. - * @param replaced An optional local archive that the new one will replace. - * Can be null if this archive does not replace anything. - * @param dependsOn An optional new or local dependency, that is an archive that - * <em>this</em> archive depends upon. In other words, we can only install - * this archive if the dependency has been successfully installed. It also - * means we need to install the dependency first. Can be null or empty. - * However it cannot contain nulls. - */ - public ArchiveInfo(Archive newArchive, Archive replaced, ArchiveInfo[] dependsOn) { - super(newArchive, replaced); - mDependsOn = dependsOn; - } - - /** - * Returns an optional new or local dependency, that is an archive that <em>this</em> - * archive depends upon. In other words, we can only install this archive if the - * dependency has been successfully installed. It also means we need to install the - * dependency first. - * <p/> - * This array can be null or empty. It can't contain nulls though. - */ - public ArchiveInfo[] getDependsOn() { - return mDependsOn; - } - - /** - * Returns true if this new archive is a dependency for <em>another</em> one that we - * want to install. - */ - public boolean isDependencyFor() { - return mDependencyFor.size() > 0; - } - - /** - * Adds an {@link ArchiveInfo} for which <em>this</em> package is a dependency. - * This means the package added here depends on this package. - */ - public ArchiveInfo addDependencyFor(ArchiveInfo dependencyFor) { - if (!mDependencyFor.contains(dependencyFor)) { - mDependencyFor.add(dependencyFor); - } - - return this; - } - - /** - * Returns the list of {@link ArchiveInfo} for which <em>this</em> package is a dependency. - * This means the packages listed here depend on this package. - * <p/> - * Implementation detail: this is the internal mutable list. Callers should not modify it. - * This list can be empty but is never null. - */ - public Collection<ArchiveInfo> getDependenciesFor() { - return mDependencyFor; - } - - /** - * Sets whether this archive was accepted (either manually by the user or - * automatically if it doesn't have a license) for installation. - */ - public void setAccepted(boolean accepted) { - mAccepted = accepted; - } - - /** - * Returns whether this archive was accepted (either manually by the user or - * automatically if it doesn't have a license) for installation. - */ - public boolean isAccepted() { - return mAccepted; - } - - /** - * Sets whether this archive was rejected manually by the user. - * An archive can neither accepted nor rejected. - */ - public void setRejected(boolean rejected) { - mRejected = rejected; - } - - /** - * Returns whether this archive was rejected manually by the user. - * An archive can neither accepted nor rejected. - */ - public boolean isRejected() { - return mRejected; - } - - /** - * ArchiveInfos are compared using ther "new archive" ordering. - * - * @see Archive#compareTo(Archive) - */ - @Override - public int compareTo(ArchiveInfo rhs) { - if (getNewArchive() != null && rhs != null) { - return getNewArchive().compareTo(rhs.getNewArchive()); - } - return 0; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISdkUpdaterWindow.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISdkUpdaterWindow.java deleted file mode 100755 index e5f2521..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISdkUpdaterWindow.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdkuilib.repository.ISdkChangeListener; - -/** - * Interface for the actual implementation of the Update Window. - */ -public interface ISdkUpdaterWindow { - - /** - * Adds a new listener to be notified when a change is made to the content of the SDK. - */ - public abstract void addListener(ISdkChangeListener listener); - - /** - * Removes a new listener to be notified anymore when a change is made to the content of - * the SDK. - */ - public abstract void removeListener(ISdkChangeListener listener); - - /** - * Opens the window. - */ - public abstract void open(); - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISettingsPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISettingsPage.java deleted file mode 100755 index 333644f..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ISettingsPage.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.internal.repository.DownloadCache; - -import java.net.URL; -import java.util.Properties; - -/** - * Interface that a settings page must implement. - */ -public interface ISettingsPage { - - /** - * Java system setting picked up by {@link URL} for http proxy port. - * Type: String. - */ - public static final String KEY_HTTP_PROXY_PORT = "http.proxyPort"; //$NON-NLS-1$ - - /** - * Java system setting picked up by {@link URL} for http proxy host. - * Type: String. - */ - public static final String KEY_HTTP_PROXY_HOST = "http.proxyHost"; //$NON-NLS-1$ - - /** - * Setting to force using http:// instead of https:// connections. - * Type: Boolean. - * Default: False. - */ - public static final String KEY_FORCE_HTTP = "sdkman.force.http"; //$NON-NLS-1$ - - /** - * Setting to display only packages that are new or updates. - * Type: Boolean. - * Default: True. - */ - public static final String KEY_SHOW_UPDATE_ONLY = "sdkman.show.update.only"; //$NON-NLS-1$ - - /** - * Setting to ask for permission before restarting ADB. - * Type: Boolean. - * Default: False. - */ - public static final String KEY_ASK_ADB_RESTART = "sdkman.ask.adb.restart"; //$NON-NLS-1$ - - /** - * Setting to use the {@link DownloadCache}, for small manifest XML files. - * Type: Boolean. - * Default: True. - */ - public static final String KEY_USE_DOWNLOAD_CACHE = "sdkman.use.dl.cache"; //$NON-NLS-1$ - - /** - * Setting to enabling previews in the package list - * Type: Boolean. - * Default: False. - */ - public static final String KEY_ENABLE_PREVIEWS = "sdkman.enable.previews"; //$NON-NLS-1$ - - /** - * Setting to set the density of the monitor. - * Type: Integer. - * Default: -1 - */ - public static final String KEY_MONITOR_DENSITY = "sdkman.monitor.density"; //$NON-NLS-1$ - - /** Loads settings from the given {@link Properties} container and update the page UI. */ - public abstract void loadSettings(Properties inSettings); - - /** Called by the application to retrieve settings from the UI and store them in - * the given {@link Properties} container. */ - public abstract void retrieveSettings(Properties outSettings); - - /** - * Called by the application to give a callback that the page should invoke when - * settings have changed. - */ - public abstract void setOnSettingsChanged(SettingsChangedCallback settingsChangedCallback); - - /** - * Callback used to notify the application that settings have changed and need to be - * applied. - */ - public interface SettingsChangedCallback { - /** - * Invoked by the settings page when settings have changed and need to be - * applied. The application will call {@link ISettingsPage#retrieveSettings(Properties)} - * and apply the new settings. - */ - public abstract void onSettingsChanged(ISettingsPage page); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/IUpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/IUpdaterData.java deleted file mode 100755 index acc3990..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/IUpdaterData.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.utils.ILogger; - -import org.eclipse.swt.widgets.Shell; - - -/** - * Interface used to retrieve some parameters from an {@link UpdaterData} instance. - * Useful mostly for unit tests purposes. - */ -interface IUpdaterData { - - public abstract ITaskFactory getTaskFactory(); - - public abstract ILogger getSdkLog(); - - public abstract DownloadCache getDownloadCache(); - - public abstract ImageFactory getImageFactory(); - - public abstract SdkManager getSdkManager(); - - public abstract AvdManager getAvdManager(); - - public abstract SettingsController getSettingsController(); - - public abstract Shell getWindowShell(); - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/MenuBarWrapper.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/MenuBarWrapper.java deleted file mode 100755 index 8d3eabd..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/MenuBarWrapper.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - - -import com.android.menubar.IMenuBarCallback; -import com.android.menubar.MenuBarEnhancer; -import com.android.sdkuilib.internal.repository.ui.SdkUpdaterWindowImpl2; - -import org.eclipse.swt.widgets.Menu; - -/** - * A simple wrapper/delegate around the {@link MenuBarEnhancer}. - * - * The {@link MenuBarEnhancer} and {@link IMenuBarCallback} classes are only - * available when the SwtMenuBar library is available too. This wrapper helps - * {@link SdkUpdaterWindowImpl2} make the call conditional, otherwise the updater - * window class would fail to load when the SwtMenuBar library isn't found. - */ -public abstract class MenuBarWrapper { - - public MenuBarWrapper(String appName, Menu menu) { - MenuBarEnhancer.setupMenu(appName, menu, new IMenuBarCallback() { - @Override - public void onPreferencesMenuSelected() { - MenuBarWrapper.this.onPreferencesMenuSelected(); - } - - @Override - public void onAboutMenuSelected() { - MenuBarWrapper.this.onAboutMenuSelected(); - } - - @Override - public void printError(String format, Object... args) { - MenuBarWrapper.this.printError(format, args); - } - }); - } - - abstract public void onPreferencesMenuSelected(); - - abstract public void onAboutMenuSelected(); - - abstract public void printError(String format, Object... args); -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterChooserDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterChooserDialog.java deleted file mode 100755 index 49bebba..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterChooserDialog.java +++ /dev/null @@ -1,762 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.SdkConstants; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.FullRevision; -import com.android.sdklib.internal.repository.packages.IAndroidVersionProvider; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.ui.GridDialog; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.SashForm; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; - -import java.util.ArrayList; -import java.util.Collection; - - -/** - * Implements an {@link SdkUpdaterChooserDialog}. - */ -final class SdkUpdaterChooserDialog extends GridDialog { - - /** Last dialog size for this session. */ - private static Point sLastSize; - private boolean mLicenseAcceptAll; - private boolean mInternalLicenseRadioUpdate; - - // UI fields - private SashForm mSashForm; - private Composite mPackageRootComposite; - private TableViewer mTableViewPackage; - private Table mTablePackage; - private TableColumn mTableColum; - private StyledText mPackageText; - private Button mLicenseRadioAccept; - private Button mLicenseRadioReject; - private Button mLicenseRadioAcceptAll; - private Group mPackageTextGroup; - private final UpdaterData mUpdaterData; - private Group mTableGroup; - private Label mErrorLabel; - - /** - * List of all archives to be installed with dependency information. - * <p/> - * Note: in a lot of cases, we need to find the archive info for a given archive. This - * is currently done using a simple linear search, which is fine since we only have a very - * limited number of archives to deal with (e.g. < 10 now). We might want to revisit - * this later if it becomes an issue. Right now just do the simple thing. - *<p/> - * Typically we could add a map Archive=>ArchiveInfo later. - */ - private final Collection<ArchiveInfo> mArchives; - - - - /** - * Create the dialog. - * @param parentShell The shell to use, typically updaterData.getWindowShell() - * @param updaterData The updater data - * @param archives The archives to be installed - */ - public SdkUpdaterChooserDialog(Shell parentShell, - UpdaterData updaterData, - Collection<ArchiveInfo> archives) { - super(parentShell, 3, false/*makeColumnsEqual*/); - mUpdaterData = updaterData; - mArchives = archives; - } - - @Override - protected boolean isResizable() { - return true; - } - - /** - * Returns the results, i.e. the list of selected new archives to install. - * This is similar to the {@link ArchiveInfo} list instance given to the constructor - * except only accepted archives are present. - * - * An empty list is returned if cancel was choosen. - */ - public ArrayList<ArchiveInfo> getResult() { - ArrayList<ArchiveInfo> ais = new ArrayList<ArchiveInfo>(); - - if (getReturnCode() == Window.OK) { - for (ArchiveInfo ai : mArchives) { - if (ai.isAccepted()) { - ais.add(ai); - } - } - } - - return ais; - } - - /** - * Create the main content of the dialog. - * See also {@link #createButtonBar(Composite)} below. - */ - @Override - public void createDialogContent(Composite parent) { - // Sash form - mSashForm = new SashForm(parent, SWT.NONE); - mSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1)); - - - // Left part of Sash Form - - mTableGroup = new Group(mSashForm, SWT.NONE); - mTableGroup.setText("Packages"); - mTableGroup.setLayout(new GridLayout(1, false/*makeColumnsEqual*/)); - - mTableViewPackage = new TableViewer(mTableGroup, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE); - mTablePackage = mTableViewPackage.getTable(); - mTablePackage.setHeaderVisible(false); - mTablePackage.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); - - mTablePackage.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onPackageSelected(); //$hide$ - } - @Override - public void widgetDefaultSelected(SelectionEvent e) { - onPackageDoubleClick(); - } - }); - - mTableColum = new TableColumn(mTablePackage, SWT.NONE); - mTableColum.setWidth(100); - mTableColum.setText("Packages"); - - - // Right part of Sash form - mPackageRootComposite = new Composite(mSashForm, SWT.NONE); - mPackageRootComposite.setLayout(new GridLayout(4, false/*makeColumnsEqual*/)); - mPackageRootComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); - - mPackageTextGroup = new Group(mPackageRootComposite, SWT.NONE); - mPackageTextGroup.setText("Package Description && License"); - mPackageTextGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 4, 1)); - mPackageTextGroup.setLayout(new GridLayout(1, false/*makeColumnsEqual*/)); - - mPackageText = new StyledText(mPackageTextGroup, - SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL); - mPackageText.setBackground( - getParentShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); - mPackageText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); - - mLicenseRadioAccept = new Button(mPackageRootComposite, SWT.RADIO); - mLicenseRadioAccept.setText("Accept"); - mLicenseRadioAccept.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onLicenseRadioSelected(); - } - }); - - mLicenseRadioReject = new Button(mPackageRootComposite, SWT.RADIO); - mLicenseRadioReject.setText("Reject"); - mLicenseRadioReject.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onLicenseRadioSelected(); - } - }); - - Label placeholder = new Label(mPackageRootComposite, SWT.NONE); - placeholder.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); - - mLicenseRadioAcceptAll = new Button(mPackageRootComposite, SWT.RADIO); - mLicenseRadioAcceptAll.setText("Accept All"); - mLicenseRadioAcceptAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onLicenseRadioSelected(); - } - }); - - mSashForm.setWeights(new int[] {200, 300}); - } - - /** - * Creates and returns the contents of this dialog's button bar. - * <p/> - * This reimplements most of the code from the base class with a few exceptions: - * <ul> - * <li>Enforces 3 columns. - * <li>Inserts a full-width error label. - * <li>Inserts a help label on the left of the first button. - * <li>Renames the OK button into "Install" - * </ul> - */ - @Override - protected Control createButtonBar(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 0; // this is incremented by createButton - layout.makeColumnsEqualWidth = false; - layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); - layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); - layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); - layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); - composite.setLayout(layout); - GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1); - composite.setLayoutData(data); - composite.setFont(parent.getFont()); - - // Error message area - mErrorLabel = new Label(composite, SWT.NONE); - mErrorLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1)); - - // Label at the left of the install/cancel buttons - Label label = new Label(composite, SWT.NONE); - label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - label.setText("[*] Something depends on this package"); - label.setEnabled(false); - layout.numColumns++; - - // Add the ok/cancel to the button bar. - createButtonsForButtonBar(composite); - - // the ok button should be an "install" button - Button button = getButton(IDialogConstants.OK_ID); - button.setText("Install"); - - return composite; - } - - // -- End of UI, Start of internal logic ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - @Override - public void create() { - super.create(); - - // set window title - getShell().setText("Choose Packages to Install"); - - setWindowImage(); - - // Automatically accept those with an empty license or no license - for (ArchiveInfo ai : mArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - String license = a.getParentPackage().getLicense(); - ai.setAccepted(license == null || license.trim().length() == 0); - } - } - - // Fill the list with the replacement packages - mTableViewPackage.setLabelProvider(new NewArchivesLabelProvider()); - mTableViewPackage.setContentProvider(new NewArchivesContentProvider()); - mTableViewPackage.setInput(mArchives); - - adjustColumnsWidth(); - - // select first item - mTablePackage.select(0); - onPackageSelected(); - } - - /** - * Creates the icon of the window shell. - */ - private void setWindowImage() { - String imageName = "android_icon_16.png"; //$NON-NLS-1$ - if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_DARWIN) { - imageName = "android_icon_128.png"; //$NON-NLS-1$ - } - - if (mUpdaterData != null) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - getShell().setImage(imgFactory.getImageByName(imageName)); - } - } - } - - /** - * Adds a listener to adjust the columns width when the parent is resized. - * <p/> - * If we need something more fancy, we might want to use this: - * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co - */ - private void adjustColumnsWidth() { - // Add a listener to resize the column to the full width of the table - ControlAdapter resizer = new ControlAdapter() { - @Override - public void controlResized(ControlEvent e) { - Rectangle r = mTablePackage.getClientArea(); - mTableColum.setWidth(r.width); - } - }; - mTablePackage.addControlListener(resizer); - resizer.controlResized(null); - } - - /** - * Captures the window size before closing this. - * @see #getInitialSize() - */ - @Override - public boolean close() { - sLastSize = getShell().getSize(); - return super.close(); - } - - /** - * Tries to reuse the last window size during this session. - * <p/> - * Note: the alternative would be to implement {@link #getDialogBoundsSettings()} - * since the default {@link #getDialogBoundsStrategy()} is to persist both location - * and size. - */ - @Override - protected Point getInitialSize() { - if (sLastSize != null) { - return sLastSize; - } else { - // Arbitrary values that look good on my screen and fit on 800x600 - return new Point(740, 370); - } - } - - /** - * Callback invoked when a package item is selected in the list. - */ - private void onPackageSelected() { - ArchiveInfo ai = getSelectedArchive(); - displayInformation(ai); - displayMissingDependency(ai); - updateLicenceRadios(ai); - } - - /** Returns the currently selected {@link ArchiveInfo} or null. */ - private ArchiveInfo getSelectedArchive() { - ISelection sel = mTableViewPackage.getSelection(); - if (sel instanceof IStructuredSelection) { - Object elem = ((IStructuredSelection) sel).getFirstElement(); - if (elem instanceof ArchiveInfo) { - return (ArchiveInfo) elem; - } - } - return null; - } - - /** - * Updates the package description and license text depending on the selected package. - * <p/> - * Note that right now there is no logic to support more than one level of dependencies - * (e.g. A <- B <- C and A is disabled so C should be disabled; currently C's state depends - * solely on B's state). We currently don't need this. It would be straightforward to add - * if we had a need for it, though. This would require changes to {@link ArchiveInfo} and - * {@link SdkUpdaterLogic}. - */ - private void displayInformation(ArchiveInfo ai) { - if (ai == null) { - mPackageText.setText("Please select a package."); - return; - } - - Archive aNew = ai.getNewArchive(); - if (aNew == null) { - // Only missing archives have a null archive, so we shouldn't be here. - return; - } - - Package pNew = aNew.getParentPackage(); - - mPackageText.setText(""); //$NON-NLS-1$ - - addSectionTitle("Package Description\n"); - addText(pNew.getLongDescription(), "\n\n"); //$NON-NLS-1$ - - Archive aOld = ai.getReplaced(); - if (aOld != null) { - Package pOld = aOld.getParentPackage(); - - FullRevision rOld = pOld.getRevision(); - FullRevision rNew = pNew.getRevision(); - - boolean showRev = true; - - if (pNew instanceof IAndroidVersionProvider && - pOld instanceof IAndroidVersionProvider) { - AndroidVersion vOld = ((IAndroidVersionProvider) pOld).getAndroidVersion(); - AndroidVersion vNew = ((IAndroidVersionProvider) pNew).getAndroidVersion(); - - if (!vOld.equals(vNew)) { - // Versions are different, so indicate more than just the revision. - addText(String.format("This update will replace API %1$s revision %2$s with API %3$s revision %4$s.\n\n", - vOld.getApiString(), rOld.toShortString(), - vNew.getApiString(), rNew.toShortString())); - showRev = false; - } - } - - if (showRev) { - addText(String.format("This update will replace revision %1$s with revision %2$s.\n\n", - rOld.toShortString(), - rNew.toShortString())); - } - } - - ArchiveInfo[] aDeps = ai.getDependsOn(); - if ((aDeps != null && aDeps.length > 0) || ai.isDependencyFor()) { - addSectionTitle("Dependencies\n"); - - if (aDeps != null && aDeps.length > 0) { - addText("Installing this package also requires installing:"); - for (ArchiveInfo aDep : aDeps) { - addText(String.format("\n- %1$s", - aDep.getShortDescription())); - } - addText("\n\n"); - } - - if (ai.isDependencyFor()) { - addText("This package is a dependency for:"); - for (ArchiveInfo ai2 : ai.getDependenciesFor()) { - addText(String.format("\n- %1$s", - ai2.getShortDescription())); - } - addText("\n\n"); - } - } - - addSectionTitle("Archive Description\n"); - addText(aNew.getLongDescription(), "\n\n"); //$NON-NLS-1$ - - String license = pNew.getLicense(); - if (license != null) { - addSectionTitle("License\n"); - addText(license.trim(), "\n\n"); //$NON-NLS-1$ - } - - addSectionTitle("Site\n"); - SdkSource source = pNew.getParentSource(); - if (source != null) { - addText(source.getShortDescription()); - } - } - - /** - * Computes and displays missing dependencies. - * - * If there's a selected package, check the dependency for that one. - * Otherwise display the first missing dependency of any other package. - */ - private void displayMissingDependency(ArchiveInfo ai) { - String error = null; - - try { - if (ai != null) { - if (ai.isAccepted()) { - // Case where this package is accepted but blocked by another non-accepted one - ArchiveInfo[] adeps = ai.getDependsOn(); - if (adeps != null) { - for (ArchiveInfo adep : adeps) { - if (!adep.isAccepted()) { - error = String.format("This package depends on '%1$s'.", - adep.getShortDescription()); - return; - } - } - } - } else { - // Case where this package blocks another one when not accepted - for (ArchiveInfo adep : ai.getDependenciesFor()) { - // It only matters if the blocked one is accepted - if (adep.isAccepted()) { - error = String.format("Package '%1$s' depends on this one.", - adep.getShortDescription()); - return; - } - } - } - } - - // If there is no missing dependency on the current selection, - // just find the first missing dependency of any other package. - for (ArchiveInfo ai2 : mArchives) { - if (ai2 == ai) { - // We already processed that one above. - continue; - } - if (ai2.isAccepted()) { - // The user requested to install this package. - // Check if all its dependencies are met. - ArchiveInfo[] adeps = ai2.getDependsOn(); - if (adeps != null) { - for (ArchiveInfo adep : adeps) { - if (!adep.isAccepted()) { - error = String.format("Package '%1$s' depends on '%2$s'", - ai2.getShortDescription(), - adep.getShortDescription()); - return; - } - } - } - } else { - // The user did not request to install this package. - // Check whether this package blocks another one when not accepted. - for (ArchiveInfo adep : ai2.getDependenciesFor()) { - // It only matters if the blocked one is accepted - // or if it's a local archive that is already installed (these - // are marked as implicitly accepted, so it's the same test.) - if (adep.isAccepted()) { - error = String.format("Package '%1$s' depends on '%2$s'", - adep.getShortDescription(), - ai2.getShortDescription()); - return; - } - } - } - } - } finally { - mErrorLabel.setText(error == null ? "" : error); //$NON-NLS-1$ - } - } - - private void addText(String...string) { - for (String s : string) { - mPackageText.append(s); - } - } - - private void addSectionTitle(String string) { - String s = mPackageText.getText(); - int start = (s == null ? 0 : s.length()); - mPackageText.append(string); - - StyleRange sr = new StyleRange(); - sr.start = start; - sr.length = string.length(); - sr.fontStyle = SWT.BOLD; - sr.underline = true; - mPackageText.setStyleRange(sr); - } - - private void updateLicenceRadios(ArchiveInfo ai) { - if (mInternalLicenseRadioUpdate) { - return; - } - mInternalLicenseRadioUpdate = true; - - boolean oneAccepted = false; - - if (mLicenseAcceptAll) { - mLicenseRadioAcceptAll.setSelection(true); - mLicenseRadioAccept.setEnabled(true); - mLicenseRadioReject.setEnabled(true); - mLicenseRadioAccept.setSelection(false); - mLicenseRadioReject.setSelection(false); - } else { - mLicenseRadioAcceptAll.setSelection(false); - oneAccepted = ai != null && ai.isAccepted(); - mLicenseRadioAccept.setEnabled(ai != null); - mLicenseRadioReject.setEnabled(ai != null); - mLicenseRadioAccept.setSelection(oneAccepted); - mLicenseRadioReject.setSelection(ai != null && ai.isRejected()); - } - - // The install button is enabled if there's at least one package accepted. - // If the current one isn't, look for another one. - boolean missing = mErrorLabel.getText() != null && mErrorLabel.getText().length() > 0; - if (!missing && !oneAccepted) { - for(ArchiveInfo ai2 : mArchives) { - if (ai2.isAccepted()) { - oneAccepted = true; - break; - } - } - } - - getButton(IDialogConstants.OK_ID).setEnabled(!missing && oneAccepted); - - mInternalLicenseRadioUpdate = false; - } - - /** - * Callback invoked when one of the radio license buttons is selected. - * - * - accept/refuse: toggle, update item checkbox - * - accept all: set accept-all, check all items - */ - private void onLicenseRadioSelected() { - if (mInternalLicenseRadioUpdate) { - return; - } - mInternalLicenseRadioUpdate = true; - - ArchiveInfo ai = getSelectedArchive(); - - if (ai == null) { - // Should never happen. - return; - } - - boolean needUpdate = true; - - if (!mLicenseAcceptAll && mLicenseRadioAcceptAll.getSelection()) { - // Accept all has been switched on. Mark all packages as accepted - mLicenseAcceptAll = true; - for(ArchiveInfo ai2 : mArchives) { - ai2.setAccepted(true); - ai2.setRejected(false); - } - - } else if (mLicenseRadioAccept.getSelection()) { - // Accept only this one - mLicenseAcceptAll = false; - ai.setAccepted(true); - ai.setRejected(false); - - } else if (mLicenseRadioReject.getSelection()) { - // Reject only this one - mLicenseAcceptAll = false; - ai.setAccepted(false); - ai.setRejected(true); - - } else { - needUpdate = false; - } - - mInternalLicenseRadioUpdate = false; - - if (needUpdate) { - if (mLicenseAcceptAll) { - mTableViewPackage.refresh(); - } else { - mTableViewPackage.refresh(ai); - } - displayMissingDependency(ai); - updateLicenceRadios(ai); - } - } - - /** - * Callback invoked when a package item is double-clicked in the list. - */ - private void onPackageDoubleClick() { - ArchiveInfo ai = getSelectedArchive(); - - if (ai == null) { - // Should never happen. - return; - } - - boolean wasAccepted = ai.isAccepted(); - ai.setAccepted(!wasAccepted); - ai.setRejected(wasAccepted); - - // update state - mLicenseAcceptAll = false; - mTableViewPackage.refresh(ai); - displayMissingDependency(ai); - updateLicenceRadios(ai); - } - - private class NewArchivesLabelProvider extends LabelProvider { - @Override - public Image getImage(Object element) { - assert element instanceof ArchiveInfo; - ArchiveInfo ai = (ArchiveInfo) element; - - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - if (ai.isAccepted()) { - return imgFactory.getImageByName("accept_icon16.png"); - } else if (ai.isRejected()) { - return imgFactory.getImageByName("reject_icon16.png"); - } - return imgFactory.getImageByName("unknown_icon16.png"); - } - return super.getImage(element); - } - - @Override - public String getText(Object element) { - assert element instanceof ArchiveInfo; - ArchiveInfo ai = (ArchiveInfo) element; - - String desc = ai.getShortDescription(); - - if (ai.isDependencyFor()) { - desc += " [*]"; - } - - return desc; - } - } - - private class NewArchivesContentProvider implements IStructuredContentProvider { - - @Override - public void dispose() { - // pass - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // Ignore. The input is always mArchives - } - - @Override - public Object[] getElements(Object inputElement) { - return mArchives.toArray(); - } - } - - // End of hiding from SWT Designer - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterLogic.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterLogic.java deleted file mode 100755 index da71115..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterLogic.java +++ /dev/null @@ -1,1435 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.AddonPackage; -import com.android.sdklib.internal.repository.packages.DocPackage; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.FullRevision; -import com.android.sdklib.internal.repository.packages.IAndroidVersionProvider; -import com.android.sdklib.internal.repository.packages.IExactApiLevelDependency; -import com.android.sdklib.internal.repository.packages.IMinApiLevelDependency; -import com.android.sdklib.internal.repository.packages.IMinPlatformToolsDependency; -import com.android.sdklib.internal.repository.packages.IMinToolsDependency; -import com.android.sdklib.internal.repository.packages.IPlatformDependency; -import com.android.sdklib.internal.repository.packages.MinToolsPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.Package.UpdateInfo; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.internal.repository.packages.SamplePackage; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.internal.repository.sources.SdkSources; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - * The logic to compute which packages to install, based on the choices - * made by the user. This adds required packages as needed. - * <p/> - * When the user doesn't provide a selection, looks at local package to find - * those that can be updated and compute dependencies too. - */ -class SdkUpdaterLogic { - - private final IUpdaterData mUpdaterData; - - public SdkUpdaterLogic(IUpdaterData updaterData) { - mUpdaterData = updaterData; - } - - /** - * Retrieves an unfiltered list of all remote archives. - * The archives are guaranteed to be compatible with the current platform. - */ - public List<ArchiveInfo> getAllRemoteArchives( - SdkSources sources, - Package[] localPkgs, - boolean includeAll) { - - List<Package> remotePkgs = new ArrayList<Package>(); - SdkSource[] remoteSources = sources.getAllSources(); - fetchRemotePackages(remotePkgs, remoteSources); - - ArrayList<Archive> archives = new ArrayList<Archive>(); - for (Package remotePkg : remotePkgs) { - // Only look for non-obsolete updates unless requested to include them - if (includeAll || !remotePkg.isObsolete()) { - // Found a suitable update. Only accept the remote package - // if it provides at least one compatible archive - - addArchives: - for (Archive a : remotePkg.getArchives()) { - if (a.isCompatible()) { - - // If we're trying to add a package for revision N, - // make sure we don't also have a package for revision N-1. - for (int i = archives.size() - 1; i >= 0; i--) { - Package pkgFound = archives.get(i).getParentPackage(); - if (pkgFound.canBeUpdatedBy(remotePkg) == UpdateInfo.UPDATE) { - // This package can update one we selected earlier. - // Remove the one that can be updated by this new one. - archives.remove(i); - } else if (remotePkg.canBeUpdatedBy(pkgFound) == UpdateInfo.UPDATE) { - // There is a package in the list that is already better - // than the one we want to add, so don't add it. - break addArchives; - } - } - - archives.add(a); - break; - } - } - } - } - - ArrayList<ArchiveInfo> result = new ArrayList<ArchiveInfo>(); - - ArchiveInfo[] localArchives = createLocalArchives(localPkgs); - - for (Archive a : archives) { - insertArchive(a, - result, - archives, - remotePkgs, - remoteSources, - localArchives, - false /*automated*/); - } - - return result; - } - - /** - * Compute which packages to install by taking the user selection - * and adding required packages as needed. - * - * When the user doesn't provide a selection, looks at local packages to find - * those that can be updated and compute dependencies too. - */ - public List<ArchiveInfo> computeUpdates( - Collection<Archive> selectedArchives, - SdkSources sources, - Package[] localPkgs, - boolean includeAll) { - - List<ArchiveInfo> archives = new ArrayList<ArchiveInfo>(); - List<Package> remotePkgs = new ArrayList<Package>(); - SdkSource[] remoteSources = sources.getAllSources(); - - // Create ArchiveInfos out of local (installed) packages. - ArchiveInfo[] localArchives = createLocalArchives(localPkgs); - - // If we do not have a specific list of archives to install (that is the user - // selected "update all" rather than request specific packages), then we try to - // find updates based on the *existing* packages. - if (selectedArchives == null) { - selectedArchives = findUpdates( - localArchives, - remotePkgs, - remoteSources, - includeAll); - } - - // Once we have a list of packages to install, we try to solve all their - // dependencies by automatically adding them to the list of things to install. - // This works on the list provided either by the user directly or the list - // computed from potential updates. - for (Archive a : selectedArchives) { - insertArchive(a, - archives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - false /*automated*/); - } - - // Finally we need to look at *existing* packages which are not being updated - // and check if they have any missing dependencies and suggest how to fix - // these dependencies. - fixMissingLocalDependencies( - archives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - return archives; - } - - private double getRevisionRank(FullRevision rev) { - int p = rev.isPreview() ? 999 : 999 - rev.getPreview(); - return rev.getMajor() + - rev.getMinor() / 1000.d + - rev.getMicro() / 1000000.d + - p / 1000000000.d; - } - - /** - * Finds new packages that the user does not have in his/her local SDK - * and adds them to the list of archives to install. - * <p/> - * The default is to only find "new" platforms, that is anything more - * recent than the highest platform currently installed. - * A side effect is that for an empty SDK install this will list *all* - * platforms available (since there's no "highest" installed platform.) - * - * @param archives The in-out list of archives to install. Typically the - * list is not empty at first as it should contain any archives that is - * already scheduled for install. This method will add to the list. - * @param sources The list of all sources, to fetch them as necessary. - * @param localPkgs The list of all currently installed packages. - * @param includeAll When true, this will list all platforms. - * (included these lower than the highest installed one) as well as - * all obsolete packages of these platforms. - */ - public void addNewPlatforms( - Collection<ArchiveInfo> archives, - SdkSources sources, - Package[] localPkgs, - boolean includeAll) { - - // Create ArchiveInfos out of local (installed) packages. - ArchiveInfo[] localArchives = createLocalArchives(localPkgs); - - // Find the highest platform installed - double currentPlatformScore = 0; - double currentSampleScore = 0; - double currentAddonScore = 0; - double currentDocScore = 0; - HashMap<String, Double> currentExtraScore = new HashMap<String, Double>(); - if (!includeAll) { - if (localPkgs != null) { - for (Package p : localPkgs) { - double rev = getRevisionRank(p.getRevision()); - int api = 0; - boolean isPreview = false; - if (p instanceof IAndroidVersionProvider) { - AndroidVersion vers = ((IAndroidVersionProvider) p).getAndroidVersion(); - api = vers.getApiLevel(); - isPreview = vers.isPreview(); - } - - // The score is 1000*api + (999 if preview) + rev - // This allows previews to rank above a non-preview and - // allows revisions to rank appropriately. - double score = api * 1000 + (isPreview ? 999 : 0) + rev; - - if (p instanceof PlatformPackage) { - currentPlatformScore = Math.max(currentPlatformScore, score); - } else if (p instanceof SamplePackage) { - currentSampleScore = Math.max(currentSampleScore, score); - } else if (p instanceof AddonPackage) { - currentAddonScore = Math.max(currentAddonScore, score); - } else if (p instanceof ExtraPackage) { - currentExtraScore.put(((ExtraPackage) p).getPath(), score); - } else if (p instanceof DocPackage) { - currentDocScore = Math.max(currentDocScore, score); - } - } - } - } - - SdkSource[] remoteSources = sources.getAllSources(); - ArrayList<Package> remotePkgs = new ArrayList<Package>(); - fetchRemotePackages(remotePkgs, remoteSources); - - Package suggestedDoc = null; - - for (Package p : remotePkgs) { - // Skip obsolete packages unless requested to include them. - if (p.isObsolete() && !includeAll) { - continue; - } - - double rev = getRevisionRank(p.getRevision()); - int api = 0; - boolean isPreview = false; - if (p instanceof IAndroidVersionProvider) { - AndroidVersion vers = ((IAndroidVersionProvider) p).getAndroidVersion(); - api = vers.getApiLevel(); - isPreview = vers.isPreview(); - } - - double score = api * 1000 + (isPreview ? 999 : 0) + rev; - - boolean shouldAdd = false; - if (p instanceof PlatformPackage) { - shouldAdd = score > currentPlatformScore; - } else if (p instanceof SamplePackage) { - shouldAdd = score > currentSampleScore; - } else if (p instanceof AddonPackage) { - shouldAdd = score > currentAddonScore; - } else if (p instanceof ExtraPackage) { - String key = ((ExtraPackage) p).getPath(); - shouldAdd = !currentExtraScore.containsKey(key) || - score > currentExtraScore.get(key).doubleValue(); - } else if (p instanceof DocPackage) { - // We don't want all the doc, only the most recent one - if (score > currentDocScore) { - suggestedDoc = p; - currentDocScore = score; - } - } - - if (shouldAdd) { - // We should suggest this package for installation. - for (Archive a : p.getArchives()) { - if (a.isCompatible()) { - insertArchive(a, - archives, - null /*selectedArchives*/, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - - if (p instanceof PlatformPackage && (score >= currentPlatformScore)) { - // We just added a new platform *or* we are visiting the highest currently - // installed platform. In either case we want to make sure it either has - // its own system image or that we provide one by default. - PlatformPackage pp = (PlatformPackage) p; - if (pp.getIncludedAbi() == null) { - for (Package p2 : remotePkgs) { - if (!(p2 instanceof SystemImagePackage) || - (p2.isObsolete() && !includeAll)) { - continue; - } - SystemImagePackage sip = (SystemImagePackage) p2; - if (sip.getAndroidVersion().equals(pp.getAndroidVersion())) { - for (Archive a : sip.getArchives()) { - if (a.isCompatible()) { - insertArchive(a, - archives, - null /*selectedArchives*/, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - } - } - } - - if (suggestedDoc != null) { - // We should suggest this package for installation. - for (Archive a : suggestedDoc.getArchives()) { - if (a.isCompatible()) { - insertArchive(a, - archives, - null /*selectedArchives*/, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - - /** - * Create a array of {@link ArchiveInfo} based on all local (already installed) - * packages. The array is always non-null but may be empty. - * <p/> - * The local {@link ArchiveInfo} are guaranteed to have one non-null archive - * that you can retrieve using {@link ArchiveInfo#getNewArchive()}. - */ - protected ArchiveInfo[] createLocalArchives(Package[] localPkgs) { - - if (localPkgs != null) { - ArrayList<ArchiveInfo> list = new ArrayList<ArchiveInfo>(); - for (Package p : localPkgs) { - // Only accept packages that have one compatible archive. - // Local package should have 1 and only 1 compatible archive anyway. - for (Archive a : p.getArchives()) { - if (a != null && a.isCompatible()) { - // We create an "installed" archive info to wrap the local package. - // Note that dependencies are not computed since right now we don't - // deal with more than one level of dependencies and installed archives - // are deemed implicitly accepted anyway. - list.add(new LocalArchiveInfo(a)); - } - } - } - - return list.toArray(new ArchiveInfo[list.size()]); - } - - return new ArchiveInfo[0]; - } - - /** - * Find suitable updates to all current local packages. - * <p/> - * Returns a list of potential updates for *existing* packages. This does NOT solve - * dependencies for the new packages. - * <p/> - * Always returns a non-null collection, which can be empty. - */ - private Collection<Archive> findUpdates( - ArchiveInfo[] localArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - boolean includeAll) { - ArrayList<Archive> updates = new ArrayList<Archive>(); - - fetchRemotePackages(remotePkgs, remoteSources); - - for (ArchiveInfo ai : localArchives) { - Archive na = ai.getNewArchive(); - if (na == null) { - continue; - } - Package localPkg = na.getParentPackage(); - - for (Package remotePkg : remotePkgs) { - // Only look for non-obsolete updates unless requested to include them - if ((includeAll || !remotePkg.isObsolete()) && - localPkg.canBeUpdatedBy(remotePkg) == UpdateInfo.UPDATE) { - // Found a suitable update. Only accept the remote package - // if it provides at least one compatible archive - - addArchives: - for (Archive a : remotePkg.getArchives()) { - if (a.isCompatible()) { - - // If we're trying to add a package for revision N, - // make sure we don't also have a package for revision N-1. - for (int i = updates.size() - 1; i >= 0; i--) { - Package pkgFound = updates.get(i).getParentPackage(); - if (pkgFound.canBeUpdatedBy(remotePkg) == UpdateInfo.UPDATE) { - // This package can update one we selected earlier. - // Remove the one that can be updated by this new one. - updates.remove(i); - } else if (remotePkg.canBeUpdatedBy(pkgFound) == - UpdateInfo.UPDATE) { - // There is a package in the list that is already better - // than the one we want to add, so don't add it. - break addArchives; - } - } - - updates.add(a); - break; - } - } - } - } - } - - return updates; - } - - /** - * Check all local archives which are NOT being updated and see if they - * miss any dependency. If they do, try to fix that dependency by selecting - * an appropriate package. - */ - private void fixMissingLocalDependencies( - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives) { - - nextLocalArchive: for (ArchiveInfo ai : localArchives) { - Archive a = ai.getNewArchive(); - Package p = a == null ? null : a.getParentPackage(); - if (p == null) { - continue; - } - - // Is this local archive being updated? - for (ArchiveInfo ai2 : outArchives) { - if (ai2.getReplaced() == a) { - // this new archive will replace the current local one, - // so we don't have to care about fixing dependencies (since the - // new archive should already have had its dependencies resolved) - continue nextLocalArchive; - } - } - - // find dependencies for the local archive and add them as needed - // to the outArchives collection. - ArchiveInfo[] deps = findDependency(p, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - if (deps != null) { - // The already installed archive has a missing dependency, which we - // just selected for install. Make sure we remember the dependency - // so that we can enforce it later in the UI. - for (ArchiveInfo aid : deps) { - aid.addDependencyFor(ai); - } - } - } - } - - private ArchiveInfo insertArchive(Archive archive, - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives, - boolean automated) { - Package p = archive.getParentPackage(); - - // Is this an update? - Archive updatedArchive = null; - for (ArchiveInfo ai : localArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package lp = a.getParentPackage(); - - if (lp.canBeUpdatedBy(p) == UpdateInfo.UPDATE) { - updatedArchive = a; - } - } - } - - // Find dependencies and adds them as needed to outArchives - ArchiveInfo[] deps = findDependency(p, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - // Make sure it's not a dup - ArchiveInfo ai = null; - - for (ArchiveInfo ai2 : outArchives) { - Archive a2 = ai2.getNewArchive(); - if (a2 != null && a2.getParentPackage().sameItemAs(archive.getParentPackage())) { - ai = ai2; - break; - } - } - - if (ai == null) { - ai = new ArchiveInfo( - archive, //newArchive - updatedArchive, //replaced - deps //dependsOn - ); - outArchives.add(ai); - } - - if (deps != null) { - for (ArchiveInfo d : deps) { - d.addDependencyFor(ai); - } - } - - return ai; - } - - /** - * Resolves dependencies for a given package. - * - * Returns null if no dependencies were found. - * Otherwise return an array of {@link ArchiveInfo}, which is guaranteed to have - * at least size 1 and contain no null elements. - */ - private ArchiveInfo[] findDependency(Package pkg, - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives) { - - // Current dependencies can be: - // - addon: *always* depends on platform of same API level - // - platform: *might* depends on tools of rev >= min-tools-rev - // - extra: *might* depends on platform with api >= min-api-level - - Set<ArchiveInfo> aiFound = new HashSet<ArchiveInfo>(); - - if (pkg instanceof IPlatformDependency) { - ArchiveInfo ai = findPlatformDependency( - (IPlatformDependency) pkg, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - if (ai != null) { - aiFound.add(ai); - } - } - - if (pkg instanceof IMinToolsDependency) { - - ArchiveInfo ai = findToolsDependency( - (IMinToolsDependency) pkg, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - if (ai != null) { - aiFound.add(ai); - } - } - - if (pkg instanceof IMinPlatformToolsDependency) { - - ArchiveInfo ai = findPlatformToolsDependency( - (IMinPlatformToolsDependency) pkg, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - if (ai != null) { - aiFound.add(ai); - } - } - - if (pkg instanceof IMinApiLevelDependency) { - - ArchiveInfo ai = findMinApiLevelDependency( - (IMinApiLevelDependency) pkg, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - if (ai != null) { - aiFound.add(ai); - } - } - - if (pkg instanceof IExactApiLevelDependency) { - - ArchiveInfo ai = findExactApiLevelDependency( - (IExactApiLevelDependency) pkg, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives); - - if (ai != null) { - aiFound.add(ai); - } - } - - if (aiFound.size() > 0) { - ArchiveInfo[] result = aiFound.toArray(new ArchiveInfo[aiFound.size()]); - Arrays.sort(result); - return result; - } - - return null; - } - - /** - * Resolves dependencies on tools. - * - * A platform or an extra package can both have a min-tools-rev, in which case it - * depends on having a tools package of the requested revision. - * Finds the tools dependency. If found, add it to the list of things to install. - * Returns the archive info dependency, if any. - */ - protected ArchiveInfo findToolsDependency( - IMinToolsDependency pkg, - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives) { - // This is the requirement to match. - FullRevision rev = pkg.getMinToolsRevision(); - - if (rev.equals(MinToolsPackage.MIN_TOOLS_REV_NOT_SPECIFIED)) { - // Well actually there's no requirement. - return null; - } - - // First look in locally installed packages. - for (ArchiveInfo ai : localArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof ToolPackage) { - if (((ToolPackage) p).getRevision().compareTo(rev) >= 0) { - // We found one already installed. - return null; - } - } - } - } - - // Look in archives already scheduled for install - for (ArchiveInfo ai : outArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof ToolPackage) { - if (((ToolPackage) p).getRevision().compareTo(rev) >= 0) { - // The dependency is already scheduled for install, nothing else to do. - return ai; - } - } - } - } - - // Otherwise look in the selected archives. - if (selectedArchives != null) { - for (Archive a : selectedArchives) { - Package p = a.getParentPackage(); - if (p instanceof ToolPackage) { - if (((ToolPackage) p).getRevision().compareTo(rev) >= 0) { - // It's not already in the list of things to install, so add it now - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - - // Finally nothing matched, so let's look at all available remote packages - fetchRemotePackages(remotePkgs, remoteSources); - for (Package p : remotePkgs) { - if (p instanceof ToolPackage) { - if (((ToolPackage) p).getRevision().compareTo(rev) >= 0) { - // It's not already in the list of things to install, so add the - // first compatible archive we can find. - for (Archive a : p.getArchives()) { - if (a.isCompatible()) { - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - } - - // We end up here if nothing matches. We don't have a good platform to match. - // We need to indicate this extra depends on a missing platform archive - // so that it can be impossible to install later on. - return new MissingArchiveInfo(MissingArchiveInfo.TITLE_TOOL, rev); - } - - /** - * Resolves dependencies on platform-tools. - * - * A tool package can have a min-platform-tools-rev, in which case it depends on - * having a platform-tool package of the requested revision. - * Finds the platform-tool dependency. If found, add it to the list of things to install. - * Returns the archive info dependency, if any. - */ - protected ArchiveInfo findPlatformToolsDependency( - IMinPlatformToolsDependency pkg, - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives) { - // This is the requirement to match. - FullRevision rev = pkg.getMinPlatformToolsRevision(); - boolean findMax = false; - ArchiveInfo aiMax = null; - Archive aMax = null; - - if (rev.equals(IMinPlatformToolsDependency.MIN_PLATFORM_TOOLS_REV_INVALID)) { - // The requirement is invalid, which is not supposed to happen since this - // property is mandatory. However in a typical upgrade scenario we can end - // up with the previous updater managing a new package and not dealing - // correctly with the new unknown property. - // So instead we parse all the existing and remote packages and try to find - // the max available revision and we'll use it. - findMax = true; - } - - // First look in locally installed packages. - for (ArchiveInfo ai : localArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformToolPackage) { - FullRevision r = ((PlatformToolPackage) p).getRevision(); - if (findMax && r.compareTo(rev) > 0) { - rev = r; - aiMax = ai; - } else if (!findMax && r.compareTo(rev) >= 0) { - // We found one already installed. - return null; - } - } - } - } - - // Look in archives already scheduled for install - for (ArchiveInfo ai : outArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformToolPackage) { - FullRevision r = ((PlatformToolPackage) p).getRevision(); - if (findMax && r.compareTo(rev) > 0) { - rev = r; - aiMax = ai; - } else if (!findMax && r.compareTo(rev) >= 0) { - // The dependency is already scheduled for install, nothing else to do. - return ai; - } - } - } - } - - // Otherwise look in the selected archives. - if (selectedArchives != null) { - for (Archive a : selectedArchives) { - Package p = a.getParentPackage(); - if (p instanceof PlatformToolPackage) { - FullRevision r = ((PlatformToolPackage) p).getRevision(); - if (findMax && r.compareTo(rev) > 0) { - rev = r; - aiMax = null; - aMax = a; - } else if (!findMax && r.compareTo(rev) >= 0) { - // It's not already in the list of things to install, so add it now - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - - // Finally nothing matched, so let's look at all available remote packages - fetchRemotePackages(remotePkgs, remoteSources); - for (Package p : remotePkgs) { - if (p instanceof PlatformToolPackage) { - FullRevision r = ((PlatformToolPackage) p).getRevision(); - if (r.compareTo(rev) >= 0) { - // Make sure there's at least one valid archive here - for (Archive a : p.getArchives()) { - if (a.isCompatible()) { - if (findMax && r.compareTo(rev) > 0) { - rev = r; - aiMax = null; - aMax = a; - } else if (!findMax && r.compareTo(rev) >= 0) { - // It's not already in the list of things to install, so add the - // first compatible archive we can find. - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - } - } - - if (findMax) { - if (aMax != null) { - return insertArchive(aMax, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } else if (aiMax != null) { - return aiMax; - } - } - - // We end up here if nothing matches. We don't have a good platform to match. - // We need to indicate this package depends on a missing platform archive - // so that it can be impossible to install later on. - return new MissingArchiveInfo(MissingArchiveInfo.TITLE_PLATFORM_TOOL, rev); - } - - /** - * Resolves dependencies on platform for an addon. - * - * An addon depends on having a platform with the same API level. - * - * Finds the platform dependency. If found, add it to the list of things to install. - * Returns the archive info dependency, if any. - */ - protected ArchiveInfo findPlatformDependency( - IPlatformDependency pkg, - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives) { - // This is the requirement to match. - AndroidVersion v = pkg.getAndroidVersion(); - - // Find a platform that would satisfy the requirement. - - // First look in locally installed packages. - for (ArchiveInfo ai : localArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (v.equals(((PlatformPackage) p).getAndroidVersion())) { - // We found one already installed. - return null; - } - } - } - } - - // Look in archives already scheduled for install - for (ArchiveInfo ai : outArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (v.equals(((PlatformPackage) p).getAndroidVersion())) { - // The dependency is already scheduled for install, nothing else to do. - return ai; - } - } - } - } - - // Otherwise look in the selected archives. - if (selectedArchives != null) { - for (Archive a : selectedArchives) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (v.equals(((PlatformPackage) p).getAndroidVersion())) { - // It's not already in the list of things to install, so add it now - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - - // Finally nothing matched, so let's look at all available remote packages - fetchRemotePackages(remotePkgs, remoteSources); - for (Package p : remotePkgs) { - if (p instanceof PlatformPackage) { - if (v.equals(((PlatformPackage) p).getAndroidVersion())) { - // It's not already in the list of things to install, so add the - // first compatible archive we can find. - for (Archive a : p.getArchives()) { - if (a.isCompatible()) { - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - } - - // We end up here if nothing matches. We don't have a good platform to match. - // We need to indicate this addon depends on a missing platform archive - // so that it can be impossible to install later on. - return new MissingPlatformArchiveInfo(pkg.getAndroidVersion()); - } - - /** - * Resolves platform dependencies for extras. - * An extra depends on having a platform with a minimun API level. - * - * We try to return the highest API level available above the specified minimum. - * Note that installed packages have priority so if one installed platform satisfies - * the dependency, we'll use it even if there's a higher API platform available but - * not installed yet. - * - * Finds the platform dependency. If found, add it to the list of things to install. - * Returns the archive info dependency, if any. - */ - protected ArchiveInfo findMinApiLevelDependency( - IMinApiLevelDependency pkg, - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives) { - - int api = pkg.getMinApiLevel(); - - if (api == IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED) { - return null; - } - - // Find a platform that would satisfy the requirement. - - // First look in locally installed packages. - for (ArchiveInfo ai : localArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().isGreaterOrEqualThan(api)) { - // We found one already installed. - return null; - } - } - } - } - - // Look in archives already scheduled for install - int foundApi = 0; - ArchiveInfo foundAi = null; - - for (ArchiveInfo ai : outArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().isGreaterOrEqualThan(api)) { - if (api > foundApi) { - foundApi = api; - foundAi = ai; - } - } - } - } - } - - if (foundAi != null) { - // The dependency is already scheduled for install, nothing else to do. - return foundAi; - } - - // Otherwise look in the selected archives *or* available remote packages - // and takes the best out of the two sets. - foundApi = 0; - Archive foundArchive = null; - if (selectedArchives != null) { - for (Archive a : selectedArchives) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().isGreaterOrEqualThan(api)) { - if (api > foundApi) { - foundApi = api; - foundArchive = a; - } - } - } - } - } - - // Finally nothing matched, so let's look at all available remote packages - fetchRemotePackages(remotePkgs, remoteSources); - for (Package p : remotePkgs) { - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().isGreaterOrEqualThan(api)) { - if (api > foundApi) { - // It's not already in the list of things to install, so add the - // first compatible archive we can find. - for (Archive a : p.getArchives()) { - if (a.isCompatible()) { - foundApi = api; - foundArchive = a; - } - } - } - } - } - } - - if (foundArchive != null) { - // It's not already in the list of things to install, so add it now - return insertArchive(foundArchive, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - - // We end up here if nothing matches. We don't have a good platform to match. - // We need to indicate this extra depends on a missing platform archive - // so that it can be impossible to install later on. - return new MissingPlatformArchiveInfo(new AndroidVersion(api, null /*codename*/)); - } - - /** - * Resolves platform dependencies for add-ons. - * An add-ons depends on having a platform with an exact specific API level. - * - * Finds the platform dependency. If found, add it to the list of things to install. - * Returns the archive info dependency, if any. - */ - protected ArchiveInfo findExactApiLevelDependency( - IExactApiLevelDependency pkg, - Collection<ArchiveInfo> outArchives, - Collection<Archive> selectedArchives, - Collection<Package> remotePkgs, - SdkSource[] remoteSources, - ArchiveInfo[] localArchives) { - - int api = pkg.getExactApiLevel(); - - if (api == IExactApiLevelDependency.API_LEVEL_INVALID) { - return null; - } - - // Find a platform that would satisfy the requirement. - - // First look in locally installed packages. - for (ArchiveInfo ai : localArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().equals(api)) { - // We found one already installed. - return null; - } - } - } - } - - // Look in archives already scheduled for install - - for (ArchiveInfo ai : outArchives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().equals(api)) { - return ai; - } - } - } - } - - // Otherwise look in the selected archives. - if (selectedArchives != null) { - for (Archive a : selectedArchives) { - Package p = a.getParentPackage(); - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().equals(api)) { - // It's not already in the list of things to install, so add it now - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - - // Finally nothing matched, so let's look at all available remote packages - fetchRemotePackages(remotePkgs, remoteSources); - for (Package p : remotePkgs) { - if (p instanceof PlatformPackage) { - if (((PlatformPackage) p).getAndroidVersion().equals(api)) { - // It's not already in the list of things to install, so add the - // first compatible archive we can find. - for (Archive a : p.getArchives()) { - if (a.isCompatible()) { - return insertArchive(a, - outArchives, - selectedArchives, - remotePkgs, - remoteSources, - localArchives, - true /*automated*/); - } - } - } - } - } - - // We end up here if nothing matches. We don't have a good platform to match. - // We need to indicate this extra depends on a missing platform archive - // so that it can be impossible to install later on. - return new MissingPlatformArchiveInfo(new AndroidVersion(api, null /*codename*/)); - } - - /** - * Fetch all remote packages only if really needed. - * <p/> - * This method takes a list of sources. Each source is only fetched once -- that is each - * source keeps the list of packages that we fetched from the remote XML file. If the list - * is null, it means this source has never been fetched so we'll do it once here. Otherwise - * we rely on the cached list of packages from this source. - * <p/> - * This method also takes a remote package list as input, which it will fill out. - * If a source has already been fetched, we'll add its packages to the remote package list - * if they are not already present. Otherwise, the source will be fetched and the packages - * added to the list. - * - * @param remotePkgs An in-out list of packages available from remote sources. - * This list must not be null. - * It can be empty or already contain some packages. - * @param remoteSources A list of available remote sources to fetch from. - */ - protected void fetchRemotePackages( - final Collection<Package> remotePkgs, - final SdkSource[] remoteSources) { - if (remotePkgs.size() > 0) { - return; - } - - // First check if there's any remote source we need to fetch. - // This will bring the task window, so we rather not display it unless - // necessary. - boolean needsFetch = false; - for (final SdkSource remoteSrc : remoteSources) { - Package[] pkgs = remoteSrc.getPackages(); - if (pkgs == null) { - // This source has never been fetched. We'll do it below. - needsFetch = true; - } else { - // This source has already been fetched and we know its package list. - // We still need to make sure all of its packages are present in the - // remotePkgs list. - - nextPackage: for (Package pkg : pkgs) { - for (Archive a : pkg.getArchives()) { - // Only add a package if it contains at least one compatible archive - // and is not already in the remote package list. - if (a.isCompatible()) { - if (!remotePkgs.contains(pkg)) { - remotePkgs.add(pkg); - continue nextPackage; - } - } - } - } - } - } - - if (!needsFetch) { - return; - } - - final boolean forceHttp = mUpdaterData.getSettingsController().getSettings().getForceHttp(); - - mUpdaterData.getTaskFactory().start("Refresh Sources", new ITask() { - @Override - public void run(ITaskMonitor monitor) { - for (SdkSource remoteSrc : remoteSources) { - Package[] pkgs = remoteSrc.getPackages(); - - if (pkgs == null) { - remoteSrc.load(mUpdaterData.getDownloadCache(), monitor, forceHttp); - pkgs = remoteSrc.getPackages(); - } - - if (pkgs != null) { - nextPackage: for (Package pkg : pkgs) { - for (Archive a : pkg.getArchives()) { - // Only add a package if it contains at least one compatible archive - // and is not already in the remote package list. - if (a.isCompatible()) { - if (!remotePkgs.contains(pkg)) { - remotePkgs.add(pkg); - continue nextPackage; - } - } - } - } - } - } - } - }); - } - - - /** - * A {@link LocalArchiveInfo} is an {@link ArchiveInfo} that wraps an already installed - * "local" package/archive. - * <p/> - * In this case, the "new Archive" is still expected to be non null and the - * "replaced Archive" is null. Installed archives are always accepted and never - * rejected. - * <p/> - * Dependencies are not set. - */ - private static class LocalArchiveInfo extends ArchiveInfo { - - public LocalArchiveInfo(Archive localArchive) { - super(localArchive, null /*replaced*/, null /*dependsOn*/); - } - - /** Installed archives are always accepted. */ - @Override - public boolean isAccepted() { - return true; - } - - /** Installed archives are never rejected. */ - @Override - public boolean isRejected() { - return false; - } - } - - /** - * A {@link MissingPlatformArchiveInfo} is an {@link ArchiveInfo} that represents a - * package/archive that we <em>really</em> need as a dependency but that we don't have. - * <p/> - * This is currently used for addons and extras in case we can't find a matching base platform. - * <p/> - * This kind of archive has specific properties: the new archive to install is null, - * there are no dependencies and no archive is being replaced. The info can never be - * accepted and is always rejected. - */ - private static class MissingPlatformArchiveInfo extends ArchiveInfo { - - private final AndroidVersion mVersion; - - /** - * Constructs a {@link MissingPlatformArchiveInfo} that will indicate the - * given platform version is missing. - */ - public MissingPlatformArchiveInfo(AndroidVersion version) { - super(null /*newArchive*/, null /*replaced*/, null /*dependsOn*/); - mVersion = version; - } - - /** Missing archives are never accepted. */ - @Override - public boolean isAccepted() { - return false; - } - - /** Missing archives are always rejected. */ - @Override - public boolean isRejected() { - return true; - } - - @Override - public String getShortDescription() { - return String.format("Missing SDK Platform Android%1$s, API %2$d", - mVersion.isPreview() ? " Preview" : "", - mVersion.getApiLevel()); - } - } - - /** - * A {@link MissingArchiveInfo} is an {@link ArchiveInfo} that represents a - * package/archive that we <em>really</em> need as a dependency but that we don't have. - * <p/> - * This is currently used for extras in case we can't find a matching tool revision - * or when a platform-tool is missing. - * <p/> - * This kind of archive has specific properties: the new archive to install is null, - * there are no dependencies and no archive is being replaced. The info can never be - * accepted and is always rejected. - */ - private static class MissingArchiveInfo extends ArchiveInfo { - - private final FullRevision mRevision; - private final String mTitle; - - public static final String TITLE_TOOL = "Tools"; - public static final String TITLE_PLATFORM_TOOL = "Platform-tools"; - - /** - * Constructs a {@link MissingPlatformArchiveInfo} that will indicate the - * given platform version is missing. - * - * @param title Typically "Tools" or "Platform-tools". - * @param revision The required revision. - */ - public MissingArchiveInfo(String title, FullRevision revision) { - super(null /*newArchive*/, null /*replaced*/, null /*dependsOn*/); - mTitle = title; - mRevision = revision; - } - - /** Missing archives are never accepted. */ - @Override - public boolean isAccepted() { - return false; - } - - /** Missing archives are always rejected. */ - @Override - public boolean isRejected() { - return true; - } - - @Override - public String getShortDescription() { - return String.format("Missing Android SDK %1$s, revision %2$s", - mTitle, - mRevision.toShortString()); - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterNoWindow.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterNoWindow.java deleted file mode 100755 index 5e7143d..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SdkUpdaterNoWindow.java +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.annotations.NonNull; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.NullTaskMonitor; -import com.android.sdklib.internal.repository.UserCredentials; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.utils.ILogger; -import com.android.utils.Pair; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Properties; - -/** - * Performs an update using only a non-interactive console output with no GUI. - */ -public class SdkUpdaterNoWindow { - - /** The {@link UpdaterData} to use. */ - private final UpdaterData mUpdaterData; - /** The {@link ILogger} logger to use. */ - private final ILogger mSdkLog; - /** The reply to any question asked by the update process. Currently this will - * be yes/no for ability to replace modified samples or restart ADB. */ - private final boolean mForce; - - /** - * Creates an UpdateNoWindow object that will update using the given SDK root - * and outputs to the given SDK logger. - * - * @param osSdkRoot The OS path of the SDK folder to update. - * @param sdkManager An existing SDK manager to list current platforms and addons. - * @param sdkLog A logger object, that should ideally output to a write-only console. - * @param force The reply to any question asked by the update process. Currently this will - * be yes/no for ability to replace modified samples or restart ADB. - * @param useHttp True to force using HTTP instead of HTTPS for downloads. - * @param proxyPort An optional HTTP/HTTPS proxy port. Can be null. - * @param proxyHost An optional HTTP/HTTPS proxy host. Can be null. - */ - public SdkUpdaterNoWindow(String osSdkRoot, - SdkManager sdkManager, - ILogger sdkLog, - boolean force, - boolean useHttp, - String proxyHost, - String proxyPort) { - mSdkLog = sdkLog; - mForce = force; - mUpdaterData = new UpdaterData(osSdkRoot, sdkLog); - - // Read and apply settings from settings file, so that http/https proxy is set - // and let the command line args override them as necessary. - SettingsController settingsController = mUpdaterData.getSettingsController(); - settingsController.loadSettings(); - settingsController.applySettings(); - setupProxy(proxyHost, proxyPort); - - // Change the in-memory settings to force the http/https mode - settingsController.setSetting(ISettingsPage.KEY_FORCE_HTTP, useHttp); - - // Use a factory that only outputs to the given ILogger. - mUpdaterData.setTaskFactory(new ConsoleTaskFactory()); - - // Check that the AVD Manager has been correctly initialized. This is done separately - // from the constructor in the GUI-based UpdaterWindowImpl to give time to the UI to - // initialize before displaying a message box. Since we don't have any GUI here - // we can call it whenever we want. - if (mUpdaterData.checkIfInitFailed()) { - return; - } - - // Setup the default sources including the getenv overrides. - mUpdaterData.setupDefaultSources(); - - mUpdaterData.getLocalSdkParser().parseSdk( - osSdkRoot, - sdkManager, - new NullTaskMonitor(sdkLog)); - } - - /** - * Performs the actual update. - * - * @param pkgFilter A list of {@link SdkRepoConstants#NODES} to limit the type of packages - * we can update. A null or empty list means to update everything possible. - * @param includeAll True to list and install all packages, including obsolete ones. - * @param dryMode True to check what would be updated/installed but do not actually - * download or install anything. - */ - public void updateAll( - ArrayList<String> pkgFilter, - boolean includeAll, - boolean dryMode) { - mUpdaterData.updateOrInstallAll_NoGUI(pkgFilter, includeAll, dryMode); - } - - /** - * Lists remote packages available for install using 'android update sdk --no-ui'. - * - * @param includeAll True to list and install all packages, including obsolete ones. - * @param extendedOutput True to display more details on each package. - */ - public void listRemotePackages(boolean includeAll, boolean extendedOutput) { - mUpdaterData.listRemotePackages_NoGUI(includeAll, extendedOutput); - } - - // ----- - - /** - * Sets both the HTTP and HTTPS proxy system properties, overriding the ones - * from the settings with these values if they are defined. - */ - private void setupProxy(String proxyHost, String proxyPort) { - - // The system property constants can be found in the Java SE documentation at - // http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html - final String JAVA_PROP_HTTP_PROXY_HOST = "http.proxyHost"; //$NON-NLS-1$ - final String JAVA_PROP_HTTP_PROXY_PORT = "http.proxyPort"; //$NON-NLS-1$ - final String JAVA_PROP_HTTPS_PROXY_HOST = "https.proxyHost"; //$NON-NLS-1$ - final String JAVA_PROP_HTTPS_PROXY_PORT = "https.proxyPort"; //$NON-NLS-1$ - - Properties props = System.getProperties(); - - if (proxyHost != null && proxyHost.length() > 0) { - props.setProperty(JAVA_PROP_HTTP_PROXY_HOST, proxyHost); - props.setProperty(JAVA_PROP_HTTPS_PROXY_HOST, proxyHost); - } - if (proxyPort != null && proxyPort.length() > 0) { - props.setProperty(JAVA_PROP_HTTP_PROXY_PORT, proxyPort); - props.setProperty(JAVA_PROP_HTTPS_PROXY_PORT, proxyPort); - } - } - - /** - * A custom implementation of {@link ITaskFactory} that - * provides {@link ConsoleTaskMonitor} objects. - */ - private class ConsoleTaskFactory implements ITaskFactory { - @Override - public void start(String title, ITask task) { - start(title, null /*parentMonitor*/, task); - } - - @Override - public void start(String title, ITaskMonitor parentMonitor, ITask task) { - if (parentMonitor == null) { - task.run(new ConsoleTaskMonitor(title, task)); - } else { - // Use all the reminder of the parent monitor. - if (parentMonitor.getProgressMax() == 0) { - parentMonitor.setProgressMax(1); - } - - ITaskMonitor sub = parentMonitor.createSubMonitor( - parentMonitor.getProgressMax() - parentMonitor.getProgress()); - try { - task.run(sub); - } finally { - int delta = - sub.getProgressMax() - sub.getProgress(); - if (delta > 0) { - sub.incProgress(delta); - } - } - } - } - } - - /** - * A custom implementation of {@link ITaskMonitor} that defers all output to the - * super {@link SdkUpdaterNoWindow#mSdkLog}. - */ - private class ConsoleTaskMonitor implements ITaskMonitor { - - private static final double MAX_COUNT = 10000.0; - private double mIncCoef = 0; - private double mValue = 0; - private String mLastDesc = null; - private String mLastProgressBase = null; - - /** - * Creates a new {@link ConsoleTaskMonitor} with the given title. - */ - public ConsoleTaskMonitor(String title, ITask task) { - mSdkLog.info("%s:\n", title); - } - - /** - * Sets the description in the current task dialog. - */ - @Override - public void setDescription(String format, Object...args) { - - String last = mLastDesc; - String line = String.format(" " + format, args); //$NON-NLS-1$ - - // If the description contains a %, it generally indicates a recurring - // progress so we want a \r at the end. - int pos = line.indexOf('%'); - if (pos > -1) { - String base = line.trim(); - if (mLastProgressBase != null && base.startsWith(mLastProgressBase)) { - line = " " + base.substring(mLastProgressBase.length()); //$NON-NLS-1$ - } - line += '\r'; - } else { - mLastProgressBase = line.trim(); - line += '\n'; - } - - // Skip line if it's the same as the last one. - if (last != null && last.equals(line.trim())) { - return; - } - mLastDesc = line.trim(); - - // If the last line terminated with a \r but the new one doesn't, we need to - // insert a \n to avoid erasing the previous line. - if (last != null && - last.endsWith("\r") && //$NON-NLS-1$ - !line.endsWith("\r")) { //$NON-NLS-1$ - line = '\n' + line; - } - - mSdkLog.info("%s", line); //$NON-NLS-1$ - } - - @Override - public void log(String format, Object...args) { - setDescription(" " + format, args); //$NON-NLS-1$ - } - - @Override - public void logError(String format, Object...args) { - setDescription(format, args); - } - - @Override - public void logVerbose(String format, Object...args) { - // The ConsoleTask does not display verbose log messages. - } - - // --- ILogger --- - - @Override - public void error(Throwable t, String errorFormat, Object... args) { - mSdkLog.error(t, errorFormat, args); - } - - @Override - public void warning(@NonNull String warningFormat, Object... args) { - mSdkLog.warning(warningFormat, args); - } - - @Override - public void info(@NonNull String msgFormat, Object... args) { - mSdkLog.info(msgFormat, args); - } - - @Override - public void verbose(@NonNull String msgFormat, Object... args) { - mSdkLog.verbose(msgFormat, args); - } - - /** - * Sets the max value of the progress bar. - * - * Weird things will happen if setProgressMax is called multiple times - * *after* {@link #incProgress(int)}: we don't try to adjust it on the - * fly. - */ - @Override - public void setProgressMax(int max) { - assert max > 0; - // Always set the dialog's progress max to 10k since it only handles - // integers and we want to have a better inner granularity. Instead - // we use the max to compute a coefficient for inc deltas. - mIncCoef = max > 0 ? MAX_COUNT / max : 0; - assert mIncCoef > 0; - } - - @Override - public int getProgressMax() { - return mIncCoef > 0 ? (int) (MAX_COUNT / mIncCoef) : 0; - } - - /** - * Increments the current value of the progress bar. - */ - @Override - public void incProgress(int delta) { - if (delta > 0 && mIncCoef > 0) { - internalIncProgress(delta * mIncCoef); - } - } - - private void internalIncProgress(double realDelta) { - mValue += realDelta; - // max value is 10k, so 10k/100 == 100%. - // Experimentation shows that it is not really useful to display this - // progression since during download the description line will change. - // mSdkLog.printf(" [%3d%%]\r", ((int)mValue) / 100); - } - - /** - * Returns the current value of the progress bar, - * between 0 and up to {@link #setProgressMax(int)} - 1. - */ - @Override - public int getProgress() { - assert mIncCoef > 0; - return mIncCoef > 0 ? (int)(mValue / mIncCoef) : 0; - } - - /** - * Returns true if the "Cancel" button was selected. - */ - @Override - public boolean isCancelRequested() { - return false; - } - - /** - * Display a yes/no question dialog box. - * - * This implementation allow this to be called from any thread, it - * makes sure the dialog is opened synchronously in the ui thread. - * - * @param title The title of the dialog box - * @param message The error message - * @return true if YES was clicked. - */ - @Override - public boolean displayPrompt(final String title, final String message) { - // TODO Make it interactive if mForce==false - mSdkLog.info("\n%1$s\n%2$s\n%3$s", //$NON-NLS-1$ - title, - message, - mForce ? "--force used, will reply yes\n" : - "Note: you can use --force to override to yes.\n"); - if (mForce) { - return true; - } - - while (true) { - mSdkLog.info("%1$s", "[y/n] =>"); //$NON-NLS-1$ - try { - byte[] readBuffer = new byte[2048]; - String reply = readLine(readBuffer).trim(); - mSdkLog.info("\n"); //$NON-NLS-1$ - if (reply.length() > 0 && reply.length() <= 3) { - char c = reply.charAt(0); - if (c == 'y' || c == 'Y') { - return true; - } else if (c == 'n' || c == 'N') { - return false; - } - } - mSdkLog.info("Unknown reply '%s'. Please use y[es]/n[o].\n"); //$NON-NLS-1$ - - } catch (IOException e) { - // Exception. Be conservative and say no. - mSdkLog.info("\n"); //$NON-NLS-1$ - return false; - } - } - } - - /** - * Displays a prompt message to the user and read two values, - * login/password. - * <p> - * <i>Asks user for login/password information.</i> - * <p> - * This method shows a question in the standard output, asking for login - * and password.</br> - * <b>Method Output:</b></br> - * Title</br> - * Message</br> - * Login: (Wait for user input)</br> - * Password: (Wait for user input)</br> - * <p> - * - * @param title The title of the iteration. - * @param message The message to be displayed. - * @return A {@link Pair} holding the entered login and password. The - * <b>first element</b> is always the <b>Login</b>, and the - * <b>second element</b> is always the <b>Password</b>. This - * method will never return null, in case of error the pair will - * be filled with empty strings. - * @see ITaskMonitor#displayLoginCredentialsPrompt(String, String) - */ - @Override - public UserCredentials displayLoginCredentialsPrompt(String title, String message) { - String login = ""; //$NON-NLS-1$ - String password = ""; //$NON-NLS-1$ - String workstation = ""; //$NON-NLS-1$ - String domain = ""; //$NON-NLS-1$ - - mSdkLog.info("\n%1$s\n%2$s", title, message); - byte[] readBuffer = new byte[2048]; - try { - mSdkLog.info("\nLogin: "); - login = readLine(readBuffer); - mSdkLog.info("\nPassword: "); - password = readLine(readBuffer); - mSdkLog.info("\nIf your proxy uses NTLM authentication, provide the following information. Leave blank otherwise."); - mSdkLog.info("\nWorkstation: "); - workstation = readLine(readBuffer); - mSdkLog.info("\nDomain: "); - domain = readLine(readBuffer); - - /* - * TODO: Implement a way to don't echo the typed password On - * Java 5 there's no simple way to do this. There's just a - * workaround which is output backspaces on each keystroke. - * A good alternative is to use Java 6 java.io.Console - */ - } catch (IOException e) { - // Reset login/pass to empty Strings. - login = ""; //$NON-NLS-1$ - password = ""; //$NON-NLS-1$ - workstation = ""; //$NON-NLS-1$ - domain = ""; //$NON-NLS-1$ - //Just print the error to console. - mSdkLog.info("\nError occurred during login/pass query: %s\n", e.getMessage()); - } - - return new UserCredentials(login, password, workstation, domain); - } - - /** - * Reads current console input in the given buffer. - * - * @param buffer Buffer to hold the user input. Must be larger than the largest - * expected input. Cannot be null. - * @return A new string. May be empty but not null. - * @throws IOException in case the buffer isn't long enough. - */ - private String readLine(byte[] buffer) throws IOException { - int count = System.in.read(buffer); - - // is the input longer than the buffer? - if (count == buffer.length && buffer[count-1] != 10) { - throw new IOException(String.format( - "Input is longer than the buffer size, (%1$s) bytes", buffer.length)); - } - - // ignore end whitespace - while (count > 0 && (buffer[count-1] == '\r' || buffer[count-1] == '\n')) { - count--; - } - - return new String(buffer, 0, count); - } - - /** - * Creates a sub-monitor that will use up to tickCount on the progress bar. - * tickCount must be 1 or more. - */ - @Override - public ITaskMonitor createSubMonitor(int tickCount) { - assert mIncCoef > 0; - assert tickCount > 0; - return new ConsoleSubTaskMonitor(this, null, mValue, tickCount * mIncCoef); - } - } - - private interface IConsoleSubTaskMonitor extends ITaskMonitor { - public void subIncProgress(double realDelta); - } - - private static class ConsoleSubTaskMonitor implements IConsoleSubTaskMonitor { - - private final ConsoleTaskMonitor mRoot; - private final IConsoleSubTaskMonitor mParent; - private final double mStart; - private final double mSpan; - private double mSubValue; - private double mSubCoef; - - /** - * Creates a new sub task monitor which will work for the given range [start, start+span] - * in its parent. - * - * @param root The ProgressTask root - * @param parent The immediate parent. Can be the null or another sub task monitor. - * @param start The start value in the root's coordinates - * @param span The span value in the root's coordinates - */ - public ConsoleSubTaskMonitor(ConsoleTaskMonitor root, - IConsoleSubTaskMonitor parent, - double start, - double span) { - mRoot = root; - mParent = parent; - mStart = start; - mSpan = span; - mSubValue = start; - } - - @Override - public boolean isCancelRequested() { - return mRoot.isCancelRequested(); - } - - @Override - public void setDescription(String format, Object... args) { - mRoot.setDescription(format, args); - } - - @Override - public void log(String format, Object... args) { - mRoot.log(format, args); - } - - @Override - public void logError(String format, Object... args) { - mRoot.logError(format, args); - } - - @Override - public void logVerbose(String format, Object... args) { - mRoot.logVerbose(format, args); - } - - @Override - public void setProgressMax(int max) { - assert max > 0; - mSubCoef = max > 0 ? mSpan / max : 0; - assert mSubCoef > 0; - } - - @Override - public int getProgressMax() { - return mSubCoef > 0 ? (int) (mSpan / mSubCoef) : 0; - } - - @Override - public int getProgress() { - assert mSubCoef > 0; - return mSubCoef > 0 ? (int)((mSubValue - mStart) / mSubCoef) : 0; - } - - @Override - public void incProgress(int delta) { - if (delta > 0 && mSubCoef > 0) { - subIncProgress(delta * mSubCoef); - } - } - - @Override - public void subIncProgress(double realDelta) { - mSubValue += realDelta; - if (mParent != null) { - mParent.subIncProgress(realDelta); - } else { - mRoot.internalIncProgress(realDelta); - } - } - - @Override - public boolean displayPrompt(String title, String message) { - return mRoot.displayPrompt(title, message); - } - - @Override - public UserCredentials displayLoginCredentialsPrompt(String title, String message) { - return mRoot.displayLoginCredentialsPrompt(title, message); - } - - @Override - public ITaskMonitor createSubMonitor(int tickCount) { - assert mSubCoef > 0; - assert tickCount > 0; - return new ConsoleSubTaskMonitor(mRoot, - this, - mSubValue, - tickCount * mSubCoef); - } - - // --- ILogger --- - - @Override - public void error(Throwable t, String errorFormat, Object... args) { - mRoot.error(t, errorFormat, args); - } - - @Override - public void warning(@NonNull String warningFormat, Object... args) { - mRoot.warning(warningFormat, args); - } - - @Override - public void info(@NonNull String msgFormat, Object... args) { - mRoot.info(msgFormat, args); - } - - @Override - public void verbose(@NonNull String msgFormat, Object... args) { - mRoot.verbose(msgFormat, args); - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsController.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsController.java deleted file mode 100755 index 2d2352b..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsController.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.annotations.NonNull; -import com.android.prefs.AndroidLocation; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.utils.ILogger; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map.Entry; -import java.util.Properties; - -/** - * Controller class to get settings values. Settings are kept in-memory. - * Users of this class must first load the settings before changing them and save - * them when modified. - * <p/> - * Settings are enumerated by constants in {@link ISettingsPage}. - */ -public class SettingsController { - - private static final String SETTINGS_FILENAME = "androidtool.cfg"; //$NON-NLS-1$ - - private final ILogger mSdkLog; - private final Settings mSettings; - - public interface OnChangedListener { - public void onSettingsChanged(SettingsController controller, Settings oldSettings); - } - private final List<OnChangedListener> mChangedListeners = new ArrayList<OnChangedListener>(1); - - /** The currently associated {@link ISettingsPage}. Can be null. */ - private ISettingsPage mSettingsPage; - - /** - * Constructs a new default {@link SettingsController}. - * - * @param sdkLog A non-null logger to use. - */ - public SettingsController(@NonNull ILogger sdkLog) { - mSdkLog = sdkLog; - mSettings = new Settings(); - } - - /** - * Specialized constructor that wraps an existing {@link Settings} instance. - * This is mostly used in unit-tests to override settings that are being used. - * Normal usage should NOT need to call this constructor. - * - * @param sdkLog A non-null logger to use. - * @param settings A non-null {@link Settings} to use as-is. It is not duplicated. - */ - protected SettingsController(@NonNull ILogger sdkLog, @NonNull Settings settings) { - mSdkLog = sdkLog; - mSettings = settings; - } - - public Settings getSettings() { - return mSettings; - } - - public void registerOnChangedListener(OnChangedListener listener) { - if (listener != null && !mChangedListeners.contains(listener)) { - mChangedListeners.add(listener); - } - } - - public void unregisterOnChangedListener(OnChangedListener listener) { - if (listener != null) { - mChangedListeners.remove(listener); - } - } - - //--- Access to settings ------------ - - - public static class Settings { - private final Properties mProperties; - - /** Initialize an empty set of settings. */ - public Settings() { - mProperties = new Properties(); - } - - /** Duplicates a set of settings. */ - public Settings(Settings settings) { - this(); - for (Entry<Object, Object> entry : settings.mProperties.entrySet()) { - mProperties.put(entry.getKey(), entry.getValue()); - } - } - - /** - * Specialized constructor for unit-tests that wraps an existing - * {@link Properties} instance. The properties instance is not duplicated, - * it's merely used as-is and changes will be reflected directly. - */ - protected Settings(Properties properties) { - mProperties = properties; - } - - /** - * Returns the value of the {@link ISettingsPage#KEY_FORCE_HTTP} setting. - * - * @see ISettingsPage#KEY_FORCE_HTTP - */ - public boolean getForceHttp() { - return Boolean.parseBoolean(mProperties.getProperty(ISettingsPage.KEY_FORCE_HTTP)); - } - - /** - * Returns the value of the {@link ISettingsPage#KEY_ASK_ADB_RESTART} setting. - * - * @see ISettingsPage#KEY_ASK_ADB_RESTART - */ - public boolean getAskBeforeAdbRestart() { - return Boolean.parseBoolean(mProperties.getProperty(ISettingsPage.KEY_ASK_ADB_RESTART)); - } - - /** - * Returns the value of the {@link ISettingsPage#KEY_USE_DOWNLOAD_CACHE} setting. - * - * @see ISettingsPage#KEY_USE_DOWNLOAD_CACHE - */ - public boolean getUseDownloadCache() { - return Boolean.parseBoolean( - mProperties.getProperty( - ISettingsPage.KEY_USE_DOWNLOAD_CACHE, - Boolean.TRUE.toString())); - } - - /** - * Returns the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting. - * - * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY - */ - public boolean getShowUpdateOnly() { - return Boolean.parseBoolean( - mProperties.getProperty( - ISettingsPage.KEY_SHOW_UPDATE_ONLY, - Boolean.TRUE.toString())); - } - - /** - * Returns the value of the {@link ISettingsPage#KEY_ENABLE_PREVIEWS} setting. - * - * @see ISettingsPage#KEY_ENABLE_PREVIEWS - */ - public boolean getEnablePreviews() { - return Boolean.parseBoolean(mProperties.getProperty(ISettingsPage.KEY_ENABLE_PREVIEWS)); - } - - /** - * Returns the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting - * @see ISettingsPage#KEY_MONITOR_DENSITY - */ - public int getMonitorDensity() { - String value = mProperties.getProperty(ISettingsPage.KEY_MONITOR_DENSITY, null); - if (value == null) { - return -1; - } - - try { - return Integer.parseInt(value); - } catch (NumberFormatException e) { - return -1; - } - } - } - - /** - * Sets the value of the {@link ISettingsPage#KEY_SHOW_UPDATE_ONLY} setting. - * - * @param enabled True if only compatible non-obsolete update items should be shown. - * @see ISettingsPage#KEY_SHOW_UPDATE_ONLY - */ - public void setShowUpdateOnly(boolean enabled) { - setSetting(ISettingsPage.KEY_SHOW_UPDATE_ONLY, enabled); - } - - /** - * Sets the value of the {@link ISettingsPage#KEY_MONITOR_DENSITY} setting. - * - * @param density the density of the monitor - * @see ISettingsPage#KEY_MONITOR_DENSITY - */ - public void setMonitorDensity(int density) { - mSettings.mProperties.setProperty( - ISettingsPage.KEY_MONITOR_DENSITY, Integer.toString(density)); - } - - /** - * Internal helper to set a boolean setting. - */ - void setSetting(String key, boolean value) { - mSettings.mProperties.setProperty(key, Boolean.toString(value)); - } - - //--- Controller methods ------------- - - /** - * Associate the given {@link ISettingsPage} with this {@link SettingsController}. - * <p/> - * This loads the current properties into the setting page UI. - * It then associates the SettingsChanged callback with this controller. - * <p/> - * If the setting page given is null, it will be unlinked from controller. - * - * @param settingsPage An {@link ISettingsPage} to associate with the controller. - */ - public void setSettingsPage(ISettingsPage settingsPage) { - mSettingsPage = settingsPage; - - if (settingsPage != null) { - settingsPage.loadSettings(mSettings.mProperties); - - settingsPage.setOnSettingsChanged(new ISettingsPage.SettingsChangedCallback() { - @Override - public void onSettingsChanged(ISettingsPage page) { - SettingsController.this.onSettingsChanged(); - } - }); - } - } - - /** - * Load settings from the settings file. - */ - public void loadSettings() { - FileInputStream fis = null; - String path = null; - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SETTINGS_FILENAME); - path = f.getPath(); - if (f.exists()) { - fis = new FileInputStream(f); - - mSettings.mProperties.load(fis); - - // Properly reformat some settings to enforce their default value when missing. - setShowUpdateOnly(mSettings.getShowUpdateOnly()); - setSetting(ISettingsPage.KEY_ASK_ADB_RESTART, mSettings.getAskBeforeAdbRestart()); - setSetting(ISettingsPage.KEY_USE_DOWNLOAD_CACHE, mSettings.getUseDownloadCache()); - } - - } catch (Exception e) { - if (mSdkLog != null) { - mSdkLog.error(e, - "Failed to load settings from .android folder. Path is '%1$s'.", - path); - } - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - } - } - } - } - - /** - * Saves settings to the settings file. - */ - public void saveSettings() { - - FileOutputStream fos = null; - String path = null; - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SETTINGS_FILENAME); - path = f.getPath(); - - fos = new FileOutputStream(f); - - mSettings.mProperties.store(fos, "## Settings for Android Tool"); //$NON-NLS-1$ - - } catch (Exception e) { - if (mSdkLog != null) { - // This is important enough that we want to really nag the user about it - String reason = null; - - if (e instanceof FileNotFoundException) { - reason = "File not found"; - } else if (e instanceof AndroidLocationException) { - reason = ".android folder not found, please define ANDROID_SDK_HOME"; - } else if (e.getMessage() != null) { - reason = String.format("%1$s: %2$s", - e.getClass().getSimpleName(), - e.getMessage()); - } else { - reason = e.getClass().getName(); - } - - mSdkLog.error(e, "Failed to save settings file '%1$s': %2$s", path, reason); - } - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - } - } - } - } - - /** - * When settings have changed: retrieve the new settings, apply them, save them - * and notify on-settings-changed listeners. - */ - private void onSettingsChanged() { - if (mSettingsPage == null) { - return; - } - - Settings oldSettings = new Settings(mSettings); - mSettingsPage.retrieveSettings(mSettings.mProperties); - applySettings(); - saveSettings(); - - for (OnChangedListener listener : mChangedListeners) { - try { - listener.onSettingsChanged(this, oldSettings); - } catch (Throwable ignore) {} - } - } - - /** - * Applies the current settings. - */ - public void applySettings() { - Properties props = System.getProperties(); - - // Get the configured HTTP proxy settings - String proxyHost = mSettings.mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_HOST, - ""); //$NON-NLS-1$ - String proxyPort = mSettings.mProperties.getProperty(ISettingsPage.KEY_HTTP_PROXY_PORT, - ""); //$NON-NLS-1$ - - // Set both the HTTP and HTTPS proxy system properties. - // The system property constants can be found in the Java SE documentation at - // http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html - final String JAVA_PROP_HTTP_PROXY_HOST = "http.proxyHost"; //$NON-NLS-1$ - final String JAVA_PROP_HTTP_PROXY_PORT = "http.proxyPort"; //$NON-NLS-1$ - final String JAVA_PROP_HTTPS_PROXY_HOST = "https.proxyHost"; //$NON-NLS-1$ - final String JAVA_PROP_HTTPS_PROXY_PORT = "https.proxyPort"; //$NON-NLS-1$ - - // Only change the proxy if have something in the preferences. - // Do not erase the default settings by empty values. - if (proxyHost != null && proxyHost.length() > 0) { - props.setProperty(JAVA_PROP_HTTP_PROXY_HOST, proxyHost); - props.setProperty(JAVA_PROP_HTTPS_PROXY_HOST, proxyHost); - } - if (proxyPort != null && proxyPort.length() > 0) { - props.setProperty(JAVA_PROP_HTTP_PROXY_PORT, proxyPort); - props.setProperty(JAVA_PROP_HTTPS_PROXY_PORT, proxyPort); - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsDialog.java deleted file mode 100755 index 7f44b7c..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/SettingsDialog.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.DownloadCache.Strategy; -import com.android.sdklib.util.FormatUtils; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -import java.util.Properties; - - -public class SettingsDialog extends UpdaterBaseDialog implements ISettingsPage { - - - // data members - private final DownloadCache mDownloadCache = new DownloadCache(Strategy.SERVE_CACHE); - private final SettingsController mSettingsController; - private SettingsChangedCallback mSettingsChangedCallback; - - // UI widgets - private Text mTextProxyServer; - private Text mTextProxyPort; - private Text mTextCacheSize; - private Button mCheckUseCache; - private Button mCheckForceHttp; - private Button mCheckAskAdbRestart; - private Button mCheckEnablePreviews; - - private SelectionAdapter mApplyOnSelected = new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - applyNewSettings(); //$hide$ - } - }; - - private ModifyListener mApplyOnModified = new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - applyNewSettings(); //$hide$ - } - }; - - public SettingsDialog(Shell parentShell, UpdaterData updaterData) { - super(parentShell, updaterData, "Settings" /*title*/); - assert updaterData != null; - mSettingsController = updaterData.getSettingsController(); - } - - @Override - protected void createContents() { - super.createContents(); - Shell shell = getShell(); - - Group group = new Group(shell, SWT.NONE); - group.setText("Proxy Settings"); - GridDataBuilder.create(group).fill().grab().hSpan(2); - GridLayoutBuilder.create(group).columns(2); - - Label label = new Label(group, SWT.NONE); - GridDataBuilder.create(label).hRight().vCenter(); - label.setText("HTTP Proxy Server"); - String tooltip = "The hostname or IP of the HTTP & HTTPS proxy server to use (e.g. proxy.example.com).\n" + - "When empty, the default Java proxy setting is used."; - label.setToolTipText(tooltip); - - mTextProxyServer = new Text(group, SWT.BORDER); - GridDataBuilder.create(mTextProxyServer).hFill().hGrab().vCenter(); - mTextProxyServer.addModifyListener(mApplyOnModified); - mTextProxyServer.setToolTipText(tooltip); - - label = new Label(group, SWT.NONE); - GridDataBuilder.create(label).hRight().vCenter(); - label.setText("HTTP Proxy Port"); - tooltip = "The port of the HTTP & HTTPS proxy server to use (e.g. 3128).\n" + - "When empty, the default Java proxy setting is used."; - label.setToolTipText(tooltip); - - mTextProxyPort = new Text(group, SWT.BORDER); - GridDataBuilder.create(mTextProxyPort).hFill().hGrab().vCenter(); - mTextProxyPort.addModifyListener(mApplyOnModified); - mTextProxyPort.setToolTipText(tooltip); - - // ---- - group = new Group(shell, SWT.NONE); - group.setText("Manifest Cache"); - GridDataBuilder.create(group).fill().grab().hSpan(2); - GridLayoutBuilder.create(group).columns(3); - - label = new Label(group, SWT.NONE); - GridDataBuilder.create(label).hRight().vCenter(); - label.setText("Directory:"); - - Text text = new Text(group, SWT.NONE); - GridDataBuilder.create(text).hFill().hGrab().vCenter().hSpan(2); - text.setEnabled(false); - text.setText(mDownloadCache.getCacheRoot().getAbsolutePath()); - - label = new Label(group, SWT.NONE); - GridDataBuilder.create(label).hRight().vCenter(); - label.setText("Current Size:"); - - mTextCacheSize = new Text(group, SWT.NONE); - GridDataBuilder.create(mTextCacheSize).hFill().hGrab().vCenter().hSpan(2); - mTextCacheSize.setEnabled(false); - updateDownloadCacheSize(); - - mCheckUseCache = new Button(group, SWT.CHECK); - GridDataBuilder.create(mCheckUseCache).vCenter().hSpan(1); - mCheckUseCache.setText("Use download cache"); - mCheckUseCache.setToolTipText("When checked, small manifest files are cached locally.\n" + - "Large binary files are never cached locally."); - mCheckUseCache.addSelectionListener(mApplyOnSelected); - - label = new Label(group, SWT.NONE); - GridDataBuilder.create(label).hFill().hGrab().hSpan(1); - - Button button = new Button(group, SWT.PUSH); - GridDataBuilder.create(button).vCenter().hSpan(1); - button.setText("Clear Cache"); - button.setToolTipText("Deletes all cached files."); - button.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - mDownloadCache.clearCache(); - updateDownloadCacheSize(); - } - }); - - // ---- - group = new Group(shell, SWT.NONE); - group.setText("Others"); - GridDataBuilder.create(group).fill().grab().hSpan(2); - GridLayoutBuilder.create(group).columns(2); - - mCheckForceHttp = new Button(group, SWT.CHECK); - GridDataBuilder.create(mCheckForceHttp).hFill().hGrab().vCenter().hSpan(2); - mCheckForceHttp.setText("Force https://... sources to be fetched using http://..."); - mCheckForceHttp.setToolTipText( - "If you are not able to connect to the official Android repository using HTTPS,\n" + - "enable this setting to force accessing it via HTTP."); - mCheckForceHttp.addSelectionListener(mApplyOnSelected); - - mCheckAskAdbRestart = new Button(group, SWT.CHECK); - GridDataBuilder.create(mCheckAskAdbRestart).hFill().hGrab().vCenter().hSpan(2); - mCheckAskAdbRestart.setText("Ask before restarting ADB"); - mCheckAskAdbRestart.setToolTipText( - "When checked, the user will be asked for permission to restart ADB\n" + - "after updating an addon-on package or a tool package."); - mCheckAskAdbRestart.addSelectionListener(mApplyOnSelected); - - mCheckEnablePreviews = new Button(group, SWT.CHECK); - GridDataBuilder.create(mCheckEnablePreviews).hFill().hGrab().vCenter().hSpan(2); - mCheckEnablePreviews.setText("Enable Preview Tools"); - mCheckEnablePreviews.setToolTipText( - "When checked, the package list will also display preview versions of the tools.\n" + - "These are optional future release candidates that the Android tools team\n" + - "publishes from time to time for early feedback."); - mCheckEnablePreviews.addSelectionListener(mApplyOnSelected); - - Label filler = new Label(shell, SWT.NONE); - GridDataBuilder.create(filler).hFill().hGrab(); - - createCloseButton(); - } - - @Override - protected void postCreate() { - super.postCreate(); - // This tells the controller to load the settings into the page UI. - mSettingsController.setSettingsPage(this); - } - - @Override - protected void close() { - // Dissociate this page from the controller - mSettingsController.setSettingsPage(null); - super.close(); - } - - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - /** Loads settings from the given {@link Properties} container and update the page UI. */ - @Override - public void loadSettings(Properties inSettings) { - mTextProxyServer.setText(inSettings.getProperty(KEY_HTTP_PROXY_HOST, "")); //$NON-NLS-1$ - mTextProxyPort.setText( inSettings.getProperty(KEY_HTTP_PROXY_PORT, "")); //$NON-NLS-1$ - mCheckForceHttp.setSelection( - Boolean.parseBoolean(inSettings.getProperty(KEY_FORCE_HTTP))); - mCheckAskAdbRestart.setSelection( - Boolean.parseBoolean(inSettings.getProperty(KEY_ASK_ADB_RESTART))); - mCheckUseCache.setSelection( - Boolean.parseBoolean(inSettings.getProperty(KEY_USE_DOWNLOAD_CACHE))); - mCheckEnablePreviews.setSelection( - Boolean.parseBoolean(inSettings.getProperty(KEY_ENABLE_PREVIEWS))); - - } - - /** Called by the application to retrieve settings from the UI and store them in - * the given {@link Properties} container. */ - @Override - public void retrieveSettings(Properties outSettings) { - outSettings.setProperty(KEY_HTTP_PROXY_HOST, mTextProxyServer.getText()); - outSettings.setProperty(KEY_HTTP_PROXY_PORT, mTextProxyPort.getText()); - outSettings.setProperty(KEY_FORCE_HTTP, - Boolean.toString(mCheckForceHttp.getSelection())); - outSettings.setProperty(KEY_ASK_ADB_RESTART, - Boolean.toString(mCheckAskAdbRestart.getSelection())); - outSettings.setProperty(KEY_USE_DOWNLOAD_CACHE, - Boolean.toString(mCheckUseCache.getSelection())); - outSettings.setProperty(KEY_ENABLE_PREVIEWS, - Boolean.toString(mCheckEnablePreviews.getSelection())); - - } - - /** - * Called by the application to give a callback that the page should invoke when - * settings must be applied. The page does not apply the settings itself, instead - * it notifies the application. - */ - @Override - public void setOnSettingsChanged(SettingsChangedCallback settingsChangedCallback) { - mSettingsChangedCallback = settingsChangedCallback; - } - - /** - * Callback invoked when user touches one of the settings. - * There is no "Apply" button, settings are applied immediately as they are changed. - * Notify the application that settings have changed. - */ - private void applyNewSettings() { - if (mSettingsChangedCallback != null) { - mSettingsChangedCallback.onSettingsChanged(this); - } - } - - private void updateDownloadCacheSize() { - long size = mDownloadCache.getCurrentSize(); - String str = FormatUtils.byteSizeToString(size); - mTextCacheSize.setText(str); - } - - - // End of hiding from SWT Designer - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterBaseDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterBaseDialog.java deleted file mode 100755 index 7752838..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterBaseDialog.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.SdkConstants; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.internal.repository.ui.SdkUpdaterWindowImpl2; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; -import com.android.sdkuilib.ui.SwtBaseDialog; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Shell; - - - -/** - * Base class for auxiliary dialogs shown in the updater (for example settings, - * about box or add-on site.) - */ -public abstract class UpdaterBaseDialog extends SwtBaseDialog { - - private final UpdaterData mUpdaterData; - - protected UpdaterBaseDialog(Shell parentShell, UpdaterData updaterData, String title) { - super(parentShell, - SWT.APPLICATION_MODAL, - String.format("%1$s - %2$s", SdkUpdaterWindowImpl2.APP_NAME, title)); //$NON-NLS-1$ - mUpdaterData = updaterData; - } - - public UpdaterData getUpdaterData() { - return mUpdaterData; - } - - /** - * Initializes the shell with a 2-column Grid layout. - * Caller should use {@link #createCloseButton()} to inject the - * close button at the bottom of the dialog. - */ - @Override - protected void createContents() { - Shell shell = getShell(); - setWindowImage(shell); - - GridLayoutBuilder.create(shell).columns(2); - - } - - protected void createCloseButton() { - Button close = new Button(getShell(), SWT.PUSH); - close.setText("Close"); - GridDataBuilder.create(close).hFill().vBottom(); - close.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - close(); - } - }); - } - - @Override - protected void postCreate() { - // pass - } - - @Override - protected void close() { - super.close(); - } - - /** - * Creates the icon of the window shell. - * - * @param shell The shell on which to put the icon - */ - private void setWindowImage(Shell shell) { - String imageName = "android_icon_16.png"; //$NON-NLS-1$ - if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_DARWIN) { - imageName = "android_icon_128.png"; //$NON-NLS-1$ - } - - if (mUpdaterData != null) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - shell.setImage(imgFactory.getImageByName(imageName)); - } - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java deleted file mode 100755 index 7fc1b1e..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java +++ /dev/null @@ -1,1159 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.SdkConstants; -import com.android.annotations.VisibleForTesting; -import com.android.annotations.VisibleForTesting.Visibility; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.repository.AdbWrapper; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.LocalSdkParser; -import com.android.sdklib.internal.repository.NullTaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.ArchiveInstaller; -import com.android.sdklib.internal.repository.packages.AddonPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.sdklib.internal.repository.sources.SdkRepoSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.internal.repository.sources.SdkSourceCategory; -import com.android.sdklib.internal.repository.sources.SdkSources; -import com.android.sdklib.repository.SdkAddonConstants; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.sdklib.util.LineUtil; -import com.android.sdklib.util.SparseIntArray; -import com.android.sdkuilib.internal.repository.SettingsController.OnChangedListener; -import com.android.sdkuilib.internal.repository.core.PackageLoader; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.internal.repository.ui.SdkUpdaterWindowImpl2; -import com.android.sdkuilib.repository.ISdkChangeListener; -import com.android.utils.ILogger; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.widgets.Shell; - -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Data shared between {@link SdkUpdaterWindowImpl2} and its pages. - */ -public class UpdaterData implements IUpdaterData { - - public static final int NO_TOOLS_MSG = 0; - public static final int TOOLS_MSG_UPDATED_FROM_ADT = 1; - public static final int TOOLS_MSG_UPDATED_FROM_SDKMAN = 2; - - private String mOsSdkRoot; - - private final LocalSdkParser mLocalSdkParser = new LocalSdkParser(); - /** Holds all sources. Do not use this directly. - * Instead use {@link #getSources()} so that unit tests can override this as needed. */ - private final SdkSources mSources = new SdkSources(); - /** Holds settings. Do not use this directly. - * Instead use {@link #getSettingsController()} so that unit tests can override this. */ - private final SettingsController mSettingsController; - private final ArrayList<ISdkChangeListener> mListeners = new ArrayList<ISdkChangeListener>(); - private final ILogger mSdkLog; - private ITaskFactory mTaskFactory; - private Shell mWindowShell; - private SdkManager mSdkManager; - private AvdManager mAvdManager; - /** - * The current {@link PackageLoader} to use. - * Lazily created in {@link #getPackageLoader()}. - */ - private PackageLoader mPackageLoader; - /** - * The current {@link DownloadCache} to use. - * Lazily created in {@link #getDownloadCache()}. - */ - private DownloadCache mDownloadCache; - /** - * The current {@link ImageFactory}. - * Set via {@link #setImageFactory(ImageFactory)} by the window implementation. - * It is null when invoked using the command-line interface. - */ - private ImageFactory mImageFactory; - private AndroidLocationException mAvdManagerInitError; - - /** - * Creates a new updater data. - * - * @param sdkLog Logger. Cannot be null. - * @param osSdkRoot The OS path to the SDK root. - */ - public UpdaterData(String osSdkRoot, ILogger sdkLog) { - mOsSdkRoot = osSdkRoot; - mSdkLog = sdkLog; - - - mSettingsController = initSettingsController(); - initSdk(); - } - - // ----- getters, setters ---- - - public String getOsSdkRoot() { - return mOsSdkRoot; - } - - @Override - public DownloadCache getDownloadCache() { - if (mDownloadCache == null) { - mDownloadCache = new DownloadCache( - getSettingsController().getSettings().getUseDownloadCache() ? - DownloadCache.Strategy.FRESH_CACHE : - DownloadCache.Strategy.DIRECT); - } - return mDownloadCache; - } - - public void setTaskFactory(ITaskFactory taskFactory) { - mTaskFactory = taskFactory; - } - - @Override - public ITaskFactory getTaskFactory() { - return mTaskFactory; - } - - public SdkSources getSources() { - return mSources; - } - - public LocalSdkParser getLocalSdkParser() { - return mLocalSdkParser; - } - - @Override - public ILogger getSdkLog() { - return mSdkLog; - } - - public void setImageFactory(ImageFactory imageFactory) { - mImageFactory = imageFactory; - } - - @Override - public ImageFactory getImageFactory() { - return mImageFactory; - } - - @Override - public SdkManager getSdkManager() { - return mSdkManager; - } - - @Override - public AvdManager getAvdManager() { - return mAvdManager; - } - - @Override - public SettingsController getSettingsController() { - return mSettingsController; - } - - /** Adds a listener ({@link ISdkChangeListener}) that is notified when the SDK is reloaded. */ - public void addListeners(ISdkChangeListener listener) { - if (mListeners.contains(listener) == false) { - mListeners.add(listener); - } - } - - /** Removes a listener ({@link ISdkChangeListener}) that is notified when the SDK is reloaded. */ - public void removeListener(ISdkChangeListener listener) { - mListeners.remove(listener); - } - - public void setWindowShell(Shell windowShell) { - mWindowShell = windowShell; - } - - @Override - public Shell getWindowShell() { - return mWindowShell; - } - - public PackageLoader getPackageLoader() { - // The package loader is lazily initialized here. - if (mPackageLoader == null) { - mPackageLoader = new PackageLoader(this); - } - return mPackageLoader; - } - - /** - * Check if any error occurred during initialization. - * If it did, display an error message. - * - * @return True if an error occurred, false if we should continue. - */ - public boolean checkIfInitFailed() { - if (mAvdManagerInitError != null) { - String example; - if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_WINDOWS) { - example = "%USERPROFILE%"; //$NON-NLS-1$ - } else { - example = "~"; //$NON-NLS-1$ - } - - String error = String.format( - "The AVD manager normally uses the user's profile directory to store " + - "AVD files. However it failed to find the default profile directory. " + - "\n" + - "To fix this, please set the environment variable ANDROID_SDK_HOME to " + - "a valid path such as \"%s\".", - example); - - // We may not have any UI. Only display a dialog if there's a window shell available. - if (mWindowShell != null && !mWindowShell.isDisposed()) { - MessageDialog.openError(mWindowShell, - "Android Virtual Devices Manager", - error); - } else { - mSdkLog.error(null /* Throwable */, "%s", error); //$NON-NLS-1$ - } - - return true; - } - return false; - } - - // ----- - - /** - * Initializes the {@link SdkManager} and the {@link AvdManager}. - * Extracted so that we can override this in unit tests. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected void initSdk() { - setSdkManager(SdkManager.createManager(mOsSdkRoot, mSdkLog)); - try { - mAvdManager = null; - mAvdManager = AvdManager.getInstance(mSdkManager, mSdkLog); - } catch (AndroidLocationException e) { - mSdkLog.error(e, "Unable to read AVDs: " + e.getMessage()); //$NON-NLS-1$ - - // Note: we used to continue here, but the thing is that - // mAvdManager==null so nothing is really going to work as - // expected. Let's just display an error later in checkIfInitFailed() - // and abort right there. This step is just too early in the SWT - // setup process to display a message box yet. - - mAvdManagerInitError = e; - } - - // notify listeners. - broadcastOnSdkReload(); - } - - /** - * Initializes the {@link SettingsController} - * Extracted so that we can override this in unit tests. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected SettingsController initSettingsController() { - SettingsController settingsController = new SettingsController(mSdkLog); - settingsController.registerOnChangedListener(new OnChangedListener() { - @Override - public void onSettingsChanged( - SettingsController controller, - SettingsController.Settings oldSettings) { - - // Reset the download cache if it doesn't match the right strategy. - // The cache instance gets lazily recreated later in getDownloadCache(). - if (mDownloadCache != null) { - if (controller.getSettings().getUseDownloadCache() && - mDownloadCache.getStrategy() != DownloadCache.Strategy.FRESH_CACHE) { - mDownloadCache = null; - } else if (!controller.getSettings().getUseDownloadCache() && - mDownloadCache.getStrategy() != DownloadCache.Strategy.DIRECT) { - mDownloadCache = null; - } - } - } - }); - return settingsController; - } - - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected void setSdkManager(SdkManager sdkManager) { - mSdkManager = sdkManager; - } - - /** - * Reloads the SDK content (targets). - * <p/> - * This also reloads the AVDs in case their status changed. - * <p/> - * This does not notify the listeners ({@link ISdkChangeListener}). - */ - public void reloadSdk() { - // reload SDK - mSdkManager.reloadSdk(mSdkLog); - - // reload AVDs - if (mAvdManager != null) { - try { - mAvdManager.reloadAvds(mSdkLog); - } catch (AndroidLocationException e) { - // FIXME - } - } - - mLocalSdkParser.clearPackages(); - - // notify listeners - broadcastOnSdkReload(); - } - - /** - * Reloads the AVDs. - * <p/> - * This does not notify the listeners. - */ - public void reloadAvds() { - // reload AVDs - if (mAvdManager != null) { - try { - mAvdManager.reloadAvds(mSdkLog); - } catch (AndroidLocationException e) { - mSdkLog.error(e, null); - } - } - } - - /** - * Sets up the default sources: <br/> - * - the default google SDK repository, <br/> - * - the user sources from prefs <br/> - * - the extra repo URLs from the environment, <br/> - * - and finally the extra user repo URLs from the environment. - */ - public void setupDefaultSources() { - SdkSources sources = getSources(); - - // Load the conventional sources. - // For testing, the env var can be set to replace the default root download URL. - // It must end with a / and its the location where the updater will look for - // the repository.xml, addons_list.xml and such files. - - String baseUrl = System.getenv("SDK_TEST_BASE_URL"); //$NON-NLS-1$ - if (baseUrl == null || baseUrl.length() <= 0 || !baseUrl.endsWith("/")) { //$NON-NLS-1$ - baseUrl = SdkRepoConstants.URL_GOOGLE_SDK_SITE; - } - - sources.add(SdkSourceCategory.ANDROID_REPO, - new SdkRepoSource(baseUrl, - SdkSourceCategory.ANDROID_REPO.getUiName())); - - // Load user sources (this will also notify change listeners but this operation is - // done early enough that there shouldn't be any anyway.) - sources.loadUserAddons(getSdkLog()); - } - - /** - * Returns the list of installed packages, parsing them if this has not yet been done. - * <p/> - * The package list is cached in the {@link LocalSdkParser} and will be reset when - * {@link #reloadSdk()} is invoked. - */ - public Package[] getInstalledPackages(ITaskMonitor monitor) { - LocalSdkParser parser = getLocalSdkParser(); - - Package[] packages = parser.getPackages(); - - if (packages == null) { - // load on demand the first time - packages = parser.parseSdk(getOsSdkRoot(), getSdkManager(), monitor); - } - - return packages; - } - /** - * Install the list of given {@link Archive}s. This is invoked by the user selecting some - * packages in the remote page and then clicking "install selected". - * - * @param archives The archives to install. Incompatible ones will be skipped. - * @param flags Optional flags for the installer, such as {@link #NO_TOOLS_MSG}. - * @return A list of archives that have been installed. Can be empty but not null. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected List<Archive> installArchives(final List<ArchiveInfo> archives, final int flags) { - if (mTaskFactory == null) { - throw new IllegalArgumentException("Task Factory is null"); - } - - // this will accumulate all the packages installed. - final List<Archive> newlyInstalledArchives = new ArrayList<Archive>(); - - final boolean forceHttp = getSettingsController().getSettings().getForceHttp(); - - // sort all archives based on their dependency level. - Collections.sort(archives, new InstallOrderComparator()); - - mTaskFactory.start("Installing Archives", new ITask() { - @Override - public void run(ITaskMonitor monitor) { - - final int progressPerArchive = 2 * ArchiveInstaller.NUM_MONITOR_INC; - monitor.setProgressMax(1 + archives.size() * progressPerArchive); - monitor.setDescription("Preparing to install archives"); - - boolean installedAddon = false; - boolean installedTools = false; - boolean installedPlatformTools = false; - boolean preInstallHookInvoked = false; - - // Mark all current local archives as already installed. - HashSet<Archive> installedArchives = new HashSet<Archive>(); - for (Package p : getInstalledPackages(monitor.createSubMonitor(1))) { - for (Archive a : p.getArchives()) { - installedArchives.add(a); - } - } - - int numInstalled = 0; - nextArchive: for (ArchiveInfo ai : archives) { - Archive archive = ai.getNewArchive(); - if (archive == null) { - // This is not supposed to happen. - continue nextArchive; - } - - int nextProgress = monitor.getProgress() + progressPerArchive; - try { - if (monitor.isCancelRequested()) { - break; - } - - ArchiveInfo[] adeps = ai.getDependsOn(); - if (adeps != null) { - for (ArchiveInfo adep : adeps) { - Archive na = adep.getNewArchive(); - if (na == null) { - // This archive depends on a missing archive. - // We shouldn't get here. - // Skip it. - monitor.log("Skipping '%1$s'; it depends on a missing package.", - archive.getParentPackage().getShortDescription()); - continue nextArchive; - } else if (!installedArchives.contains(na)) { - // This archive depends on another one that was not installed. - // We shouldn't get here. - // Skip it. - monitor.logError("Skipping '%1$s'; it depends on '%2$s' which was not installed.", - archive.getParentPackage().getShortDescription(), - adep.getShortDescription()); - continue nextArchive; - } - } - } - - if (!preInstallHookInvoked) { - preInstallHookInvoked = true; - broadcastPreInstallHook(); - } - - ArchiveInstaller installer = createArchiveInstaler(); - if (installer.install(ai, - mOsSdkRoot, - forceHttp, - mSdkManager, - getDownloadCache(), - monitor)) { - // We installed this archive. - newlyInstalledArchives.add(archive); - installedArchives.add(archive); - numInstalled++; - - // If this package was replacing an existing one, the old one - // is no longer installed. - installedArchives.remove(ai.getReplaced()); - - // Check if we successfully installed a platform-tool or add-on package. - if (archive.getParentPackage() instanceof AddonPackage) { - installedAddon = true; - } else if (archive.getParentPackage() instanceof ToolPackage) { - installedTools = true; - } else if (archive.getParentPackage() instanceof PlatformToolPackage) { - installedPlatformTools = true; - } - } - - } catch (Throwable t) { - // Display anything unexpected in the monitor. - String msg = t.getMessage(); - if (msg != null) { - msg = String.format("Unexpected Error installing '%1$s': %2$s: %3$s", - archive.getParentPackage().getShortDescription(), - t.getClass().getCanonicalName(), msg); - } else { - // no error info? get the stack call to display it - // At least that'll give us a better bug report. - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - t.printStackTrace(new PrintStream(baos)); - - msg = String.format("Unexpected Error installing '%1$s'\n%2$s", - archive.getParentPackage().getShortDescription(), - baos.toString()); - } - - monitor.log( "%1$s", msg); //$NON-NLS-1$ - mSdkLog.error(t, "%1$s", msg); //$NON-NLS-1$ - } finally { - - // Always move the progress bar to the desired position. - // This allows internal methods to not have to care in case - // they abort early - monitor.incProgress(nextProgress - monitor.getProgress()); - } - } - - if (installedAddon) { - // Update the USB vendor ids for adb - try { - mSdkManager.updateAdb(); - monitor.log("Updated ADB to support the USB devices declared in the SDK add-ons."); - } catch (Exception e) { - mSdkLog.error(e, "Update ADB failed"); - monitor.logError("failed to update adb to support the USB devices declared in the SDK add-ons."); - } - } - - if (preInstallHookInvoked) { - broadcastPostInstallHook(); - } - - if (installedAddon || installedPlatformTools) { - // We need to restart ADB. Actually since we don't know if it's even - // running, maybe we should just kill it and not start it. - // Note: it turns out even under Windows we don't need to kill adb - // before updating the tools folder, as adb.exe is (surprisingly) not - // locked. - - askForAdbRestart(monitor); - } - - if (installedTools) { - notifyToolsNeedsToBeRestarted(flags); - } - - if (numInstalled == 0) { - monitor.setDescription("Done. Nothing was installed."); - } else { - monitor.setDescription("Done. %1$d %2$s installed.", - numInstalled, - numInstalled == 1 ? "package" : "packages"); - - //notify listeners something was installed, so that they can refresh - reloadSdk(); - } - } - }); - - return newlyInstalledArchives; - } - - /** - * A comparator to sort all the {@link ArchiveInfo} based on their - * dependency level. This forces the installer to install first all packages - * with no dependency, then those with one level of dependency, etc. - */ - private static class InstallOrderComparator implements Comparator<ArchiveInfo> { - - private final Map<ArchiveInfo, Integer> mOrders = new HashMap<ArchiveInfo, Integer>(); - - @Override - public int compare(ArchiveInfo o1, ArchiveInfo o2) { - int n1 = getDependencyOrder(o1); - int n2 = getDependencyOrder(o2); - - return n1 - n2; - } - - private int getDependencyOrder(ArchiveInfo ai) { - if (ai == null) { - return 0; - } - - // reuse cached value, if any - Integer cached = mOrders.get(ai); - if (cached != null) { - return cached.intValue(); - } - - ArchiveInfo[] deps = ai.getDependsOn(); - if (deps == null) { - return 0; - } - - // compute dependencies, recursively - int n = deps.length; - - for (ArchiveInfo dep : deps) { - n += getDependencyOrder(dep); - } - - // cache it - mOrders.put(ai, Integer.valueOf(n)); - - return n; - } - - } - - /** - * Attempts to restart ADB. - * <p/> - * If the "ask before restart" setting is set (the default), prompt the user whether - * now is a good time to restart ADB. - * - * @param monitor - */ - private void askForAdbRestart(ITaskMonitor monitor) { - final boolean[] canRestart = new boolean[] { true }; - - if (getWindowShell() != null && - getSettingsController().getSettings().getAskBeforeAdbRestart()) { - // need to ask for permission first - final Shell shell = getWindowShell(); - if (shell != null && !shell.isDisposed()) { - shell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!shell.isDisposed()) { - canRestart[0] = MessageDialog.openQuestion(shell, - "ADB Restart", - "A package that depends on ADB has been updated. \n" + - "Do you want to restart ADB now?"); - } - } - }); - } - } - - if (canRestart[0]) { - AdbWrapper adb = new AdbWrapper(getOsSdkRoot(), monitor); - adb.stopAdb(); - adb.startAdb(); - } - } - - private void notifyToolsNeedsToBeRestarted(int flags) { - - String msg = null; - if ((flags & TOOLS_MSG_UPDATED_FROM_ADT) != 0) { - msg = - "The Android SDK and AVD Manager that you are currently using has been updated. " + - "Please also run Eclipse > Help > Check for Updates to see if the Android " + - "plug-in needs to be updated."; - - } else if ((flags & TOOLS_MSG_UPDATED_FROM_SDKMAN) != 0) { - msg = - "The Android SDK and AVD Manager that you are currently using has been updated. " + - "It is recommended that you now close the manager window and re-open it. " + - "If you use Eclipse, please run Help > Check for Updates to see if the Android " + - "plug-in needs to be updated."; - } - - final String msg2 = msg; - - final Shell shell = getWindowShell(); - if (msg2 != null && shell != null && !shell.isDisposed()) { - shell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!shell.isDisposed()) { - MessageDialog.openInformation(shell, - "Android Tools Updated", - msg2); - } - } - }); - } - } - - - /** - * Tries to update all the *existing* local packages. - * This version *requires* to be run with a GUI. - * <p/> - * There are two modes of operation: - * <ul> - * <li>If selectedArchives is null, refreshes all sources, compares the available remote - * packages with the current local ones and suggest updates to be done to the user (including - * new platforms that the users doesn't have yet). - * <li>If selectedArchives is not null, this represents a list of archives/packages that - * the user wants to install or update, so just process these. - * </ul> - * - * @param selectedArchives The list of remote archives to consider for the update. - * This can be null, in which case a list of remote archive is fetched from all - * available sources. - * @param includeObsoletes True if obsolete packages should be used when resolving what - * to update. - * @param flags Optional flags for the installer, such as {@link #NO_TOOLS_MSG}. - * @return A list of archives that have been installed. Can be null if nothing was done. - */ - public List<Archive> updateOrInstallAll_WithGUI( - Collection<Archive> selectedArchives, - boolean includeObsoletes, - int flags) { - - // Note: we no longer call refreshSources(true) here. This will be done - // automatically by computeUpdates() iif it needs to access sources to - // resolve missing dependencies. - - SdkUpdaterLogic ul = new SdkUpdaterLogic(this); - List<ArchiveInfo> archives = ul.computeUpdates( - selectedArchives, - getSources(), - getLocalSdkParser().getPackages(), - includeObsoletes); - - if (selectedArchives == null) { - getPackageLoader().loadRemoteAddonsList(new NullTaskMonitor(getSdkLog())); - ul.addNewPlatforms( - archives, - getSources(), - getLocalSdkParser().getPackages(), - includeObsoletes); - } - - // TODO if selectedArchives is null and archives.len==0, find if there are - // any new platform we can suggest to install instead. - - Collections.sort(archives); - - SdkUpdaterChooserDialog dialog = - new SdkUpdaterChooserDialog(getWindowShell(), this, archives); - dialog.open(); - - ArrayList<ArchiveInfo> result = dialog.getResult(); - if (result != null && result.size() > 0) { - return installArchives(result, flags); - } - return null; - } - - /** - * Fetches all archives available on the known remote sources. - * - * Used by {@link UpdaterData#listRemotePackages_NoGUI} and - * {@link UpdaterData#updateOrInstallAll_NoGUI}. - * - * @param includeAll True to list and install all packages, including obsolete ones. - * @return A list of potential {@link ArchiveInfo} to install. - */ - private List<ArchiveInfo> getRemoteArchives_NoGUI(boolean includeAll) { - refreshSources(true); - getPackageLoader().loadRemoteAddonsList(new NullTaskMonitor(getSdkLog())); - - List<ArchiveInfo> archives; - SdkUpdaterLogic ul = new SdkUpdaterLogic(this); - - if (includeAll) { - archives = ul.getAllRemoteArchives( - getSources(), - getLocalSdkParser().getPackages(), - includeAll); - - } else { - archives = ul.computeUpdates( - null /*selectedArchives*/, - getSources(), - getLocalSdkParser().getPackages(), - includeAll); - - ul.addNewPlatforms( - archives, - getSources(), - getLocalSdkParser().getPackages(), - includeAll); - } - - Collections.sort(archives); - return archives; - } - - /** - * Lists remote packages available for install using - * {@link UpdaterData#updateOrInstallAll_NoGUI}. - * - * @param includeAll True to list and install all packages, including obsolete ones. - * @param extendedOutput True to display more details on each package. - */ - public void listRemotePackages_NoGUI(boolean includeAll, boolean extendedOutput) { - - List<ArchiveInfo> archives = getRemoteArchives_NoGUI(includeAll); - - mSdkLog.info("Packages available for installation or update: %1$d\n", archives.size()); - - int index = 1; - for (ArchiveInfo ai : archives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p != null) { - if (extendedOutput) { - mSdkLog.info("----------\n"); - mSdkLog.info("id: %1$d or \"%2$s\"\n", index, p.installId()); - mSdkLog.info(" Type: %1$s\n", - p.getClass().getSimpleName().replaceAll("Package", "")); //$NON-NLS-1$ //$NON-NLS-2$ - String desc = LineUtil.reformatLine(" Desc: %s\n", - p.getLongDescription()); - mSdkLog.info("%s", desc); //$NON-NLS-1$ - } else { - mSdkLog.info("%1$ 4d- %2$s\n", - index, - p.getShortDescription()); - } - index++; - } - } - } - } - - /** - * Tries to update all the *existing* local packages. - * This version is intended to run without a GUI and - * only outputs to the current {@link ILogger}. - * - * @param pkgFilter A list of {@link SdkRepoConstants#NODES} or {@link Package#installId()} - * or package indexes to limit the packages we can update or install. - * A null or empty list means to update everything possible. - * @param includeAll True to list and install all packages, including obsolete ones. - * @param dryMode True to check what would be updated/installed but do not actually - * download or install anything. - * @return A list of archives that have been installed. Can be null if nothing was done. - */ - public List<Archive> updateOrInstallAll_NoGUI( - Collection<String> pkgFilter, - boolean includeAll, - boolean dryMode) { - - List<ArchiveInfo> archives = getRemoteArchives_NoGUI(includeAll); - - // Filter the selected archives to only keep the ones matching the filter - if (pkgFilter != null && pkgFilter.size() > 0 && archives != null && archives.size() > 0) { - // Map filter types to an SdkRepository Package type, - // e.g. create a map "platform" => PlatformPackage.class - HashMap<String, Class<? extends Package>> pkgMap = - new HashMap<String, Class<? extends Package>>(); - - mapFilterToPackageClass(pkgMap, SdkRepoConstants.NODES); - mapFilterToPackageClass(pkgMap, SdkAddonConstants.NODES); - - // Prepare a map install-id => package instance - HashMap<String, Package> installIdMap = new HashMap<String, Package>(); - for (ArchiveInfo ai : archives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p != null) { - String id = p.installId(); - if (id != null && id.length() > 0 && !installIdMap.containsKey(id)) { - installIdMap.put(id, p); - } - } - } - } - - // Now intersect this with the pkgFilter requested by the user, in order to - // only keep the classes that the user wants to install. - // We also create a set with the package indices requested by the user - // and a set of install-ids requested by the user. - - HashSet<Class<? extends Package>> userFilteredClasses = - new HashSet<Class<? extends Package>>(); - SparseIntArray userFilteredIndices = new SparseIntArray(); - Set<String> userFilteredInstallIds = new HashSet<String>(); - - for (String type : pkgFilter) { - if (installIdMap.containsKey(type)) { - userFilteredInstallIds.add(type); - - } else if (type.replaceAll("[0-9]+", "").length() == 0) {//$NON-NLS-1$ //$NON-NLS-2$ - // An all-digit number is a package index requested by the user. - int index = Integer.parseInt(type); - userFilteredIndices.put(index, index); - - } else if (pkgMap.containsKey(type)) { - userFilteredClasses.add(pkgMap.get(type)); - - } else { - // This should not happen unless there's a mismatch in the package map. - mSdkLog.error(null, "Ignoring unknown package filter '%1$s'", type); - } - } - - // we don't need the maps anymore - pkgMap = null; - installIdMap = null; - - // Now filter the remote archives list to keep: - // - any package which class matches userFilteredClasses - // - any package index which matches userFilteredIndices - // - any package install id which matches userFilteredInstallIds - - int index = 1; - for (Iterator<ArchiveInfo> it = archives.iterator(); it.hasNext(); ) { - boolean keep = false; - ArchiveInfo ai = it.next(); - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p != null) { - if (userFilteredInstallIds.contains(p.installId()) || - userFilteredClasses.contains(p.getClass()) || - userFilteredIndices.get(index) > 0) { - keep = true; - } - - index++; - } - } - - if (!keep) { - it.remove(); - } - } - - if (archives.size() == 0) { - mSdkLog.info(LineUtil.reflowLine( - "Warning: The package filter removed all packages. There is nothing to install.\nPlease consider trying to update again without a package filter.\n")); - return null; - } - } - - if (archives != null && archives.size() > 0) { - if (dryMode) { - mSdkLog.info("Packages selected for install:\n"); - for (ArchiveInfo ai : archives) { - Archive a = ai.getNewArchive(); - if (a != null) { - Package p = a.getParentPackage(); - if (p != null) { - mSdkLog.info("- %1$s\n", p.getShortDescription()); - } - } - } - mSdkLog.info("\nDry mode is on so nothing is actually being installed.\n"); - } else { - return installArchives(archives, NO_TOOLS_MSG); - } - } else { - mSdkLog.info("There is nothing to install or update.\n"); - } - - return null; - } - - @SuppressWarnings("unchecked") - private void mapFilterToPackageClass( - HashMap<String, Class<? extends Package>> inOutPkgMap, - String[] nodes) { - - // Automatically find the classes matching the node names - ClassLoader classLoader = getClass().getClassLoader(); - String basePackage = Package.class.getPackage().getName(); - - for (String node : nodes) { - // Capitalize the name - String name = node.substring(0, 1).toUpperCase() + node.substring(1); - - // We can have one dash at most in a name. If it's present, we'll try - // with the dash or with the next letter capitalized. - int dash = name.indexOf('-'); - if (dash > 0) { - name = name.replaceFirst("-", ""); - } - - for (int alternatives = 0; alternatives < 2; alternatives++) { - - String fqcn = basePackage + '.' + name + "Package"; //$NON-NLS-1$ - try { - Class<? extends Package> clazz = - (Class<? extends Package>) classLoader.loadClass(fqcn); - if (clazz != null) { - inOutPkgMap.put(node, clazz); - continue; - } - } catch (Throwable ignore) { - } - - if (alternatives == 0 && dash > 0) { - // Try an alternative where the next letter after the dash - // is converted to an upper case. - name = name.substring(0, dash) + - name.substring(dash, dash + 1).toUpperCase() + - name.substring(dash + 1); - } else { - break; - } - } - } - } - - /** - * Refresh all sources. This is invoked either internally (reusing an existing monitor) - * or as a UI callback on the remote page "Refresh" button (in which case the monitor is - * null and a new task should be created.) - * - * @param forceFetching When true, load sources that haven't been loaded yet. - * When false, only refresh sources that have been loaded yet. - */ - public void refreshSources(final boolean forceFetching) { - assert mTaskFactory != null; - - final boolean forceHttp = getSettingsController().getSettings().getForceHttp(); - - mTaskFactory.start("Refresh Sources", new ITask() { - @Override - public void run(ITaskMonitor monitor) { - - getPackageLoader().loadRemoteAddonsList(monitor); - - SdkSource[] sources = getSources().getAllSources(); - monitor.setDescription("Refresh Sources"); - monitor.setProgressMax(monitor.getProgress() + sources.length); - for (SdkSource source : sources) { - if (forceFetching || - source.getPackages() != null || - source.getFetchError() != null) { - source.load(getDownloadCache(), monitor.createSubMonitor(1), forceHttp); - } - monitor.incProgress(1); - } - } - }); - } - - /** - * Safely invoke all the registered {@link ISdkChangeListener#onSdkLoaded()}. - * This can be called from any thread. - */ - public void broadcastOnSdkLoaded() { - if (mWindowShell != null && !mWindowShell.isDisposed() && mListeners.size() > 0) { - mWindowShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - for (ISdkChangeListener listener : mListeners) { - try { - listener.onSdkLoaded(); - } catch (Throwable t) { - mSdkLog.error(t, null); - } - } - } - }); - } - } - - /** - * Safely invoke all the registered {@link ISdkChangeListener#onSdkReload()}. - * This can be called from any thread. - */ - private void broadcastOnSdkReload() { - if (mWindowShell != null && !mWindowShell.isDisposed() && mListeners.size() > 0) { - mWindowShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - for (ISdkChangeListener listener : mListeners) { - try { - listener.onSdkReload(); - } catch (Throwable t) { - mSdkLog.error(t, null); - } - } - } - }); - } - } - - /** - * Safely invoke all the registered {@link ISdkChangeListener#preInstallHook()}. - * This can be called from any thread. - */ - private void broadcastPreInstallHook() { - if (mWindowShell != null && !mWindowShell.isDisposed() && mListeners.size() > 0) { - mWindowShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - for (ISdkChangeListener listener : mListeners) { - try { - listener.preInstallHook(); - } catch (Throwable t) { - mSdkLog.error(t, null); - } - } - } - }); - } - } - - /** - * Safely invoke all the registered {@link ISdkChangeListener#postInstallHook()}. - * This can be called from any thread. - */ - private void broadcastPostInstallHook() { - if (mWindowShell != null && !mWindowShell.isDisposed() && mListeners.size() > 0) { - mWindowShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - for (ISdkChangeListener listener : mListeners) { - try { - listener.postInstallHook(); - } catch (Throwable t) { - mSdkLog.error(t, null); - } - } - } - }); - } - } - - /** - * Internal helper to return a new {@link ArchiveInstaller}. - * This allows us to override the installer for unit-testing. - */ - @VisibleForTesting(visibility=Visibility.PRIVATE) - protected ArchiveInstaller createArchiveInstaler() { - return new ArchiveInstaller(); - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java deleted file mode 100755 index 18cccae..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackageLoader.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.sdklib.internal.repository.AddonsListFetcher; -import com.android.sdklib.internal.repository.AddonsListFetcher.Site; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.NullTaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.Package.UpdateInfo; -import com.android.sdklib.internal.repository.sources.SdkAddonSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.internal.repository.sources.SdkSourceCategory; -import com.android.sdklib.internal.repository.sources.SdkSources; -import com.android.sdklib.internal.repository.sources.SdkSysImgSource; -import com.android.sdklib.repository.SdkAddonsListConstants; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.sdkuilib.internal.repository.UpdaterData; - -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Loads packages fetched from the remote SDK Repository and keeps track - * of their state compared with the current local SDK installation. - */ -public class PackageLoader { - - /** The update data context. Never null. */ - private final UpdaterData mUpdaterData; - - /** - * The {@link DownloadCache} override. Can be null, in which case the one from - * {@link UpdaterData} is used instead. - * @see #getDownloadCache() - */ - private final DownloadCache mOverrideCache; - - /** - * 0 = need to fetch remote addons list once.. - * 1 = fetch succeeded, don't need to do it any more. - * -1= fetch failed, do it again only if the user requests a refresh - * or changes the force-http setting. - */ - private int mStateFetchRemoteAddonsList; - - - /** - * Interface for the callback called by - * {@link PackageLoader#loadPackages(boolean, ISourceLoadedCallback)}. - * <p/> - * After processing each source, the package loader calls {@link #onUpdateSource} - * with the list of packages found in that source. - * By returning true from {@link #onUpdateSource}, the client tells the loader to - * continue and process the next source. By returning false, it tells to stop loading. - * <p/> - * The {@link #onLoadCompleted()} method is guaranteed to be called at the end, no - * matter how the loader stopped, so that the client can clean up or perform any - * final action. - */ - public interface ISourceLoadedCallback { - /** - * After processing each source, the package loader calls this method with the - * list of packages found in that source. - * By returning true from {@link #onUpdateSource}, the client tells - * the loader to continue and process the next source. - * By returning false, it tells to stop loading. - * <p/> - * <em>Important</em>: This method is called from a sub-thread, so clients which - * try to access any UI widgets must wrap their calls into - * {@link Display#syncExec(Runnable)} or {@link Display#asyncExec(Runnable)}. - * - * @param packages All the packages loaded from the source. Never null. - * @return True if the load operation should continue, false if it should stop. - */ - public boolean onUpdateSource(SdkSource source, Package[] packages); - - /** - * This method is guaranteed to be called at the end, no matter how the - * loader stopped, so that the client can clean up or perform any final action. - */ - public void onLoadCompleted(); - } - - /** - * Interface describing the task of installing a specific package. - * For details on the operation, - * see {@link PackageLoader#loadPackagesWithInstallTask(int, IAutoInstallTask)}. - * - * @see PackageLoader#loadPackagesWithInstallTask(int, IAutoInstallTask) - */ - public interface IAutoInstallTask { - /** - * Invoked by the loader once a source has been loaded and its package - * definitions are known. The method should return the {@code packages} - * array and can modify it if necessary. - * The loader will call {@link #acceptPackage(Package)} on all the packages returned. - * - * @param source The source of the packages. Null for the locally installed packages. - * @param packages The packages found in the source. - */ - public Package[] filterLoadedSource(SdkSource source, Package[] packages); - - /** - * Called by the install task for every package available (new ones, updates as well - * as existing ones that don't have a potential update.) - * The method should return true if this is a package that should be installed. - * <p/> - * <em>Important</em>: This method is called from a sub-thread, so clients who try - * to access any UI widgets must wrap their calls into {@link Display#syncExec(Runnable)} - * or {@link Display#asyncExec(Runnable)}. - */ - public boolean acceptPackage(Package pkg); - - /** - * Called when the accepted package has been installed, successfully or not. - * If an already installed (aka existing) package has been accepted, this will - * be called with a 'true' success and the actual install paths. - * <p/> - * <em>Important</em>: This method is called from a sub-thread, so clients who try - * to access any UI widgets must wrap their calls into {@link Display#syncExec(Runnable)} - * or {@link Display#asyncExec(Runnable)}. - */ - public void setResult(boolean success, Map<Package, File> installPaths); - - /** - * Called when the task is done iterating and completed. - */ - public void taskCompleted(); - } - - /** - * Creates a new PackageManager associated with the given {@link UpdaterData} - * and using the {@link UpdaterData}'s default {@link DownloadCache}. - * - * @param updaterData The {@link UpdaterData}. Must not be null. - */ - public PackageLoader(UpdaterData updaterData) { - mUpdaterData = updaterData; - mOverrideCache = null; - } - - /** - * Creates a new PackageManager associated with the given {@link UpdaterData} - * but using the specified {@link DownloadCache} instead of the one from - * {@link UpdaterData}. - * - * @param updaterData The {@link UpdaterData}. Must not be null. - * @param cache The {@link DownloadCache} to use instead of the one from {@link UpdaterData}. - */ - public PackageLoader(UpdaterData updaterData, DownloadCache cache) { - mUpdaterData = updaterData; - mOverrideCache = cache; - } - - /** - * Loads all packages from the remote repository. - * This runs in an {@link ITask}. The call is blocking. - * <p/> - * The callback is called with each set of {@link PkgItem} found in each source. - * The caller is responsible to accumulate the packages given to the callback - * after each source is finished loaded. In return the callback tells the loader - * whether to continue loading sources. - * <p/> - * Normally this method doesn't access the remote source if it's already - * been loaded in the in-memory source (e.g. don't fetch twice). - * - * @param overrideExisting Set this to true when the caller wants to - * check for updates and discard any existing source already - * loaded in memory. It should be false for normal use. - * @param sourceLoadedCallback The callback to invoke for each loaded source. - */ - public void loadPackages( - final boolean overrideExisting, - final ISourceLoadedCallback sourceLoadedCallback) { - try { - if (mUpdaterData == null) { - return; - } - - mUpdaterData.getTaskFactory().start("Loading Sources", new ITask() { - @Override - public void run(ITaskMonitor monitor) { - monitor.setProgressMax(10); - - // get local packages and offer them to the callback - Package[] localPkgs = - mUpdaterData.getInstalledPackages(monitor.createSubMonitor(1)); - if (localPkgs == null) { - localPkgs = new Package[0]; - } - if (!sourceLoadedCallback.onUpdateSource(null, localPkgs)) { - return; - } - - // get remote packages - boolean forceHttp = - mUpdaterData.getSettingsController().getSettings().getForceHttp(); - loadRemoteAddonsList(monitor.createSubMonitor(1)); - - SdkSource[] sources = mUpdaterData.getSources().getAllSources(); - try { - if (sources != null && sources.length > 0) { - ITaskMonitor subMonitor = monitor.createSubMonitor(8); - subMonitor.setProgressMax(sources.length); - for (SdkSource source : sources) { - Package[] pkgs = source.getPackages(); - if (pkgs == null || overrideExisting) { - source.load(getDownloadCache(), - subMonitor.createSubMonitor(1), - forceHttp); - pkgs = source.getPackages(); - } - if (pkgs == null) { - continue; - } - - // Notify the callback a new source has finished loading. - // If the callback requests so, stop right away. - if (!sourceLoadedCallback.onUpdateSource(source, pkgs)) { - return; - } - } - } - } catch(Exception e) { - monitor.logError("Loading source failed: %1$s", e.toString()); - } finally { - monitor.setDescription("Done loading packages."); - } - } - }); - } finally { - sourceLoadedCallback.onLoadCompleted(); - } - } - - /** - * Load packages, source by source using - * {@link #loadPackages(boolean, ISourceLoadedCallback)}, - * and executes the given {@link IAutoInstallTask} on the current package list. - * That is for each package known, the install task is queried to find if - * the package is the one to be installed or updated. - * <p/> - * - If an already installed package is accepted by the task, it is returned. <br/> - * - If a new package (remotely available but not installed locally) is accepted, - * the user will be <em>prompted</em> for permission to install it. <br/> - * - If an existing package has updates, the install task will be accept if it - * accepts one of the updating packages, and if yes the the user will be - * <em>prompted</em> for permission to install it. <br/> - * <p/> - * Only one package can be accepted, after which the task is completed. - * There is no direct return value, {@link IAutoInstallTask#setResult} is called on the - * result of the accepted package. - * When the task is completed, {@link IAutoInstallTask#taskCompleted()} is called. - * <p/> - * <em>Important</em>: Since some UI will be displayed to install the selected package, - * the {@link UpdaterData} must have a window {@link Shell} associated using - * {@link UpdaterData#setWindowShell(Shell)}. - * <p/> - * The call is blocking. Although the name says "Task", this is not an {@link ITask} - * running in its own thread but merely a synchronous call. - * - * @param installFlags Flags for installation such as - * {@link UpdaterData#TOOLS_MSG_UPDATED_FROM_ADT}. - * @param installTask The task to perform. - */ - public void loadPackagesWithInstallTask( - final int installFlags, - final IAutoInstallTask installTask) { - - loadPackages(false /*overrideExisting*/, new ISourceLoadedCallback() { - List<Archive> mArchivesToInstall = new ArrayList<Archive>(); - Map<Package, File> mInstallPaths = new HashMap<Package, File>(); - - @Override - public boolean onUpdateSource(SdkSource source, Package[] packages) { - packages = installTask.filterLoadedSource(source, packages); - if (packages == null || packages.length == 0) { - // Tell loadPackages() to process the next source. - return true; - } - - for (Package pkg : packages) { - if (pkg.isLocal()) { - // This is a local (aka installed) package - if (installTask.acceptPackage(pkg)) { - // If the caller is accepting an installed package, - // return a success and give the package's install path - Archive[] a = pkg.getArchives(); - // an installed package should have one local compatible archive - if (a.length == 1 && a[0].isCompatible()) { - mInstallPaths.put(pkg, new File(a[0].getLocalOsPath())); - } - } - - } else { - // This is a remote package - if (installTask.acceptPackage(pkg)) { - // The caller is accepting this remote package. We'll install it. - for (Archive archive : pkg.getArchives()) { - if (archive.isCompatible()) { - mArchivesToInstall.add(archive); - break; - } - } - } - } - } - - // Tell loadPackages() to process the next source. - return true; - } - - @Override - public void onLoadCompleted() { - if (!mArchivesToInstall.isEmpty()) { - installArchives(mArchivesToInstall); - } - if (mInstallPaths == null) { - installTask.setResult(false, null); - } else { - installTask.setResult(true, mInstallPaths); - } - - installTask.taskCompleted(); - } - - /** - * Shows the UI of the install selector. - * If the package is then actually installed, refresh the local list and - * notify the install task of the installation path. - * - * @param archivesToInstall The archives to install. - */ - private void installArchives(final List<Archive> archivesToInstall) { - // Actually install the new archives that we just found. - // This will display some UI so we need a shell's sync exec. - - final List<Archive> installedArchives = new ArrayList<Archive>(); - - Shell shell = mUpdaterData.getWindowShell(); - if (shell != null && !shell.isDisposed()) { - shell.getDisplay().syncExec(new Runnable() {; - @Override - public void run() { - List<Archive> archives = - mUpdaterData.updateOrInstallAll_WithGUI( - archivesToInstall, - true /* includeObsoletes */, - installFlags); - - if (archives != null) { - installedArchives.addAll(archives); - } - } - }); - } - - if (installedArchives.isEmpty()) { - // We failed to install anything. - mInstallPaths = null; - return; - } - - // The local package list has changed, make sure to refresh it - mUpdaterData.getSdkManager().reloadSdk(mUpdaterData.getSdkLog()); - mUpdaterData.getLocalSdkParser().clearPackages(); - final Package[] localPkgs = mUpdaterData.getInstalledPackages( - new NullTaskMonitor(mUpdaterData.getSdkLog())); - - // Scan the installed package list to find the install paths. - for (Archive installedArchive : installedArchives) { - Package pkg = installedArchive.getParentPackage(); - - for (Package localPkg : localPkgs) { - if (localPkg.canBeUpdatedBy(pkg) == UpdateInfo.NOT_UPDATE) { - Archive[] localArchive = localPkg.getArchives(); - if (localArchive.length == 1 && localArchive[0].isCompatible()) { - mInstallPaths.put( - localPkg, - new File(localArchive[0].getLocalOsPath())); - } - } - } - } - } - }); - } - - - /** - * Loads the remote add-ons list. - */ - public void loadRemoteAddonsList(ITaskMonitor monitor) { - - if (mStateFetchRemoteAddonsList != 0) { - return; - } - - mUpdaterData.getTaskFactory().start("Load Add-ons List", monitor, new ITask() { - @Override - public void run(ITaskMonitor subMonitor) { - loadRemoteAddonsListInTask(subMonitor); - } - }); - } - - private void loadRemoteAddonsListInTask(ITaskMonitor monitor) { - mStateFetchRemoteAddonsList = -1; - - String url = SdkAddonsListConstants.URL_ADDON_LIST; - - // We override SdkRepoConstants.URL_GOOGLE_SDK_SITE if this is defined - String baseUrl = System.getenv("SDK_TEST_BASE_URL"); //$NON-NLS-1$ - if (baseUrl != null) { - if (baseUrl.length() > 0 && baseUrl.endsWith("/")) { //$NON-NLS-1$ - if (url.startsWith(SdkRepoConstants.URL_GOOGLE_SDK_SITE)) { - url = baseUrl + url.substring(SdkRepoConstants.URL_GOOGLE_SDK_SITE.length()); - } - } else { - monitor.logError("Ignoring invalid SDK_TEST_BASE_URL: %1$s", baseUrl); //$NON-NLS-1$ - } - } - - if (mUpdaterData.getSettingsController().getSettings().getForceHttp()) { - url = url.replaceAll("https://", "http://"); //$NON-NLS-1$ //$NON-NLS-2$ - } - - // Hook to bypass loading 3rd party addons lists. - boolean fetch3rdParties = System.getenv("SDK_SKIP_3RD_PARTIES") == null; - - AddonsListFetcher fetcher = new AddonsListFetcher(); - Site[] sites = fetcher.fetch(url, getDownloadCache(), monitor); - if (sites != null) { - SdkSources sources = mUpdaterData.getSources(); - sources.removeAll(SdkSourceCategory.ADDONS_3RD_PARTY); - - if (fetch3rdParties) { - for (Site s : sites) { - switch (s.getType()) { - case ADDON_SITE: - sources.add(SdkSourceCategory.ADDONS_3RD_PARTY, - new SdkAddonSource(s.getUrl(), s.getUiName())); - break; - case SYS_IMG_SITE: - sources.add(SdkSourceCategory.ADDONS_3RD_PARTY, - new SdkSysImgSource(s.getUrl(), s.getUiName())); - break; - } - } - } - - sources.notifyChangeListeners(); - - mStateFetchRemoteAddonsList = 1; - } - - monitor.setDescription("Fetched Add-ons List successfully"); - } - - /** - * Returns the {@link DownloadCache} to use. - * - * @return Returns {@link #mOverrideCache} if not null; otherwise returns the - * one from {@link UpdaterData} is used instead. - */ - private DownloadCache getDownloadCache() { - return mOverrideCache != null ? mOverrideCache : mUpdaterData.getDownloadCache(); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackagesDiffLogic.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackagesDiffLogic.java deleted file mode 100755 index f5a2ed3..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PackagesDiffLogic.java +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.SdkConstants; -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.IAndroidVersionProvider; -import com.android.sdklib.internal.repository.packages.IFullRevisionProvider; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.Package.UpdateInfo; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.internal.repository.packages.SystemImagePackage; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.util.SparseArray; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.core.PkgItem.PkgState; -import com.android.sdkuilib.internal.repository.ui.PackagesPageIcons; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * Helper class that separates the logic of package management from the UI - * so that we can test it using head-less unit tests. - */ -public class PackagesDiffLogic { - private final UpdaterData mUpdaterData; - private boolean mFirstLoadComplete = true; - - public PackagesDiffLogic(UpdaterData updaterData) { - mUpdaterData = updaterData; - } - - /** - * Removes all the internal state and resets the object. - * Useful for testing. - */ - public void clear() { - mFirstLoadComplete = true; - mOpApi.clear(); - mOpSource.clear(); - } - - /** Return mFirstLoadComplete and resets it to false. - * All following calls will returns false. */ - public boolean isFirstLoadComplete() { - boolean b = mFirstLoadComplete; - mFirstLoadComplete = false; - return b; - } - - /** - * Mark all new and update PkgItems as checked. - * - * @param selectNew If true, select all new packages (except the rc/preview ones). - * @param selectUpdates If true, select all update packages. - * @param selectTop If true, select the top platform. - * If the top platform has nothing installed, select all items in it (except the rc/preview); - * If it is partially installed, at least select the platform and system images if none of - * the system images are installed. - * @param currentPlatform The {@link SdkConstants#currentPlatform()} value. - */ - public void checkNewUpdateItems( - boolean selectNew, - boolean selectUpdates, - boolean selectTop, - int currentPlatform) { - int maxApi = 0; - Set<Integer> installedPlatforms = new HashSet<Integer>(); - SparseArray<List<PkgItem>> platformItems = new SparseArray<List<PkgItem>>(); - - // sort items in platforms... directly deal with new/update items - List<PkgItem> allItems = getAllPkgItems(true /*byApi*/, true /*bySource*/); - for (PkgItem item : allItems) { - if (!item.hasCompatibleArchive()) { - // Ignore items that have no archive compatible with the current platform. - continue; - } - - // Get the main package's API level. We don't need to look at the updates - // since by definition they should target the same API level. - int api = 0; - Package p = item.getMainPackage(); - if (p instanceof IAndroidVersionProvider) { - api = ((IAndroidVersionProvider) p).getAndroidVersion().getApiLevel(); - } - - if (selectTop && api > 0) { - // Keep track of the max api seen - maxApi = Math.max(maxApi, api); - - // keep track of what platform is currently installed (that is, has at least - // one thing installed.) - if (item.getState() == PkgState.INSTALLED) { - installedPlatforms.add(api); - } - - // for each platform, collect all its related item for later use below. - List<PkgItem> items = platformItems.get(api); - if (items == null) { - platformItems.put(api, items = new ArrayList<PkgItem>()); - } - items.add(item); - } - - if ((selectUpdates || selectNew) && - item.getState() == PkgState.NEW && - !item.getRevision().isPreview()) { - boolean sameFound = false; - Package newPkg = item.getMainPackage(); - if (newPkg instanceof IFullRevisionProvider) { - // We have a potential new non-preview package; but this kind of package - // supports having previews, which means we want to make sure we're not - // offering an older "new" non-preview if there's a newer preview installed. - // - // We should get into this odd situation only when updating an RC/preview - // by a final release pkg. - - IFullRevisionProvider newPkg2 = (IFullRevisionProvider) newPkg; - for (PkgItem item2 : allItems) { - if (item2.getState() == PkgState.INSTALLED) { - Package installed = item2.getMainPackage(); - - if (installed.getRevision().isPreview() && - newPkg2.sameItemAs(installed, true /*ignorePreviews*/)) { - sameFound = true; - - if (installed.canBeUpdatedBy(newPkg) == UpdateInfo.UPDATE) { - item.setChecked(true); - break; - } - } - } - } - } - - if (selectNew && !sameFound) { - item.setChecked(true); - } - - } else if (selectUpdates && item.hasUpdatePkg()) { - item.setChecked(true); - } - } - - List<PkgItem> items = platformItems.get(maxApi); - if (selectTop && maxApi > 0 && items != null) { - if (!installedPlatforms.contains(maxApi)) { - // If the top platform has nothing installed at all, select everything in it - for (PkgItem item : items) { - if ((item.getState() == PkgState.NEW && !item.getRevision().isPreview()) || - item.hasUpdatePkg()) { - item.setChecked(true); - } - } - - } else { - // The top platform has at least one thing installed. - - // First make sure the platform package itself is installed, or select it. - for (PkgItem item : items) { - Package p = item.getMainPackage(); - if (p instanceof PlatformPackage && - item.getState() == PkgState.NEW && !item.getRevision().isPreview()) { - item.setChecked(true); - break; - } - } - - // Check we have at least one system image installed, otherwise select them - boolean hasSysImg = false; - for (PkgItem item : items) { - Package p = item.getMainPackage(); - if (p instanceof PlatformPackage && item.getState() == PkgState.INSTALLED) { - if (item.hasUpdatePkg() && item.isChecked()) { - // If the installed platform is scheduled for update, look for the - // system image in the update package, not the current one. - p = item.getUpdatePkg(); - if (p instanceof PlatformPackage) { - hasSysImg = ((PlatformPackage) p).getIncludedAbi() != null; - } - } else { - // Otherwise look into the currently installed platform - hasSysImg = ((PlatformPackage) p).getIncludedAbi() != null; - } - if (hasSysImg) { - break; - } - } - if (p instanceof SystemImagePackage && item.getState() == PkgState.INSTALLED) { - hasSysImg = true; - break; - } - } - if (!hasSysImg) { - // No system image installed. - // Try whether the current platform or its update would bring one. - - for (PkgItem item : items) { - Package p = item.getMainPackage(); - if (p instanceof PlatformPackage) { - if (item.getState() == PkgState.NEW && - !item.getRevision().isPreview() && - ((PlatformPackage) p).getIncludedAbi() != null) { - item.setChecked(true); - hasSysImg = true; - } else if (item.hasUpdatePkg()) { - p = item.getUpdatePkg(); - if (p instanceof PlatformPackage && - ((PlatformPackage) p).getIncludedAbi() != null) { - item.setChecked(true); - hasSysImg = true; - } - } - } - } - } - if (!hasSysImg) { - // No system image in the platform, try a system image package - for (PkgItem item : items) { - Package p = item.getMainPackage(); - if (p instanceof SystemImagePackage && item.getState() == PkgState.NEW) { - item.setChecked(true); - } - } - } - } - } - - if (selectTop && currentPlatform == SdkConstants.PLATFORM_WINDOWS) { - // On Windows, we'll also auto-select the USB driver - for (PkgItem item : getAllPkgItems(true /*byApi*/, true /*bySource*/)) { - Package p = item.getMainPackage(); - if (p instanceof ExtraPackage && - item.getState() == PkgState.NEW && - !item.getRevision().isPreview()) { - ExtraPackage ep = (ExtraPackage) p; - if (ep.getVendorId().equals("google") && //$NON-NLS-1$ - ep.getPath().equals("usb_driver")) { //$NON-NLS-1$ - item.setChecked(true); - } - } - } - } - } - - /** - * Mark all PkgItems as not checked. - */ - public void uncheckAllItems() { - for (PkgItem item : getAllPkgItems(true /*byApi*/, true /*bySource*/)) { - item.setChecked(false); - } - } - - /** - * An update operation, customized to either sort by API or sort by source. - */ - abstract class UpdateOp { - private final Set<SdkSource> mVisitedSources = new HashSet<SdkSource>(); - private final List<PkgCategory> mCategories = new ArrayList<PkgCategory>(); - private final Set<PkgCategory> mCatsToRemove = new HashSet<PkgCategory>(); - private final Set<PkgItem> mItemsToRemove = new HashSet<PkgItem>(); - private final Map<Package, PkgItem> mUpdatesToRemove = new HashMap<Package, PkgItem>(); - - /** Removes all internal state. */ - public void clear() { - mVisitedSources.clear(); - mCategories.clear(); - } - - /** Retrieve the sorted category list. */ - public List<PkgCategory> getCategories() { - return mCategories; - } - - /** Retrieve the category key for the given package, either local or remote. */ - public abstract Object getCategoryKey(Package pkg); - - /** Modified {@code currentCategories} to add default categories. */ - public abstract void addDefaultCategories(); - - /** Creates the category for the given key and returns it. */ - public abstract PkgCategory createCategory(Object catKey); - /** Adjust attributes of an existing category. */ - public abstract void adjustCategory(PkgCategory cat, Object catKey); - - /** Sorts the category list (but not the items within the categories.) */ - public abstract void sortCategoryList(); - - /** Called after items of a given category have changed. Used to sort the - * items and/or adjust the category name. */ - public abstract void postCategoryItemsChanged(); - - public void updateStart() { - mVisitedSources.clear(); - - // Note that default categories are created after the unused ones so that - // the callback can decide whether they should be marked as unused or not. - mCatsToRemove.clear(); - mItemsToRemove.clear(); - mUpdatesToRemove.clear(); - for (PkgCategory cat : mCategories) { - mCatsToRemove.add(cat); - List<PkgItem> items = cat.getItems(); - mItemsToRemove.addAll(items); - for (PkgItem item : items) { - if (item.hasUpdatePkg()) { - mUpdatesToRemove.put(item.getUpdatePkg(), item); - } - } - } - - addDefaultCategories(); - } - - public boolean updateSourcePackages(SdkSource source, Package[] newPackages) { - mVisitedSources.add(source); - if (source == null) { - return processLocals(this, newPackages); - } else { - return processSource(this, source, newPackages); - } - } - - public boolean updateEnd() { - boolean hasChanged = false; - - // Remove unused categories & items at the end of the update - synchronized (mCategories) { - for (PkgCategory unusedCat : mCatsToRemove) { - if (mCategories.remove(unusedCat)) { - hasChanged = true; - } - } - } - - for (PkgCategory cat : mCategories) { - for (Iterator<PkgItem> itemIt = cat.getItems().iterator(); itemIt.hasNext(); ) { - PkgItem item = itemIt.next(); - if (mItemsToRemove.contains(item)) { - itemIt.remove(); - hasChanged = true; - } else if (item.hasUpdatePkg() && - mUpdatesToRemove.containsKey(item.getUpdatePkg())) { - item.removeUpdate(); - hasChanged = true; - } - } - } - - mCatsToRemove.clear(); - mItemsToRemove.clear(); - mUpdatesToRemove.clear(); - - return hasChanged; - } - - public boolean isKeep(PkgItem item) { - return !mItemsToRemove.contains(item); - } - - public void keep(Package pkg) { - mUpdatesToRemove.remove(pkg); - } - - public void keep(PkgItem item) { - mItemsToRemove.remove(item); - } - - public void keep(PkgCategory cat) { - mCatsToRemove.remove(cat); - } - - public void dontKeep(PkgItem item) { - mItemsToRemove.add(item); - } - - public void dontKeep(PkgCategory cat) { - mCatsToRemove.add(cat); - } - } - - private final UpdateOpApi mOpApi = new UpdateOpApi(); - private final UpdateOpSource mOpSource = new UpdateOpSource(); - - public List<PkgCategory> getCategories(boolean displayIsSortByApi) { - return displayIsSortByApi ? mOpApi.getCategories() : mOpSource.getCategories(); - } - - public List<PkgItem> getAllPkgItems(boolean byApi, boolean bySource) { - List<PkgItem> items = new ArrayList<PkgItem>(); - - if (byApi) { - List<PkgCategory> cats = getCategories(true /*displayIsSortByApi*/); - synchronized (cats) { - for (PkgCategory cat : cats) { - items.addAll(cat.getItems()); - } - } - } - - if (bySource) { - List<PkgCategory> cats = getCategories(false /*displayIsSortByApi*/); - synchronized (cats) { - for (PkgCategory cat : cats) { - items.addAll(cat.getItems()); - } - } - } - - return items; - } - - public void updateStart() { - mOpApi.updateStart(); - mOpSource.updateStart(); - } - - public boolean updateSourcePackages( - boolean displayIsSortByApi, - SdkSource source, - Package[] newPackages) { - - boolean apiListChanged = mOpApi.updateSourcePackages(source, newPackages); - boolean sourceListChanged = mOpSource.updateSourcePackages(source, newPackages); - return displayIsSortByApi ? apiListChanged : sourceListChanged; - } - - public boolean updateEnd(boolean displayIsSortByApi) { - boolean apiListChanged = mOpApi.updateEnd(); - boolean sourceListChanged = mOpSource.updateEnd(); - return displayIsSortByApi ? apiListChanged : sourceListChanged; - } - - - /** Process all local packages. Returns true if something changed. */ - private boolean processLocals(UpdateOp op, Package[] packages) { - boolean hasChanged = false; - List<PkgCategory> cats = op.getCategories(); - Set<PkgItem> keep = new HashSet<PkgItem>(); - - // For all locally installed packages, check they are either listed - // as installed or create new installed items for them. - - nextPkg: for (Package localPkg : packages) { - // Check to see if we already have the exact same package - // (type & revision) marked as installed. - for (PkgCategory cat : cats) { - for (PkgItem currItem : cat.getItems()) { - if (currItem.getState() == PkgState.INSTALLED && - currItem.isSameMainPackageAs(localPkg)) { - // This package is already listed as installed. - op.keep(currItem); - op.keep(cat); - keep.add(currItem); - continue nextPkg; - } - } - } - - // If not found, create a new installed package item - keep.add(addNewItem(op, localPkg, PkgState.INSTALLED)); - hasChanged = true; - } - - // Remove installed items that we don't want to keep anymore. They would normally be - // cleanup up in UpdateOp.updateEnd(); however it's easier to remove them before we - // run processSource() to avoid merging updates in items that would be removed later. - - for (PkgCategory cat : cats) { - for (Iterator<PkgItem> itemIt = cat.getItems().iterator(); itemIt.hasNext(); ) { - PkgItem item = itemIt.next(); - if (item.getState() == PkgState.INSTALLED && !keep.contains(item)) { - itemIt.remove(); - hasChanged = true; - } - } - } - - if (hasChanged) { - op.postCategoryItemsChanged(); - } - - return hasChanged; - } - - /** - * {@link PkgState}s to check in {@link #processSource(UpdateOp, SdkSource, Package[])}. - * The order matters. - * When installing the diff will have both the new and the installed item and we - * need to merge with the installed one before the new one. - */ - private final static PkgState[] PKG_STATES = { PkgState.INSTALLED, PkgState.NEW }; - - /** Process all remote packages. Returns true if something changed. */ - private boolean processSource(UpdateOp op, SdkSource source, Package[] packages) { - boolean hasChanged = false; - List<PkgCategory> cats = op.getCategories(); - - boolean enablePreviews = - mUpdaterData.getSettingsController().getSettings().getEnablePreviews(); - - nextPkg: for (Package newPkg : packages) { - - if (!enablePreviews && newPkg.getRevision().isPreview()) { - // This is a preview and previews are not enabled. Ignore the package. - continue nextPkg; - } - - for (PkgCategory cat : cats) { - for (PkgState state : PKG_STATES) { - for (Iterator<PkgItem> currItemIt = cat.getItems().iterator(); - currItemIt.hasNext(); ) { - PkgItem currItem = currItemIt.next(); - // We need to merge with installed items first. When installing - // the diff will have both the new and the installed item and we - // need to merge with the installed one before the new one. - if (currItem.getState() != state) { - continue; - } - // Only process current items if they represent the same item (but - // with a different revision number) than the new package. - Package mainPkg = currItem.getMainPackage(); - if (!mainPkg.sameItemAs(newPkg)) { - continue; - } - - // Check to see if we already have the exact same package - // (type & revision) marked as main or update package. - if (currItem.isSameMainPackageAs(newPkg)) { - op.keep(currItem); - op.keep(cat); - continue nextPkg; - } else if (currItem.hasUpdatePkg() && - currItem.isSameUpdatePackageAs(newPkg)) { - op.keep(currItem.getUpdatePkg()); - op.keep(cat); - continue nextPkg; - } - - switch (currItem.getState()) { - case NEW: - if (newPkg.getRevision().compareTo(mainPkg.getRevision()) < 0) { - if (!op.isKeep(currItem)) { - // The new item has a lower revision than the current one, - // but the current one hasn't been marked as being kept so - // it's ok to downgrade it. - currItemIt.remove(); - addNewItem(op, newPkg, PkgState.NEW); - hasChanged = true; - } - } else if (newPkg.getRevision().compareTo(mainPkg.getRevision()) > 0) { - // We have a more recent new version, remove the current one - // and replace by a new one - currItemIt.remove(); - addNewItem(op, newPkg, PkgState.NEW); - hasChanged = true; - } - break; - case INSTALLED: - // if newPkg.revision<=mainPkg.revision: it's already installed, ignore. - if (newPkg.getRevision().compareTo(mainPkg.getRevision()) > 0) { - // This is a new update for the main package. - if (currItem.mergeUpdate(newPkg)) { - op.keep(currItem.getUpdatePkg()); - op.keep(cat); - hasChanged = true; - } - } - break; - } - continue nextPkg; - } - } - } - // If not found, create a new package item - addNewItem(op, newPkg, PkgState.NEW); - hasChanged = true; - } - - if (hasChanged) { - op.postCategoryItemsChanged(); - } - - return hasChanged; - } - - private PkgItem addNewItem(UpdateOp op, Package pkg, PkgState state) { - List<PkgCategory> cats = op.getCategories(); - Object catKey = op.getCategoryKey(pkg); - PkgCategory cat = findCurrentCategory(cats, catKey); - - if (cat == null) { - // This is a new category. Create it and add it to the list. - cat = op.createCategory(catKey); - synchronized (cats) { - cats.add(cat); - } - op.sortCategoryList(); - } else { - // Not a new category. Give op a chance to adjust the category attributes - op.adjustCategory(cat, catKey); - } - - PkgItem item = new PkgItem(pkg, state); - op.keep(item); - cat.getItems().add(item); - op.keep(cat); - return item; - } - - private PkgCategory findCurrentCategory( - List<PkgCategory> currentCategories, - Object categoryKey) { - for (PkgCategory cat : currentCategories) { - if (cat.getKey().equals(categoryKey)) { - return cat; - } - } - return null; - } - - /** - * {@link UpdateOp} describing the Sort-by-API operation. - */ - private class UpdateOpApi extends UpdateOp { - @Override - public Object getCategoryKey(Package pkg) { - // Sort by API - - if (pkg instanceof IAndroidVersionProvider) { - return ((IAndroidVersionProvider) pkg).getAndroidVersion(); - - } else if (pkg instanceof ToolPackage || pkg instanceof PlatformToolPackage) { - if (pkg.getRevision().isPreview()) { - return PkgCategoryApi.KEY_TOOLS_PREVIEW; - } else { - return PkgCategoryApi.KEY_TOOLS; - } - } else { - return PkgCategoryApi.KEY_EXTRA; - } - } - - @Override - public void addDefaultCategories() { - boolean needTools = true; - boolean needExtras = true; - - List<PkgCategory> cats = getCategories(); - for (PkgCategory cat : cats) { - if (cat.getKey().equals(PkgCategoryApi.KEY_TOOLS)) { - // Mark them as no unused to prevent their removal in updateEnd(). - keep(cat); - needTools = false; - } else if (cat.getKey().equals(PkgCategoryApi.KEY_EXTRA)) { - keep(cat); - needExtras = false; - } - } - - // Always add the tools & extras categories, even if empty (unlikely anyway) - if (needTools) { - PkgCategoryApi acat = new PkgCategoryApi( - PkgCategoryApi.KEY_TOOLS, - null, - mUpdaterData.getImageFactory().getImageByName(PackagesPageIcons.ICON_CAT_OTHER)); - synchronized (cats) { - cats.add(acat); - } - } - - if (needExtras) { - PkgCategoryApi acat = new PkgCategoryApi( - PkgCategoryApi.KEY_EXTRA, - null, - mUpdaterData.getImageFactory().getImageByName(PackagesPageIcons.ICON_CAT_OTHER)); - synchronized (cats) { - cats.add(acat); - } - } - } - - @Override - public PkgCategory createCategory(Object catKey) { - // Create API category. - PkgCategory cat = null; - - assert catKey instanceof AndroidVersion; - AndroidVersion key = (AndroidVersion) catKey; - - // We should not be trying to recreate the tools or extra categories. - assert !key.equals(PkgCategoryApi.KEY_TOOLS) && !key.equals(PkgCategoryApi.KEY_EXTRA); - - // We need a label for the category. - // If we have an API level, try to get the info from the SDK Manager. - // If we don't (e.g. when installing a new platform that isn't yet available - // locally in the SDK Manager), it's OK we'll try to find the first platform - // package available. - String platformName = null; - for (IAndroidTarget target : - mUpdaterData.getSdkManager().getTargets()) { - if (target.isPlatform() && key.equals(target.getVersion())) { - platformName = target.getVersionName(); - break; - } - } - - cat = new PkgCategoryApi( - key, - platformName, - mUpdaterData.getImageFactory().getImageByName(PackagesPageIcons.ICON_CAT_PLATFORM)); - - return cat; - } - - @Override - public void adjustCategory(PkgCategory cat, Object catKey) { - // Pass. Nothing to do for API-sorted categories - } - - @Override - public void sortCategoryList() { - // Sort the categories list. - // We always want categories in order tools..platforms..extras. - // For platform, we compare in descending order (o2-o1). - // This order is achieved by having the category keys ordered as - // needed for the sort to just do what we expect. - - synchronized (getCategories()) { - Collections.sort(getCategories(), new Comparator<PkgCategory>() { - @Override - public int compare(PkgCategory cat1, PkgCategory cat2) { - assert cat1 instanceof PkgCategoryApi; - assert cat2 instanceof PkgCategoryApi; - assert cat1.getKey() instanceof AndroidVersion; - assert cat2.getKey() instanceof AndroidVersion; - AndroidVersion v1 = (AndroidVersion) cat1.getKey(); - AndroidVersion v2 = (AndroidVersion) cat2.getKey(); - return v2.compareTo(v1); - } - }); - } - } - - @Override - public void postCategoryItemsChanged() { - // Sort the items - for (PkgCategory cat : getCategories()) { - Collections.sort(cat.getItems()); - - // When sorting by API, we can't always get the platform name - // from the package manager. In this case at the very end we - // look for a potential platform package we can use to extract - // the platform version name (e.g. '1.5') from the first suitable - // platform package we can find. - - assert cat instanceof PkgCategoryApi; - PkgCategoryApi pac = (PkgCategoryApi) cat; - if (pac.getPlatformName() == null) { - // Check whether we can get the actual platform version name (e.g. "1.5") - // from the first Platform package we find in this category. - - for (PkgItem item : cat.getItems()) { - Package p = item.getMainPackage(); - if (p instanceof PlatformPackage) { - String platformName = ((PlatformPackage) p).getVersionName(); - if (platformName != null) { - pac.setPlatformName(platformName); - break; - } - } - } - } - } - - } - } - - /** - * {@link UpdateOp} describing the Sort-by-Source operation. - */ - private class UpdateOpSource extends UpdateOp { - - @Override - public boolean updateSourcePackages(SdkSource source, Package[] newPackages) { - // When displaying the repo by source, we want to create all the - // categories so that they can appear on the UI even if empty. - if (source != null) { - List<PkgCategory> cats = getCategories(); - Object catKey = source; - PkgCategory cat = findCurrentCategory(cats, catKey); - - if (cat == null) { - // This is a new category. Create it and add it to the list. - cat = createCategory(catKey); - synchronized (cats) { - cats.add(cat); - } - sortCategoryList(); - } - - keep(cat); - } - - return super.updateSourcePackages(source, newPackages); - } - - @Override - public Object getCategoryKey(Package pkg) { - // Sort by source - SdkSource source = pkg.getParentSource(); - if (source == null) { - return PkgCategorySource.UNKNOWN_SOURCE; - } - return source; - } - - @Override - public void addDefaultCategories() { - List<PkgCategory> cats = getCategories(); - for (PkgCategory cat : cats) { - if (cat.getKey().equals(PkgCategorySource.UNKNOWN_SOURCE)) { - // Already present. - return; - } - } - - // Always add the local categories, even if empty (unlikely anyway) - PkgCategorySource cat = new PkgCategorySource( - PkgCategorySource.UNKNOWN_SOURCE, - mUpdaterData); - // Mark it so that it can be cleared in updateEnd() if not used. - dontKeep(cat); - synchronized (cats) { - cats.add(cat); - } - } - - /** - * Create a new source category. - * <p/> - * One issue is that local archives are processed first and we don't have the - * full source information on them (e.g. we know the referral URL but not - * the referral name of the site). - * In this case this will just create {@link PkgCategorySource} where the label isn't - * known yet. - */ - @Override - public PkgCategory createCategory(Object catKey) { - assert catKey instanceof SdkSource; - PkgCategory cat = new PkgCategorySource((SdkSource) catKey, mUpdaterData); - return cat; - } - - /** - * Checks whether the category needs to be adjust. - * As mentioned in {@link #createCategory(Object)}, local archives are processed - * first and result in a {@link PkgCategorySource} where the label isn't known. - * Once we process the external source with the actual name, we'll update it. - */ - @Override - public void adjustCategory(PkgCategory cat, Object catKey) { - assert cat instanceof PkgCategorySource; - assert catKey instanceof SdkSource; - if (cat instanceof PkgCategorySource) { - ((PkgCategorySource) cat).adjustLabel((SdkSource) catKey); - } - } - - @Override - public void sortCategoryList() { - // Sort the sources in ascending source name order, - // with the local packages always first. - - synchronized (getCategories()) { - Collections.sort(getCategories(), new Comparator<PkgCategory>() { - @Override - public int compare(PkgCategory cat1, PkgCategory cat2) { - assert cat1 instanceof PkgCategorySource; - assert cat2 instanceof PkgCategorySource; - - SdkSource src1 = ((PkgCategorySource) cat1).getSource(); - SdkSource src2 = ((PkgCategorySource) cat2).getSource(); - - if (src1 == src2) { - return 0; - } else if (src1 == PkgCategorySource.UNKNOWN_SOURCE) { - return -1; - } else if (src2 == PkgCategorySource.UNKNOWN_SOURCE) { - return 1; - } - assert src1 != null; // true because LOCAL_SOURCE==null - assert src2 != null; - return src1.toString().compareTo(src2.toString()); - } - }); - } - } - - @Override - public void postCategoryItemsChanged() { - // Sort the items - for (PkgCategory cat : getCategories()) { - Collections.sort(cat.getItems()); - } - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategory.java deleted file mode 100755 index a08b6ef..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategory.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - - -import java.util.ArrayList; -import java.util.List; - -public abstract class PkgCategory { - private final Object mKey; - private final Object mIconRef; - private final List<PkgItem> mItems = new ArrayList<PkgItem>(); - private String mLabel; - - public PkgCategory(Object key, String label, Object iconRef) { - mKey = key; - mLabel = label; - mIconRef = iconRef; - } - - public Object getKey() { - return mKey; - } - - public String getLabel() { - return mLabel; - } - - public void setLabel(String label) { - mLabel = label; - } - - public Object getIconRef() { - return mIconRef; - } - - public List<PkgItem> getItems() { - return mItems; - } - - @Override - public String toString() { - return String.format("%s <key=%s, label=%s, #items=%d>", - this.getClass().getSimpleName(), - mKey == null ? "null" : mKey.toString(), - mLabel, - mItems.size()); - } - - /** {@link PkgCategory}s are equal if their internal keys are equal. */ - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((mKey == null) ? 0 : mKey.hashCode()); - return result; - } - - /** {@link PkgCategory}s are equal if their internal keys are equal. */ - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - PkgCategory other = (PkgCategory) obj; - if (mKey == null) { - if (other.mKey != null) return false; - } else if (!mKey.equals(other.mKey)) return false; - return true; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategoryApi.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategoryApi.java deleted file mode 100755 index aff11e5..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategoryApi.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.sdklib.AndroidVersion; - - -public class PkgCategoryApi extends PkgCategory { - - /** Platform name, in the form "Android 1.2". Can be null if we don't have the name. */ - private String mPlatformName; - - // When sorting by Source, key is the hash of the source's name. - // When storing by API, key is the AndroidVersion (API level >=1 + optional codename). - // We always want categories in order tools..platforms..extras; to achieve that tools - // and extras have the special values so they get "naturally" sorted the way we want - // them. - // (Note: don't use integer.max to avoid integers wrapping in comparisons. We can - // revisit the day we get 2^30 platforms.) - public final static AndroidVersion KEY_TOOLS = new AndroidVersion(Integer.MAX_VALUE / 2, null); - public final static AndroidVersion KEY_TOOLS_PREVIEW = - new AndroidVersion(Integer.MAX_VALUE / 2 - 1, null); - public final static AndroidVersion KEY_EXTRA = new AndroidVersion(-1, null); - - public PkgCategoryApi(AndroidVersion version, String platformName, Object iconRef) { - super(version, null /*label*/, iconRef); - setPlatformName(platformName); - } - - public String getPlatformName() { - return mPlatformName; - } - - public void setPlatformName(String platformName) { - if (platformName != null) { - // Normal case for actual platform categories - mPlatformName = String.format("Android %1$s", platformName); - super.setLabel(null); - } - } - - public String getApiLabel() { - AndroidVersion key = (AndroidVersion) getKey(); - if (key.equals(KEY_TOOLS)) { - return "TOOLS"; //$NON-NLS-1$ // for internal debug use only - } else if (key.equals(KEY_TOOLS_PREVIEW)) { - return "TOOLS-PREVIEW"; //$NON-NLS-1$ // for internal debug use only - } else if (key.equals(KEY_EXTRA)) { - return "EXTRAS"; //$NON-NLS-1$ // for internal debug use only - } else { - return key.toString(); - } - } - - @Override - public String getLabel() { - String label = super.getLabel(); - if (label == null) { - AndroidVersion key = (AndroidVersion) getKey(); - - if (key.equals(KEY_TOOLS)) { - label = "Tools"; - } else if (key.equals(KEY_TOOLS_PREVIEW)) { - label = "Tools (Preview Channel)"; - } else if (key.equals(KEY_EXTRA)) { - label = "Extras"; - } else { - if (mPlatformName != null) { - label = String.format("%1$s (%2$s)", mPlatformName, getApiLabel()); - } else { - label = getApiLabel(); - } - } - super.setLabel(label); - } - return label; - } - - @Override - public void setLabel(String label) { - throw new UnsupportedOperationException("Use setPlatformName() instead."); - } - - @Override - public String toString() { - return String.format("%s <API=%s, label=%s, #items=%d>", - this.getClass().getSimpleName(), - getApiLabel(), - getLabel(), - getItems().size()); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategorySource.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategorySource.java deleted file mode 100755 index b73288b..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgCategorySource.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.sdklib.internal.repository.sources.SdkRepoSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.ui.PackagesPageIcons; - - -public class PkgCategorySource extends PkgCategory { - - /** - * A special {@link SdkSource} object that represents the locally installed - * items, or more exactly a lack of remote source. - */ - public final static SdkSource UNKNOWN_SOURCE = - new SdkRepoSource("http://no.source", "Local Packages"); - private final SdkSource mSource; - - /** - * Creates a new {@link PkgCategorySource}. - * This uses {@link SdkSource#toString()} to get the source's description. - * Note that if the name of the source isn't known, the description will use its URL. - */ - public PkgCategorySource(SdkSource source, UpdaterData updaterData) { - super( - source, // the source is the key and it can be null - source == UNKNOWN_SOURCE ? "Local Packages" : source.toString(), - source == UNKNOWN_SOURCE ? - updaterData.getImageFactory().getImageByName(PackagesPageIcons.ICON_PKG_INSTALLED) : - source); - mSource = source; - } - - @Override - public String toString() { - return String.format("%s <source=%s, #items=%d>", - this.getClass().getSimpleName(), - mSource.toString(), - getItems().size()); - } - - public SdkSource getSource() { - return mSource; - } - - /** Sets the label to match the source's UI name if the label wasn't already set. */ - public void adjustLabel(SdkSource source) { - if (getLabel() == null || getLabel().startsWith("http")) { //$NON-NLS-1$ - setLabel(source == UNKNOWN_SOURCE ? "Local Packages" : source.toString()); - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgContentProvider.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgContentProvider.java deleted file mode 100755 index 8adf428..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgContentProvider.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdkuilib.internal.repository.ui.PackagesPage; - -import org.eclipse.jface.viewers.IInputProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.Viewer; - -import java.util.ArrayList; -import java.util.List; - -/** - * Content provider for the main tree view in {@link PackagesPage}. - */ -public class PkgContentProvider implements ITreeContentProvider { - - private final IInputProvider mViewer; - private boolean mDisplayArchives; - - public PkgContentProvider(IInputProvider viewer) { - mViewer = viewer; - } - - public void setDisplayArchives(boolean displayArchives) { - mDisplayArchives = displayArchives; - } - - @Override - public Object[] getChildren(Object parentElement) { - if (parentElement instanceof ArrayList<?>) { - return ((ArrayList<?>) parentElement).toArray(); - - } else if (parentElement instanceof PkgCategorySource) { - return getSourceChildren((PkgCategorySource) parentElement); - - } else if (parentElement instanceof PkgCategory) { - return ((PkgCategory) parentElement).getItems().toArray(); - - } else if (parentElement instanceof PkgItem) { - if (mDisplayArchives) { - - Package pkg = ((PkgItem) parentElement).getUpdatePkg(); - - // Display update packages as sub-items if the details mode is activated. - if (pkg != null) { - return new Object[] { pkg }; - } - - return ((PkgItem) parentElement).getArchives(); - } - - } else if (parentElement instanceof Package) { - if (mDisplayArchives) { - return ((Package) parentElement).getArchives(); - } - - } - - return new Object[0]; - } - - @Override - @SuppressWarnings("unchecked") - public Object getParent(Object element) { - // This operation is expensive, so we do the minimum - // and don't try to cover all cases. - - if (element instanceof PkgItem) { - Object input = mViewer.getInput(); - if (input != null) { - for (PkgCategory cat : (List<PkgCategory>) input) { - if (cat.getItems().contains(element)) { - return cat; - } - } - } - } - - return null; - } - - @Override - public boolean hasChildren(Object parentElement) { - if (parentElement instanceof ArrayList<?>) { - return true; - - } else if (parentElement instanceof PkgCategory) { - return true; - - } else if (parentElement instanceof PkgItem) { - if (mDisplayArchives) { - Package pkg = ((PkgItem) parentElement).getUpdatePkg(); - - // Display update packages as sub-items if the details mode is activated. - if (pkg != null) { - return true; - } - - Archive[] archives = ((PkgItem) parentElement).getArchives(); - return archives.length > 0; - } - } else if (parentElement instanceof Package) { - if (mDisplayArchives) { - return ((Package) parentElement).getArchives().length > 0; - } - } - - return false; - } - - @Override - public Object[] getElements(Object inputElement) { - return getChildren(inputElement); - } - - @Override - public void dispose() { - // unused - - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // unused - } - - - private Object[] getSourceChildren(PkgCategorySource parentElement) { - List<?> children = parentElement.getItems(); - - SdkSource source = parentElement.getSource(); - IDescription error = null; - IDescription empty = null; - - String errStr = source.getFetchError(); - if (errStr != null) { - error = new RepoSourceError(source); - } - if (!source.isEnabled() || children.isEmpty()) { - empty = new RepoSourceNotification(source); - } - - if (error != null || empty != null) { - ArrayList<Object> children2 = new ArrayList<Object>(); - if (error != null) { - children2.add(error); - } - if (empty != null) { - children2.add(empty); - } - children2.addAll(children); - children = children2; - } - - return children.toArray(); - } - - - /** - * A dummy entry returned for sources which had load errors. - * It displays a summary of the error as its short description or - * it displays the source's long description. - */ - public static class RepoSourceError implements IDescription { - - private final SdkSource mSource; - - public RepoSourceError(SdkSource source) { - mSource = source; - } - - @Override - public String getLongDescription() { - return mSource.getLongDescription(); - } - - @Override - public String getShortDescription() { - return mSource.getFetchError(); - } - } - - /** - * A dummy entry returned for sources with no packages. - * We need that to force the SWT tree to display an open/close triangle - * even for empty sources. - */ - public static class RepoSourceNotification implements IDescription { - - private final SdkSource mSource; - - public RepoSourceNotification(SdkSource source) { - mSource = source; - } - - @Override - public String getLongDescription() { - if (mSource.isEnabled()) { - return mSource.getLongDescription(); - } else { - return "Loading from this site has been disabled. " + - "To enable it, use Tools > Manage Add-ons Sites."; - } - } - - @Override - public String getShortDescription() { - if (mSource.isEnabled()) { - return "No packages found."; - } else { - return "This site is disabled. "; - } - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgItem.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgItem.java deleted file mode 100755 index cac43e4..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/PkgItem.java +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.FullRevision; -import com.android.sdklib.internal.repository.packages.IAndroidVersionProvider; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.Package.UpdateInfo; -import com.android.sdklib.internal.repository.sources.SdkSource; - -/** - * A {@link PkgItem} represents one main {@link Package} combined with its state - * and an optional update package. - * <p/> - * The main package is final and cannot change since it's what "defines" this PkgItem. - * The state or update package can change later. - */ -public class PkgItem implements Comparable<PkgItem> { - private final PkgState mState; - private final Package mMainPkg; - private Package mUpdatePkg; - private boolean mChecked; - - /** - * The state of the a given {@link PkgItem}, that is the relationship between - * a given remote package and the local repository. - */ - public enum PkgState { - // Implementation detail: if this is changed then PackageDiffLogic#STATES - // and PackageDiffLogic#processSource() need to be changed accordingly. - - /** - * Package is locally installed and may or may not have an update. - */ - INSTALLED, - - /** - * There's a new package available on the remote site that isn't installed locally. - */ - NEW - } - - /** - * Create a new {@link PkgItem} for this main package. - * The main package is final and cannot change since it's what "defines" this PkgItem. - * The state or update package can change later. - */ - public PkgItem(Package mainPkg, PkgState state) { - mMainPkg = mainPkg; - mState = state; - assert mMainPkg != null; - } - - public boolean isObsolete() { - return mMainPkg.isObsolete(); - } - - public boolean isChecked() { - return mChecked; - } - - public void setChecked(boolean checked) { - mChecked = checked; - } - - public Package getUpdatePkg() { - return mUpdatePkg; - } - - public boolean hasUpdatePkg() { - return mUpdatePkg != null; - } - - public String getName() { - return mMainPkg.getListDescription(); - } - - public FullRevision getRevision() { - return mMainPkg.getRevision(); - } - - public String getDescription() { - return mMainPkg.getDescription(); - } - - public Package getMainPackage() { - return mMainPkg; - } - - public PkgState getState() { - return mState; - } - - public SdkSource getSource() { - return mMainPkg.getParentSource(); - } - - public int getApi() { - return mMainPkg instanceof IAndroidVersionProvider ? - ((IAndroidVersionProvider) mMainPkg).getAndroidVersion().getApiLevel() : - -1; - } - - public Archive[] getArchives() { - return mMainPkg.getArchives(); - } - - @Override - public int compareTo(PkgItem pkg) { - return getMainPackage().compareTo(pkg.getMainPackage()); - } - - /** - * Returns true if this package or its updating packages contains - * the exact given archive. - * Important: This compares object references, not object equality. - */ - public boolean hasArchive(Archive archive) { - if (mMainPkg.hasArchive(archive)) { - return true; - } - if (mUpdatePkg != null && mUpdatePkg.hasArchive(archive)) { - return true; - } - return false; - } - - /** - * Returns true if the main package has at least one archive - * compatible with the current platform. - */ - public boolean hasCompatibleArchive() { - return mMainPkg.hasCompatibleArchive(); - } - - /** - * Checks whether the main packages are of the same type and are - * not an update of each other and have the same revision number. - */ - public boolean isSameMainPackageAs(Package pkg) { - if (mMainPkg.canBeUpdatedBy(pkg) == UpdateInfo.NOT_UPDATE) { - // package revision numbers must match - return mMainPkg.getRevision().equals(pkg.getRevision()); - } - return false; - } - - /** - * Checks whether the update packages are of the same type and are - * not an update of each other and have the same revision numbers. - */ - public boolean isSameUpdatePackageAs(Package pkg) { - if (mUpdatePkg != null && mUpdatePkg.canBeUpdatedBy(pkg) == UpdateInfo.NOT_UPDATE) { - // package revision numbers must match - return mUpdatePkg.getRevision().equals(pkg.getRevision()); - } - return false; - } - - /** - * Checks whether too {@link PkgItem} are the same. - * This checks both items have the same state, both main package are similar - * and that they have the same updating packages. - */ - public boolean isSameItemAs(PkgItem item) { - if (this == item) { - return true; - } - boolean same = this.mState == item.mState; - if (same) { - same = isSameMainPackageAs(item.getMainPackage()); - } - - if (same) { - // check updating packages are the same - Package p1 = this.mUpdatePkg; - Package p2 = item.getUpdatePkg(); - same = (p1 == p2) || (p1 == null && p2 == null) || (p1 != null && p2 != null); - - if (same && p1 != null) { - same = p1.canBeUpdatedBy(p2) == UpdateInfo.NOT_UPDATE; - } - } - - return same; - } - - /** - * Equality is defined as {@link #isSameItemAs(PkgItem)}: state, main package - * and update package must be the similar. - */ - @Override - public boolean equals(Object obj) { - return (obj instanceof PkgItem) && this.isSameItemAs((PkgItem) obj); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((mState == null) ? 0 : mState.hashCode()); - result = prime * result + ((mMainPkg == null) ? 0 : mMainPkg.hashCode()); - result = prime * result + ((mUpdatePkg == null) ? 0 : mUpdatePkg.hashCode()); - return result; - } - - /** - * Check whether the 'pkg' argument is an update for this package. - * If it is, record it as an updating package. - * If there's already an updating package, only keep the most recent update. - * Returns true if it is update (even if there was already an update and this - * ended up not being the most recent), false if incompatible or not an update. - * - * This should only be used for installed packages. - */ - public boolean mergeUpdate(Package pkg) { - if (mUpdatePkg == pkg) { - return true; - } - if (mMainPkg.canBeUpdatedBy(pkg) == UpdateInfo.UPDATE) { - if (mUpdatePkg == null) { - mUpdatePkg = pkg; - } else if (mUpdatePkg.canBeUpdatedBy(pkg) == UpdateInfo.UPDATE) { - // If we have more than one, keep only the most recent update - mUpdatePkg = pkg; - } - return true; - } - - return false; - } - - public void removeUpdate() { - mUpdatePkg = null; - } - - /** Returns a string representation of this item, useful when debugging. */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append('<'); - - if (mChecked) { - sb.append(" * "); //$NON-NLS-1$ - } - - sb.append(mState.toString()); - - if (mMainPkg != null) { - sb.append(", pkg:"); //$NON-NLS-1$ - sb.append(mMainPkg.toString()); - } - - if (mUpdatePkg != null) { - sb.append(", updated by:"); //$NON-NLS-1$ - sb.append(mUpdatePkg.toString()); - } - - sb.append('>'); - return sb.toString(); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/SdkLogAdapter.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/SdkLogAdapter.java deleted file mode 100755 index 5f24030..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/core/SdkLogAdapter.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.sdkuilib.internal.tasks.ILogUiProvider; -import com.android.utils.ILogger; - - -/** - * Adapter that transform log from an {@link ILogUiProvider} to an {@link ILogger}. - */ -public final class SdkLogAdapter implements ILogUiProvider { - - private ILogger mSdkLog; - private String mLastLogMsg; - - /** - * Creates a new adapter to output log on the given {@code sdkLog}. - * - * @param sdkLog The logger to output to. Must not be null. - */ - public SdkLogAdapter(ILogger sdkLog) { - mSdkLog = sdkLog; - } - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - @Override - public void setDescription(final String description) { - if (acceptLog(description)) { - mSdkLog.info("%1$s", description); //$NON-NLS-1$ - } - } - - /** - * Logs a "normal" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void log(String log) { - if (acceptLog(log)) { - mSdkLog.info(" %1$s", log); //$NON-NLS-1$ - } - } - - /** - * Logs an "error" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logError(String log) { - if (acceptLog(log)) { - mSdkLog.error(null, " %1$s", log); //$NON-NLS-1$ - } - } - - /** - * Logs a "verbose" information line, that is extra details which are typically - * not that useful for the end-user and might be hidden until explicitly shown. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logVerbose(String log) { - if (acceptLog(log)) { - mSdkLog.verbose(" %1$s", log); //$NON-NLS-1$ - } - } - - // ---- - - /** - * Filter messages displayed in the log: <br/> - * - Messages with a % are typical part of a progress update and shouldn't be in the log. <br/> - * - Messages that are the same as the same output message should be output a second time. - * - * @param msg The potential log line to print. - * @return True if the log line should be printed, false otherwise. - */ - private boolean acceptLog(String msg) { - if (msg == null) { - return false; - } - - msg = msg.trim(); - if (msg.indexOf('%') != -1) { - return false; - } - - if (msg.equals(mLastLogMsg)) { - return false; - } - - mLastLogMsg = msg; - return true; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java deleted file mode 100755 index ab84cc2..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/ImageFactory.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.icons; - -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.internal.repository.sources.SdkSourceCategory; -import com.android.sdkuilib.internal.repository.core.PkgContentProvider; - -import org.eclipse.swt.SWTException; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; - -import java.io.InputStream; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Locale; -import java.util.Map; - - -/** - * An utility class to serve {@link Image} correspond to the various icons - * present in this package and dispose of them correctly at the end. - */ -public class ImageFactory { - - private final Display mDisplay; - private final Map<String, Image> mImages = new HashMap<String, Image>(); - - public ImageFactory(Display display) { - mDisplay = display; - } - - /** - * Loads an image given its filename (with its extension). - * Might return null if the image cannot be loaded. - * The image is cached. Successive calls will return the <em>same</em> object. - * - * @param imageName The filename (with extension) of the image to load. - * @return A new or existing {@link Image}. The caller must NOT dispose the image (the - * image will disposed by {@link #dispose()}). The returned image can be null if the - * expected file is missing. - */ - public Image getImageByName(String imageName) { - - Image image = mImages.get(imageName); - if (image != null) { - return image; - } - - InputStream stream = getClass().getResourceAsStream(imageName); - if (stream != null) { - try { - image = new Image(mDisplay, stream); - } catch (SWTException e) { - // ignore - } catch (IllegalArgumentException e) { - // ignore - } - } - - // Store the image in the hash, even if this failed. If it fails now, it will fail later. - mImages.put(imageName, image); - - return image; - } - - /** - * Loads and returns the appropriate image for a given package, archive or source object. - * The image is cached. Successive calls will return the <em>same</em> object. - * - * @param object A {@link SdkSource} or {@link Package} or {@link Archive}. - * @return A new or existing {@link Image}. The caller must NOT dispose the image (the - * image will disposed by {@link #dispose()}). The returned image can be null if the - * object is of an unknown type. - */ - public Image getImageForObject(Object object) { - - if (object == null) { - return null; - } - - if (object instanceof Image) { - return (Image) object; - } - - String clz = object.getClass().getSimpleName(); - if (clz.endsWith(Package.class.getSimpleName())) { - String name = clz.replaceFirst(Package.class.getSimpleName(), "") //$NON-NLS-1$ - .replace("SystemImage", "sysimg") //$NON-NLS-1$ //$NON-NLS-2$ - .toLowerCase(Locale.US); - name += "_pkg_16.png"; //$NON-NLS-1$ - return getImageByName(name); - } - - if (object instanceof SdkSourceCategory) { - return getImageByName("source_cat_icon_16.png"); //$NON-NLS-1$ - - } else if (object instanceof SdkSource) { - return getImageByName("source_icon_16.png"); //$NON-NLS-1$ - - } else if (object instanceof PkgContentProvider.RepoSourceError) { - return getImageByName("error_icon_16.png"); //$NON-NLS-1$ - - } else if (object instanceof PkgContentProvider.RepoSourceNotification) { - return getImageByName("nopkg_icon_16.png"); //$NON-NLS-1$ - } - - if (object instanceof Archive) { - if (((Archive) object).isCompatible()) { - return getImageByName("archive_icon16.png"); //$NON-NLS-1$ - } else { - return getImageByName("incompat_icon16.png"); //$NON-NLS-1$ - } - } - - if (object instanceof String) { - return getImageByName((String) object); - } - - - if (object != null) { - // For debugging - // System.out.println("No image for object " + object.getClass().getSimpleName()); - } - - return null; - } - - /** - * Dispose all the images created by this factory so far. - */ - public void dispose() { - Iterator<Image> it = mImages.values().iterator(); - while(it.hasNext()) { - Image img = it.next(); - if (img != null && img.isDisposed() == false) { - img.dispose(); - } - it.remove(); - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/accept_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/accept_icon16.png Binary files differdeleted file mode 100755 index a9483fb..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/accept_icon16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/addon_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/addon_pkg_16.png Binary files differdeleted file mode 100755 index ca6a231..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/addon_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_128.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_128.png Binary files differdeleted file mode 100644 index 830c04b..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_128.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_16.png Binary files differdeleted file mode 100644 index 08ffda8..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/android_icon_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/archive_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/archive_icon16.png Binary files differdeleted file mode 100755 index be5edd7..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/archive_icon16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/broken_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/broken_16.png Binary files differdeleted file mode 100755 index 945d871..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/broken_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/broken_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/broken_pkg_16.png Binary files differdeleted file mode 100755 index 6daa67b..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/broken_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/doc_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/doc_pkg_16.png Binary files differdeleted file mode 100755 index 186b3b1..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/doc_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon_16.png Binary files differdeleted file mode 100755 index ccb4d0a..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/error_icon_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/extra_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/extra_pkg_16.png Binary files differdeleted file mode 100755 index a6529f0..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/extra_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/incompat_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/incompat_icon16.png Binary files differdeleted file mode 100755 index 2a307e9..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/incompat_icon16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/log_off_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/log_off_16.png Binary files differdeleted file mode 100755 index c9d7cb7..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/log_off_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/log_on_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/log_on_16.png Binary files differdeleted file mode 100755 index 58f4195..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/log_on_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon_16.png Binary files differdeleted file mode 100755 index 147837f..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/nopkg_icon_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_incompat_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_incompat_16.png Binary files differdeleted file mode 100755 index 7ef989e..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_incompat_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_installed_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_installed_16.png Binary files differdeleted file mode 100755 index 78b7e5a..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_installed_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_new_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_new_16.png Binary files differdeleted file mode 100755 index 0976ad4..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_new_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_update_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_update_16.png Binary files differdeleted file mode 100755 index e766251..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkg_update_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkgcat_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkgcat_16.png Binary files differdeleted file mode 100755 index cd9b807..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkgcat_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkgcat_other_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkgcat_other_16.png Binary files differdeleted file mode 100755 index 395a240..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/pkgcat_other_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/platform_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/platform_pkg_16.png Binary files differdeleted file mode 100755 index 0b0744b..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/platform_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/platformtool_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/platformtool_pkg_16.png Binary files differdeleted file mode 100755 index 8bb0bb3..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/platformtool_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/reject_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/reject_icon16.png Binary files differdeleted file mode 100755 index b87bbc9..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/reject_icon16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sample_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sample_pkg_16.png Binary files differdeleted file mode 100755 index 8d31865..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sample_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sdkman_logo_128.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sdkman_logo_128.png Binary files differdeleted file mode 100644 index 0f1670d..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sdkman_logo_128.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon_16.png Binary files differdeleted file mode 100755 index 13c8bb3..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_cat_icon_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon_16.png Binary files differdeleted file mode 100755 index 5eb1ead..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_icon_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_pkg_16.png Binary files differdeleted file mode 100755 index 9992cda..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/source_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/status_ok_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/status_ok_16.png Binary files differdeleted file mode 100755 index eeb0a6f..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/status_ok_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/stop_disabled_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/stop_disabled_16.png Binary files differdeleted file mode 100755 index ae6da31..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/stop_disabled_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/stop_enabled_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/stop_enabled_16.png Binary files differdeleted file mode 100755 index 7ce1864..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/stop_enabled_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sysimg_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sysimg_pkg_16.png Binary files differdeleted file mode 100755 index 7795c2c..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/sysimg_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/tool_pkg_16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/tool_pkg_16.png Binary files differdeleted file mode 100755 index 8ca7710..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/tool_pkg_16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/unknown_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/unknown_icon16.png Binary files differdeleted file mode 100755 index 1b97eb7..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/unknown_icon16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/warning_icon16.png b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/warning_icon16.png Binary files differdeleted file mode 100755 index 0f5128d..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/icons/warning_icon16.png +++ /dev/null diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AddonSitesDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AddonSitesDialog.java deleted file mode 100755 index 6174ba6..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AddonSitesDialog.java +++ /dev/null @@ -1,576 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import com.android.sdklib.internal.repository.sources.SdkAddonSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.internal.repository.sources.SdkSourceCategory; -import com.android.sdklib.internal.repository.sources.SdkSourceProperties; -import com.android.sdklib.internal.repository.sources.SdkSources; -import com.android.sdklib.internal.repository.sources.SdkSysImgSource; -import com.android.sdklib.repository.SdkSysImgConstants; -import com.android.sdkuilib.internal.repository.UpdaterBaseDialog; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; - -import org.eclipse.jface.dialogs.IInputValidator; -import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTableViewer; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.LabelProvider; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.MouseAdapter; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.TabFolder; -import org.eclipse.swt.widgets.TabItem; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; - -import java.util.ArrayList; -import java.util.Arrays; - -/** - * Dialog that displays 2 tabs: <br/> - * - one tab with the list of extra add-ons sites defined by the user. <br/> - * - one tab with the list of 3rd-party add-ons currently available, which the user can - * deactivate to prevent from loading them. - */ -public class AddonSitesDialog extends UpdaterBaseDialog { - - private final SdkSources mSources; - private Table mUserTable; - private TableViewer mUserTableViewer; - private CheckboxTableViewer mSitesTableViewer; - private Button mUserButtonNew; - private Button mUserButtonDelete; - private Button mUserButtonEdit; - private Runnable mSourcesChangeListener; - - /** - * Create the dialog. - * - * @param parent The parent's shell - * @wbp.parser.entryPoint - */ - public AddonSitesDialog(Shell parent, UpdaterData updaterData) { - super(parent, updaterData, "Add-on Sites"); - mSources = updaterData.getSources(); - assert mSources != null; - } - - /** - * Create contents of the dialog. - * @wbp.parser.entryPoint - */ - @Override - protected void createContents() { - super.createContents(); - Shell shell = getShell(); - shell.setMinimumSize(new Point(300, 300)); - shell.setSize(600, 400); - - TabFolder tabFolder = new TabFolder(shell, SWT.NONE); - tabFolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); - GridDataBuilder.create(tabFolder).fill().grab().hSpan(2); - - TabItem sitesTabItem = new TabItem(tabFolder, SWT.NONE); - sitesTabItem.setText("Official Add-on Sites"); - createTabOfficialSites(tabFolder, sitesTabItem); - - TabItem userTabItem = new TabItem(tabFolder, SWT.NONE); - userTabItem.setText("User Defined Sites"); - createTabUserSites(tabFolder, userTabItem); - - // placeholder for aligning close button - Label label = new Label(shell, SWT.NONE); - GridDataBuilder.create(label).hFill().hGrab(); - - createCloseButton(); - } - - void createTabOfficialSites(TabFolder tabFolder, TabItem sitesTabItem) { - Composite root = new Composite(tabFolder, SWT.NONE); - sitesTabItem.setControl(root); - GridLayoutBuilder.create(root).columns(3); - - Label label = new Label(root, SWT.NONE); - GridDataBuilder.create(label).hLeft().vCenter().hSpan(3); - label.setText( - "This lets select which official 3rd-party sites you want to load.\n" + - "\n" + - "These sites are managed by non-Android vendors to provide add-ons and extra packages.\n" + - "They are by default all enabled. When you disable one, the SDK Manager will not check the site for new packages." - ); - - mSitesTableViewer = CheckboxTableViewer.newCheckList(root, SWT.BORDER | SWT.FULL_SELECTION); - mSitesTableViewer.setContentProvider(new SourcesContentProvider()); - - Table sitesTable = mSitesTableViewer.getTable(); - sitesTable.setToolTipText("Enable 3rd-Party Site"); - sitesTable.setLinesVisible(true); - sitesTable.setHeaderVisible(true); - GridDataBuilder.create(sitesTable).fill().grab().hSpan(3); - - TableViewerColumn columnViewer = new TableViewerColumn(mSitesTableViewer, SWT.NONE); - TableColumn column = columnViewer.getColumn(); - column.setResizable(true); - column.setWidth(150); - column.setText("Name"); - columnViewer.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - if (element instanceof SdkSource) { - String name = ((SdkSource) element).getUiName(); - if (name != null) { - return name; - } - return ((SdkSource) element).getShortDescription(); - } - return super.getText(element); - } - }); - - columnViewer = new TableViewerColumn(mSitesTableViewer, SWT.NONE); - column = columnViewer.getColumn(); - column.setResizable(true); - column.setWidth(400); - column.setText("URL"); - columnViewer.setLabelProvider(new ColumnLabelProvider() { - @Override - public String getText(Object element) { - if (element instanceof SdkSource) { - return ((SdkSource) element).getUrl(); - } - return super.getText(element); - } - }); - - mSitesTableViewer.addCheckStateListener(new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - on_SitesTableViewer_checkStateChanged(event); - } - }); - - // "enable all" and "disable all" buttons under the table - Button selectAll = new Button(root, SWT.NONE); - selectAll.setText("Enable All"); - GridDataBuilder.create(selectAll).hLeft(); - selectAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - on_SitesTableViewer_selectAll(); - } - }); - - // placeholder between both buttons - label = new Label(root, SWT.NONE); - GridDataBuilder.create(label).hFill().hGrab(); - - Button deselectAll = new Button(root, SWT.NONE); - deselectAll.setText("Disable All"); - GridDataBuilder.create(deselectAll).hRight(); - deselectAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - on_SitesTableViewer_deselectAll(); - } - }); - } - - void createTabUserSites(TabFolder tabFolder, TabItem userTabItem) { - Composite root = new Composite(tabFolder, SWT.NONE); - userTabItem.setControl(root); - GridLayoutBuilder.create(root).columns(2); - - Label label = new Label(root, SWT.NONE); - GridDataBuilder.create(label).hLeft().vCenter().hSpan(2); - label.setText( - "This lets you manage a list of user-contributed external add-on sites URLs.\n" + - "\n" + - "Add-on sites can provide new add-ons and extra packages.\n" + - "They cannot provide standard Android platforms, system images or docs.\n" + - "Adding a URL here will not allow you to clone an official Android repository." - ); - - mUserTableViewer = new TableViewer(root, SWT.BORDER | SWT.FULL_SELECTION); - mUserTableViewer.setContentProvider(new SourcesContentProvider()); - - mUserTableViewer.addPostSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - on_UserTableViewer_selectionChanged(event); - } - }); - mUserTable = mUserTableViewer.getTable(); - mUserTable.setLinesVisible(true); - mUserTable.addMouseListener(new MouseAdapter() { - @Override - public void mouseUp(MouseEvent event) { - on_UserTable_mouseUp(event); - } - }); - GridDataBuilder.create(mUserTable).fill().grab().vSpan(5); - - TableViewerColumn tableViewerColumn = new TableViewerColumn(mUserTableViewer, SWT.NONE); - TableColumn userColumnUrl = tableViewerColumn.getColumn(); - userColumnUrl.setWidth(100); - - // Implementation detail: set the label provider on the table viewer *after* associating - // a column. This will set the label provider on the column for us. - mUserTableViewer.setLabelProvider(new LabelProvider()); - - - mUserButtonNew = new Button(root, SWT.NONE); - mUserButtonNew.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - userNewOrEdit(false /*isEdit*/); - } - }); - GridDataBuilder.create(mUserButtonNew).hFill().vCenter(); - mUserButtonNew.setText("New..."); - - mUserButtonEdit = new Button(root, SWT.NONE); - mUserButtonEdit.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - userNewOrEdit(true /*isEdit*/); - } - }); - GridDataBuilder.create(mUserButtonEdit).hFill().vCenter(); - mUserButtonEdit.setText("Edit..."); - - mUserButtonDelete = new Button(root, SWT.NONE); - mUserButtonDelete.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - on_UserButtonDelete_widgetSelected(e); - } - }); - GridDataBuilder.create(mUserButtonDelete).hFill().vCenter(); - mUserButtonDelete.setText("Delete..."); - - adjustColumnsWidth(mUserTable, userColumnUrl); - } - - @Override - protected void close() { - if (mSources != null && mSourcesChangeListener != null) { - mSources.removeChangeListener(mSourcesChangeListener); - } - SdkSourceProperties p = new SdkSourceProperties(); - p.save(); - super.close(); - } - - /** - * Adds a listener to adjust the column width when the parent is resized. - */ - private void adjustColumnsWidth(final Table table, final TableColumn column0) { - // Add a listener to resize the column to the full width of the table - table.addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent e) { - Rectangle r = table.getClientArea(); - column0.setWidth(r.width * 100 / 100); // 100% - } - }); - } - - private void userNewOrEdit(final boolean isEdit) { - final SdkSource[] knownSources = mSources.getAllSources(); - String title = isEdit ? "Edit Add-on Site URL" : "Add Add-on Site URL"; - String msg = "Please enter the URL of the addon.xml:"; - IStructuredSelection sel = (IStructuredSelection) mUserTableViewer.getSelection(); - final String initialValue = !isEdit || sel.isEmpty() ? null : - sel.getFirstElement().toString(); - - if (isEdit && initialValue == null) { - // Edit with no actual value is not supposed to happen. Ignore this case. - return; - } - - InputDialog dlg = new InputDialog( - getShell(), - title, - msg, - initialValue, - new IInputValidator() { - @Override - public String isValid(String newText) { - - newText = newText == null ? null : newText.trim(); - - if (newText == null || newText.length() == 0) { - return "Error: URL field is empty. Please enter a URL."; - } - - // A URL should have one of the following prefixes - if (!newText.startsWith("file://") && //$NON-NLS-1$ - !newText.startsWith("ftp://") && //$NON-NLS-1$ - !newText.startsWith("http://") && //$NON-NLS-1$ - !newText.startsWith("https://")) { //$NON-NLS-1$ - return "Error: The URL must start by one of file://, ftp://, http:// or https://"; - } - - if (isEdit && newText.equals(initialValue)) { - // Edited value hasn't changed. This isn't an error. - return null; - } - - // Reject URLs that are already in the source list. - // URLs are generally case-insensitive (except for file:// where it all depends - // on the current OS so we'll ignore this case.) - for (SdkSource s : knownSources) { - if (newText.equalsIgnoreCase(s.getUrl())) { - return "Error: This site is already listed."; - } - } - - return null; - } - }); - - if (dlg.open() == Window.OK) { - String url = dlg.getValue().trim(); - - if (!url.equals(initialValue)) { - if (isEdit && initialValue != null) { - // Remove the old value before we add the new one, which is we just - // asserted will be different. - for (SdkSource source : mSources.getSources(SdkSourceCategory.USER_ADDONS)) { - if (initialValue.equals(source.getUrl())) { - mSources.remove(source); - break; - } - } - - } - - // create the source, store it and update the list - SdkSource newSource; - // use url suffix to decide whether this is a SysImg or Addon; - // see SdkSources.loadUserAddons() for another check like this - if (url.endsWith(SdkSysImgConstants.URL_DEFAULT_FILENAME)) { - newSource = new SdkSysImgSource(url, null/*uiName*/); - } else { - newSource = new SdkAddonSource(url, null/*uiName*/); - } - mSources.add(SdkSourceCategory.USER_ADDONS, newSource); - setReturnValue(true); - // notify sources change listeners. This will invoke our own loadUserUrlsList(). - mSources.notifyChangeListeners(); - - // select the new source - IStructuredSelection newSel = new StructuredSelection(newSource); - mUserTableViewer.setSelection(newSel, true /*reveal*/); - } - } - } - - private void on_UserButtonDelete_widgetSelected(SelectionEvent e) { - IStructuredSelection sel = (IStructuredSelection) mUserTableViewer.getSelection(); - String selectedUrl = sel.isEmpty() ? null : sel.getFirstElement().toString(); - - if (selectedUrl == null) { - return; - } - - MessageBox mb = new MessageBox(getShell(), - SWT.YES | SWT.NO | SWT.ICON_QUESTION | SWT.APPLICATION_MODAL); - mb.setText("Delete add-on site"); - mb.setMessage(String.format("Do you want to delete the URL %1$s?", selectedUrl)); - if (mb.open() == SWT.YES) { - for (SdkSource source : mSources.getSources(SdkSourceCategory.USER_ADDONS)) { - if (selectedUrl.equals(source.getUrl())) { - mSources.remove(source); - setReturnValue(true); - mSources.notifyChangeListeners(); - break; - } - } - } - } - - private void on_UserTable_mouseUp(MouseEvent event) { - Point p = new Point(event.x, event.y); - if (mUserTable.getItem(p) == null) { - mUserTable.deselectAll(); - on_UserTableViewer_selectionChanged(null /*event*/); - } - } - - private void on_UserTableViewer_selectionChanged(SelectionChangedEvent event) { - ISelection sel = mUserTableViewer.getSelection(); - mUserButtonDelete.setEnabled(!sel.isEmpty()); - mUserButtonEdit.setEnabled(!sel.isEmpty()); - } - - private void on_SitesTableViewer_checkStateChanged(CheckStateChangedEvent event) { - Object element = event.getElement(); - if (element instanceof SdkSource) { - SdkSource source = (SdkSource) element; - boolean isChecked = event.getChecked(); - if (source.isEnabled() != isChecked) { - setReturnValue(true); - source.setEnabled(isChecked); - mSources.notifyChangeListeners(); - } - } - } - - private void on_SitesTableViewer_selectAll() { - for (Object item : (Object[]) mSitesTableViewer.getInput()) { - if (!mSitesTableViewer.getChecked(item)) { - mSitesTableViewer.setChecked(item, true); - on_SitesTableViewer_checkStateChanged( - new CheckStateChangedEvent(mSitesTableViewer, item, true)); - } - } - } - - private void on_SitesTableViewer_deselectAll() { - for (Object item : (Object[]) mSitesTableViewer.getInput()) { - if (mSitesTableViewer.getChecked(item)) { - mSitesTableViewer.setChecked(item, false); - on_SitesTableViewer_checkStateChanged( - new CheckStateChangedEvent(mSitesTableViewer, item, false)); - } - } - } - - - @Override - protected void postCreate() { - // A runnable to initially load and then update the user urls & sites lists. - final Runnable updateInUiThread = new Runnable() { - @Override - public void run() { - loadUserUrlsList(); - loadSiteUrlsList(); - } - }; - - // A listener that runs when the sources have changed. - // This is most likely called on a worker thread. - mSourcesChangeListener = new Runnable() { - @Override - public void run() { - Shell shell = getShell(); - if (shell != null) { - Display display = shell.getDisplay(); - if (display != null) { - display.syncExec(updateInUiThread); - } - } - } - }; - - mSources.addChangeListener(mSourcesChangeListener); - - // initialize the list - updateInUiThread.run(); - } - - private void loadUserUrlsList() { - SdkSource[] knownSources = mSources.getSources(SdkSourceCategory.USER_ADDONS); - Arrays.sort(knownSources); - - ISelection oldSelection = mUserTableViewer.getSelection(); - - mUserTableViewer.setInput(knownSources); - mUserTableViewer.refresh(); - // initialize buttons' state that depend on the list - on_UserTableViewer_selectionChanged(null /*event*/); - - if (oldSelection != null && !oldSelection.isEmpty()) { - mUserTableViewer.setSelection(oldSelection, true /*reveal*/); - } - } - - private void loadSiteUrlsList() { - SdkSource[] knownSources = mSources.getSources(SdkSourceCategory.ADDONS_3RD_PARTY); - Arrays.sort(knownSources); - - ISelection oldSelection = mSitesTableViewer.getSelection(); - - mSitesTableViewer.setInput(knownSources); - mSitesTableViewer.refresh(); - - if (oldSelection != null && !oldSelection.isEmpty()) { - mSitesTableViewer.setSelection(oldSelection, true /*reveal*/); - } - - // Check the sources which are currently enabled. - ArrayList<SdkSource> disabled = new ArrayList<SdkSource>(knownSources.length); - for (SdkSource source : knownSources) { - if (source.isEnabled()) { - disabled.add(source); - } - } - mSitesTableViewer.setCheckedElements(disabled.toArray()); - } - - - private static class SourcesContentProvider implements IStructuredContentProvider { - @Override - public void dispose() { - // pass - } - - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // pass - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof SdkSource[]) { - return (Object[]) inputElement; - } else { - return new Object[0]; - } - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AdtUpdateDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AdtUpdateDialog.java deleted file mode 100755 index e90c3d9..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AdtUpdateDialog.java +++ /dev/null @@ -1,494 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - - -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.internal.repository.packages.ExtraPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.packages.PlatformPackage; -import com.android.sdklib.internal.repository.packages.PlatformToolPackage; -import com.android.sdklib.internal.repository.packages.ToolPackage; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdkuilib.internal.repository.SettingsController; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.core.PackageLoader; -import com.android.sdkuilib.internal.repository.core.SdkLogAdapter; -import com.android.sdkuilib.internal.repository.core.PackageLoader.IAutoInstallTask; -import com.android.sdkuilib.internal.tasks.ProgressView; -import com.android.sdkuilib.internal.tasks.ProgressViewFactory; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; -import com.android.sdkuilib.ui.SwtBaseDialog; -import com.android.utils.ILogger; -import com.android.utils.Pair; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.ProgressBar; -import org.eclipse.swt.widgets.Shell; - -import java.io.File; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * This is a private implementation of UpdateWindow for ADT, - * designed to install a very specific package. - * <p/> - * Example of usage: - * <pre> - * AdtUpdateDialog dialog = new AdtUpdateDialog( - * AdtPlugin.getDisplay().getActiveShell(), - * new AdtConsoleSdkLog(), - * sdk.getSdkLocation()); - * - * Pair<Boolean, File> result = dialog.installExtraPackage( - * "android", "compatibility"); //$NON-NLS-1$ //$NON-NLS-2$ - * or - * Pair<Boolean, File> result = dialog.installPlatformPackage(11); - * </pre> - */ -public class AdtUpdateDialog extends SwtBaseDialog { - - public static final int USE_MAX_REMOTE_API_LEVEL = 0; - - private static final String APP_NAME = "Android SDK Manager"; - private final UpdaterData mUpdaterData; - - private Boolean mResultCode = Boolean.FALSE; - private Map<Package, File> mResultPaths = null; - private SettingsController mSettingsController; - private PackageFilter mPackageFilter; - private PackageLoader mPackageLoader; - - private ProgressBar mProgressBar; - private Label mStatusText; - - /** - * Creates a new {@link AdtUpdateDialog}. - * Callers will want to call {@link #installExtraPackage} or - * {@link #installPlatformPackage} after this. - * - * @param parentShell The existing parent shell. Must not be null. - * @param sdkLog An SDK logger. Must not be null. - * @param osSdkRoot The current SDK root OS path. Must not be null or empty. - */ - public AdtUpdateDialog( - Shell parentShell, - ILogger sdkLog, - String osSdkRoot) { - super(parentShell, SWT.NONE, APP_NAME); - mUpdaterData = new UpdaterData(osSdkRoot, sdkLog); - } - - /** - * Displays the update dialog and triggers installation of the requested {@code extra} - * package with the specified vendor and path attributes. - * <p/> - * Callers must not try to reuse this dialog after this call. - * - * @param vendor The extra package vendor string to match. - * @param path The extra package path string to match. - * @return A boolean indicating whether the installation was successful (meaning the package - * was either already present, or got installed or updated properly) and a {@link File} - * with the path to the root folder of the package. The file is null when the boolean - * is false, otherwise it should point to an existing valid folder. - * @wbp.parser.entryPoint - */ - public Pair<Boolean, File> installExtraPackage(String vendor, String path) { - mPackageFilter = createExtraFilter(vendor, path); - open(); - - File installPath = null; - if (mResultPaths != null) { - for (Entry<Package, File> entry : mResultPaths.entrySet()) { - if (entry.getKey() instanceof ExtraPackage) { - installPath = entry.getValue(); - break; - } - } - } - - return Pair.of(mResultCode, installPath); - } - - /** - * Displays the update dialog and triggers installation of platform-tools package. - * <p/> - * Callers must not try to reuse this dialog after this call. - * - * @return A boolean indicating whether the installation was successful (meaning the package - * was either already present, or got installed or updated properly) and a {@link File} - * with the path to the root folder of the package. The file is null when the boolean - * is false, otherwise it should point to an existing valid folder. - * @wbp.parser.entryPoint - */ - public Pair<Boolean, File> installPlatformTools() { - mPackageFilter = createPlatformToolsFilter(); - open(); - - File installPath = null; - if (mResultPaths != null) { - for (Entry<Package, File> entry : mResultPaths.entrySet()) { - if (entry.getKey() instanceof ExtraPackage) { - installPath = entry.getValue(); - break; - } - } - } - - return Pair.of(mResultCode, installPath); - } - - /** - * Displays the update dialog and triggers installation of the requested platform - * package with the specified API level. - * <p/> - * Callers must not try to reuse this dialog after this call. - * - * @param apiLevel The platform API level to match. - * The special value {@link #USE_MAX_REMOTE_API_LEVEL} means to use - * the highest API level available on the remote repository. - * @return A boolean indicating whether the installation was successful (meaning the package - * was either already present, or got installed or updated properly) and a {@link File} - * with the path to the root folder of the package. The file is null when the boolean - * is false, otherwise it should point to an existing valid folder. - */ - public Pair<Boolean, File> installPlatformPackage(int apiLevel) { - mPackageFilter = createPlatformFilter(apiLevel); - open(); - - File installPath = null; - if (mResultPaths != null) { - for (Entry<Package, File> entry : mResultPaths.entrySet()) { - if (entry.getKey() instanceof PlatformPackage) { - installPath = entry.getValue(); - break; - } - } - } - - return Pair.of(mResultCode, installPath); - } - - /** - * Displays the update dialog and triggers installation of a new SDK. This works by - * requesting a remote platform package with the specified API levels as well as - * the first tools or platform-tools packages available. - * <p/> - * Callers must not try to reuse this dialog after this call. - * - * @param apiLevels A set of platform API levels to match. - * The special value {@link #USE_MAX_REMOTE_API_LEVEL} means to use - * the highest API level available in the repository. - * @return A boolean indicating whether the installation was successful (meaning the packages - * were either already present, or got installed or updated properly). - */ - public boolean installNewSdk(Set<Integer> apiLevels) { - mPackageFilter = createNewSdkFilter(apiLevels); - open(); - return mResultCode.booleanValue(); - } - - @Override - protected void createContents() { - Shell shell = getShell(); - shell.setMinimumSize(new Point(450, 100)); - shell.setSize(450, 100); - - mUpdaterData.setWindowShell(shell); - - GridLayoutBuilder.create(shell).columns(1); - - Composite composite1 = new Composite(shell, SWT.NONE); - composite1.setLayout(new GridLayout(1, false)); - GridDataBuilder.create(composite1).fill().grab(); - - mProgressBar = new ProgressBar(composite1, SWT.NONE); - GridDataBuilder.create(mProgressBar).hFill().hGrab(); - - mStatusText = new Label(composite1, SWT.NONE); - mStatusText.setText("Status Placeholder"); //$NON-NLS-1$ placeholder - GridDataBuilder.create(mStatusText).hFill().hGrab(); - } - - @Override - protected void postCreate() { - ProgressViewFactory factory = new ProgressViewFactory(); - factory.setProgressView(new ProgressView( - mStatusText, - mProgressBar, - null /*buttonStop*/, - new SdkLogAdapter(mUpdaterData.getSdkLog()))); - mUpdaterData.setTaskFactory(factory); - - setupSources(); - initializeSettings(); - - if (mUpdaterData.checkIfInitFailed()) { - close(); - return; - } - - mUpdaterData.broadcastOnSdkLoaded(); - - mPackageLoader = new PackageLoader(mUpdaterData); - } - - @Override - protected void eventLoop() { - mPackageLoader.loadPackagesWithInstallTask( - mPackageFilter.installFlags(), - new IAutoInstallTask() { - @Override - public Package[] filterLoadedSource(SdkSource source, Package[] packages) { - for (Package pkg : packages) { - mPackageFilter.visit(pkg); - } - return packages; - } - - @Override - public boolean acceptPackage(Package pkg) { - // Is this the package we want to install? - return mPackageFilter.accept(pkg); - } - - @Override - public void setResult(boolean success, Map<Package, File> installPaths) { - // Capture the result from the installation. - mResultCode = Boolean.valueOf(success); - mResultPaths = installPaths; - } - - @Override - public void taskCompleted() { - // We can close that window now. - close(); - } - }); - - super.eventLoop(); - } - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - // --- Public API ----------- - - - // --- Internals & UI Callbacks ----------- - - /** - * Used to initialize the sources. - */ - private void setupSources() { - mUpdaterData.setupDefaultSources(); - } - - /** - * Initializes settings. - */ - private void initializeSettings() { - mSettingsController = mUpdaterData.getSettingsController(); - mSettingsController.loadSettings(); - mSettingsController.applySettings(); - } - - // ---- - - private static abstract class PackageFilter { - /** Returns the installer flags for the corresponding mode. */ - abstract int installFlags(); - - /** Visit a new package definition, in case we need to adjust the filter dynamically. */ - abstract void visit(Package pkg); - - /** Checks whether this is the package we've been looking for. */ - abstract boolean accept(Package pkg); - } - - public static PackageFilter createExtraFilter( - final String vendor, - final String path) { - return new PackageFilter() { - String mVendor = vendor; - String mPath = path; - - @Override - boolean accept(Package pkg) { - if (pkg instanceof ExtraPackage) { - ExtraPackage ep = (ExtraPackage) pkg; - if (ep.getVendorId().equals(mVendor)) { - // Check actual extra <path> field first - if (ep.getPath().equals(mPath)) { - return true; - } - // If not, check whether this is one of the <old-paths> values. - for (String oldPath : ep.getOldPaths()) { - if (oldPath.equals(mPath)) { - return true; - } - } - } - } - return false; - } - - @Override - void visit(Package pkg) { - // nop - } - - @Override - int installFlags() { - return UpdaterData.TOOLS_MSG_UPDATED_FROM_ADT; - } - }; - } - - private PackageFilter createPlatformToolsFilter() { - return new PackageFilter() { - @Override - boolean accept(Package pkg) { - return pkg instanceof PlatformToolPackage; - } - - @Override - void visit(Package pkg) { - // nop - } - - @Override - int installFlags() { - return UpdaterData.TOOLS_MSG_UPDATED_FROM_ADT; - } - }; - } - - public static PackageFilter createPlatformFilter(final int apiLevel) { - return new PackageFilter() { - int mApiLevel = apiLevel; - boolean mFindMaxApi = apiLevel == USE_MAX_REMOTE_API_LEVEL; - - @Override - boolean accept(Package pkg) { - if (pkg instanceof PlatformPackage) { - PlatformPackage pp = (PlatformPackage) pkg; - AndroidVersion v = pp.getAndroidVersion(); - return !v.isPreview() && v.getApiLevel() == mApiLevel; - } - return false; - } - - @Override - void visit(Package pkg) { - // Try to find the max API in all remote packages - if (mFindMaxApi && - pkg instanceof PlatformPackage && - !pkg.isLocal()) { - PlatformPackage pp = (PlatformPackage) pkg; - AndroidVersion v = pp.getAndroidVersion(); - if (!v.isPreview()) { - int api = v.getApiLevel(); - if (api > mApiLevel) { - mApiLevel = api; - } - } - } - } - - @Override - int installFlags() { - return UpdaterData.TOOLS_MSG_UPDATED_FROM_ADT; - } - }; - } - - public static PackageFilter createNewSdkFilter(final Set<Integer> apiLevels) { - return new PackageFilter() { - int mMaxApiLevel; - boolean mFindMaxApi = apiLevels.contains(USE_MAX_REMOTE_API_LEVEL); - boolean mNeedTools = true; - boolean mNeedPlatformTools = true; - - @Override - boolean accept(Package pkg) { - if (!pkg.isLocal()) { - if (pkg instanceof PlatformPackage) { - PlatformPackage pp = (PlatformPackage) pkg; - AndroidVersion v = pp.getAndroidVersion(); - if (!v.isPreview()) { - int level = v.getApiLevel(); - if ((mFindMaxApi && level == mMaxApiLevel) || - (level > 0 && apiLevels.contains(level))) { - return true; - } - } - } else if (mNeedTools && pkg instanceof ToolPackage) { - // We want a tool package. There should be only one, - // but in case of error just take the first one. - mNeedTools = false; - return true; - } else if (mNeedPlatformTools && pkg instanceof PlatformToolPackage) { - // We want a platform-tool package. There should be only one, - // but in case of error just take the first one. - mNeedPlatformTools = false; - return true; - } - } - return false; - } - - @Override - void visit(Package pkg) { - // Try to find the max API in all remote packages - if (mFindMaxApi && - pkg instanceof PlatformPackage && - !pkg.isLocal()) { - PlatformPackage pp = (PlatformPackage) pkg; - AndroidVersion v = pp.getAndroidVersion(); - if (!v.isPreview()) { - int api = v.getApiLevel(); - if (api > mMaxApiLevel) { - mMaxApiLevel = api; - } - } - } - } - - @Override - int installFlags() { - return UpdaterData.NO_TOOLS_MSG; - } - }; - } - - - - // End of hiding from SWT Designer - //$hide<<$ - - // ----- - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AvdManagerPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AvdManagerPage.java deleted file mode 100755 index 1074dfa..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AvdManagerPage.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.devices.DeviceManager.DevicesChangeListener; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.widgets.AvdSelector; -import com.android.sdkuilib.internal.widgets.AvdSelector.DisplayMode; -import com.android.sdkuilib.repository.ISdkChangeListener; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; - -/** - * An Update page displaying AVD Manager entries. - * This is the sole page displayed by {@link AvdManagerWindowImpl1}. - * - * Note: historically the SDK Manager was a single window with several sub-pages and a tab - * switcher. For simplicity each page was separated in its own window. The AVD Manager is - * thus composed of the {@link AvdManagerWindowImpl1} (the window shell itself) and this - * page displays the actually list of AVDs and various action buttons. - */ -public class AvdManagerPage extends Composite - implements ISdkChangeListener, DevicesChangeListener, DisposeListener { - - private AvdSelector mAvdSelector; - - private final UpdaterData mUpdaterData; - private final DeviceManager mDeviceManager; - /** - * Create the composite. - * @param parent The parent of the composite. - * @param updaterData An instance of {@link UpdaterData}. - */ - public AvdManagerPage(Composite parent, - int swtStyle, - UpdaterData updaterData, - DeviceManager deviceManager) { - super(parent, swtStyle); - - mUpdaterData = updaterData; - mUpdaterData.addListeners(this); - - mDeviceManager = deviceManager; - mDeviceManager.registerListener(this); - - createContents(this); - postCreate(); //$hide$ - } - - private void createContents(Composite parent) { - parent.setLayout(new GridLayout(1, false)); - - Label label = new Label(parent, SWT.NONE); - label.setLayoutData(new GridData()); - - try { - if (mUpdaterData != null && mUpdaterData.getAvdManager() != null) { - label.setText(String.format( - "List of existing Android Virtual Devices located at %s", - mUpdaterData.getAvdManager().getBaseAvdFolder())); - } else { - label.setText("Error: cannot find the AVD folder location.\r\n Please set the 'ANDROID_SDK_HOME' env variable."); - } - } catch (AndroidLocationException e) { - label.setText(e.getMessage()); - } - - mAvdSelector = new AvdSelector(parent, - mUpdaterData.getOsSdkRoot(), - mUpdaterData.getAvdManager(), - DisplayMode.MANAGER, - mUpdaterData.getSdkLog()); - mAvdSelector.setSettingsController(mUpdaterData.getSettingsController()); - } - - @Override - public void widgetDisposed(DisposeEvent e) { - dispose(); - } - - @Override - public void dispose() { - mUpdaterData.removeListener(this); - mDeviceManager.unregisterListener(this); - super.dispose(); - } - - @Override - protected void checkSubclass() { - // Disable the check that prevents subclassing of SWT components - } - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - /** - * Called by the constructor right after {@link #createContents(Composite)}. - */ - private void postCreate() { - // nothing to be done for now. - } - - // --- Implementation of ISdkChangeListener --- - - @Override - public void onSdkLoaded() { - onSdkReload(); - } - - @Override - public void onSdkReload() { - mAvdSelector.refresh(false /*reload*/); - } - - @Override - public void preInstallHook() { - // nothing to be done for now. - } - - @Override - public void postInstallHook() { - // nothing to be done for now. - } - - // --- Implementation of DevicesChangeListener - - @Override - public void onDevicesChange() { - mAvdSelector.refresh(false /*reload*/); - } - - - // End of hiding from SWT Designer - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AvdManagerWindowImpl1.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AvdManagerWindowImpl1.java deleted file mode 100755 index ae6ba1c..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/AvdManagerWindowImpl1.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - - -import com.android.SdkConstants; -import com.android.sdklib.devices.Device; -import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdkuilib.internal.repository.AboutDialog; -import com.android.sdkuilib.internal.repository.MenuBarWrapper; -import com.android.sdkuilib.internal.repository.SettingsController; -import com.android.sdkuilib.internal.repository.SettingsDialog; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.internal.widgets.DeviceCreationDialog; -import com.android.sdkuilib.repository.AvdManagerWindow.AvdInvocationContext; -import com.android.sdkuilib.repository.ISdkChangeListener; -import com.android.sdkuilib.repository.SdkUpdaterWindow; -import com.android.utils.ILogger; - -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.Shell; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * This is an intermediate version of the {@link AvdManagerPage} - * wrapped in its own standalone window for use from the SDK Manager 2. - */ -public class AvdManagerWindowImpl1 { - - private static final String APP_NAME = "Android Virtual Device Manager"; - private static final String APP_NAME_MAC_MENU = "AVD Manager"; - private static final String SIZE_POS_PREFIX = "avdman1"; //$NON-NLS-1$ - - private final Shell mParentShell; - private final AvdInvocationContext mContext; - /** Internal data shared between the window and its pages. */ - private final UpdaterData mUpdaterData; - /** True if this window created the UpdaterData, in which case it needs to dispose it. */ - private final boolean mOwnUpdaterData; - private final DeviceManager mDeviceManager; - - - // --- UI members --- - - protected Shell mShell; - private AvdManagerPage mAvdPage; - private SettingsController mSettingsController; - - /** - * Creates a new window. Caller must call open(), which will block. - * - * @param parentShell Parent shell. - * @param sdkLog Logger. Cannot be null. - * @param osSdkRoot The OS path to the SDK root. - * @param context The {@link AvdInvocationContext} to change the behavior depending on who's - * opening the SDK Manager. - */ - public AvdManagerWindowImpl1( - Shell parentShell, - ILogger sdkLog, - String osSdkRoot, - AvdInvocationContext context) { - mParentShell = parentShell; - mContext = context; - mUpdaterData = new UpdaterData(osSdkRoot, sdkLog); - mOwnUpdaterData = true; - mDeviceManager = new DeviceManager(sdkLog); - } - - /** - * Creates a new window. Caller must call open(), which will block. - * <p/> - * This is to be used when the window is opened from {@link SdkUpdaterWindowImpl2} - * to share the same {@link UpdaterData} structure. - * - * @param parentShell Parent shell. - * @param updaterData The parent's updater data. - * @param context The {@link AvdInvocationContext} to change the behavior depending on who's - * opening the SDK Manager. - */ - public AvdManagerWindowImpl1( - Shell parentShell, - UpdaterData updaterData, - AvdInvocationContext context) { - mParentShell = parentShell; - mContext = context; - mUpdaterData = updaterData; - mOwnUpdaterData = false; - mDeviceManager = new DeviceManager(mUpdaterData.getSdkLog()); - } - - /** - * Opens the window. - * @wbp.parser.entryPoint - */ - public void open() { - if (mParentShell == null) { - Display.setAppName(APP_NAME); //$hide$ (hide from SWT designer) - } - - createShell(); - preCreateContent(); - createContents(); - createMenuBar(); - mShell.open(); - mShell.layout(); - - boolean ok = postCreateContent(); - - if (ok && mContext == AvdInvocationContext.STANDALONE) { - Display display = Display.getDefault(); - while (!mShell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - dispose(); //$hide$ - } - } - - private void createShell() { - // The AVD Manager must use a shell trim when standalone - // or a dialog trim when invoked from somewhere else. - int style = SWT.SHELL_TRIM; - if (mContext != AvdInvocationContext.STANDALONE) { - style |= SWT.APPLICATION_MODAL; - } - - mShell = new Shell(mParentShell, style); - mShell.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - ShellSizeAndPos.saveSizeAndPos(mShell, SIZE_POS_PREFIX); //$hide$ - onAndroidSdkUpdaterDispose(); //$hide$ - mAvdPage.dispose(); //$hide$ - } - }); - - GridLayout glShell = new GridLayout(2, false); - glShell.verticalSpacing = 0; - glShell.horizontalSpacing = 0; - glShell.marginWidth = 0; - glShell.marginHeight = 0; - mShell.setLayout(glShell); - - mShell.setMinimumSize(new Point(500, 300)); - mShell.setSize(700, 500); - mShell.setText(APP_NAME); - - ShellSizeAndPos.loadSizeAndPos(mShell, SIZE_POS_PREFIX); - } - - private void createContents() { - - mAvdPage = new AvdManagerPage(mShell, SWT.NONE, mUpdaterData, mDeviceManager); - mAvdPage.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); - } - - @SuppressWarnings("unused") - // MenuBarWrapper works using side effects - private void createMenuBar() { - Menu menuBar = new Menu(mShell, SWT.BAR); - mShell.setMenuBar(menuBar); - - // Only create the tools menu when running as standalone. - // We don't need the tools menu when invoked from the IDE, or the SDK Manager - // or from the AVD Chooser dialog. The only point of the tools menu is to - // get the about box, and invoke Tools > SDK Manager, which we don't - // need to do in these cases. - if (mContext == AvdInvocationContext.STANDALONE) { - - MenuItem menuBarTools = new MenuItem(menuBar, SWT.CASCADE); - menuBarTools.setText("Tools"); - - Menu menuTools = new Menu(menuBarTools); - menuBarTools.setMenu(menuTools); - - MenuItem manageSdk = new MenuItem(menuTools, SWT.NONE); - manageSdk.setText("Manage SDK..."); - manageSdk.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - onSdkManager(); - } - }); - - try { - new MenuBarWrapper(APP_NAME_MAC_MENU, menuTools) { - @Override - public void onPreferencesMenuSelected() { - SettingsDialog sd = new SettingsDialog(mShell, mUpdaterData); - sd.open(); - } - - @Override - public void onAboutMenuSelected() { - AboutDialog ad = new AboutDialog(mShell, mUpdaterData); - ad.open(); - } - - @Override - public void printError(String format, Object... args) { - if (mUpdaterData != null) { - mUpdaterData.getSdkLog().error(null, format, args); - } - } - }; - } catch (Throwable e) { - mUpdaterData.getSdkLog().error(e, "Failed to setup menu bar"); - e.printStackTrace(); - } - } - - MenuItem menuBarDevices = new MenuItem(menuBar, SWT.CASCADE); - menuBarDevices.setText("Devices"); - setupDevices(menuBarDevices); - } - - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - // --- Public API ----------- - - /** - * Adds a new listener to be notified when a change is made to the content of the SDK. - */ - public void addListener(ISdkChangeListener listener) { - mUpdaterData.addListeners(listener); - } - - /** - * Removes a new listener to be notified anymore when a change is made to the content of - * the SDK. - */ - public void removeListener(ISdkChangeListener listener) { - mUpdaterData.removeListener(listener); - } - - // --- Internals & UI Callbacks ----------- - - /** - * Called before the UI is created. - */ - private void preCreateContent() { - mUpdaterData.setWindowShell(mShell); - // We need the UI factory to create the UI - mUpdaterData.setImageFactory(new ImageFactory(mShell.getDisplay())); - // Note: we can't create the TaskFactory yet because we need the UI - // to be created first, so this is done in postCreateContent(). - } - - /** - * Once the UI has been created, initializes the content. - * This creates the pages, selects the first one, setup sources and scan for local folders. - * - * Returns true if we should show the window. - */ - private boolean postCreateContent() { - setWindowImage(mShell); - - setupSources(); - initializeSettings(); - - if (mUpdaterData.checkIfInitFailed()) { - return false; - } - - mUpdaterData.broadcastOnSdkLoaded(); - - return true; - } - - /** - * Creates the icon of the window shell. - * - * @param shell The shell on which to put the icon - */ - private void setWindowImage(Shell shell) { - String imageName = "android_icon_16.png"; //$NON-NLS-1$ - if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_DARWIN) { - imageName = "android_icon_128.png"; - } - - if (mUpdaterData != null) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - shell.setImage(imgFactory.getImageByName(imageName)); - } - } - } - - /** - * Called by the main loop when the window has been disposed. - */ - private void dispose() { - mUpdaterData.getSources().saveUserAddons(mUpdaterData.getSdkLog()); - } - - /** - * Callback called when the window shell is disposed. - */ - private void onAndroidSdkUpdaterDispose() { - if (mOwnUpdaterData && mUpdaterData != null) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - imgFactory.dispose(); - } - } - } - - /** - * Used to initialize the sources. - */ - private void setupSources() { - mUpdaterData.setupDefaultSources(); - } - - /** - * Sets up the devices in the device menu. - */ - @SuppressWarnings("unused") - private void setupDevices(final MenuItem menuBarDevices) { - Menu menuDevices = new Menu(menuBarDevices); - menuBarDevices.setMenu(menuDevices); - - MenuItem createDevice = new MenuItem(menuDevices, SWT.NONE); - createDevice.setText("Create New Device"); - createDevice.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - DeviceCreationDialog dlg = new DeviceCreationDialog( - mShell, mDeviceManager, mUpdaterData.getImageFactory(), null); - if (dlg.open() == Window.OK) { - setupDevices(menuBarDevices); - } - } - }); - new MenuItem(menuDevices, SWT.SEPARATOR); - - Map<String, List<Device>> devices = new HashMap<String, List<Device>>(); - for (Device d : mDeviceManager.getDevices(mUpdaterData.getOsSdkRoot())) { - List<Device> l; - if (devices.containsKey(d.getManufacturer())) { - l = devices.get(d.getManufacturer()); - } else { - l = new ArrayList<Device>(); - devices.put(d.getManufacturer(), l); - } - l.add(d); - } - - for (String manufacturer : devices.keySet()) { - MenuItem manufacturerItem = new MenuItem(menuDevices, SWT.CASCADE); - manufacturerItem.setText(manufacturer); - Menu manufacturerMenu = new Menu(menuDevices); - manufacturerItem.setMenu(manufacturerMenu); - for (final Device d : devices.get(manufacturer)) { - MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.NONE); - deviceItem.setText(d.getName()); - deviceItem.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - DeviceCreationDialog dlg = new DeviceCreationDialog( - mShell, mDeviceManager, mUpdaterData.getImageFactory(), d); - if(dlg.open() == Window.OK) { - setupDevices(menuBarDevices); - } - } - }); - } - } - } - - /** - * Initializes settings. - * This must be called after addExtraPages(), which created a settings page. - * Iterate through all the pages to find the first (and supposedly unique) setting page, - * and use it to load and apply these settings. - */ - private void initializeSettings() { - mSettingsController = mUpdaterData.getSettingsController(); - mSettingsController.loadSettings(); - mSettingsController.applySettings(); - } - - private void onSdkManager() { - ITaskFactory oldFactory = mUpdaterData.getTaskFactory(); - - try { - SdkUpdaterWindowImpl2 win = new SdkUpdaterWindowImpl2( - mShell, - mUpdaterData, - SdkUpdaterWindow.SdkInvocationContext.AVD_MANAGER); - - win.open(); - } catch (Exception e) { - mUpdaterData.getSdkLog().error(e, "SDK Manager window error"); - } finally { - mUpdaterData.setTaskFactory(oldFactory); - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/LogWindow.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/LogWindow.java deleted file mode 100755 index 43dbaf5..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/LogWindow.java +++ /dev/null @@ -1,379 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import com.android.sdkuilib.internal.tasks.ILogUiProvider; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; -import com.android.utils.ILogger; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyleRange; -import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.ShellAdapter; -import org.eclipse.swt.events.ShellEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Widget; - - -/** - * A floating log window that can be displayed or hidden by the main SDK Manager 2 window. - * It displays a log of the sdk manager operation (listing, install, delete) including - * any errors (e.g. network error or install/delete errors.) - * <p/> - * Since the SDK Manager will direct all log to this window, its purpose is to be - * opened by the main window at startup and left open all the time. When not needed - * the floating window is hidden but not closed. This way it can easily accumulate - * all the log. - */ -class LogWindow implements ILogUiProvider { - - private Shell mParentShell; - private Shell mShell; - private Composite mRootComposite; - private StyledText mStyledText; - private Label mLogDescription; - private Button mCloseButton; - - private final ILogger mSecondaryLog; - private boolean mCloseRequested; - private boolean mInitPosition = true; - private String mLastLogMsg = null; - - private enum TextStyle { - DEFAULT, - TITLE, - ERROR - } - - /** - * Creates the floating window. Callers should use {@link #open()} later. - * - * @param parentShell Parent container - * @param secondaryLog An optional logger where messages will <em>also</em> be output. - */ - public LogWindow(Shell parentShell, ILogger secondaryLog) { - mParentShell = parentShell; - mSecondaryLog = secondaryLog; - } - - /** - * For testing only. See {@link #open()} and {@link #close()} for normal usage. - * @wbp.parser.entryPoint - */ - void openBlocking() { - open(); - Display display = Display.getDefault(); - while (!mShell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - close(); - } - - /** - * Opens the window. - * This call does not block and relies on the fact that the main window is - * already running an SWT event dispatch loop. - * Caller should use {@link #close()} later. - */ - public void open() { - createShell(); - createContents(); - mShell.open(); - mShell.layout(); - mShell.setVisible(false); - } - - /** - * Closes and <em>destroys</em> the window. - * This must be called just before quitting the app. - * <p/> - * To simply hide/show the window, use {@link #setVisible(boolean)} instead. - */ - public void close() { - if (mShell != null && !mShell.isDisposed()) { - mCloseRequested = true; - mShell.close(); - mShell = null; - } - } - - /** - * Determines whether the window is currently shown or not. - * - * @return True if the window is shown. - */ - public boolean isVisible() { - return mShell != null && !mShell.isDisposed() && mShell.isVisible(); - } - - /** - * Toggles the window visibility. - * - * @param visible True to make the window visible, false to hide it. - */ - public void setVisible(boolean visible) { - if (mShell != null && !mShell.isDisposed()) { - mShell.setVisible(visible); - if (visible && mInitPosition) { - mInitPosition = false; - positionWindow(); - } - } - } - - private void createShell() { - mShell = new Shell(mParentShell, SWT.SHELL_TRIM | SWT.TOOL); - mShell.setMinimumSize(new Point(600, 300)); - mShell.setSize(450, 300); - mShell.setText("Android SDK Manager Log"); - GridLayoutBuilder.create(mShell); - - mShell.addShellListener(new ShellAdapter() { - @Override - public void shellClosed(ShellEvent e) { - if (!mCloseRequested) { - e.doit = false; - setVisible(false); - } - } - }); - } - - /** - * Create contents of the dialog. - */ - private void createContents() { - mRootComposite = new Composite(mShell, SWT.NONE); - GridLayoutBuilder.create(mRootComposite).columns(2); - GridDataBuilder.create(mRootComposite).fill().grab(); - - mStyledText = new StyledText(mRootComposite, - SWT.BORDER | SWT.MULTI | SWT.READ_ONLY | SWT.WRAP | SWT.V_SCROLL); - GridDataBuilder.create(mStyledText).hSpan(2).fill().grab(); - - mLogDescription = new Label(mRootComposite, SWT.NONE); - GridDataBuilder.create(mLogDescription).hFill().hGrab(); - - mCloseButton = new Button(mRootComposite, SWT.NONE); - mCloseButton.setText("Close"); - mCloseButton.setToolTipText("Closes the log window"); - mCloseButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setVisible(false); //$hide$ - } - }); - } - - // --- Implementation of ILogUiProvider --- - - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - @Override - public void setDescription(final String description) { - syncExec(mLogDescription, new Runnable() { - @Override - public void run() { - mLogDescription.setText(description); - - if (acceptLog(description, true /*isDescription*/)) { - appendLine(TextStyle.TITLE, description); - - if (mSecondaryLog != null) { - mSecondaryLog.info("%1$s", description); //$NON-NLS-1$ - } - } - } - }); - } - - /** - * Logs a "normal" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void log(final String log) { - if (acceptLog(log, false /*isDescription*/)) { - syncExec(mLogDescription, new Runnable() { - @Override - public void run() { - appendLine(TextStyle.DEFAULT, log); - } - }); - - if (mSecondaryLog != null) { - mSecondaryLog.info(" %1$s", log); //$NON-NLS-1$ - } - } - } - - /** - * Logs an "error" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logError(final String log) { - if (acceptLog(log, false /*isDescription*/)) { - syncExec(mLogDescription, new Runnable() { - @Override - public void run() { - appendLine(TextStyle.ERROR, log); - } - }); - - if (mSecondaryLog != null) { - mSecondaryLog.error(null, "%1$s", log); //$NON-NLS-1$ - } - } - } - - /** - * Logs a "verbose" information line, that is extra details which are typically - * not that useful for the end-user and might be hidden until explicitly shown. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logVerbose(final String log) { - if (acceptLog(log, false /*isDescription*/)) { - syncExec(mLogDescription, new Runnable() { - @Override - public void run() { - appendLine(TextStyle.DEFAULT, " " + log); //$NON-NLS-1$ - } - }); - - if (mSecondaryLog != null) { - mSecondaryLog.info(" %1$s", log); //$NON-NLS-1$ - } - } - } - - - // ---- - - - /** - * Centers the dialog in its parent shell. - */ - private void positionWindow() { - // Centers the dialog in its parent shell - Shell child = mShell; - if (child != null && mParentShell != null) { - // get the parent client area with a location relative to the display - Rectangle parentArea = mParentShell.getClientArea(); - Point parentLoc = mParentShell.getLocation(); - int px = parentLoc.x; - int py = parentLoc.y; - int pw = parentArea.width; - int ph = parentArea.height; - - Point childSize = child.getSize(); - int cw = Math.max(childSize.x, pw); - int ch = childSize.y; - - int x = 30 + px + (pw - cw) / 2; - if (x < 0) x = 0; - - int y = py + (ph - ch) / 2; - if (y < py) y = py; - - child.setLocation(x, y); - child.setSize(cw, ch); - } - } - - private void appendLine(TextStyle style, String text) { - if (!text.endsWith("\n")) { //$NON-NLS-1$ - text += '\n'; - } - - int start = mStyledText.getCharCount(); - - if (style == TextStyle.DEFAULT) { - mStyledText.append(text); - - } else { - mStyledText.append(text); - - StyleRange sr = new StyleRange(); - sr.start = start; - sr.length = text.length(); - sr.fontStyle = SWT.BOLD; - if (style == TextStyle.ERROR) { - sr.foreground = mStyledText.getDisplay().getSystemColor(SWT.COLOR_DARK_RED); - } - sr.underline = false; - mStyledText.setStyleRange(sr); - } - - // Scroll caret if it was already at the end before we added new text. - // Ideally we would scroll if the scrollbar is at the bottom but we don't - // have direct access to the scrollbar without overriding the SWT impl. - if (mStyledText.getCaretOffset() >= start) { - mStyledText.setSelection(mStyledText.getCharCount()); - } - } - - - private void syncExec(final Widget widget, final Runnable runnable) { - if (widget != null && !widget.isDisposed()) { - widget.getDisplay().syncExec(runnable); - } - } - - /** - * Filter messages displayed in the log: <br/> - * - Messages with a % are typical part of a progress update and shouldn't be in the log. <br/> - * - Messages that are the same as the same output message should be output a second time. - * - * @param msg The potential log line to print. - * @return True if the log line should be printed, false otherwise. - */ - private boolean acceptLog(String msg, boolean isDescription) { - if (msg == null) { - return false; - } - - msg = msg.trim(); - - // Descriptions also have the download progress status (0..100%) which we want to avoid - if (isDescription && msg.indexOf('%') != -1) { - return false; - } - - if (msg.equals(mLastLogMsg)) { - return false; - } - - mLastLogMsg = msg; - return true; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPage.java deleted file mode 100755 index 025be46..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPage.java +++ /dev/null @@ -1,1280 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.archives.ArchiveInstaller; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.core.PkgCategory; -import com.android.sdkuilib.internal.repository.core.PkgCategoryApi; -import com.android.sdkuilib.internal.repository.core.PkgContentProvider; -import com.android.sdkuilib.internal.repository.core.PkgItem; -import com.android.sdkuilib.internal.repository.core.PkgItem.PkgState; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.repository.ISdkChangeListener; -import com.android.sdkuilib.repository.SdkUpdaterWindow.SdkInvocationContext; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; -import org.eclipse.jface.viewers.DoubleClickEvent; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.IDoubleClickListener; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.ITreeSelection; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.jface.window.ToolTip; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Link; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.Tree; -import org.eclipse.swt.widgets.TreeColumn; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -/** - * Page that displays both locally installed packages as well as all known - * remote available packages. This gives an overview of what is installed - * vs what is available and allows the user to update or install packages. - */ -public final class PackagesPage extends Composite implements ISdkChangeListener { - - enum MenuAction { - RELOAD (SWT.NONE, "Reload"), - SHOW_ADDON_SITES (SWT.NONE, "Manage Add-on Sites..."), - TOGGLE_SHOW_ARCHIVES (SWT.CHECK, "Show Archives Details"), - TOGGLE_SHOW_INSTALLED_PKG (SWT.CHECK, "Show Installed Packages"), - TOGGLE_SHOW_OBSOLETE_PKG (SWT.CHECK, "Show Obsolete Packages"), - TOGGLE_SHOW_UPDATE_NEW_PKG (SWT.CHECK, "Show Updates/New Packages"), - SORT_API_LEVEL (SWT.RADIO, "Sort by API Level"), - SORT_SOURCE (SWT.RADIO, "Sort by Repository") - ; - - private final int mMenuStyle; - private final String mMenuTitle; - - MenuAction(int menuStyle, String menuTitle) { - mMenuStyle = menuStyle; - mMenuTitle = menuTitle; - } - - public int getMenuStyle() { - return mMenuStyle; - } - - public String getMenuTitle() { - return mMenuTitle; - } - }; - - private final Map<MenuAction, MenuItem> mMenuActions = new HashMap<MenuAction, MenuItem>(); - - private final PackagesPageImpl mImpl; - private final SdkInvocationContext mContext; - - private boolean mDisplayArchives = false; - private boolean mOperationPending; - - private Composite mGroupPackages; - private Text mTextSdkOsPath; - private Button mCheckSortSource; - private Button mCheckSortApi; - private Button mCheckFilterObsolete; - private Button mCheckFilterInstalled; - private Button mCheckFilterNew; - private Composite mGroupOptions; - private Composite mGroupSdk; - private Button mButtonDelete; - private Button mButtonInstall; - private Font mTreeFontItalic; - private TreeColumn mTreeColumnName; - private CheckboxTreeViewer mTreeViewer; - - public PackagesPage( - Composite parent, - int swtStyle, - UpdaterData updaterData, - SdkInvocationContext context) { - super(parent, swtStyle); - mImpl = new PackagesPageImpl(updaterData) { - @Override - protected boolean isUiDisposed() { - return mGroupPackages == null || mGroupPackages.isDisposed(); - }; - @Override - protected void syncExec(Runnable runnable) { - if (!isUiDisposed()) { - mGroupPackages.getDisplay().syncExec(runnable); - } - }; - @Override - protected void refreshViewerInput() { - PackagesPage.this.refreshViewerInput(); - } - - @Override - protected boolean isSortByApi() { - return PackagesPage.this.isSortByApi(); - } - - @Override - protected Font getTreeFontItalic() { - return mTreeFontItalic; - } - - @Override - protected void loadPackages(boolean useLocalCache, boolean overrideExisting) { - PackagesPage.this.loadPackages(useLocalCache, overrideExisting); - } - }; - mContext = context; - - createContents(this); - postCreate(); //$hide$ - } - - public void performFirstLoad() { - mImpl.performFirstLoad(); - } - - @SuppressWarnings("unused") - private void createContents(Composite parent) { - GridLayoutBuilder.create(parent).noMargins().columns(2); - - mGroupSdk = new Composite(parent, SWT.NONE); - GridDataBuilder.create(mGroupSdk).hFill().vCenter().hGrab().hSpan(2); - GridLayoutBuilder.create(mGroupSdk).columns(2); - - Label label1 = new Label(mGroupSdk, SWT.NONE); - label1.setText("SDK Path:"); - - mTextSdkOsPath = new Text(mGroupSdk, SWT.NONE); - GridDataBuilder.create(mTextSdkOsPath).hFill().vCenter().hGrab(); - mTextSdkOsPath.setEnabled(false); - - Group groupPackages = new Group(parent, SWT.NONE); - mGroupPackages = groupPackages; - GridDataBuilder.create(mGroupPackages).fill().grab().hSpan(2); - groupPackages.setText("Packages"); - GridLayoutBuilder.create(groupPackages).columns(1); - - mTreeViewer = new CheckboxTreeViewer(groupPackages, SWT.BORDER); - mImpl.setITreeViewer(new PackagesPageImpl.ICheckboxTreeViewer() { - @Override - public Object getInput() { - return mTreeViewer.getInput(); - } - - @Override - public void setInput(List<PkgCategory> cats) { - mTreeViewer.setInput(cats); - } - - @Override - public void setContentProvider(PkgContentProvider pkgContentProvider) { - mTreeViewer.setContentProvider(pkgContentProvider); - } - - @Override - public void refresh() { - mTreeViewer.refresh(); - } - - @Override - public Object[] getCheckedElements() { - return mTreeViewer.getCheckedElements(); - } - }); - mTreeViewer.addFilter(new ViewerFilter() { - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - return filterViewerItem(element); - } - }); - - mTreeViewer.addCheckStateListener(new ICheckStateListener() { - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - onTreeCheckStateChanged(event); //$hide$ - } - }); - - mTreeViewer.addDoubleClickListener(new IDoubleClickListener() { - @Override - public void doubleClick(DoubleClickEvent event) { - onTreeDoubleClick(event); //$hide$ - } - }); - - Tree tree = mTreeViewer.getTree(); - tree.setLinesVisible(true); - tree.setHeaderVisible(true); - GridDataBuilder.create(tree).fill().grab(); - - // column name icon is set when loading depending on the current filter type - // (e.g. API level or source) - TreeViewerColumn columnName = new TreeViewerColumn(mTreeViewer, SWT.NONE); - mTreeColumnName = columnName.getColumn(); - mTreeColumnName.setText("Name"); - mTreeColumnName.setWidth(340); - - TreeViewerColumn columnApi = new TreeViewerColumn(mTreeViewer, SWT.NONE); - TreeColumn treeColumn2 = columnApi.getColumn(); - treeColumn2.setText("API"); - treeColumn2.setAlignment(SWT.CENTER); - treeColumn2.setWidth(50); - - TreeViewerColumn columnRevision = new TreeViewerColumn(mTreeViewer, SWT.NONE); - TreeColumn treeColumn3 = columnRevision.getColumn(); - treeColumn3.setText("Rev."); - treeColumn3.setToolTipText("Revision currently installed"); - treeColumn3.setAlignment(SWT.CENTER); - treeColumn3.setWidth(50); - - - TreeViewerColumn columnStatus = new TreeViewerColumn(mTreeViewer, SWT.NONE); - TreeColumn treeColumn4 = columnStatus.getColumn(); - treeColumn4.setText("Status"); - treeColumn4.setAlignment(SWT.LEAD); - treeColumn4.setWidth(190); - - mImpl.setIColumns( - wrapColumn(columnName), - wrapColumn(columnApi), - wrapColumn(columnRevision), - wrapColumn(columnStatus)); - - mGroupOptions = new Composite(groupPackages, SWT.NONE); - GridDataBuilder.create(mGroupOptions).hFill().vCenter().hGrab(); - GridLayoutBuilder.create(mGroupOptions).columns(6).noMargins(); - - // Options line 1, 6 columns - - Label label3 = new Label(mGroupOptions, SWT.NONE); - label3.setText("Show:"); - - mCheckFilterNew = new Button(mGroupOptions, SWT.CHECK); - mCheckFilterNew.setText("Updates/New"); - mCheckFilterNew.setToolTipText("Show Updates and New"); - mCheckFilterNew.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - refreshViewerInput(); - } - }); - mCheckFilterNew.setSelection(true); - - mCheckFilterInstalled = new Button(mGroupOptions, SWT.CHECK); - mCheckFilterInstalled.setToolTipText("Show Installed"); - mCheckFilterInstalled.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - refreshViewerInput(); - } - }); - mCheckFilterInstalled.setSelection(true); - mCheckFilterInstalled.setText("Installed"); - - mCheckFilterObsolete = new Button(mGroupOptions, SWT.CHECK); - mCheckFilterObsolete.setText("Obsolete"); - mCheckFilterObsolete.setToolTipText("Also show obsolete packages"); - mCheckFilterObsolete.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - refreshViewerInput(); - } - }); - mCheckFilterObsolete.setSelection(false); - - Link linkSelectNew = new Link(mGroupOptions, SWT.NONE); - // Note for i18n: we need to identify which link is used, and this is done by using the - // text itself so for translation purposes we want to keep the <a> link strings separate. - final String strLinkNew = "New"; - final String strLinkUpdates = "Updates"; - linkSelectNew.setText( - String.format("Select <a>%1$s</a> or <a>%2$s</a>", strLinkNew, strLinkUpdates)); - linkSelectNew.setToolTipText("Selects all items that are either new or updates."); - GridDataBuilder.create(linkSelectNew).hFill().hGrab(); - linkSelectNew.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - boolean selectNew = e.text == null || e.text.equals(strLinkNew); - onSelectNewUpdates(selectNew, !selectNew, false/*selectTop*/); - } - }); - - mButtonInstall = new Button(mGroupOptions, SWT.NONE); - mButtonInstall.setText(""); //$NON-NLS-1$ placeholder, filled in updateButtonsState() - mButtonInstall.setToolTipText("Install one or more packages"); - GridDataBuilder.create(mButtonInstall).hFill().vCenter().hGrab(); - mButtonInstall.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onButtonInstall(); //$hide$ - } - }); - - // Options line 2, 6 columns - - Label label2 = new Label(mGroupOptions, SWT.NONE); - label2.setText("Sort by:"); - - mCheckSortApi = new Button(mGroupOptions, SWT.RADIO); - mCheckSortApi.setToolTipText("Sort by API level"); - mCheckSortApi.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (mCheckSortApi.getSelection()) { - refreshViewerInput(); - copySelection(true /*toApi*/); - syncViewerSelection(); - } - } - }); - mCheckSortApi.setText("API level"); - mCheckSortApi.setSelection(true); - - mCheckSortSource = new Button(mGroupOptions, SWT.RADIO); - mCheckSortSource.setText("Repository"); - mCheckSortSource.setToolTipText("Sort by Repository"); - mCheckSortSource.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - if (mCheckSortSource.getSelection()) { - refreshViewerInput(); - copySelection(false /*toApi*/); - syncViewerSelection(); - } - } - }); - - new Label(mGroupOptions, SWT.NONE); - - Link linkDeselect = new Link(mGroupOptions, SWT.NONE); - linkDeselect.setText("<a>Deselect All</a>"); - linkDeselect.setToolTipText("Deselects all the currently selected items"); - GridDataBuilder.create(linkDeselect).hFill().hGrab(); - linkDeselect.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - onDeselectAll(); - } - }); - - mButtonDelete = new Button(mGroupOptions, SWT.NONE); - mButtonDelete.setText(""); //$NON-NLS-1$ placeholder, filled in updateButtonsState() - mButtonDelete.setToolTipText("Delete one ore more installed packages"); - GridDataBuilder.create(mButtonDelete).hFill().vCenter().hGrab(); - mButtonDelete.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onButtonDelete(); //$hide$ - } - }); - } - - private PackagesPageImpl.ITreeViewerColumn wrapColumn(final TreeViewerColumn column) { - return new PackagesPageImpl.ITreeViewerColumn() { - @Override - public void setLabelProvider(ColumnLabelProvider labelProvider) { - column.setLabelProvider(labelProvider); - } - }; - } - - private Image getImage(String filename) { - if (mImpl.mUpdaterData != null) { - ImageFactory imgFactory = mImpl.mUpdaterData.getImageFactory(); - if (imgFactory != null) { - return imgFactory.getImageByName(filename); - } - } - return null; - } - - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - - // --- menu interactions --- - - public void registerMenuAction(final MenuAction action, MenuItem item) { - item.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - Button button = null; - - switch (action) { - case RELOAD: - mImpl.fullReload(); - break; - case SHOW_ADDON_SITES: - AddonSitesDialog d = new AddonSitesDialog(getShell(), mImpl.mUpdaterData); - if (d.open()) { - mImpl.loadPackages(); - } - break; - case TOGGLE_SHOW_ARCHIVES: - mDisplayArchives = !mDisplayArchives; - // Force the viewer to be refreshed - ((PkgContentProvider) mTreeViewer.getContentProvider()). - setDisplayArchives(mDisplayArchives); - mTreeViewer.setInput(null); - refreshViewerInput(); - syncViewerSelection(); - updateButtonsState(); - break; - case TOGGLE_SHOW_INSTALLED_PKG: - button = mCheckFilterInstalled; - break; - case TOGGLE_SHOW_OBSOLETE_PKG: - button = mCheckFilterObsolete; - break; - case TOGGLE_SHOW_UPDATE_NEW_PKG: - button = mCheckFilterNew; - break; - case SORT_API_LEVEL: - button = mCheckSortApi; - break; - case SORT_SOURCE: - button = mCheckSortSource; - break; - } - - if (button != null && !button.isDisposed()) { - // Toggle this button (radio or checkbox) - - boolean value = button.getSelection(); - - // SWT doesn't automatically switch radio buttons when using the - // Widget#setSelection method, so we'll do it here manually. - if (!value && (button.getStyle() & SWT.RADIO) != 0) { - // we'll be selecting this radio button, so deselect all ther other ones - // in the parent group. - for (Control child : button.getParent().getChildren()) { - if (child instanceof Button && - child != button && - (child.getStyle() & SWT.RADIO) != 0) { - ((Button) child).setSelection(value); - } - } - } - - button.setSelection(!value); - - // SWT doesn't actually invoke the listeners when using Widget#setSelection - // so let's run the actual action. - button.notifyListeners(SWT.Selection, new Event()); - } - - updateMenuCheckmarks(); - } - }); - - mMenuActions.put(action, item); - } - - // --- internal methods --- - - private void updateMenuCheckmarks() { - - for (Entry<MenuAction, MenuItem> entry : mMenuActions.entrySet()) { - MenuAction action = entry.getKey(); - MenuItem item = entry.getValue(); - - if (action.getMenuStyle() == SWT.NONE) { - continue; - } - - boolean value = false; - Button button = null; - - switch (action) { - case TOGGLE_SHOW_ARCHIVES: - value = mDisplayArchives; - break; - case TOGGLE_SHOW_INSTALLED_PKG: - button = mCheckFilterInstalled; - break; - case TOGGLE_SHOW_OBSOLETE_PKG: - button = mCheckFilterObsolete; - break; - case TOGGLE_SHOW_UPDATE_NEW_PKG: - button = mCheckFilterNew; - break; - case SORT_API_LEVEL: - button = mCheckSortApi; - break; - case SORT_SOURCE: - button = mCheckSortSource; - break; - } - - if (button != null && !button.isDisposed()) { - value = button.getSelection(); - } - - if (!item.isDisposed()) { - item.setSelection(value); - } - } - } - - private void postCreate() { - mImpl.postCreate(); - - if (mImpl.mUpdaterData != null) { - mTextSdkOsPath.setText(mImpl.mUpdaterData.getOsSdkRoot()); - } - - ((PkgContentProvider) mTreeViewer.getContentProvider()).setDisplayArchives( - mDisplayArchives); - - ColumnViewerToolTipSupport.enableFor(mTreeViewer, ToolTip.NO_RECREATE); - - Tree tree = mTreeViewer.getTree(); - FontData fontData = tree.getFont().getFontData()[0]; - fontData.setStyle(SWT.ITALIC); - mTreeFontItalic = new Font(tree.getDisplay(), fontData); - - tree.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - mTreeFontItalic.dispose(); - mTreeFontItalic = null; - } - }); - } - - private void loadPackages(boolean useLocalCache, boolean overrideExisting) { - if (mImpl.mUpdaterData == null) { - return; - } - - // LoadPackage is synchronous but does not block the UI. - // Consequently it's entirely possible for the user - // to request the app to close whilst the packages are loading. Any - // action done after loadPackages must check the UI hasn't been - // disposed yet. Otherwise hilarity ensues. - - boolean displaySortByApi = isSortByApi(); - - if (mTreeColumnName.isDisposed()) { - // If the UI got disposed, don't try to load anything since we won't be - // able to display it anyway. - return; - } - - mTreeColumnName.setImage(getImage( - displaySortByApi ? PackagesPageIcons.ICON_SORT_BY_API - : PackagesPageIcons.ICON_SORT_BY_SOURCE)); - - mImpl.loadPackagesImpl(useLocalCache, overrideExisting); - } - - private void refreshViewerInput() { - // Dynamically update the table while we load after each source. - // Since the official Android source gets loaded first, it makes the - // window look non-empty a lot sooner. - if (!mGroupPackages.isDisposed()) { - try { - mImpl.setViewerInput(); - } catch (Exception ignore) {} - - // set the initial expanded state - expandInitial(mTreeViewer.getInput()); - - updateButtonsState(); - updateMenuCheckmarks(); - } - } - - private boolean isSortByApi() { - return mCheckSortApi != null && !mCheckSortApi.isDisposed() && mCheckSortApi.getSelection(); - } - - /** - * Decide whether to keep an item in the current tree based on user-chosen filter options. - */ - private boolean filterViewerItem(Object treeElement) { - if (treeElement instanceof PkgCategory) { - PkgCategory cat = (PkgCategory) treeElement; - - if (!cat.getItems().isEmpty()) { - // A category is hidden if all of its content is hidden. - // However empty categories are always visible. - for (PkgItem item : cat.getItems()) { - if (filterViewerItem(item)) { - // We found at least one element that is visible. - return true; - } - } - return false; - } - } - - if (treeElement instanceof PkgItem) { - PkgItem item = (PkgItem) treeElement; - - if (!mCheckFilterObsolete.getSelection()) { - if (item.isObsolete()) { - return false; - } - } - - if (!mCheckFilterInstalled.getSelection()) { - if (item.getState() == PkgState.INSTALLED) { - return false; - } - } - - if (!mCheckFilterNew.getSelection()) { - if (item.getState() == PkgState.NEW || item.hasUpdatePkg()) { - return false; - } - } - } - - return true; - } - - /** - * Performs the initial expansion of the tree. This expands categories that contain - * at least one installed item and collapses the ones with nothing installed. - * - * TODO: change this to only change the expanded state on categories that have not - * been touched by the user yet. Once we do that, call this every time a new source - * is added or the list is reloaded. - */ - private void expandInitial(Object elem) { - if (elem == null) { - return; - } - if (mTreeViewer != null && !mTreeViewer.getTree().isDisposed()) { - - boolean enablePreviews = - mImpl.mUpdaterData.getSettingsController().getSettings().getEnablePreviews(); - - mTreeViewer.setExpandedState(elem, true); - nextCategory: for (Object pkg : - ((ITreeContentProvider) mTreeViewer.getContentProvider()). - getChildren(elem)) { - if (pkg instanceof PkgCategory) { - PkgCategory cat = (PkgCategory) pkg; - - // Always expand the Tools category (and the preview one, if enabled) - if (cat.getKey().equals(PkgCategoryApi.KEY_TOOLS) || - (enablePreviews && - cat.getKey().equals(PkgCategoryApi.KEY_TOOLS_PREVIEW))) { - expandInitial(pkg); - continue nextCategory; - } - - - for (PkgItem item : cat.getItems()) { - if (item.getState() == PkgState.INSTALLED) { - expandInitial(pkg); - continue nextCategory; - } - } - } - } - } - } - - /** - * Handle checking and unchecking of the tree items. - * - * When unchecking, all sub-tree items checkboxes are cleared too. - * When checking a source, all of its packages are checked too. - * When checking a package, only its compatible archives are checked. - */ - private void onTreeCheckStateChanged(CheckStateChangedEvent event) { - boolean checked = event.getChecked(); - Object elem = event.getElement(); - - assert event.getSource() == mTreeViewer; - - // When selecting, we want to only select compatible archives and expand the super nodes. - checkAndExpandItem(elem, checked, true/*fixChildren*/, true/*fixParent*/); - updateButtonsState(); - } - - private void onTreeDoubleClick(DoubleClickEvent event) { - assert event.getSource() == mTreeViewer; - ISelection sel = event.getSelection(); - if (sel.isEmpty() || !(sel instanceof ITreeSelection)) { - return; - } - ITreeSelection tsel = (ITreeSelection) sel; - Object elem = tsel.getFirstElement(); - if (elem == null) { - return; - } - - ITreeContentProvider provider = - (ITreeContentProvider) mTreeViewer.getContentProvider(); - Object[] children = provider.getElements(elem); - if (children == null) { - return; - } - - if (children.length > 0) { - // If the element has children, expand/collapse it. - if (mTreeViewer.getExpandedState(elem)) { - mTreeViewer.collapseToLevel(elem, 1); - } else { - mTreeViewer.expandToLevel(elem, 1); - } - } else { - // If the element is a terminal one, select/deselect it. - checkAndExpandItem( - elem, - !mTreeViewer.getChecked(elem), - false /*fixChildren*/, - true /*fixParent*/); - updateButtonsState(); - } - } - - private void checkAndExpandItem( - Object elem, - boolean checked, - boolean fixChildren, - boolean fixParent) { - ITreeContentProvider provider = - (ITreeContentProvider) mTreeViewer.getContentProvider(); - - // fix the item itself - if (checked != mTreeViewer.getChecked(elem)) { - mTreeViewer.setChecked(elem, checked); - } - if (elem instanceof PkgItem) { - // update the PkgItem to reflect the selection - ((PkgItem) elem).setChecked(checked); - } - - if (!checked) { - if (fixChildren) { - // when de-selecting, we deselect all children too - mTreeViewer.setSubtreeChecked(elem, checked); - for (Object child : provider.getChildren(elem)) { - checkAndExpandItem(child, checked, fixChildren, false/*fixParent*/); - } - } - - // fix the parent when deselecting - if (fixParent) { - Object parent = provider.getParent(elem); - if (parent != null && mTreeViewer.getChecked(parent)) { - mTreeViewer.setChecked(parent, false); - } - } - return; - } - - // When selecting, we also select sub-items (for a category) - if (fixChildren) { - if (elem instanceof PkgCategory || elem instanceof PkgItem) { - Object[] children = provider.getChildren(elem); - for (Object child : children) { - checkAndExpandItem(child, true, fixChildren, false/*fixParent*/); - } - // only fix the parent once the last sub-item is set - if (elem instanceof PkgCategory) { - if (children.length > 0) { - checkAndExpandItem( - children[0], true, false/*fixChildren*/, true/*fixParent*/); - } else { - mTreeViewer.setChecked(elem, false); - } - } - } else if (elem instanceof Package) { - // in details mode, we auto-select compatible packages - selectCompatibleArchives(elem, provider); - } - } - - if (fixParent && checked && elem instanceof PkgItem) { - Object parent = provider.getParent(elem); - if (!mTreeViewer.getChecked(parent)) { - Object[] children = provider.getChildren(parent); - boolean allChecked = children.length > 0; - for (Object e : children) { - if (!mTreeViewer.getChecked(e)) { - allChecked = false; - break; - } - } - if (allChecked) { - mTreeViewer.setChecked(parent, true); - } - } - } - } - - private void selectCompatibleArchives(Object pkg, ITreeContentProvider provider) { - for (Object archive : provider.getChildren(pkg)) { - if (archive instanceof Archive) { - mTreeViewer.setChecked(archive, ((Archive) archive).isCompatible()); - } - } - } - - /** - * Checks all PkgItems that are either new or have updates or select top platform - * for initial run. - */ - private void onSelectNewUpdates(boolean selectNew, boolean selectUpdates, boolean selectTop) { - // This does not update the tree itself, syncViewerSelection does it below. - mImpl.onSelectNewUpdates(selectNew, selectUpdates, selectTop); - syncViewerSelection(); - updateButtonsState(); - } - - /** - * Deselect all checked PkgItems. - */ - private void onDeselectAll() { - // This does not update the tree itself, syncViewerSelection does it below. - mImpl.onDeselectAll(); - syncViewerSelection(); - updateButtonsState(); - } - - /** - * When switching between the tree-by-api and the tree-by-source, copy the selection - * (aka the checked items) from one list to the other. - * This does not update the tree itself. - */ - private void copySelection(boolean fromSourceToApi) { - List<PkgItem> fromItems = - mImpl.mDiffLogic.getAllPkgItems(!fromSourceToApi, fromSourceToApi); - List<PkgItem> toItems = - mImpl.mDiffLogic.getAllPkgItems(fromSourceToApi, !fromSourceToApi); - - // deselect all targets - for (PkgItem item : toItems) { - item.setChecked(false); - } - - // mark new one from the source - for (PkgItem source : fromItems) { - if (source.isChecked()) { - // There should typically be a corresponding item in the target side - for (PkgItem target : toItems) { - if (target.isSameMainPackageAs(source.getMainPackage())) { - target.setChecked(true); - break; - } - } - } - } - } - - /** - * Synchronize the 'checked' state of PkgItems in the tree with their internal isChecked state. - */ - private void syncViewerSelection() { - ITreeContentProvider provider = (ITreeContentProvider) mTreeViewer.getContentProvider(); - - Object input = mTreeViewer.getInput(); - if (input == null) { - return; - } - for (Object cat : provider.getElements(input)) { - Object[] children = provider.getElements(cat); - boolean allChecked = children.length > 0; - for (Object child : children) { - if (child instanceof PkgItem) { - PkgItem item = (PkgItem) child; - boolean checked = item.isChecked(); - allChecked &= checked; - - if (checked != mTreeViewer.getChecked(item)) { - if (checked) { - if (!mTreeViewer.getExpandedState(cat)) { - mTreeViewer.setExpandedState(cat, true); - } - } - checkAndExpandItem(item, checked, true/*fixChildren*/, false/*fixParent*/); - } - } - } - - if (allChecked != mTreeViewer.getChecked(cat)) { - mTreeViewer.setChecked(cat, allChecked); - } - } - } - - /** - * Indicate an install/delete operation is pending. - * This disables the install/delete buttons. - * Use {@link #endOperationPending()} to revert, typically in a {@code try..finally} block. - */ - private void beginOperationPending() { - mOperationPending = true; - updateButtonsState(); - } - - private void endOperationPending() { - mOperationPending = false; - updateButtonsState(); - } - - /** - * Updates the Install and Delete Package buttons. - */ - private void updateButtonsState() { - if (!mButtonInstall.isDisposed()) { - int numPackages = getArchivesForInstall(null /*archives*/); - - mButtonInstall.setEnabled((numPackages > 0) && !mOperationPending); - mButtonInstall.setText( - numPackages == 0 ? "Install packages..." : // disabled button case - numPackages == 1 ? "Install 1 package..." : - String.format("Install %d packages...", numPackages)); - } - - if (!mButtonDelete.isDisposed()) { - // We can only delete local archives - int numPackages = getArchivesToDelete(null /*outMsg*/, null /*outArchives*/); - - mButtonDelete.setEnabled((numPackages > 0) && !mOperationPending); - mButtonDelete.setText( - numPackages == 0 ? "Delete packages..." : // disabled button case - numPackages == 1 ? "Delete 1 package..." : - String.format("Delete %d packages...", numPackages)); - } - } - - /** - * Called when the Install Package button is selected. - * Collects the packages to be installed and shows the installation window. - */ - private void onButtonInstall() { - ArrayList<Archive> archives = new ArrayList<Archive>(); - getArchivesForInstall(archives); - - if (mImpl.mUpdaterData != null) { - boolean needsRefresh = false; - try { - beginOperationPending(); - - List<Archive> installed = mImpl.mUpdaterData.updateOrInstallAll_WithGUI( - archives, - mCheckFilterObsolete.getSelection() /* includeObsoletes */, - mContext == SdkInvocationContext.IDE ? - UpdaterData.TOOLS_MSG_UPDATED_FROM_ADT : - UpdaterData.TOOLS_MSG_UPDATED_FROM_SDKMAN); - needsRefresh = installed != null && !installed.isEmpty(); - } finally { - endOperationPending(); - - if (needsRefresh) { - // The local package list has changed, make sure to refresh it - mImpl.localReload(); - } - } - } - } - - /** - * Selects the archives that can be installed. - * This can be used with a null {@code outArchives} just to count the number of - * installable archives. - * - * @param outArchives An archive list where to add the archives that can be installed. - * This can be null. - * @return The number of archives that can be installed. - */ - private int getArchivesForInstall(List<Archive> outArchives) { - if (mTreeViewer == null || - mTreeViewer.getTree() == null || - mTreeViewer.getTree().isDisposed()) { - return 0; - } - Object[] checked = mTreeViewer.getCheckedElements(); - if (checked == null) { - return 0; - } - - int count = 0; - - // Give us a way to force install of incompatible archives. - boolean checkIsCompatible = - System.getenv(ArchiveInstaller.ENV_VAR_IGNORE_COMPAT) == null; - - if (mDisplayArchives) { - // In detail mode, we display archives so we can install only the - // archives that are actually selected. - - for (Object c : checked) { - if (c instanceof Archive) { - Archive a = (Archive) c; - if (a != null) { - if (checkIsCompatible && !a.isCompatible()) { - continue; - } - count++; - if (outArchives != null) { - outArchives.add((Archive) c); - } - } - } - } - } else { - // In non-detail mode, we install all the compatible archives - // found in the selected pkg items. We also automatically - // select update packages rather than the root package if any. - - for (Object c : checked) { - Package p = null; - if (c instanceof Package) { - // This is an update package - p = (Package) c; - } else if (c instanceof PkgItem) { - p = ((PkgItem) c).getMainPackage(); - - PkgItem pi = (PkgItem) c; - if (pi.getState() == PkgState.INSTALLED) { - // We don't allow installing items that are already installed - // unless they have a pending update. - p = pi.getUpdatePkg(); - - } else if (pi.getState() == PkgState.NEW) { - p = pi.getMainPackage(); - } - } - if (p != null) { - for (Archive a : p.getArchives()) { - if (a != null) { - if (checkIsCompatible && !a.isCompatible()) { - continue; - } - count++; - if (outArchives != null) { - outArchives.add(a); - } - } - } - } - } - } - - return count; - } - - /** - * Called when the Delete Package button is selected. - * Collects the packages to be deleted, prompt the user for confirmation - * and actually performs the deletion. - */ - private void onButtonDelete() { - final String title = "Delete SDK Package"; - StringBuilder msg = new StringBuilder("Are you sure you want to delete:"); - - // A list of archives to delete - final ArrayList<Archive> archives = new ArrayList<Archive>(); - - getArchivesToDelete(msg, archives); - - if (!archives.isEmpty()) { - msg.append("\n").append("This cannot be undone."); //$NON-NLS-1$ - if (MessageDialog.openQuestion(getShell(), title, msg.toString())) { - try { - beginOperationPending(); - - mImpl.mUpdaterData.getTaskFactory().start("Delete Package", new ITask() { - @Override - public void run(ITaskMonitor monitor) { - monitor.setProgressMax(archives.size() + 1); - for (Archive a : archives) { - monitor.setDescription("Deleting '%1$s' (%2$s)", - a.getParentPackage().getShortDescription(), - a.getLocalOsPath()); - - // Delete the actual package - a.deleteLocal(); - - monitor.incProgress(1); - if (monitor.isCancelRequested()) { - break; - } - } - - monitor.incProgress(1); - monitor.setDescription("Done"); - } - }); - } finally { - endOperationPending(); - - // The local package list has changed, make sure to refresh it - mImpl.localReload(); - } - } - } - } - - /** - * Selects the archives that can be deleted and collect their names. - * This can be used with a null {@code outArchives} and a null {@code outMsg} - * just to count the number of archives to be deleted. - * - * @param outMsg A StringBuilder where the names of the packages to be deleted is - * accumulated. This is used to confirm deletion with the user. - * @param outArchives An archive list where to add the archives that can be installed. - * This can be null. - * @return The number of archives that can be deleted. - */ - private int getArchivesToDelete(StringBuilder outMsg, List<Archive> outArchives) { - if (mTreeViewer == null || - mTreeViewer.getTree() == null || - mTreeViewer.getTree().isDisposed()) { - return 0; - } - Object[] checked = mTreeViewer.getCheckedElements(); - if (checked == null) { - // This should not happen since the button should be disabled - return 0; - } - - int count = 0; - - if (mDisplayArchives) { - // In detail mode, select archives that can be deleted - - for (Object c : checked) { - if (c instanceof Archive) { - Archive a = (Archive) c; - if (a != null && a.isLocal()) { - count++; - if (outMsg != null) { - String osPath = a.getLocalOsPath(); - File dir = new File(osPath); - Package p = a.getParentPackage(); - if (p != null && dir.isDirectory()) { - outMsg.append("\n - ") //$NON-NLS-1$ - .append(p.getShortDescription()); - } - } - if (outArchives != null) { - outArchives.add(a); - } - } - } - } - } else { - // In non-detail mode, select archives of selected packages that can be deleted. - - for (Object c : checked) { - if (c instanceof PkgItem) { - PkgItem pi = (PkgItem) c; - PkgState state = pi.getState(); - if (state == PkgState.INSTALLED) { - Package p = pi.getMainPackage(); - - for (Archive a : p.getArchives()) { - if (a != null && a.isLocal()) { - count++; - if (outMsg != null) { - String osPath = a.getLocalOsPath(); - File dir = new File(osPath); - if (dir.isDirectory()) { - outMsg.append("\n - ") //$NON-NLS-1$ - .append(p.getShortDescription()); - } - } - if (outArchives != null) { - outArchives.add(a); - } - } - } - } - } - } - } - - return count; - } - - // ---------------------- - - - // --- Implementation of ISdkChangeListener --- - - @Override - public void onSdkLoaded() { - onSdkReload(); - } - - @Override - public void onSdkReload() { - // The sdkmanager finished reloading its data. We must not call localReload() from here - // since we don't want to alter the sdkmanager's data that just finished loading. - mImpl.loadPackages(); - } - - @Override - public void preInstallHook() { - // nothing to be done for now. - } - - @Override - public void postInstallHook() { - // nothing to be done for now. - } - - - // --- End of hiding from SWT Designer --- - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageIcons.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageIcons.java deleted file mode 100755 index 4fe8fca..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageIcons.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - - -/** - * Icons used by {@link PackagesPage}. - */ -public class PackagesPageIcons { - - public static final String ICON_CAT_OTHER = "pkgcat_other_16.png"; //$NON-NLS-1$ - public static final String ICON_CAT_PLATFORM = "pkgcat_16.png"; //$NON-NLS-1$ - public static final String ICON_SORT_BY_SOURCE = "source_icon16.png"; //$NON-NLS-1$ - public static final String ICON_SORT_BY_API = "platform_pkg_16.png"; //$NON-NLS-1$ - public static final String ICON_PKG_NEW = "pkg_new_16.png"; //$NON-NLS-1$ - public static final String ICON_PKG_INCOMPAT = "pkg_incompat_16.png"; //$NON-NLS-1$ - public static final String ICON_PKG_UPDATE = "pkg_update_16.png"; //$NON-NLS-1$ - public static final String ICON_PKG_INSTALLED = "pkg_installed_16.png"; //$NON-NLS-1$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java deleted file mode 100755 index 3ca0ee3..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PackagesPageImpl.java +++ /dev/null @@ -1,568 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import com.android.SdkConstants; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.DownloadCache.Strategy; -import com.android.sdklib.internal.repository.IDescription; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.core.PackageLoader; -import com.android.sdkuilib.internal.repository.core.PackageLoader.ISourceLoadedCallback; -import com.android.sdkuilib.internal.repository.core.PackagesDiffLogic; -import com.android.sdkuilib.internal.repository.core.PkgCategory; -import com.android.sdkuilib.internal.repository.core.PkgCategoryApi; -import com.android.sdkuilib.internal.repository.core.PkgContentProvider; -import com.android.sdkuilib.internal.repository.core.PkgItem; -import com.android.sdkuilib.internal.repository.core.PkgItem.PkgState; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; - -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.IInputProvider; -import org.eclipse.jface.viewers.ITableFontProvider; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.List; - -/** - * Base class for {@link PackagesPage} that holds most of the logic to display - * the tree/list of packages. This class holds most of the logic and {@link PackagesPage} - * holds most of the UI (creating the UI, dealing with menus and buttons and tree - * selection.) This makes it easier to test the functionality by mocking only a - * subset of the UI. - */ -abstract class PackagesPageImpl { - - final UpdaterData mUpdaterData; - final PackagesDiffLogic mDiffLogic; - - private ICheckboxTreeViewer mITreeViewer; - private ITreeViewerColumn mIColumnName; - private ITreeViewerColumn mIColumnApi; - private ITreeViewerColumn mIColumnRevision; - private ITreeViewerColumn mIColumnStatus; - - PackagesPageImpl(UpdaterData updaterData) { - mUpdaterData = updaterData; - mDiffLogic = new PackagesDiffLogic(updaterData); - } - - /** - * Utility method that derived classes can override to check whether the UI is disposed. - * When the UI is disposed, most operations that affect the UI will be bypassed. - * @return True if UI is not available and should not be touched. - */ - abstract protected boolean isUiDisposed(); - - /** - * Utility method to execute a runnable on the main UI thread. - * Will do nothing if {@link #isUiDisposed()} returns false. - * @param runnable The runnable to execute on the main UI thread. - */ - abstract protected void syncExec(Runnable runnable); - - void performFirstLoad() { - // First a package loader is created that only checks - // the local cache xml files. It populates the package - // list based on what the client got last, essentially. - loadPackages(true /*useLocalCache*/, false /*overrideExisting*/); - - // Next a regular package loader is created that will - // respect the expiration and refresh parameters of the - // download cache. - loadPackages(false /*useLocalCache*/, true /*overrideExisting*/); - } - - public void setITreeViewer(ICheckboxTreeViewer iTreeViewer) { - mITreeViewer = iTreeViewer; - } - - public void setIColumns( - ITreeViewerColumn columnName, - ITreeViewerColumn columnApi, - ITreeViewerColumn columnRevision, - ITreeViewerColumn columnStatus) { - mIColumnName = columnName; - mIColumnApi = columnApi; - mIColumnRevision = columnRevision; - mIColumnStatus = columnStatus; - } - - void postCreate() { - // Caller needs to call setITreeViewer before this. - assert mITreeViewer != null; - // Caller needs to call setIColumns before this. - assert mIColumnApi != null; - assert mIColumnName != null; - assert mIColumnStatus != null; - assert mIColumnRevision != null; - - mITreeViewer.setContentProvider(new PkgContentProvider(mITreeViewer)); - - mIColumnApi.setLabelProvider( - new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnApi))); - mIColumnName.setLabelProvider( - new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnName))); - mIColumnStatus.setLabelProvider( - new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnStatus))); - mIColumnRevision.setLabelProvider( - new PkgTreeColumnViewerLabelProvider(new PkgCellLabelProvider(mIColumnRevision))); - } - - /** - * Performs a full reload by removing all cached packages data, including the platforms - * and addons from the sdkmanager instance. This will perform a full local parsing - * as well as a full reload of the remote data (by fetching all sources again.) - */ - void fullReload() { - // Clear all source information, forcing them to be refreshed. - mUpdaterData.getSources().clearAllPackages(); - // Clear and reload all local data too. - localReload(); - } - - /** - * Performs a full reload of all the local package information, including the platforms - * and addons from the sdkmanager instance. This will perform a full local parsing. - * <p/> - * This method does NOT force a new fetch of the remote sources. - * - * @see #fullReload() - */ - void localReload() { - // Clear all source caches, otherwise loading will use the cached data - mUpdaterData.getLocalSdkParser().clearPackages(); - mUpdaterData.getSdkManager().reloadSdk(mUpdaterData.getSdkLog()); - loadPackages(); - } - - /** - * Performs a "normal" reload of the package information, use the default download - * cache and refreshing strategy as needed. - */ - void loadPackages() { - loadPackages(false /*useLocalCache*/, false /*overrideExisting*/); - } - - /** - * Performs a reload of the package information. - * - * @param useLocalCache When true, the {@link PackageLoader} is switched to use - * a specific {@link DownloadCache} using the {@link Strategy#ONLY_CACHE}, meaning - * it will only use data from the local cache. It will not try to fetch or refresh - * manifests. This is used once the very first time the sdk manager window opens - * and is typically followed by a regular load with refresh. - */ - abstract protected void loadPackages(boolean useLocalCache, boolean overrideExisting); - - /** - * Actual implementation of {@link #loadPackages(boolean, boolean)}. - * Derived implementations must call this to do the actual work after setting up the UI. - */ - void loadPackagesImpl(final boolean useLocalCache, final boolean overrideExisting) { - if (mUpdaterData == null) { - return; - } - - final boolean displaySortByApi = isSortByApi(); - - PackageLoader packageLoader = getPackageLoader(useLocalCache); - assert packageLoader != null; - - mDiffLogic.updateStart(); - packageLoader.loadPackages(overrideExisting, new ISourceLoadedCallback() { - @Override - public boolean onUpdateSource(SdkSource source, Package[] newPackages) { - // This runs in a thread and must not access UI directly. - final boolean changed = mDiffLogic.updateSourcePackages( - displaySortByApi, source, newPackages); - - syncExec(new Runnable() { - @Override - public void run() { - if (changed || - mITreeViewer.getInput() != mDiffLogic.getCategories(isSortByApi())) { - refreshViewerInput(); - } - } - }); - - // Return true to tell the loader to continue with the next source. - // Return false to stop the loader if any UI has been disposed, which can - // happen if the user is trying to close the window during the load operation. - return !isUiDisposed(); - } - - @Override - public void onLoadCompleted() { - // This runs in a thread and must not access UI directly. - final boolean changed = mDiffLogic.updateEnd(displaySortByApi); - - syncExec(new Runnable() { - @Override - public void run() { - if (changed || - mITreeViewer.getInput() != mDiffLogic.getCategories(isSortByApi())) { - try { - refreshViewerInput(); - } catch (Exception ignore) {} - } - - if (!useLocalCache && - mDiffLogic.isFirstLoadComplete() && - !isUiDisposed()) { - // At the end of the first load, if nothing is selected then - // automatically select all new and update packages. - Object[] checked = mITreeViewer.getCheckedElements(); - if (checked == null || checked.length == 0) { - onSelectNewUpdates( - false, //selectNew - true, //selectUpdates, - true); //selectTop - } - } - } - }); - } - }); - } - - /** - * Used by {@link #loadPackagesImpl(boolean, boolean)} to get the package - * loader for the first or second pass update. When starting the manager - * starts with a first pass that reads only from the local cache, with no - * extra network access. That's {@code useLocalCache} being true. - * <p/> - * Leter it does a second pass with {@code useLocalCache} set to false - * and actually uses the download cache specified in {@link UpdaterData}. - * - * This is extracted so that we can control this cache via unit tests. - */ - protected PackageLoader getPackageLoader(boolean useLocalCache) { - if (useLocalCache) { - return new PackageLoader(mUpdaterData, new DownloadCache(Strategy.ONLY_CACHE)); - } else { - return mUpdaterData.getPackageLoader(); - } - } - - /** - * Overridden by the UI to respond to a request to refresh the tree viewer - * when the input has changed. - * The implementation must call {@link #setViewerInput()} somehow and will - * also need to adjust the expand state of the tree items and/or update - * some buttons or other state. - */ - abstract protected void refreshViewerInput(); - - /** - * Invoked from {@link #refreshViewerInput()} to actually either set the - * input of the tree viewer or refresh it if it's the <em>same</em> input - * object. - */ - protected void setViewerInput() { - List<PkgCategory> cats = mDiffLogic.getCategories(isSortByApi()); - if (mITreeViewer.getInput() != cats) { - // set initial input - mITreeViewer.setInput(cats); - } else { - // refresh existing, which preserves the expanded state, the selection - // and the checked state. - mITreeViewer.refresh(); - } - } - - /** - * Overridden by the UI to determine if the tree should display packages sorted - * by API (returns true) or by repository source (returns false.) - */ - abstract protected boolean isSortByApi(); - - /** - * Checks all PkgItems that are either new or have updates or select top platform - * for initial run. - */ - void onSelectNewUpdates(boolean selectNew, boolean selectUpdates, boolean selectTop) { - // This does not update the tree itself, syncViewerSelection does it in the caller. - mDiffLogic.checkNewUpdateItems( - selectNew, - selectUpdates, - selectTop, - SdkConstants.CURRENT_PLATFORM); - } - - /** - * Deselect all checked PkgItems. - */ - void onDeselectAll() { - // This does not update the tree itself, syncViewerSelection does it in the caller. - mDiffLogic.uncheckAllItems(); - } - - // ---------------------- - - abstract protected Font getTreeFontItalic(); - - class PkgCellLabelProvider extends ColumnLabelProvider implements ITableFontProvider { - - private final ITreeViewerColumn mColumn; - - public PkgCellLabelProvider(ITreeViewerColumn column) { - super(); - mColumn = column; - } - - @Override - public String getText(Object element) { - - if (mColumn == mIColumnName) { - if (element instanceof PkgCategory) { - return ((PkgCategory) element).getLabel(); - } else if (element instanceof PkgItem) { - return getPkgItemName((PkgItem) element); - } else if (element instanceof IDescription) { - return ((IDescription) element).getShortDescription(); - } - - } else if (mColumn == mIColumnApi) { - int api = -1; - if (element instanceof PkgItem) { - api = ((PkgItem) element).getApi(); - } - if (api >= 1) { - return Integer.toString(api); - } - - } else if (mColumn == mIColumnRevision) { - if (element instanceof PkgItem) { - PkgItem pkg = (PkgItem) element; - return pkg.getRevision().toShortString(); - } - - } else if (mColumn == mIColumnStatus) { - if (element instanceof PkgItem) { - PkgItem pkg = (PkgItem) element; - - switch(pkg.getState()) { - case INSTALLED: - Package update = pkg.getUpdatePkg(); - if (update != null) { - return String.format( - "Update available: rev. %1$s", - update.getRevision().toShortString()); - } - return "Installed"; - - case NEW: - Package p = pkg.getMainPackage(); - if (p != null && p.hasCompatibleArchive()) { - return "Not installed"; - } else { - return String.format("Not compatible with %1$s", - SdkConstants.currentPlatformName()); - } - } - return pkg.getState().toString(); - - } else if (element instanceof Package) { - // This is an update package. - return "New revision " + ((Package) element).getRevision().toShortString(); - } - } - - return ""; //$NON-NLS-1$ - } - - private String getPkgItemName(PkgItem item) { - String name = item.getName().trim(); - - if (isSortByApi()) { - // When sorting by API, the package name might contains the API number - // or the platform name at the end. If we find it, cut it out since it's - // redundant. - - PkgCategoryApi cat = (PkgCategoryApi) findCategoryForItem(item); - String apiLabel = cat.getApiLabel(); - String platLabel = cat.getPlatformName(); - - if (platLabel != null && name.endsWith(platLabel)) { - return name.substring(0, name.length() - platLabel.length()); - - } else if (apiLabel != null && name.endsWith(apiLabel)) { - return name.substring(0, name.length() - apiLabel.length()); - - } else if (platLabel != null && item.isObsolete() && name.indexOf(platLabel) > 0) { - // For obsolete items, the format is "<base name> <platform name> (Obsolete)" - // so in this case only accept removing a platform name that is not at - // the end. - name = name.replace(platLabel, ""); //$NON-NLS-1$ - } - } - - // Collapse potential duplicated spacing - name = name.replaceAll(" +", " "); //$NON-NLS-1$ //$NON-NLS-2$ - - return name; - } - - private PkgCategory findCategoryForItem(PkgItem item) { - List<PkgCategory> cats = mDiffLogic.getCategories(isSortByApi()); - for (PkgCategory cat : cats) { - for (PkgItem i : cat.getItems()) { - if (i == item) { - return cat; - } - } - } - - return null; - } - - @Override - public Image getImage(Object element) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - - if (imgFactory != null) { - if (mColumn == mIColumnName) { - if (element instanceof PkgCategory) { - return imgFactory.getImageForObject(((PkgCategory) element).getIconRef()); - } else if (element instanceof PkgItem) { - return imgFactory.getImageForObject(((PkgItem) element).getMainPackage()); - } - return imgFactory.getImageForObject(element); - - } else if (mColumn == mIColumnStatus && element instanceof PkgItem) { - PkgItem pi = (PkgItem) element; - switch(pi.getState()) { - case INSTALLED: - if (pi.hasUpdatePkg()) { - return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_UPDATE); - } else { - return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_INSTALLED); - } - case NEW: - Package p = pi.getMainPackage(); - if (p != null && p.hasCompatibleArchive()) { - return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_NEW); - } else { - return imgFactory.getImageByName(PackagesPageIcons.ICON_PKG_INCOMPAT); - } - } - } - } - return super.getImage(element); - } - - // -- ITableFontProvider - - @Override - public Font getFont(Object element, int columnIndex) { - if (element instanceof PkgItem) { - if (((PkgItem) element).getState() == PkgState.NEW) { - return getTreeFontItalic(); - } - } else if (element instanceof Package) { - // update package - return getTreeFontItalic(); - } - return super.getFont(element); - } - - // -- Tooltip support - - @Override - public String getToolTipText(Object element) { - PkgItem pi = element instanceof PkgItem ? (PkgItem) element : null; - if (pi != null) { - element = pi.getMainPackage(); - } - if (element instanceof IDescription) { - String s = getTooltipDescription((IDescription) element); - - if (pi != null && pi.hasUpdatePkg()) { - s += "\n-----------------" + //$NON-NLS-1$ - "\nUpdate Available:\n" + //$NON-NLS-1$ - getTooltipDescription(pi.getUpdatePkg()); - } - - return s; - } - return super.getToolTipText(element); - } - - private String getTooltipDescription(IDescription element) { - String s = element.getLongDescription(); - if (element instanceof Package) { - Package p = (Package) element; - - if (!p.isLocal()) { - // For non-installed item, try to find a download size - for (Archive a : p.getArchives()) { - if (!a.isLocal() && a.isCompatible()) { - s += '\n' + a.getSizeDescription(); - break; - } - } - } - - // Display info about where this package comes/came from - SdkSource src = p.getParentSource(); - if (src != null) { - try { - URL url = new URL(src.getUrl()); - String host = url.getHost(); - if (p.isLocal()) { - s += String.format("\nInstalled from %1$s", host); - } else { - s += String.format("\nProvided by %1$s", host); - } - } catch (MalformedURLException ignore) { - } - } - } - return s; - } - - @Override - public Point getToolTipShift(Object object) { - return new Point(15, 5); - } - - @Override - public int getToolTipDisplayDelayTime(Object object) { - return 500; - } - } - - interface ICheckboxTreeViewer extends IInputProvider { - void setContentProvider(PkgContentProvider pkgContentProvider); - void refresh(); - void setInput(List<PkgCategory> cats); - Object[] getCheckedElements(); - } - - interface ITreeViewerColumn { - void setLabelProvider(ColumnLabelProvider labelProvider); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PkgTreeColumnViewerLabelProvider.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PkgTreeColumnViewerLabelProvider.java deleted file mode 100755 index 3323104..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/PkgTreeColumnViewerLabelProvider.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import org.eclipse.jface.viewers.CellLabelProvider; -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider; -import org.eclipse.jface.viewers.TreePath; -import org.eclipse.jface.viewers.TreeViewerColumn; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; - -/** - * A custom version of {@link TreeColumnViewerLabelProvider} which - * handles {@link TreePath}s and delegates content to the given - * {@link ColumnLabelProvider} for a given {@link TreeViewerColumn}. - * <p/> - * The implementation handles a variety of providers (table label, table - * color, table font) but does not implement a tooltip provider, so we - * delegate the calls here to the appropriate {@link ColumnLabelProvider}. - * <p/> - * Only {@link #getToolTipText(Object)} is really useful for us but we - * delegate all the tooltip calls for completeness and avoid surprises later - * if we ever decide to override more things in the label provider. - */ -class PkgTreeColumnViewerLabelProvider extends TreeColumnViewerLabelProvider { - - private CellLabelProvider mTooltipProvider; - - public PkgTreeColumnViewerLabelProvider(ColumnLabelProvider columnLabelProvider) { - super(columnLabelProvider); - } - - @Override - public void setProviders(Object provider) { - super.setProviders(provider); - if (provider instanceof CellLabelProvider) { - mTooltipProvider = (CellLabelProvider) provider; - } - } - - @Override - public Image getToolTipImage(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipImage(object); - } - return super.getToolTipImage(object); - } - - @Override - public String getToolTipText(Object element) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipText(element); - } - return super.getToolTipText(element); - } - - @Override - public Color getToolTipBackgroundColor(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipBackgroundColor(object); - } - return super.getToolTipBackgroundColor(object); - } - - @Override - public Color getToolTipForegroundColor(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipForegroundColor(object); - } - return super.getToolTipForegroundColor(object); - } - - @Override - public Font getToolTipFont(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipFont(object); - } - return super.getToolTipFont(object); - } - - @Override - public Point getToolTipShift(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipShift(object); - } - return super.getToolTipShift(object); - } - - @Override - public boolean useNativeToolTip(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.useNativeToolTip(object); - } - return super.useNativeToolTip(object); - } - - @Override - public int getToolTipTimeDisplayed(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipTimeDisplayed(object); - } - return super.getToolTipTimeDisplayed(object); - } - - @Override - public int getToolTipDisplayDelayTime(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipDisplayDelayTime(object); - } - return super.getToolTipDisplayDelayTime(object); - } - - @Override - public int getToolTipStyle(Object object) { - if (mTooltipProvider != null) { - return mTooltipProvider.getToolTipStyle(object); - } - return super.getToolTipStyle(object); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/SdkUpdaterWindowImpl2.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/SdkUpdaterWindowImpl2.java deleted file mode 100755 index 41235c6..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/SdkUpdaterWindowImpl2.java +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - - -import com.android.SdkConstants; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.sources.SdkSourceProperties; -import com.android.sdkuilib.internal.repository.AboutDialog; -import com.android.sdkuilib.internal.repository.ISdkUpdaterWindow; -import com.android.sdkuilib.internal.repository.MenuBarWrapper; -import com.android.sdkuilib.internal.repository.SettingsController; -import com.android.sdkuilib.internal.repository.SettingsController.Settings; -import com.android.sdkuilib.internal.repository.SettingsDialog; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.internal.repository.ui.PackagesPage.MenuAction; -import com.android.sdkuilib.internal.tasks.ILogUiProvider; -import com.android.sdkuilib.internal.tasks.ProgressView; -import com.android.sdkuilib.internal.tasks.ProgressViewFactory; -import com.android.sdkuilib.internal.widgets.ImgDisabledButton; -import com.android.sdkuilib.internal.widgets.ToggleButton; -import com.android.sdkuilib.repository.AvdManagerWindow.AvdInvocationContext; -import com.android.sdkuilib.repository.ISdkChangeListener; -import com.android.sdkuilib.repository.SdkUpdaterWindow.SdkInvocationContext; -import com.android.utils.ILogger; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Menu; -import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.ProgressBar; -import org.eclipse.swt.widgets.Shell; - -/** - * This is the private implementation of the UpdateWindow - * for the second version of the SDK Manager. - * <p/> - * This window features only one embedded page, the combined installed+available package list. - */ -public class SdkUpdaterWindowImpl2 implements ISdkUpdaterWindow { - - public static final String APP_NAME = "Android SDK Manager"; - private static final String SIZE_POS_PREFIX = "sdkman2"; //$NON-NLS-1$ - - private final Shell mParentShell; - private final SdkInvocationContext mContext; - /** Internal data shared between the window and its pages. */ - private final UpdaterData mUpdaterData; - - // --- UI members --- - - protected Shell mShell; - private PackagesPage mPkgPage; - private ProgressBar mProgressBar; - private Label mStatusText; - private ImgDisabledButton mButtonStop; - private ToggleButton mButtonShowLog; - private SettingsController mSettingsController; - private LogWindow mLogWindow; - - /** - * Creates a new window. Caller must call open(), which will block. - * - * @param parentShell Parent shell. - * @param sdkLog Logger. Cannot be null. - * @param osSdkRoot The OS path to the SDK root. - * @param context The {@link SdkInvocationContext} to change the behavior depending on who's - * opening the SDK Manager. - */ - public SdkUpdaterWindowImpl2( - Shell parentShell, - ILogger sdkLog, - String osSdkRoot, - SdkInvocationContext context) { - mParentShell = parentShell; - mContext = context; - mUpdaterData = new UpdaterData(osSdkRoot, sdkLog); - } - - /** - * Creates a new window. Caller must call open(), which will block. - * <p/> - * This is to be used when the window is opened from {@link AvdManagerWindowImpl1} - * to share the same {@link UpdaterData} structure. - * - * @param parentShell Parent shell. - * @param updaterData The parent's updater data. - * @param context The {@link SdkInvocationContext} to change the behavior depending on who's - * opening the SDK Manager. - */ - public SdkUpdaterWindowImpl2( - Shell parentShell, - UpdaterData updaterData, - SdkInvocationContext context) { - mParentShell = parentShell; - mContext = context; - mUpdaterData = updaterData; - } - - /** - * Opens the window. - * @wbp.parser.entryPoint - */ - @Override - public void open() { - if (mParentShell == null) { - Display.setAppName(APP_NAME); //$hide$ (hide from SWT designer) - } - - createShell(); - preCreateContent(); - createContents(); - createMenuBar(); - createLogWindow(); - mShell.open(); - mShell.layout(); - - if (postCreateContent()) { //$hide$ (hide from SWT designer) - Display display = Display.getDefault(); - while (!mShell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - } - - SdkSourceProperties p = new SdkSourceProperties(); - p.save(); - - dispose(); //$hide$ - } - - private void createShell() { - // The SDK Manager must use a shell trim when standalone - // or a dialog trim when invoked from somewhere else. - int style = SWT.SHELL_TRIM; - if (mContext != SdkInvocationContext.STANDALONE) { - style |= SWT.APPLICATION_MODAL; - } - - mShell = new Shell(mParentShell, style); - mShell.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - ShellSizeAndPos.saveSizeAndPos(mShell, SIZE_POS_PREFIX); - onAndroidSdkUpdaterDispose(); //$hide$ (hide from SWT designer) - } - }); - - GridLayout glShell = new GridLayout(2, false); - glShell.verticalSpacing = 0; - glShell.horizontalSpacing = 0; - glShell.marginWidth = 0; - glShell.marginHeight = 0; - mShell.setLayout(glShell); - - mShell.setMinimumSize(new Point(500, 300)); - mShell.setSize(700, 500); - mShell.setText(APP_NAME); - - ShellSizeAndPos.loadSizeAndPos(mShell, SIZE_POS_PREFIX); - } - - private void createContents() { - mPkgPage = new PackagesPage(mShell, SWT.NONE, mUpdaterData, mContext); - mPkgPage.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); - - Composite composite1 = new Composite(mShell, SWT.NONE); - composite1.setLayout(new GridLayout(1, false)); - composite1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - - mProgressBar = new ProgressBar(composite1, SWT.NONE); - mProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - - mStatusText = new Label(composite1, SWT.NONE); - mStatusText.setText("Status Placeholder"); //$NON-NLS-1$ placeholder - mStatusText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - - Composite composite2 = new Composite(mShell, SWT.NONE); - composite2.setLayout(new GridLayout(2, false)); - - mButtonStop = new ImgDisabledButton(composite2, SWT.NONE, - getImage("stop_enabled_16.png"), //$NON-NLS-1$ - getImage("stop_disabled_16.png"), //$NON-NLS-1$ - "Click to abort the current task", - ""); //$NON-NLS-1$ nothing to abort - mButtonStop.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - onStopSelected(); - } - }); - - mButtonShowLog = new ToggleButton(composite2, SWT.NONE, - getImage("log_off_16.png"), //$NON-NLS-1$ - getImage("log_on_16.png"), //$NON-NLS-1$ - "Click to show the log window", // tooltip for state hidden=>shown - "Click to hide the log window"); // tooltip for state shown=>hidden - mButtonShowLog.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - onToggleLogWindow(); - } - }); - } - - @SuppressWarnings("unused") // MenuItem works using side effects - private void createMenuBar() { - - Menu menuBar = new Menu(mShell, SWT.BAR); - mShell.setMenuBar(menuBar); - - MenuItem menuBarPackages = new MenuItem(menuBar, SWT.CASCADE); - menuBarPackages.setText("Packages"); - - Menu menuPkgs = new Menu(menuBarPackages); - menuBarPackages.setMenu(menuPkgs); - - MenuItem showUpdatesNew = new MenuItem(menuPkgs, - MenuAction.TOGGLE_SHOW_UPDATE_NEW_PKG.getMenuStyle()); - showUpdatesNew.setText( - MenuAction.TOGGLE_SHOW_UPDATE_NEW_PKG.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.TOGGLE_SHOW_UPDATE_NEW_PKG, showUpdatesNew); - - MenuItem showInstalled = new MenuItem(menuPkgs, - MenuAction.TOGGLE_SHOW_INSTALLED_PKG.getMenuStyle()); - showInstalled.setText( - MenuAction.TOGGLE_SHOW_INSTALLED_PKG.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.TOGGLE_SHOW_INSTALLED_PKG, showInstalled); - - MenuItem showObsoletePackages = new MenuItem(menuPkgs, - MenuAction.TOGGLE_SHOW_OBSOLETE_PKG.getMenuStyle()); - showObsoletePackages.setText( - MenuAction.TOGGLE_SHOW_OBSOLETE_PKG.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.TOGGLE_SHOW_OBSOLETE_PKG, showObsoletePackages); - - MenuItem showArchives = new MenuItem(menuPkgs, - MenuAction.TOGGLE_SHOW_ARCHIVES.getMenuStyle()); - showArchives.setText( - MenuAction.TOGGLE_SHOW_ARCHIVES.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.TOGGLE_SHOW_ARCHIVES, showArchives); - - new MenuItem(menuPkgs, SWT.SEPARATOR); - - MenuItem sortByApi = new MenuItem(menuPkgs, - MenuAction.SORT_API_LEVEL.getMenuStyle()); - sortByApi.setText( - MenuAction.SORT_API_LEVEL.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.SORT_API_LEVEL, sortByApi); - - MenuItem sortBySource = new MenuItem(menuPkgs, - MenuAction.SORT_SOURCE.getMenuStyle()); - sortBySource.setText( - MenuAction.SORT_SOURCE.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.SORT_SOURCE, sortBySource); - - new MenuItem(menuPkgs, SWT.SEPARATOR); - - MenuItem reload = new MenuItem(menuPkgs, - MenuAction.RELOAD.getMenuStyle()); - reload.setText( - MenuAction.RELOAD.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.RELOAD, reload); - - MenuItem menuBarTools = new MenuItem(menuBar, SWT.CASCADE); - menuBarTools.setText("Tools"); - - Menu menuTools = new Menu(menuBarTools); - menuBarTools.setMenu(menuTools); - - if (mContext == SdkInvocationContext.STANDALONE) { - MenuItem manageAvds = new MenuItem(menuTools, SWT.NONE); - manageAvds.setText("Manage AVDs..."); - manageAvds.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - onAvdManager(); - } - }); - } - - MenuItem manageSources = new MenuItem(menuTools, - MenuAction.SHOW_ADDON_SITES.getMenuStyle()); - manageSources.setText( - MenuAction.SHOW_ADDON_SITES.getMenuTitle()); - mPkgPage.registerMenuAction( - MenuAction.SHOW_ADDON_SITES, manageSources); - - if (mContext == SdkInvocationContext.STANDALONE || mContext == SdkInvocationContext.IDE) { - try { - new MenuBarWrapper(APP_NAME, menuTools) { - @Override - public void onPreferencesMenuSelected() { - - // capture a copy of the initial settings - Settings settings1 = new Settings(mSettingsController.getSettings()); - - // open the dialog and wait for it to close - SettingsDialog sd = new SettingsDialog(mShell, mUpdaterData); - sd.open(); - - // get the new settings - Settings settings2 = mSettingsController.getSettings(); - - // We need to reload the package list if the http mode or the preview - // modes have changed. - if (settings1.getForceHttp() != settings2.getForceHttp() || - settings1.getEnablePreviews() != settings2.getEnablePreviews()) { - mPkgPage.onSdkReload(); - } - } - - @Override - public void onAboutMenuSelected() { - AboutDialog ad = new AboutDialog(mShell, mUpdaterData); - ad.open(); - } - - @Override - public void printError(String format, Object... args) { - if (mUpdaterData != null) { - mUpdaterData.getSdkLog().error(null, format, args); - } - } - }; - } catch (Throwable e) { - mUpdaterData.getSdkLog().error(e, "Failed to setup menu bar"); - e.printStackTrace(); - } - } - } - - private Image getImage(String filename) { - if (mUpdaterData != null) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - return imgFactory.getImageByName(filename); - } - } - return null; - } - - /** - * Creates the log window. - * <p/> - * If this is invoked from an IDE, we also define a secondary logger so that all - * messages flow to the IDE log. This may or may not be what we want in the end - * (e.g. a middle ground would be to repeat error, and ignore normal/verbose) - */ - private void createLogWindow() { - mLogWindow = new LogWindow(mShell, - mContext == SdkInvocationContext.IDE ? mUpdaterData.getSdkLog() : null); - mLogWindow.open(); - } - - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - // --- Public API ----------- - - /** - * Adds a new listener to be notified when a change is made to the content of the SDK. - */ - @Override - public void addListener(ISdkChangeListener listener) { - mUpdaterData.addListeners(listener); - } - - /** - * Removes a new listener to be notified anymore when a change is made to the content of - * the SDK. - */ - @Override - public void removeListener(ISdkChangeListener listener) { - mUpdaterData.removeListener(listener); - } - - // --- Internals & UI Callbacks ----------- - - /** - * Called before the UI is created. - */ - private void preCreateContent() { - mUpdaterData.setWindowShell(mShell); - // We need the UI factory to create the UI - mUpdaterData.setImageFactory(new ImageFactory(mShell.getDisplay())); - // Note: we can't create the TaskFactory yet because we need the UI - // to be created first, so this is done in postCreateContent(). - } - - /** - * Once the UI has been created, initializes the content. - * This creates the pages, selects the first one, setups sources and scans for local folders. - * - * Returns true if we should show the window. - */ - private boolean postCreateContent() { - ProgressViewFactory factory = new ProgressViewFactory(); - - // This class delegates all logging to the mLogWindow window - // and filters errors to make sure the window is visible when - // an error is logged. - ILogUiProvider logAdapter = new ILogUiProvider() { - @Override - public void setDescription(String description) { - mLogWindow.setDescription(description); - } - - @Override - public void log(String log) { - mLogWindow.log(log); - } - - @Override - public void logVerbose(String log) { - mLogWindow.logVerbose(log); - } - - @Override - public void logError(String log) { - mLogWindow.logError(log); - - // Run the window visibility check/toggle on the UI thread. - // Note: at least on Windows, it seems ok to check for the window visibility - // on a sub-thread but that doesn't seem cross-platform safe. We shouldn't - // have a lot of error logging, so this should be acceptable. If not, we could - // cache the visibility state. - if (mShell != null && !mShell.isDisposed()) { - mShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!mLogWindow.isVisible()) { - // Don't toggle the window visibility directly. - // Instead use the same action as the log-toggle button - // so that the button's state be kept in sync. - onToggleLogWindow(); - } - } - }); - } - } - }; - - factory.setProgressView( - new ProgressView(mStatusText, mProgressBar, mButtonStop, logAdapter)); - mUpdaterData.setTaskFactory(factory); - - setWindowImage(mShell); - - setupSources(); - initializeSettings(); - - if (mUpdaterData.checkIfInitFailed()) { - return false; - } - - mUpdaterData.broadcastOnSdkLoaded(); - - // Tell the one page its the selected one - mPkgPage.performFirstLoad(); - - return true; - } - - /** - * Creates the icon of the window shell. - * - * @param shell The shell on which to put the icon - */ - private void setWindowImage(Shell shell) { - String imageName = "android_icon_16.png"; //$NON-NLS-1$ - if (SdkConstants.currentPlatform() == SdkConstants.PLATFORM_DARWIN) { - imageName = "android_icon_128.png"; //$NON-NLS-1$ - } - - if (mUpdaterData != null) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - shell.setImage(imgFactory.getImageByName(imageName)); - } - } - } - - /** - * Called by the main loop when the window has been disposed. - */ - private void dispose() { - mLogWindow.close(); - mUpdaterData.getSources().saveUserAddons(mUpdaterData.getSdkLog()); - } - - /** - * Callback called when the window shell is disposed. - */ - private void onAndroidSdkUpdaterDispose() { - if (mUpdaterData != null) { - ImageFactory imgFactory = mUpdaterData.getImageFactory(); - if (imgFactory != null) { - imgFactory.dispose(); - } - } - } - - /** - * Used to initialize the sources. - */ - private void setupSources() { - mUpdaterData.setupDefaultSources(); - } - - /** - * Initializes settings. - * This must be called after addExtraPages(), which created a settings page. - * Iterate through all the pages to find the first (and supposedly unique) setting page, - * and use it to load and apply these settings. - */ - private void initializeSettings() { - mSettingsController = mUpdaterData.getSettingsController(); - mSettingsController.loadSettings(); - mSettingsController.applySettings(); - } - - private void onToggleLogWindow() { - // toggle visibility - if (!mButtonShowLog.isDisposed()) { - mLogWindow.setVisible(!mLogWindow.isVisible()); - mButtonShowLog.setState(mLogWindow.isVisible() ? 1 : 0); - } - } - - private void onStopSelected() { - // TODO - } - - private void onAvdManager() { - ITaskFactory oldFactory = mUpdaterData.getTaskFactory(); - - try { - AvdManagerWindowImpl1 win = new AvdManagerWindowImpl1( - mShell, - mUpdaterData, - AvdInvocationContext.DIALOG); - - win.open(); - } catch (Exception e) { - mUpdaterData.getSdkLog().error(e, "AVD Manager window error"); - } finally { - mUpdaterData.setTaskFactory(oldFactory); - } - } - - // End of hiding from SWT Designer - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/ShellSizeAndPos.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/ShellSizeAndPos.java deleted file mode 100755 index 4921ba0..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/ui/ShellSizeAndPos.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - - -import com.android.prefs.AndroidLocation; - -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Monitor; -import org.eclipse.swt.widgets.Shell; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Properties; - -/** - * Utility to save & restore the size and position on a window - * using a common config file. - */ -public class ShellSizeAndPos { - - private static final String SETTINGS_FILENAME = "androidwin.cfg"; //$NON-NLS-1$ - private static final String PX = "_px"; //$NON-NLS-1$ - private static final String PY = "_py"; //$NON-NLS-1$ - private static final String SX = "_sx"; //$NON-NLS-1$ - private static final String SY = "_sy"; //$NON-NLS-1$ - - public static void loadSizeAndPos(Shell shell, String prefix) { - Properties props = loadProperties(); - - try { - int px = Integer.parseInt(props.getProperty(prefix + PX)); - int py = Integer.parseInt(props.getProperty(prefix + PY)); - int sx = Integer.parseInt(props.getProperty(prefix + SX)); - int sy = Integer.parseInt(props.getProperty(prefix + SY)); - - Point p1 = new Point(px, py); - Point p2 = new Point(px + sx, py + sy); - Rectangle r = new Rectangle(px, py, sy, sy); - - Monitor bestMatch = null; - int bestSurface = -1; - for (Monitor monitor : shell.getDisplay().getMonitors()) { - Rectangle area = monitor.getClientArea(); - if (area.contains(p1) && area.contains(p2)) { - // The shell is fully visible on this monitor. Just use that. - bestMatch = monitor; - bestSurface = Integer.MAX_VALUE; - break; - } else { - // Find which monitor displays the largest surface of the window. - // We'll use this one to center the window there, to make sure we're not - // starting split between several monitors. - Rectangle i = area.intersection(r); - int surface = i.width * i.height; - if (surface > bestSurface) { - bestSurface = surface; - bestMatch = monitor; - } - } - } - - if (bestMatch != null && bestSurface != Integer.MAX_VALUE) { - // Recenter the window on this monitor and make sure it fits - Rectangle area = bestMatch.getClientArea(); - - sx = Math.min(sx, area.width); - sy = Math.min(sy, area.height); - px = area.x + (area.width - sx) / 2; - py = area.y + (area.height - sy) / 2; - } - - shell.setLocation(px, py); - shell.setSize(sx, sy); - - } catch ( Exception e) { - // Ignore exception. We could typically get NPE from the getProperty - // or NumberFormatException from parseInt calls. Either way, do - // nothing if anything goes wrong. - } - } - - public static void saveSizeAndPos(Shell shell, String prefix) { - Properties props = loadProperties(); - - Point loc = shell.getLocation(); - Point size = shell.getSize(); - - props.setProperty(prefix + PX, Integer.toString(loc.x)); - props.setProperty(prefix + PY, Integer.toString(loc.y)); - props.setProperty(prefix + SX, Integer.toString(size.x)); - props.setProperty(prefix + SY, Integer.toString(size.y)); - - saveProperties(props); - } - - /** - * Load properties saved in {@link #SETTINGS_FILENAME}. - * If the file does not exists or doesn't load properly, just return an - * empty set of properties. - */ - private static Properties loadProperties() { - Properties props = new Properties(); - FileInputStream fis = null; - - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SETTINGS_FILENAME); - if (f.exists()) { - fis = new FileInputStream(f); - - props.load(fis); - } - } catch (Exception e) { - // Ignore - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - } - } - } - - return props; - } - - private static void saveProperties(Properties props) { - FileOutputStream fos = null; - - try { - String folder = AndroidLocation.getFolder(); - File f = new File(folder, SETTINGS_FILENAME); - fos = new FileOutputStream(f); - - props.store(fos, "## Size and Pos for SDK Manager Windows"); //$NON-NLS-1$ - - } catch (Exception e) { - // ignore - } finally { - if (fos != null) { - try { - fos.close(); - } catch (IOException e) { - } - } - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ILogUiProvider.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ILogUiProvider.java deleted file mode 100755 index 8f77b7a..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ILogUiProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - - -/** - * Interface for a user interface that displays the log from a task monitor. - */ -public interface ILogUiProvider { - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - public abstract void setDescription(String description); - - /** - * Logs a "normal" information line. - * This method can be invoked from a non-UI thread. - */ - public abstract void log(String log); - - /** - * Logs an "error" information line. - * This method can be invoked from a non-UI thread. - */ - public abstract void logError(String log); - - /** - * Logs a "verbose" information line, that is extra details which are typically - * not that useful for the end-user and might be hidden until explicitly shown. - * This method can be invoked from a non-UI thread. - */ - public abstract void logVerbose(String log); - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/IProgressUiProvider.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/IProgressUiProvider.java deleted file mode 100755 index 4e2c131..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/IProgressUiProvider.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.UserCredentials; - -import org.eclipse.swt.widgets.ProgressBar; - -/** - * Interface for a user interface that displays both a task status - * (e.g. via an {@link ITaskMonitor}) and the progress state of the - * task (e.g. via a progress bar.) - * <p/> - * See {@link ITaskMonitor} for details on how a monitor expects to - * be displayed. - */ -interface IProgressUiProvider extends ILogUiProvider { - - public abstract boolean isCancelRequested(); - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - @Override - public abstract void setDescription(String description); - - /** - * Sets the max value of the progress bar. - * This method can be invoked from a non-UI thread. - * - * @see ProgressBar#setMaximum(int) - */ - public abstract void setProgressMax(int max); - - /** - * Sets the current value of the progress bar. - * This method can be invoked from a non-UI thread. - */ - public abstract void setProgress(int value); - - /** - * Returns the current value of the progress bar, - * between 0 and up to {@link #setProgressMax(int)} - 1. - * This method can be invoked from a non-UI thread. - */ - public abstract int getProgress(); - - /** - * Display a yes/no question dialog box. - * - * This implementation allow this to be called from any thread, it - * makes sure the dialog is opened synchronously in the ui thread. - * - * @param title The title of the dialog box - * @param message The error message - * @return true if YES was clicked. - */ - public abstract boolean displayPrompt(String title, String message); - - /** - * Launch an interface which asks for login credentials. Implementations - * MUST allow this to be called from any thread, e.g. by making sure the - * dialog is opened synchronously in the UI thread. - * - * @param title The title of the dialog box. - * @param message The message to be displayed as an instruction. - * @return Returns user provided credentials - */ - public UserCredentials displayLoginCredentialsPrompt(String title, String message); - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java deleted file mode 100755 index d5404ae..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTask.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskMonitor; - -import org.eclipse.swt.widgets.Shell; - - -/** - * An {@link ITaskMonitor} that displays a {@link ProgressTaskDialog}. - */ -public final class ProgressTask extends TaskMonitorImpl { - - private final String mTitle; - private final ProgressTaskDialog mDialog; - private volatile boolean mAutoClose = true; - - - /** - * Creates a new {@link ProgressTask} with the given title. - * This does NOT start the task. The caller must invoke {@link #start(ITask)}. - */ - public ProgressTask(Shell parent, String title) { - super(new ProgressTaskDialog(parent)); - mTitle = title; - mDialog = (ProgressTaskDialog) getUiProvider(); - mDialog.setText(mTitle); - } - - /** - * Execute the given task in a separate thread (not the UI thread). - * This blocks till the thread ends. - * <p/> - * The {@link ProgressTask} must not be reused after this call. - */ - public void start(ITask task) { - assert mDialog != null; - mDialog.open(createTaskThread(mTitle, task)); - } - - /** - * Changes the auto-close behavior of the dialog on task completion. - * - * @param autoClose True if the dialog should be closed automatically when the task - * has completed. - */ - public void setAutoClose(boolean autoClose) { - if (autoClose != mAutoClose) { - if (autoClose) { - mDialog.setAutoCloseRequested(); - } else { - mDialog.setManualCloseRequested(); - } - mAutoClose = autoClose; - } - } - - /** - * Creates a thread to run the task. The thread has not been started yet. - * When the task completes, requests to close the dialog. - * - * @return A new thread that will run the task. The thread has not been started yet. - */ - private Thread createTaskThread(String title, final ITask task) { - if (task != null) { - return new Thread(title) { - @Override - public void run() { - task.run(ProgressTask.this); - if (mAutoClose) { - mDialog.setAutoCloseRequested(); - } else { - mDialog.setManualCloseRequested(); - } - } - }; - } - return null; - } - - /** - * {@inheritDoc} - * <p/> - * Sets the dialog to not auto-close since we want the user to see the error - * (this is equivalent to calling {@code setAutoClose(false)}). - */ - @Override - public void logError(String format, Object...args) { - setAutoClose(false); - super.logError(format, args); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskDialog.java deleted file mode 100755 index 50f1e57..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskDialog.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - -import com.android.SdkConstants; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.UserCredentials; -import com.android.sdkuilib.ui.AuthenticationDialog; -import com.android.sdkuilib.ui.GridDialog; -import com.android.utils.Pair; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.ShellAdapter; -import org.eclipse.swt.events.ShellEvent; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Dialog; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.ProgressBar; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - - -/** - * Implements a {@link ProgressTaskDialog}, used by the {@link ProgressTask} class. - * This separates the dialog UI from the task logic. - * - * Note: this does not implement the {@link ITaskMonitor} interface to avoid confusing - * SWT Designer. - */ -final class ProgressTaskDialog extends Dialog implements IProgressUiProvider { - - /** - * Min Y location for dialog. Need to deal with the menu bar on mac os. - */ - private final static int MIN_Y = SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN ? - 20 : 0; - - private static enum CancelMode { - /** Cancel button says "Cancel" and is enabled. Waiting for user to cancel. */ - ACTIVE, - /** Cancel button has been clicked. Waiting for thread to finish. */ - CANCEL_PENDING, - /** Close pending. Close button clicked or thread finished but there were some - * messages so the user needs to manually close. */ - CLOSE_MANUAL, - /** Close button clicked or thread finished. The window will automatically close. */ - CLOSE_AUTO - } - - /** The current mode of operation of the dialog. */ - private CancelMode mCancelMode = CancelMode.ACTIVE; - - /** Last dialog size for this session. */ - private static Point sLastSize; - - - // UI fields - private Shell mDialogShell; - private Composite mRootComposite; - private Label mLabel; - private ProgressBar mProgressBar; - private Button mCancelButton; - private Text mResultText; - - - /** - * Create the dialog. - * @param parent Parent container - */ - public ProgressTaskDialog(Shell parent) { - super(parent, SWT.APPLICATION_MODAL); - } - - /** - * Open the dialog and blocks till it gets closed - * @param taskThread The thread to run the task. Cannot be null. - */ - public void open(Thread taskThread) { - createContents(); - positionShell(); //$hide$ (hide from SWT designer) - mDialogShell.open(); - mDialogShell.layout(); - - startThread(taskThread); //$hide$ (hide from SWT designer) - - Display display = getParent().getDisplay(); - while (!mDialogShell.isDisposed() && mCancelMode != CancelMode.CLOSE_AUTO) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - - setCancelRequested(); //$hide$ (hide from SWT designer) - - if (!mDialogShell.isDisposed()) { - sLastSize = mDialogShell.getSize(); - mDialogShell.close(); - } - } - - /** - * Create contents of the dialog. - */ - private void createContents() { - mDialogShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE); - mDialogShell.addShellListener(new ShellAdapter() { - @Override - public void shellClosed(ShellEvent e) { - onShellClosed(e); - } - }); - mDialogShell.setLayout(new GridLayout(1, false)); - mDialogShell.setSize(450, 300); - mDialogShell.setText(getText()); - - mRootComposite = new Composite(mDialogShell, SWT.NONE); - mRootComposite.setLayout(new GridLayout(2, false)); - mRootComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); - - mLabel = new Label(mRootComposite, SWT.NONE); - mLabel.setText("Task"); - mLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); - - mProgressBar = new ProgressBar(mRootComposite, SWT.NONE); - mProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - mCancelButton = new Button(mRootComposite, SWT.NONE); - mCancelButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); - mCancelButton.setText("Cancel"); - - mCancelButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onCancelSelected(); //$hide$ - } - }); - - mResultText = new Text(mRootComposite, - SWT.BORDER | SWT.READ_ONLY | SWT.WRAP | - SWT.H_SCROLL | SWT.V_SCROLL | SWT.CANCEL | SWT.MULTI); - mResultText.setEditable(true); - mResultText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); - } - - // -- End of UI, Start of internal logic ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - @Override - public boolean isCancelRequested() { - return mCancelMode != CancelMode.ACTIVE; - } - - /** - * Sets the mode to cancel pending. - * The first time this grays the cancel button, to let the user know that the - * cancel operation is pending. - */ - public void setCancelRequested() { - if (!mDialogShell.isDisposed()) { - // The dialog is not disposed, make sure to run all this in the UI thread - // and lock on the cancel button mode. - mDialogShell.getDisplay().syncExec(new Runnable() { - - @Override - public void run() { - synchronized (mCancelMode) { - if (mCancelMode == CancelMode.ACTIVE) { - mCancelMode = CancelMode.CANCEL_PENDING; - - if (!mCancelButton.isDisposed()) { - mCancelButton.setEnabled(false); - } - } - } - } - }); - } else { - // The dialog is disposed. Just set the boolean. We shouldn't be here. - if (mCancelMode == CancelMode.ACTIVE) { - mCancelMode = CancelMode.CANCEL_PENDING; - } - } - } - - /** - * Sets the mode to close manual. - * The first time, this also ungrays the pause button and converts it to a close button. - */ - public void setManualCloseRequested() { - if (!mDialogShell.isDisposed()) { - // The dialog is not disposed, make sure to run all this in the UI thread - // and lock on the cancel button mode. - mDialogShell.getDisplay().syncExec(new Runnable() { - - @Override - public void run() { - synchronized (mCancelMode) { - if (mCancelMode != CancelMode.CLOSE_MANUAL && - mCancelMode != CancelMode.CLOSE_AUTO) { - mCancelMode = CancelMode.CLOSE_MANUAL; - - if (!mCancelButton.isDisposed()) { - mCancelButton.setEnabled(true); - mCancelButton.setText("Close"); - } - } - } - } - }); - } else { - // The dialog is disposed. Just set the booleans. We shouldn't be here. - if (mCancelMode != CancelMode.CLOSE_MANUAL && - mCancelMode != CancelMode.CLOSE_AUTO) { - mCancelMode = CancelMode.CLOSE_MANUAL; - } - } - } - - /** - * Sets the mode to close auto. - * The main loop will just exit and close the shell at the first opportunity. - */ - public void setAutoCloseRequested() { - synchronized (mCancelMode) { - if (mCancelMode != CancelMode.CLOSE_AUTO) { - mCancelMode = CancelMode.CLOSE_AUTO; - } - } - } - - /** - * Callback invoked when the cancel button is selected. - * When in closing mode, this simply closes the shell. Otherwise triggers a cancel. - */ - private void onCancelSelected() { - if (mCancelMode == CancelMode.CLOSE_MANUAL) { - setAutoCloseRequested(); - } else { - setCancelRequested(); - } - } - - /** - * Callback invoked when the shell is closed either by clicking the close button - * on by calling shell.close(). - * This does the same thing as clicking the cancel/close button unless the mode is - * to auto close in which case we should do nothing to let the shell close normally. - */ - private void onShellClosed(ShellEvent e) { - if (mCancelMode != CancelMode.CLOSE_AUTO) { - e.doit = false; // don't close directly - onCancelSelected(); - } - } - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - @Override - public void setDescription(final String description) { - mDialogShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!mLabel.isDisposed()) { - mLabel.setText(description); - } - } - }); - } - - /** - * Adds to the log in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - @Override - public void log(final String info) { - if (!mDialogShell.isDisposed()) { - mDialogShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!mResultText.isDisposed()) { - mResultText.setVisible(true); - String lastText = mResultText.getText(); - if (lastText != null && - lastText.length() > 0 && - !lastText.endsWith("\n") && //$NON-NLS-1$ - !info.startsWith("\n")) { //$NON-NLS-1$ - mResultText.append("\n"); //$NON-NLS-1$ - } - mResultText.append(info); - } - } - }); - } - } - - @Override - public void logError(String info) { - log(info); - } - - @Override - public void logVerbose(String info) { - log(info); - } - - /** - * Sets the max value of the progress bar. - * This method can be invoked from a non-UI thread. - * - * @see ProgressBar#setMaximum(int) - */ - @Override - public void setProgressMax(final int max) { - if (!mDialogShell.isDisposed()) { - mDialogShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!mProgressBar.isDisposed()) { - mProgressBar.setMaximum(max); - } - } - }); - } - } - - /** - * Sets the current value of the progress bar. - * This method can be invoked from a non-UI thread. - */ - @Override - public void setProgress(final int value) { - if (!mDialogShell.isDisposed()) { - mDialogShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!mProgressBar.isDisposed()) { - mProgressBar.setSelection(value); - } - } - }); - } - } - - /** - * Returns the current value of the progress bar, - * between 0 and up to {@link #setProgressMax(int)} - 1. - * This method can be invoked from a non-UI thread. - */ - @Override - public int getProgress() { - final int[] result = new int[] { 0 }; - - if (!mDialogShell.isDisposed()) { - mDialogShell.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!mProgressBar.isDisposed()) { - result[0] = mProgressBar.getSelection(); - } - } - }); - } - - return result[0]; - } - - /** - * Display a yes/no question dialog box. - * - * This implementation allow this to be called from any thread, it - * makes sure the dialog is opened synchronously in the ui thread. - * - * @param title The title of the dialog box - * @param message The error message - * @return true if YES was clicked. - */ - @Override - public boolean displayPrompt(final String title, final String message) { - Display display = mDialogShell.getDisplay(); - - // we need to ask the user what he wants to do. - final boolean[] result = new boolean[] { false }; - display.syncExec(new Runnable() { - @Override - public void run() { - result[0] = MessageDialog.openQuestion(mDialogShell, title, message); - } - }); - return result[0]; - } - - /** - * This method opens a pop-up window which requests for User Login and - * password. - * - * @param title The title of the window. - * @param message The message to displayed in the login/password window. - * @return Returns a {@link Pair} holding the entered login and password. - * The information must always be in the following order: - * Login,Password. So in order to retrieve the <b>login</b> callers - * should retrieve the first element, and the second value for the - * <b>password</b>. - * If operation is <b>canceled</b> by user the return value must be <b>null</b>. - * @see ITaskMonitor#displayLoginCredentialsPrompt(String, String) - */ - @Override - public UserCredentials displayLoginCredentialsPrompt( - final String title, final String message) { - Display display = mDialogShell.getDisplay(); - - // open dialog and request login and password - GetUserCredentialsTask task = new GetUserCredentialsTask(mDialogShell, title, message); - display.syncExec(task); - - return task.getUserCredentials(); - } - - private static class GetUserCredentialsTask implements Runnable { - private UserCredentials mResult = null; - - private Shell mShell; - private String mTitle; - private String mMessage; - - public GetUserCredentialsTask(Shell shell, String title, String message) { - mShell = shell; - mTitle = title; - mMessage = message; - } - - @Override - public void run() { - AuthenticationDialog authenticationDialog = new AuthenticationDialog(mShell, - mTitle, mMessage); - int dlgResult= authenticationDialog.open(); - if(dlgResult == GridDialog.OK) { - mResult = new UserCredentials( - authenticationDialog.getLogin(), - authenticationDialog.getPassword(), - authenticationDialog.getWorkstation(), - authenticationDialog.getDomain()); - } - } - - public UserCredentials getUserCredentials() { - return mResult; - } - } - - /** - * Starts the thread that runs the task. - * This is deferred till the UI is created. - */ - private void startThread(Thread taskThread) { - if (taskThread != null) { - taskThread.start(); - } - } - - /** - * Centers the dialog in its parent shell. - */ - private void positionShell() { - // Centers the dialog in its parent shell - Shell child = mDialogShell; - Shell parent = getParent(); - if (child != null && parent != null) { - - // get the parent client area with a location relative to the display - Rectangle parentArea = parent.getClientArea(); - Point parentLoc = parent.getLocation(); - int px = parentLoc.x; - int py = parentLoc.y; - int pw = parentArea.width; - int ph = parentArea.height; - - // Reuse the last size if there's one, otherwise use the default - Point childSize = sLastSize != null ? sLastSize : child.getSize(); - int cw = childSize.x; - int ch = childSize.y; - - int x = px + (pw - cw) / 2; - if (x < 0) x = 0; - - int y = py + (ph - ch) / 2; - if (y < MIN_Y) y = MIN_Y; - - child.setLocation(x, y); - child.setSize(cw, ch); - } - } - - // End of hiding from SWT Designer - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java deleted file mode 100755 index 17cba7a..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressTaskFactory.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.ITaskMonitor; - -import org.eclipse.swt.widgets.Shell; - -/** - * An {@link ITaskFactory} that creates a new {@link ProgressTask} dialog - * for each new task. - */ -public final class ProgressTaskFactory implements ITaskFactory { - - private final Shell mShell; - - public ProgressTaskFactory(Shell shell) { - mShell = shell; - } - - @Override - public void start(String title, ITask task) { - start(title, null /*parentMonitor*/, task); - } - - @Override - public void start(String title, ITaskMonitor parentMonitor, ITask task) { - - if (parentMonitor == null) { - ProgressTask p = new ProgressTask(mShell, title); - p.start(task); - } else { - // Use all the reminder of the parent monitor. - if (parentMonitor.getProgressMax() == 0) { - parentMonitor.setProgressMax(1); - } - - ITaskMonitor sub = parentMonitor.createSubMonitor( - parentMonitor.getProgressMax() - parentMonitor.getProgress()); - try { - task.run(sub); - } finally { - int delta = - sub.getProgressMax() - sub.getProgress(); - if (delta > 0) { - sub.incProgress(delta); - } - } - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressView.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressView.java deleted file mode 100755 index 8987351..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressView.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.UserCredentials; -import com.android.sdkuilib.ui.AuthenticationDialog; -import com.android.sdkuilib.ui.GridDialog; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.ProgressBar; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Widget; - -import java.util.concurrent.atomic.AtomicReference; - - -/** - * Implements a "view" that uses an existing progress bar, status button and - * status text to display a {@link ITaskMonitor}. - */ -public final class ProgressView implements IProgressUiProvider { - - private static enum State { - /** View created but there's no task running. Next state can only be ACTIVE. */ - IDLE, - /** A task is currently running. Next state is either STOP_PENDING or IDLE. */ - ACTIVE, - /** Stop button has been clicked. Waiting for thread to finish. Next state is IDLE. */ - STOP_PENDING, - } - - /** The current mode of operation of the dialog. */ - private State mState = State.IDLE; - - - - // UI fields - private final Label mLabel; - private final Control mStopButton; - private final ProgressBar mProgressBar; - - /** Logger object. Cannot not be null. */ - private final ILogUiProvider mLog; - - /** - * Creates a new {@link ProgressView} object, a simple "holder" for the various - * widgets used to display and update a progress + status bar. - * - * @param label The label to display titles of status updates (e.g. task titles and - * calls to {@link #setDescription(String)}.) Must not be null. - * @param progressBar The progress bar to update during a task. Must not be null. - * @param stopButton The stop button. It will be disabled when there's no task that can - * be interrupted. A selection listener will be attached to it. Optional. Can be null. - * @param log A <em>mandatory</em> logger object that will be used to report all the log. - * Must not be null. - */ - public ProgressView( - Label label, - ProgressBar progressBar, - Control stopButton, - ILogUiProvider log) { - mLabel = label; - mProgressBar = progressBar; - mLog = log; - mProgressBar.setEnabled(false); - - mStopButton = stopButton; - if (mStopButton != null) { - mStopButton.addListener(SWT.Selection, new Listener() { - @Override - public void handleEvent(Event event) { - if (mState == State.ACTIVE) { - changeState(State.STOP_PENDING); - } - } - }); - } - } - - /** - * Starts the task and block till it's either finished or canceled. - * This can be called from a non-UI thread safely. - * <p/> - * When a task is started from within a monitor, it reuses the thread - * from the parent. Otherwise it starts a new thread and runs it own - * UI loop. This means the task can perform UI operations using - * {@link Display#asyncExec(Runnable)}. - * <p/> - * In either case, the method only returns when the task has finished. - */ - public void startTask( - final String title, - final ITaskMonitor parentMonitor, - final ITask task) { - if (task != null) { - try { - if (parentMonitor == null && !mProgressBar.isDisposed()) { - mLabel.setText(title); - mProgressBar.setSelection(0); - mProgressBar.setEnabled(true); - changeState(ProgressView.State.ACTIVE); - } - - Runnable r = new Runnable() { - @Override - public void run() { - if (parentMonitor == null) { - task.run(new TaskMonitorImpl(ProgressView.this)); - - } else { - // Use all the reminder of the parent monitor. - if (parentMonitor.getProgressMax() == 0) { - parentMonitor.setProgressMax(1); - } - ITaskMonitor sub = parentMonitor.createSubMonitor( - parentMonitor.getProgressMax() - parentMonitor.getProgress()); - try { - task.run(sub); - } finally { - int delta = - sub.getProgressMax() - sub.getProgress(); - if (delta > 0) { - sub.incProgress(delta); - } - } - } - } - }; - - // If for some reason the UI has been disposed, just abort the thread. - if (mProgressBar.isDisposed()) { - return; - } - - if (TaskMonitorImpl.isTaskMonitorImpl(parentMonitor)) { - // If there's a parent monitor and it's our own class, we know this parent - // is already running a thread and the base one is running an event loop. - // We should thus not run a second event loop and we can process the - // runnable right here instead of spawning a thread inside the thread. - r.run(); - - } else { - // No parent monitor. This is the first one so we need a thread and - // we need to process UI events. - - final Thread t = new Thread(r, title); - t.start(); - - // Process the app's event loop whilst we wait for the thread to finish - while (!mProgressBar.isDisposed() && t.isAlive()) { - Display display = mProgressBar.getDisplay(); - if (!mProgressBar.isDisposed() && !display.readAndDispatch()) { - display.sleep(); - } - } - } - } catch (Exception e) { - // TODO log - - } finally { - if (parentMonitor == null && !mProgressBar.isDisposed()) { - changeState(ProgressView.State.IDLE); - mProgressBar.setSelection(0); - mProgressBar.setEnabled(false); - } - } - } - } - - private void syncExec(final Widget widget, final Runnable runnable) { - if (widget != null && !widget.isDisposed()) { - widget.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - // Check again whether the widget got disposed between the time where - // we requested the syncExec and the time it actually happened. - if (!widget.isDisposed()) { - runnable.run(); - } - } - }); - } - } - - private void changeState(State state) { - if (mState != null ) { - mState = state; - } - - syncExec(mStopButton, new Runnable() { - @Override - public void run() { - mStopButton.setEnabled(mState == State.ACTIVE); - } - }); - - } - - // --- Implementation of ITaskUiProvider --- - - @Override - public boolean isCancelRequested() { - return mState != State.ACTIVE; - } - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - @Override - public void setDescription(final String description) { - syncExec(mLabel, new Runnable() { - @Override - public void run() { - mLabel.setText(description); - } - }); - - mLog.setDescription(description); - } - - /** - * Logs a "normal" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void log(String log) { - mLog.log(log); - } - - /** - * Logs an "error" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logError(String log) { - mLog.logError(log); - } - - /** - * Logs a "verbose" information line, that is extra details which are typically - * not that useful for the end-user and might be hidden until explicitly shown. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logVerbose(String log) { - mLog.logVerbose(log); - } - - /** - * Sets the max value of the progress bar. - * This method can be invoked from a non-UI thread. - * - * @see ProgressBar#setMaximum(int) - */ - @Override - public void setProgressMax(final int max) { - syncExec(mProgressBar, new Runnable() { - @Override - public void run() { - mProgressBar.setMaximum(max); - } - }); - } - - /** - * Sets the current value of the progress bar. - * This method can be invoked from a non-UI thread. - */ - @Override - public void setProgress(final int value) { - syncExec(mProgressBar, new Runnable() { - @Override - public void run() { - mProgressBar.setSelection(value); - } - }); - } - - /** - * Returns the current value of the progress bar, - * between 0 and up to {@link #setProgressMax(int)} - 1. - * This method can be invoked from a non-UI thread. - */ - @Override - public int getProgress() { - final int[] result = new int[] { 0 }; - - if (!mProgressBar.isDisposed()) { - mProgressBar.getDisplay().syncExec(new Runnable() { - @Override - public void run() { - if (!mProgressBar.isDisposed()) { - result[0] = mProgressBar.getSelection(); - } - } - }); - } - - return result[0]; - } - - @Override - public boolean displayPrompt(final String title, final String message) { - final boolean[] result = new boolean[] { false }; - - syncExec(mProgressBar, new Runnable() { - @Override - public void run() { - Shell shell = mProgressBar.getShell(); - result[0] = MessageDialog.openQuestion(shell, title, message); - } - }); - - return result[0]; - } - - /** - * This method opens a pop-up window which requests for User Credentials. - * - * @param title The title of the window. - * @param message The message to displayed in the login/password window. - * @return Returns user provided credentials. - * If operation is <b>canceled</b> by user the return value must be <b>null</b>. - * @see ITaskMonitor#displayLoginCredentialsPrompt(String, String) - */ - @Override - public UserCredentials - displayLoginCredentialsPrompt(final String title, final String message) { - final AtomicReference<UserCredentials> result = new AtomicReference<UserCredentials>(null); - - // open dialog and request login and password - syncExec(mProgressBar, new Runnable() { - @Override - public void run() { - Shell shell = mProgressBar.getShell(); - AuthenticationDialog authenticationDialog = new AuthenticationDialog(shell, - title, - message); - int dlgResult = authenticationDialog.open(); - if (dlgResult == GridDialog.OK) { - result.set(new UserCredentials( - authenticationDialog.getLogin(), - authenticationDialog.getPassword(), - authenticationDialog.getWorkstation(), - authenticationDialog.getDomain())); - } - } - }); - - return result.get(); - } -} - diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressViewFactory.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressViewFactory.java deleted file mode 100755 index 2590169..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/ProgressViewFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.ITaskMonitor; - -/** - * An {@link ITaskFactory} that creates a new {@link ProgressTask} dialog - * for each new task. - */ -public final class ProgressViewFactory implements ITaskFactory { - - private ProgressView mProgressView; - - public ProgressViewFactory() { - } - - public void setProgressView(ProgressView progressView) { - mProgressView = progressView; - } - - @Override - public void start(String title, ITask task) { - start(title, null /*monitor*/, task); - } - - @Override - public void start(String title, ITaskMonitor parentMonitor, ITask task) { - assert mProgressView != null; - mProgressView.startTask(title, parentMonitor, task); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/TaskMonitorImpl.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/TaskMonitorImpl.java deleted file mode 100755 index 4d4f3c9..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/tasks/TaskMonitorImpl.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.tasks; - -import com.android.annotations.NonNull; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.UserCredentials; - -/** - * Internal class that implements the logic of an {@link ITaskMonitor}. - * It doesn't deal with any UI directly. Instead it delegates the UI to - * the provided {@link IProgressUiProvider}. - */ -class TaskMonitorImpl implements ITaskMonitor { - - private static final double MAX_COUNT = 10000.0; - - private interface ISubTaskMonitor extends ITaskMonitor { - public void subIncProgress(double realDelta); - } - - private double mIncCoef = 0; - private double mValue = 0; - private final IProgressUiProvider mUi; - - /** - * Returns true if the given {@code monitor} is an instance of {@link TaskMonitorImpl} - * or its private SubTaskMonitor. - */ - public static boolean isTaskMonitorImpl(ITaskMonitor monitor) { - return monitor instanceof TaskMonitorImpl || monitor instanceof SubTaskMonitor; - } - - /** - * Constructs a new {@link TaskMonitorImpl} that relies on the given - * {@link IProgressUiProvider} to change the user interface. - * @param ui The {@link IProgressUiProvider}. Cannot be null. - */ - public TaskMonitorImpl(IProgressUiProvider ui) { - mUi = ui; - } - - /** Returns the {@link IProgressUiProvider} passed to the constructor. */ - public IProgressUiProvider getUiProvider() { - return mUi; - } - - /** - * Sets the description in the current task dialog. - * This method can be invoked from a non-UI thread. - */ - @Override - public void setDescription(String format, Object... args) { - final String text = String.format(format, args); - mUi.setDescription(text); - } - - /** - * Logs a "normal" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void log(String format, Object... args) { - String text = String.format(format, args); - mUi.log(text); - } - - /** - * Logs an "error" information line. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logError(String format, Object... args) { - String text = String.format(format, args); - mUi.logError(text); - } - - /** - * Logs a "verbose" information line, that is extra details which are typically - * not that useful for the end-user and might be hidden until explicitly shown. - * This method can be invoked from a non-UI thread. - */ - @Override - public void logVerbose(String format, Object... args) { - String text = String.format(format, args); - mUi.logVerbose(text); - } - - /** - * Sets the max value of the progress bar. - * This method can be invoked from a non-UI thread. - * - * Weird things will happen if setProgressMax is called multiple times - * *after* {@link #incProgress(int)}: we don't try to adjust it on the - * fly. - */ - @Override - public void setProgressMax(int max) { - assert max > 0; - // Always set the dialog's progress max to 10k since it only handles - // integers and we want to have a better inner granularity. Instead - // we use the max to compute a coefficient for inc deltas. - mUi.setProgressMax((int) MAX_COUNT); - mIncCoef = max > 0 ? MAX_COUNT / max : 0; - assert mIncCoef > 0; - } - - @Override - public int getProgressMax() { - return mIncCoef > 0 ? (int) (MAX_COUNT / mIncCoef) : 0; - } - - /** - * Increments the current value of the progress bar. - * - * This method can be invoked from a non-UI thread. - */ - @Override - public void incProgress(int delta) { - if (delta > 0 && mIncCoef > 0) { - internalIncProgress(delta * mIncCoef); - } - } - - private void internalIncProgress(double realDelta) { - mValue += realDelta; - mUi.setProgress((int)mValue); - } - - /** - * Returns the current value of the progress bar, - * between 0 and up to {@link #setProgressMax(int)} - 1. - * - * This method can be invoked from a non-UI thread. - */ - @Override - public int getProgress() { - // mIncCoef is 0 if setProgressMax hasn't been used yet. - return mIncCoef > 0 ? (int)(mUi.getProgress() / mIncCoef) : 0; - } - - /** - * Returns true if the "Cancel" button was selected. - * It is up to the task thread to pool this and exit. - */ - @Override - public boolean isCancelRequested() { - return mUi.isCancelRequested(); - } - - /** - * Displays a yes/no question dialog box. - * - * This implementation allow this to be called from any thread, it - * makes sure the dialog is opened synchronously in the ui thread. - * - * @param title The title of the dialog box - * @param message The error message - * @return true if YES was clicked. - */ - @Override - public boolean displayPrompt(final String title, final String message) { - return mUi.displayPrompt(title, message); - } - - /** - * Displays a Login/Password dialog. This implementation allows this method to be - * called from any thread, it makes sure the dialog is opened synchronously - * in the ui thread. - * - * @param title The title of the dialog box - * @param message Message to be displayed - * @return Pair with entered login/password. Login is always the first - * element and Password is always the second. If any error occurs a - * pair with empty strings is returned. - */ - @Override - public UserCredentials displayLoginCredentialsPrompt(String title, String message) { - return mUi.displayLoginCredentialsPrompt(title, message); - } - - /** - * Creates a sub-monitor that will use up to tickCount on the progress bar. - * tickCount must be 1 or more. - */ - @Override - public ITaskMonitor createSubMonitor(int tickCount) { - assert mIncCoef > 0; - assert tickCount > 0; - return new SubTaskMonitor(this, null, mValue, tickCount * mIncCoef); - } - - // ----- ILogger interface ---- - - @Override - public void error(Throwable throwable, String errorFormat, Object... arg) { - if (errorFormat != null) { - logError("Error: " + errorFormat, arg); - } - - if (throwable != null) { - logError("%s", throwable.getMessage()); //$NON-NLS-1$ - } - } - - @Override - public void warning(@NonNull String warningFormat, Object... arg) { - log("Warning: " + warningFormat, arg); - } - - @Override - public void info(@NonNull String msgFormat, Object... arg) { - log(msgFormat, arg); - } - - @Override - public void verbose(@NonNull String msgFormat, Object... arg) { - log(msgFormat, arg); - } - - // ----- Sub Monitor ----- - - private static class SubTaskMonitor implements ISubTaskMonitor { - - private final TaskMonitorImpl mRoot; - private final ISubTaskMonitor mParent; - private final double mStart; - private final double mSpan; - private double mSubValue; - private double mSubCoef; - - /** - * Creates a new sub task monitor which will work for the given range [start, start+span] - * in its parent. - * - * @param taskMonitor The ProgressTask root - * @param parent The immediate parent. Can be the null or another sub task monitor. - * @param start The start value in the root's coordinates - * @param span The span value in the root's coordinates - */ - public SubTaskMonitor(TaskMonitorImpl taskMonitor, - ISubTaskMonitor parent, - double start, - double span) { - mRoot = taskMonitor; - mParent = parent; - mStart = start; - mSpan = span; - mSubValue = start; - } - - @Override - public boolean isCancelRequested() { - return mRoot.isCancelRequested(); - } - - @Override - public void setDescription(String format, Object... args) { - mRoot.setDescription(format, args); - } - - @Override - public void log(String format, Object... args) { - mRoot.log(format, args); - } - - @Override - public void logError(String format, Object... args) { - mRoot.logError(format, args); - } - - @Override - public void logVerbose(String format, Object... args) { - mRoot.logVerbose(format, args); - } - - @Override - public void setProgressMax(int max) { - assert max > 0; - mSubCoef = max > 0 ? mSpan / max : 0; - assert mSubCoef > 0; - } - - @Override - public int getProgressMax() { - return mSubCoef > 0 ? (int) (mSpan / mSubCoef) : 0; - } - - @Override - public int getProgress() { - // subCoef can be 0 if setProgressMax() and incProgress() haven't been called yet - assert mSubValue == mStart || mSubCoef > 0; - return mSubCoef > 0 ? (int)((mSubValue - mStart) / mSubCoef) : 0; - } - - @Override - public void incProgress(int delta) { - if (delta > 0 && mSubCoef > 0) { - subIncProgress(delta * mSubCoef); - } - } - - @Override - public void subIncProgress(double realDelta) { - mSubValue += realDelta; - if (mParent != null) { - mParent.subIncProgress(realDelta); - } else { - mRoot.internalIncProgress(realDelta); - } - } - - @Override - public boolean displayPrompt(String title, String message) { - return mRoot.displayPrompt(title, message); - } - - @Override - public UserCredentials displayLoginCredentialsPrompt(String title, String message) { - return mRoot.displayLoginCredentialsPrompt(title, message); - } - - @Override - public ITaskMonitor createSubMonitor(int tickCount) { - assert mSubCoef > 0; - assert tickCount > 0; - return new SubTaskMonitor(mRoot, - this, - mSubValue, - tickCount * mSubCoef); - } - - // ----- ILogger interface ---- - - @Override - public void error(Throwable throwable, String errorFormat, Object... arg) { - mRoot.error(throwable, errorFormat, arg); - } - - @Override - public void warning(@NonNull String warningFormat, Object... arg) { - mRoot.warning(warningFormat, arg); - } - - @Override - public void info(@NonNull String msgFormat, Object... arg) { - mRoot.info(msgFormat, arg); - } - - @Override - public void verbose(@NonNull String msgFormat, Object... arg) { - mRoot.verbose(msgFormat, arg); - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java deleted file mode 100644 index 93c0fe5..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdCreationDialog.java +++ /dev/null @@ -1,1103 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.SdkConstants; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.resources.Density; -import com.android.resources.ScreenSize; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISystemImage; -import com.android.sdklib.SdkManager; -import com.android.sdklib.devices.Camera; -import com.android.sdklib.devices.CameraLocation; -import com.android.sdklib.devices.Device; -import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.devices.Hardware; -import com.android.sdklib.devices.Screen; -import com.android.sdklib.devices.Storage; -import com.android.sdklib.internal.avd.AvdInfo; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.avd.AvdManager.AvdConflict; -import com.android.sdklib.internal.avd.HardwareProperties; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.ui.GridDialog; -import com.android.utils.ILogger; -import com.android.utils.Pair; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -public class AvdCreationDialog extends GridDialog { - - private AvdManager mAvdManager; - private ImageFactory mImageFactory; - private ILogger mSdkLog; - private AvdInfo mAvdInfo; - - // A map from manufacturers to their list of devices. - private Map<String, List<Device>> mDeviceMap; - private final TreeMap<String, IAndroidTarget> mCurrentTargets = - new TreeMap<String, IAndroidTarget>(); - - private Button mOkButton; - - private Text mAvdName; - - private Combo mDeviceManufacturer; - private Combo mDeviceName; - - private Combo mTarget; - private Combo mAbi; - - private Combo mFrontCamera; - private Combo mBackCamera; - - private Button mSnapshot; - private Button mGpuEmulation; - - private Text mRam; - private Text mVmHeap; - - private Text mDataPartition; - private Combo mDataPartitionSize; - - private Button mSdCardSizeRadio; - private Text mSdCardSize; - private Combo mSdCardSizeCombo; - private Button mSdCardFileRadio; - private Text mSdCardFile; - private Button mBrowseSdCard; - - private Button mForceCreation; - private Composite mStatusComposite; - - private Label mStatusIcon; - private Label mStatusLabel; - - /** - * {@link VerifyListener} for {@link Text} widgets that should only contains - * numbers. - */ - private final VerifyListener mDigitVerifier = new VerifyListener() { - @Override - public void verifyText(VerifyEvent event) { - int count = event.text.length(); - for (int i = 0; i < count; i++) { - char c = event.text.charAt(i); - if (c < '0' || c > '9') { - event.doit = false; - return; - } - } - } - }; - - public AvdCreationDialog(Shell shell, - AvdManager avdManager, - ImageFactory imageFactory, - ILogger log, - AvdInfo editAvdInfo) { - - super(shell, 2, false); - mAvdManager = avdManager; - mImageFactory = imageFactory; - mSdkLog = log; - mAvdInfo = editAvdInfo; - - mDeviceMap = new TreeMap<String, List<Device>>(); - - SdkManager sdkMan = avdManager.getSdkManager(); - if (sdkMan != null && sdkMan.getLocation() != null) { - List<Device> devices = (new DeviceManager(log)).getDevices(sdkMan.getLocation()); - for (Device d : devices) { - List<Device> list; - if (mDeviceMap.containsKey(d.getManufacturer())) { - list = mDeviceMap.get(d.getManufacturer()); - } else { - list = new ArrayList<Device>(); - mDeviceMap.put(d.getManufacturer(), list); - } - list.add(d); - } - } - } - - @Override - protected Control createContents(Composite parent) { - Control control = super.createContents(parent); - getShell().setText(mAvdInfo == null ? "Create new Android Virtual Device (AVD)" - : "Edit Android Virtual Device (AVD)"); - - mOkButton = getButton(IDialogConstants.OK_ID); - - if (mAvdInfo != null) { - fillExistingAvdInfo(mAvdInfo); - } - - validatePage(); - return control; - } - - @Override - public void createDialogContent(Composite parent) { - - Label label; - String tooltip; - ValidateListener validateListener = new ValidateListener(); - - // --- avd name - label = new Label(parent, SWT.NONE); - label.setText("AVD Name:"); - tooltip = "The name of the Android Virtual Device"; - label.setToolTipText(tooltip); - mAvdName = new Text(parent, SWT.BORDER); - mAvdName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mAvdName.addModifyListener(new CreateNameModifyListener()); - - // --- device selection - label = new Label(parent, SWT.NONE); - label.setText("Device\nManufacturer:"); - tooltip = "The manufacturer of the device this AVD will be based on"; - mDeviceManufacturer = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - for (String manufacturer : mDeviceMap.keySet()) { - mDeviceManufacturer.add(manufacturer); - } - mDeviceManufacturer.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDeviceManufacturer.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - reloadDeviceNameCombo(); - validatePage(); - } - }); - - label = new Label(parent, SWT.NONE); - label.setText("Device Name:"); - tooltip = "The name of the device this AVD will be based on"; - mDeviceName = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mDeviceName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDeviceName.addSelectionListener(new DeviceSelectionListener()); - - // --- api target - label = new Label(parent, SWT.NONE); - label.setText("Target:"); - tooltip = "The target API of the AVD"; - label.setToolTipText(tooltip); - mTarget = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mTarget.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mTarget.setToolTipText(tooltip); - mTarget.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - reloadAbiTypeCombo(); - validatePage(); - } - }); - - reloadTargetCombo(); - - // --- avd ABIs - label = new Label(parent, SWT.NONE); - label.setText("CPU/ABI:"); - tooltip = "The CPU/ABI of the virtual device"; - label.setToolTipText(tooltip); - mAbi = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mAbi.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mAbi.setToolTipText(tooltip); - mAbi.addSelectionListener(validateListener); - - label = new Label(parent, SWT.NONE); - label.setText("Front Camera:"); - tooltip = ""; - label.setToolTipText(tooltip); - mFrontCamera = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mFrontCamera.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mFrontCamera.add("None"); - mFrontCamera.add("Emulated"); - mFrontCamera.add("Webcam0"); - mFrontCamera.select(0); - - label = new Label(parent, SWT.NONE); - label.setText("Back Camera:"); - tooltip = ""; - label.setToolTipText(tooltip); - mBackCamera = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mBackCamera.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mBackCamera.add("None"); - mBackCamera.add("Emulated"); - mBackCamera.add("Webcam0"); - mBackCamera.select(0); - - toggleCameras(); - - // --- memory options group - label = new Label(parent, SWT.NONE); - label.setText("Memory Options:"); - - - Group memoryGroup = new Group(parent, SWT.BORDER); - memoryGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - memoryGroup.setLayout(new GridLayout(4, false)); - - label = new Label(memoryGroup, SWT.NONE); - label.setText("RAM:"); - tooltip = "The amount of RAM the emulated device should have in MiB"; - label.setToolTipText(tooltip); - mRam = new Text(memoryGroup, SWT.BORDER); - mRam.addVerifyListener(mDigitVerifier); - mRam.addModifyListener(validateListener); - mRam.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - label = new Label(memoryGroup, SWT.NONE); - label.setText("VM Heap:"); - tooltip = "The amount of memory, in MiB, available to typical Android applications"; - label.setToolTipText(tooltip); - mVmHeap = new Text(memoryGroup, SWT.BORDER); - mVmHeap.addVerifyListener(mDigitVerifier); - mVmHeap.addModifyListener(validateListener); - mVmHeap.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mVmHeap.setToolTipText(tooltip); - - // --- Data partition group - label = new Label(parent, SWT.NONE); - label.setText("Internal Storage:"); - tooltip = "The size of the data partition on the device."; - Group storageGroup = new Group(parent, SWT.NONE); - storageGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - storageGroup.setLayout(new GridLayout(2, false)); - mDataPartition = new Text(storageGroup, SWT.BORDER); - mDataPartition.setText("200"); - mDataPartition.addVerifyListener(mDigitVerifier); - mDataPartition.addModifyListener(validateListener); - mDataPartition.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDataPartitionSize = new Combo(storageGroup, SWT.READ_ONLY | SWT.DROP_DOWN); - mDataPartitionSize.add("MiB"); - mDataPartitionSize.add("GiB"); - mDataPartitionSize.select(0); - mDataPartitionSize.addModifyListener(validateListener); - - // --- sd card group - label = new Label(parent, SWT.NONE); - label.setText("SD Card:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group sdCardGroup = new Group(parent, SWT.NONE); - sdCardGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - sdCardGroup.setLayout(new GridLayout(3, false)); - - mSdCardSizeRadio = new Button(sdCardGroup, SWT.RADIO); - mSdCardSizeRadio.setText("Size:"); - mSdCardSizeRadio.setToolTipText("Create a new SD Card file"); - mSdCardSizeRadio.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - boolean sizeMode = mSdCardSizeRadio.getSelection(); - enableSdCardWidgets(sizeMode); - validatePage(); - } - }); - - mSdCardSize = new Text(sdCardGroup, SWT.BORDER); - mSdCardSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSdCardSize.addVerifyListener(mDigitVerifier); - mSdCardSize.addModifyListener(validateListener); - mSdCardSize.setToolTipText("Size of the new SD Card file (must be at least 9 MiB)"); - - mSdCardSizeCombo = new Combo(sdCardGroup, SWT.DROP_DOWN | SWT.READ_ONLY); - mSdCardSizeCombo.add("KiB"); - mSdCardSizeCombo.add("MiB"); - mSdCardSizeCombo.add("GiB"); - mSdCardSizeCombo.select(1); - mSdCardSizeCombo.addSelectionListener(validateListener); - - mSdCardFileRadio = new Button(sdCardGroup, SWT.RADIO); - mSdCardFileRadio.setText("File:"); - mSdCardFileRadio.setToolTipText("Use an existing file for the SD Card"); - - mSdCardFile = new Text(sdCardGroup, SWT.BORDER); - mSdCardFile.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSdCardFile.addModifyListener(validateListener); - mSdCardFile.setToolTipText("File to use for the SD Card"); - - mBrowseSdCard = new Button(sdCardGroup, SWT.PUSH); - mBrowseSdCard.setText("Browse..."); - mBrowseSdCard.setToolTipText("Select the file to use for the SD Card"); - mBrowseSdCard.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onBrowseSdCard(); - validatePage(); - } - }); - - mSdCardSizeRadio.setSelection(true); - enableSdCardWidgets(true); - - // --- avd options group - label = new Label(parent, SWT.NONE); - label.setText("Emulation Options:"); - Group optionsGroup = new Group(parent, SWT.NONE); - optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - optionsGroup.setLayout(new GridLayout(2, true)); - mSnapshot = new Button(optionsGroup, SWT.CHECK); - mSnapshot.setText("Snapshot"); - mSnapshot.setToolTipText("Emulator's state will be persisted between emulator executions"); - mSnapshot.addSelectionListener(validateListener); - mGpuEmulation = new Button(optionsGroup, SWT.CHECK); - mGpuEmulation.setText("GPU Emulation"); - mGpuEmulation.setToolTipText("Enable hardware OpenGLES emulation"); - mGpuEmulation.addSelectionListener(validateListener); - - // --- force creation group - mForceCreation = new Button(parent, SWT.CHECK); - mForceCreation.setText("Override the existing AVD with the same name"); - mForceCreation - .setToolTipText("There's already an AVD with the same name. Check this to delete it and replace it by the new AVD."); - mForceCreation.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, - true, false, 2, 1)); - mForceCreation.setEnabled(false); - mForceCreation.addSelectionListener(validateListener); - - // add a separator to separate from the ok/cancel button - label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); - - // add stuff for the error display - mStatusComposite = new Composite(parent, SWT.NONE); - mStatusComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - true, false, 3, 1)); - GridLayout gl; - mStatusComposite.setLayout(gl = new GridLayout(2, false)); - gl.marginHeight = gl.marginWidth = 0; - - mStatusIcon = new Label(mStatusComposite, SWT.NONE); - mStatusIcon.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - mStatusLabel = new Label(mStatusComposite, SWT.NONE); - mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mStatusLabel.setText(""); //$NON-NLS-1$ - - } - - /** - * {@link ModifyListener} used for live-validation of the fields content. - */ - private class ValidateListener extends SelectionAdapter implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - validatePage(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - validatePage(); - } - } - - /** - * Callback when the AVD name is changed. When creating a new AVD, enables - * the force checkbox if the name is a duplicate. When editing an existing - * AVD, it's OK for the name to match the existing AVD. - */ - private class CreateNameModifyListener implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - String name = mAvdName.getText().trim(); - if (mAvdInfo == null || !name.equals(mAvdInfo.getName())) { - // Case where we're creating a new AVD or editing an existing - // one - // and the AVD name has been changed... check for name - // uniqueness. - - Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(name); - if (conflict.getFirst() != AvdManager.AvdConflict.NO_CONFLICT) { - // If we're changing the state from disabled to enabled, - // make sure - // to uncheck the button, to force the user to voluntarily - // re-enforce it. - // This happens when editing an existing AVD and changing - // the name from - // the existing AVD to another different existing AVD. - if (!mForceCreation.isEnabled()) { - mForceCreation.setEnabled(true); - mForceCreation.setSelection(false); - } - } else { - mForceCreation.setEnabled(false); - mForceCreation.setSelection(false); - } - } else { - // Case where we're editing an existing AVD with the name - // unchanged. - - mForceCreation.setEnabled(false); - mForceCreation.setSelection(false); - } - validatePage(); - } - } - - private class DeviceSelectionListener extends SelectionAdapter { - - @Override - public void widgetSelected(SelectionEvent arg0) { - Device currentDevice = null; - for (Device d : mDeviceMap.get(mDeviceManufacturer.getText())) { - if (d.getName().equals(mDeviceName.getText())) { - currentDevice = d; - break; - } - } - - if (currentDevice != null) { - Hardware hw = currentDevice.getDefaultHardware(); - Long ram = hw.getRam().getSizeAsUnit(Storage.Unit.MiB); - mRam.setText(Long.toString(ram)); - - // Set the default VM heap size. This is based on the Android CDD minimums for each - // screen size and density. - Screen s = hw.getScreen(); - ScreenSize size = s.getSize(); - Density density = s.getPixelDensity(); - int vmHeapSize = 32; - if (size.equals(ScreenSize.XLARGE)) { - switch (density) { - case LOW: - case MEDIUM: - vmHeapSize = 32; - break; - case TV: - case HIGH: - vmHeapSize = 64; - break; - case XHIGH: - case XXHIGH: - vmHeapSize = 128; - } - } else { - switch (density) { - case LOW: - case MEDIUM: - vmHeapSize = 16; - break; - case TV: - case HIGH: - vmHeapSize = 32; - break; - case XHIGH: - case XXHIGH: - vmHeapSize = 64; - - } - } - mVmHeap.setText(Integer.toString(vmHeapSize)); - } - - toggleCameras(); - validatePage(); - } - - } - - private void toggleCameras() { - mFrontCamera.setEnabled(false); - mBackCamera.setEnabled(false); - if (mDeviceName.getSelectionIndex() >= 0) { - List<Device> devices = mDeviceMap.get(mDeviceManufacturer.getText()); - for (Device d : devices) { - if (mDeviceName.getText().equals(d.getName())) { - for (Camera c : d.getDefaultHardware().getCameras()) { - if (CameraLocation.FRONT.equals(c.getLocation())) { - mFrontCamera.setEnabled(true); - } - if (CameraLocation.BACK.equals(c.getLocation())) { - mBackCamera.setEnabled(true); - } - } - } - } - - } - } - - private void reloadDeviceNameCombo() { - mDeviceName.removeAll(); - if (mDeviceMap.containsKey(mDeviceManufacturer.getText())) { - for (final Device d : mDeviceMap.get(mDeviceManufacturer.getText())) { - mDeviceName.add(d.getName()); - } - } - - } - - private void reloadTargetCombo() { - String selected = null; - int index = mTarget.getSelectionIndex(); - if (index >= 0) { - selected = mTarget.getItem(index); - } - - mCurrentTargets.clear(); - mTarget.removeAll(); - - boolean found = false; - index = -1; - - SdkManager sdkManager = mAvdManager.getSdkManager(); - if (sdkManager != null) { - for (IAndroidTarget target : sdkManager.getTargets()) { - String name; - if (target.isPlatform()) { - name = String.format("%s - API Level %s", - target.getName(), - target.getVersion().getApiString()); - } else { - name = String.format("%s (%s) - API Level %s", - target.getName(), - target.getVendor(), - target.getVersion().getApiString()); - } - mCurrentTargets.put(name, target); - mTarget.add(name); - if (!found) { - index++; - found = name.equals(selected); - } - } - } - - mTarget.setEnabled(mCurrentTargets.size() > 0); - - if (found) { - mTarget.select(index); - } - } - - /** - * Reload all the abi types in the selection list - */ - private void reloadAbiTypeCombo() { - String selected = null; - boolean found = false; - - int index = mTarget.getSelectionIndex(); - if (index >= 0) { - String targetName = mTarget.getItem(index); - IAndroidTarget target = mCurrentTargets.get(targetName); - - ISystemImage[] systemImages = getSystemImages(target); - - mAbi.setEnabled(systemImages.length > 1); - - // If user explicitly selected an ABI before, preserve that option - // If user did not explicitly select before (only one option before) - // force them to select - index = mAbi.getSelectionIndex(); - if (index >= 0 && mAbi.getItemCount() > 1) { - selected = mAbi.getItem(index); - } - - mAbi.removeAll(); - - int i; - for (i = 0; i < systemImages.length; i++) { - String prettyAbiType = AvdInfo.getPrettyAbiType(systemImages[i].getAbiType()); - mAbi.add(prettyAbiType); - if (!found) { - found = prettyAbiType.equals(selected); - if (found) { - mAbi.select(i); - } - } - } - - if (systemImages.length == 1) { - mAbi.select(0); - } - } - } - - /** - * Enable or disable the sd card widgets. - * - * @param sizeMode if true the size-based widgets are to be enabled, and the - * file-based ones disabled. - */ - private void enableSdCardWidgets(boolean sizeMode) { - mSdCardSize.setEnabled(sizeMode); - mSdCardSizeCombo.setEnabled(sizeMode); - - mSdCardFile.setEnabled(!sizeMode); - mBrowseSdCard.setEnabled(!sizeMode); - } - - private void onBrowseSdCard() { - FileDialog dlg = new FileDialog(getContents().getShell(), SWT.OPEN); - dlg.setText("Choose SD Card image file."); - - String fileName = dlg.open(); - if (fileName != null) { - mSdCardFile.setText(fileName); - } - } - - @Override - public void okPressed() { - if (createAvd()) { - super.okPressed(); - } - } - - private void validatePage() { - String error = null; - String warning = null; - boolean valid = true; - if (mAvdName.getText().isEmpty()) { - valid = false; - } - - if (mDeviceManufacturer.getSelectionIndex() < 0 || mDeviceName.getSelectionIndex() < 0) { - valid = false; - } - - if (mTarget.getSelectionIndex() < 0 || mAbi.getSelectionIndex() < 0) { - valid = false; - } - - if (mRam.getText().isEmpty()) { - valid = false; - } - - if (mVmHeap.getText().isEmpty()) { - valid = false; - } - - if (mDataPartition.getText().isEmpty() || mDataPartitionSize.getSelectionIndex() < 0) { - valid = false; - error = "Data partition must be a valid file size."; - } - - // validate sdcard size or file - if (mSdCardSizeRadio.getSelection()) { - if (!mSdCardSize.getText().isEmpty() && mSdCardSizeCombo.getSelectionIndex() >= 0) { - try { - long sdSize = Long.parseLong(mSdCardSize.getText()); - - int sizeIndex = mSdCardSizeCombo.getSelectionIndex(); - if (sizeIndex >= 0) { - // index 0 shifts by 10 (1024=K), index 1 by 20, etc. - sdSize <<= 10 * (1 + sizeIndex); - } - - if (sdSize < AvdManager.SDCARD_MIN_BYTE_SIZE || - sdSize > AvdManager.SDCARD_MAX_BYTE_SIZE) { - valid = false; - error = "SD Card size is invalid. Range is 9 MiB..1023 GiB."; - } - } catch (NumberFormatException e) { - valid = false; - error = " SD Card size must be a valid integer between 9 MiB and 1023 GiB"; - } - } - } else { - if (mSdCardFile.getText().isEmpty() || !new File(mSdCardFile.getText()).isFile()) { - valid = false; - error = "SD Card path isn't valid."; - } - } - - if (mForceCreation.isEnabled() && !mForceCreation.getSelection()) { - valid = false; - error = String.format( - "The AVD name '%s' is already used.\n" + - "Check \"Override the existing AVD\" to delete the existing one.", - mAvdName.getText()); - } - - if (mAvdInfo != null && !mAvdInfo.getName().equals(mAvdName.getText())) { - warning = String.format("The AVD '%1$s' will be duplicated into '%2$s'.", - mAvdInfo.getName(), - mAvdName.getText()); - } - - if (mGpuEmulation.getSelection() && mSnapshot.getSelection()) { - valid = false; - error = "GPU Emulation and Snapshot cannot be used simultaneously"; - } - - mOkButton.setEnabled(valid); - if (error != null) { - mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png")); //$NON-NLS-1$ - mStatusLabel.setText(error); - } else if (warning != null) { - mStatusIcon.setImage(mImageFactory.getImageByName("warning_icon16.png")); //$NON-NLS-1$ - mStatusLabel.setText(warning); - } else { - mStatusIcon.setImage(null); - mStatusLabel.setText(" \n "); //$NON-NLS-1$ - } - - mStatusComposite.pack(true); - } - - private boolean createAvd() { - - String avdName = mAvdName.getText(); - if (avdName == null || avdName.isEmpty()) { - return false; - } - - String targetName = mTarget.getItem(mTarget.getSelectionIndex()); - IAndroidTarget target = mCurrentTargets.get(targetName); - if (target == null) { - return false; - } - - // get the abi type - String abiType = SdkConstants.ABI_ARMEABI; - ISystemImage[] systemImages = getSystemImages(target); - if (systemImages.length > 0) { - int abiIndex = mAbi.getSelectionIndex(); - if (abiIndex >= 0) { - String prettyname = mAbi.getItem(abiIndex); - // Extract the abi type - int firstIndex = prettyname.indexOf("("); - int lastIndex = prettyname.indexOf(")"); - abiType = prettyname.substring(firstIndex + 1, lastIndex); - } - } - - // get the SD card data from the UI. - String sdName = null; - if (mSdCardSizeRadio.getSelection()) { - // size mode - String value = mSdCardSize.getText().trim(); - if (value.length() > 0) { - sdName = value; - // add the unit - switch (mSdCardSizeCombo.getSelectionIndex()) { - case 0: - sdName += "K"; //$NON-NLS-1$ - break; - case 1: - sdName += "M"; //$NON-NLS-1$ - break; - case 2: - sdName += "G"; //$NON-NLS-1$ - break; - default: - // shouldn't be here - assert false; - } - } - } else { - // file mode. - sdName = mSdCardFile.getText().trim(); - } - - // Get the device - List<Device> devices = mDeviceMap.get(mDeviceManufacturer.getText()); - if (devices == null) { - return false; - } - - Device device = null; - for (Device d : devices) { - if (mDeviceName.getText().equals(d.getName())) { - device = d; - break; - } - } - - if (device == null) { - return false; - } - - Screen s = device.getDefaultHardware().getScreen(); - String skinName = s.getXDimension() + "x" + s.getYDimension(); - - ILogger log = mSdkLog; - if (log == null || log instanceof MessageBoxLog) { - // If the current logger is a message box, we use our own (to make sure - // to display errors right away and customize the title). - log = new MessageBoxLog( - String.format("Result of creating AVD '%s':", avdName), - getContents().getDisplay(), - false /* logErrorsOnly */); - } - - Map<String, String> hwProps = DeviceManager.getHardwareProperties(device); - if (mGpuEmulation.getSelection()) { - hwProps.put(AvdManager.AVD_INI_GPU_EMULATION, HardwareProperties.BOOLEAN_YES); - } - - File avdFolder = null; - try { - avdFolder = AvdInfo.getDefaultAvdFolder(mAvdManager, avdName); - } catch (AndroidLocationException e) { - return false; - } - - // Although the device has this information, some devices have more RAM than we'd want to - // allocate to an emulator. - hwProps.put(AvdManager.AVD_INI_RAM_SIZE, mRam.getText()); - hwProps.put(AvdManager.AVD_INI_VM_HEAP_SIZE, mVmHeap.getText()); - - String suffix; - switch (mDataPartitionSize.getSelectionIndex()) { - case 0: - suffix = "M"; - break; - case 1: - suffix = "G"; - break; - default: - suffix = "K"; - } - hwProps.put(AvdManager.AVD_INI_DATA_PARTITION_SIZE, mDataPartition.getText()+suffix); - - if (mFrontCamera.isEnabled()) { - hwProps.put(AvdManager.AVD_INI_CAMERA_FRONT, - mFrontCamera.getText().toLowerCase()); - } - - if (mBackCamera.isEnabled()) { - hwProps.put(AvdManager.AVD_INI_CAMERA_BACK, - mBackCamera.getText().toLowerCase()); - } - - if (sdName != null) { - hwProps.put(HardwareProperties.HW_SDCARD, HardwareProperties.BOOLEAN_YES); - } - - AvdInfo avdInfo = mAvdManager.createAvd(avdFolder, - avdName, - target, - abiType, - skinName, - sdName, - hwProps, - mSnapshot.getSelection(), - mForceCreation.getSelection(), - mAvdInfo != null, // edit existing - log); - - boolean success = avdInfo != null; - - if (log instanceof MessageBoxLog) { - ((MessageBoxLog) log).displayResult(success); - } - return success; - } - - private void fillExistingAvdInfo(AvdInfo avd) { - mAvdName.setText(avd.getName()); - String manufacturer = avd.getDeviceManufacturer(); - for (int i = 0; i < mDeviceManufacturer.getItemCount(); i++) { - if (mDeviceManufacturer.getItem(i).equals(manufacturer)) { - mDeviceManufacturer.select(i); - break; - } - } - reloadDeviceNameCombo(); - - String deviceName = avd.getDeviceName(); - for (int i = 0; i < mDeviceName.getItemCount(); i++) { - if (mDeviceName.getItem(i).equals(deviceName)) { - mDeviceName.select(i); - break; - } - } - toggleCameras(); - - IAndroidTarget target = avd.getTarget(); - - if (target != null && !mCurrentTargets.isEmpty()) { - // Try to select the target in the target combo. - // This will fail if the AVD needs to be repaired. - // - // This is a linear search but the list is always - // small enough and we only do this once. - int n = mTarget.getItemCount(); - for (int i = 0; i < n; i++) { - if (target.equals(mCurrentTargets.get(mTarget.getItem(i)))) { - mTarget.select(i); - reloadAbiTypeCombo(); - break; - } - } - } - - ISystemImage[] systemImages = getSystemImages(target); - if (target != null && systemImages.length > 0) { - mAbi.setEnabled(systemImages.length > 1); - String abiType = AvdInfo.getPrettyAbiType(avd.getAbiType()); - int n = mAbi.getItemCount(); - for (int i = 0; i < n; i++) { - if (abiType.equals(mAbi.getItem(i))) { - mAbi.select(i); - break; - } - } - } - - Map<String, String> props = avd.getProperties(); - - if (props != null) { - String snapshots = props.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); - if (snapshots != null && snapshots.length() > 0) { - mSnapshot.setSelection(snapshots.equals("true")); - } - - String gpuEmulation = props.get(AvdManager.AVD_INI_GPU_EMULATION); - mGpuEmulation.setSelection(gpuEmulation != null && - gpuEmulation.equals(HardwareProperties.BOOLEAN_VALUES[0])); - - String sdcard = props.get(AvdManager.AVD_INI_SDCARD_PATH); - if (sdcard != null && sdcard.length() > 0) { - enableSdCardWidgets(false); - mSdCardSizeRadio.setSelection(false); - mSdCardFileRadio.setSelection(true); - mSdCardFile.setText(sdcard); - } - - String ramSize = props.get(AvdManager.AVD_INI_RAM_SIZE); - if (ramSize != null) { - mRam.setText(ramSize); - } - - String vmHeapSize = props.get(AvdManager.AVD_INI_VM_HEAP_SIZE); - if (vmHeapSize != null) { - mVmHeap.setText(vmHeapSize); - } - - String dataPartitionSize = props.get(AvdManager.AVD_INI_DATA_PARTITION_SIZE); - if (dataPartitionSize != null) { - mDataPartition.setText( - dataPartitionSize.substring(0, dataPartitionSize.length() - 1)); - switch (dataPartitionSize.charAt(dataPartitionSize.length() - 1)) { - case 'M': - mDataPartitionSize.select(0); - break; - case 'G': - mDataPartitionSize.select(1); - break; - default: - mDataPartitionSize.select(-1); - } - } - - String cameraFront = props.get(AvdManager.AVD_INI_CAMERA_FRONT); - if (cameraFront != null) { - String[] items = mFrontCamera.getItems(); - for (int i = 0; i < items.length; i++) { - if (items[i].toLowerCase().equals(cameraFront)) { - mFrontCamera.select(i); - break; - } - } - } - - String cameraBack = props.get(AvdManager.AVD_INI_CAMERA_BACK); - if (cameraBack != null) { - String[] items = mBackCamera.getItems(); - for (int i = 0; i < items.length; i++) { - if (items[i].toLowerCase().equals(cameraBack)) { - mBackCamera.select(i); - break; - } - } - } - - sdcard = props.get(AvdManager.AVD_INI_SDCARD_SIZE); - if (sdcard != null && sdcard.length() > 0) { - String[] values = new String[2]; - long sdcardSize = AvdManager.parseSdcardSize(sdcard, values); - - if (sdcardSize != AvdManager.SDCARD_NOT_SIZE_PATTERN) { - enableSdCardWidgets(true); - mSdCardFileRadio.setSelection(false); - mSdCardSizeRadio.setSelection(true); - - mSdCardSize.setText(values[0]); - - String suffix = values[1]; - int n = mSdCardSizeCombo.getItemCount(); - for (int i = 0; i < n; i++) { - if (mSdCardSizeCombo.getItem(i).startsWith(suffix)) { - mSdCardSizeCombo.select(i); - } - } - } - } - } - } - - /** - * Returns the list of system images of a target. - * <p/> - * If target is null, returns an empty list. If target is an add-on with no - * system images, return the list from its parent platform. - * - * @param target An IAndroidTarget. Can be null. - * @return A non-null ISystemImage array. Can be empty. - */ - private ISystemImage[] getSystemImages(IAndroidTarget target) { - if (target != null) { - ISystemImage[] images = target.getSystemImages(); - - if ((images == null || images.length == 0) && !target.isPlatform()) { - // If an add-on does not provide any system images, use the ones - // from the parent. - images = target.getParent().getSystemImages(); - } - - if (images != null) { - return images; - } - } - - return new ISystemImage[0]; - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java deleted file mode 100644 index ce40360..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdDetailsDialog.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.sdklib.AndroidVersion; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.internal.avd.AvdInfo; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.avd.AvdInfo.AvdStatus; -import com.android.sdkuilib.ui.GridDataBuilder; -import com.android.sdkuilib.ui.GridLayoutBuilder; -import com.android.sdkuilib.ui.SwtBaseDialog; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -import java.util.HashMap; -import java.util.Map; - -/** - * Dialog displaying the details of an AVD. - */ -final class AvdDetailsDialog extends SwtBaseDialog { - - private final AvdInfo mAvdInfo; - - public AvdDetailsDialog(Shell shell, AvdInfo avdInfo) { - super(shell, SWT.APPLICATION_MODAL, "AVD details"); - mAvdInfo = avdInfo; - } - - /** - * Create contents of the dialog. - */ - @Override - protected void createContents() { - Shell shell = getShell(); - GridLayoutBuilder.create(shell).columns(2); - GridDataBuilder.create(shell).fill(); - - GridLayout gl; - - Composite c = new Composite(shell, SWT.NONE); - c.setLayout(gl = new GridLayout(2, false)); - gl.marginHeight = gl.marginWidth = 0; - c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - if (mAvdInfo != null) { - displayValue(c, "Name:", mAvdInfo.getName()); - displayValue(c, "CPU/ABI:", AvdInfo.getPrettyAbiType(mAvdInfo.getAbiType())); - - displayValue(c, "Path:", mAvdInfo.getDataFolderPath()); - - if (mAvdInfo.getStatus() != AvdStatus.OK) { - displayValue(c, "Error:", mAvdInfo.getErrorMessage()); - } else { - IAndroidTarget target = mAvdInfo.getTarget(); - AndroidVersion version = target.getVersion(); - displayValue(c, "Target:", String.format("%s (API level %s)", - target.getName(), version.getApiString())); - - // display some extra values. - Map<String, String> properties = mAvdInfo.getProperties(); - if (properties != null) { - String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME); - if (skin != null) { - displayValue(c, "Skin:", skin); - } - - String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE); - if (sdcard == null) { - sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH); - } - if (sdcard != null) { - displayValue(c, "SD Card:", sdcard); - } - - String snapshot = properties.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); - if (snapshot != null) { - displayValue(c, "Snapshot:", snapshot); - } - - // display other hardware - HashMap<String, String> copy = new HashMap<String, String>(properties); - // remove stuff we already displayed (or that we don't want to display) - copy.remove(AvdManager.AVD_INI_ABI_TYPE); - copy.remove(AvdManager.AVD_INI_CPU_ARCH); - copy.remove(AvdManager.AVD_INI_SKIN_NAME); - copy.remove(AvdManager.AVD_INI_SKIN_PATH); - copy.remove(AvdManager.AVD_INI_SDCARD_SIZE); - copy.remove(AvdManager.AVD_INI_SDCARD_PATH); - copy.remove(AvdManager.AVD_INI_IMAGES_1); - copy.remove(AvdManager.AVD_INI_IMAGES_2); - - if (copy.size() > 0) { - Label l = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL); - l.setLayoutData(new GridData( - GridData.FILL, GridData.CENTER, false, false, 2, 1)); - - c = new Composite(shell, SWT.NONE); - c.setLayout(gl = new GridLayout(2, false)); - gl.marginHeight = gl.marginWidth = 0; - c.setLayoutData(new GridData(GridData.FILL_BOTH)); - - for (Map.Entry<String, String> entry : copy.entrySet()) { - displayValue(c, entry.getKey() + ":", entry.getValue()); - } - } - } - } - } - } - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - - @Override - protected void postCreate() { - // pass - } - - /** - * Displays a value with a label. - * - * @param parent the parent Composite in which to display the value. This Composite must use a - * {@link GridLayout} with 2 columns. - * @param label the label of the value to display. - * @param value the string value to display. - */ - private void displayValue(Composite parent, String label, String value) { - Label l = new Label(parent, SWT.NONE); - l.setText(label); - l.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); - - l = new Label(parent, SWT.NONE); - l.setText(value); - l.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false)); - } - - // End of hiding from SWT Designer - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java deleted file mode 100644 index ab8e1c9..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdSelector.java +++ /dev/null @@ -1,1240 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.SdkConstants; -import com.android.annotations.Nullable; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.devices.Device; -import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.internal.avd.AvdInfo; -import com.android.sdklib.internal.avd.AvdInfo.AvdStatus; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.util.GrabProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.IProcessOutput; -import com.android.sdklib.util.GrabProcessOutput.Wait; -import com.android.sdkuilib.internal.repository.SettingsController; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.internal.repository.ui.AvdManagerWindowImpl1; -import com.android.sdkuilib.internal.tasks.ProgressTask; -import com.android.sdkuilib.repository.AvdManagerWindow.AvdInvocationContext; -import com.android.sdkuilib.ui.GridDialog; -import com.android.utils.ILogger; -import com.android.utils.NullLogger; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; -import java.util.Formatter; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - - -/** - * The AVD selector is a table that is added to the given parent composite. - * <p/> - * After using one of the constructors, call {@link #setSelection(AvdInfo)}, - * {@link #setSelectionListener(SelectionListener)} and finally use - * {@link #getSelected()} to retrieve the selection. - */ -public final class AvdSelector { - private static int NUM_COL = 2; - - private final DisplayMode mDisplayMode; - - private AvdManager mAvdManager; - private final String mOsSdkPath; - - private Table mTable; - private Button mDeleteButton; - private Button mDetailsButton; - private Button mNewButton; - private Button mEditButton; - private Button mRefreshButton; - private Button mManagerButton; - private Button mRepairButton; - private Button mStartButton; - - private SelectionListener mSelectionListener; - private IAvdFilter mTargetFilter; - - /** Defaults to true. Changed by the {@link #setEnabled(boolean)} method to represent the - * "global" enabled state on this composite. */ - private boolean mIsEnabled = true; - - private ImageFactory mImageFactory; - private Image mOkImage; - private Image mBrokenImage; - private Image mInvalidImage; - - private SettingsController mController; - - private final ILogger mSdkLog; - - - /** - * The display mode of the AVD Selector. - */ - public static enum DisplayMode { - /** - * Manager mode. Invalid AVDs are displayed. Buttons to create/delete AVDs - */ - MANAGER, - - /** - * Non manager mode. Only valid AVDs are displayed. Cannot create/delete AVDs, but - * there is a button to open the AVD Manager. - * In the "check" selection mode, checkboxes are displayed on each line - * and {@link AvdSelector#getSelected()} returns the line that is checked - * even if it is not the currently selected line. Only one line can - * be checked at once. - */ - SIMPLE_CHECK, - - /** - * Non manager mode. Only valid AVDs are displayed. Cannot create/delete AVDs, but - * there is a button to open the AVD Manager. - * In the "select" selection mode, there are no checkboxes and - * {@link AvdSelector#getSelected()} returns the line currently selected. - * Only one line can be selected at once. - */ - SIMPLE_SELECTION, - } - - /** - * A filter to control the whether or not an AVD should be displayed by the AVD Selector. - */ - public interface IAvdFilter { - /** - * Called before {@link #accept(AvdInfo)} is called for any AVD. - */ - void prepare(); - - /** - * Called to decided whether an AVD should be displayed. - * @param avd the AVD to test. - * @return true if the AVD should be displayed. - */ - boolean accept(AvdInfo avd); - - /** - * Called after {@link #accept(AvdInfo)} has been called on all the AVDs. - */ - void cleanup(); - } - - /** - * Internal implementation of {@link IAvdFilter} to filter out the AVDs that are not - * running an image compatible with a specific target. - */ - private final static class TargetBasedFilter implements IAvdFilter { - private final IAndroidTarget mTarget; - - TargetBasedFilter(IAndroidTarget target) { - mTarget = target; - } - - @Override - public void prepare() { - // nothing to prepare - } - - @Override - public boolean accept(AvdInfo avd) { - if (avd != null) { - return mTarget.canRunOn(avd.getTarget()); - } - - return false; - } - - @Override - public void cleanup() { - // nothing to clean up - } - } - - /** - * Creates a new SDK Target Selector, and fills it with a list of {@link AvdInfo}, filtered - * by a {@link IAndroidTarget}. - * <p/>Only the {@link AvdInfo} able to run application developed for the given - * {@link IAndroidTarget} will be displayed. - * - * @param parent The parent composite where the selector will be added. - * @param osSdkPath The SDK root path. When not null, enables the start button to start - * an emulator on a given AVD. - * @param manager the AVD manager. - * @param filter When non-null, will allow filtering the AVDs to display. - * @param displayMode The display mode ({@link DisplayMode}). - * @param sdkLog The logger. Cannot be null. - */ - public AvdSelector(Composite parent, - String osSdkPath, - AvdManager manager, - IAvdFilter filter, - DisplayMode displayMode, - ILogger sdkLog) { - mOsSdkPath = osSdkPath; - mAvdManager = manager; - mTargetFilter = filter; - mDisplayMode = displayMode; - mSdkLog = sdkLog; - - // get some bitmaps. - mImageFactory = new ImageFactory(parent.getDisplay()); - mOkImage = mImageFactory.getImageByName("accept_icon16.png"); - mBrokenImage = mImageFactory.getImageByName("broken_16.png"); - mInvalidImage = mImageFactory.getImageByName("reject_icon16.png"); - - // Layout has 2 columns - Composite group = new Composite(parent, SWT.NONE); - GridLayout gl; - group.setLayout(gl = new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/)); - gl.marginHeight = gl.marginWidth = 0; - group.setLayoutData(new GridData(GridData.FILL_BOTH)); - group.setFont(parent.getFont()); - group.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent arg0) { - mImageFactory.dispose(); - } - }); - - int style = SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER; - if (displayMode == DisplayMode.SIMPLE_CHECK) { - style |= SWT.CHECK; - } - mTable = new Table(group, style); - mTable.setHeaderVisible(true); - mTable.setLinesVisible(false); - setTableHeightHint(0); - - Composite buttons = new Composite(group, SWT.NONE); - buttons.setLayout(gl = new GridLayout(1, false /*makeColumnsEqualWidth*/)); - gl.marginHeight = gl.marginWidth = 0; - buttons.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - buttons.setFont(group.getFont()); - - if (displayMode == DisplayMode.MANAGER) { - mNewButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mNewButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mNewButton.setText("New..."); - mNewButton.setToolTipText("Creates a new AVD."); - mNewButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onNew(); - } - }); - - mEditButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mEditButton.setText("Edit..."); - mEditButton.setToolTipText("Edit an existing AVD."); - mEditButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onEdit(); - } - }); - - mDeleteButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDeleteButton.setText("Delete..."); - mDeleteButton.setToolTipText("Deletes the selected AVD."); - mDeleteButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onDelete(); - } - }); - - mRepairButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mRepairButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mRepairButton.setText("Repair..."); - mRepairButton.setToolTipText("Repairs the selected AVD."); - mRepairButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onRepair(); - } - }); - - Label l = new Label(buttons, SWT.SEPARATOR | SWT.HORIZONTAL); - l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - } - - mDetailsButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mDetailsButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDetailsButton.setText("Details..."); - mDetailsButton.setToolTipText("Displays details of the selected AVD."); - mDetailsButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onDetails(); - } - }); - - mStartButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mStartButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mStartButton.setText("Start..."); - mStartButton.setToolTipText("Starts the selected AVD."); - mStartButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onStart(); - } - }); - - Composite padding = new Composite(buttons, SWT.NONE); - padding.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - - mRefreshButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mRefreshButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mRefreshButton.setText("Refresh"); - mRefreshButton.setToolTipText("Reloads the list of AVD.\nUse this if you create AVDs from the command line."); - mRefreshButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - refresh(true); - } - }); - - if (displayMode != DisplayMode.MANAGER) { - mManagerButton = new Button(buttons, SWT.PUSH | SWT.FLAT); - mManagerButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mManagerButton.setText("Manager..."); - mManagerButton.setToolTipText("Launches the AVD manager."); - mManagerButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onAvdManager(); - } - }); - } else { - Composite legend = new Composite(group, SWT.NONE); - legend.setLayout(gl = new GridLayout(4, false /*makeColumnsEqualWidth*/)); - gl.marginHeight = gl.marginWidth = 0; - legend.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false, - NUM_COL, 1)); - legend.setFont(group.getFont()); - - new Label(legend, SWT.NONE).setImage(mOkImage); - new Label(legend, SWT.NONE).setText("A valid Android Virtual Device."); - new Label(legend, SWT.NONE).setImage(mBrokenImage); - new Label(legend, SWT.NONE).setText( - "A repairable Android Virtual Device."); - new Label(legend, SWT.NONE).setImage(mInvalidImage); - Label l = new Label(legend, SWT.NONE); - l.setText("An Android Virtual Device that failed to load. Click 'Details' to see the error."); - GridData gd; - l.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 3; - } - - // create the table columns - final TableColumn column0 = new TableColumn(mTable, SWT.NONE); - column0.setText("AVD Name"); - final TableColumn column1 = new TableColumn(mTable, SWT.NONE); - column1.setText("Target Name"); - final TableColumn column2 = new TableColumn(mTable, SWT.NONE); - column2.setText("Platform"); - final TableColumn column3 = new TableColumn(mTable, SWT.NONE); - column3.setText("API Level"); - final TableColumn column4 = new TableColumn(mTable, SWT.NONE); - column4.setText("CPU/ABI"); - - adjustColumnsWidth(mTable, column0, column1, column2, column3, column4); - setupSelectionListener(mTable); - fillTable(mTable); - setEnabled(true); - } - - /** - * Creates a new SDK Target Selector, and fills it with a list of {@link AvdInfo}. - * - * @param parent The parent composite where the selector will be added. - * @param manager the AVD manager. - * @param displayMode The display mode ({@link DisplayMode}). - * @param sdkLog The logger. Cannot be null. - */ - public AvdSelector(Composite parent, - String osSdkPath, - AvdManager manager, - DisplayMode displayMode, - ILogger sdkLog) { - this(parent, osSdkPath, manager, (IAvdFilter)null /* filter */, displayMode, sdkLog); - } - - /** - * Creates a new SDK Target Selector, and fills it with a list of {@link AvdInfo}, filtered - * by an {@link IAndroidTarget}. - * <p/>Only the {@link AvdInfo} able to run applications developed for the given - * {@link IAndroidTarget} will be displayed. - * - * @param parent The parent composite where the selector will be added. - * @param manager the AVD manager. - * @param filter Only shows the AVDs matching this target (must not be null). - * @param displayMode The display mode ({@link DisplayMode}). - * @param sdkLog The logger. Cannot be null. - */ - public AvdSelector(Composite parent, - String osSdkPath, - AvdManager manager, - IAndroidTarget filter, - DisplayMode displayMode, - ILogger sdkLog) { - this(parent, osSdkPath, manager, new TargetBasedFilter(filter), displayMode, sdkLog); - } - - /** - * Sets an optional SettingsController. - * @param controller the controller. - */ - public void setSettingsController(SettingsController controller) { - mController = controller; - } - /** - * Sets the table grid layout data. - * - * @param heightHint If > 0, the height hint is set to the requested value. - */ - public void setTableHeightHint(int heightHint) { - GridData data = new GridData(); - if (heightHint > 0) { - data.heightHint = heightHint; - } - data.grabExcessVerticalSpace = true; - data.grabExcessHorizontalSpace = true; - data.horizontalAlignment = GridData.FILL; - data.verticalAlignment = GridData.FILL; - mTable.setLayoutData(data); - } - - /** - * Refresh the display of Android Virtual Devices. - * Tries to keep the selection. - * <p/> - * This must be called from the UI thread. - * - * @param reload if true, the AVD manager will reload the AVD from the disk. - * @return false if the reloading failed. This is always true if <var>reload</var> is - * <code>false</code>. - */ - public boolean refresh(boolean reload) { - if (reload) { - try { - mAvdManager.reloadAvds(NullLogger.getLogger()); - } catch (AndroidLocationException e) { - return false; - } - } - - AvdInfo selected = getSelected(); - - fillTable(mTable); - - setSelection(selected); - - return true; - } - - /** - * Sets a new AVD manager - * This does not refresh the display. Call {@link #refresh(boolean)} to do so. - * @param manager the AVD manager. - */ - public void setManager(AvdManager manager) { - mAvdManager = manager; - } - - /** - * Sets a new AVD filter. - * This does not refresh the display. Call {@link #refresh(boolean)} to do so. - * @param filter An IAvdFilter. If non-null, this will filter out the AVD to not display. - */ - public void setFilter(IAvdFilter filter) { - mTargetFilter = filter; - } - - /** - * Sets a new Android Target-based AVD filter. - * This does not refresh the display. Call {@link #refresh(boolean)} to do so. - * @param target An IAndroidTarget. If non-null, only AVD whose target are compatible with the - * filter target will displayed an available for selection. - */ - public void setFilter(IAndroidTarget target) { - if (target != null) { - mTargetFilter = new TargetBasedFilter(target); - } else { - mTargetFilter = null; - } - } - - /** - * Sets a selection listener. Set it to null to remove it. - * The listener will be called <em>after</em> this table processed its selection - * events so that the caller can see the updated state. - * <p/> - * The event's item contains a {@link TableItem}. - * The {@link TableItem#getData()} contains an {@link IAndroidTarget}. - * <p/> - * It is recommended that the caller uses the {@link #getSelected()} method instead. - * <p/> - * The default behavior for double click (when not in {@link DisplayMode#SIMPLE_CHECK}) is to - * display the details of the selected AVD.<br> - * To disable it (when you provide your own double click action), set - * {@link SelectionEvent#doit} to false in - * {@link SelectionListener#widgetDefaultSelected(SelectionEvent)} - * - * @param selectionListener The new listener or null to remove it. - */ - public void setSelectionListener(SelectionListener selectionListener) { - mSelectionListener = selectionListener; - } - - /** - * Sets the current target selection. - * <p/> - * If the selection is actually changed, this will invoke the selection listener - * (if any) with a null event. - * - * @param target the target to be selected. Use null to deselect everything. - * @return true if the target could be selected, false otherwise. - */ - public boolean setSelection(AvdInfo target) { - boolean found = false; - boolean modified = false; - - int selIndex = mTable.getSelectionIndex(); - int index = 0; - for (TableItem i : mTable.getItems()) { - if (mDisplayMode == DisplayMode.SIMPLE_CHECK) { - if ((AvdInfo) i.getData() == target) { - found = true; - if (!i.getChecked()) { - modified = true; - i.setChecked(true); - } - } else if (i.getChecked()) { - modified = true; - i.setChecked(false); - } - } else { - if ((AvdInfo) i.getData() == target) { - found = true; - if (index != selIndex) { - mTable.setSelection(index); - modified = true; - } - break; - } - - index++; - } - } - - if (modified && mSelectionListener != null) { - mSelectionListener.widgetSelected(null); - } - - enableActionButtons(); - - return found; - } - - /** - * Returns the currently selected item. In {@link DisplayMode#SIMPLE_CHECK} mode this will - * return the {@link AvdInfo} that is checked instead of the list selection. - * - * @return The currently selected item or null. - */ - public AvdInfo getSelected() { - if (mDisplayMode == DisplayMode.SIMPLE_CHECK) { - for (TableItem i : mTable.getItems()) { - if (i.getChecked()) { - return (AvdInfo) i.getData(); - } - } - } else { - int selIndex = mTable.getSelectionIndex(); - if (selIndex >= 0) { - return (AvdInfo) mTable.getItem(selIndex).getData(); - } - } - - return null; - } - - /** - * Enables the receiver if the argument is true, and disables it otherwise. - * A disabled control is typically not selectable from the user interface - * and draws with an inactive or "grayed" look. - * - * @param enabled the new enabled state. - */ - public void setEnabled(boolean enabled) { - // We can only enable widgets if the AVD Manager is defined. - mIsEnabled = enabled && mAvdManager != null; - - mTable.setEnabled(mIsEnabled); - mRefreshButton.setEnabled(mIsEnabled); - - if (mNewButton != null) { - mNewButton.setEnabled(mIsEnabled); - } - if (mManagerButton != null) { - mManagerButton.setEnabled(mIsEnabled); - } - - enableActionButtons(); - } - - public boolean isEnabled() { - return mIsEnabled; - } - - /** - * Adds a listener to adjust the columns width when the parent is resized. - * <p/> - * If we need something more fancy, we might want to use this: - * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co - */ - private void adjustColumnsWidth(final Table table, - final TableColumn column0, - final TableColumn column1, - final TableColumn column2, - final TableColumn column3, - final TableColumn column4) { - // Add a listener to resize the column to the full width of the table - table.addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent e) { - Rectangle r = table.getClientArea(); - column0.setWidth(r.width * 20 / 100); // 20% - column1.setWidth(r.width * 30 / 100); // 30% - column2.setWidth(r.width * 15 / 100); // 15% - column3.setWidth(r.width * 15 / 100); // 15% - column4.setWidth(r.width * 20 / 100); // 22% - } - }); - } - - /** - * Creates a selection listener that will check or uncheck the whole line when - * double-clicked (aka "the default selection"). - */ - private void setupSelectionListener(final Table table) { - // Add a selection listener that will check/uncheck items when they are double-clicked - table.addSelectionListener(new SelectionListener() { - - /** - * Handles single-click selection on the table. - * {@inheritDoc} - */ - @Override - public void widgetSelected(SelectionEvent e) { - if (e.item instanceof TableItem) { - TableItem i = (TableItem) e.item; - enforceSingleSelection(i); - } - - if (mSelectionListener != null) { - mSelectionListener.widgetSelected(e); - } - - enableActionButtons(); - } - - /** - * Handles double-click selection on the table. - * Note that the single-click handler will probably already have been called. - * - * On double-click, <em>always</em> check the table item. - * - * {@inheritDoc} - */ - @Override - public void widgetDefaultSelected(SelectionEvent e) { - if (e.item instanceof TableItem) { - TableItem i = (TableItem) e.item; - if (mDisplayMode == DisplayMode.SIMPLE_CHECK) { - i.setChecked(true); - } - enforceSingleSelection(i); - - } - - // whether or not we display details. default: true when not in SIMPLE_CHECK mode. - boolean showDetails = mDisplayMode != DisplayMode.SIMPLE_CHECK; - - if (mSelectionListener != null) { - mSelectionListener.widgetDefaultSelected(e); - showDetails &= e.doit; // enforce false in SIMPLE_CHECK - } - - if (showDetails) { - onDetails(); - } - - enableActionButtons(); - } - - /** - * To ensure single selection, uncheck all other items when this one is selected. - * This makes the chekboxes act as radio buttons. - */ - private void enforceSingleSelection(TableItem item) { - if (mDisplayMode == DisplayMode.SIMPLE_CHECK) { - if (item.getChecked()) { - Table parentTable = item.getParent(); - for (TableItem i2 : parentTable.getItems()) { - if (i2 != item && i2.getChecked()) { - i2.setChecked(false); - } - } - } - } else { - // pass - } - } - }); - } - - /** - * Fills the table with all AVD. - * The table columns are: - * <ul> - * <li>column 0: sdk name - * <li>column 1: sdk vendor - * <li>column 2: sdk api name - * <li>column 3: sdk version - * </ul> - */ - private void fillTable(final Table table) { - table.removeAll(); - - // get the AVDs - AvdInfo avds[] = null; - if (mAvdManager != null) { - if (mDisplayMode == DisplayMode.MANAGER) { - avds = mAvdManager.getAllAvds(); - } else { - avds = mAvdManager.getValidAvds(); - } - } - - if (avds != null && avds.length > 0) { - Arrays.sort(avds, new Comparator<AvdInfo>() { - @Override - public int compare(AvdInfo o1, AvdInfo o2) { - return o1.compareTo(o2); - } - }); - - table.setEnabled(true); - - if (mTargetFilter != null) { - mTargetFilter.prepare(); - } - - for (AvdInfo avd : avds) { - if (mTargetFilter == null || mTargetFilter.accept(avd)) { - TableItem item = new TableItem(table, SWT.NONE); - item.setData(avd); - item.setText(0, avd.getName()); - if (mDisplayMode == DisplayMode.MANAGER) { - AvdStatus status = avd.getStatus(); - item.setImage(0, status == AvdStatus.OK ? mOkImage : - isAvdRepairable(status) ? mBrokenImage : mInvalidImage); - } - IAndroidTarget target = avd.getTarget(); - if (target != null) { - item.setText(1, target.getFullName()); - item.setText(2, target.getVersionName()); - item.setText(3, target.getVersion().getApiString()); - item.setText(4, AvdInfo.getPrettyAbiType(avd.getAbiType())); - } else { - item.setText(1, "?"); - item.setText(2, "?"); - item.setText(3, "?"); - item.setText(4, "?"); - } - } - } - - if (mTargetFilter != null) { - mTargetFilter.cleanup(); - } - } - - if (table.getItemCount() == 0) { - table.setEnabled(false); - TableItem item = new TableItem(table, SWT.NONE); - item.setData(null); - item.setText(0, "--"); - item.setText(1, "No AVD available"); - item.setText(2, "--"); - item.setText(3, "--"); - } - } - - /** - * Returns the currently selected AVD in the table. - * <p/> - * Unlike {@link #getSelected()} this will always return the item being selected - * in the list, ignoring the check boxes state in {@link DisplayMode#SIMPLE_CHECK} mode. - */ - private AvdInfo getTableSelection() { - int selIndex = mTable.getSelectionIndex(); - if (selIndex >= 0) { - return (AvdInfo) mTable.getItem(selIndex).getData(); - } - - return null; - } - - /** - * Updates the enable state of the Details, Start, Delete and Update buttons. - */ - @SuppressWarnings("null") - private void enableActionButtons() { - if (mIsEnabled == false) { - mDetailsButton.setEnabled(false); - mStartButton.setEnabled(false); - - if (mEditButton != null) { - mEditButton.setEnabled(false); - } - if (mDeleteButton != null) { - mDeleteButton.setEnabled(false); - } - if (mRepairButton != null) { - mRepairButton.setEnabled(false); - } - } else { - AvdInfo selection = getTableSelection(); - boolean hasSelection = selection != null; - - mDetailsButton.setEnabled(hasSelection); - mStartButton.setEnabled(mOsSdkPath != null && - hasSelection && - selection.getStatus() == AvdStatus.OK); - - if (mEditButton != null) { - mEditButton.setEnabled(hasSelection); - } - if (mDeleteButton != null) { - mDeleteButton.setEnabled(hasSelection); - } - if (mRepairButton != null) { - mRepairButton.setEnabled(hasSelection && isAvdRepairable(selection.getStatus())); - } - } - } - - private void onNew() { - AvdCreationDialog dlg = new AvdCreationDialog(mTable.getShell(), - mAvdManager, - mImageFactory, - mSdkLog, - null); - - if (dlg.open() == Window.OK) { - refresh(false /*reload*/); - } - } - - private void onEdit() { - AvdInfo avdInfo = getTableSelection(); - GridDialog dlg; - if(!avdInfo.getDeviceName().isEmpty()) { - dlg = new AvdCreationDialog(mTable.getShell(), - mAvdManager, - mImageFactory, - mSdkLog, - avdInfo); - } else { - dlg = new LegacyAvdEditDialog(mTable.getShell(), - mAvdManager, - mImageFactory, - mSdkLog, - avdInfo); - } - - - if (dlg.open() == Window.OK) { - refresh(false /*reload*/); - } - } - - private void onDetails() { - AvdInfo avdInfo = getTableSelection(); - - AvdDetailsDialog dlg = new AvdDetailsDialog(mTable.getShell(), avdInfo); - dlg.open(); - } - - private void onDelete() { - final AvdInfo avdInfo = getTableSelection(); - - // get the current Display - final Display display = mTable.getDisplay(); - - // check if the AVD is running - if (avdInfo.isRunning()) { - display.asyncExec(new Runnable() { - @Override - public void run() { - Shell shell = display.getActiveShell(); - MessageDialog.openError(shell, - "Delete Android Virtual Device", - String.format( - "The Android Virtual Device '%1$s' is currently running in an emulator and cannot be deleted.", - avdInfo.getName())); - } - }); - return; - } - - // Confirm you want to delete this AVD - final boolean[] result = new boolean[1]; - display.syncExec(new Runnable() { - @Override - public void run() { - Shell shell = display.getActiveShell(); - result[0] = MessageDialog.openQuestion(shell, - "Delete Android Virtual Device", - String.format( - "Please confirm that you want to delete the Android Virtual Device named '%s'. This operation cannot be reverted.", - avdInfo.getName())); - } - }); - - if (result[0] == false) { - return; - } - - // log for this action. - ILogger log = mSdkLog; - if (log == null || log instanceof MessageBoxLog) { - // If the current logger is a message box, we use our own (to make sure - // to display errors right away and customize the title). - log = new MessageBoxLog( - String.format("Result of deleting AVD '%s':", avdInfo.getName()), - display, - false /*logErrorsOnly*/); - } - - // delete the AVD - boolean success = mAvdManager.deleteAvd(avdInfo, log); - - // display the result - if (log instanceof MessageBoxLog) { - ((MessageBoxLog) log).displayResult(success); - } - - if (success) { - refresh(false /*reload*/); - } - } - - /** - * Repairs the selected AVD. - * <p/> - * For now this only supports fixing the wrong value in image.sysdir.* - */ - private void onRepair() { - final AvdInfo avdInfo = getTableSelection(); - - // get the current Display - final Display display = mTable.getDisplay(); - - // log for this action. - ILogger log = mSdkLog; - if (log == null || log instanceof MessageBoxLog) { - // If the current logger is a message box, we use our own (to make sure - // to display errors right away and customize the title). - log = new MessageBoxLog( - String.format("Result of updating AVD '%s':", avdInfo.getName()), - display, - false /*logErrorsOnly*/); - } - - boolean success = true; - - if (avdInfo.getStatus() == AvdStatus.ERROR_IMAGE_DIR) { - // delete the AVD - try { - mAvdManager.updateAvd(avdInfo, log); - refresh(false /*reload*/); - } catch (IOException e) { - log.error(e, null); - success = false; - } - } else if (avdInfo.getStatus() == AvdStatus.ERROR_DEVICE_CHANGED) { - // Overwrite the properties derived from the device and nothing else - Map<String, String> properties = new HashMap<String, String>(avdInfo.getProperties()); - - List<Device> devices = (new DeviceManager(mSdkLog)).getDevices(mOsSdkPath); - String name = properties.get(AvdManager.AVD_INI_DEVICE_NAME); - String manufacturer = properties.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER); - - if (properties != null && devices != null && name != null && manufacturer != null) { - for (Device d : devices) { - if (d.getName().equals(name) && d.getManufacturer().equals(manufacturer)) { - properties.putAll(DeviceManager.getHardwareProperties(d)); - try { - mAvdManager.updateAvd(avdInfo, properties, AvdStatus.OK, log); - } catch (IOException e) { - log.error(e,null); - success = false; - } - } - } - } else { - log.error(null, "Base device information incomplete or missing."); - success = false; - } - - // display the result - if (log instanceof MessageBoxLog) { - ((MessageBoxLog) log).displayResult(success); - } - refresh(false /*reload*/); - } else if (avdInfo.getStatus() == AvdStatus.ERROR_DEVICE_MISSING) { - onEdit(); - } - } - - private void onAvdManager() { - - // get the current Display - Display display = mTable.getDisplay(); - - // log for this action. - ILogger log = mSdkLog; - if (log == null || log instanceof MessageBoxLog) { - // If the current logger is a message box, we use our own (to make sure - // to display errors right away and customize the title). - log = new MessageBoxLog("Result of SDK Manager", display, true /*logErrorsOnly*/); - } - - try { - AvdManagerWindowImpl1 win = new AvdManagerWindowImpl1( - mTable.getShell(), - log, - mOsSdkPath, - AvdInvocationContext.DIALOG); - - win.open(); - } catch (Exception ignore) {} - - refresh(true /*reload*/); // UpdaterWindow uses its own AVD manager so this one must reload. - - if (log instanceof MessageBoxLog) { - ((MessageBoxLog) log).displayResult(true); - } - } - - private void onStart() { - AvdInfo avdInfo = getTableSelection(); - - if (avdInfo == null || mOsSdkPath == null) { - return; - } - - AvdStartDialog dialog = new AvdStartDialog(mTable.getShell(), avdInfo, mOsSdkPath, - mController, mSdkLog); - if (dialog.open() == Window.OK) { - String path = mOsSdkPath + File.separator - + SdkConstants.OS_SDK_TOOLS_FOLDER - + SdkConstants.FN_EMULATOR; - - final String avdName = avdInfo.getName(); - - // build the command line based on the available parameters. - ArrayList<String> list = new ArrayList<String>(); - list.add(path); - list.add("-avd"); //$NON-NLS-1$ - list.add(avdName); - if (dialog.hasWipeData()) { - list.add("-wipe-data"); //$NON-NLS-1$ - } - if (dialog.hasSnapshot()) { - if (!dialog.hasSnapshotLaunch()) { - list.add("-no-snapshot-load"); - } - if (!dialog.hasSnapshotSave()) { - list.add("-no-snapshot-save"); - } - } - float scale = dialog.getScale(); - if (scale != 0.f) { - // do the rounding ourselves. This is because %.1f will write .4899 as .4 - scale = Math.round(scale * 100); - scale /= 100.f; - list.add("-scale"); //$NON-NLS-1$ - // because the emulator expects English decimal values, don't use String.format - // but a Formatter. - Formatter formatter = new Formatter(Locale.US); - formatter.format("%.2f", scale); //$NON-NLS-1$ - list.add(formatter.toString()); - formatter.close(); - } - - // convert the list into an array for the call to exec. - final String[] command = list.toArray(new String[list.size()]); - - // launch the emulator - final ProgressTask progress = new ProgressTask(mTable.getShell(), - "Starting Android Emulator"); - progress.start(new ITask() { - volatile ITaskMonitor mMonitor = null; - - @Override - public void run(final ITaskMonitor monitor) { - mMonitor = monitor; - try { - monitor.setDescription( - "Starting emulator for AVD '%1$s'", - avdName); - monitor.log("Starting emulator for AVD '%1$s'", avdName); - - // we'll wait 100ms*100 = 10s. The emulator sometimes seem to - // start mostly OK just to crash a few seconds later. 10 seconds - // seems a good wait for that case. - int n = 100; - monitor.setProgressMax(n); - - Process process = Runtime.getRuntime().exec(command); - GrabProcessOutput.grabProcessOutput( - process, - Wait.ASYNC, - new IProcessOutput() { - @Override - public void out(@Nullable String line) { - filterStdOut(line); - } - - @Override - public void err(@Nullable String line) { - filterStdErr(line); - } - }); - - // This small wait prevents the dialog from closing too fast: - // When it works, the emulator returns immediately, even if - // no UI is shown yet. And when it fails (because the AVD is - // locked/running) this allows us to have time to capture the - // error and display it. - for (int i = 0; i < n; i++) { - try { - Thread.sleep(100); - monitor.incProgress(1); - } catch (InterruptedException e) { - // ignore - } - } - } catch (Exception e) { - monitor.logError("Failed to start emulator: %1$s", - e.getMessage()); - } finally { - mMonitor = null; - } - } - - private void filterStdOut(String line) { - ITaskMonitor m = mMonitor; - if (line == null || m == null) { - return; - } - - // Skip some non-useful messages. - if (line.indexOf("NSQuickDrawView") != -1) { //$NON-NLS-1$ - // Discard the MacOS warning: - // "This application, or a library it uses, is using NSQuickDrawView, - // which has been deprecated. Apps should cease use of QuickDraw and move - // to Quartz." - return; - } - - if (line.toLowerCase().indexOf("error") != -1 || //$NON-NLS-1$ - line.indexOf("qemu: fatal") != -1) { //$NON-NLS-1$ - // Sometimes the emulator seems to output errors on stdout. Catch these. - m.logError("%1$s", line); //$NON-NLS-1$ - return; - } - - m.log("%1$s", line); //$NON-NLS-1$ - } - - private void filterStdErr(String line) { - ITaskMonitor m = mMonitor; - if (line == null || m == null) { - return; - } - - if (line.indexOf("emulator: device") != -1 || //$NON-NLS-1$ - line.indexOf("HAX is working") != -1) { //$NON-NLS-1$ - // These are not errors. Output them as regular stdout messages. - m.log("%1$s", line); //$NON-NLS-1$ - return; - } - - m.logError("%1$s", line); //$NON-NLS-1$ - } - }); - } - } - - private boolean isAvdRepairable(AvdStatus avdStatus) { - return avdStatus == AvdStatus.ERROR_IMAGE_DIR - || avdStatus == AvdStatus.ERROR_DEVICE_CHANGED - || avdStatus == AvdStatus.ERROR_DEVICE_MISSING; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdStartDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdStartDialog.java deleted file mode 100644 index 0c68dcf..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/AvdStartDialog.java +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.sdklib.devices.Device; -import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.internal.avd.AvdInfo; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdkuilib.internal.repository.SettingsController; -import com.android.sdkuilib.ui.GridDialog; -import com.android.utils.ILogger; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -import java.awt.Toolkit; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Dialog dealing with emulator launch options. The following options are supported: - * <ul> - * <li>-wipe-data</li> - * <li>-scale</li> - * </ul> - * Values are stored (in the class as static field) to be reused while the app is still running. - * The Monitor dpi is stored in the settings if available. - */ -final class AvdStartDialog extends GridDialog { - // static field to reuse values during the same session. - private static boolean sWipeData = false; - private static boolean sSnapshotSave = true; - private static boolean sSnapshotLaunch = true; - private static int sMonitorDpi = 72; // used if there's no setting controller. - private static final Map<String, String> sSkinScaling = new HashMap<String, String>(); - - private static final Pattern sScreenSizePattern = Pattern.compile("\\d*(\\.\\d?)?"); - - private final AvdInfo mAvd; - private final String mSdkLocation; - private final SettingsController mSettingsController; - private final DeviceManager mDeviceManager; - - private Text mScreenSize; - private Text mMonitorDpi; - private Button mScaleButton; - - private float mScale = 0.f; - private boolean mWipeData = false; - private int mDensity = 160; // medium density - private int mSize1 = -1; - private int mSize2 = -1; - private String mSkinDisplay; - private boolean mEnableScaling = true; - private Label mScaleField; - private boolean mHasSnapshot = true; - private boolean mSnapshotSave = true; - private boolean mSnapshotLaunch = true; - private Button mSnapshotLaunchCheckbox; - - AvdStartDialog(Shell parentShell, AvdInfo avd, String sdkLocation, - SettingsController settingsController, ILogger sdkLog) { - super(parentShell, 2, false); - mAvd = avd; - mSdkLocation = sdkLocation; - mSettingsController = settingsController; - mDeviceManager = new DeviceManager(sdkLog); - if (mAvd == null) { - throw new IllegalArgumentException("avd cannot be null"); - } - if (mSdkLocation == null) { - throw new IllegalArgumentException("sdkLocation cannot be null"); - } - - computeSkinData(); - } - - public boolean hasWipeData() { - return mWipeData; - } - - /** - * Returns the scaling factor, or 0.f if none are set. - */ - public float getScale() { - return mScale; - } - - @Override - public void createDialogContent(final Composite parent) { - GridData gd; - - Label l = new Label(parent, SWT.NONE); - l.setText("Skin:"); - - l = new Label(parent, SWT.NONE); - l.setText(mSkinDisplay == null ? "None" : mSkinDisplay); - l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - l = new Label(parent, SWT.NONE); - l.setText("Density:"); - - l = new Label(parent, SWT.NONE); - l.setText(getDensityText()); - l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - mScaleButton = new Button(parent, SWT.CHECK); - mScaleButton.setText("Scale display to real size"); - mScaleButton.setEnabled(mEnableScaling); - boolean defaultState = mEnableScaling && sSkinScaling.get(mAvd.getName()) != null; - mScaleButton.setSelection(defaultState); - mScaleButton.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 2; - final Group scaleGroup = new Group(parent, SWT.NONE); - scaleGroup.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalIndent = 30; - gd.horizontalSpan = 2; - scaleGroup.setLayout(new GridLayout(3, false)); - - l = new Label(scaleGroup, SWT.NONE); - l.setText("Screen Size (in):"); - mScreenSize = new Text(scaleGroup, SWT.BORDER); - mScreenSize.setText(getScreenSize()); - mScreenSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mScreenSize.addVerifyListener(new VerifyListener() { - @Override - public void verifyText(VerifyEvent event) { - // combine the current content and the new text - String text = mScreenSize.getText(); - text = text.substring(0, event.start) + event.text + text.substring(event.end); - - // now make sure it's a match for the regex - event.doit = sScreenSizePattern.matcher(text).matches(); - } - }); - mScreenSize.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent event) { - onScaleChange(); - } - }); - - // empty composite, only 2 widgets on this line. - new Composite(scaleGroup, SWT.NONE).setLayoutData(gd = new GridData()); - gd.widthHint = gd.heightHint = 0; - - l = new Label(scaleGroup, SWT.NONE); - l.setText("Monitor dpi:"); - mMonitorDpi = new Text(scaleGroup, SWT.BORDER); - mMonitorDpi.setText(Integer.toString(getMonitorDpi())); - mMonitorDpi.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.widthHint = 50; - mMonitorDpi.addVerifyListener(new VerifyListener() { - @Override - public void verifyText(VerifyEvent event) { - // check for digit only. - for (int i = 0 ; i < event.text.length(); i++) { - char letter = event.text.charAt(i); - if (letter < '0' || letter > '9') { - event.doit = false; - return; - } - } - } - }); - mMonitorDpi.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent event) { - onScaleChange(); - } - }); - - Button button = new Button(scaleGroup, SWT.PUSH | SWT.FLAT); - button.setText("?"); - button.setToolTipText("Click to figure out your monitor's pixel density"); - button.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - ResolutionChooserDialog dialog = new ResolutionChooserDialog(parent.getShell()); - if (dialog.open() == Window.OK) { - mMonitorDpi.setText(Integer.toString(dialog.getDensity())); - } - } - }); - - l = new Label(scaleGroup, SWT.NONE); - l.setText("Scale:"); - mScaleField = new Label(scaleGroup, SWT.NONE); - mScaleField.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - true /*grabExcessHorizontalSpace*/, - true /*grabExcessVerticalSpace*/, - 2 /*horizontalSpan*/, - 1 /*verticalSpan*/)); - setScale(mScale); // set initial text value - - enableGroup(scaleGroup, defaultState); - - mScaleButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - boolean enabled = mScaleButton.getSelection(); - enableGroup(scaleGroup, enabled); - if (enabled) { - onScaleChange(); - } else { - setScale(0); - } - } - }); - - final Button wipeButton = new Button(parent, SWT.CHECK); - wipeButton.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 2; - wipeButton.setText("Wipe user data"); - wipeButton.setSelection(mWipeData = sWipeData); - wipeButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - mWipeData = wipeButton.getSelection(); - updateSnapshotLaunchAvailability(); - } - }); - - Map<String, String> prop = mAvd.getProperties(); - String snapshotPresent = prop.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); - mHasSnapshot = (snapshotPresent != null) && snapshotPresent.equals("true"); - - mSnapshotLaunchCheckbox = new Button(parent, SWT.CHECK); - mSnapshotLaunchCheckbox.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 2; - mSnapshotLaunchCheckbox.setText("Launch from snapshot"); - updateSnapshotLaunchAvailability(); - mSnapshotLaunchCheckbox.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - mSnapshotLaunch = mSnapshotLaunchCheckbox.getSelection(); - } - }); - - final Button snapshotSaveCheckbox = new Button(parent, SWT.CHECK); - snapshotSaveCheckbox.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 2; - snapshotSaveCheckbox.setText("Save to snapshot"); - snapshotSaveCheckbox.setSelection((mSnapshotSave = sSnapshotSave) && mHasSnapshot); - snapshotSaveCheckbox.setEnabled(mHasSnapshot); - snapshotSaveCheckbox.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - mSnapshotSave = snapshotSaveCheckbox.getSelection(); - } - }); - - l = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - l.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 2; - - // if the scaling is enabled by default, we must initialize the value of mScale - if (defaultState) { - onScaleChange(); - } - } - - /** On Windows we need to manually enable/disable the children of a group */ - private void enableGroup(final Group group, boolean enabled) { - group.setEnabled(enabled); - for (Control c : group.getChildren()) { - c.setEnabled(enabled); - } - } - - @Override - protected void configureShell(Shell newShell) { - super.configureShell(newShell); - newShell.setText("Launch Options"); - } - - @Override - protected Button createButton(Composite parent, int id, String label, boolean defaultButton) { - if (id == IDialogConstants.OK_ID) { - label = "Launch"; - } - - return super.createButton(parent, id, label, defaultButton); - } - - @Override - protected void okPressed() { - // override ok to store some info - // first the monitor dpi - String dpi = mMonitorDpi.getText(); - if (dpi.length() > 0) { - sMonitorDpi = Integer.parseInt(dpi); - - // if there is a setting controller, save it - if (mSettingsController != null) { - mSettingsController.setMonitorDensity(sMonitorDpi); - mSettingsController.saveSettings(); - } - } - - // now the scale factor - String key = mAvd.getName(); - sSkinScaling.remove(key); - if (mScaleButton.getSelection()) { - String size = mScreenSize.getText(); - if (size.length() > 0) { - sSkinScaling.put(key, size); - } - } - - // and then the wipe-data checkbox - sWipeData = mWipeData; - - // and the snapshot handling if those checkboxes are enabled. - if (mHasSnapshot) { - sSnapshotSave = mSnapshotSave; - if (!mWipeData) { - sSnapshotLaunch = mSnapshotLaunch; - } - } - - // finally continue with the ok action - super.okPressed(); - } - - private void computeSkinData() { - Map<String, String> prop = mAvd.getProperties(); - String dpi = prop.get("hw.lcd.density"); - if (dpi != null && dpi.length() > 0) { - mDensity = Integer.parseInt(dpi); - } - - findSkinResolution(); - } - - private void onScaleChange() { - String sizeStr = mScreenSize.getText(); - if (sizeStr.length() == 0) { - setScale(0); - return; - } - - String dpiStr = mMonitorDpi.getText(); - if (dpiStr.length() == 0) { - setScale(0); - return; - } - - int dpi = Integer.parseInt(dpiStr); - float size = Float.parseFloat(sizeStr); - /* - * We are trying to emulate the following device: - * resolution: 'mSize1'x'mSize2' - * density: 'mDensity' - * screen diagonal: 'size' - * ontop a monitor running at 'dpi' - */ - // We start by computing the screen diagonal in pixels, if the density was really mDensity - float diagonalPx = (float)Math.sqrt(mSize1*mSize1+mSize2*mSize2); - // Now we would convert this in actual inches: - // diagonalIn = diagonal / mDensity - // the scale factor is a mix of adapting to the new density and to the new size. - // (size/diagonalIn) * (dpi/mDensity) - // this can be simplified to: - setScale((size * dpi) / diagonalPx); - } - - private void setScale(float scale) { - mScale = scale; - - // Do the rounding exactly like AvdSelector will do. - scale = Math.round(scale * 100); - scale /= 100.f; - - if (scale == 0.f) { - mScaleField.setText("default"); //$NON-NLS-1$ - } else { - mScaleField.setText(String.format("%.2f", scale)); //$NON-NLS-1$ - } - } - - /** - * Returns the monitor dpi to start with. - * This can be coming from the settings, the session-based storage, or the from whatever Java - * can tell us. - */ - private int getMonitorDpi() { - if (mSettingsController != null) { - sMonitorDpi = mSettingsController.getSettings().getMonitorDensity(); - } - - if (sMonitorDpi == -1) { // first time? try to get a value - sMonitorDpi = Toolkit.getDefaultToolkit().getScreenResolution(); - } - - return sMonitorDpi; - } - - /** - * Returns the screen size to start with. - * <p/>If an emulator with the same skin was already launched, scaled, the size used is reused. - * <p/>If one hasn't been launched and the AVD is based on a device, use the device's screen - * size. Otherwise, use the default (3). - */ - private String getScreenSize() { - String size = sSkinScaling.get(mAvd.getName()); - if (size != null) { - return size; - } - - Map<String, String> properties = mAvd.getProperties(); - if (properties != null) { - String name = properties.get(AvdManager.AVD_INI_DEVICE_NAME); - String mfctr = properties.get(AvdManager.AVD_INI_DEVICE_MANUFACTURER); - if (name != null && mfctr != null) { - Device d = mDeviceManager.getDevice(mSdkLocation, name, mfctr); - if (d != null) { - double screenSize = - d.getDefaultHardware().getScreen().getDiagonalLength(); - return String.format("%.1f", screenSize); - } - } - } - - return "3"; - } - - /** - * Returns a display string for the density. - */ - private String getDensityText() { - switch (mDensity) { - case 120: - return "Low (120)"; - case 160: - return "Medium (160)"; - case 240: - return "High (240)"; - } - - return Integer.toString(mDensity); - } - - /** - * Finds the skin resolution and sets it in {@link #mSize1} and {@link #mSize2}. - */ - private void findSkinResolution() { - Map<String, String> prop = mAvd.getProperties(); - String skinName = prop.get(AvdManager.AVD_INI_SKIN_NAME); - - if (skinName != null) { - Matcher m = AvdManager.NUMERIC_SKIN_SIZE.matcher(skinName); - if (m != null && m.matches()) { - mSize1 = Integer.parseInt(m.group(1)); - mSize2 = Integer.parseInt(m.group(2)); - mSkinDisplay = skinName; - mEnableScaling = true; - return; - } - } - - // The resolution is inside the layout file of the skin. - mEnableScaling = false; // default to false for now. - - // path to the skin layout file. - String skinPath = prop.get(AvdManager.AVD_INI_SKIN_PATH); - if (skinPath != null) { - File skinFolder = new File(mSdkLocation, skinPath); - if (skinFolder.isDirectory()) { - File layoutFile = new File(skinFolder, "layout"); - if (layoutFile.isFile()) { - if (parseLayoutFile(layoutFile)) { - mSkinDisplay = String.format("%1$s (%2$dx%3$d)", skinName, mSize1, mSize2); - mEnableScaling = true; - } else { - mSkinDisplay = skinName; - } - } - } - } - } - - /** - * Parses a layout file. - * <p/> - * the format is relatively easy. It's a collection of items defined as - * ≶name> { - * ≶content> - * } - * - * content is either 1+ items or 1+ properties - * properties are defined as - * ≶name>≶whitespace>≶value> - * - * We're going to look for an item called display, with 2 properties height and width. - * This is very basic parser. - * - * @param layoutFile the file to parse - * @return true if both sizes where found. - */ - private boolean parseLayoutFile(File layoutFile) { - BufferedReader input = null; - try { - input = new BufferedReader(new FileReader(layoutFile)); - String line; - - while ((line = input.readLine()) != null) { - // trim to remove whitespace - line = line.trim(); - int len = line.length(); - if (len == 0) continue; - - // check if this is a new item - if (line.charAt(len-1) == '{') { - // this is the start of a node - String[] tokens = line.split(" "); - if ("display".equals(tokens[0])) { - // this is the one we're looking for! - while ((mSize1 == -1 || mSize2 == -1) && - (line = input.readLine()) != null) { - // trim to remove whitespace - line = line.trim(); - len = line.length(); - if (len == 0) continue; - - if ("}".equals(line)) { // looks like we're done with the item. - break; - } - - tokens = line.split(" "); - if (tokens.length >= 2) { - // there can be multiple space between the name and value - // in which case we'll get an extra empty token in the middle. - if ("width".equals(tokens[0])) { - mSize1 = Integer.parseInt(tokens[tokens.length-1]); - } else if ("height".equals(tokens[0])) { - mSize2 = Integer.parseInt(tokens[tokens.length-1]); - } - } - } - - return mSize1 != -1 && mSize2 != -1; - } - } - - } - // if it reaches here, display was not found. - // false is returned below. - } catch (IOException e) { - // ignore. - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException e) { - // ignore - } - } - } - - return false; - } - - /** - * @return Whether there's a snapshot file available. - */ - public boolean hasSnapshot() { - return mHasSnapshot; - } - - /** - * @return Whether to launch and load snapshot. - */ - public boolean hasSnapshotLaunch() { - return mSnapshotLaunch && !hasWipeData(); - } - - /** - * @return Whether to preserve emulator state to snapshot. - */ - public boolean hasSnapshotSave() { - return mSnapshotSave; - } - - /** - * Updates snapshot launch availability, for when mWipeData value changes. - */ - private void updateSnapshotLaunchAvailability() { - boolean enabled = !mWipeData && mHasSnapshot; - mSnapshotLaunchCheckbox.setEnabled(enabled); - mSnapshotLaunch = enabled && sSnapshotLaunch; - mSnapshotLaunchCheckbox.setSelection(mSnapshotLaunch); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/DeviceCreationDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/DeviceCreationDialog.java deleted file mode 100644 index 873a822..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/DeviceCreationDialog.java +++ /dev/null @@ -1,1014 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.annotations.Nullable; -import com.android.resources.Density; -import com.android.resources.Keyboard; -import com.android.resources.KeyboardState; -import com.android.resources.Navigation; -import com.android.resources.NavigationState; -import com.android.resources.ResourceEnum; -import com.android.resources.ScreenOrientation; -import com.android.resources.ScreenRatio; -import com.android.resources.ScreenSize; -import com.android.resources.TouchScreen; -import com.android.sdklib.devices.Abi; -import com.android.sdklib.devices.ButtonType; -import com.android.sdklib.devices.Camera; -import com.android.sdklib.devices.CameraLocation; -import com.android.sdklib.devices.Device; -import com.android.sdklib.devices.DeviceManager; -import com.android.sdklib.devices.Hardware; -import com.android.sdklib.devices.Multitouch; -import com.android.sdklib.devices.Network; -import com.android.sdklib.devices.PowerType; -import com.android.sdklib.devices.Screen; -import com.android.sdklib.devices.ScreenType; -import com.android.sdklib.devices.Sensor; -import com.android.sdklib.devices.Software; -import com.android.sdklib.devices.State; -import com.android.sdklib.devices.Storage; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.ui.GridDialog; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -import java.util.List; - -public class DeviceCreationDialog extends GridDialog { - - private static final String MANUFACTURER = "User"; - - private final ImageFactory mImageFactory; - private final DeviceManager mManager; - private List<Device> mUserDevices; - - private Device mDevice; - - private Text mDeviceName; - private Text mDiagonalLength; - private Text mXDimension; - private Text mYDimension; - private Button mKeyboard; - private Button mDpad; - private Button mTrackball; - private Button mNoNav; - private Text mRam; - private Combo mRamCombo; - private Combo mButtons; - private Combo mSize; - private Combo mDensity; - private Combo mRatio; - private Button mAccelerometer; // hw.accelerometer - private Button mGyro; // hw.sensors.orientation - private Button mGps; // hw.sensors.gps - private Button mProximitySensor; // hw.sensors.proximity - private Button mCameraFront; - private Button mCameraRear; - private Group mStateGroup; - private Button mPortrait; - private Label mPortraitLabel; - private Button mPortraitNav; - private Button mLandscape; - private Label mLandscapeLabel; - private Button mLandscapeNav; - private Button mPortraitKeys; - private Label mPortraitKeysLabel; - private Button mPortraitKeysNav; - private Button mLandscapeKeys; - private Label mLandscapeKeysLabel; - private Button mLandscapeKeysNav; - - private Button mForceCreation; - private Label mStatusIcon; - private Label mStatusLabel; - - private Button mOkButton; - - // The hardware instance attached to each of the states of the created - // device - private Hardware mHardware; - // This contains the Software for the device. Since it has no effect on the - // emulator whatsoever, we just use a single instance with reasonable - // defaults. - private static final Software mSoftware; - - static { - mSoftware = new Software(); - mSoftware.setLiveWallpaperSupport(true); - mSoftware.setGlVersion("2.0"); - } - - public DeviceCreationDialog(Shell parentShell, - DeviceManager manager, - ImageFactory imageFactory, - @Nullable Device device) { - super(parentShell, 2, false); - mImageFactory = imageFactory; - mDevice = device; - mManager = manager; - mUserDevices = mManager.getUserDevices(); - } - - @Override - protected Control createContents(Composite parent) { - Control control = super.createContents(parent); - - mOkButton = getButton(IDialogConstants.OK_ID); - - if (mDevice == null) { - getShell().setText("Create New Device"); - } else { - if (mUserDevices.contains(mDevice)) { - getShell().setText("Edit Device"); - } else { - getShell().setText("Clone Device"); - } - } - - validatePage(); - - return control; - } - - @Override - public void createDialogContent(Composite parent) { - - ValidationListener validator = new ValidationListener(); - SizeListener sizeListener = new SizeListener(); - NavStateListener navListener = new NavStateListener(); - - String tooltip = "Name of the new device"; - generateLabel("Name:", tooltip, parent); - mDeviceName = generateText(parent, tooltip, new CreateNameModifyListener()); - - tooltip = "Diagonal length of the screen in inches"; - generateLabel("Screen Size (in):", tooltip, parent); - mDiagonalLength = generateText(parent, tooltip, sizeListener); - - tooltip = "The resolution of the device in pixels"; - generateLabel("Resolution:", tooltip, parent); - Group dimensionGroup = new Group(parent, SWT.NONE); - dimensionGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - dimensionGroup.setLayout(new GridLayout(3, false)); - mXDimension = generateText(dimensionGroup, tooltip, sizeListener); - new Label(dimensionGroup, SWT.NONE).setText("x"); - mYDimension = generateText(dimensionGroup, tooltip, sizeListener); - - tooltip = "The screen size bucket that the device falls into"; - generateLabel("Size:", tooltip, parent); - mSize = generateCombo(parent, tooltip, ScreenSize.values(), 1, validator); - - tooltip = "The aspect ratio bucket the screen falls into. A \"long\" screen is wider."; - generateLabel("Screen Ratio:", tooltip, parent); - mRatio = generateCombo(parent, tooltip, ScreenRatio.values(), 1, validator); - - tooltip = "The pixel density bucket the device falls in"; - generateLabel("Density:", tooltip, parent); - mDensity = generateCombo(parent, tooltip, Density.values(), 3, validator); - - generateLabel("Sensors:", "The sensors available on the device", parent); - Group sensorGroup = new Group(parent, SWT.NONE); - sensorGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - sensorGroup.setLayout(new GridLayout(2, false)); - mAccelerometer = generateButton(sensorGroup, "Accelerometer", - "Presence of an accelerometer", SWT.CHECK, true, validator); - mGyro = generateButton(sensorGroup, "Gyroscope", - "Presence of a gyroscope", SWT.CHECK, true, validator); - mGps = generateButton(sensorGroup, "GPS", "Presence of a GPS", SWT.CHECK, true, validator); - mProximitySensor = generateButton(sensorGroup, "Proximity Sensor", - "Presence of a proximity sensor", SWT.CHECK, true, validator); - - generateLabel("Cameras", "The cameras available on the device", parent); - Group cameraGroup = new Group(parent, SWT.NONE); - cameraGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - cameraGroup.setLayout(new GridLayout(2, false)); - mCameraFront = generateButton(cameraGroup, "Front", "Presence of a front camera", - SWT.CHECK, false, validator); - mCameraRear = generateButton(cameraGroup, "Rear", "Presence of a rear camera", - SWT.CHECK, true, validator); - - generateLabel("Input:", "The input hardware on the given device", parent); - Group inputGroup = new Group(parent, SWT.NONE); - inputGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - inputGroup.setLayout(new GridLayout(3, false)); - mKeyboard = generateButton(inputGroup, "Keyboard", "Presence of a hardware keyboard", - SWT.CHECK, false, - new KeyboardListener()); - GridData gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 3; - mKeyboard.setLayoutData(gridData); - mNoNav = generateButton(inputGroup, "No Nav", "No hardware navigation", - SWT.RADIO, true, navListener); - mDpad = generateButton(inputGroup, "DPad", "The device has a DPad navigation element", - SWT.RADIO, false, navListener); - mTrackball = generateButton(inputGroup, "Trackball", - "The device has a trackball navigation element", SWT.RADIO, false, navListener); - - tooltip = "The amount of RAM on the device"; - generateLabel("RAM:", tooltip, parent); - Group ramGroup = new Group(parent, SWT.NONE); - ramGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - ramGroup.setLayout(new GridLayout(2, false)); - mRam = generateText(ramGroup, tooltip, validator); - mRamCombo = new Combo(ramGroup, SWT.DROP_DOWN | SWT.READ_ONLY); - mRamCombo.setToolTipText(tooltip); - mRamCombo.add("MiB"); - mRamCombo.add("GiB"); - mRamCombo.select(0); - mRamCombo.addModifyListener(validator); - - tooltip = "Type of buttons (Home, Menu, etc.) on the device. " - + "This can be software buttons like on the Galaxy Nexus, or hardware buttons like " - + "the capacitive buttons on the Nexus S."; - generateLabel("Buttons:", tooltip, parent); - mButtons = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); - mButtons.setToolTipText(tooltip); - mButtons.add("Software"); - mButtons.add("Hardware"); - mButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mButtons.select(0); - mButtons.addModifyListener(validator); - - generateLabel("Device States:", "The available states for the given device", parent); - - mStateGroup = new Group(parent, SWT.NONE); - mStateGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mStateGroup.setLayout(new GridLayout(2, true)); - - tooltip = "The device has a portait position with no keyboard available"; - mPortraitLabel = generateLabel("Portrait:", tooltip, mStateGroup); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 2; - mPortraitLabel.setLayoutData(gridData); - mPortrait = generateButton(mStateGroup, "Enabled", tooltip, SWT.CHECK, true, - navListener); - mPortraitNav = generateButton(mStateGroup, "Navigation", - "Hardware navigation is available in this state", SWT.CHECK, true, validator); - mPortraitNav.setEnabled(false); - - tooltip = "The device has a landscape position with no keyboard available"; - mLandscapeLabel = generateLabel("Landscape:", tooltip, mStateGroup); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 2; - mLandscapeLabel.setLayoutData(gridData); - mLandscape = generateButton(mStateGroup, "Enabled", tooltip, SWT.CHECK, true, - navListener); - mLandscapeNav = generateButton(mStateGroup, "Navigation", - "Hardware navigation is available in this state", SWT.CHECK, true, validator); - mLandscapeNav.setEnabled(false); - - tooltip = "The device has a portait position with a keyboard available"; - mPortraitKeysLabel = generateLabel("Portrait with keyboard:", tooltip, mStateGroup); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 2; - mPortraitKeysLabel.setLayoutData(gridData); - mPortraitKeysLabel.setEnabled(false); - mPortraitKeys = generateButton(mStateGroup, "Enabled", tooltip, SWT.CHECK, true, - navListener); - mPortraitKeys.setEnabled(false); - mPortraitKeysNav = generateButton(mStateGroup, "Navigation", - "Hardware navigation is available in this state", SWT.CHECK, true, validator); - mPortraitKeysNav.setEnabled(false); - - tooltip = "The device has a landscape position with the keyboard open"; - mLandscapeKeysLabel = generateLabel("Landscape with keyboard:", tooltip, mStateGroup); - gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.horizontalSpan = 2; - mLandscapeKeysLabel.setLayoutData(gridData); - mLandscapeKeysLabel.setEnabled(false); - mLandscapeKeys = generateButton(mStateGroup, "Enabled", tooltip, SWT.CHECK, true, - navListener); - mLandscapeKeys.setEnabled(false); - mLandscapeKeysNav = generateButton(mStateGroup, "Navigation", - "Hardware navigation is available in this state", SWT.CHECK, true, validator); - mLandscapeKeysNav.setEnabled(false); - - mForceCreation = new Button(parent, SWT.CHECK); - mForceCreation.setText("Override the existing device with the same name"); - mForceCreation - .setToolTipText("There's already an AVD with the same name. Check this to delete it and replace it by the new AVD."); - mForceCreation.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, - true, false, 2, 1)); - mForceCreation.setEnabled(false); - mForceCreation.addSelectionListener(validator); - - // add a separator to separate from the ok/cancel button - Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); - - // add stuff for the error display - Composite statusComposite = new Composite(parent, SWT.NONE); - GridLayout gl; - statusComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - true, false, 3, 1)); - statusComposite.setLayout(gl = new GridLayout(2, false)); - gl.marginHeight = gl.marginWidth = 0; - - mStatusIcon = new Label(statusComposite, SWT.NONE); - mStatusIcon.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - mStatusLabel = new Label(statusComposite, SWT.NONE); - mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mStatusLabel.setText(""); //$NON-NLS-1$ - - prefillWithDevice(mDevice); - - validatePage(); - } - - private Button generateButton(Composite parent, String text, String tooltip, int type, - boolean selected, SelectionListener listener) { - Button b = new Button(parent, type); - b.setText(text); - b.setToolTipText(tooltip); - b.setSelection(selected); - b.addSelectionListener(listener); - b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - return b; - } - - /** - * Generates a combo widget attached to the given parent, then sets the - * tooltip, adds all of the {@link String}s returned by - * {@link ResourceEnum#getResourceValue()} for each {@link ResourceEnum}, - * sets the combo to the given index and adds the given - * {@link ModifyListener}. - */ - private Combo generateCombo(Composite parent, String tooltip, ResourceEnum[] values, - int selection, - ModifyListener validator) { - Combo c = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); - c.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - c.setToolTipText(tooltip); - for (ResourceEnum r : values) { - c.add(r.getResourceValue()); - } - c.select(selection); - c.addModifyListener(validator); - return c; - } - - /** Generates a text widget with the given tooltip, parent and listener */ - private Text generateText(Composite parent, String tooltip, ModifyListener listener) { - Text t = new Text(parent, SWT.BORDER); - t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - t.setToolTipText(tooltip); - t.addModifyListener(listener); - return t; - } - - /** Generates a label and attaches it to the given parent */ - private Label generateLabel(String text, String tooltip, Composite parent) { - Label label = new Label(parent, SWT.NONE); - label.setText(text); - label.setToolTipText(tooltip); - label.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_CENTER)); - return label; - } - - /** - * Callback when the device name is changed. Enforces that device names - * don't conflict with already existing devices unless we're editing that - * device. - */ - private class CreateNameModifyListener implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - String name = mDeviceName.getText(); - boolean nameCollision = false; - for (Device d : mUserDevices) { - if (MANUFACTURER.equals(d.getManufacturer()) && name.equals(d.getName())) { - nameCollision = true; - break; - } - } - mForceCreation.setEnabled(nameCollision); - mForceCreation.setSelection(!nameCollision); - - validatePage(); - } - } - - /** - * Callback attached to the diagonal length and resolution text boxes. Sets - * the screen size and display density based on their values, then validates - * the page. - */ - private class SizeListener implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - - if (!mDiagonalLength.getText().isEmpty()) { - double diagonal = Double.parseDouble(mDiagonalLength.getText()); - double diagonalDp = 160.0 * diagonal; - - // Set the Screen Size - if (diagonalDp >= 1200) { - mSize.select(ScreenSize.getIndex(ScreenSize.getEnum("xlarge"))); - } else if (diagonalDp >= 800) { - mSize.select(ScreenSize.getIndex(ScreenSize.getEnum("large"))); - } else if (diagonalDp >= 568) { - mSize.select(ScreenSize.getIndex(ScreenSize.getEnum("normal"))); - } else { - mSize.select(ScreenSize.getIndex(ScreenSize.getEnum("small"))); - } - if (!mXDimension.getText().isEmpty() && !mYDimension.getText().isEmpty()) { - - // Set the density based on which bucket it's closest to - double x = Double.parseDouble(mXDimension.getText()); - double y = Double.parseDouble(mYDimension.getText()); - double dpi = Math.sqrt(x * x + y * y) / diagonal; - double difference = Double.MAX_VALUE; - Density bucket = Density.MEDIUM; - for (Density d : Density.values()) { - if (Math.abs(d.getDpiValue() - dpi) < difference) { - difference = Math.abs(d.getDpiValue() - dpi); - bucket = d; - } - } - mDensity.select(Density.getIndex(bucket)); - } - } - } - } - - - /** - * Callback attached to the keyboard checkbox.Enables / disables device - * states based on the keyboard presence and then validates the page. - */ - private class KeyboardListener extends SelectionAdapter { - @Override - public void widgetSelected(SelectionEvent event) { - super.widgetSelected(event); - if (mKeyboard.getSelection()) { - mPortraitKeys.setEnabled(true); - mPortraitKeysLabel.setEnabled(true); - mLandscapeKeys.setEnabled(true); - mLandscapeKeysLabel.setEnabled(true); - } else { - mPortraitKeys.setEnabled(false); - mPortraitKeysLabel.setEnabled(false); - mLandscapeKeys.setEnabled(false); - mLandscapeKeysLabel.setEnabled(false); - } - toggleNav(); - validatePage(); - } - - } - - /** - * Listens for changes on widgets that affect nav availability and toggles - * the nav checkboxes for device states based on them. - */ - private class NavStateListener extends SelectionAdapter { - @Override - public void widgetSelected(SelectionEvent event) { - super.widgetSelected(event); - toggleNav(); - validatePage(); - } - } - - /** - * Method that inspects all of the relevant dialog state and enables or disables the nav - * elements accordingly. - */ - private void toggleNav() { - mPortraitNav.setEnabled(mPortrait.getSelection() && !mNoNav.getSelection()); - mLandscapeNav.setEnabled(mLandscape.getSelection() && !mNoNav.getSelection()); - mPortraitKeysNav.setEnabled(mPortraitKeys.getSelection() && mPortraitKeys.getEnabled() - && !mNoNav.getSelection()); - mLandscapeKeysNav.setEnabled(mLandscapeKeys.getSelection() - && mLandscapeKeys.getEnabled() && !mNoNav.getSelection()); - validatePage(); - } - - /** - * Callback that validates the page on modification events or widget - * selections - */ - private class ValidationListener extends SelectionAdapter implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - validatePage(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - validatePage(); - } - } - - /** - * Validates all of the config options to ensure a valid device can be - * created from them. - * - * @return Whether the config options will result in a valid device. - */ - private boolean validatePage() { - boolean valid = true; - String error = null; - String warning = null; - setError(null); - - String name = mDeviceName.getText(); - - /* If we're editing / cloning a device, this will get called when the name gets pre-filled - * but the ok button won't be populated yet, so we need to skip the initial setting. - */ - if (mOkButton != null) { - if (mDevice == null) { - getShell().setText("Create New Device"); - mOkButton.setText("Create Device"); - } else { - if (mDevice.getName().equals(name)){ - if (mUserDevices.contains(mDevice)) { - getShell().setText("Edit Device"); - mOkButton.setText("Edit Device"); - } else { - warning = "Only user created devices are editable.\nA clone of it will be created under " + - "the \"User\" category."; - getShell().setText("Clone Device"); - mOkButton.setText("Clone Device"); - } - } else { - warning = "The device \"" + mDevice.getName() +"\" will be duplicated into\n" + - "\"" + name + "\" under the \"User\" category"; - getShell().setText("Clone Device"); - mOkButton.setText("Clone Device"); - } - } - } - - if (name.isEmpty()) { - valid = false; - } - if (!validateFloat("Diagonal Length", mDiagonalLength.getText())) { - valid = false; - } - if (!validateInt("Resolution", mXDimension.getText())) { - valid = false; - } - if (!validateInt("Resolution", mYDimension.getText())) { - valid = false; - } - if (mSize.getSelectionIndex() < 0) { - error = "A size bucket must be selected."; - valid = false; - } - if (mDensity.getSelectionIndex() < 0) { - error = "A screen density bucket must be selected"; - valid = false; - } - if (mRatio.getSelectionIndex() < 0) { - error = "A screen ratio must be selected."; - valid = false; - } - if (!mNoNav.getSelection() && !mTrackball.getSelection() && !mDpad.getSelection()) { - error = "A mode of hardware navigation, or no navigation, has to be selected."; - valid = false; - } - if (!validateInt("RAM", mRam.getText())) { - valid = false; - } - if (mRamCombo.getSelectionIndex() < 0) { - error = "RAM must have a selected unit."; - valid = false; - } - if (mButtons.getSelectionIndex() < 0) { - error = "A button type must be selected."; - valid = false; - } - if (mKeyboard.getSelection()) { - if (!mPortraitKeys.getSelection() - && !mPortrait.getSelection() - && !mLandscapeKeys.getSelection() - && !mLandscape.getSelection()) { - error = "At least one device state must be enabled."; - valid = false; - } - } else { - if (!mPortrait.getSelection() && !mLandscape.getSelection()) { - error = "At least one device state must be enabled"; - valid = false; - } - } - if (mForceCreation.isEnabled() && !mForceCreation.getSelection()) { - error = "Name conflicts with an existing device."; - valid = false; - } - - if (mOkButton != null) { - mOkButton.setEnabled(valid); - } - - if (error != null) { - setError(error); - } else if (warning != null) { - setWarning(warning); - } - - return valid; - } - - /** - * Validates the string is a valid, positive float. If not, it sets the - * error at the bottom of the dialog and returns false. Note this does - * <b>not</b> unset the error message, it's up to the caller to unset it iff - * it knows there are no errors on the page. - */ - private boolean validateFloat(String box, String value) { - if (value == null || value.isEmpty()) { - return false; - } - boolean ret = true; - try { - double val = Double.parseDouble(value); - if (val <= 0) { - ret = false; - } - } catch (NumberFormatException e) { - ret = false; - } - if (!ret) { - setError(box + " must be a valid, positive number."); - } - return ret; - } - - /** - * Validates the string is a valid, positive integer. If not, it sets the - * error at the bottom of the dialog and returns false. Note this does - * <b>not</b> unset the error message, it's up to the caller to unset it iff - * it knows there are no errors on the page. - */ - private boolean validateInt(String box, String value) { - if (value == null || value.isEmpty()) { - return false; - } - boolean ret = true; - try { - int val = Integer.parseInt(value); - if (val <= 0) { - ret = false; - } - } catch (NumberFormatException e) { - ret = false; - } - - if (!ret) { - setError(box + " must be a valid, positive integer."); - } - - return ret; - } - - /** - * Sets the error to the given string. If null, removes the error message. - */ - private void setError(@Nullable String error) { - if (error == null) { - mStatusIcon.setImage(null); - mStatusLabel.setText(""); - } else { - mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png")); - mStatusLabel.setText(error); - } - } - - /** - * Sets the warning message to the given string. If null, removes the - * warning message. - */ - private void setWarning(@Nullable String warning) { - if (warning == null) { - mStatusIcon.setImage(null); - mStatusLabel.setText(""); - } else { - mStatusIcon.setImage(mImageFactory.getImageByName("warning_icon16.png")); - mStatusLabel.setText(warning); - } - } - - /** Sets the hardware for the new device */ - private void prefillWithDevice(@Nullable Device device) { - if (device == null) { - - // Setup the default hardware instance with reasonable values for - // the things which are configurable via this dialog. - mHardware = new Hardware(); - - Screen s = new Screen(); - s.setXdpi(316); - s.setYdpi(316); - s.setMultitouch(Multitouch.JAZZ_HANDS); - s.setMechanism(TouchScreen.FINGER); - s.setScreenType(ScreenType.CAPACITIVE); - mHardware.setScreen(s); - - mHardware.addNetwork(Network.BLUETOOTH); - mHardware.addNetwork(Network.WIFI); - mHardware.addNetwork(Network.NFC); - - mHardware.addSensor(Sensor.BAROMETER); - mHardware.addSensor(Sensor.COMPASS); - mHardware.addSensor(Sensor.LIGHT_SENSOR); - - mHardware.setHasMic(true); - mHardware.addInternalStorage(new Storage(4, Storage.Unit.GiB)); - mHardware.setCpu("Generic CPU"); - mHardware.setGpu("Generic GPU"); - - mHardware.addSupportedAbi(Abi.ARMEABI); - mHardware.addSupportedAbi(Abi.ARMEABI_V7A); - mHardware.addSupportedAbi(Abi.MIPS); - mHardware.addSupportedAbi(Abi.X86); - - mHardware.setChargeType(PowerType.BATTERY); - return; - } - mHardware = device.getDefaultHardware().deepCopy(); - mDeviceName.setText(device.getName()); - mForceCreation.setSelection(true); - Screen s = mHardware.getScreen(); - mDiagonalLength.setText(Double.toString(s.getDiagonalLength())); - mXDimension.setText(Integer.toString(s.getXDimension())); - mYDimension.setText(Integer.toString(s.getYDimension())); - String size = s.getSize().getResourceValue(); - for (int i = 0; i < mSize.getItemCount(); i++) { - if (size.equals(mSize.getItem(i))) { - mSize.select(i); - break; - } - } - String ratio = s.getRatio().getResourceValue(); - for (int i = 0; i < mRatio.getItemCount(); i++) { - if (ratio.equals(mRatio.getItem(i))) { - mRatio.select(i); - break; - } - } - String density = s.getPixelDensity().getResourceValue(); - for (int i = 0; i < mDensity.getItemCount(); i++) { - if (density.equals(mDensity.getItem(i))) { - mDensity.select(i); - break; - } - } - mKeyboard.setSelection(!Keyboard.NOKEY.equals(mHardware.getKeyboard())); - mDpad.setSelection(Navigation.DPAD.equals(mHardware.getNav())); - mTrackball.setSelection(Navigation.TRACKBALL.equals(mHardware.getNav())); - mNoNav.setSelection(Navigation.NONAV.equals(mHardware.getNav())); - mAccelerometer.setSelection(mHardware.getSensors().contains(Sensor.ACCELEROMETER)); - mGyro.setSelection(mHardware.getSensors().contains(Sensor.GYROSCOPE)); - mGps.setSelection(mHardware.getSensors().contains(Sensor.GPS)); - mProximitySensor.setSelection(mHardware.getSensors().contains(Sensor.PROXIMITY_SENSOR)); - mCameraFront.setSelection(false); - mCameraRear.setSelection(false); - for (Camera c : mHardware.getCameras()) { - if (CameraLocation.FRONT.equals(c.getLocation())) { - mCameraFront.setSelection(true); - } else if (CameraLocation.BACK.equals(c.getLocation())) { - mCameraRear.setSelection(true); - } - } - mRam.setText(Long.toString(mHardware.getRam().getSizeAsUnit(Storage.Unit.MiB))); - mRamCombo.select(0); - for (int i = 0; i < mButtons.getItemCount(); i++) { - if (mButtons.getItem(i).equals(mHardware.getButtonType().toString())) { - mButtons.select(i); - break; - } - } - - for (State state : device.getAllStates()) { - Button nav = null; - if (state.getOrientation().equals(ScreenOrientation.PORTRAIT)) { - if (state.getKeyState().equals(KeyboardState.EXPOSED)) { - mPortraitKeys.setSelection(true); - nav = mPortraitKeysNav; - } else { - mPortrait.setSelection(true); - nav = mPortraitNav; - } - } else { - if (state.getKeyState().equals(KeyboardState.EXPOSED)) { - mLandscapeKeys.setSelection(true); - nav = mLandscapeKeysNav; - } else { - mLandscape.setSelection(true); - nav = mLandscapeNav; - } - } - nav.setSelection(state.getNavState().equals(NavigationState.EXPOSED) - && !mHardware.getNav().equals(Navigation.NONAV)); - } - } - - /** - * If given a valid page, generates the corresponding device. The device is - * then added to the user device list, replacing any previous device with - * its given name and manufacturer, and the list is saved out to disk. - */ - @Override - protected void okPressed() { - if (validatePage()) { - Device.Builder builder = new Device.Builder(); - builder.setManufacturer("User"); - builder.setName(mDeviceName.getText()); - builder.addSoftware(mSoftware); - Screen s = mHardware.getScreen(); - double diagonal = Double.parseDouble(mDiagonalLength.getText()); - int x = Integer.parseInt(mXDimension.getText()); - int y = Integer.parseInt(mYDimension.getText()); - s.setDiagonalLength(diagonal); - s.setXDimension(x); - s.setYDimension(y); - // The diagonal DPI will be somewhere in between the X and Y dpi if - // they differ - double dpi = Math.sqrt(x * x + y * y) / diagonal; - s.setXdpi(dpi); - s.setYdpi(dpi); - s.setPixelDensity(Density.getEnum(mDensity.getText())); - s.setSize(ScreenSize.getEnum(mSize.getText())); - s.setRatio(ScreenRatio.getEnum(mRatio.getText())); - if (mAccelerometer.getSelection()) { - mHardware.addSensor(Sensor.ACCELEROMETER); - } - if (mGyro.getSelection()) { - mHardware.addSensor(Sensor.GYROSCOPE); - } - if (mGps.getSelection()) { - mHardware.addSensor(Sensor.GPS); - } - if (mProximitySensor.getSelection()) { - mHardware.addSensor(Sensor.PROXIMITY_SENSOR); - } - if (mCameraFront.getSelection()) { - Camera c = new Camera(); - c.setAutofocus(true); - c.setFlash(true); - c.setLocation(CameraLocation.FRONT); - mHardware.addCamera(c); - } - if (mCameraRear.getSelection()) { - Camera c = new Camera(); - c.setAutofocus(true); - c.setFlash(true); - c.setLocation(CameraLocation.BACK); - mHardware.addCamera(c); - } - if (mKeyboard.getSelection()) { - mHardware.setKeyboard(Keyboard.QWERTY); - } else { - mHardware.setKeyboard(Keyboard.NOKEY); - } - if (mDpad.getSelection()) { - mHardware.setNav(Navigation.DPAD); - } else if (mTrackball.getSelection()) { - mHardware.setNav(Navigation.TRACKBALL); - } else { - mHardware.setNav(Navigation.NONAV); - } - long ram = Long.parseLong(mRam.getText()); - Storage.Unit unit = Storage.Unit.getEnum(mRamCombo.getText()); - mHardware.setRam(new Storage(ram, unit)); - if (mButtons.getText().equals("Hardware")) { - mHardware.setButtonType(ButtonType.HARD); - } else { - mHardware.setButtonType(ButtonType.SOFT); - } - - // Set the first enabled state to the default state - boolean defaultSelected = false; - if (mPortrait.getSelection()) { - State state = new State(); - state.setName("Portrait"); - state.setDescription("The device in portrait orientation"); - state.setOrientation(ScreenOrientation.PORTRAIT); - if (mHardware.getNav().equals(Navigation.NONAV) || !mPortraitNav.getSelection()) { - state.setNavState(NavigationState.HIDDEN); - } else { - state.setNavState(NavigationState.EXPOSED); - } - if (mHardware.getKeyboard().equals(Keyboard.NOKEY)) { - state.setKeyState(KeyboardState.SOFT); - } else { - state.setKeyState(KeyboardState.HIDDEN); - } - state.setHardware(mHardware); - if (!defaultSelected) { - state.setDefaultState(true); - defaultSelected = true; - } - builder.addState(state); - } - if (mLandscape.getSelection()) { - State state = new State(); - state.setName("Landscape"); - state.setDescription("The device in landscape orientation"); - state.setOrientation(ScreenOrientation.LANDSCAPE); - if (mHardware.getNav().equals(Navigation.NONAV) || !mLandscapeNav.getSelection()) { - state.setNavState(NavigationState.HIDDEN); - } else { - state.setNavState(NavigationState.EXPOSED); - } - if (mHardware.getKeyboard().equals(Keyboard.NOKEY)) { - state.setKeyState(KeyboardState.SOFT); - } else { - state.setKeyState(KeyboardState.HIDDEN); - } - state.setHardware(mHardware); - if (!defaultSelected) { - state.setDefaultState(true); - defaultSelected = true; - } - builder.addState(state); - } - if (mKeyboard.getSelection()) { - if (mPortraitKeys.getSelection()) { - State state = new State(); - state.setName("Portrait with keyboard"); - state.setDescription("The device in portrait orientation with a keyboard open"); - state.setOrientation(ScreenOrientation.LANDSCAPE); - if (mHardware.getNav().equals(Navigation.NONAV) - || !mPortraitKeysNav.getSelection()) { - state.setNavState(NavigationState.HIDDEN); - } else { - state.setNavState(NavigationState.EXPOSED); - } - state.setKeyState(KeyboardState.EXPOSED); - state.setHardware(mHardware); - if (!defaultSelected) { - state.setDefaultState(true); - defaultSelected = true; - } - builder.addState(state); - } - if (mLandscapeKeys.getSelection()) { - State state = new State(); - state.setName("Landscape with keyboard"); - state.setDescription("The device in landscape orientation with a keyboard open"); - state.setOrientation(ScreenOrientation.LANDSCAPE); - if (mHardware.getNav().equals(Navigation.NONAV) - || !mLandscapeKeysNav.getSelection()) { - state.setNavState(NavigationState.HIDDEN); - } else { - state.setNavState(NavigationState.EXPOSED); - } - state.setKeyState(KeyboardState.EXPOSED); - state.setHardware(mHardware); - if (!defaultSelected) { - state.setDefaultState(true); - defaultSelected = true; - } - builder.addState(state); - } - } - Device d = builder.build(); - if (mForceCreation.isEnabled() && mForceCreation.getSelection()) { - mManager.replaceUserDevice(d); - } else { - mManager.addUserDevice(d); - } - mManager.saveUserDevices(); - super.okPressed(); - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/HardwarePropertyChooser.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/HardwarePropertyChooser.java deleted file mode 100644 index a07768c..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/HardwarePropertyChooser.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty; -import com.android.sdklib.internal.avd.HardwareProperties.HardwarePropertyType; -import com.android.sdkuilib.ui.GridDialog; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.TreeSet; - -/** - * Dialog to choose a hardware property - */ -class HardwarePropertyChooser extends GridDialog { - - private final Map<String, HardwareProperty> mProperties; - private final Collection<String> mExceptProperties; - private HardwareProperty mChosenProperty; - private Label mTypeLabel; - private Label mDescriptionLabel; - - HardwarePropertyChooser(Shell parentShell, - Map<String, HardwareProperty> properties, - Collection<String> exceptProperties) { - super(parentShell, 2, false); - mProperties = properties; - mExceptProperties = exceptProperties; - } - - public HardwareProperty getProperty() { - return mChosenProperty; - } - - @Override - public void createDialogContent(Composite parent) { - Label l = new Label(parent, SWT.NONE); - l.setText("Property:"); - - final Combo c = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); - // simple list for index->name resolution. - final ArrayList<String> indexToName = new ArrayList<String>(); - - // Sort the combo entries by display name if available, otherwise by hardware name. - Set<Entry<String, HardwareProperty>> entries = - new TreeSet<Map.Entry<String,HardwareProperty>>( - new Comparator<Map.Entry<String,HardwareProperty>>() { - @Override - public int compare(Entry<String, HardwareProperty> entry0, - Entry<String, HardwareProperty> entry1) { - String s0 = entry0.getValue().getAbstract(); - String s1 = entry1.getValue().getAbstract(); - if (s0 != null && s1 != null) { - return s0.compareTo(s1); - } - return entry0.getKey().compareTo(entry1.getKey()); - } - }); - entries.addAll(mProperties.entrySet()); - - for (Entry<String, HardwareProperty> entry : entries) { - if (entry.getValue().isValidForUi() && - mExceptProperties.contains(entry.getKey()) == false) { - c.add(entry.getValue().getAbstract()); - indexToName.add(entry.getKey()); - } - } - boolean hasValues = true; - if (indexToName.size() == 0) { - hasValues = false; - c.add("No properties"); - c.select(0); - c.setEnabled(false); - } - - c.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - int index = c.getSelectionIndex(); - String name = indexToName.get(index); - processSelection(name, true /* pack */); - } - }); - - l = new Label(parent, SWT.NONE); - l.setText("Type:"); - - mTypeLabel = new Label(parent, SWT.NONE); - - l = new Label(parent, SWT.NONE); - l.setText("Description:"); - - mDescriptionLabel = new Label(parent, SWT.NONE); - - if (hasValues) { - c.select(0); - processSelection(indexToName.get(0), false /* pack */); - } - } - - private void processSelection(String name, boolean pack) { - mChosenProperty = name == null ? null : mProperties.get(name); - - String type = "Unknown"; - String desc = "Unknown"; - - if (mChosenProperty != null) { - desc = mChosenProperty.getDescription(); - HardwarePropertyType vt = mChosenProperty.getType(); - if (vt != null) { - type = vt.getName(); - } - } - - mTypeLabel.setText(type); - mDescriptionLabel.setText(desc); - - if (pack) { - getShell().pack(); - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ImgDisabledButton.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ImgDisabledButton.java deleted file mode 100755 index 62973a4..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ImgDisabledButton.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; - -/** - * A label that can display 2 images depending on its enabled/disabled state. - * This acts as a button by firing the {@link SWT#Selection} listener. - */ -public class ImgDisabledButton extends ToggleButton { - public ImgDisabledButton( - Composite parent, - int style, - Image imageEnabled, - Image imageDisabled, - String tooltipEnabled, - String tooltipDisabled) { - super(parent, - style, - imageEnabled, - imageDisabled, - tooltipEnabled, - tooltipDisabled); - } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - updateImageAndTooltip(); - redraw(); - } - - @Override - public void setState(int state) { - throw new UnsupportedOperationException(); // not available for this type of button - } - - @Override - public int getState() { - return (isDisposed() || !isEnabled()) ? 1 : 0; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/LegacyAvdEditDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/LegacyAvdEditDialog.java deleted file mode 100644 index 91f45c8..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/LegacyAvdEditDialog.java +++ /dev/null @@ -1,1425 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.SdkConstants; -import com.android.io.FileWrapper; -import com.android.prefs.AndroidLocation.AndroidLocationException; -import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.ISystemImage; -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.avd.AvdInfo; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.avd.AvdManager.AvdConflict; -import com.android.sdklib.internal.avd.HardwareProperties; -import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty; -import com.android.sdklib.internal.project.ProjectProperties; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.sdkuilib.ui.GridDialog; -import com.android.utils.ILogger; -import com.android.utils.Pair; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.viewers.CellEditor; -import org.eclipse.jface.viewers.CellLabelProvider; -import org.eclipse.jface.viewers.ComboBoxCellEditor; -import org.eclipse.jface.viewers.EditingSupport; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.ISelectionChangedListener; -import org.eclipse.jface.viewers.IStructuredContentProvider; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.SelectionChangedEvent; -import org.eclipse.jface.viewers.TableViewer; -import org.eclipse.jface.viewers.TableViewerColumn; -import org.eclipse.jface.viewers.TextCellEditor; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Group; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.Text; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; -import java.util.regex.Matcher; - -/** - * AVD creation or edit dialog. - * - * TODO: - * - use SdkTargetSelector instead of Combo - * - tooltips on widgets. - * - */ -final class LegacyAvdEditDialog extends GridDialog { - - private final AvdManager mAvdManager; - private final TreeMap<String, IAndroidTarget> mCurrentTargets = - new TreeMap<String, IAndroidTarget>(); - - private final Map<String, HardwareProperty> mHardwareMap; - private final Map<String, String> mProperties = new HashMap<String, String>(); - // a list of user-edited properties. - private final ArrayList<String> mEditedProperties = new ArrayList<String>(); - private final ImageFactory mImageFactory; - private final ILogger mSdkLog; - /** - * The original AvdInfo if we're editing an existing AVD. - * Null when we're creating a new AVD. - */ - private final AvdInfo mEditAvdInfo; - - private Text mAvdName; - private Combo mTargetCombo; - - private Combo mAbiTypeCombo; - private String mAbiType; - - private Button mSdCardSizeRadio; - private Text mSdCardSize; - private Combo mSdCardSizeCombo; - - private Text mSdCardFile; - private Button mBrowseSdCard; - private Button mSdCardFileRadio; - - private Button mSnapshotCheck; - - private Button mSkinListRadio; - private Combo mSkinCombo; - - private Button mSkinSizeRadio; - private Text mSkinSizeWidth; - private Text mSkinSizeHeight; - - private TableViewer mHardwareViewer; - private Button mDeleteHardwareProp; - - private Button mForceCreation; - private Button mOkButton; - private Label mStatusIcon; - private Label mStatusLabel; - private Composite mStatusComposite; - - /** - * {@link VerifyListener} for {@link Text} widgets that should only contains numbers. - */ - private final VerifyListener mDigitVerifier = new VerifyListener() { - @Override - public void verifyText(VerifyEvent event) { - int count = event.text.length(); - for (int i = 0 ; i < count ; i++) { - char c = event.text.charAt(i); - if (c < '0' || c > '9') { - event.doit = false; - return; - } - } - } - }; - - /** - * Callback when the AVD name is changed. - * When creating a new AVD, enables the force checkbox if the name is a duplicate. - * When editing an existing AVD, it's OK for the name to match the existing AVD. - */ - private class CreateNameModifyListener implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - String name = mAvdName.getText().trim(); - if (mEditAvdInfo == null || !name.equals(mEditAvdInfo.getName())) { - // Case where we're creating a new AVD or editing an existing one - // and the AVD name has been changed... check for name uniqueness. - - Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(name); - if (conflict.getFirst() != AvdManager.AvdConflict.NO_CONFLICT) { - // If we're changing the state from disabled to enabled, make sure - // to uncheck the button, to force the user to voluntarily re-enforce it. - // This happens when editing an existing AVD and changing the name from - // the existing AVD to another different existing AVD. - if (!mForceCreation.isEnabled()) { - mForceCreation.setEnabled(true); - mForceCreation.setSelection(false); - } - } else { - mForceCreation.setEnabled(false); - mForceCreation.setSelection(false); - } - } else { - // Case where we're editing an existing AVD with the name unchanged. - - mForceCreation.setEnabled(false); - mForceCreation.setSelection(false); - } - validatePage(); - } - } - - /** - * {@link ModifyListener} used for live-validation of the fields content. - */ - private class ValidateListener extends SelectionAdapter implements ModifyListener { - @Override - public void modifyText(ModifyEvent e) { - validatePage(); - } - - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - validatePage(); - } - } - - /** - * Creates the dialog. Caller should then use {@link Window#open()} and - * refresh if the status is {@link Window#OK}. - * - * @param parentShell The parent shell. - * @param avdManager The existing {@link AvdManager} to use. Must not be null. - * @param imageFactory An existing {@link ImageFactory} to use. Must not be null. - * @param log An existing {@link ILogger} where output will go. Must not be null. - * @param editAvdInfo An optional {@link AvdInfo}. When null, the dialog is used - * to create a new AVD. When non-null, the dialog is used to <em>edit</em> this AVD. - */ - protected LegacyAvdEditDialog(Shell parentShell, - AvdManager avdManager, - ImageFactory imageFactory, - ILogger log, - AvdInfo editAvdInfo) { - super(parentShell, 2, false); - mAvdManager = avdManager; - mImageFactory = imageFactory; - mSdkLog = log; - mEditAvdInfo = editAvdInfo; - - File hardwareDefs = null; - - SdkManager sdkMan = avdManager.getSdkManager(); - if (sdkMan != null) { - String sdkPath = sdkMan.getLocation(); - if (sdkPath != null) { - hardwareDefs = new File (sdkPath + File.separator + - SdkConstants.OS_SDK_TOOLS_LIB_FOLDER, SdkConstants.FN_HARDWARE_INI); - } - } - - if (hardwareDefs == null) { - log.error(null, "Failed to load file %s from SDK", SdkConstants.FN_HARDWARE_INI); - mHardwareMap = new HashMap<String, HardwareProperty>(); - } else { - mHardwareMap = HardwareProperties.parseHardwareDefinitions( - hardwareDefs, null /*sdkLog*/); - } - } - - @Override - public void create() { - super.create(); - - Point p = getShell().getSize(); - if (p.x < 400) { - p.x = 400; - } - getShell().setSize(p); - } - - @Override - protected Control createContents(Composite parent) { - Control control = super.createContents(parent); - getShell().setText(mEditAvdInfo == null ? "Create new Android Virtual Device (AVD)" - : "Edit Android Virtual Device (AVD)"); - - mOkButton = getButton(IDialogConstants.OK_ID); - - fillExistingAvdInfo(); - validatePage(); - - return control; - } - - @Override - public void createDialogContent(final Composite parent) { - GridData gd; - GridLayout gl; - - Label label = new Label(parent, SWT.NONE); - label.setText("Name:"); - String tooltip = "Name of the new Android Virtual Device"; - label.setToolTipText(tooltip); - - mAvdName = new Text(parent, SWT.BORDER); - mAvdName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mAvdName.addModifyListener(new CreateNameModifyListener()); - mAvdName.setToolTipText(tooltip); - - label = new Label(parent, SWT.NONE); - label.setText("Target:"); - tooltip = "The version of Android to use in the virtual device"; - label.setToolTipText(tooltip); - - mTargetCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mTargetCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mTargetCombo.setToolTipText(tooltip); - mTargetCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - reloadSkinCombo(); - reloadAbiTypeCombo(); - validatePage(); - } - }); - - //ABI group - label = new Label(parent, SWT.NONE); - label.setText("CPU/ABI:"); - tooltip = "The CPU/ABI to use in the virtual device"; - label.setToolTipText(tooltip); - - mAbiTypeCombo = new Combo(parent, SWT.READ_ONLY | SWT.DROP_DOWN); - mAbiTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mAbiTypeCombo.setToolTipText(tooltip); - mAbiTypeCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - super.widgetSelected(e); - validatePage(); - } - }); - mAbiTypeCombo.setEnabled(false); - - // --- sd card group - label = new Label(parent, SWT.NONE); - label.setText("SD Card:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group sdCardGroup = new Group(parent, SWT.NONE); - sdCardGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - sdCardGroup.setLayout(new GridLayout(3, false)); - - mSdCardSizeRadio = new Button(sdCardGroup, SWT.RADIO); - mSdCardSizeRadio.setText("Size:"); - mSdCardSizeRadio.setToolTipText("Create a new SD Card file"); - mSdCardSizeRadio.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - boolean sizeMode = mSdCardSizeRadio.getSelection(); - enableSdCardWidgets(sizeMode); - validatePage(); - } - }); - - ValidateListener validateListener = new ValidateListener(); - - mSdCardSize = new Text(sdCardGroup, SWT.BORDER); - mSdCardSize.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSdCardSize.addVerifyListener(mDigitVerifier); - mSdCardSize.addModifyListener(validateListener); - mSdCardSize.setToolTipText("Size of the new SD Card file (must be at least 9 MiB)"); - - mSdCardSizeCombo = new Combo(sdCardGroup, SWT.DROP_DOWN | SWT.READ_ONLY); - mSdCardSizeCombo.add("KiB"); - mSdCardSizeCombo.add("MiB"); - mSdCardSizeCombo.add("GiB"); - mSdCardSizeCombo.select(1); - mSdCardSizeCombo.addSelectionListener(validateListener); - - mSdCardFileRadio = new Button(sdCardGroup, SWT.RADIO); - mSdCardFileRadio.setText("File:"); - mSdCardFileRadio.setToolTipText("Use an existing file for the SD Card"); - - mSdCardFile = new Text(sdCardGroup, SWT.BORDER); - mSdCardFile.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSdCardFile.addModifyListener(validateListener); - mSdCardFile.setToolTipText("File to use for the SD Card"); - - mBrowseSdCard = new Button(sdCardGroup, SWT.PUSH); - mBrowseSdCard.setText("Browse..."); - mBrowseSdCard.setToolTipText("Select the file to use for the SD Card"); - mBrowseSdCard.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - onBrowseSdCard(); - validatePage(); - } - }); - - mSdCardSizeRadio.setSelection(true); - enableSdCardWidgets(true); - - // --- snapshot group - - label = new Label(parent, SWT.NONE); - label.setText("Snapshot:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group snapshotGroup = new Group(parent, SWT.NONE); - snapshotGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - snapshotGroup.setLayout(new GridLayout(3, false)); - - mSnapshotCheck = new Button(snapshotGroup, SWT.CHECK); - mSnapshotCheck.setText("Enabled"); - mSnapshotCheck.setToolTipText( - "Emulator's state will be persisted between emulator executions"); - - // --- skin group - label = new Label(parent, SWT.NONE); - label.setText("Skin:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group skinGroup = new Group(parent, SWT.NONE); - skinGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - skinGroup.setLayout(new GridLayout(4, false)); - - mSkinListRadio = new Button(skinGroup, SWT.RADIO); - mSkinListRadio.setText("Built-in:"); - mSkinListRadio.setToolTipText("Select an emulated screen size provided by the current Android target"); - mSkinListRadio.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - boolean listMode = mSkinListRadio.getSelection(); - enableSkinWidgets(listMode); - validatePage(); - } - }); - - mSkinCombo = new Combo(skinGroup, SWT.READ_ONLY | SWT.DROP_DOWN); - mSkinCombo.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); - gd.horizontalSpan = 3; - mSkinCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - // get the skin info - loadSkin(); - } - }); - - mSkinSizeRadio = new Button(skinGroup, SWT.RADIO); - mSkinSizeRadio.setText("Resolution:"); - mSkinSizeRadio.setToolTipText("Select a custom emulated screen size"); - - mSkinSizeWidth = new Text(skinGroup, SWT.BORDER); - mSkinSizeWidth.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSkinSizeWidth.addVerifyListener(mDigitVerifier); - mSkinSizeWidth.addModifyListener(validateListener); - mSkinSizeWidth.setToolTipText("Width in pixels of the emulated screen size"); - - new Label(skinGroup, SWT.NONE).setText("x"); - - mSkinSizeHeight = new Text(skinGroup, SWT.BORDER); - mSkinSizeHeight.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mSkinSizeHeight.addVerifyListener(mDigitVerifier); - mSkinSizeHeight.addModifyListener(validateListener); - mSkinSizeHeight.setToolTipText("Height in pixels of the emulated screen size"); - - mSkinListRadio.setSelection(true); - enableSkinWidgets(true); - - // --- hardware group - label = new Label(parent, SWT.NONE); - label.setText("Hardware:"); - label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - - final Group hwGroup = new Group(parent, SWT.NONE); - hwGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - hwGroup.setLayout(new GridLayout(2, false)); - - createHardwareTable(hwGroup); - - // composite for the side buttons - Composite hwButtons = new Composite(hwGroup, SWT.NONE); - hwButtons.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - hwButtons.setLayout(gl = new GridLayout(1, false)); - gl.marginHeight = gl.marginWidth = 0; - - Button b = new Button(hwButtons, SWT.PUSH | SWT.FLAT); - b.setText("New..."); - b.setToolTipText("Add a new hardware property"); - b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - b.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent event) { - HardwarePropertyChooser dialog = new HardwarePropertyChooser(parent.getShell(), - mHardwareMap, mProperties.keySet()); - if (dialog.open() == Window.OK) { - HardwareProperty choice = dialog.getProperty(); - if (choice != null) { - mProperties.put(choice.getName(), choice.getDefault()); - mHardwareViewer.refresh(); - } - } - } - }); - mDeleteHardwareProp = new Button(hwButtons, SWT.PUSH | SWT.FLAT); - mDeleteHardwareProp.setText("Delete"); - mDeleteHardwareProp.setToolTipText("Delete the selected hardware property"); - mDeleteHardwareProp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mDeleteHardwareProp.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - ISelection selection = mHardwareViewer.getSelection(); - if (selection instanceof IStructuredSelection) { - String hwName = (String)((IStructuredSelection)selection).getFirstElement(); - mProperties.remove(hwName); - mHardwareViewer.refresh(); - } - } - }); - mDeleteHardwareProp.setEnabled(false); - - // --- end hardware group - - mForceCreation = new Button(parent, SWT.CHECK); - mForceCreation.setText("Override the existing AVD with the same name"); - mForceCreation.setToolTipText("There's already an AVD with the same name. Check this to delete it and replace it by the new AVD."); - mForceCreation.setLayoutData(new GridData(GridData.BEGINNING, GridData.CENTER, - true, false, 2, 1)); - mForceCreation.setEnabled(false); - mForceCreation.addSelectionListener(validateListener); - - // add a separator to separate from the ok/cancel button - label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - label.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 3, 1)); - - // add stuff for the error display - mStatusComposite = new Composite(parent, SWT.NONE); - mStatusComposite.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, - true, false, 3, 1)); - mStatusComposite.setLayout(gl = new GridLayout(2, false)); - gl.marginHeight = gl.marginWidth = 0; - - mStatusIcon = new Label(mStatusComposite, SWT.NONE); - mStatusIcon.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, - false, false)); - mStatusLabel = new Label(mStatusComposite, SWT.NONE); - mStatusLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mStatusLabel.setText(" \n "); //$NON-NLS-1$ - - reloadTargetCombo(); - } - - /** - * Creates the UI for the hardware properties table. - * This creates the {@link Table}, and several viewers ({@link TableViewer}, - * {@link TableViewerColumn}) and adds edit support for the 2nd column - */ - private void createHardwareTable(Composite parent) { - final Table hardwareTable = new Table(parent, SWT.SINGLE | SWT.FULL_SELECTION); - GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); - gd.widthHint = 200; - gd.heightHint = 100; - hardwareTable.setLayoutData(gd); - hardwareTable.setHeaderVisible(true); - hardwareTable.setLinesVisible(true); - - // -- Table viewer - mHardwareViewer = new TableViewer(hardwareTable); - mHardwareViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - // it's a single selection mode, we can just access the selection index - // from the table directly. - mDeleteHardwareProp.setEnabled(hardwareTable.getSelectionIndex() != -1); - } - }); - - // only a content provider. Use viewers per column below (for editing support) - mHardwareViewer.setContentProvider(new IStructuredContentProvider() { - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - // we can just ignore this. we just use mProperties directly. - } - - @Override - public Object[] getElements(Object arg0) { - return mProperties.keySet().toArray(); - } - - @Override - public void dispose() { - // pass - } - }); - - // -- column 1: prop abstract name - TableColumn col1 = new TableColumn(hardwareTable, SWT.LEFT); - col1.setText("Property"); - col1.setWidth(150); - TableViewerColumn tvc1 = new TableViewerColumn(mHardwareViewer, col1); - tvc1.setLabelProvider(new CellLabelProvider() { - @Override - public void update(ViewerCell cell) { - String name = cell.getElement().toString(); - HardwareProperty prop = mHardwareMap.get(name); - if (prop != null) { - cell.setText(prop.getAbstract()); - } else { - cell.setText(String.format("%1$s (Unknown)", name)); - } - } - }); - - // -- column 2: prop value - TableColumn col2 = new TableColumn(hardwareTable, SWT.LEFT); - col2.setText("Value"); - col2.setWidth(50); - TableViewerColumn tvc2 = new TableViewerColumn(mHardwareViewer, col2); - tvc2.setLabelProvider(new CellLabelProvider() { - @Override - public void update(ViewerCell cell) { - String value = mProperties.get(cell.getElement()); - cell.setText(value != null ? value : ""); - } - }); - - // add editing support to the 2nd column - tvc2.setEditingSupport(new EditingSupport(mHardwareViewer) { - @Override - protected void setValue(Object element, Object value) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - int index; - switch (property.getType()) { - case INTEGER: - mProperties.put((String)element, (String)value); - break; - case DISKSIZE: - if (HardwareProperties.DISKSIZE_PATTERN.matcher((String)value).matches()) { - mProperties.put((String)element, (String)value); - } - break; - case BOOLEAN: - index = (Integer)value; - mProperties.put((String)element, HardwareProperties.BOOLEAN_VALUES[index]); - break; - case STRING_ENUM: - case INTEGER_ENUM: - // For a combo, value is the index of the enum to use. - index = (Integer)value; - String[] values = property.getEnum(); - if (values != null && values.length > index) { - mProperties.put((String)element, values[index]); - } - break; - } - mHardwareViewer.refresh(element); - } - - @Override - protected Object getValue(Object element) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - String value = mProperties.get(hardwareName); - switch (property.getType()) { - case INTEGER: - // intended fall-through. - case DISKSIZE: - return value; - case BOOLEAN: - return HardwareProperties.getBooleanValueIndex(value); - case STRING_ENUM: - case INTEGER_ENUM: - // For a combo, we need to return the index of the value in the enum - String[] values = property.getEnum(); - if (values != null) { - for (int i = 0; i < values.length; i++) { - if (values[i].equals(value)) { - return i; - } - } - } - } - - return null; - } - - @Override - protected CellEditor getCellEditor(Object element) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - switch (property.getType()) { - // TODO: custom TextCellEditor that restrict input. - case INTEGER: - // intended fall-through. - case DISKSIZE: - return new TextCellEditor(hardwareTable); - case BOOLEAN: - return new ComboBoxCellEditor(hardwareTable, - HardwareProperties.BOOLEAN_VALUES, - SWT.READ_ONLY | SWT.DROP_DOWN); - case STRING_ENUM: - case INTEGER_ENUM: - String[] values = property.getEnum(); - if (values != null && values.length > 0) { - return new ComboBoxCellEditor(hardwareTable, - values, - SWT.READ_ONLY | SWT.DROP_DOWN); - } - } - return null; - } - - @Override - protected boolean canEdit(Object element) { - String hardwareName = (String)element; - HardwareProperty property = mHardwareMap.get(hardwareName); - return property != null; - } - }); - - - mHardwareViewer.setInput(mProperties); - } - - // -- Start of internal part ---------- - // Hide everything down-below from SWT designer - //$hide>>$ - - /** - * When editing an existing AVD info, fill the UI that has just been created with - * the values from the AVD. - */ - public void fillExistingAvdInfo() { - if (mEditAvdInfo == null) { - return; - } - - mAvdName.setText(mEditAvdInfo.getName()); - - Map<String, String> props = mEditAvdInfo.getProperties(); - - IAndroidTarget target = mEditAvdInfo.getTarget(); - if (target != null && !mCurrentTargets.isEmpty()) { - // Try to select the target in the target combo. - // This will fail if the AVD needs to be repaired. - // - // This is a linear search but the list is always - // small enough and we only do this once. - int n = mTargetCombo.getItemCount(); - for (int i = 0;i < n; i++) { - if (target.equals(mCurrentTargets.get(mTargetCombo.getItem(i)))) { - mTargetCombo.select(i); - reloadAbiTypeCombo(); - reloadSkinCombo(); - break; - } - } - } - - // select the abi type - ISystemImage[] systemImages = getSystemImages(target); - if (target != null && systemImages.length > 0) { - mAbiTypeCombo.setEnabled(systemImages.length > 1); - String abiType = AvdInfo.getPrettyAbiType(mEditAvdInfo.getAbiType()); - int n = mAbiTypeCombo.getItemCount(); - for (int i = 0; i < n; i++) { - if (abiType.equals(mAbiTypeCombo.getItem(i))) { - mAbiTypeCombo.select(i); - reloadSkinCombo(); - break; - } - } - } - - if (props != null) { - - // First try the skin name and if it doesn't work fallback on the skin path - nextSkin: for (int s = 0; s < 2; s++) { - String skin = props.get(s == 0 ? AvdManager.AVD_INI_SKIN_NAME - : AvdManager.AVD_INI_SKIN_PATH); - if (skin != null && skin.length() > 0) { - Matcher m = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin); - if (m.matches() && m.groupCount() == 2) { - enableSkinWidgets(false); - mSkinListRadio.setSelection(false); - mSkinSizeRadio.setSelection(true); - mSkinSizeWidth.setText(m.group(1)); - mSkinSizeHeight.setText(m.group(2)); - break nextSkin; - } else { - enableSkinWidgets(true); - mSkinSizeRadio.setSelection(false); - mSkinListRadio.setSelection(true); - - int n = mSkinCombo.getItemCount(); - for (int i = 0; i < n; i++) { - if (skin.equals(mSkinCombo.getItem(i))) { - mSkinCombo.select(i); - break nextSkin; - } - } - } - } - } - - String sdcard = props.get(AvdManager.AVD_INI_SDCARD_PATH); - if (sdcard != null && sdcard.length() > 0) { - enableSdCardWidgets(false); - mSdCardSizeRadio.setSelection(false); - mSdCardFileRadio.setSelection(true); - mSdCardFile.setText(sdcard); - } - - sdcard = props.get(AvdManager.AVD_INI_SDCARD_SIZE); - if (sdcard != null && sdcard.length() > 0) { - String[] values = new String[2]; - long sdcardSize = AvdManager.parseSdcardSize(sdcard, values); - - if (sdcardSize != AvdManager.SDCARD_NOT_SIZE_PATTERN) { - enableSdCardWidgets(true); - mSdCardFileRadio.setSelection(false); - mSdCardSizeRadio.setSelection(true); - - mSdCardSize.setText(values[0]); - - String suffix = values[1]; - int n = mSdCardSizeCombo.getItemCount(); - for (int i = 0; i < n; i++) { - if (mSdCardSizeCombo.getItem(i).startsWith(suffix)) { - mSdCardSizeCombo.select(i); - } - } - } - } - - String snapshots = props.get(AvdManager.AVD_INI_SNAPSHOT_PRESENT); - if (snapshots != null && snapshots.length() > 0) { - mSnapshotCheck.setSelection(snapshots.equals("true")); - } - } - - mProperties.clear(); - - if (props != null) { - for (Entry<String, String> entry : props.entrySet()) { - HardwareProperty prop = mHardwareMap.get(entry.getKey()); - if (prop != null && prop.isValidForUi()) { - mProperties.put(entry.getKey(), entry.getValue()); - } - } - } - - // Cleanup known non-hardware properties - mProperties.remove(AvdManager.AVD_INI_ABI_TYPE); - mProperties.remove(AvdManager.AVD_INI_CPU_ARCH); - mProperties.remove(AvdManager.AVD_INI_SKIN_PATH); - mProperties.remove(AvdManager.AVD_INI_SKIN_NAME); - mProperties.remove(AvdManager.AVD_INI_SDCARD_SIZE); - mProperties.remove(AvdManager.AVD_INI_SDCARD_PATH); - mProperties.remove(AvdManager.AVD_INI_SNAPSHOT_PRESENT); - mProperties.remove(AvdManager.AVD_INI_IMAGES_1); - mProperties.remove(AvdManager.AVD_INI_IMAGES_2); - - mHardwareViewer.refresh(); - } - - @Override - protected void okPressed() { - if (createAvd()) { - super.okPressed(); - } - } - - /** - * Enable or disable the sd card widgets. - * @param sizeMode if true the size-based widgets are to be enabled, and the file-based ones - * disabled. - */ - private void enableSdCardWidgets(boolean sizeMode) { - mSdCardSize.setEnabled(sizeMode); - mSdCardSizeCombo.setEnabled(sizeMode); - - mSdCardFile.setEnabled(!sizeMode); - mBrowseSdCard.setEnabled(!sizeMode); - } - - /** - * Enable or disable the skin widgets. - * @param listMode if true the list-based widgets are to be enabled, and the size-based ones - * disabled. - */ - private void enableSkinWidgets(boolean listMode) { - mSkinCombo.setEnabled(listMode); - - mSkinSizeWidth.setEnabled(!listMode); - mSkinSizeHeight.setEnabled(!listMode); - } - - - private void onBrowseSdCard() { - FileDialog dlg = new FileDialog(getContents().getShell(), SWT.OPEN); - dlg.setText("Choose SD Card image file."); - - String fileName = dlg.open(); - if (fileName != null) { - mSdCardFile.setText(fileName); - } - } - - - - private void reloadTargetCombo() { - String selected = null; - int index = mTargetCombo.getSelectionIndex(); - if (index >= 0) { - selected = mTargetCombo.getItem(index); - } - - mCurrentTargets.clear(); - mTargetCombo.removeAll(); - - boolean found = false; - index = -1; - - SdkManager sdkManager = mAvdManager.getSdkManager(); - if (sdkManager != null) { - for (IAndroidTarget target : sdkManager.getTargets()) { - String name; - if (target.isPlatform()) { - name = String.format("%s - API Level %s", - target.getName(), - target.getVersion().getApiString()); - } else { - name = String.format("%s (%s) - API Level %s", - target.getName(), - target.getVendor(), - target.getVersion().getApiString()); - } - mCurrentTargets.put(name, target); - mTargetCombo.add(name); - if (!found) { - index++; - found = name.equals(selected); - } - } - } - - mTargetCombo.setEnabled(mCurrentTargets.size() > 0); - - if (found) { - mTargetCombo.select(index); - } - - reloadSkinCombo(); - } - - private void reloadSkinCombo() { - String selected = null; - int index = mSkinCombo.getSelectionIndex(); - if (index >= 0) { - selected = mSkinCombo.getItem(index); - } - - mSkinCombo.removeAll(); - mSkinCombo.setEnabled(false); - - index = mTargetCombo.getSelectionIndex(); - if (index >= 0) { - - String targetName = mTargetCombo.getItem(index); - - boolean found = false; - IAndroidTarget target = mCurrentTargets.get(targetName); - if (target != null) { - mSkinCombo.add(String.format("Default (%s)", target.getDefaultSkin())); - - index = -1; - for (String skin : target.getSkins()) { - mSkinCombo.add(skin); - if (!found) { - index++; - found = skin.equals(selected); - } - } - - mSkinCombo.setEnabled(true); - - if (found) { - mSkinCombo.select(index); - } else { - mSkinCombo.select(0); // default - loadSkin(); - } - } - } - } - - /** - * Reload all the abi types in the selection list - */ - private void reloadAbiTypeCombo() { - String selected = null; - boolean found = false; - - int index = mTargetCombo.getSelectionIndex(); - if (index >= 0) { - String targetName = mTargetCombo.getItem(index); - IAndroidTarget target = mCurrentTargets.get(targetName); - - ISystemImage[] systemImages = getSystemImages(target); - - mAbiTypeCombo.setEnabled(systemImages.length > 1); - - // If user explicitly selected an ABI before, preserve that option - // If user did not explicitly select before (only one option before) - // force them to select - index = mAbiTypeCombo.getSelectionIndex(); - if (index >= 0 && mAbiTypeCombo.getItemCount() > 1) { - selected = mAbiTypeCombo.getItem(index); - } - - mAbiTypeCombo.removeAll(); - - int i; - for ( i = 0; i < systemImages.length ; i++ ) { - String prettyAbiType = AvdInfo.getPrettyAbiType(systemImages[i].getAbiType()); - mAbiTypeCombo.add(prettyAbiType); - if (!found) { - found = prettyAbiType.equals(selected); - if (found) { - mAbiTypeCombo.select(i); - } - } - } - - if (systemImages.length == 1) { - mAbiTypeCombo.select(0); - } - } - } - - /** - * Validates the fields, displays errors and warnings. - * Enables the finish button if there are no errors. - */ - private void validatePage() { - String error = null; - String warning = null; - - // Validate AVD name - String avdName = mAvdName.getText().trim(); - boolean hasAvdName = avdName.length() > 0; - boolean isCreate = mEditAvdInfo == null || !avdName.equals(mEditAvdInfo.getName()); - - if (hasAvdName && !AvdManager.RE_AVD_NAME.matcher(avdName).matches()) { - error = String.format( - "AVD name '%1$s' contains invalid characters.\nAllowed characters are: %2$s", - avdName, AvdManager.CHARS_AVD_NAME); - } - - // Validate target - if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() < 0) { - error = "A target must be selected in order to create an AVD."; - } - - // validate abi type if the selected target supports multi archs. - if (hasAvdName && error == null && mTargetCombo.getSelectionIndex() > 0) { - int index = mTargetCombo.getSelectionIndex(); - String targetName = mTargetCombo.getItem(index); - IAndroidTarget target = mCurrentTargets.get(targetName); - ISystemImage[] systemImages = getSystemImages(target); - if (systemImages.length > 1 && mAbiTypeCombo.getSelectionIndex() < 0) { - error = "An ABI type must be selected in order to create an AVD."; - } - } - - // Validate SDCard path or value - if (error == null) { - // get the mode. We only need to check the file since the - // verifier on the size Text will prevent invalid input - boolean sdcardFileMode = mSdCardFileRadio.getSelection(); - if (sdcardFileMode) { - String sdName = mSdCardFile.getText().trim(); - if (sdName.length() > 0 && !new File(sdName).isFile()) { - error = "SD Card path isn't valid."; - } - } else { - String valueString = mSdCardSize.getText(); - if (valueString.length() > 0) { - long value = 0; - try { - value = Long.parseLong(valueString); - - int sizeIndex = mSdCardSizeCombo.getSelectionIndex(); - if (sizeIndex >= 0) { - // index 0 shifts by 10 (1024=K), index 1 by 20, etc. - value <<= 10*(1 + sizeIndex); - } - - if (value < AvdManager.SDCARD_MIN_BYTE_SIZE || - value > AvdManager.SDCARD_MAX_BYTE_SIZE) { - value = 0; - } - } catch (Exception e) { - // ignore, we'll test value below. - } - if (value <= 0) { - error = "SD Card size is invalid. Range is 9 MiB..1023 GiB."; - } else if (mEditAvdInfo != null) { - // When editing an existing AVD, compare with the existing - // sdcard size, if any. It only matters if there was an sdcard setting - // before. - Map<String, String> props = mEditAvdInfo.getProperties(); - if (props != null) { - String original = - mEditAvdInfo.getProperties().get(AvdManager.AVD_INI_SDCARD_SIZE); - if (original != null && original.length() > 0) { - long originalSize = - AvdManager.parseSdcardSize(original, null/*parsedStrings*/); - if (originalSize > 0 && value != originalSize) { - warning = "A new SD Card file will be created.\nThe current SD Card file will be lost."; - } - } - } - } - } - } - } - - // validate the skin - if (error == null) { - // get the mode, we should only check if it's in size mode since - // the built-in list mode is always valid. - if (mSkinSizeRadio.getSelection()) { - // need both with and heigh to be non null - String width = mSkinSizeWidth.getText(); // no need for trim, since the verifier - String height = mSkinSizeHeight.getText(); // rejects non digit. - - if (width.length() == 0 || height.length() == 0) { - error = "Skin size is incorrect.\nBoth dimensions must be > 0."; - } - } - } - - // Check for duplicate AVD name - if (isCreate && hasAvdName && error == null && !mForceCreation.getSelection()) { - Pair<AvdConflict, String> conflict = mAvdManager.isAvdNameConflicting(avdName); - assert conflict != null; - switch(conflict.getFirst()) { - case NO_CONFLICT: - break; - case CONFLICT_EXISTING_AVD: - case CONFLICT_INVALID_AVD: - error = String.format( - "The AVD name '%s' is already used.\n" + - "Check \"Override the existing AVD\" to delete the existing one.", - avdName); - break; - case CONFLICT_EXISTING_PATH: - error = String.format( - "Conflict with %s\n" + - "Check \"Override the existing AVD\" to delete the existing one.", - conflict.getSecond()); - break; - default: - // Hmm not supposed to happen... probably someone expanded the - // enum without adding something here. In this case just do an - // assert and use a generic error message. - error = String.format( - "Conflict %s with %s.\n" + - "Check \"Override the existing AVD\" to delete the existing one.", - conflict.getFirst().toString(), - conflict.getSecond()); - assert false; - break; - } - } - - if (error == null && mEditAvdInfo != null && isCreate) { - warning = String.format("The AVD '%1$s' will be duplicated into '%2$s'.", - mEditAvdInfo.getName(), - avdName); - } - - // Validate the create button - boolean can_create = hasAvdName && error == null; - if (can_create) { - can_create &= mTargetCombo.getSelectionIndex() >= 0; - } - mOkButton.setEnabled(can_create); - - // Adjust the create button label as needed - if (isCreate) { - mOkButton.setText("Create AVD"); - } else { - mOkButton.setText("Edit AVD"); - } - - // -- update UI - if (error != null) { - mStatusIcon.setImage(mImageFactory.getImageByName("reject_icon16.png")); //$NON-NLS-1$ - mStatusLabel.setText(error); - } else if (warning != null) { - mStatusIcon.setImage(mImageFactory.getImageByName("warning_icon16.png")); //$NON-NLS-1$ - mStatusLabel.setText(warning); - } else { - mStatusIcon.setImage(null); - mStatusLabel.setText(" \n "); //$NON-NLS-1$ - } - - mStatusComposite.pack(true); - } - - private void loadSkin() { - int targetIndex = mTargetCombo.getSelectionIndex(); - if (targetIndex < 0) { - return; - } - - // resolve the target. - String targetName = mTargetCombo.getItem(targetIndex); - IAndroidTarget target = mCurrentTargets.get(targetName); - if (target == null) { - return; - } - - // get the skin name - String skinName = null; - int skinIndex = mSkinCombo.getSelectionIndex(); - if (skinIndex < 0) { - return; - } else if (skinIndex == 0) { // default skin for the target - skinName = target.getDefaultSkin(); - } else { - skinName = mSkinCombo.getItem(skinIndex); - } - - // load the skin properties - String path = target.getPath(IAndroidTarget.SKINS); - File skin = new File(path, skinName); - if (skin.isDirectory() == false && target.isPlatform() == false) { - // it's possible the skin is in the parent target - path = target.getParent().getPath(IAndroidTarget.SKINS); - skin = new File(path, skinName); - } - - if (skin.isDirectory() == false) { - return; - } - - // now get the hardware.ini from the add-on (if applicable) and from the skin - // (if applicable) - HashMap<String, String> hardwareValues = new HashMap<String, String>(); - if (target.isPlatform() == false) { - FileWrapper targetHardwareFile = new FileWrapper(target.getLocation(), - AvdManager.HARDWARE_INI); - if (targetHardwareFile.isFile()) { - Map<String, String> targetHardwareConfig = ProjectProperties.parsePropertyFile( - targetHardwareFile, null /*log*/); - - if (targetHardwareConfig != null) { - hardwareValues.putAll(targetHardwareConfig); - } - } - } - - // from the skin - FileWrapper skinHardwareFile = new FileWrapper(skin, AvdManager.HARDWARE_INI); - if (skinHardwareFile.isFile()) { - Map<String, String> skinHardwareConfig = ProjectProperties.parsePropertyFile( - skinHardwareFile, null /*log*/); - - if (skinHardwareConfig != null) { - hardwareValues.putAll(skinHardwareConfig); - } - } - - // now set those values in the list of properties for the AVD. - // We just check that none of those properties have been edited by the user yet. - for (Entry<String, String> entry : hardwareValues.entrySet()) { - if (mEditedProperties.contains(entry.getKey()) == false) { - mProperties.put(entry.getKey(), entry.getValue()); - } - } - - mHardwareViewer.refresh(); - } - - /** - * Creates an AVD from the values in the UI. Called when the user presses the OK button. - */ - private boolean createAvd() { - String avdName = mAvdName.getText().trim(); - int index = mTargetCombo.getSelectionIndex(); - - // quick check on the name and the target selection - if (avdName.length() == 0 || index < 0) { - return false; - } - - // resolve the target. - String targetName = mTargetCombo.getItem(index); - IAndroidTarget target = mCurrentTargets.get(targetName); - if (target == null) { - return false; - } - - // get the abi type - mAbiType = SdkConstants.ABI_ARMEABI; - ISystemImage[] systemImages = getSystemImages(target); - if (systemImages.length > 0) { - int abiIndex = mAbiTypeCombo.getSelectionIndex(); - if (abiIndex >= 0) { - String prettyname = mAbiTypeCombo.getItem(abiIndex); - //Extract the abi type - int firstIndex = prettyname.indexOf("("); - int lastIndex = prettyname.indexOf(")"); - mAbiType = prettyname.substring(firstIndex+1, lastIndex); - } - } - - // get the SD card data from the UI. - String sdName = null; - if (mSdCardSizeRadio.getSelection()) { - // size mode - String value = mSdCardSize.getText().trim(); - if (value.length() > 0) { - sdName = value; - // add the unit - switch (mSdCardSizeCombo.getSelectionIndex()) { - case 0: - sdName += "K"; //$NON-NLS-1$ - break; - case 1: - sdName += "M"; //$NON-NLS-1$ - break; - case 2: - sdName += "G"; //$NON-NLS-1$ - break; - default: - // shouldn't be here - assert false; - } - } - } else { - // file mode. - sdName = mSdCardFile.getText().trim(); - } - - // get the Skin data from the UI - String skinName = null; - if (mSkinListRadio.getSelection()) { - // built-in list provides the skin - int skinIndex = mSkinCombo.getSelectionIndex(); - if (skinIndex > 0) { - // index 0 is the default, we don't use it - skinName = mSkinCombo.getItem(skinIndex); - } - } else { - // size mode. get both size and writes it as a skin name - // thanks to validatePage() we know the content of the fields is correct - skinName = mSkinSizeWidth.getText() + "x" + mSkinSizeHeight.getText(); //$NON-NLS-1$ - } - - ILogger log = mSdkLog; - if (log == null || log instanceof MessageBoxLog) { - // If the current logger is a message box, we use our own (to make sure - // to display errors right away and customize the title). - log = new MessageBoxLog( - String.format("Result of creating AVD '%s':", avdName), - getContents().getDisplay(), - false /*logErrorsOnly*/); - } - - File avdFolder = null; - try { - avdFolder = AvdInfo.getDefaultAvdFolder(mAvdManager, avdName); - } catch (AndroidLocationException e) { - return false; - } - - boolean force = mForceCreation.getSelection(); - boolean snapshot = mSnapshotCheck.getSelection(); - - boolean success = false; - AvdInfo avdInfo = mAvdManager.createAvd( - avdFolder, - avdName, - target, - mAbiType, - skinName, - sdName, - mProperties, - snapshot, - force, - mEditAvdInfo != null, //edit existing - log); - - success = avdInfo != null; - - if (log instanceof MessageBoxLog) { - ((MessageBoxLog) log).displayResult(success); - } - return success; - } - - /** - * Returns the list of system images of a target. - * <p/> - * If target is null, returns an empty list. - * If target is an add-on with no system images, return the list from its parent platform. - * - * @param target An IAndroidTarget. Can be null. - * @return A non-null ISystemImage array. Can be empty. - */ - private ISystemImage[] getSystemImages(IAndroidTarget target) { - if (target != null) { - ISystemImage[] images = target.getSystemImages(); - - if ((images == null || images.length == 0) && !target.isPlatform()) { - // If an add-on does not provide any system images, use the ones from the parent. - images = target.getParent().getSystemImages(); - } - - if (images != null) { - return images; - } - } - - return new ISystemImage[0]; - } - - // End of hiding from SWT Designer - //$hide<<$ -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/MessageBoxLog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/MessageBoxLog.java deleted file mode 100755 index f5b75e0..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/MessageBoxLog.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.annotations.NonNull; -import com.android.utils.ILogger; - -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -import java.util.ArrayList; - - -/** - * Collects all log and displays it in a message box dialog. - * <p/> - * This is good if only a few lines of log are expected. - * If you pass <var>logErrorsOnly</var> to the constructor, the message box - * will be shown only if errors were generated, which is the typical use-case. - * <p/> - * To use this: </br> - * - Construct a new {@link MessageBoxLog}. </br> - * - Pass the logger to the action. </br> - * - Once the action is completed, call {@link #displayResult(boolean)} - * indicating whether the operation was successful or not. - * - * When <var>logErrorsOnly</var> is true, if the operation was not successful or errors - * were generated, this will display the message box. - */ -public final class MessageBoxLog implements ILogger { - - final ArrayList<String> logMessages = new ArrayList<String>(); - private final String mMessage; - private final Display mDisplay; - private final boolean mLogErrorsOnly; - - /** - * Creates a logger that will capture all logs and eventually display them - * in a simple message box. - * - * @param message - * @param display - * @param logErrorsOnly - */ - public MessageBoxLog(String message, Display display, boolean logErrorsOnly) { - mMessage = message; - mDisplay = display; - mLogErrorsOnly = logErrorsOnly; - } - - @Override - public void error(Throwable throwable, String errorFormat, Object... arg) { - if (errorFormat != null) { - logMessages.add(String.format("Error: " + errorFormat, arg)); - } - - if (throwable != null) { - logMessages.add(throwable.getMessage()); - } - } - - @Override - public void warning(@NonNull String warningFormat, Object... arg) { - if (!mLogErrorsOnly) { - logMessages.add(String.format("Warning: " + warningFormat, arg)); - } - } - - @Override - public void info(@NonNull String msgFormat, Object... arg) { - if (!mLogErrorsOnly) { - logMessages.add(String.format(msgFormat, arg)); - } - } - - @Override - public void verbose(@NonNull String msgFormat, Object... arg) { - if (!mLogErrorsOnly) { - logMessages.add(String.format(msgFormat, arg)); - } - } - - /** - * Displays the log if anything was captured. - * <p/> - * @param success Used only when the logger was constructed with <var>logErrorsOnly</var>==true. - * In this case the dialog will only be shown either if success if false or some errors - * where captured. - */ - public void displayResult(final boolean success) { - if (logMessages.size() > 0) { - final StringBuilder sb = new StringBuilder(mMessage + "\n\n"); - for (String msg : logMessages) { - if (msg.length() > 0) { - if (msg.charAt(0) != '\n') { - int n = sb.length(); - if (n > 0 && sb.charAt(n-1) != '\n') { - sb.append('\n'); - } - } - sb.append(msg); - } - } - - // display the message - // dialog box only run in ui thread.. - if (mDisplay != null && !mDisplay.isDisposed()) { - mDisplay.asyncExec(new Runnable() { - @Override - public void run() { - // This is typically displayed at the end, so make sure the UI - // instances are not disposed. - Shell shell = null; - if (mDisplay != null && !mDisplay.isDisposed()) { - shell = mDisplay.getActiveShell(); - } - if (shell == null || shell.isDisposed()) { - return; - } - // Use the success icon if the call indicates success. - // However just use the error icon if the logger was only recording errors. - if (success && !mLogErrorsOnly) { - MessageDialog.openInformation(shell, "Android Virtual Devices Manager", - sb.toString()); - } else { - MessageDialog.openError(shell, "Android Virtual Devices Manager", - sb.toString()); - - } - } - }); - } - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ResolutionChooserDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ResolutionChooserDialog.java deleted file mode 100644 index 7454437..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ResolutionChooserDialog.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.sdkuilib.ui.GridDialog; - -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Monitor; -import org.eclipse.swt.widgets.Shell; - -/** - * Small dialog to let a user choose a screen size (from a fixed list) and a resolution - * (as returned by {@link Display#getMonitors()}). - - * After the dialog as returned, one can query {@link #getDensity()} to get the chosen monitor - * pixel density. - */ -public class ResolutionChooserDialog extends GridDialog { - public final static float[] MONITOR_SIZES = new float[] { - 13.3f, 14, 15.4f, 15.6f, 17, 19, 20, 21, 24, 30, - }; - - private Button mButton; - private Combo mScreenSizeCombo; - private Combo mMonitorCombo; - - private Monitor[] mMonitors; - private int mScreenSizeIndex = -1; - private int mMonitorIndex = 0; - - public ResolutionChooserDialog(Shell parentShell) { - super(parentShell, 2, false); - } - - /** - * Returns the pixel density of the user-chosen monitor. - */ - public int getDensity() { - float size = MONITOR_SIZES[mScreenSizeIndex]; - Rectangle rect = mMonitors[mMonitorIndex].getBounds(); - - // compute the density - double d = Math.sqrt(rect.width * rect.width + rect.height * rect.height) / size; - return (int)Math.round(d); - } - - @Override - protected void configureShell(Shell newShell) { - newShell.setText("Monitor Density"); - super.configureShell(newShell); - } - - @Override - protected Control createContents(Composite parent) { - Control control = super.createContents(parent); - mButton = getButton(IDialogConstants.OK_ID); - mButton.setEnabled(false); - return control; - } - - @Override - public void createDialogContent(Composite parent) { - Label l = new Label(parent, SWT.NONE); - l.setText("Screen Size:"); - - mScreenSizeCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); - for (float size : MONITOR_SIZES) { - if (Math.round(size) == size) { - mScreenSizeCombo.add(String.format("%.0f\"", size)); - } else { - mScreenSizeCombo.add(String.format("%.1f\"", size)); - } - } - mScreenSizeCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent arg0) { - mScreenSizeIndex = mScreenSizeCombo.getSelectionIndex(); - mButton.setEnabled(mScreenSizeIndex != -1); - } - }); - - l = new Label(parent, SWT.NONE); - l.setText("Resolution:"); - - mMonitorCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY); - mMonitors = parent.getDisplay().getMonitors(); - for (Monitor m : mMonitors) { - Rectangle r = m.getBounds(); - mMonitorCombo.add(String.format("%d x %d", r.width, r.height)); - } - mMonitorCombo.select(mMonitorIndex); - mMonitorCombo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetDefaultSelected(SelectionEvent arg0) { - mMonitorIndex = mMonitorCombo.getSelectionIndex(); - } - }); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/SdkTargetSelector.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/SdkTargetSelector.java deleted file mode 100644 index 7d2e90f..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/SdkTargetSelector.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - -import com.android.SdkConstants; -import com.android.sdklib.IAndroidTarget; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; - -import java.util.Arrays; -import java.util.Comparator; - - -/** - * The SDK target selector is a table that is added to the given parent composite. - * <p/> - * To use, create it using {@link #SdkTargetSelector(Composite, IAndroidTarget[], boolean)} then - * call {@link #setSelection(IAndroidTarget)}, {@link #setSelectionListener(SelectionListener)} - * and finally use {@link #getSelected()} to retrieve the - * selection. - */ -public class SdkTargetSelector { - - private IAndroidTarget[] mTargets; - private final boolean mAllowSelection; - private SelectionListener mSelectionListener; - private Table mTable; - private Label mDescription; - private Composite mInnerGroup; - - /** Cache for {@link #getCheckboxWidth()} */ - private static int sCheckboxWidth = -1; - - /** - * Creates a new SDK Target Selector. - * - * @param parent The parent composite where the selector will be added. - * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. - * Targets can be null or an empty array, in which case the table is disabled. - */ - public SdkTargetSelector(Composite parent, IAndroidTarget[] targets) { - this(parent, targets, true /*allowSelection*/); - } - - /** - * Creates a new SDK Target Selector. - * - * @param parent The parent composite where the selector will be added. - * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. - * Targets can be null or an empty array, in which case the table is disabled. - * @param allowSelection True if selection is enabled. - */ - public SdkTargetSelector(Composite parent, IAndroidTarget[] targets, boolean allowSelection) { - // Layout has 1 column - mInnerGroup = new Composite(parent, SWT.NONE); - mInnerGroup.setLayout(new GridLayout()); - mInnerGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - mInnerGroup.setFont(parent.getFont()); - - mAllowSelection = allowSelection; - int style = SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION; - if (allowSelection) { - style |= SWT.CHECK; - } - mTable = new Table(mInnerGroup, style); - mTable.setHeaderVisible(true); - mTable.setLinesVisible(false); - - GridData data = new GridData(); - data.grabExcessVerticalSpace = true; - data.grabExcessHorizontalSpace = true; - data.horizontalAlignment = GridData.FILL; - data.verticalAlignment = GridData.FILL; - mTable.setLayoutData(data); - - mDescription = new Label(mInnerGroup, SWT.WRAP); - mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - // create the table columns - final TableColumn column0 = new TableColumn(mTable, SWT.NONE); - column0.setText("Target Name"); - final TableColumn column1 = new TableColumn(mTable, SWT.NONE); - column1.setText("Vendor"); - final TableColumn column2 = new TableColumn(mTable, SWT.NONE); - column2.setText("Platform"); - final TableColumn column3 = new TableColumn(mTable, SWT.NONE); - column3.setText("API Level"); - - adjustColumnsWidth(mTable, column0, column1, column2, column3); - setupSelectionListener(mTable); - setTargets(targets); - setupTooltip(mTable); - } - - /** - * Returns the layout data of the inner composite widget that contains the target selector. - * By default the layout data is set to a {@link GridData} with a {@link GridData#FILL_BOTH} - * mode. - * <p/> - * This can be useful if you want to change the {@link GridData#horizontalSpan} for example. - */ - public Object getLayoutData() { - return mInnerGroup.getLayoutData(); - } - - /** - * Returns the list of known targets. - * <p/> - * This is not a copy. Callers must <em>not</em> modify this array. - */ - public IAndroidTarget[] getTargets() { - return mTargets; - } - - /** - * Changes the targets of the SDK Target Selector. - * - * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. - */ - public void setTargets(IAndroidTarget[] targets) { - mTargets = targets; - if (mTargets != null) { - Arrays.sort(mTargets, new Comparator<IAndroidTarget>() { - @Override - public int compare(IAndroidTarget o1, IAndroidTarget o2) { - return o1.compareTo(o2); - } - }); - } - - fillTable(mTable); - } - - /** - * Sets a selection listener. Set it to null to remove it. - * The listener will be called <em>after</em> this table processed its selection - * events so that the caller can see the updated state. - * <p/> - * The event's item contains a {@link TableItem}. - * The {@link TableItem#getData()} contains an {@link IAndroidTarget}. - * <p/> - * It is recommended that the caller uses the {@link #getSelected()} method instead. - * - * @param selectionListener The new listener or null to remove it. - */ - public void setSelectionListener(SelectionListener selectionListener) { - mSelectionListener = selectionListener; - } - - /** - * Sets the current target selection. - * <p/> - * If the selection is actually changed, this will invoke the selection listener - * (if any) with a null event. - * - * @param target the target to be selection - * @return true if the target could be selected, false otherwise. - */ - public boolean setSelection(IAndroidTarget target) { - if (!mAllowSelection) { - return false; - } - - boolean found = false; - boolean modified = false; - - if (mTable != null && !mTable.isDisposed()) { - for (TableItem i : mTable.getItems()) { - if ((IAndroidTarget) i.getData() == target) { - found = true; - if (!i.getChecked()) { - modified = true; - i.setChecked(true); - } - } else if (i.getChecked()) { - modified = true; - i.setChecked(false); - } - } - } - - if (modified && mSelectionListener != null) { - mSelectionListener.widgetSelected(null); - } - - return found; - } - - /** - * Returns the selected item. - * - * @return The selected item or null. - */ - public IAndroidTarget getSelected() { - if (mTable == null || mTable.isDisposed()) { - return null; - } - - for (TableItem i : mTable.getItems()) { - if (i.getChecked()) { - return (IAndroidTarget) i.getData(); - } - } - return null; - } - - /** - * Adds a listener to adjust the columns width when the parent is resized. - * <p/> - * If we need something more fancy, we might want to use this: - * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co - */ - private void adjustColumnsWidth(final Table table, - final TableColumn column0, - final TableColumn column1, - final TableColumn column2, - final TableColumn column3) { - // Add a listener to resize the column to the full width of the table - table.addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent e) { - Rectangle r = table.getClientArea(); - int width = r.width; - - // On the Mac, the width of the checkbox column is not included (and checkboxes - // are shown if mAllowSelection=true). Subtract this size from the available - // width to be distributed among the columns. - if (mAllowSelection - && SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN) { - width -= getCheckboxWidth(); - } - - column0.setWidth(width * 30 / 100); // 30% - column1.setWidth(width * 45 / 100); // 45% - column2.setWidth(width * 15 / 100); // 15% - column3.setWidth(width * 10 / 100); // 10% - } - }); - } - - - /** - * Creates a selection listener that will check or uncheck the whole line when - * double-clicked (aka "the default selection"). - */ - private void setupSelectionListener(final Table table) { - if (!mAllowSelection) { - return; - } - - // Add a selection listener that will check/uncheck items when they are double-clicked - table.addSelectionListener(new SelectionListener() { - /** Default selection means double-click on "most" platforms */ - @Override - public void widgetDefaultSelected(SelectionEvent e) { - if (e.item instanceof TableItem) { - TableItem i = (TableItem) e.item; - i.setChecked(!i.getChecked()); - enforceSingleSelection(i); - updateDescription(i); - } - - if (mSelectionListener != null) { - mSelectionListener.widgetDefaultSelected(e); - } - } - - @Override - public void widgetSelected(SelectionEvent e) { - if (e.item instanceof TableItem) { - TableItem i = (TableItem) e.item; - enforceSingleSelection(i); - updateDescription(i); - } - - if (mSelectionListener != null) { - mSelectionListener.widgetSelected(e); - } - } - - /** - * If we're not in multiple selection mode, uncheck all other - * items when this one is selected. - */ - private void enforceSingleSelection(TableItem item) { - if (item.getChecked()) { - Table parentTable = item.getParent(); - for (TableItem i2 : parentTable.getItems()) { - if (i2 != item && i2.getChecked()) { - i2.setChecked(false); - } - } - } - } - }); - } - - - /** - * Fills the table with all SDK targets. - * The table columns are: - * <ul> - * <li>column 0: sdk name - * <li>column 1: sdk vendor - * <li>column 2: sdk api name - * <li>column 3: sdk version - * </ul> - */ - private void fillTable(final Table table) { - - if (table == null || table.isDisposed()) { - return; - } - - table.removeAll(); - - if (mTargets != null && mTargets.length > 0) { - table.setEnabled(true); - for (IAndroidTarget target : mTargets) { - TableItem item = new TableItem(table, SWT.NONE); - item.setData(target); - item.setText(0, target.getName()); - item.setText(1, target.getVendor()); - item.setText(2, target.getVersionName()); - item.setText(3, target.getVersion().getApiString()); - } - } else { - table.setEnabled(false); - TableItem item = new TableItem(table, SWT.NONE); - item.setData(null); - item.setText(0, "--"); - item.setText(1, "No target available"); - item.setText(2, "--"); - item.setText(3, "--"); - } - } - - /** - * Sets up a tooltip that displays the current item description. - * <p/> - * Displaying a tooltip over the table looks kind of odd here. Instead we actually - * display the description in a label under the table. - */ - private void setupTooltip(final Table table) { - - if (table == null || table.isDisposed()) { - return; - } - - /* - * Reference: - * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup - */ - - final Listener listener = new Listener() { - @Override - public void handleEvent(Event event) { - - switch(event.type) { - case SWT.KeyDown: - case SWT.MouseExit: - case SWT.MouseDown: - return; - - case SWT.MouseHover: - updateDescription(table.getItem(new Point(event.x, event.y))); - break; - - case SWT.Selection: - if (event.item instanceof TableItem) { - updateDescription((TableItem) event.item); - } - break; - - default: - return; - } - - } - }; - - table.addListener(SWT.Dispose, listener); - table.addListener(SWT.KeyDown, listener); - table.addListener(SWT.MouseMove, listener); - table.addListener(SWT.MouseHover, listener); - } - - /** - * Updates the description label with the description of the item's android target, if any. - */ - private void updateDescription(TableItem item) { - if (item != null) { - Object data = item.getData(); - if (data instanceof IAndroidTarget) { - String newTooltip = ((IAndroidTarget) data).getDescription(); - mDescription.setText(newTooltip == null ? "" : newTooltip); //$NON-NLS-1$ - } - } - } - - /** Enables or disables the controls. */ - public void setEnabled(boolean enabled) { - if (mInnerGroup != null && mTable != null && !mTable.isDisposed()) { - enableControl(mInnerGroup, enabled); - } - } - - /** Enables or disables controls; recursive for composite controls. */ - private void enableControl(Control c, boolean enabled) { - c.setEnabled(enabled); - if (c instanceof Composite) - for (Control c2 : ((Composite) c).getChildren()) { - enableControl(c2, enabled); - } - } - - /** Computes the width of a checkbox */ - private int getCheckboxWidth() { - if (sCheckboxWidth == -1) { - Shell shell = new Shell(mTable.getShell(), SWT.NO_TRIM); - Button checkBox = new Button(shell, SWT.CHECK); - sCheckboxWidth = checkBox.computeSize(SWT.DEFAULT, SWT.DEFAULT).x; - shell.dispose(); - } - - return sCheckboxWidth; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ToggleButton.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ToggleButton.java deleted file mode 100755 index 7c66bcf..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/widgets/ToggleButton.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.widgets; - - -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.CLabel; -import org.eclipse.swt.events.MouseEvent; -import org.eclipse.swt.events.MouseListener; -import org.eclipse.swt.events.MouseTrackListener; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Event; - -/** - * A label that can display 2 images depending on its internal state. - * This acts as a button by firing the {@link SWT#Selection} listener. - */ -public class ToggleButton extends CLabel { - private Image[] mImage = new Image[2]; - private String[] mTooltip = new String[2]; - private boolean mMouseIn; - private int mState = 0; - - - public ToggleButton( - Composite parent, - int style, - Image image1, - Image image2, - String tooltip1, - String tooltip2) { - super(parent, style); - mImage[0] = image1; - mImage[1] = image2; - mTooltip[0] = tooltip1; - mTooltip[1] = tooltip2; - updateImageAndTooltip(); - - addMouseListener(new MouseListener() { - @Override - public void mouseDown(MouseEvent e) { - // pass - } - - @Override - public void mouseUp(MouseEvent e) { - // We select on mouse-up, as it should be properly done since this is the - // only way a user can cancel a button click by moving out of the button. - if (mMouseIn && e.button == 1) { - notifyListeners(SWT.Selection, new Event()); - } - } - - @Override - public void mouseDoubleClick(MouseEvent e) { - if (mMouseIn && e.button == 1) { - notifyListeners(SWT.DefaultSelection, new Event()); - } - } - }); - - addMouseTrackListener(new MouseTrackListener() { - @Override - public void mouseExit(MouseEvent e) { - if (mMouseIn) { - mMouseIn = false; - redraw(); - } - } - - @Override - public void mouseEnter(MouseEvent e) { - if (!mMouseIn) { - mMouseIn = true; - redraw(); - } - } - - @Override - public void mouseHover(MouseEvent e) { - // pass - } - }); - } - - @Override - public int getStyle() { - int style = super.getStyle(); - if (mMouseIn) { - style |= SWT.SHADOW_IN; - } - return style; - } - - /** - * Sets current state. - * @param state A value 0 or 1. - */ - public void setState(int state) { - assert state == 0 || state == 1; - mState = state; - updateImageAndTooltip(); - redraw(); - } - - /** - * Returns the current state - * @return Returns the current state, either 0 or 1. - */ - public int getState() { - return mState; - } - - protected void updateImageAndTooltip() { - setImage(mImage[getState()]); - setToolTipText(mTooltip[getState()]); - } -} - diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/AvdManagerWindow.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/AvdManagerWindow.java deleted file mode 100755 index dd34bef..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/AvdManagerWindow.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.repository; - -import com.android.sdkuilib.internal.repository.ui.AvdManagerWindowImpl1; -import com.android.sdkuilib.internal.widgets.AvdSelector; -import com.android.utils.ILogger; - -import org.eclipse.swt.widgets.Shell; - -/** - * Opens an AVD Manager Window. - * - * This is the public entry point for using the window. - */ -public class AvdManagerWindow { - - /** The actual window implementation to which this class delegates. */ - private AvdManagerWindowImpl1 mWindow; - - /** - * Enum giving some indication of what is invoking this window. - * The behavior and UI will change slightly depending on the context. - * <p/> - * Note: if you add Android support to your specific IDE, you might want - * to specialize this context enum. - */ - public enum AvdInvocationContext { - /** - * The AVD Manager is invoked from the stand-alone 'android' tool. - * In this mode, we present an about box, a settings page. - * For SdkMan2, we also have a menu bar and link to the SDK Manager 2. - */ - STANDALONE, - - /** - * The AVD Manager is embedded as a dialog in the SDK Manager - * or in the {@link AvdSelector}. - * This is similar to the {@link #STANDALONE} mode except we don't need - * to display a menu bar at all since we don't want a menu item linking - * back to the SDK Manager and we don't need to redisplay the options - * and about which are already on the root window. - */ - DIALOG, - - /** - * The AVD Manager is invoked from an IDE. - * In this mode, we do not modify the menu bar. - * There is no about box and no settings. - */ - IDE, - } - - - /** - * Creates a new window. Caller must call open(), which will block. - * - * @param parentShell Parent shell. - * @param sdkLog Logger. Cannot be null. - * @param osSdkRoot The OS path to the SDK root. - * @param context The {@link AvdInvocationContext} to change the behavior depending on who's - * opening the SDK Manager. - */ - public AvdManagerWindow( - Shell parentShell, - ILogger sdkLog, - String osSdkRoot, - AvdInvocationContext context) { - mWindow = new AvdManagerWindowImpl1( - parentShell, - sdkLog, - osSdkRoot, - context); - } - - /** - * Opens the window. - */ - public void open() { - mWindow.open(); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/ISdkChangeListener.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/ISdkChangeListener.java deleted file mode 100755 index e221f98..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/ISdkChangeListener.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.repository; - - -/** - * Interface for listeners on SDK modifications by the SDK Manager UI. - * This notifies when the SDK manager is first loading the SDK or before/after it installed - * a package. - */ -public interface ISdkChangeListener { - /** - * Invoked when the content of the SDK is being loaded by the SDK Manager UI - * for the first time. - * This is generally followed by a call to {@link #onSdkReload()} - * or by a call to {@link #preInstallHook()}. - */ - void onSdkLoaded(); - - /** - * Invoked when the SDK Manager UI is about to start installing packages. - * This will be followed by a call to {@link #postInstallHook()}. - */ - void preInstallHook(); - - /** - * Invoked when the SDK Manager UI is done installing packages. - * Some new packages might have been installed or the user might have cancelled the operation. - * This is generally followed by a call to {@link #onSdkReload()}. - */ - void postInstallHook(); - - /** - * Invoked when the content of the SDK is being reloaded by the SDK Manager UI, - * typically after a package was installed. The SDK content might or might not - * have changed. - */ - void onSdkReload(); -} - diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/SdkUpdaterWindow.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/SdkUpdaterWindow.java deleted file mode 100755 index 6010e48..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/repository/SdkUpdaterWindow.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.repository; - -import com.android.sdkuilib.internal.repository.ISdkUpdaterWindow; -import com.android.sdkuilib.internal.repository.ui.SdkUpdaterWindowImpl2; -import com.android.utils.ILogger; - -import org.eclipse.swt.widgets.Shell; - -/** - * Opens an SDK Manager Window. - * - * This is the public entry point for using the window. - */ -public class SdkUpdaterWindow { - - /** The actual window implementation to which this class delegates. */ - private ISdkUpdaterWindow mWindow; - - /** - * Enum giving some indication of what is invoking this window. - * The behavior and UI will change slightly depending on the context. - * <p/> - * Note: if you add Android support to your specific IDE, you might want - * to specialize this context enum. - */ - public enum SdkInvocationContext { - /** - * The SDK Manager is invoked from the stand-alone 'android' tool. - * In this mode, we present an about box, a settings page. - * For SdkMan2, we also have a menu bar and link to the AVD manager. - */ - STANDALONE, - - /** - * The SDK Manager is invoked from the standalone AVD Manager. - * This is similar to the standalone mode except that in this case we - * don't display a menu item linking to the AVD Manager. - */ - AVD_MANAGER, - - /** - * The SDK Manager is invoked from an IDE. - * In this mode, we do not modify the menu bar. There is no about box - * and no settings (e.g. HTTP proxy settings are inherited from Eclipse.) - */ - IDE, - - /** - * The SDK Manager is invoked from the AVD Selector. - * For SdkMan1, this means the AVD page will be displayed first. - * For SdkMan2, we won't be using this. - */ - AVD_SELECTOR - } - - /** - * Creates a new window. Caller must call open(), which will block. - * - * @param parentShell Parent shell. - * @param sdkLog Logger. Cannot be null. - * @param osSdkRoot The OS path to the SDK root. - * @param context The {@link SdkInvocationContext} to change the behavior depending on who's - * opening the SDK Manager. - */ - public SdkUpdaterWindow( - Shell parentShell, - ILogger sdkLog, - String osSdkRoot, - SdkInvocationContext context) { - - mWindow = new SdkUpdaterWindowImpl2(parentShell, sdkLog, osSdkRoot, context); - } - - /** - * Adds a new listener to be notified when a change is made to the content of the SDK. - * This should be called before {@link #open()}. - */ - public void addListener(ISdkChangeListener listener) { - mWindow.addListener(listener); - } - - /** - * Removes a new listener to be notified anymore when a change is made to the content of - * the SDK. - */ - public void removeListener(ISdkChangeListener listener) { - mWindow.removeListener(listener); - } - - /** - * Opens the window. - */ - public void open() { - mWindow.open(); - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/AuthenticationDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/AuthenticationDialog.java deleted file mode 100644 index 07e65b7..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/AuthenticationDialog.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.ui; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * Dialog which collects from the user his/her login and password. - */ -public class AuthenticationDialog extends GridDialog { - private Text mTxtLogin; - private Text mTxtPassword; - private Text mTxtWorkstation; - private Text mTxtDomain; - - private String mTitle; - private String mMessage; - - private static String sLogin = ""; - private static String sPassword = ""; - private static String sWorkstation = ""; - private static String sDomain = ""; - - /** - * Constructor which retrieves the parent {@link Shell} and the message to - * be displayed in this dialog. - * - * @param parentShell Parent Shell - * @param title Title of the window. - * @param message Message the be displayed in this dialog. - */ - public AuthenticationDialog(Shell parentShell, String title, String message) { - super(parentShell, 1, false); - // assign fields - mTitle = title; - mMessage = message; - } - - @Override - public void createDialogContent(Composite parent) { - // Configure Dialog - getShell().setText(mTitle); - GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); - parent.setLayoutData(data); - - // Upper Composite - Composite upperComposite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(2, false); - layout.verticalSpacing = 10; - upperComposite.setLayout(layout); - data = new GridData(SWT.FILL, SWT.CENTER, true, true); - upperComposite.setLayoutData(data); - - // add message label - Label lblMessage = new Label(upperComposite, SWT.WRAP); - lblMessage.setText(mMessage); - data = new GridData(SWT.FILL, SWT.CENTER, true, true, 2, 1); - data.widthHint = 500; - lblMessage.setLayoutData(data); - - // add user name label and text field - Label lblUserName = new Label(upperComposite, SWT.NONE); - lblUserName.setText("Login:"); - data = new GridData(SWT.LEFT, SWT.CENTER, false, false); - lblUserName.setLayoutData(data); - - mTxtLogin = new Text(upperComposite, SWT.SINGLE | SWT.BORDER); - data = new GridData(SWT.FILL, SWT.CENTER, true, false); - mTxtLogin.setLayoutData(data); - mTxtLogin.setFocus(); - mTxtLogin.setText(sLogin); - mTxtLogin.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent arg0) { - sLogin = mTxtLogin.getText().trim(); - } - }); - - // add password label and text field - Label lblPassword = new Label(upperComposite, SWT.NONE); - lblPassword.setText("Password:"); - data = new GridData(SWT.LEFT, SWT.CENTER, false, false); - lblPassword.setLayoutData(data); - - mTxtPassword = new Text(upperComposite, SWT.SINGLE | SWT.PASSWORD | SWT.BORDER); - data = new GridData(SWT.FILL, SWT.CENTER, true, false); - mTxtPassword.setLayoutData(data); - mTxtPassword.setText(sPassword); - mTxtPassword.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent arg0) { - sPassword = mTxtPassword.getText(); - } - }); - - // add a label indicating that the following two fields are optional - Label lblInfo = new Label(upperComposite, SWT.NONE); - lblInfo.setText("Provide the following info if your proxy uses NTLM authentication. Leave blank otherwise."); - data = new GridData(); - data.horizontalSpan = 2; - lblInfo.setLayoutData(data); - - // add workstation label and text field - Label lblWorkstation = new Label(upperComposite, SWT.NONE); - lblWorkstation.setText("Workstation:"); - data = new GridData(SWT.LEFT, SWT.CENTER, false, false); - lblWorkstation.setLayoutData(data); - - mTxtWorkstation = new Text(upperComposite, SWT.SINGLE | SWT.BORDER); - data = new GridData(SWT.FILL, SWT.CENTER, true, false); - mTxtWorkstation.setLayoutData(data); - mTxtWorkstation.setText(sWorkstation); - mTxtWorkstation.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent arg0) { - sWorkstation = mTxtWorkstation.getText().trim(); - } - }); - - // add domain label and text field - Label lblDomain = new Label(upperComposite, SWT.NONE); - lblDomain.setText("Domain:"); - data = new GridData(SWT.LEFT, SWT.CENTER, false, false); - lblDomain.setLayoutData(data); - - mTxtDomain = new Text(upperComposite, SWT.SINGLE | SWT.BORDER); - data = new GridData(SWT.FILL, SWT.CENTER, true, false); - mTxtDomain.setLayoutData(data); - mTxtDomain.setText(sDomain); - mTxtDomain.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent arg0) { - sDomain = mTxtDomain.getText().trim(); - } - }); - } - - /** - * Retrieves the Login field information - * - * @return Login field value or empty String. Return value is never null - */ - public String getLogin() { - return sLogin; - } - - /** - * Retrieves the Password field information - * - * @return Password field value or empty String. Return value is never null - */ - public String getPassword() { - return sPassword; - } - - /** - * Retrieves the workstation field information - * - * @return Workstation field value or empty String. Return value is never null - */ - public String getWorkstation() { - return sWorkstation; - } - - /** - * Retrieves the domain field information - * - * @return Domain field value or empty String. Return value is never null - */ - public String getDomain() { - return sDomain; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDataBuilder.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDataBuilder.java deleted file mode 100755 index 381dea0..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDataBuilder.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.ui; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Control; - -/** - * A little helper to create a new {@link GridData} and set its properties. - * <p/> - * Example of usage: <br/> - * <code> - * GridDataHelper.create(myControl).hSpan(2).hAlignCenter().fill(); - * </code> - */ -public final class GridDataBuilder { - - private GridData mGD; - - private GridDataBuilder() { - mGD = new GridData(); - } - - /** - * Creates new {@link GridData} and associates it on the <code>control</code> composite. - */ - static public GridDataBuilder create(Control control) { - GridDataBuilder gdh = new GridDataBuilder(); - control.setLayoutData(gdh.mGD); - return gdh; - } - - /** Sets <code>widthHint</code> to <code>w</code>. */ - public GridDataBuilder wHint(int w) { - mGD.widthHint = w; - return this; - } - - /** Sets <code>heightHint</code> to <code>h</code>. */ - public GridDataBuilder hHint(int h) { - mGD.heightHint = h; - return this; - } - - /** Sets <code>horizontalIndent</code> to <code>h</code>. */ - public GridDataBuilder hIndent(int h) { - mGD.horizontalIndent = h; - return this; - } - - /** Sets <code>horizontalSpan</code> to <code>h</code>. */ - public GridDataBuilder hSpan(int h) { - mGD.horizontalSpan = h; - return this; - } - - /** Sets <code>verticalSpan</code> to <code>v</code>. */ - public GridDataBuilder vSpan(int v) { - mGD.verticalSpan = v; - return this; - } - - /** Sets <code>horizontalAlignment</code> to {@link SWT#CENTER}. */ - public GridDataBuilder hCenter() { - mGD.horizontalAlignment = SWT.CENTER; - return this; - } - - /** Sets <code>verticalAlignment</code> to {@link SWT#CENTER}. */ - public GridDataBuilder vCenter() { - mGD.verticalAlignment = SWT.CENTER; - return this; - } - - /** Sets <code>verticalAlignment</code> to {@link SWT#TOP}. */ - public GridDataBuilder vTop() { - mGD.verticalAlignment = SWT.TOP; - return this; - } - - /** Sets <code>verticalAlignment</code> to {@link SWT#BOTTOM}. */ - public GridDataBuilder vBottom() { - mGD.verticalAlignment = SWT.BOTTOM; - return this; - } - - /** Sets <code>horizontalAlignment</code> to {@link SWT#LEFT}. */ - public GridDataBuilder hLeft() { - mGD.horizontalAlignment = SWT.LEFT; - return this; - } - - /** Sets <code>horizontalAlignment</code> to {@link SWT#RIGHT}. */ - public GridDataBuilder hRight() { - mGD.horizontalAlignment = SWT.RIGHT; - return this; - } - - /** Sets <code>horizontalAlignment</code> to {@link GridData#FILL}. */ - public GridDataBuilder hFill() { - mGD.horizontalAlignment = GridData.FILL; - return this; - } - - /** Sets <code>verticalAlignment</code> to {@link GridData#FILL}. */ - public GridDataBuilder vFill() { - mGD.verticalAlignment = GridData.FILL; - return this; - } - - /** - * Sets both <code>horizontalAlignment</code> and <code>verticalAlignment</code> - * to {@link GridData#FILL}. - */ - public GridDataBuilder fill() { - mGD.horizontalAlignment = GridData.FILL; - mGD.verticalAlignment = GridData.FILL; - return this; - } - - /** Sets <code>grabExcessHorizontalSpace</code> to true. */ - public GridDataBuilder hGrab() { - mGD.grabExcessHorizontalSpace = true; - return this; - } - - /** Sets <code>grabExcessVerticalSpace</code> to true. */ - public GridDataBuilder vGrab() { - mGD.grabExcessVerticalSpace = true; - return this; - } - - /** - * Sets both <code>grabExcessHorizontalSpace</code> and - * <code>grabExcessVerticalSpace</code> to true. - */ - public GridDataBuilder grab() { - mGD.grabExcessHorizontalSpace = true; - mGD.grabExcessVerticalSpace = true; - return this; - } - -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java deleted file mode 100644 index 9bf9c29..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridDialog.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.ui; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Shell; - -/** - * JFace-based dialog that properly sets up a {@link GridLayout} top composite with the proper - * margin. - * <p/> - * Implementing dialog must create the content of the dialog in - * {@link #createDialogContent(Composite)}. - * <p/> - * A JFace dialog is perfect if you want a typical "OK | cancel" workflow, with the OK and - * cancel things all handled for you using a predefined layout. If you want a different set - * of buttons or a different layout, consider {@link SwtBaseDialog} instead. - */ -public abstract class GridDialog extends Dialog { - - private final int mNumColumns; - private final boolean mMakeColumnsEqualWidth; - - /** - * Creates the dialog - * @param parentShell the parent {@link Shell}. - * @param numColumns the number of columns in the grid - * @param makeColumnsEqualWidth whether or not the columns will have equal width - */ - public GridDialog(Shell parentShell, int numColumns, boolean makeColumnsEqualWidth) { - super(parentShell); - mNumColumns = numColumns; - mMakeColumnsEqualWidth = makeColumnsEqualWidth; - } - - /** - * Creates the content of the dialog. The <var>parent</var> composite is a {@link GridLayout} - * created with the <var>numColumn</var> and <var>makeColumnsEqualWidth</var> parameters - * passed to {@link #GridDialog(Shell, int, boolean)}. - * @param parent the parent composite. - */ - public abstract void createDialogContent(Composite parent); - - @Override - protected Control createDialogArea(Composite parent) { - Composite top = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(mNumColumns, mMakeColumnsEqualWidth); - layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); - layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); - layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); - layout.horizontalSpacing = convertHorizontalDLUsToPixels( - IDialogConstants.HORIZONTAL_SPACING); - top.setLayout(layout); - top.setLayoutData(new GridData(GridData.FILL_BOTH)); - - createDialogContent(top); - - applyDialogFont(top); - return top; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridLayoutBuilder.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridLayoutBuilder.java deleted file mode 100755 index fbb31ce..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/GridLayoutBuilder.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.ui; - -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; - -/** - * A little helper to create a new {@link GridLayout}, associate to a {@link Composite} - * and set its common attributes. - * <p/> - * Example of usage: <br/> - * <code> - * GridLayoutHelper.create(myComposite).noMargins().vSpacing(0).columns(2); - * </code> - */ -public final class GridLayoutBuilder { - - private static GridLayout mGL; - - private GridLayoutBuilder() { - mGL = new GridLayout(); - } - - /** - * Creates new {@link GridLayout} and associates it on the <code>parent</code> composite. - */ - static public GridLayoutBuilder create(Composite parent) { - GridLayoutBuilder glh = new GridLayoutBuilder(); - parent.setLayout(GridLayoutBuilder.mGL); - return glh; - } - - /** Sets all margins to 0. */ - public GridLayoutBuilder noMargins() { - mGL.marginHeight = 0; - mGL.marginWidth = 0; - mGL.marginLeft = 0; - mGL.marginTop = 0; - mGL.marginRight = 0; - mGL.marginBottom = 0; - return this; - } - - /** Sets all margins to <code>n</code>. */ - public GridLayoutBuilder margins(int n) { - mGL.marginHeight = n; - mGL.marginWidth = n; - mGL.marginLeft = n; - mGL.marginTop = n; - mGL.marginRight = n; - mGL.marginBottom = n; - return this; - } - - /** Sets <code>numColumns</code> to <code>n</code>. */ - public GridLayoutBuilder columns(int n) { - mGL.numColumns = n; - return this; - } - - /** Sets <code>makeColumnsEqualWidth</code> to true. */ - public GridLayoutBuilder columnsEqual() { - mGL.makeColumnsEqualWidth = true; - return this; - } - - /** Sets <code>verticalSpacing</code> to <code>v</code>. */ - public GridLayoutBuilder vSpacing(int v) { - mGL.verticalSpacing = v; - return this; - } - - /** Sets <code>horizontalSpacing</code> to <code>h</code>. */ - public GridLayoutBuilder hSpacing(int h) { - mGL.horizontalSpacing = h; - return this; - } - - /** - * Sets <code>horizontalSpacing</code> and <code>verticalSpacing</code> - * to <code>s</code>. - */ - public GridLayoutBuilder spacing(int s) { - mGL.verticalSpacing = s; - mGL.horizontalSpacing = s; - return this; - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/SwtBaseDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/SwtBaseDialog.java deleted file mode 100755 index bb0210b..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ui/SwtBaseDialog.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.ui; - -import com.android.SdkConstants; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Dialog; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -import java.util.HashMap; -import java.util.Map; - -/** - * A base class for an SWT Dialog. - * <p/> - * The base class offers the following goodies: <br/> - * - Dialog is automatically centered on its parent. <br/> - * - Dialog size is reused during the session. <br/> - * - A simple API with an {@link #open()} method that returns a boolean. <br/> - * <p/> - * A typical usage is: - * <pre> - * MyDialog extends SwtBaseDialog { ... } - * MyDialog d = new MyDialog(parentShell, "My Dialog Title"); - * if (d.open()) { - * ...do something like refresh parent list view - * } - * </pre> - * We also have a JFace-base {@link GridDialog}. - * The JFace dialog is good when you just want a typical OK/Cancel layout with the - * buttons all managed for you. - * This SWT base dialog has little decoration. - * It's up to you to manage whatever buttons you want, if any. - */ -public abstract class SwtBaseDialog extends Dialog { - - /** - * Min Y location for dialog. Need to deal with the menu bar on mac os. - */ - private final static int MIN_Y = - SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN ? 20 : 0; - - /** Last dialog size for this session, different for each dialog class. */ - private static Map<Class<?>, Point> sLastSizeMap = new HashMap<Class<?>, Point>(); - - private volatile boolean mQuitRequested = false; - private boolean mReturnValue; - private Shell mShell; - - /** - * Create the dialog. - * - * @param parent The parent's shell - * @param title The dialog title. Can be null. - */ - public SwtBaseDialog(Shell parent, int swtStyle, String title) { - super(parent, swtStyle); - if (title != null) { - setText(title); - } - } - - /** - * Open the dialog. - * - * @return The last value set using {@link #setReturnValue(boolean)} or false by default. - */ - public boolean open() { - if (!mQuitRequested) { - createShell(); - } - if (!mQuitRequested) { - createContents(); - } - if (!mQuitRequested) { - positionShell(); - } - if (!mQuitRequested) { - postCreate(); - } - if (!mQuitRequested) { - mShell.open(); - mShell.layout(); - eventLoop(); - } - - return mReturnValue; - } - - /** - * Creates the shell for this dialog. - * The default shell has a size of 450x300, which is also its minimum size. - * You might want to override these values. - * <p/> - * Called before {@link #createContents()}. - */ - protected void createShell() { - mShell = new Shell(getParent(), SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL); - mShell.setMinimumSize(new Point(450, 300)); - mShell.setSize(450, 300); - if (getText() != null) { - mShell.setText(getText()); - } - mShell.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - saveSize(); - } - }); - } - - /** - * Creates the content and attaches it to the current shell (cf. {@link #getShell()}). - * <p/> - * Derived classes should consider creating the UI here and initializing their - * state in {@link #postCreate()}. - */ - protected abstract void createContents(); - - /** - * Called after {@link #createContents()} and after {@link #positionShell()} - * just before the dialog is actually shown on screen. - * <p/> - * Derived classes should consider creating the UI in {@link #createContents()} and - * initialize it here. - */ - protected abstract void postCreate(); - - /** - * Run the event loop. - * This is called from {@link #open()} after {@link #postCreate()} and - * after the window has been shown on screen. - * Derived classes might want to use this as a place to start automated - * tasks that will update the UI. - */ - protected void eventLoop() { - Display display = getParent().getDisplay(); - while (!mQuitRequested && !mShell.isDisposed()) { - if (!display.readAndDispatch()) { - display.sleep(); - } - } - } - - /** - * Returns the current value that {@link #open()} will return to the caller. - * Default is false. - */ - protected boolean getReturnValue() { - return mReturnValue; - } - - /** - * Sets the value that {@link #open()} will return to the caller. - * @param returnValue The new value to be returned by {@link #open()}. - */ - protected void setReturnValue(boolean returnValue) { - mReturnValue = returnValue; - } - - /** - * Returns the shell created by {@link #createShell()}. - * @return The current {@link Shell}. - */ - protected Shell getShell() { - return mShell; - } - - /** - * Saves the dialog size and close the dialog. - * The {@link #open()} method will given return value (see {@link #setReturnValue(boolean)}. - * <p/> - * It's safe to call this method before the shell is initialized, - * in which case the dialog will close as soon as possible. - */ - protected void close() { - if (mShell != null && !mShell.isDisposed()) { - saveSize(); - getShell().close(); - } - mQuitRequested = true; - } - - //------- - - /** - * Centers the dialog in its parent shell. - */ - private void positionShell() { - // Centers the dialog in its parent shell - Shell child = mShell; - Shell parent = getParent(); - if (child != null && parent != null) { - // get the parent client area with a location relative to the display - Rectangle parentArea = parent.getClientArea(); - Point parentLoc = parent.getLocation(); - int px = parentLoc.x; - int py = parentLoc.y; - int pw = parentArea.width; - int ph = parentArea.height; - - // Reuse the last size if there's one, otherwise use the default - Point childSize = sLastSizeMap.get(this.getClass()); - if (childSize == null) { - childSize = child.getSize(); - } - int cw = childSize.x; - int ch = childSize.y; - - int x = px + (pw - cw) / 2; - if (x < 0) x = 0; - - int y = py + (ph - ch) / 2; - if (y < MIN_Y) y = MIN_Y; - - child.setLocation(x, y); - child.setSize(cw, ch); - } - } - - private void saveSize() { - if (mShell != null && !mShell.isDisposed()) { - sLastSizeMap.put(this.getClass(), mShell.getSize()); - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/tests/Android.mk b/sdkmanager/libs/sdkuilib/tests/Android.mk deleted file mode 100644 index a7ba9a7..0000000 --- a/sdkmanager/libs/sdkuilib/tests/Android.mk +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (C) 2011 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -# Only compile source java files in this lib. -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_MODULE := sdkuilib-tests -LOCAL_MODULE_TAGS := optional - -LOCAL_JAVA_LIBRARIES := \ - sdklib \ - sdklib-tests \ - sdkuilib \ - junit \ - swt \ - -include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockDownloadCache.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockDownloadCache.java deleted file mode 100755 index 04f2b04..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockDownloadCache.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.sdklib.internal.repository.CanceledByUserException; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.utils.Pair; - -import org.apache.http.Header; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.ProtocolVersion; -import org.apache.http.message.BasicHttpResponse; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import java.util.TreeMap; - -/** A mock UpdaterData that simply records what would have been installed. */ -public class MockDownloadCache extends DownloadCache { - - private final File mCacheRoot; - - /** Map url => payload bytes, http code response. - * If the payload pair is null, an exception such as FNF is thrown. */ - private final Map<String, Payload> mDirectPayloads = new HashMap<String, Payload>(); - /** Map url => payload bytes, http code response. - * If the payload pair is null, an exception such as FNF is thrown. */ - private final Map<String, Payload> mCachedPayloads = new HashMap<String, Payload>(); - - private final Map<String, Integer> mDirectHits = new TreeMap<String, Integer>(); - private final Map<String, Integer> mCachedHits = new TreeMap<String, Integer>(); - - private Strategy mOverrideStrategy; - - public final static int THROW_FNF = -1; - - /** - * Creates a download cache with a {@code DIRECT} strategy and - * no root {@code $HOME/.android} folder, which effectively disables the cache. - */ - public MockDownloadCache() { - super(DownloadCache.Strategy.DIRECT); - mCacheRoot = null; - } - - /** - * Creates a download with the given strategy and the given cache root. - */ - public MockDownloadCache(DownloadCache.Strategy strategy, File cacheRoot) { - super(strategy); - mCacheRoot = cacheRoot; - } - - @Override - protected File initCacheRoot() { - return mCacheRoot; - } - - /** - * Override the {@link DownloadCache.Strategy} of the cache. - * This lets us set it temporarily to {@link DownloadCache.Strategy#ONLY_CACHE}, - * which will force {@link #openCachedUrl(String, ITaskMonitor)} to throw an FNF, - * essentially simulating an empty cache at first. - * <p/> - * Setting it back to null reverts the behavior to its default. - */ - public void overrideStrategy(DownloadCache.Strategy strategy) { - mOverrideStrategy = strategy; - } - - /** - * Register a direct payload response. - * - * @param url The URL to match. - * @param httpCode The expected response code. - * Use {@link #THROW_FNF} to mean an FNF should be thrown (which is what the - * httpClient stack seems to return instead of {@link HttpStatus#SC_NOT_FOUND}.) - * @param content The payload to return. - * As a shortcut a null will be replaced by an empty byte array. - */ - public void registerDirectPayload(String url, int httpCode, byte[] content) { - mDirectPayloads.put(url, new Payload(httpCode, content)); - } - - /** - * Register a cached payload response. - * - * @param url The URL to match. - * @param content The payload to return or null to throw a FNF. - */ - public void registerCachedPayload(String url, byte[] content) { - mCachedPayloads.put(url, - new Payload(content == null ? THROW_FNF : HttpStatus.SC_OK, content)); - } - - public String[] getDirectHits() { - ArrayList<String> list = new ArrayList<String>(); - synchronized (mDirectHits) { - for (Entry<String, Integer> entry : mDirectHits.entrySet()) { - list.add(String.format("<%1$s : %2$d>", - entry.getKey(), entry.getValue().intValue())); - } - } - return list.toArray(new String[list.size()]); - } - - public String[] getCachedHits() { - ArrayList<String> list = new ArrayList<String>(); - synchronized (mCachedHits) { - for (Entry<String, Integer> entry : mCachedHits.entrySet()) { - list.add(String.format("<%1$s : %2$d>", - entry.getKey(), entry.getValue().intValue())); - } - } - return list.toArray(new String[list.size()]); - } - - public void clearDirectHits() { - synchronized (mDirectHits) { - mDirectHits.clear(); - } - } - - public void clearCachedHits() { - synchronized (mCachedHits) { - mCachedHits.clear(); - } - } - - /** - * Override openDirectUrl to return one of the registered payloads or throw a FNF exception. - * This totally ignores the cache's {@link DownloadCache.Strategy}. - */ - @Override - public Pair<InputStream, HttpResponse> openDirectUrl( - @NonNull String urlString, - @Nullable Header[] headers, - @NonNull ITaskMonitor monitor) throws IOException, CanceledByUserException { - - synchronized (mDirectHits) { - Integer count = mDirectHits.get(urlString); - mDirectHits.put(urlString, (count == null ? 0 : count.intValue()) + 1); - } - - Payload payload = mDirectPayloads.get(urlString); - - if (payload == null || payload.mHttpCode == THROW_FNF) { - throw new FileNotFoundException(urlString); - } - - byte[] content = payload.mContent; - if (content == null) { - content = new byte[0]; - } - - InputStream is = new ByteArrayInputStream(content); - HttpResponse hr = new BasicHttpResponse( - new ProtocolVersion("HTTP", 1, 1), - payload.mHttpCode, - "Http-Code-" + payload.mHttpCode); - - return Pair.of(is, hr); - } - - /** - * Override openCachedUrl to return one of the registered payloads or throw a FNF exception. - * This totally ignores the cache's {@link DownloadCache.Strategy}. - * It will however throw a FNF if {@link #overrideStrategy(Strategy)} is set to - * {@link DownloadCache.Strategy#ONLY_CACHE}. - */ - @Override - public InputStream openCachedUrl(String urlString, ITaskMonitor monitor) - throws IOException, CanceledByUserException { - - synchronized (mCachedHits) { - Integer count = mCachedHits.get(urlString); - mCachedHits.put(urlString, (count == null ? 0 : count.intValue()) + 1); - } - - if (Strategy.ONLY_CACHE.equals(mOverrideStrategy)) { - // Override the cache to read only "local cached" data. - // In this first phase, we assume there's nothing cached. - // TODO register first-pass files later. - throw new FileNotFoundException(urlString); - } - - Payload payload = mCachedPayloads.get(urlString); - - if (payload == null || payload.mHttpCode != HttpStatus.SC_OK) { - throw new FileNotFoundException(urlString); - } - - byte[] content = payload.mContent; - if (content == null) { - content = new byte[0]; - } - - return new ByteArrayInputStream(content); - } - - private static class Payload { - final byte[] mContent; - final int mHttpCode; - - Payload(int httpCode, byte[] content) { - mHttpCode = httpCode; - mContent = content; - } - } - -} diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockUpdaterData.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockUpdaterData.java deleted file mode 100755 index f19bfcc..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/MockUpdaterData.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITask; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.ITaskMonitor; -import com.android.sdklib.internal.repository.MockEmptySdkManager; -import com.android.sdklib.internal.repository.NullTaskMonitor; -import com.android.sdklib.internal.repository.archives.ArchiveInstaller; -import com.android.sdklib.internal.repository.archives.ArchiveReplacement; -import com.android.sdklib.internal.repository.sources.SdkSourceCategory; -import com.android.sdklib.internal.repository.sources.SdkSources; -import com.android.sdklib.mock.MockLog; -import com.android.sdkuilib.internal.repository.SettingsController.Settings; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.utils.ILogger; -import com.android.utils.NullLogger; - -import org.eclipse.swt.graphics.Image; - -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -/** A mock UpdaterData that simply records what would have been installed. */ -public class MockUpdaterData extends UpdaterData { - - public final static String SDK_PATH = "/tmp/SDK"; - - private final List<ArchiveReplacement> mInstalled = new ArrayList<ArchiveReplacement>(); - - private DownloadCache mMockDownloadCache = new MockDownloadCache(); - - private final SdkSources mMockSdkSources = new SdkSources() { - @Override - public void loadUserAddons(ILogger log) { - // This source does not load user addons. - removeAll(SdkSourceCategory.USER_ADDONS); - }; - }; - - /** Creates a {@link MockUpdaterData} using a {@link MockEmptySdkManager}. */ - public MockUpdaterData() { - super(SDK_PATH, new MockLog()); - - setTaskFactory(new MockTaskFactory()); - setImageFactory(new NullImageFactory()); - } - - /** Creates a {@link MockUpdaterData} using the given {@link SdkManager}. */ - public MockUpdaterData(SdkManager sdkManager) { - super(sdkManager.getLocation(), new MockLog()); - setSdkManager(sdkManager); - setTaskFactory(new MockTaskFactory()); - setImageFactory(new NullImageFactory()); - } - - /** Gives access to the internal {@link #installArchives(List, int)}. */ - public void _installArchives(List<ArchiveInfo> result) { - installArchives(result, 0/*flags*/); - } - - public ArchiveReplacement[] getInstalled() { - return mInstalled.toArray(new ArchiveReplacement[mInstalled.size()]); - } - - /** Overrides the sdk manager with our mock instance. */ - @Override - protected void initSdk() { - setSdkManager(new MockEmptySdkManager(SDK_PATH)); - } - - /** Overrides the settings controller with our mock instance. */ - @Override - protected SettingsController initSettingsController() { - return createSettingsController(getSdkLog()); - } - - /** Override original implementation to do nothing. */ - @Override - public void reloadSdk() { - // nop - } - - /** - * Override original implementation to return a mock SdkSources that - * does not load user add-ons from the local .android/repository.cfg file. - */ - @Override - public SdkSources getSources() { - return mMockSdkSources; - } - - /** Returns a mock installer that simply records what would have been installed. */ - @Override - protected ArchiveInstaller createArchiveInstaler() { - return new ArchiveInstaller() { - @Override - public boolean install( - ArchiveReplacement archiveInfo, - String osSdkRoot, - boolean forceHttp, - SdkManager sdkManager, - DownloadCache cache, - ITaskMonitor monitor) { - mInstalled.add(archiveInfo); - return true; - } - }; - } - - /** Returns a mock download cache. */ - @Override - public DownloadCache getDownloadCache() { - return mMockDownloadCache; - } - - /** Overrides the mock download cache. */ - public void setMockDownloadCache(DownloadCache mockDownloadCache) { - mMockDownloadCache = mockDownloadCache; - } - - public void overrideSetting(String key, boolean boolValue) { - SettingsController sc = getSettingsController(); - assert sc instanceof MockSettingsController; - ((MockSettingsController)sc).overrideSetting(key, boolValue); - } - - //------------ - - public static SettingsController createSettingsController(ILogger sdkLog) { - Properties props = new Properties(); - Settings settings = new Settings(props) {}; // this constructor is protected - MockSettingsController controller = new MockSettingsController(sdkLog, settings); - controller.setProperties(props); - return controller; - } - - static class MockSettingsController extends SettingsController { - - private Properties mProperties; - - MockSettingsController(ILogger sdkLog, Settings settings) { - super(sdkLog, settings); - } - - void setProperties(Properties properties) { - mProperties = properties; - } - - public void overrideSetting(String key, boolean boolValue) { - mProperties.setProperty(key, Boolean.valueOf(boolValue).toString()); - } - - @Override - public void loadSettings() { - // This mock setting controller does not load live file settings. - } - - @Override - public void saveSettings() { - // This mock setting controller does not save live file settings. - } - } - - //------------ - - private class MockTaskFactory implements ITaskFactory { - @Override - public void start(String title, ITask task) { - start(title, null /*parentMonitor*/, task); - } - - @SuppressWarnings("unused") // works by side-effect of creating a new MockTask. - @Override - public void start(String title, ITaskMonitor parentMonitor, ITask task) { - new MockTask(task); - } - } - - //------------ - - private static class MockTask extends NullTaskMonitor { - public MockTask(ITask task) { - super(NullLogger.getLogger()); - task.run(this); - } - } - - //------------ - - private static class NullImageFactory extends ImageFactory { - public NullImageFactory() { - // pass - super(null /*display*/); - } - - @Override - public Image getImageByName(String imageName) { - return null; - } - - @Override - public Image getImageForObject(Object object) { - return null; - } - - @Override - public void dispose() { - // pass - } - - } -} diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterDataTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterDataTest.java deleted file mode 100755 index 6b8c850..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterDataTest.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.MockEmptyPackage; - -import java.util.ArrayList; -import java.util.Arrays; - -import junit.framework.TestCase; - -public class UpdaterDataTest extends TestCase { - - private MockUpdaterData m; - - @Override - protected void setUp() throws Exception { - super.setUp(); - m = new MockUpdaterData(); - assertEquals("[]", Arrays.toString(m.getInstalled())); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - /** - * Tests the case where we have nothing to install. - */ - public void testInstallArchives_None() { - m._installArchives(new ArrayList<ArchiveInfo>()); - assertEquals("[]", Arrays.toString(m.getInstalled())); - } - - - /** - * Tests the case where there's a simple dependency, in the right order - * (e.g. install A1 then A2 that depends on A1). - */ - public void testInstallArchives_SimpleDependency() { - - ArrayList<ArchiveInfo> archives = new ArrayList<ArchiveInfo>(); - - Archive a1 = new MockEmptyPackage("a1").getLocalArchive(); - ArchiveInfo ai1 = new ArchiveInfo(a1, null, null); - - Archive a2 = new MockEmptyPackage("a2").getLocalArchive(); - ArchiveInfo ai2 = new ArchiveInfo(a2, null, new ArchiveInfo[] { ai1 } ); - - archives.add(ai1); - archives.add(ai2); - - m._installArchives(archives); - assertEquals( - "[MockEmptyPackage 'a1', MockEmptyPackage 'a2']", - Arrays.toString(m.getInstalled())); - } - - /** - * Tests the case where there's a simple dependency, in the wrong order - * (e.g. install A2 then A1 which A2 depends on) - */ - public void testInstallArchives_ReverseDependency() { - - ArrayList<ArchiveInfo> archives = new ArrayList<ArchiveInfo>(); - - Archive a1 = new MockEmptyPackage("a1").getLocalArchive(); - ArchiveInfo ai1 = new ArchiveInfo(a1, null, null); - - Archive a2 = new MockEmptyPackage("a2").getLocalArchive(); - ArchiveInfo ai2 = new ArchiveInfo(a2, null, new ArchiveInfo[] { ai1 } ); - - archives.add(ai2); - archives.add(ai1); - - m._installArchives(archives); - assertEquals( - "[MockEmptyPackage 'a1', MockEmptyPackage 'a2']", - Arrays.toString(m.getInstalled())); - } - -} diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java deleted file mode 100755 index 7918885..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/UpdaterLogicTest.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.internal.avd.AvdManager; -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.ITaskFactory; -import com.android.sdklib.internal.repository.archives.Archive; -import com.android.sdklib.internal.repository.packages.MockAddonPackage; -import com.android.sdklib.internal.repository.packages.MockBrokenPackage; -import com.android.sdklib.internal.repository.packages.MockPlatformPackage; -import com.android.sdklib.internal.repository.packages.MockPlatformToolPackage; -import com.android.sdklib.internal.repository.packages.MockToolPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.internal.repository.sources.SdkSources; -import com.android.sdkuilib.internal.repository.icons.ImageFactory; -import com.android.utils.ILogger; - -import org.eclipse.swt.widgets.Shell; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import junit.framework.TestCase; - -public class UpdaterLogicTest extends TestCase { - - private static class NullUpdaterData implements IUpdaterData { - - @Override - public AvdManager getAvdManager() { - return null; - } - - @Override - public ImageFactory getImageFactory() { - return null; - } - - @Override - public ILogger getSdkLog() { - return null; - } - - @Override - public DownloadCache getDownloadCache() { - return null; - } - - @Override - public SdkManager getSdkManager() { - return null; - } - - @Override - public SettingsController getSettingsController() { - return null; - } - - @Override - public ITaskFactory getTaskFactory() { - return null; - } - - @Override - public Shell getWindowShell() { - return null; - } - - } - - private static class MockUpdaterLogic extends SdkUpdaterLogic { - private final Package[] mRemotePackages; - - public MockUpdaterLogic(IUpdaterData updaterData, Package[] remotePackages) { - super(updaterData); - mRemotePackages = remotePackages; - } - - @Override - protected void fetchRemotePackages(Collection<Package> remotePkgs, - SdkSource[] remoteSources) { - // Ignore remoteSources and instead uses the remotePackages list given to the - // constructor. - if (mRemotePackages != null) { - remotePkgs.addAll(Arrays.asList(mRemotePackages)); - } - } - } - - /** - * Addon packages depend on a base platform package. - * This test checks that UpdaterLogic.findPlatformToolsDependency(...) - * can find the base platform for a given addon. - */ - public void testFindAddonDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformPackage p1 = new MockPlatformPackage(1, 1); - MockPlatformPackage p2 = new MockPlatformPackage(2, 1); - - MockAddonPackage a1 = new MockAddonPackage(p1, 1); - MockAddonPackage a2 = new MockAddonPackage(p2, 2); - - ArrayList<ArchiveInfo> out = new ArrayList<ArchiveInfo>(); - ArrayList<Archive> selected = new ArrayList<Archive>(); - ArrayList<Package> remote = new ArrayList<Package>(); - - // a2 depends on p2, which is not in the locals - Package[] localPkgs = { p1, a1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // a2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying platform. - ArchiveInfo fai = mul.findPlatformDependency(a2, out, selected, remote, sources, locals); - assertNotNull(fai); - assertNull(fai.getNewArchive()); - assertTrue(fai.isRejected()); - assertEquals(0, out.size()); - - // p2 is now selected, and should be scheduled for install in out - Archive p2_archive = p2.getArchives()[0]; - selected.add(p2_archive); - ArchiveInfo ai2 = mul.findPlatformDependency(a2, out, selected, remote, sources, locals); - assertNotNull(ai2); - assertSame(p2_archive, ai2.getNewArchive()); - assertEquals(1, out.size()); - assertSame(p2_archive, out.get(0).getNewArchive()); - } - - /** - * Broken add-on packages require an exact platform package to be present or installed. - * This tests checks that findExactApiLevelDependency() can find a base - * platform package for a given broken add-on package. - */ - public void testFindExactApiLevelDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformPackage p1 = new MockPlatformPackage(1, 1); - MockPlatformPackage p2 = new MockPlatformPackage(2, 1); - - MockBrokenPackage a1 = new MockBrokenPackage(0, 1); - MockBrokenPackage a2 = new MockBrokenPackage(0, 2); - - ArrayList<ArchiveInfo> out = new ArrayList<ArchiveInfo>(); - ArrayList<Archive> selected = new ArrayList<Archive>(); - ArrayList<Package> remote = new ArrayList<Package>(); - - // a2 depends on p2, which is not in the locals - Package[] localPkgs = { p1, a1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // a1 depends on p1, which can be found in the locals. p1 is already "installed" - // so we donn't need to suggest it as a dependency to solve any problem. - ArchiveInfo found = mul.findExactApiLevelDependency( - a1, out, selected, remote, sources, locals); - assertNull(found); - - // a2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying platform. - found = mul.findExactApiLevelDependency(a2, out, selected, remote, sources, locals); - assertNotNull(found); - assertNull(found.getNewArchive()); - assertTrue(found.isRejected()); - assertEquals(0, out.size()); - - // p2 is now selected, and should be scheduled for install in out - Archive p2_archive = p2.getArchives()[0]; - selected.add(p2_archive); - found = mul.findExactApiLevelDependency(a2, out, selected, remote, sources, locals); - assertNotNull(found); - assertSame(p2_archive, found.getNewArchive()); - assertEquals(1, out.size()); - assertSame(p2_archive, out.get(0).getNewArchive()); - } - - /** - * Platform packages depend on a tool package. - * This tests checks that UpdaterLogic.findToolsDependency() can find a base - * tool package for a given platform package. - */ - public void testFindPlatformDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformToolPackage pt1 = new MockPlatformToolPackage(1); - - MockToolPackage t1 = new MockToolPackage(1, 1); - MockToolPackage t2 = new MockToolPackage(2, 1); - - MockPlatformPackage p2 = new MockPlatformPackage(2, 1, 2); - - ArrayList<ArchiveInfo> out = new ArrayList<ArchiveInfo>(); - ArrayList<Archive> selected = new ArrayList<Archive>(); - ArrayList<Package> remote = new ArrayList<Package>(); - - // p2 depends on t2, which is not locally installed - Package[] localPkgs = { t1, pt1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // p2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying tool - ArchiveInfo fai = mul.findToolsDependency(p2, out, selected, remote, sources, locals); - assertNotNull(fai); - assertNull(fai.getNewArchive()); - assertTrue(fai.isRejected()); - assertEquals(0, out.size()); - - // t2 is now selected and can be used as a dependency - Archive t2_archive = t2.getArchives()[0]; - selected.add(t2_archive); - ArchiveInfo ai2 = mul.findToolsDependency(p2, out, selected, remote, sources, locals); - assertNotNull(ai2); - assertSame(t2_archive, ai2.getNewArchive()); - assertEquals(1, out.size()); - assertSame(t2_archive, out.get(0).getNewArchive()); - } - - /** - * Tool packages require a platform-tool package to be present or installed. - * This tests checks that UpdaterLogic.findPlatformToolsDependency() can find a base - * platform-tool package for a given tool package. - */ - public void testFindPlatformToolDependency() { - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), null); - - MockPlatformToolPackage t1 = new MockPlatformToolPackage(1); - MockPlatformToolPackage t2 = new MockPlatformToolPackage(2); - - MockToolPackage p2 = new MockToolPackage(2, 2); - - ArrayList<ArchiveInfo> out = new ArrayList<ArchiveInfo>(); - ArrayList<Archive> selected = new ArrayList<Archive>(); - ArrayList<Package> remote = new ArrayList<Package>(); - - // p2 depends on t2, which is not locally installed - Package[] localPkgs = { t1 }; - ArchiveInfo[] locals = mul.createLocalArchives(localPkgs); - - SdkSource[] sources = null; - - // p2 now depends on a "fake" archive info with no newArchive that wraps the missing - // underlying tool - ArchiveInfo fai = mul.findPlatformToolsDependency( - p2, out, selected, remote, sources, locals); - assertNotNull(fai); - assertNull(fai.getNewArchive()); - assertTrue(fai.isRejected()); - assertEquals(0, out.size()); - - // t2 is now selected and can be used as a dependency - Archive t2_archive = t2.getArchives()[0]; - selected.add(t2_archive); - ArchiveInfo ai2 = mul.findPlatformToolsDependency( - p2, out, selected, remote, sources, locals); - assertNotNull(ai2); - assertSame(t2_archive, ai2.getNewArchive()); - assertEquals(1, out.size()); - assertSame(t2_archive, out.get(0).getNewArchive()); - } - - public void testComputeRevisionUpdate() { - // Scenario: - // - user has tools rev 7 installed + plat-tools rev 1 installed - // - server has tools rev 8, depending on plat-tools rev 2 - // - server has tools rev 9, depending on plat-tools rev 3 - // - server has platform 9 that requires min-tools-rev 9 - // - // If we do an update all, we want to the installer to pick up: - // - the new platform 9 - // - the tools rev 9 (required by platform 9) - // - the plat-tools rev 3 (required by tools rev 9) - - final MockPlatformToolPackage pt1 = new MockPlatformToolPackage(1); - final MockPlatformToolPackage pt2 = new MockPlatformToolPackage(2); - final MockPlatformToolPackage pt3 = new MockPlatformToolPackage(3); - - final MockToolPackage t7 = new MockToolPackage(7, 1 /*min-plat-tools*/); - final MockToolPackage t8 = new MockToolPackage(8, 2 /*min-plat-tools*/); - final MockToolPackage t9 = new MockToolPackage(9, 3 /*min-plat-tools*/); - - final MockPlatformPackage p9 = new MockPlatformPackage(9, 1, 9 /*min-tools*/); - - // Note: the mock updater logic gets the remotes packages from the array given - // here and bypasses the source (to avoid fetching any actual URLs) - MockUpdaterLogic mul = new MockUpdaterLogic(new NullUpdaterData(), - new Package[] { t8, pt2, t9, pt3, p9 }); - - SdkSources sources = new SdkSources(); - Package[] localPkgs = { t7, pt1 }; - - List<ArchiveInfo> selected = mul.computeUpdates( - null /*selectedArchives*/, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9]", - Arrays.toString(selected.toArray())); - - mul.addNewPlatforms( - selected, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9, " + - "SDK Platform Android android-9, API 9, revision 1]", - Arrays.toString(selected.toArray())); - - // Now try again but reverse the order of the remote package list. - - mul = new MockUpdaterLogic(new NullUpdaterData(), - new Package[] { p9, t9, pt3, t8, pt2 }); - - selected = mul.computeUpdates( - null /*selectedArchives*/, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9]", - Arrays.toString(selected.toArray())); - - mul.addNewPlatforms( - selected, - sources, - localPkgs, - false /*includeObsoletes*/); - - assertEquals( - "[Android SDK Platform-tools, revision 3, " + - "Android SDK Tools, revision 9, " + - "SDK Platform Android android-9, API 9, revision 1]", - Arrays.toString(selected.toArray())); - } -} diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/core/PackagesDiffLogicTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/core/PackagesDiffLogicTest.java deleted file mode 100755 index 1f7a27a..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/core/PackagesDiffLogicTest.java +++ /dev/null @@ -1,1814 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.core; - -import com.android.SdkConstants; -import com.android.sdklib.internal.repository.packages.BrokenPackage; -import com.android.sdklib.internal.repository.packages.FullRevision; -import com.android.sdklib.internal.repository.packages.MockAddonPackage; -import com.android.sdklib.internal.repository.packages.MockBrokenPackage; -import com.android.sdklib.internal.repository.packages.MockEmptyPackage; -import com.android.sdklib.internal.repository.packages.MockExtraPackage; -import com.android.sdklib.internal.repository.packages.MockPlatformPackage; -import com.android.sdklib.internal.repository.packages.MockPlatformToolPackage; -import com.android.sdklib.internal.repository.packages.MockSystemImagePackage; -import com.android.sdklib.internal.repository.packages.MockToolPackage; -import com.android.sdklib.internal.repository.packages.Package; -import com.android.sdklib.internal.repository.sources.SdkRepoSource; -import com.android.sdklib.internal.repository.sources.SdkSource; -import com.android.sdklib.repository.PkgProps; -import com.android.sdkuilib.internal.repository.ISettingsPage; -import com.android.sdkuilib.internal.repository.MockUpdaterData; -import com.android.sdkuilib.internal.repository.core.PackagesDiffLogic; -import com.android.sdkuilib.internal.repository.core.PkgCategory; -import com.android.sdkuilib.internal.repository.core.PkgItem; - -import java.util.Properties; - -import junit.framework.TestCase; - -public class PackagesDiffLogicTest extends TestCase { - - private PackagesDiffLogic m; - private MockUpdaterData u; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - u = new MockUpdaterData(); - m = new PackagesDiffLogic(u); - } - - @Override - protected void tearDown() throws Exception { - super.tearDown(); - } - - // ---- - // - // Test Details Note: the way load is implemented in PackageLoader, the - // loader processes each source and then for each source the packages are added - // to a list and the sorting algorithm is called with that list. Thus for - // one load, many calls to the sortByX/Y happen, with the list progressively - // being populated. - // However when the user switches sorting algorithm, the package list is not - // reloaded and is processed at once. - - public void testSortByApi_Empty() { - m.updateStart(); - assertFalse(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[0])); - assertFalse(m.updateEnd(true /*sortByApi*/)); - - // We also keep these 2 categories even if they contain nothing - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - } - - public void testSortByApi_AddSamePackage() { - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - m.updateStart(); - // First insert local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "some pkg", 1) - })); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'some pkg' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - - // Insert the next source - // Same package as the one installed, so we don't display it - assertFalse(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "some pkg", 1) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'some pkg' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - } - - public void testSortByApi_AddOtherPackage() { - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - m.updateStart(); - // First insert local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "some pkg", 1) - })); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'some pkg' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - - // Insert the next source - // Not the same package as the one installed, so we'll display it - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "other pkg", 1) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'some pkg' rev=1>\n" + - "-- <NEW, pkg:MockEmptyPackage 'other pkg' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - } - - public void testSortByApi_Update1() { - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - // Typical case: user has a locally installed package in revision 1 - // The display list after sort should show that installed package. - m.updateStart(); - // First insert local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 4), - new MockEmptyPackage(src1, "type1", 2) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=4>\n", - getTree(m, true /*displaySortByApi*/)); - } - - public void testSortByApi_Reload() { - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - // First load reveals a package local package and its update - m.updateStart(); - // First insert local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n", - getTree(m, true /*displaySortByApi*/)); - - // Now simulate a reload that clears the package list and creates similar - // objects but not the same references. The only difference is that updateXyz - // returns false since nothing changes. - - m.updateStart(); - // First insert local packages - assertFalse(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - assertFalse(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n", - getTree(m, true /*displaySortByApi*/)); - } - - public void testSortByApi_InstallPackage() { - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - // First load reveals a new package - m.updateStart(); - // No local packages at first - assertFalse(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[0])); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - - // Install it. - m.updateStart(); - // local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - assertFalse(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - - assertTrue(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - - // Load reveals an update - m.updateStart(); - // local packages - assertFalse(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n", - getTree(m, true /*displaySortByApi*/)); - } - - public void testSortByApi_DeletePackage() { - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - // We have an installed package - m.updateStart(); - // local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n", - getTree(m, true /*displaySortByApi*/)); - - // User now deletes the installed package. - m.updateStart(); - // No local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[0])); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - })); - - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, true /*displaySortByApi*/)); - } - - public void testSortByApi_NoRemoteSources() { - SdkSource src1 = new SdkRepoSource("http://example.com/url1", "repo1"); - SdkSource src2 = new SdkRepoSource("http://example.com/url2", "repo2"); - - // We have a couple installed packages - m.updateStart(); - // local packages - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src2, "carrier", "custom_rom", 1, 0), - new MockExtraPackage(src2, "android", "usb_driver", 5, 3), - })); - // and no remote sources have been loaded (e.g. because there's no network) - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 5>\n" + - "-- <INSTALLED, pkg:Carrier Custom Rom, revision 1>\n", - getTree(m, true /*displaySortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategorySource <source=repo2 (example.com), #items=2>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 5>\n" + - "-- <INSTALLED, pkg:Carrier Custom Rom, revision 1>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSortByApi_CompleteUpdate() { - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - SdkSource src2 = new SdkRepoSource("http://2.example.com/url2", "repo2"); - - // Resulting categories are sorted by Tools, descending platform API and finally Extras. - // Addons are sorted by name within their API. - // Extras are sorted by vendor name. - // The order packages are added to the mAllPkgItems list is purposedly different from - // the final order we get. - - // First update has the typical tools and a couple extras - m.updateStart(); - - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "android", "usb_driver", 4, 3), - })); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "carrier", "custom_rom", 1, 0), - new MockExtraPackage(src1, "android", "usb_driver", 5, 3), - })); - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 4, updated by:Android USB Driver, revision 5>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n", - getTree(m, true /*displaySortByApi*/)); - - // Next update adds platforms and addon, sorted in a category based on their API level - m.updateStart(); - MockPlatformPackage p1; - MockPlatformPackage p2; - @SuppressWarnings("unused") // keep p3 for clarity - MockPlatformPackage p3; - - assertTrue(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "android", "usb_driver", 4, 3), - // second update - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - p3 = new MockPlatformPackage(src1, 3, 6, 3), - new MockAddonPackage(src2, "addon A", p1, 5), - new MockAddonPackage(src2, "addon D", p1, 10), - })); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "carrier", "custom_rom", 1, 0), - new MockExtraPackage(src1, "android", "usb_driver", 5, 3), - // second update - p2 = new MockPlatformPackage(src1, 2, 4, 3), // API 2 - })); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src2, new Package[] { - new MockAddonPackage(src2, "addon C", p2, 9), - new MockAddonPackage(src2, "addon A", p1, 6), - // the rev 7+8 will be ignored since there's a rev 9 coming after - new MockAddonPackage(src2, "addon B", p2, 7), - new MockAddonPackage(src2, "addon B", p2, 8), - new MockAddonPackage(src2, "addon B", p2, 9), - // 11+12 should be ignored updates, 13 will update 10 - new MockAddonPackage(src2, "addon D", p1, 10), - new MockAddonPackage(src2, "addon D", p1, 12), // note: 12 listed before 11 - new MockAddonPackage(src2, "addon D", p1, 11), - new MockAddonPackage(src2, "addon D", p1, 13), - })); - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=API 3, label=Android android-3 (API 3), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-3, API 3, revision 6>\n" + - "PkgCategoryApi <API=API 2, label=Android android-2 (API 2), #items=3>\n" + - "-- <NEW, pkg:SDK Platform Android android-2, API 2, revision 4>\n" + - "-- <NEW, pkg:The addon B from vendor 2, Android API 2, revision 9>\n" + - "-- <NEW, pkg:The addon C from vendor 2, Android API 2, revision 9>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=3>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 5, updated by:The addon A from vendor 1, Android API 1, revision 6>\n" + - "-- <INSTALLED, pkg:The addon D from vendor 1, Android API 1, revision 10, updated by:The addon D from vendor 1, Android API 1, revision 13>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 4, updated by:Android USB Driver, revision 5>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n", - getTree(m, true /*displaySortByApi*/)); - - // Reloading the same thing should have no impact except for the update methods - // returning false when they don't change the current list. - m.updateStart(); - - assertFalse(m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "android", "usb_driver", 4, 3), - // second update - p1 = new MockPlatformPackage(src1, 1, 2, 3), - p3 = new MockPlatformPackage(src1, 3, 6, 3), - new MockAddonPackage(src2, "addon A", p1, 5), - new MockAddonPackage(src2, "addon D", p1, 10), - })); - assertFalse(m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "carrier", "custom_rom", 1, 0), - new MockExtraPackage(src1, "android", "usb_driver", 5, 3), - // second update - p2 = new MockPlatformPackage(src1, 2, 4, 3), - })); - assertTrue(m.updateSourcePackages(true /*sortByApi*/, src2, new Package[] { - new MockAddonPackage(src2, "addon C", p2, 9), - new MockAddonPackage(src2, "addon A", p1, 6), - // the rev 7+8 will be ignored since there's a rev 9 coming after - new MockAddonPackage(src2, "addon B", p2, 7), - new MockAddonPackage(src2, "addon B", p2, 8), - new MockAddonPackage(src2, "addon B", p2, 9), - // 11+12 should be ignored updates, 13 will update 10 - new MockAddonPackage(src2, "addon D", p1, 10), - new MockAddonPackage(src2, "addon D", p1, 12), // note: 12 listed before 11 - new MockAddonPackage(src2, "addon D", p1, 11), - new MockAddonPackage(src2, "addon D", p1, 13), - })); - assertFalse(m.updateEnd(true /*sortByApi*/)); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=API 3, label=Android android-3 (API 3), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-3, API 3, revision 6>\n" + - "PkgCategoryApi <API=API 2, label=Android android-2 (API 2), #items=3>\n" + - "-- <NEW, pkg:SDK Platform Android android-2, API 2, revision 4>\n" + - "-- <NEW, pkg:The addon B from vendor 2, Android API 2, revision 9>\n" + - "-- <NEW, pkg:The addon C from vendor 2, Android API 2, revision 9>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=3>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 5, updated by:The addon A from vendor 1, Android API 1, revision 6>\n" + - "-- <INSTALLED, pkg:The addon D from vendor 1, Android API 1, revision 10, updated by:The addon D from vendor 1, Android API 1, revision 13>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 4, updated by:Android USB Driver, revision 5>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n", - getTree(m, true /*displaySortByApi*/)); - } - - // ---- - - public void testSortBySource_Empty() { - m.updateStart(); - assertFalse(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[0])); - // UpdateEnd returns true since it removed the synthetic "unknown source" category - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertTrue(m.getCategories(false /*sortByApi*/).isEmpty()); - - assertEquals( - "", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSortBySource_AddPackages() { - // Since we're sorting by source, items are grouped under their source - // even if installed. The 'local' source is only for installed items for - // which we don't know the source. - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - m.updateStart(); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "known source", 2), - new MockEmptyPackage(null, "unknown source", 3), - })); - - assertEquals( - "PkgCategorySource <source=Local Packages (no.source), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'unknown source' rev=3>\n" + - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'known source' rev=2>\n", - getTree(m, false /*displaySortByApi*/)); - - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "new", 1), - })); - - assertFalse(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=Local Packages (no.source), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'unknown source' rev=3>\n" + - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'new' rev=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'known source' rev=2>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSortBySource_Update1() { - - // Typical case: user has a locally installed package in revision 1 - // The display list after sort should show that instaled package. - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - m.updateStart(); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - - assertEquals( - "PkgCategorySource <source=Local Packages (no.source), #items=0>\n" + - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, false /*displaySortByApi*/)); - - // Edge case: the source reveals an update in revision 2. It is ignored since - // we already have a package in rev 4. - - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 4), - new MockEmptyPackage(src1, "type1", 2), - })); - - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=4>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSortBySource_Reload() { - - // First load reveals a package local package and its update - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - m.updateStart(); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now simulate a reload that clears the package list and creates similar - // objects but not the same references. Update methods return false since - // they don't change anything. - m.updateStart(); - assertFalse(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertFalse(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSortBySource_InstallPackage() { - - // First load reveals a new package - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - m.updateStart(); - // no local package - assertFalse(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[0])); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, false /*displaySortByApi*/)); - - - // Install it. The display only shows the installed one, 'hiding' the remote package - m.updateStart(); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertFalse(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now we have an update - m.updateStart(); - assertFalse(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSortBySource_DeletePackage() { - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - - // Start with an installed package and its matching remote package - m.updateStart(); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertFalse(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, false /*displaySortByApi*/)); - - // User now deletes the installed package. - m.updateStart(); - // no local package - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[0])); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 1), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type1' rev=1>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSortBySource_CompleteUpdate() { - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - SdkSource src2 = new SdkRepoSource("http://2.example.com/url2", "repo2"); - - // First update has the typical tools and a couple extras - m.updateStart(); - - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "android", "usb_driver", 4, 3), - })); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "carrier", "custom_rom", 1, 0), - new MockExtraPackage(src1, "android", "usb_driver", 5, 3), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=4>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 4, updated by:Android USB Driver, revision 5>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n", - getTree(m, false /*displaySortByApi*/)); - - // Next update adds platforms and addon, sorted in a category based on their API level - m.updateStart(); - MockPlatformPackage p1; - MockPlatformPackage p2; - @SuppressWarnings("unused") // keep p3 for clarity - MockPlatformPackage p3; - - assertTrue(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "android", "usb_driver", 4, 3), - // second update - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - p3 = new MockPlatformPackage(src1, 3, 6, 3), - new MockPlatformPackage(src1, 3, 6, 3), // API 3 - new MockAddonPackage(src2, "addon A", p1, 5), - new MockAddonPackage(src2, "addon D", p1, 10), - })); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "carrier", "custom_rom", 1, 0), - new MockExtraPackage(src1, "android", "usb_driver", 5, 3), - // second update - p2 = new MockPlatformPackage(src1, 2, 4, 3), // API 2 - })); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src2, new Package[] { - new MockAddonPackage(src2, "addon C", p2, 9), - new MockAddonPackage(src2, "addon A", p1, 6), - // the rev 7+8 will be ignored since there's a rev 9 coming after - new MockAddonPackage(src2, "addon B", p2, 7), - new MockAddonPackage(src2, "addon B", p2, 8), - new MockAddonPackage(src2, "addon B", p2, 9), - // 11+12 should be ignored updates, 13 will update 10 - new MockAddonPackage(src2, "addon D", p1, 10), - new MockAddonPackage(src2, "addon D", p1, 12), // note: 12 listed before 11 - new MockAddonPackage(src2, "addon D", p1, 11), - new MockAddonPackage(src2, "addon D", p1, 13), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=7>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-3, API 3, revision 6>\n" + - "-- <NEW, pkg:SDK Platform Android android-2, API 2, revision 4>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 4, updated by:Android USB Driver, revision 5>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n" + - "PkgCategorySource <source=repo2 (2.example.com), #items=4>\n" + - "-- <NEW, pkg:The addon B from vendor 2, Android API 2, revision 9>\n" + - "-- <NEW, pkg:The addon C from vendor 2, Android API 2, revision 9>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 5, updated by:The addon A from vendor 1, Android API 1, revision 6>\n" + - "-- <INSTALLED, pkg:The addon D from vendor 1, Android API 1, revision 10, updated by:The addon D from vendor 1, Android API 1, revision 13>\n", - getTree(m, false /*displaySortByApi*/)); - - // Reloading the same thing should have no impact except for the update methods - // returning false when they don't change the current list. - m.updateStart(); - - assertFalse(m.updateSourcePackages(false /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "android", "usb_driver", 4, 3), - // second update - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - p3 = new MockPlatformPackage(src1, 3, 6, 3), - new MockPlatformPackage(src1, 3, 6, 3), // API 3 - new MockAddonPackage(src2, "addon A", p1, 5), - new MockAddonPackage(src2, "addon D", p1, 10), - })); - assertFalse(m.updateSourcePackages(false /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "carrier", "custom_rom", 1, 0), - new MockExtraPackage(src1, "android", "usb_driver", 5, 3), - // second update - p2 = new MockPlatformPackage(src1, 2, 4, 3), - })); - assertTrue(m.updateSourcePackages(false /*sortByApi*/, src2, new Package[] { - new MockAddonPackage(src2, "addon C", p2, 9), - new MockAddonPackage(src2, "addon A", p1, 6), - // the rev 7+8 will be ignored since there's a rev 9 coming after - new MockAddonPackage(src2, "addon B", p2, 7), - new MockAddonPackage(src2, "addon B", p2, 8), - new MockAddonPackage(src2, "addon B", p2, 9), - // 11+12 should be ignored updates, 13 will update 10 - new MockAddonPackage(src2, "addon D", p1, 10), - new MockAddonPackage(src2, "addon D", p1, 12), // note: 12 listed before 11 - new MockAddonPackage(src2, "addon D", p1, 11), - new MockAddonPackage(src2, "addon D", p1, 13), - })); - assertTrue(m.updateEnd(false /*sortByApi*/)); - - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=7>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 10>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-3, API 3, revision 6>\n" + - "-- <NEW, pkg:SDK Platform Android android-2, API 2, revision 4>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <INSTALLED, pkg:Android USB Driver, revision 4, updated by:Android USB Driver, revision 5>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n" + - "PkgCategorySource <source=repo2 (2.example.com), #items=4>\n" + - "-- <NEW, pkg:The addon B from vendor 2, Android API 2, revision 9>\n" + - "-- <NEW, pkg:The addon C from vendor 2, Android API 2, revision 9>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 5, updated by:The addon A from vendor 1, Android API 1, revision 6>\n" + - "-- <INSTALLED, pkg:The addon D from vendor 1, Android API 1, revision 10, updated by:The addon D from vendor 1, Android API 1, revision 13>\n", - getTree(m, false /*displaySortByApi*/)); - } - - // ---- - - public void testIsFirstLoadComplete() { - // isFirstLoadComplete is a simple toggle that goes from true to false when read once - assertTrue(m.isFirstLoadComplete()); - assertFalse(m.isFirstLoadComplete()); - assertFalse(m.isFirstLoadComplete()); - } - - public void testCheckNewUpdateItems_NewOnly() { - // Populate the list with a few items and an update - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "has update", 1), - new MockEmptyPackage(src1, "no update", 4) - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "has update", 2), - new MockEmptyPackage(src1, "new stuff", 3), - }); - m.updateEnd(true /*sortByApi*/); - // Nothing is checked at first - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now request to check new items only - m.checkNewUpdateItems(true, false, false, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- < * NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- < * NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testCheckNewUpdateItems_UpdateOnly() { - // Populate the list with a few items and an update - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "has update", 1), - new MockEmptyPackage(src1, "no update", 4) - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "has update", 2), - new MockEmptyPackage(src1, "new stuff", 3), - }); - m.updateEnd(true /*sortByApi*/); - // Nothing is checked at first - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now request to check update items only - m.checkNewUpdateItems(false, true, false, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=3>\n" + - "-- < * INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=3>\n" + - "-- < * INSTALLED, pkg:MockEmptyPackage 'has update' rev=1, updated by:MockEmptyPackage 'has update' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'new stuff' rev=3>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'no update' rev=4>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testCheckNewUpdateItems_SelectInitial() { - // Populate the list with typical items: tools, platforms tools, extras, 2 platforms. - // With nothing installed, this should pick the top platform and its system images - // (the mock platform claims to not have any included abi) - // It's ok not to select the tools, since they are a dependency of all platforms. - - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - SdkSource src2 = new SdkRepoSource("http://2.example.com/url2", "repo2"); - - m.updateStart(); - MockPlatformPackage p1; - MockPlatformPackage p2; - - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 10, 3), - new MockPlatformToolPackage(src1, 3), - new MockExtraPackage(src1, "google", "usb_driver", 5, 3), - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - p2 = new MockPlatformPackage(src1, 2, 4, 3), // API 2 - new MockSystemImagePackage(src1, p2, 1, "armeabi"), - new MockSystemImagePackage(src1, p2, 1, "x86"), - }); - m.updateSourcePackages(true /*sortByApi*/, src2, new Package[] { - new MockAddonPackage(src2, "addon A", p1, 5), - new MockAddonPackage(src2, "addon B", p2, 7), - new MockExtraPackage(src2, "carrier", "custom_rom", 1, 0), - }); - m.updateEnd(true /*sortByApi*/); - - m.checkNewUpdateItems(false, true, true, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 10>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=API 2, label=Android android-2 (API 2), #items=4>\n" + - "-- < * NEW, pkg:SDK Platform Android android-2, API 2, revision 4>\n" + - "-- < * NEW, pkg:ARM EABI System Image, Android API 2, revision 1>\n" + - "-- < * NEW, pkg:Intel x86 Atom System Image, Android API 2, revision 1>\n" + - "-- < * NEW, pkg:The addon B from vendor 2, Android API 2, revision 7>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=2>\n" + - "-- <NEW, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 5>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n" + - "-- <NEW, pkg:Google USB Driver, revision 5>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=7>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 10>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 3>\n" + - "-- < * NEW, pkg:SDK Platform Android android-2, API 2, revision 4>\n" + - "-- <NEW, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- < * NEW, pkg:ARM EABI System Image, Android API 2, revision 1>\n" + - "-- < * NEW, pkg:Intel x86 Atom System Image, Android API 2, revision 1>\n" + - "-- <NEW, pkg:Google USB Driver, revision 5>\n" + - "PkgCategorySource <source=repo2 (2.example.com), #items=3>\n" + - "-- < * NEW, pkg:The addon B from vendor 2, Android API 2, revision 7>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 5>\n" + - "-- <NEW, pkg:Carrier Custom Rom, revision 1>\n", - getTree(m, false /*displaySortByApi*/)); - - // We don't install the USB driver by default on Mac or Linux, only on Windows - m.clear(); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockExtraPackage(src1, "google", "usb_driver", 5, 3), - }); - m.updateEnd(true /*sortByApi*/); - m.checkNewUpdateItems(false, true, true, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <NEW, pkg:Google USB Driver, revision 5>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=1>\n" + - "-- <NEW, pkg:Google USB Driver, revision 5>\n", - getTree(m, false /*displaySortByApi*/)); - - m.clear(); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockExtraPackage(src1, "google", "usb_driver", 5, 3), - }); - m.updateEnd(true /*sortByApi*/); - m.checkNewUpdateItems(false, true, true, SdkConstants.PLATFORM_DARWIN); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <NEW, pkg:Google USB Driver, revision 5>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=1>\n" + - "-- <NEW, pkg:Google USB Driver, revision 5>\n", - getTree(m, false /*displaySortByApi*/)); - - m.clear(); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockExtraPackage(src1, "google", "usb_driver", 5, 3), - }); - m.updateEnd(true /*sortByApi*/); - m.checkNewUpdateItems(false, true, true, SdkConstants.PLATFORM_WINDOWS); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- < * NEW, pkg:Google USB Driver, revision 5>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=1>\n" + - "-- < * NEW, pkg:Google USB Driver, revision 5>\n", - getTree(m, false /*displaySortByApi*/)); - - } - - public void testCheckUncheckAllItems() { - // Populate the list with a couple items and an update - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockEmptyPackage(src1, "type1", 1) - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockEmptyPackage(src1, "type1", 2), - new MockEmptyPackage(src1, "type3", 3), - }); - m.updateEnd(true /*sortByApi*/); - // Nothing is checked at first - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, true /*displaySortByApi*/)); - - // Manually check the items in the sort-by-API case, but not the source - for (PkgItem item : m.getAllPkgItems(true /*byApi*/, false /*bySource*/)) { - item.setChecked(true); - } - - // by-api sort should be checked but not by source - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- < * INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- < * NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, false /*displaySortByApi*/)); - - // now uncheck them all - m.uncheckAllItems(); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, false /*displaySortByApi*/)); - - // Manually check the items in both by-api and by-source - for (PkgItem item : m.getAllPkgItems(true /*byApi*/, true /*bySource*/)) { - item.setChecked(true); - } - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- < * INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- < * NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- < * INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- < * NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, false /*displaySortByApi*/)); - - // now uncheck them all - m.uncheckAllItems(); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- <INSTALLED, pkg:MockEmptyPackage 'type1' rev=1, updated by:MockEmptyPackage 'type1' rev=2>\n" + - "-- <NEW, pkg:MockEmptyPackage 'type3' rev=3>\n", - getTree(m, false /*displaySortByApi*/)); - } - - // ---- - - public void testLocalIsNewer() { - // This tests an edge case that typically happens only during development where - // one would have a local package which revision number is larger than what the - // remove repositories can offer. In this case we don't want to offer the remote - // package as an "upgrade" nor as a downgrade. - - // Populate the list with local revisions 5 and lower remote revisions 3 - SdkSource src1 = new SdkRepoSource("http://example.com/url", "repo1"); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage( src1, 5, 5), - new MockPlatformToolPackage(src1, 5), - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage( src1, 3, 3), - new MockPlatformToolPackage(src1, 3), - }); - m.updateEnd(true /*sortByApi*/); - - // The remote packages in rev 3 are hidden by the local packages in rev 5 - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 5>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 5>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 5>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 5>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testSourceDups() { - // This tests an edge case were 2 remote repositories are giving the - // same kind of packages. In rev 14, we didn't want to merge them together - // unless they had the same hostname. In rev 15, we now treat them the same. - - // repo1, 2 and 3 have the same hostname so redundancy is ok - SdkSource src1 = new SdkRepoSource("http://example.com/url1", "repo1"); - SdkSource src2 = new SdkRepoSource("http://example.com/url2", "repo2"); - SdkSource src3 = new SdkRepoSource("http://example.com/url3", "repo3"); - // repo4 has a different hostname but as of rev 15, the packages will be merged together. - SdkSource src4 = new SdkRepoSource("http://4.example.com/url4", "repo4"); - MockPlatformPackage p1 = null; - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage( src1, 3, 3), - new MockPlatformToolPackage(src1, 3), - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - }); - m.updateSourcePackages(true /*sortByApi*/, src2, new Package[] { - new MockAddonPackage(src2, "addon A", p1, 5), - new MockAddonPackage(src2, "addon B", p1, 6), - }); - m.updateSourcePackages(true /*sortByApi*/, src3, new Package[] { - new MockAddonPackage(src3, "addon A", p1, 5), // same as addon A rev 5 from src2 - new MockAddonPackage(src3, "addon B", p1, 7), // upgrades addon B rev 6 from src2 - }); - m.updateSourcePackages(true /*sortByApi*/, src4, new Package[] { - new MockAddonPackage(src4, "addon A", p1, 5), // same as addon A rev 5 from src2 - new MockAddonPackage(src4, "addon B", p1, 7), // upgrades addon B rev 6 from src2 - }); - m.updateEnd(true /*sortByApi*/); - - // The remote packages in rev 3 are hidden by the local packages in rev 5. - // When sorting by API, the user can tell where the packages come from by looking - // at the UI tooltip on the packages. - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=3>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 5>\n" + // from src2+3+4 - "-- <NEW, pkg:The addon B from vendor 1, Android API 1, revision 7>\n" + // from src3+4 - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - // When sorting by source, the src4 source is listed, however since its - // packages are the same as the ones from src2 or src3 the packages themselves - // are not shown. - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=3>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategorySource <source=repo2 (example.com), #items=1>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 5>\n" + // from src2+3+4 - "PkgCategorySource <source=repo3 (example.com), #items=1>\n" + - "-- <NEW, pkg:The addon B from vendor 1, Android API 1, revision 7>\n" + // from src3+4 - "PkgCategorySource <source=repo4 (4.example.com), #items=0>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testRenamedExtraPackage() { - // Starting with schemas repo v5 and addon v3, an extra package can be renamed - // using the "old-paths" attribute. This test checks that the diff logic will - // match an old extra and its new name together. - - // First scenario: local pkg "old_path1" and remote pkg "new_path2". - // Since the new package does not provide an old_paths attribute, the - // new package is not treated as an update. - - SdkSource src1 = new SdkRepoSource("http://example.com/url1", "repo1"); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockExtraPackage(src1, "vendor1", "old_path1", 1, 1), - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockExtraPackage(src1, "vendor1", "new_path2", 2, 1), - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=2>\n" + - "-- <NEW, pkg:Vendor1 New Path2, revision 2>\n" + - "-- <INSTALLED, pkg:Vendor1 Old Path1, revision 1>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=2>\n" + - "-- <NEW, pkg:Vendor1 New Path2, revision 2>\n" + - "-- <INSTALLED, pkg:Vendor1 Old Path1, revision 1>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now, start again, but this time the new package uses the old-path attribute - Properties props = new Properties(); - props.setProperty(PkgProps.EXTRA_OLD_PATHS, "old_path1;oldpath2"); - m.clear(); - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockExtraPackage(src1, "vendor1", "old_path1", 1, 1), - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockExtraPackage(src1, props, "vendor1", "new_path2", 2), - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:Vendor1 Old Path1, revision 1, updated by:Vendor1 New Path2, revision 2>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (example.com), #items=1>\n" + - "-- <INSTALLED, pkg:Vendor1 Old Path1, revision 1, updated by:Vendor1 New Path2, revision 2>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testBrokenAddon() { - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - SdkSource src2 = new SdkRepoSource("http://2.example.com/url2", "repo2"); - - MockPlatformPackage p1 = null; - MockAddonPackage a1 = null; - - // User has a platform + addon locally installed - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - a1 = new MockAddonPackage(src2, "addon A", p1, 4), - }); - m.updateSourcePackages(true /*sortByApi*/, src1 /*locals*/, new Package[] { - p1 - }); - m.updateSourcePackages(true /*sortByApi*/, src2 /*locals*/, new Package[] { - a1 - }); - m.updateEnd(true /*sortByApi*/); - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=2>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 4>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategorySource <source=repo2 (2.example.com), #items=1>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 4>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now user deletes the platform on disk and reload. - // The local package parser will only find a broken addon. - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockBrokenPackage(BrokenPackage.MIN_API_LEVEL_NOT_SPECIFIED, 1), - }); - m.updateSourcePackages(true /*sortByApi*/, src1 /*locals*/, new Package[] { - new MockPlatformPackage(src1, 1, 2, 3) - }); - m.updateSourcePackages(true /*sortByApi*/, src2 /*locals*/, new Package[] { - new MockAddonPackage(src2, "addon A", p1, 4) - }); - m.updateEnd(true /*sortByApi*/); - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=2>\n" + - "-- <NEW, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 4>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=1>\n" + - "-- <INSTALLED, pkg:Broken package for API 1>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=1>\n" + - "-- <NEW, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategorySource <source=repo2 (2.example.com), #items=1>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 4>\n" + - "PkgCategorySource <source=Local Packages (no.source), #items=1>\n" + - "-- <INSTALLED, pkg:Broken package for API 1>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now user restores the missing platform on disk. - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - a1 = new MockAddonPackage(src2, "addon A", p1, 4), - }); - m.updateSourcePackages(true /*sortByApi*/, src1 /*locals*/, new Package[] { - p1 - }); - m.updateSourcePackages(true /*sortByApi*/, src2 /*locals*/, new Package[] { - a1 - }); - m.updateEnd(true /*sortByApi*/); - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=0>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=2>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 4>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategorySource <source=repo2 (2.example.com), #items=1>\n" + - "-- <INSTALLED, pkg:The addon A from vendor 1, Android API 1, revision 4>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testToolsUpdate() { - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - SdkSource src2 = new SdkRepoSource("http://2.example.com/url2", "repo2"); - MockPlatformPackage p1; - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(3, 3), // tool package has no source defined - new MockPlatformToolPackage(src1, 3), - p1 = new MockPlatformPackage(src1, 1, 2, 3), // API 1 - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 4, 4), - new MockPlatformToolPackage(src1, 4), - }); - m.updateSourcePackages(true /*sortByApi*/, src2, new Package[] { - new MockAddonPackage(src2, "addon A", p1, 5), - new MockAddonPackage(src2, "addon B", p1, 6), - }); - m.updateEnd(true /*sortByApi*/); - - // The remote packages in rev 3 are hidden by the local packages in rev 5 - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 4>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3, updated by:Android SDK Platform-tools, revision 4>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=3>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 5>\n" + - "-- <NEW, pkg:The addon B from vendor 1, Android API 1, revision 6>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=Local Packages (no.source), #items=1>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 4>\n" + - "PkgCategorySource <source=repo1 (1.example.com), #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3, updated by:Android SDK Platform-tools, revision 4>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategorySource <source=repo2 (2.example.com), #items=2>\n" + - "-- <NEW, pkg:The addon A from vendor 1, Android API 1, revision 5>\n" + - "-- <NEW, pkg:The addon B from vendor 1, Android API 1, revision 6>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testToolsMinorUpdate() { - // Test: Check a minor revision updates an installed major revision. - - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(3, 3), // Tools 3.0.0 - new MockPlatformToolPackage(src1, 3), - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, new FullRevision(3, 0, 1), 3), // Tools 3.0.1 - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 3.0.1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=Local Packages (no.source), #items=1>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 3.0.1>\n" + - "PkgCategorySource <source=repo1 (1.example.com), #items=1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testToolsPreviewsDisabled() { - // Test: No local tools installed. The remote server has both tools and platforms - // in release and RC versions. However the settings "enable previews" is disabled - // (which is the default) so the previews are not actually loaded from the server. - - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, new FullRevision(2, 0, 0), 3), // Tools 2 - new MockToolPackage(src1, new FullRevision(4, 0, 0, 1), 3), // Tools 4 rc1 - new MockPlatformToolPackage(src1, new FullRevision(3, 0, 0)), // Plat-T 3 - new MockPlatformToolPackage(src1, new FullRevision(5, 0, 0, 1)), // Plat-T 5 rc1 - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 2>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 2>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 3>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testToolsPreviews() { - // Test: No local tools installed. The remote server has both tools and platforms - // in release and RC versions. - - // Enable previews in the settings - u.overrideSetting(ISettingsPage.KEY_ENABLE_PREVIEWS, true); - - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, new FullRevision(2, 0, 0), 3), // Tools 2 - new MockToolPackage(src1, new FullRevision(4, 0, 0, 1), 3), // Tools 4 rc1 - new MockPlatformToolPackage(src1, new FullRevision(3, 0, 0)), // Plat-T 3 - new MockPlatformToolPackage(src1, new FullRevision(5, 0, 0, 1)), // Plat-T 5 rc1 - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 2>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 3>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 4 rc1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 5 rc1>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=4>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 4 rc1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 3>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 5 rc1>\n", - getTree(m, false /*displaySortByApi*/)); - } - - public void testPreviewUpdateInstalledRelease() { - // Test: Local release Tools 3.0.0 installed, server has both a release 3.0.1 available - // and a Tools Preview 4.0.0 rc1 available. - // => v3 is updated by 3.0.1 - // => v4.0.0rc1 does not update 3.0.0, instead it's a separate download. - - // Enable previews in the settings - u.overrideSetting(ISettingsPage.KEY_ENABLE_PREVIEWS, true); - - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(3, 3), // tool package has no source defined - new MockPlatformToolPackage(src1, 3), - new MockPlatformPackage(src1, 1, 2, 3), // API 1 - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, 3, 3), // Tools 3 - new MockToolPackage(src1, new FullRevision(3, 0, 1), 3), // Tools 3.0.1 - new MockToolPackage(src1, new FullRevision(4, 0, 0, 1), 3), // Tools 4 rc1 - new MockPlatformToolPackage(src1, new FullRevision(3, 0, 1)), // PT 3.0.1 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 0, 1)), // PT 4 rc1 - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 3.0.1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3, updated by:Android SDK Platform-tools, revision 3.0.1>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 4 rc1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4 rc1>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=Local Packages (no.source), #items=1>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 3.0.1>\n" + - "PkgCategorySource <source=repo1 (1.example.com), #items=4>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 4 rc1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 3, updated by:Android SDK Platform-tools, revision 3.0.1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4 rc1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n", - getTree(m, false /*displaySortByApi*/)); - - // Now request to check new items and updates: - // Tools 4 rc1 is greater than the installed Tools 3, but it's a preview so we will NOT - // auto-select it by default even though we requested to select "NEW" packages. We - // want the user to manually opt-in into the rc/preview package. - // However Tools 3 has a 3.0.1 update that we'll auto-select. - m.checkNewUpdateItems(true, true, false, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- < * INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 3.0.1>\n" + - "-- < * INSTALLED, pkg:Android SDK Platform-tools, revision 3, updated by:Android SDK Platform-tools, revision 3.0.1>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 4 rc1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4 rc1>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=Local Packages (no.source), #items=1>\n" + - "-- < * INSTALLED, pkg:Android SDK Tools, revision 3, updated by:Android SDK Tools, revision 3.0.1>\n" + - "PkgCategorySource <source=repo1 (1.example.com), #items=4>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 4 rc1>\n" + - "-- < * INSTALLED, pkg:Android SDK Platform-tools, revision 3, updated by:Android SDK Platform-tools, revision 3.0.1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4 rc1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n", - getTree(m, false /*displaySortByApi*/)); - - } - - public void testPreviewUpdateInstalledPreview() { - // Test: Local preview Tools 3.0.1rc1 installed, server has both a release 3.0.0 available - // and a Tools Preview 3.0.1 rc2 available. - // => Installed 3.0.1rc1 can be updated by 3.0.1rc2 - // => There's a separate "new" download for 3.0.0, not installed and NOT updating 3.0.1rc1. - - // Enable previews in the settings - u.overrideSetting(ISettingsPage.KEY_ENABLE_PREVIEWS, true); - - SdkSource src1 = new SdkRepoSource("http://1.example.com/url1", "repo1"); - - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, new FullRevision(3, 0, 1, 1), 4), // T 3.0.1rc1 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 1, 1)), // PT 4.0.1rc1 - new MockPlatformPackage(src1, 1, 2, 3), // API 1 - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, new FullRevision(3, 0, 0), 4), // T 3.0.0 - new MockToolPackage(src1, new FullRevision(3, 0, 1, 2), 4), // T 3.0.1rc2 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 0)), // PT 4.0.0 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 1, 2)), // PT 4.0.1 rc2 - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 3>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1, updated by:Android SDK Tools, revision 3.0.1 rc2>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1, updated by:Android SDK Platform-tools, revision 4.0.1 rc2>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=5>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 3>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1, updated by:Android SDK Tools, revision 3.0.1 rc2>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1, updated by:Android SDK Platform-tools, revision 4.0.1 rc2>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n", - getTree(m, false /*displaySortByApi*/)); - - // Auto select new and update items. In this case: - // - the previews have updates available. - // - we're not selecting the non-installed "3.0" version that is older than the - // currently installed "3.0.1rc1" version since that would be a downgrade. - m.checkNewUpdateItems(true, true, false, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 3>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- < * INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1, updated by:Android SDK Tools, revision 3.0.1 rc2>\n" + - "-- < * INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1, updated by:Android SDK Platform-tools, revision 4.0.1 rc2>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=5>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 3>\n" + - "-- < * INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1, updated by:Android SDK Tools, revision 3.0.1 rc2>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4>\n" + - "-- < * INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1, updated by:Android SDK Platform-tools, revision 4.0.1 rc2>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n", - getTree(m, false /*displaySortByApi*/)); - - // ----- - - // Now simulate that the server has a final package (3.0.1) to replace the - // installed 3.0.1rc1 package. It's not installed yet, just available. - // - A new 3.0.1 will be available. - // - The server no longer lists the RC since there's a final package, yet it is - // still locally installed. - // - The 3.0.1 rc1 is not listed as having an update, since we treat the previews - // separately. TODO: consider having the 3.0.1 show up as both a new item /and/ - // as an update to the 3.0.1rc1. That may have some other side effects. - - m.uncheckAllItems(); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, new FullRevision(3, 0, 1, 1), 4), // T 3.0.1rc1 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 1, 1)), // PT 4.0.1rc1 - new MockPlatformPackage(src1, 1, 2, 3), // API 1 - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, new FullRevision(3, 0, 1), 4), // T 3.0.1 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 1)), // PT 4.0.1 - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 3.0.1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4.0.1>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=5>\n" + - "-- <NEW, pkg:Android SDK Tools, revision 3.0.1>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1>\n" + - "-- <NEW, pkg:Android SDK Platform-tools, revision 4.0.1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n", - getTree(m, false /*displaySortByApi*/)); - - // Auto select new and update items. In this case the new items are considered - // updates and yet new at the same time. - // Test by selecting new items only: - m.checkNewUpdateItems(true, false, false, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- < * NEW, pkg:Android SDK Tools, revision 3.0.1>\n" + - "-- < * NEW, pkg:Android SDK Platform-tools, revision 4.0.1>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - - // Test by selecting update items only: - m.uncheckAllItems(); - m.checkNewUpdateItems(false, true, false, SdkConstants.PLATFORM_LINUX); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- < * NEW, pkg:Android SDK Tools, revision 3.0.1>\n" + - "-- < * NEW, pkg:Android SDK Platform-tools, revision 4.0.1>\n" + - "PkgCategoryApi <API=TOOLS-PREVIEW, label=Tools (Preview Channel), #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1 rc1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1 rc1>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - - - // ----- - - // Now simulate that the user has installed the final package (3.0.1) to replace the - // installed 3.0.1rc1 package. - // - The 3.0.1 is installed. - // - The 3.0.1 rc1 isn't listed anymore by the server. - - m.uncheckAllItems(); - m.updateStart(); - m.updateSourcePackages(true /*sortByApi*/, null /*locals*/, new Package[] { - new MockToolPackage(src1, new FullRevision(3, 0, 1), 4), // T 3.0.1 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 1)), // PT 4.0.1 - new MockPlatformPackage(src1, 1, 2, 3), // API 1 - }); - m.updateSourcePackages(true /*sortByApi*/, src1, new Package[] { - new MockToolPackage(src1, new FullRevision(3, 0, 1), 4), // T 3.0.1 - new MockPlatformToolPackage(src1, new FullRevision(4, 0, 1)), // PT 4.0.1 - }); - m.updateEnd(true /*sortByApi*/); - - assertEquals( - "PkgCategoryApi <API=TOOLS, label=Tools, #items=2>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1>\n" + - "PkgCategoryApi <API=API 1, label=Android android-1 (API 1), #items=1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n" + - "PkgCategoryApi <API=EXTRAS, label=Extras, #items=0>\n", - getTree(m, true /*displaySortByApi*/)); - assertEquals( - "PkgCategorySource <source=repo1 (1.example.com), #items=3>\n" + - "-- <INSTALLED, pkg:Android SDK Tools, revision 3.0.1>\n" + - "-- <INSTALLED, pkg:Android SDK Platform-tools, revision 4.0.1>\n" + - "-- <INSTALLED, pkg:SDK Platform Android android-1, API 1, revision 2>\n", - getTree(m, false /*displaySortByApi*/)); - } - - - - // ---- - - /** - * Simulates the display we would have in the Packages Tree. - * This always depends on mCurrentCategories like the tree does. - * The display format is something like: - * <pre> - * PkgCategory <description> - * -- <PkgItem description> - * </pre> - */ - public String getTree(PackagesDiffLogic l, boolean displaySortByApi) { - StringBuilder sb = new StringBuilder(); - - for (PkgCategory cat : m.getCategories(displaySortByApi)) { - sb.append(cat.toString()).append('\n'); - for (PkgItem item : cat.getItems()) { - sb.append("-- ").append(item.toString()).append('\n'); - } - } - - return sb.toString(); - } -} diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/ui/MockPackagesPageImpl.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/ui/MockPackagesPageImpl.java deleted file mode 100755 index 9ab36c1..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/ui/MockPackagesPageImpl.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import com.android.sdklib.internal.repository.DownloadCache; -import com.android.sdklib.internal.repository.DownloadCache.Strategy; -import com.android.sdklib.util.SparseIntArray; -import com.android.sdkuilib.internal.repository.MockDownloadCache; -import com.android.sdkuilib.internal.repository.UpdaterData; -import com.android.sdkuilib.internal.repository.core.PackageLoader; -import com.android.sdkuilib.internal.repository.core.PkgCategory; -import com.android.sdkuilib.internal.repository.core.PkgContentProvider; - -import org.eclipse.jface.viewers.ColumnLabelProvider; -import org.eclipse.swt.graphics.Font; - -import java.util.ArrayList; -import java.util.List; - -public class MockPackagesPageImpl extends PackagesPageImpl { - - public MockPackagesPageImpl(UpdaterData updaterData) { - super(updaterData); - } - - /** UI is never disposed in the unit test. */ - @Override - protected boolean isUiDisposed() { - return false; - } - - /** Sync exec always executes immediately in the unit test, no threading is used. */ - @Override - protected void syncExec(Runnable runnable) { - runnable.run(); - } - - private MockTreeViewer mTreeViewer; - - @Override - void postCreate() { - mTreeViewer = new MockTreeViewer(); - setITreeViewer(mTreeViewer); - - setIColumns(new MockTreeColumn(mTreeViewer), // columnName - new MockTreeColumn(mTreeViewer), // columnApi - new MockTreeColumn(mTreeViewer), // columnRevision - new MockTreeColumn(mTreeViewer)); // columnStatus - - super.postCreate(); - } - - @Override - protected void refreshViewerInput() { - super.setViewerInput(); - } - - @Override - protected boolean isSortByApi() { - return true; - } - - @Override - protected Font getTreeFontItalic() { - return null; - } - - @Override - protected void loadPackages(boolean useLocalCache, boolean overrideExisting) { - super.loadPackagesImpl(useLocalCache, overrideExisting); - } - - /** - * In this mock version, we use the default {@link PackageLoader} which will - * use the {@link DownloadCache} from the {@link UpdaterData}. This should be - * the mock download cache, in which case we change the strategy at run-time - * to set it to only-cache on the first manager update. - */ - @Override - protected PackageLoader getPackageLoader(boolean useLocalCache) { - DownloadCache dc = mUpdaterData.getDownloadCache(); - assert dc instanceof MockDownloadCache; - if (dc instanceof MockDownloadCache) { - ((MockDownloadCache) dc).overrideStrategy(useLocalCache ? Strategy.ONLY_CACHE : null); - } - return mUpdaterData.getPackageLoader(); - } - - /** - * Get a dump-out of the tree in a format suitable for unit testing. - */ - public String getMockTreeDisplay() throws Exception { - return mTreeViewer.getTreeDisplay(); - } - - private static class MockTreeViewer implements PackagesPageImpl.ICheckboxTreeViewer { - private final SparseIntArray mWidths = new SparseIntArray(); - private final List<MockTreeColumn> mColumns = new ArrayList<MockTreeColumn>(); - private List<PkgCategory> mInput; - private PkgContentProvider mPkgContentProvider; - private String mLastRefresh; - private static final String SPACE = " "; - - @Override - public void setInput(List<PkgCategory> input) { - mInput = input; - refresh(); - } - - @Override - public Object getInput() { - return mInput; - } - - @Override - public void setContentProvider(PkgContentProvider pkgContentProvider) { - mPkgContentProvider = pkgContentProvider; - } - - @Override - public void refresh() { - // Recompute the display of the tree - StringBuilder sb = new StringBuilder(); - boolean widthChanged = false; - - for (int render = 0; render < (widthChanged ? 2 : 1); render++) { - widthChanged = false; - sb.setLength(0); - for (Object cat : mPkgContentProvider.getElements(mInput)) { - if (cat == null) { - continue; - } - - if (sb.length() > 0) { - sb.append('\n'); - } - - widthChanged |= rowAsString(cat, sb, 3); - - Object[] children = mPkgContentProvider.getElements(cat); - if (children == null) { - continue; - } - for (Object child : children) { - sb.append("\n L_"); - widthChanged |= rowAsString(child, sb, 0); - } - } - } - - mLastRefresh = sb.toString(); - } - - boolean rowAsString(Object element, StringBuilder sb, int space) { - boolean widthChanged = false; - sb.append("[] "); - for (int col = 0; col < mColumns.size(); col++) { - if (col > 0) { - sb.append(" | "); - } - String t = mColumns.get(col).getLabelProvider().getText(element); - if (t == null) { - t = "(null)"; - } - int len = t.length(); - int w = mWidths.get(col); - if (len > w) { - widthChanged = true; - mWidths.put(col, len); - w = len; - } - String pad = len >= w ? "" : SPACE.substring(SPACE.length() - w + len); - if (col == 0 && space > 0) { - sb.append(SPACE.substring(SPACE.length() - space)); - } - if (col >= 1 && col <= 2) { - sb.append(pad); - } - sb.append(t); - if (col == 0 || col > 2) { - sb.append(pad); - } - } - return widthChanged; - } - - @Override - public Object[] getCheckedElements() { - return null; - } - - public void addColumn(MockTreeColumn mockTreeColumn) { - mColumns.add(mockTreeColumn); - } - - public String getTreeDisplay() { - return mLastRefresh; - } - } - - private static class MockTreeColumn implements PackagesPageImpl.ITreeViewerColumn { - private ColumnLabelProvider mLabelProvider; - - public MockTreeColumn(MockTreeViewer treeViewer) { - treeViewer.addColumn(this); - } - - @Override - public void setLabelProvider(ColumnLabelProvider labelProvider) { - mLabelProvider = labelProvider; - } - - public ColumnLabelProvider getLabelProvider() { - return mLabelProvider; - } - } -} diff --git a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/ui/SdkManagerUpgradeTest.java b/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/ui/SdkManagerUpgradeTest.java deleted file mode 100755 index 00d9684..0000000 --- a/sdkmanager/libs/sdkuilib/tests/com/android/sdkuilib/internal/repository/ui/SdkManagerUpgradeTest.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.sdkuilib.internal.repository.ui; - -import com.android.sdklib.SdkManager; -import com.android.sdklib.SdkManagerTestCase; -import com.android.sdklib.repository.SdkRepoConstants; -import com.android.sdkuilib.internal.repository.MockDownloadCache; -import com.android.sdkuilib.internal.repository.MockUpdaterData; - -import java.util.Arrays; - -public class SdkManagerUpgradeTest extends SdkManagerTestCase { - - @Override - public void setUp() throws Exception { - super.setUp(); - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - } - - /** - * Create a mock page and list the current SDK state - */ - public void testPackagesPage1() throws Exception { - SdkManager sdkman = getSdkManager(); - - MockUpdaterData updaterData = new MockUpdaterData(sdkman); - MockDownloadCache cache = (MockDownloadCache) updaterData.getDownloadCache(); - updaterData.setupDefaultSources(); - - MockPackagesPageImpl pageImpl = new MockPackagesPageImpl(updaterData); - pageImpl.postCreate(); - pageImpl.performFirstLoad(); - - // We have no network access possible and no mock download cache items. - // The only thing visible in the display are the local packages as set by - // the fake locally-installed SDK. - String actual = pageImpl.getMockTreeDisplay(); - assertEquals( - "[] Tools | | | \n" + - " L_[] Android SDK Tools | | 0 | Installed\n" + - "[] Android 0.0 (API 0) | | | \n" + - " L_[] SDK Platform | | 1 | Installed\n" + - " L_[] Sources for Android SDK | | 0 | Installed\n" + - "[] Extras | | | ", - actual); - - assertEquals( - "[]", // there are no direct downloads till we try to install. - Arrays.toString(cache.getDirectHits())); - assertEquals( - "[<https://dl-ssl.google.com/android/repository/addons_list-1.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/addons_list-2.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/repository-5.xml : 2>, " + - "<https://dl-ssl.google.com/android/repository/repository-6.xml : 2>, " + - "<https://dl-ssl.google.com/android/repository/repository-7.xml : 2>, " + - "<https://dl-ssl.google.com/android/repository/repository.xml : 2>]", - Arrays.toString(cache.getCachedHits())); - - - // Now prepare a tools update on the server and reload - setupToolsXml1(cache); - cache.clearDirectHits(); - cache.clearCachedHits(); - pageImpl.fullReload(); - - actual = pageImpl.getMockTreeDisplay(); - assertEquals( - "[] Tools | | | \n" + - " L_[] Android SDK Tools | | 0 | Update available: rev. 20.0.3\n" + - " L_[] Android SDK Platform-tools | | 14 | Not installed \n" + - "[] Android 0.0 (API 0) | | | \n" + - " L_[] SDK Platform | | 1 | Installed \n" + - " L_[] Sources for Android SDK | | 0 | Installed \n" + - "[] Extras | | | ", - actual); - - assertEquals( - "[]", // there are no direct downloads till we try to install. - Arrays.toString(cache.getDirectHits())); - assertEquals( - "[<https://dl-ssl.google.com/android/repository/repository-5.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/repository-6.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/repository-7.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/repository.xml : 1>]", - Arrays.toString(cache.getCachedHits())); - - - // We should get the same display if we restart the manager page from scratch - // (e.g. simulate a first load) - - cache.clearDirectHits(); - cache.clearCachedHits(); - pageImpl = new MockPackagesPageImpl(updaterData); - pageImpl.postCreate(); - pageImpl.performFirstLoad(); - - actual = pageImpl.getMockTreeDisplay(); - assertEquals( - "[] Tools | | | \n" + - " L_[] Android SDK Tools | | 0 | Update available: rev. 20.0.3\n" + - " L_[] Android SDK Platform-tools | | 14 | Not installed \n" + - "[] Android 0.0 (API 0) | | | \n" + - " L_[] SDK Platform | | 1 | Installed \n" + - " L_[] Sources for Android SDK | | 0 | Installed \n" + - "[] Extras | | | ", - actual); - - assertEquals( - "[]", // there are no direct downloads till we try to install. - Arrays.toString(cache.getDirectHits())); - assertEquals( - "[<https://dl-ssl.google.com/android/repository/repository-5.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/repository-6.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/repository-7.xml : 1>, " + - "<https://dl-ssl.google.com/android/repository/repository.xml : 1>]", - Arrays.toString(cache.getCachedHits())); - } - - private void setupToolsXml1(MockDownloadCache cache) throws Exception { - String repoXml = - "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + - "<sdk:sdk-repository xmlns:sdk=\"http://schemas.android.com/sdk/android/repository/7\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + - "<sdk:license id=\"android-sdk-license\" type=\"text\">Blah blah blah.</sdk:license>\n" + - "\n" + - "<sdk:platform-tool>\n" + - " <sdk:revision>\n" + - " <sdk:major>14</sdk:major>\n" + - " </sdk:revision>\n" + - " <sdk:archives>\n" + - " <sdk:archive arch=\"any\" os=\"windows\">\n" + - " <sdk:size>11159472</sdk:size>\n" + - " <sdk:checksum type=\"sha1\">6028258d8f2fba14d8b40c3cf507afa0289aaa13</sdk:checksum>\n" + - " <sdk:url>platform-tools_r14-windows.zip</sdk:url>\n" + - " </sdk:archive>\n" + - " <sdk:archive arch=\"any\" os=\"linux\">\n" + - " <sdk:size>10985068</sdk:size>\n" + - " <sdk:checksum type=\"sha1\">6e2bc329c9485eb383172cbc2cde8b0c0cd1843f</sdk:checksum>\n" + - " <sdk:url>platform-tools_r14-linux.zip</sdk:url>\n" + - " </sdk:archive>\n" + - " <sdk:archive arch=\"any\" os=\"macosx\">\n" + - " <sdk:size>11342461</sdk:size>\n" + - " <sdk:checksum type=\"sha1\">4a015090c6a209fc33972acdbc65745e0b3c08b9</sdk:checksum>\n" + - " <sdk:url>platform-tools_r14-macosx.zip</sdk:url>\n" + - " </sdk:archive>\n" + - " </sdk:archives>\n" + - "</sdk:platform-tool>\n" + - "\n" + - "<sdk:tool>\n" + - " <sdk:revision>\n" + - " <sdk:major>20</sdk:major>\n" + - " <sdk:minor>0</sdk:minor>\n" + - " <sdk:micro>3</sdk:micro>\n" + - " </sdk:revision>\n" + - " <sdk:min-platform-tools-rev>\n" + - " <sdk:major>12</sdk:major>\n" + - " </sdk:min-platform-tools-rev>\n" + - " <sdk:archives>\n" + - " <sdk:archive arch=\"any\" os=\"windows\">\n" + - " <sdk:size>90272048</sdk:size>\n" + - " <sdk:checksum type=\"sha1\">54fb94168e631e211910f88aa40c532205730dd4</sdk:checksum>\n" + - " <sdk:url>tools_r20.0.3-windows.zip</sdk:url>\n" + - " </sdk:archive>\n" + - " <sdk:archive arch=\"any\" os=\"linux\">\n" + - " <sdk:size>82723559</sdk:size>\n" + - " <sdk:checksum type=\"sha1\">09bc633b406ae81981e3a0db19426acbb01ef219</sdk:checksum>\n" + - " <sdk:url>tools_r20.0.3-linux.zip</sdk:url>\n" + - " </sdk:archive>\n" + - " <sdk:archive arch=\"any\" os=\"macosx\">\n" + - " <sdk:size>58197071</sdk:size>\n" + - " <sdk:checksum type=\"sha1\">09cee5ff3226277a6f0c07dcd29cba4ffc2e1da4</sdk:checksum>\n" + - " <sdk:url>tools_r20.0.3-macosx.zip</sdk:url>\n" + - " </sdk:archive>\n" + - " </sdk:archives>\n" + - "</sdk:tool>\n" + - "\n" + - "</sdk:sdk-repository>\n"; - - String url = SdkRepoConstants.URL_GOOGLE_SDK_SITE + - String.format(SdkRepoConstants.URL_DEFAULT_FILENAME, SdkRepoConstants.NS_LATEST_VERSION); - - cache.registerCachedPayload(url, repoXml.getBytes("UTF-8")); - } - -} |