android:layout_alignParentLeft="true"
android:text="@string/development_settings_show_updates_text" />
+ <CheckBox android:id="@+id/compatibility_mode"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/show_updates"
+ android:layout_alignParentLeft="true"
+ android:text="@string/development_settings_compatibility_mode_text" />
+
<Spinner android:id="@+id/max_procs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/show_updates"
+ android:layout_below="@id/compatibility_mode"
android:layout_alignParentLeft="true" />
<View android:id="@+id/separator2"
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="?android:attr/listPreferredItemHeight"
+ android:orientation="vertical"
+ android:gravity="fill" >
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:paddingRight="6dip"
+ android:paddingLeft="6dip"
+ android:gravity="center_vertical" >
+
+ <ImageView android:id="@+id/icon"
+ android:layout_width="@android:dimen/app_icon_size"
+ android:layout_height="@android:dimen/app_icon_size"
+ android:layout_marginLeft="5dip"
+ android:layout_marginRight="11dip"
+ android:layout_gravity="center_vertical"
+ android:scaleType="fitCenter"/>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+ <TextView android:id="@+id/name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textStyle="bold"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:layout_marginBottom="2dip" />
+ <TextView android:id="@+id/description"
+ android:layout_marginTop="-4dip"
+ android:layout_gravity="center_vertical|left"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="4dip"
+ android:singleLine="true"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceSmall" />
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout>
<string name="development_settings_always_finish_text">Immediately destroy activities</string>
<string name="development_settings_show_load_text">Show running processes</string>
<string name="development_settings_show_updates_text">Show screen updates</string>
+ <string name="development_settings_compatibility_mode_text">Disable compatibility mode</string>
+ <string name="development_settings_compatibility_mode_toast">Reboot required for
+ change to take effect.</string>
<string name="development_settings_enable_gl_text">Enable OpenGL ES (reboot needed)</string>
<string name="development_settings_allow_mock_location_text">Allow mock locations for testing</string>
<string name="development_settings_wait_for_debugger_text">Wait for debugger</string>
package com.android.development;
+import com.android.development.PackageBrowser.MyPackageInfo;
+
import android.app.ActivityManagerNative;
import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.Settings;
import android.view.ViewGroup;
import android.view.LayoutInflater;
import android.widget.BaseAdapter;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.text.Collator;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@Override
protected void onListItemClick(ListView l, View v, int position, long id)
{
- ApplicationInfo app = mAdapter.appForPosition(position);
+ MyApplicationInfo app = mAdapter.itemForPosition(position);
Intent intent = new Intent();
- if (app != null) intent.setAction(app.packageName);
+ if (app.info != null) intent.setAction(app.info.packageName);
setResult(RESULT_OK, intent);
- /* This is a temporary fix for 824637 while it is blocked by 805226. When 805226 is resolved, please remove this. */
try {
boolean waitForDebugger = Settings.System.getInt(
getContentResolver(), Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
ActivityManagerNative.getDefault().setDebugApp(
- app != null ? app.packageName : null, waitForDebugger, true);
+ app.info != null ? app.info.packageName : null, waitForDebugger, true);
} catch (RemoteException ex) {
}
finish();
}
- private final class AppListAdapter extends BaseAdapter
- {
- public AppListAdapter(Context context)
- {
- mContext = context;
- mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-
- mList = context.getPackageManager().getInstalledApplications(0);
- if (mList != null) {
- Collections.sort(mList, sDisplayNameComparator);
- mList.add(0, null);
- }
- }
+ class MyApplicationInfo {
+ ApplicationInfo info;
+ String label;
+ }
- public ApplicationInfo appForPosition(int position)
- {
- if (mList == null) {
- return null;
+ public class AppListAdapter extends ArrayAdapter<MyApplicationInfo> {
+ private List<MyApplicationInfo> mPackageInfoList = new ArrayList<MyApplicationInfo>();
+
+ public AppListAdapter(Context context) {
+ super(context, R.layout.package_list_item);
+ List<ApplicationInfo> pkgs = context.getPackageManager().getInstalledApplications(0);
+ for (int i=0; i<pkgs.size(); i++) {
+ MyApplicationInfo info = new MyApplicationInfo();
+ info.info = pkgs.get(i);
+ info.label = info.info.loadLabel(getPackageManager()).toString();
+ mPackageInfoList.add(info);
}
-
- return mList.get(position);
- }
-
- public int getCount()
- {
- return mList != null ? mList.size() : 0;
- }
-
- public Object getItem(int position)
- {
- return position;
- }
-
- public long getItemId(int position)
- {
- return position;
+ Collections.sort(mPackageInfoList, sDisplayNameComparator);
+ MyApplicationInfo info = new MyApplicationInfo();
+ info.label = "(none)";
+ mPackageInfoList.add(0, info);
+ setSource(mPackageInfoList);
}
- public View getView(int position, View convertView, ViewGroup parent)
- {
- View view;
- if (convertView == null) {
- view = mInflater.inflate(
- android.R.layout.simple_list_item_1, parent, false);
+ @Override
+ public void bindView(View view, MyApplicationInfo info) {
+ ImageView icon = (ImageView)view.findViewById(R.id.icon);
+ TextView name = (TextView)view.findViewById(R.id.name);
+ TextView description = (TextView)view.findViewById(R.id.description);
+ name.setText(info.label);
+ if (info.info != null) {
+ icon.setImageDrawable(info.info.loadIcon(getPackageManager()));
+ description.setText(info.info.packageName);
} else {
- view = convertView;
+ icon.setImageDrawable(null);
+ description.setText("");
}
- bindView(view, mList.get(position));
- return view;
- }
-
- private final void bindView(View view, ApplicationInfo info)
- {
- TextView text = (TextView)view.findViewById(android.R.id.text1);
-
- text.setText(info != null ? info.packageName : "(none)");
}
-
- protected final Context mContext;
- protected final LayoutInflater mInflater;
-
- protected List<ApplicationInfo> mList;
-
}
- private final static Comparator sDisplayNameComparator = new Comparator() {
+ private final static Comparator<MyApplicationInfo> sDisplayNameComparator
+ = new Comparator<MyApplicationInfo>() {
public final int
- compare(Object a, Object b)
- {
- CharSequence sa = ((ApplicationInfo) a).packageName;
- CharSequence sb = ((ApplicationInfo) b).packageName;
-
- return collator.compare(sa, sb);
+ compare(MyApplicationInfo a, MyApplicationInfo b) {
+ return collator.compare(a.label, b.label);
}
private final Collator collator = Collator.getInstance();
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Spinner;
+import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
import java.io.FileInputStream;
private CheckBox mShowBackgroundCB;
private CheckBox mShowSleepCB;
private CheckBox mShowXmppCB;
+ private CheckBox mCompatibilityModeCB;
private Spinner mMaxProcsSpinner;
private Spinner mWindowAnimationScaleSpinner;
private Spinner mTransitionAnimationScaleSpinner;
private int mProcessLimit;
private boolean mShowSleep;
private boolean mShowXmpp;
+ private boolean mCompatibilityMode;
private AnimationScaleSelectedListener mWindowAnimationScale
= new AnimationScaleSelectedListener(0);
private AnimationScaleSelectedListener mTransitionAnimationScale
mShowSleepCB.setOnClickListener(mShowSleepClicked);
mShowXmppCB = (CheckBox)findViewById(R.id.show_xmpp);
mShowXmppCB.setOnClickListener(mShowXmppClicked);
+ mCompatibilityModeCB = (CheckBox)findViewById(R.id.compatibility_mode);
+ mCompatibilityModeCB.setOnClickListener(mCompatibilityModeClicked);
mMaxProcsSpinner = (Spinner)findViewById(R.id.max_procs);
mMaxProcsSpinner.setOnItemSelectedListener(mMaxProcsChanged);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
updateSharedOptions();
updateFlingerOptions();
updateSleepOptions();
- updateXmppOptions();
+ updateXmppOptions();
+ updateCompatibilityOptions();
try {
FileInputStream in = new FileInputStream( FONT_HINTING_FILE );
Settings.System.SHOW_PROCESSES, 0) != 0);
}
+ private void writeCompatibilityOptions() {
+ Settings.System.putInt(getContentResolver(),
+ Settings.System.COMPATIBILITY_MODE, mCompatibilityMode ? 0 : 1);
+ }
+
+ private void updateCompatibilityOptions() {
+ mCompatibilityMode = Settings.System.getInt(
+ getContentResolver(), Settings.System.COMPATIBILITY_MODE, 1) == 0;
+ mCompatibilityModeCB.setChecked(mCompatibilityMode);
+ }
+
private void updateFlingerOptions() {
// magic communication with surface flinger.
try {
}
};
+ private View.OnClickListener mCompatibilityModeClicked =
+ new View.OnClickListener() {
+ public void onClick(View v) {
+ mCompatibilityMode = ((CheckBox)v).isChecked();
+ writeCompatibilityOptions();
+ updateCompatibilityOptions();
+ Toast toast = Toast.makeText(DevelopmentSettings.this,
+ R.string.development_settings_compatibility_mode_toast,
+ Toast.LENGTH_LONG);
+ toast.show();
+ }
+};
+
private View.OnClickListener mShowLoadClicked = new View.OnClickListener() {
public void onClick(View v) {
boolean value = ((CheckBox)v).isChecked();
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.text.Collator;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-public class PackageBrowser extends ListActivity
-{
+public class PackageBrowser extends ListActivity {
+ static class MyPackageInfo {
+ PackageInfo info;
+ String label;
+ }
+
private PackageListAdapter mAdapter;
- private List<PackageInfo> mPackageInfoList = null;
+ private List<MyPackageInfo> mPackageInfoList = new ArrayList<MyPackageInfo>();
private Handler mHandler;
-
- public class PackageListAdapter extends ArrayAdapter<PackageInfo>
- {
-
- public PackageListAdapter(Context context)
- {
- super(context, android.R.layout.simple_list_item_1);
- mPackageInfoList = context.getPackageManager().getInstalledPackages(0);
+ private BroadcastReceiver mRegisteredReceiver;
+
+ public class PackageListAdapter extends ArrayAdapter<MyPackageInfo> {
+
+ public PackageListAdapter(Context context) {
+ super(context, R.layout.package_list_item);
+ List<PackageInfo> pkgs = context.getPackageManager().getInstalledPackages(0);
+ for (int i=0; i<pkgs.size(); i++) {
+ MyPackageInfo info = new MyPackageInfo();
+ info.info = pkgs.get(i);
+ info.label = info.info.applicationInfo.loadLabel(getPackageManager()).toString();
+ mPackageInfoList.add(info);
+ }
if (mPackageInfoList != null) {
Collections.sort(mPackageInfoList, sDisplayNameComparator);
}
}
@Override
- public void bindView(View view, PackageInfo info)
- {
- TextView text = (TextView)view.findViewById(android.R.id.text1);
- text.setText(info.packageName);
+ public void bindView(View view, MyPackageInfo info) {
+ ImageView icon = (ImageView)view.findViewById(R.id.icon);
+ TextView name = (TextView)view.findViewById(R.id.name);
+ TextView description = (TextView)view.findViewById(R.id.description);
+ icon.setImageDrawable(info.info.applicationInfo.loadIcon(getPackageManager()));
+ name.setText(info.label);
+ description.setText(info.info.packageName);
}
}
}
}
- private final static Comparator sDisplayNameComparator = new Comparator() {
+ private final static Comparator<MyPackageInfo> sDisplayNameComparator
+ = new Comparator<MyPackageInfo>() {
public final int
- compare(Object a, Object b)
- {
- CharSequence sa = ((PackageInfo) a).packageName;
- CharSequence sb = ((PackageInfo) b).packageName;
- return collator.compare(sa, sb);
+ compare(MyPackageInfo a, MyPackageInfo b) {
+ return collator.compare(a.label, b.label);
}
private final Collator collator = Collator.getInstance();
registerIntentReceivers();
}
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mRegisteredReceiver != null) {
+ unregisterReceiver(mRegisteredReceiver);
+ }
+ }
+
private void setupAdapter() {
mAdapter = new PackageListAdapter(this);
setListAdapter(mAdapter);
final int curSelection = getSelectedItemPosition();
if (curSelection >= 0) {
// todo: verification dialog for package deletion
- final PackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
+ final MyPackageInfo packageInfo = mAdapter.itemForPosition(curSelection);
if (packageInfo != null) {
- getPackageManager().deletePackage(packageInfo.packageName,
+ getPackageManager().deletePackage(packageInfo.info.packageName,
new IPackageDeleteObserver.Stub() {
public void packageDeleted(boolean succeeded) throws RemoteException {
if (succeeded) {
});
// todo: verification dialog for data directory
- final String dataPath = packageInfo.applicationInfo.dataDir;
+ final String dataPath = packageInfo.info.applicationInfo.dataDir;
// todo: delete the data directory
} else {
mHandler.post(new Runnable() {
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
- registerReceiver(new ApplicationsIntentReceiver(), filter);
+ mRegisteredReceiver = new ApplicationsIntentReceiver();
+ registerReceiver(mRegisteredReceiver, filter);
}
@Override
- protected void onListItemClick(ListView l, View v, int position, long id)
- {
- PackageInfo info =
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ MyPackageInfo info =
mAdapter.itemForPosition(position);
if (info != null) {
Intent intent = new Intent(
- null, Uri.fromParts("package", info.packageName, null));
+ null, Uri.fromParts("package", info.info.packageName, null));
intent.setClass(this, PackageSummary.class);
startActivity(intent);
}
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
info = pm.getPackageInfo(mPackageName,
PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
| PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS
- | PackageManager.GET_INSTRUMENTATION);
+ | PackageManager.GET_INSTRUMENTATION
+ | PackageManager.GET_DISABLED_COMPONENTS);
} catch (PackageManager.NameNotFoundException e) {
}
ActivityInfo ai = info.receivers[i];
Button view = (Button)inflate.inflate(
R.layout.package_item, null, false);
+ Log.i("foo", "Receiver #" + i + " of " + N + ": " + ai);
setItemText(view, info, ai.name);
receivers.addView(view, lp);
}
# sdk scripts
development/tools/scripts/AndroidManifest.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.template
development/tools/scripts/AndroidManifest.tests.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.tests.template
-development/tools/scripts/iml.template platforms/${PLATFORM_NAME}/templates/iml.template
-development/tools/scripts/ipr.template platforms/${PLATFORM_NAME}/templates/ipr.template
-development/tools/scripts/iws.template platforms/${PLATFORM_NAME}/templates/iws.template
development/tools/scripts/java_file.template platforms/${PLATFORM_NAME}/templates/java_file.template
development/tools/scripts/java_tests_file.template platforms/${PLATFORM_NAME}/templates/java_tests_file.template
development/tools/scripts/layout.template platforms/${PLATFORM_NAME}/templates/layout.template
TARGET_ARFLAGS := crs
TARGET_LIBGCC := $(shell $(TARGET_CC) -mthumb-interwork -print-libgcc-file-name)
-TARGET_LDLIBS := -Wl,-rpath-link=$(SYSROOT)/usr/lib $(TARGET_LIBGCC)
+TARGET_LDLIBS := -Wl,-rpath-link=$(SYSROOT)/usr/lib
# These flags are used to ensure that a binary doesn't reference undefined
# flags.
# this toolchain's generated binaries
TARGET_ABI_SUBDIR := armeabi
+# NOTE: Ensure that TARGET_LIBGCC is placed after all private objects
+# and static libraries, but before any other library in the link
+# command line when generating shared libraries and executables.
+#
+# This ensures that all libgcc.a functions required by the target
+# will be included into it, instead of relying on what's available
+# on other libraries like libc.so, which may change between system
+# releases due to toolchain or library changes.
+#
define cmd-build-shared-library
$(TARGET_CC) \
-nostdlib -Wl,-soname,$(notdir $@) \
$(PRIVATE_WHOLE_STATIC_LIBRARIES) \
-Wl,--no-whole-archive \
$(PRIVATE_STATIC_LIBRARIES) \
+ $(TARGET_LIBGCC) \
$(PRIVATE_SHARED_LIBRARIES) \
$(PRIVATE_LDFLAGS) \
$(PRIVATE_LDLIBS) \
-Wl,-dynamic-linker,/system/bin/linker \
-Wl,--gc-sections \
-Wl,-z,nocopyreloc \
- $(PRIVATE_SHARED_LIBRARIES) \
$(TARGET_CRTBEGIN_DYNAMIC_O) \
$(PRIVATE_OBJECTS) \
$(PRIVATE_STATIC_LIBRARIES) \
+ $(TARGET_LIBGCC) \
+ $(PRIVATE_SHARED_LIBRARIES) \
$(PRIVATE_LDFLAGS) \
$(PRIVATE_LDLIBS) \
$(TARGET_CRTEND_O) \
Android NDK ChangeLog:
-------------------------------------------------------------------------------
+current version
+
+IMPORTANT BUG FIXES:
+
+- Make target shared libraries portable to systems that don't use the exact same
+ toolchain (GCC 4.2.1) .
+
+-------------------------------------------------------------------------------
android-ndk-1.6_r1
IMPORTANT BUG FIXES:
in $(CLEAR_VARS) script.
-IMPORTANT CHANGES
+IMPORTANT CHANGES:
- The 'sources' directory is gone. The NDK build system now looks for
$(APP_PROJECT_PATH)/jni/Android.mk by default. You can override this with
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent msg) {
-
- if (keyCode == 4)
- super.onKeyDown(keyCode, msg);
-
- return mJetBoyThread.doKeyDown(keyCode, msg);
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ return super.onKeyDown(keyCode, msg);
+ } else {
+ return mJetBoyThread.doKeyDown(keyCode, msg);
+ }
}
/**
- * Standard override for key-up. We actually care about these, so we can
- * turn off the engine or stop rotating.
+ * Standard override for key-up.
*/
@Override
public boolean onKeyUp(int keyCode, KeyEvent msg) {
- return mJetBoyThread.doKeyUp(keyCode, msg);
+ if (keyCode == KeyEvent.KEYCODE_BACK) {
+ return super.onKeyUp(keyCode, msg);
+ } else {
+ return mJetBoyThread.doKeyUp(keyCode, msg);
+ }
}
}
<test name="contactsprov"
build_path="packages/providers/ContactsProvider/tests"
package="com.android.providers.contacts.tests"
- coverage_target="ContactsProvider" />
+ coverage_target="ContactsProvider"
+ continuous="true" />
<test name="contacts"
build_path="packages/apps/Contacts"
package="com.android.contacts.tests"
runner="android.test.InstrumentationTestRunner"
coverage_target="Contacts"
- description="Tests for the Contacts app." />
+ description="Tests for the Contacts app."
+ continuous="true" />
<test name="gcontactsprov"
build_path="packages/providers/GoogleContactsProvider/tests"
+++ /dev/null
-/*
- * 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.ant;
-
-import com.android.sdklib.SdkConstants;
-
-import java.util.Iterator;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathFactory;
-
-/**
- * XPath factory with automatic support for the android namespace.
- */
-class AndroidXPathFactory {
- public final static String DEFAULT_NS_PREFIX = "android"; //$NON-NLS-1$
-
- private final static XPathFactory sFactory = XPathFactory.newInstance();
-
- /** Namespace context for Android resource XML files. */
- private static class AndroidNamespaceContext implements NamespaceContext {
- private String mAndroidPrefix;
-
- /**
- * Construct the context with the prefix associated with the android namespace.
- * @param androidPrefix the Prefix
- */
- public AndroidNamespaceContext(String androidPrefix) {
- mAndroidPrefix = androidPrefix;
- }
-
- public String getNamespaceURI(String prefix) {
- if (prefix != null) {
- if (prefix.equals(mAndroidPrefix)) {
- return SdkConstants.NS_RESOURCES;
- }
- }
-
- return XMLConstants.NULL_NS_URI;
- }
-
- public String getPrefix(String namespaceURI) {
- // This isn't necessary for our use.
- assert false;
- return null;
- }
-
- public Iterator<?> getPrefixes(String namespaceURI) {
- // This isn't necessary for our use.
- assert false;
- return null;
- }
- }
-
- /**
- * Creates a new XPath object, specifying which prefix in the query is used for the
- * android namespace.
- * @param androidPrefix The namespace prefix.
- */
- public static XPath newXPath(String androidPrefix) {
- XPath xpath = sFactory.newXPath();
- xpath.setNamespaceContext(new AndroidNamespaceContext(androidPrefix));
- return xpath;
- }
-
- /**
- * Creates a new XPath object using the default prefix for the android namespace.
- * @see #DEFAULT_NS_PREFIX
- */
- public static XPath newXPath() {
- return newXPath(DEFAULT_NS_PREFIX);
- }
-}
import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.xml.AndroidXPathFactory;
-import com.android.sdklib.xml.ManifestConstants;
+import com.android.sdklib.xml.AndroidManifest;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
XPath xPath = AndroidXPathFactory.newXPath();
- String value = xPath.evaluate("/" + ManifestConstants.NODE_MANIFEST +"/" +
- ManifestConstants.NODE_USES_SDK + "/@" +
- AndroidXPathFactory.DEFAULT_NS_PREFIX + ":" +
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+ String value = xPath.evaluate(
+ "/" + AndroidManifest.NODE_MANIFEST +
+ "/" + AndroidManifest.NODE_USES_SDK +
+ "/@" + AndroidXPathFactory.DEFAULT_NS_PREFIX + ":" +
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
new InputSource(new FileInputStream(manifest)));
if (androidVersion.isPreview()) {
// looks like it's not a number: error!
throw new BuildException(String.format(
"Attribute %1$s in AndroidManifest.xml must be an Integer!",
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION));
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION));
}
int projectApiLevel = androidVersion.getApiLevel();
if (minSdkValue < projectApiLevel) {
System.out.println(String.format(
"WARNING: Attribute %1$s in AndroidManifest.xml (%2$d) is lower than the project target API level (%3$d)",
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
minSdkValue, projectApiLevel));
} else if (minSdkValue > androidVersion.getApiLevel()) {
System.out.println(String.format(
"WARNING: Attribute %1$s in AndroidManifest.xml (%2$d) is higher than the project target API level (%3$d)",
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
minSdkValue, projectApiLevel));
}
} else {
package com.android.ant;
+import com.android.sdklib.xml.AndroidXPathFactory;
+
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
progress.setTaskName(Messages.AdtPlugin_Parsing_Resources);
- int n = sdk.getTargets().length;
+ final IAndroidTarget[] targets = sdk.getTargets();
+ final int n = targets.length;
if (n > 0) {
+ // load the layout devices.
+ sdk.parseAddOnLayoutDevices();
+
+ // load the rest of the targes.
+ // TODO: make this on-demand.
int w = 60 / n;
- for (IAndroidTarget target : sdk.getTargets()) {
+ for (IAndroidTarget target : targets) {
SubMonitor p2 = progress.newChild(w);
IStatus status = new AndroidTargetParser(target).run(p2);
if (status.getCode() != IStatus.OK) {
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
-import com.android.sdklib.xml.ManifestConstants;
+import com.android.sdklib.xml.AndroidManifest;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
// integer minSdk when the target is a preview => fatal error
String msg = String.format(
"Platform %1$s is a preview and requires appication manifest to set %2$s to '%1$s'",
- codename, ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION);
+ codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
IMarker.SEVERITY_ERROR);
// integer minSdk is not high enough for the target => warning
String msg = String.format(
"Attribute %1$s (%2$d) is lower than the project target API level (%3$d)",
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
minSdkValue, projectVersion.getApiLevel());
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
// integer minSdk is too high for the target => warning
String msg = String.format(
"Attribute %1$s (%2$d) is higher than the project target API level (%3$d)",
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
minSdkValue, projectVersion.getApiLevel());
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
// platform is not a preview => fatal error
String msg = String.format(
"Manifest attribute '%1$s' is set to '%2$s'. Integer is expected.",
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION, minSdkVersion);
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, minSdkVersion);
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
IMarker.SEVERITY_ERROR);
// platform and manifest codenames don't match => fatal error.
String msg = String.format(
"Value of manifest attribute '%1$s' does not match platform codename '%2$s'",
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION, codename);
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION, codename);
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
IMarker.SEVERITY_ERROR);
String codename = projectTarget.getVersion().getCodename();
String msg = String.format(
"Platform %1$s is a preview and requires appication manifests to set %2$s to '%1$s'",
- codename, ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION);
+ codename, AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION);
AdtPlugin.printErrorToConsole(project, msg);
BaseProjectHelper.addMarker(manifest, AdtConstants.MARKER_ADT, msg,
IMarker.SEVERITY_ERROR);
// enable the create button if the current and edited config are not equals\r
mConfigComposite.setEnabledCreate(\r
mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false);\r
+\r
+ reloadConfigurationUi(false /*notifyListener*/);\r
}\r
\r
public Clipboard getClipboard() {\r
}\r
}\r
\r
- public void reloadConfigurationUi() {\r
+ public void reloadConfigurationUi(boolean notifyListener) {\r
// enable the clipping button if it's supported.\r
Sdk currentSdk = Sdk.getCurrent();\r
if (currentSdk != null) {\r
AndroidTargetData data = currentSdk.getTargetData(target);\r
if (data != null) {\r
LayoutBridge bridge = data.getLayoutBridge();\r
+ mConfigComposite.reloadDevices(notifyListener);\r
mConfigComposite.setClippingSupport(bridge.apiLevel >= 4);\r
}\r
}\r
mConfigComposite.setEnabledCreate(
mEditedConfig.equals(mConfigComposite.getCurrentConfig()) == false);
- reloadConfigurationUi();
+ reloadConfigurationUi(false /*notifyListener*/);
}
public Rectangle getBounds() {
PaletteFactory.createPaletteRoot(mPaletteRoot, mLayoutEditor.getTargetData());
}
- public void reloadConfigurationUi() {
+ public void reloadConfigurationUi(boolean notifyListener) {
// enable the clipping button if it's supported.
Sdk currentSdk = Sdk.getCurrent();
if (currentSdk != null) {
AndroidTargetData data = currentSdk.getTargetData(target);
if (data != null) {
LayoutBridge bridge = data.getLayoutBridge();
+ mConfigComposite.reloadDevices(notifyListener);
mConfigComposite.setClippingSupport(bridge.apiLevel >= 4);
}
}
abstract Clipboard getClipboard();
- abstract void reloadConfigurationUi();
+ abstract void reloadConfigurationUi(boolean notifyListener);
}
if (mGraphicalEditor != null) {
mGraphicalEditor.reloadEditor();
mGraphicalEditor.reloadPalette();
- mGraphicalEditor.reloadConfigurationUi();
+ mGraphicalEditor.reloadConfigurationUi(true /*notify listener */);
mGraphicalEditor.recomputeLayout();
}
}
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.sdk.DeviceConfiguration;
+import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.LanguageRegionVerifier;
import com.android.layoutlib.api.IResourceValue;
import com.android.layoutlib.api.IStyleResourceValue;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
/** The {@link FolderConfiguration} representing the state of the UI controls */
private final FolderConfiguration mCurrentConfig = new FolderConfiguration();
- private DeviceConfiguration[] mDevices;
+ private List<DeviceConfiguration> mDevices;
private final ArrayList<ResourceQualifier[] > mLocaleList =
new ArrayList<ResourceQualifier[]>();
public ConfigurationComposite(IConfigListener listener, Composite parent, int style) {
super(parent, style);
mListener = listener;
- mDevices = DeviceConfiguration.getDevices();
+ if (Sdk.getCurrent() != null) {
+ mDevices = Sdk.getCurrent().getLayoutDevices();
+ }
GridLayout gl;
GridData gd;
new Label(this, SWT.NONE).setText("Devices");
mDeviceList = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
- // fill with the devices
- for (DeviceConfiguration device : mDevices) {
- mDeviceList.add(device.getName());
- }
-
- mDeviceList.select(0);
mDeviceList.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
mDeviceList.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
- onDeviceChange();
+ onDeviceChange(true /* recomputeLayout*/);
}
});
new Label(this, SWT.NONE).setText("Config");
mDeviceConfigs = new Combo(this, SWT.DROP_DOWN | SWT.READ_ONLY);
- Map<String, FolderConfiguration> configs = mDevices[0].getConfigs();
- Set<String> configNames = configs.keySet();
- for (String name : configNames) {
- mDeviceConfigs.add(name);
- }
- mDeviceConfigs.select(0);
- if (configNames.size() == 1) {
- mDeviceConfigs.setEnabled(false);
- }
mDeviceConfigs.setLayoutData(new GridData(
GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL));
mDeviceConfigs.addSelectionListener(new SelectionAdapter() {
}
});
+ initUiWithDevices();
+
onDeviceConfigChange();
}
+
public FolderConfiguration getCurrentConfig() {
return mCurrentConfig;
}
}
/**
+ * Reloads the list of {@link DeviceConfiguration} from the {@link Sdk}.
+ * @param notifyListener
+ */
+ public void reloadDevices(boolean notifyListener) {
+ mDevices = Sdk.getCurrent().getLayoutDevices();
+ initUiWithDevices();
+ onDeviceChange(notifyListener);
+ }
+
+ /**
+ * Init the UI with the list of Devices.
+ */
+ private void initUiWithDevices() {
+ // remove older devices if applicable
+ mDeviceList.removeAll();
+ mDeviceConfigs.removeAll();
+
+ // fill with the devices
+ if (mDevices != null) {
+ for (DeviceConfiguration device : mDevices) {
+ mDeviceList.add(device.getName());
+ }
+ mDeviceList.select(0);
+
+ if (mDevices.size() > 0) {
+ Map<String, FolderConfiguration> configs = mDevices.get(0).getConfigs();
+ Set<String> configNames = configs.keySet();
+ for (String name : configNames) {
+ mDeviceConfigs.add(name);
+ }
+ mDeviceConfigs.select(0);
+ if (configNames.size() == 1) {
+ mDeviceConfigs.setEnabled(false);
+ }
+ }
+ }
+ }
+
+ /**
* Call back for language combo selection
*/
private void onLocaleChange() {
}
}
- private void onDeviceChange() {
+ private void onDeviceChange(boolean recomputeLayout) {
int deviceIndex = mDeviceList.getSelectionIndex();
- DeviceConfiguration device = mDevices[deviceIndex];
+ DeviceConfiguration device = mDevices.get(deviceIndex);
mDeviceConfigs.removeAll();
mDeviceConfigs.setEnabled(false);
}
- onDeviceConfigChange();
+ if (recomputeLayout) {
+ onDeviceConfigChange();
+ }
}
private void onDeviceConfigChange() {
- int deviceIndex = mDeviceList.getSelectionIndex();
- DeviceConfiguration device = mDevices[deviceIndex];
+ if (mDevices != null) {
+ int deviceIndex = mDeviceList.getSelectionIndex();
+ DeviceConfiguration device = mDevices.get(deviceIndex);
- int configIndex = mDeviceConfigs.getSelectionIndex();
- String name = mDeviceConfigs.getItem(configIndex);
- FolderConfiguration config = device.getConfigs().get(name);
+ int configIndex = mDeviceConfigs.getSelectionIndex();
+ String name = mDeviceConfigs.getItem(configIndex);
+ FolderConfiguration config = device.getConfigs().get(name);
- // get the current qualifiers from the current config
- LanguageQualifier lang = mCurrentConfig.getLanguageQualifier();
- RegionQualifier region = mCurrentConfig.getRegionQualifier();
- VersionQualifier version = mCurrentConfig.getVersionQualifier();
+ // get the current qualifiers from the current config
+ LanguageQualifier lang = mCurrentConfig.getLanguageQualifier();
+ RegionQualifier region = mCurrentConfig.getRegionQualifier();
+ VersionQualifier version = mCurrentConfig.getVersionQualifier();
- // replace the config with the one from the device
- mCurrentConfig.set(config);
+ // replace the config with the one from the device
+ mCurrentConfig.set(config);
- // and put back the rest of the qualifiers
- mCurrentConfig.addQualifier(lang);
- mCurrentConfig.addQualifier(region);
- mCurrentConfig.addQualifier(version);
+ // and put back the rest of the qualifiers
+ mCurrentConfig.addQualifier(lang);
+ mCurrentConfig.addQualifier(region);
+ mCurrentConfig.addQualifier(version);
- if (mListener != null) {
- mListener.onConfigurationChange();
+ if (mListener != null) {
+ mListener.onConfigurationChange();
+ }
}
}
return false;
}
}
+
import com.android.ide.eclipse.adt.internal.editors.ui.SectionHelper;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode;
-import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+import com.android.sdklib.xml.AndroidManifest;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
private IPostTypeCreationAction mPostCreationAction;
private boolean mMandatory;
private final boolean mDefaultToProjectOnly;
-
+
private class HierarchyTypeSelection extends TypeSelectionExtension {
-
+
private IJavaProject mJavaProject;
private IType mReferenceType;
private Button mProjectOnly;
public ITypeInfoFilterExtension getFilterExtension() {
return new ITypeInfoFilterExtension() {
public boolean select(ITypeInfoRequestor typeInfoRequestor) {
-
+
boolean projectOnly = mUseProjectOnly;
-
+
String packageName = typeInfoRequestor.getPackageName();
String typeName = typeInfoRequestor.getTypeName();
String enclosingType = typeInfoRequestor.getEnclosingName();
-
+
// build the full class name.
StringBuilder sb = new StringBuilder(packageName);
sb.append('.');
sb.append('.');
}
sb.append(typeName);
-
+
String className = sb.toString();
-
+
try {
IType type = mJavaProject.findType(className);
return false;
}
}
-
+
// get the type hierarchy and reference type is one of the super classes.
ITypeHierarchy hierarchy = type.newSupertypeHierarchy(
new NullProgressMonitor());
-
+
IType[] supertypes = hierarchy.getAllSupertypes(type);
int n = supertypes.length;
for (int i = 0; i < n; i++) {
}
} catch (JavaModelException e) {
}
-
+
return false;
}
};
}
-
+
@Override
public Control createContentArea(Composite parent) {
mProjectOnly.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
mProjectOnly.setText(String.format("Display classes from sources of project '%s' only",
mJavaProject.getProject().getName()));
-
+
mUseProjectOnly = mDefaultToProjectOnly;
mProjectOnly.setSelection(mUseProjectOnly);
-
+
mProjectOnly.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
getTypeSelectionComponent().triggerSearch();
}
});
-
+
return super.createContentArea(parent);
}
}
* @param mandatory indicates if the class value is mandatory
* @param attributeDescriptor the {@link AttributeDescriptor} object linked to the Ui Node.
* @param defaultToProjectOnly When true display classes of this project only by default.
- * When false any class path will be considered. The user can always toggle this.
+ * When false any class path will be considered. The user can always toggle this.
*/
public UiClassAttributeNode(String referenceClass, IPostTypeCreationAction postCreationAction,
boolean mandatory, AttributeDescriptor attributeDescriptor, UiElementNode uiParent,
boolean defaultToProjectOnly) {
super(attributeDescriptor, uiParent);
-
+
mReferenceClass = referenceClass;
mPostCreationAction = postCreationAction;
mMandatory = mandatory;
});
formText.setLayoutData(new TableWrapData(TableWrapData.LEFT, TableWrapData.MIDDLE));
SectionHelper.addControlTooltip(formText, desc.getTooltip());
-
+
Composite composite = toolkit.createComposite(parent);
composite.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.MIDDLE));
GridLayout gl = new GridLayout(2, false);
// Fixes missing text borders under GTK... also requires adding a 1-pixel margin
// for the text field below
toolkit.paintBordersFor(composite);
-
+
final Text text = toolkit.createText(composite, getCurrentValue());
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalIndent = 1; // Needed by the fixed composite borders under GTK
text.setLayoutData(gd);
Button browseButton = toolkit.createButton(composite, "Browse...", SWT.PUSH);
-
+
setTextWidget(text);
browseButton.addSelectionListener(new SelectionAdapter() {
}
});
}
-
+
/* (non-java doc)
- *
+ *
* Add a modify listener that will check the validity of the class
*/
@Override
String javaPackage = getManifestPackage();
// build the fully qualified name of the class
- String className = AndroidManifestParser.combinePackageAndClassName(
+ String className = AndroidManifest.combinePackageAndClassName(
javaPackage, textValue);
-
+
// only test the vilibility for activities.
boolean testVisibility = AndroidConstants.CLASS_ACTIVITY.equals(
- mReferenceClass);
+ mReferenceClass);
// test the class
setErrorMessage(BaseProjectHelper.testClassForManifest(
private void handleBrowseClick() {
Text text = getTextWidget();
-
+
// we need to get the project of the manifest.
IProject project = getProject();
if (project != null) {
-
+
// Create a search scope including only the source folder of the current
// project.
IPackageFragmentRoot[] packageFragmentRoots = getPackageFragmentRoots(project,
if (dlg instanceof ITypeSelectionComponent) {
((ITypeSelectionComponent)dlg).triggerSearch();
}
-
+
if (dlg.open() == Window.OK) {
Object[] results = dlg.getResult();
if (results.length == 1) {
// get the package name from the manifest.
String packageName = getManifestPackage();
-
+
if (className.length() == 0) {
createNewClass(packageName, null /* className */);
} else {
fullClassName = packageName + "." + className; //$NON-NLS-1$
}
}
-
+
// in case the type is enclosed, we need to replace the $ with .
fullClassName = fullClassName.replaceAll("\\$", "\\."); //$NON-NLS-1$ //$NON-NLS2$
-
+
// now we try to find the file that contains this class and we open it in the editor.
IProject project = getProject();
IJavaProject javaProject = JavaCore.create(project);
}
}
}
-
+
private IProject getProject() {
UiElementNode uiNode = getUiParent();
AndroidEditor editor = uiNode.getEditor();
IFile file = ((IFileEditorInput)input).getFile();
return file.getProject();
}
-
+
return null;
}
private String getManifestPackage() {
// get the root uiNode to get the 'package' attribute value.
UiElementNode rootNode = getUiParent().getUiRoot();
-
+
Element xmlElement = (Element) rootNode.getXmlNode();
if (xmlElement != null) {
return result.toArray(new IPackageFragmentRoot[result.size()]);
}
-
+
private void handleNewType(IType type) {
Text text = getTextWidget();
// get the fully qualified name with $ to properly detect the enclosing types.
String name = type.getFullyQualifiedName('$');
-
+
String packageValue = getManifestPackage();
-
+
// check if the class doesn't start with the package.
if (packageValue.length() > 0 && name.startsWith(packageValue)) {
// if it does, we remove the package and the first dot.
name = name.substring(packageValue.length() + 1);
-
+
// look for how many segments we have left.
// if one, just write it that way.
// if more than one, write it with a leading dot.
text.setText(name);
}
}
-
+
private void createNewClass(String packageName, String className) {
// create the wizard page for the class creation, and configure it
NewClassWizardPage page = new NewClassWizardPage();
-
+
// set the parent class
page.setSuperClass(mReferenceClass, true /* canBeModified */);
-
+
// get the source folders as java elements.
IPackageFragmentRoot[] roots = getPackageFragmentRoots(getProject(),
true /*include_containers*/);
IPackageFragmentRoot currentRoot = null;
IPackageFragment currentFragment = null;
int packageMatchCount = -1;
-
+
for (IPackageFragmentRoot root : roots) {
// Get the java element for the package.
// This method is said to always return a IPackageFragment even if the
}
}
}
-
+
ArrayList<IPackageFragment> createdFragments = null;
if (currentRoot != null) {
// know what to delete in case of a cancel.
try {
createdFragments = new ArrayList<IPackageFragment>();
-
+
int totalCount = packageName.split("\\.").length; //$NON-NLS-1$
int count = 0;
int index = -1;
index = packageName.indexOf('.', index+1);
count++;
}
-
+
// create the rest of the segments, except for the last one as indexOf will
// return -1;
while (count < totalCount - 1) {
packageName.substring(0, index),
true /* force*/, new NullProgressMonitor()));
}
-
+
// create the last package
createdFragments.add(currentRoot.createPackageFragment(
packageName, true /* force*/, new NullProgressMonitor()));
-
+
// set the root and fragment in the Wizard page
page.setPackageFragmentRoot(currentRoot, true /* canBeModified*/);
page.setPackageFragment(createdFragments.get(createdFragments.size()-1),
// if we haven't found a valid fragment, we set the root to the first source folder.
page.setPackageFragmentRoot(roots[0], true /* canBeModified*/);
}
-
+
// if we have a starting class name we use it
if (className != null) {
page.setTypeName(className, true /* canBeModified*/);
}
-
+
// create the action that will open it the wizard.
OpenNewClassWizardAction action = new OpenNewClassWizardAction();
action.setConfiguredWizardPage(page);
action.run();
IJavaElement element = action.getCreatedElement();
-
+
if (element != null) {
if (element.getElementType() == IJavaElement.TYPE) {
-
+
IType type = (IType)element;
-
+
if (mPostCreationAction != null) {
mPostCreationAction.processNewType(type);
}
-
+
handleNewType(type);
}
} else {
}
}
}
-
+
/**
* Sets the error messages. If message is <code>null</code>, the message is removed.
* @param message the message to set, or <code>null</code> to remove the current message
getManagedForm().getMessageManager().removeMessage(textWidget, textWidget);
}
}
-
+
@Override
public String[] getPossibleValues(String prefix) {
// TODO: compute a list of existing classes for content assist completion
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
import com.android.sdklib.SdkConstants;
-import com.android.sdklib.xml.ManifestConstants;
+import com.android.sdklib.xml.AndroidManifest;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
String value;
switch (mValidLevel) {
case LEVEL_MANIFEST:
- if (ManifestConstants.NODE_MANIFEST.equals(localName)) {
+ if (AndroidManifest.NODE_MANIFEST.equals(localName)) {
// lets get the package name.
mPackage = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_PACKAGE,
+ AndroidManifest.ATTRIBUTE_PACKAGE,
false /* hasNamespace */);
mValidLevel++;
}
break;
case LEVEL_APPLICATION:
- if (ManifestConstants.NODE_APPLICATION.equals(localName)) {
+ if (AndroidManifest.NODE_APPLICATION.equals(localName)) {
value = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_PROCESS,
+ AndroidManifest.ATTRIBUTE_PROCESS,
true /* hasNamespace */);
if (value != null) {
addProcessName(value);
}
value = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_DEBUGGABLE,
+ AndroidManifest.ATTRIBUTE_DEBUGGABLE,
true /* hasNamespace*/);
if (value != null) {
mDebuggable = Boolean.parseBoolean(value);
}
mValidLevel++;
- } else if (ManifestConstants.NODE_USES_SDK.equals(localName)) {
+ } else if (AndroidManifest.NODE_USES_SDK.equals(localName)) {
mApiLevelRequirement = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_MIN_SDK_VERSION,
+ AndroidManifest.ATTRIBUTE_MIN_SDK_VERSION,
true /* hasNamespace */);
- } else if (ManifestConstants.NODE_INSTRUMENTATION.equals(localName)) {
+ } else if (AndroidManifest.NODE_INSTRUMENTATION.equals(localName)) {
processInstrumentationNode(attributes);
}
break;
case LEVEL_ACTIVITY:
- if (ManifestConstants.NODE_ACTIVITY.equals(localName)) {
+ if (AndroidManifest.NODE_ACTIVITY.equals(localName)) {
processActivityNode(attributes);
mValidLevel++;
- } else if (ManifestConstants.NODE_SERVICE.equals(localName)) {
+ } else if (AndroidManifest.NODE_SERVICE.equals(localName)) {
processNode(attributes, AndroidConstants.CLASS_SERVICE);
mValidLevel++;
- } else if (ManifestConstants.NODE_RECEIVER.equals(localName)) {
+ } else if (AndroidManifest.NODE_RECEIVER.equals(localName)) {
processNode(attributes, AndroidConstants.CLASS_BROADCASTRECEIVER);
mValidLevel++;
- } else if (ManifestConstants.NODE_PROVIDER.equals(localName)) {
+ } else if (AndroidManifest.NODE_PROVIDER.equals(localName)) {
processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
mValidLevel++;
- } else if (ManifestConstants.NODE_USES_LIBRARY.equals(localName)) {
+ } else if (AndroidManifest.NODE_USES_LIBRARY.equals(localName)) {
value = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_NAME,
+ AndroidManifest.ATTRIBUTE_NAME,
true /* hasNamespace */);
if (value != null) {
mLibraries.add(value);
case LEVEL_INTENT_FILTER:
// only process this level if we are in an activity
if (mCurrentActivity != null &&
- ManifestConstants.NODE_INTENT.equals(localName)) {
+ AndroidManifest.NODE_INTENT.equals(localName)) {
mCurrentActivity.resetIntentFilter();
mValidLevel++;
}
break;
case LEVEL_CATEGORY:
if (mCurrentActivity != null) {
- if (ManifestConstants.NODE_ACTION.equals(localName)) {
+ if (AndroidManifest.NODE_ACTION.equals(localName)) {
// get the name attribute
String action = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_NAME,
+ AndroidManifest.ATTRIBUTE_NAME,
true /* hasNamespace */);
if (action != null) {
mCurrentActivity.setHasAction(true);
mCurrentActivity.setHasMainAction(
ACTION_MAIN.equals(action));
}
- } else if (ManifestConstants.NODE_CATEGORY.equals(localName)) {
+ } else if (AndroidManifest.NODE_CATEGORY.equals(localName)) {
String category = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_NAME,
+ AndroidManifest.ATTRIBUTE_NAME,
true /* hasNamespace */);
if (CATEGORY_LAUNCHER.equals(category)) {
mCurrentActivity.setHasLauncherCategory(true);
*/
private void processActivityNode(Attributes attributes) {
// lets get the activity name, and add it to the list
- String activityName = getAttributeValue(attributes, ManifestConstants.ATTRIBUTE_NAME,
+ String activityName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_NAME,
true /* hasNamespace */);
if (activityName != null) {
- activityName = combinePackageAndClassName(mPackage, activityName);
+ activityName = AndroidManifest.combinePackageAndClassName(mPackage, activityName);
// get the exported flag.
String exportedStr = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_EXPORTED, true);
+ AndroidManifest.ATTRIBUTE_EXPORTED, true);
boolean exported = exportedStr == null ||
exportedStr.toLowerCase().equals("true"); // $NON-NLS-1$
mCurrentActivity = new Activity(activityName, exported);
mCurrentActivity = null;
}
- String processName = getAttributeValue(attributes, ManifestConstants.ATTRIBUTE_PROCESS,
+ String processName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_PROCESS,
true /* hasNamespace */);
if (processName != null) {
addProcessName(processName);
*/
private void processNode(Attributes attributes, String superClassName) {
// lets get the class name, and check it if required.
- String serviceName = getAttributeValue(attributes, ManifestConstants.ATTRIBUTE_NAME,
+ String serviceName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_NAME,
true /* hasNamespace */);
if (serviceName != null) {
- serviceName = combinePackageAndClassName(mPackage, serviceName);
+ serviceName = AndroidManifest.combinePackageAndClassName(mPackage, serviceName);
if (mMarkErrors) {
checkClass(serviceName, superClassName, false /* testVisibility */);
}
}
- String processName = getAttributeValue(attributes, ManifestConstants.ATTRIBUTE_PROCESS,
+ String processName = getAttributeValue(attributes, AndroidManifest.ATTRIBUTE_PROCESS,
true /* hasNamespace */);
if (processName != null) {
addProcessName(processName);
private void processInstrumentationNode(Attributes attributes) {
// lets get the class name, and check it if required.
String instrumentationName = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_NAME,
+ AndroidManifest.ATTRIBUTE_NAME,
true /* hasNamespace */);
if (instrumentationName != null) {
- String instrClassName = combinePackageAndClassName(mPackage, instrumentationName);
+ String instrClassName = AndroidManifest.combinePackageAndClassName(mPackage,
+ instrumentationName);
String targetPackage = getAttributeValue(attributes,
- ManifestConstants.ATTRIBUTE_TARGET_PACKAGE,
+ AndroidManifest.ATTRIBUTE_TARGET_PACKAGE,
true /* hasNamespace */);
mInstrumentations.add(new Instrumentation(instrClassName, targetPackage));
if (mMarkErrors) {
}
/**
- * Combines a java package, with a class value from the manifest to make a fully qualified
- * class name
- * @param javaPackage the java package from the manifest.
- * @param className the class name from the manifest.
- * @return the fully qualified class name.
- */
- public static String combinePackageAndClassName(String javaPackage, String className) {
- if (className == null || className.length() == 0) {
- return javaPackage;
- }
- if (javaPackage == null || javaPackage.length() == 0) {
- return className;
- }
-
- // the class name can be a subpackage (starts with a '.'
- // char), a simple class name (no dot), or a full java package
- boolean startWithDot = (className.charAt(0) == '.');
- boolean hasDot = (className.indexOf('.') != -1);
- if (startWithDot || hasDot == false) {
-
- // add the concatenation of the package and class name
- if (startWithDot) {
- return javaPackage + className;
- } else {
- return javaPackage + '.' + className;
- }
- } else {
- // just add the class as it should be a fully qualified java name.
- return className;
- }
- }
-
- /**
* Given a fully qualified activity name (e.g. com.foo.test.MyClass) and given a project
* package base name (e.g. com.foo), returns the relative activity name that would be used
* the "name" attribute of an "activity" element.
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static KeyboardState getEnum(String value) {
+ public static KeyboardState getEnum(String value) {
for (KeyboardState orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static NavigationMethod getEnum(String value) {
+ public static NavigationMethod getEnum(String value) {
for (NavigationMethod orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static Density getEnum(String value) {
+ public static Density getEnum(String value) {
for (Density orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static ScreenOrientation getEnum(String value) {
+ public static ScreenOrientation getEnum(String value) {
for (ScreenOrientation orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static ScreenRatio getEnum(String value) {
+ public static ScreenRatio getEnum(String value) {
for (ScreenRatio orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static ScreenSize getEnum(String value) {
+ public static ScreenSize getEnum(String value) {
for (ScreenSize orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static TextInputMethod getEnum(String value) {
+ public static TextInputMethod getEnum(String value) {
for (TextInputMethod orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
* @param value The qualifier value.
* @return the enum for the qualifier value or null if no matching was found.
*/
- static TouchScreenType getEnum(String value) {
+ public static TouchScreenType getEnum(String value) {
for (TouchScreenType orient : values()) {
if (orient.mValue.equals(value)) {
return orient;
package com.android.ide.eclipse.adt.internal.sdk;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
-import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
-import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
-import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
-import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
import java.util.Collections;
import java.util.HashMap;
public Map<String, FolderConfiguration> getConfigs() {
return mMap;
}
-
- /**
- * temp method returning some hard-coded devices.
- * TODO: load devices from the SDK and add-ons and remove this method.
- */
- public static DeviceConfiguration[] getDevices() {
- DeviceConfiguration adp1 = new DeviceConfiguration("ADP1");
- // default config
- FolderConfiguration defConfig = new FolderConfiguration();
- defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
- defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
- defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
- defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
- defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.QWERTY));
- defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
- defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
-
- // specific configs
- FolderConfiguration closedLand = new FolderConfiguration();
- closedLand.set(defConfig);
- closedLand.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
- closedLand.addQualifier(new KeyboardStateQualifier(KeyboardState.HIDDEN));
- adp1.addConfig("Closed, landscape", closedLand);
-
- FolderConfiguration closedPort = new FolderConfiguration();
- closedPort.set(defConfig);
- closedPort.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
- closedPort.addQualifier(new KeyboardStateQualifier(KeyboardState.HIDDEN));
- adp1.addConfig("Closed, portrait", closedPort);
-
- FolderConfiguration opened = new FolderConfiguration();
- opened.set(defConfig);
- opened.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
- opened.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
- adp1.addConfig("Opened", opened);
-
- DeviceConfiguration ion = new DeviceConfiguration("Ion");
- // default config
- defConfig = new FolderConfiguration();
- defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
- defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
- defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
- defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
- defConfig.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
- defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.NOKEY));
- defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
- defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
-
- // specific configs
- FolderConfiguration landscape = new FolderConfiguration();
- landscape.set(defConfig);
- landscape.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
- ion.addConfig("Landscape", landscape);
-
- FolderConfiguration portrait = new FolderConfiguration();
- portrait.set(defConfig);
- portrait.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
- ion.addConfig("Portrait", portrait);
-
- return new DeviceConfiguration[] { adp1, ion };
-
- }
-}
+ }
package com.android.ide.eclipse.adt.internal.sdk;\r
\r
\r
+import org.xml.sax.ErrorHandler;\r
+import org.xml.sax.SAXException;\r
+\r
import java.io.InputStream;\r
\r
+import javax.xml.XMLConstants;\r
+import javax.xml.transform.stream.StreamSource;\r
+import javax.xml.validation.Schema;\r
+import javax.xml.validation.SchemaFactory;\r
+import javax.xml.validation.Validator;\r
+\r
/**\r
- * Public constants for the sdk-repository XML Schema.\r
+ * Public constants for the layout device description XML Schema.\r
*/\r
public class LayoutConfigsXsd {\r
\r
\r
public static final String NODE_SCREEN_DIMENSION = "screen-dimension"; //$NON-NLS-1$\r
\r
+ /** The screen-dimension element has 2 size element children. */\r
public static final String NODE_SIZE = "size"; //$NON-NLS-1$\r
\r
+ public static final String NODE_XPDI = "xdpi"; //$NON-NLS-1$\r
+\r
+ public static final String NODE_YDPI = "ydpi"; //$NON-NLS-1$\r
+\r
/**\r
* The "name" attribute, used by both the "device" and the "config"\r
* elements. It represents the user-interface name of these objects.\r
return LayoutConfigsXsd.class.getResourceAsStream("layout-configs.xsd"); //$NON-NLS-1$\r
}\r
\r
+ /** Helper method that returns a {@link Validator} for our XSD */\r
+ public static Validator getValidator(ErrorHandler handler) throws SAXException {\r
+ InputStream xsdStream = getXsdStream();\r
+ SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);\r
+ Schema schema = factory.newSchema(new StreamSource(xsdStream));\r
+ Validator validator = schema.newValidator();\r
+ if (handler != null) {\r
+ validator.setErrorHandler(handler);\r
+ }\r
+\r
+ return validator;\r
+ }\r
+\r
}\r
--- /dev/null
+/*
+ * 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.ide.eclipse.adt.internal.sdk;
+
+import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
+import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
+import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
+import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@link DefaultHandler} implementation to parse Layout Device XML file.
+ * @see LayoutConfigsXsd
+ * @see Layout-configs.xsd
+ */
+class LayoutDeviceHandler extends DefaultHandler {
+ /*
+ * The handler does most of the work in startElement and endElement.
+ * In startElement, it'll create DeviceConfiguration on <device>, as well as
+ * FolderConfiguration instances on <default> and <config>.
+ * Those objects are then filled as new nodes are discovered.
+ *
+ * For the qualifier values, the qualifier is created and added to the current config
+ * on the endElement, by using the content found in characters().
+ */
+
+ private List<DeviceConfiguration> mDevices = new ArrayList<DeviceConfiguration>();
+
+ private DeviceConfiguration mCurrentDevice;
+ private FolderConfiguration mDefaultConfig;
+ private FolderConfiguration mCurrentConfig;
+ private final StringBuilder mStringAccumulator = new StringBuilder();
+
+ private String mSize1, mSize2;
+
+ public List<DeviceConfiguration> getDevices() {
+ return mDevices;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String name, Attributes attributes)
+ throws SAXException {
+ if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) {
+ // get the deviceName, will not be null since we validated the XML.
+ String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME);
+
+ // create a device and add it to the list
+ mCurrentDevice = new DeviceConfiguration(deviceName);
+ mDevices.add(mCurrentDevice);
+ } else if (LayoutConfigsXsd.NODE_DEFAULT.equals(localName)) {
+ // create a new default config
+ mDefaultConfig = mCurrentConfig = new FolderConfiguration();
+ } else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) {
+ // create a new config
+ mCurrentConfig = new FolderConfiguration();
+
+ // init with default config if applicable
+ if (mDefaultConfig != null) {
+ mCurrentConfig.set(mDefaultConfig);
+ }
+
+ // get the name of the config
+ String deviceName = attributes.getValue("", LayoutConfigsXsd.ATTR_NAME);
+
+ // give it to the current device.
+ mCurrentDevice.addConfig(deviceName, mCurrentConfig);
+ } else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) {
+ mSize1 = mSize2 = null;
+ }
+
+ mStringAccumulator.setLength(0);
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ mStringAccumulator.append(ch, start, length);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String name) throws SAXException {
+ if (LayoutConfigsXsd.NODE_DEVICE.equals(localName)) {
+ mCurrentDevice = null;
+ mDefaultConfig = null;
+ } else if (LayoutConfigsXsd.NODE_CONFIG.equals(localName)) {
+ mCurrentConfig = null;
+ } else if (LayoutConfigsXsd.NODE_SCREEN_SIZE.equals(localName)) {
+ ScreenSizeQualifier ssq = new ScreenSizeQualifier(
+ ScreenSize.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setScreenSizeQualifier(ssq);
+ } else if (LayoutConfigsXsd.NODE_SCREEN_RATIO.equals(localName)) {
+ ScreenRatioQualifier srq = new ScreenRatioQualifier(
+ ScreenRatio.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setScreenRatioQualifier(srq);
+ } else if (LayoutConfigsXsd.NODE_SCREEN_ORIENTATION.equals(localName)) {
+ ScreenOrientationQualifier soq = new ScreenOrientationQualifier(
+ ScreenOrientation.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setScreenOrientationQualifier(soq);
+ } else if (LayoutConfigsXsd.NODE_PIXEL_DENSITY.equals(localName)) {
+ PixelDensityQualifier pdq = new PixelDensityQualifier(
+ Density.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setPixelDensityQualifier(pdq);
+ } else if (LayoutConfigsXsd.NODE_TOUCH_TYPE.equals(localName)) {
+ TouchScreenQualifier tsq = new TouchScreenQualifier(
+ TouchScreenType.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setTouchTypeQualifier(tsq);
+ } else if (LayoutConfigsXsd.NODE_KEYBOARD_STATE.equals(localName)) {
+ KeyboardStateQualifier ksq = new KeyboardStateQualifier(
+ KeyboardState.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setKeyboardStateQualifier(ksq);
+ } else if (LayoutConfigsXsd.NODE_TEXT_INPUT_METHOD.equals(localName)) {
+ TextInputMethodQualifier timq = new TextInputMethodQualifier(
+ TextInputMethod.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setTextInputMethodQualifier(timq);
+ } else if (LayoutConfigsXsd.NODE_NAV_METHOD.equals(localName)) {
+ NavigationMethodQualifier nmq = new NavigationMethodQualifier(
+ NavigationMethod.getEnum(mStringAccumulator.toString()));
+ mCurrentConfig.setNavigationMethodQualifier(nmq);
+ } else if (LayoutConfigsXsd.NODE_SCREEN_DIMENSION.equals(localName)) {
+ ScreenDimensionQualifier qual = ScreenDimensionQualifier.getQualifier(mSize1, mSize2);
+ if (qual != null) {
+ mCurrentConfig.setScreenDimensionQualifier(qual);
+ }
+ } else if (LayoutConfigsXsd.NODE_SIZE.equals(localName)) {
+ if (mSize1 == null) {
+ mSize1 = mStringAccumulator.toString();
+ } else if (mSize2 == null) {
+ mSize2 = mStringAccumulator.toString();
+ }
+ }
+ }
+}
import com.android.ddmlib.IDevice;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
+import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
+import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
+import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
+import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IProjectListener;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Validator;
+
/**
* Central point to load, manipulate and deal with the Android SDK. Only one SDK can be used
* at the same time.
new HashMap<IProject, ApkSettings>();
private final String mDocBaseUrl;
+ private List<DeviceConfiguration> mLayoutDevices = new ArrayList<DeviceConfiguration>();
+
/**
* Classes implementing this interface will receive notification when targets are changed.
*/
// pre-compute some paths
mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() +
SdkConstants.OS_SDK_DOCS_FOLDER);
+
+ // create some built-in layout devices
+ createDefaultLayoutDevices();
}
/**
// ignore this. The project will be added to the map the first time the target needs
// to be resolved.
}
+
+
+ // ---------- Device Configuration methods ----------
+
+ /**
+ * 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.
+ */
+ private static class CaptureErrorHandler implements ErrorHandler {
+
+ private final String mSourceLocation;
+
+ private boolean mFoundError = false;
+
+ CaptureErrorHandler(String sourceLocation) {
+ mSourceLocation = sourceLocation;
+ }
+
+ public boolean foundError() {
+ return mFoundError;
+ }
+
+ /**
+ * @throws SAXException
+ */
+ public void error(SAXParseException ex) throws SAXException {
+ mFoundError = true;
+ AdtPlugin.log(ex, "Error validating %1$s", mSourceLocation);
+ }
+
+ /**
+ * @throws SAXException
+ */
+ public void fatalError(SAXParseException ex) throws SAXException {
+ mFoundError = true;
+ AdtPlugin.log(ex, "Error validating %1$s", mSourceLocation);
+ }
+
+ /**
+ * @throws SAXException
+ */
+ public void warning(SAXParseException ex) throws SAXException {
+ // ignore those for now.
+ }
+ }
+
+ /**
+ * Returns the list of {@link DeviceConfiguration} found in the SDK.
+ */
+ public List<DeviceConfiguration> getLayoutDevices() {
+ return mLayoutDevices;
+ }
+
+ /**
+ * Parses the SDK add-ons to look for files called {@link SdkConstants#FN_DEVICES_XML} to
+ * load {@link DeviceConfiguration} from them.
+ */
+ public void parseAddOnLayoutDevices() {
+ SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+ parserFactory.setNamespaceAware(true);
+
+ IAndroidTarget[] targets = mManager.getTargets();
+ for (IAndroidTarget target : targets) {
+ if (target.isPlatform() == false) {
+ File deviceXml = new File(target.getLocation(), SdkConstants.FN_DEVICES_XML);
+ if (deviceXml.isFile()) {
+ parseLayoutDevices(parserFactory, deviceXml);
+ }
+ }
+ }
+
+ mLayoutDevices = Collections.unmodifiableList(mLayoutDevices);
+ }
+
+ /**
+ * Does the actual parsing of a devices.xml file.
+ */
+ private void parseLayoutDevices(SAXParserFactory parserFactory, File deviceXml) {
+ // first we validate the XML
+ try {
+ Source source = new StreamSource(new FileReader(deviceXml));
+
+ CaptureErrorHandler errorHandler = new CaptureErrorHandler(deviceXml.getAbsolutePath());
+
+ Validator validator = LayoutConfigsXsd.getValidator(errorHandler);
+ validator.validate(source);
+
+ if (errorHandler.foundError() == false) {
+ // do the actual parsing
+ LayoutDeviceHandler handler = new LayoutDeviceHandler();
+
+ SAXParser parser = parserFactory.newSAXParser();
+ parser.parse(new InputSource(new FileInputStream(deviceXml)), handler);
+
+ // get the parsed devices
+ mLayoutDevices.addAll(handler.getDevices());
+ }
+ } catch (SAXException e) {
+ AdtPlugin.log(e, "Error parsing %1$s", deviceXml.getAbsoluteFile());
+ } catch (FileNotFoundException e) {
+ // this shouldn't happen as we check above.
+ } catch (IOException e) {
+ AdtPlugin.log(e, "Error reading %1$s", deviceXml.getAbsoluteFile());
+ } catch (ParserConfigurationException e) {
+ AdtPlugin.log(e, "Error parsing %1$s", deviceXml.getAbsoluteFile());
+ }
+ }
+
+ /**
+ * Creates some built-it layout devices.
+ */
+ private void createDefaultLayoutDevices() {
+ DeviceConfiguration adp1 = new DeviceConfiguration("ADP1");
+ mLayoutDevices.add(adp1);
+ // default config
+ FolderConfiguration defConfig = new FolderConfiguration();
+ defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
+ defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
+ defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
+ defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
+ defConfig.addQualifier(new KeyboardStateQualifier(KeyboardState.SOFT));
+ defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.QWERTY));
+ defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
+ defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
+
+ // specific configs
+ FolderConfiguration closedPort = new FolderConfiguration();
+ closedPort.set(defConfig);
+ closedPort.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
+ adp1.addConfig("Portrait, closed", closedPort);
+
+ FolderConfiguration closedLand = new FolderConfiguration();
+ closedLand.set(defConfig);
+ closedLand.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
+ adp1.addConfig("Landscape, closed", closedLand);
+
+ FolderConfiguration opened = new FolderConfiguration();
+ opened.set(defConfig);
+ opened.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
+ opened.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
+ adp1.addConfig("Landscape, opened", opened);
+
+ DeviceConfiguration ion = new DeviceConfiguration("Ion");
+ mLayoutDevices.add(ion);
+ // default config
+ defConfig = new FolderConfiguration();
+ defConfig.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
+ defConfig.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
+ defConfig.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
+ defConfig.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
+ defConfig.addQualifier(new KeyboardStateQualifier(KeyboardState.EXPOSED));
+ defConfig.addQualifier(new TextInputMethodQualifier(TextInputMethod.NOKEY));
+ defConfig.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
+ defConfig.addQualifier(new ScreenDimensionQualifier(480, 320));
+
+ // specific configs
+ FolderConfiguration landscape = new FolderConfiguration();
+ landscape.set(defConfig);
+ landscape.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.LANDSCAPE));
+ ion.addConfig("Landscape", landscape);
+
+ FolderConfiguration portrait = new FolderConfiguration();
+ portrait.set(defConfig);
+ portrait.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
+ ion.addConfig("Portrait", portrait);
+ }
}
+
<xsd:element name="layout-configs">
<xsd:annotation>
- <xsd:documentation>
+ <xsd:documentation xml:lang="en">
The "layout-configs" element is the root element of this schema.
It must contain one or more "device" elements that each define the configurations
<xsd:element name="device" minOccurs="1" maxOccurs="unbounded">
<xsd:annotation>
- <xsd:documentation>
+ <xsd:documentation xml:lang="en">
A device element must contain at most one "default" element
followed by one or more "config" elements.
-->
<xsd:complexType name="parametersType">
<xsd:annotation>
- <xsd:documentation>
+ <xsd:documentation xml:lang="en">
The parametersType define all the parameters that can happen either in a
"default" element or in a named "config" element.
Each parameter element can appear once at most.
+
+ Parameters here are the same as those used to specify alternate Android
+ resources, as documented by
+ http://d.android.com/guide/topics/resources/resources-i18n.html#AlternateResources
</xsd:documentation>
</xsd:annotation>
<!-- parametersType says that 0..1 of each of these elements must be declared. -->
<xsd:element name="screen-size" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies that the configuration is for a particular class of screen.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="small" />
- <xsd:enumeration value="medium" />
+ <xsd:enumeration value="normal" />
<xsd:enumeration value="large" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="screen-ratio" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies that the configuration is for a taller/wider than traditional
+ screen. This is based purely on the aspect ration of the screen: QVGA,
+ HVGA, and VGA are notlong; WQVGA, WVGA, FWVGA are long. Note that long
+ may mean either wide or tall, depending on the current orientation.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="long" />
</xsd:element>
<xsd:element name="screen-orientation" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies that the configuration is for a screen that is tall (port) or
+ wide (land).
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="port" />
</xsd:element>
<xsd:element name="pixel-density" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the screen density the configuration is defined for. The medium
+ density of traditional HVGA screens (mdpi) is defined to be approximately
+ 160dpi; low density (ldpi) is 120, and high density (hdpi) is 240. There
+ is thus a 4:3 scaling factor between each density, so a 9x9 bitmap in ldpi
+ would be 12x12 is mdpi and 16x16 in hdpi.
+ The special nodpi density that can be used in resource qualifiers is not
+ a valid keyword here.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="ldpi" />
</xsd:element>
<xsd:element name="touch-type" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the touch type the configuration is defined for.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="notouch" />
</xsd:element>
<xsd:element name="keyboard-state" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ If your configuration uses a soft keyboard, use the keyssoft value.
+ If it doesn't and has a real keyboard, use keysexposed or keyshidden.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="keysexposed" />
</xsd:element>
<xsd:element name="text-input-method" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the primary text input method the configuration is designed for.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="nokeys" />
</xsd:element>
<xsd:element name="nav-method" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the primary non-touchscreen navigation method the configuration
+ is designed for.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:simpleType>
<xsd:restriction base="xsd:token">
<xsd:enumeration value="dpad" />
</xsd:element>
<xsd:element name="screen-dimension" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the device screen resolution, in pixels.
+ </xsd:documentation>
+ </xsd:annotation>
<xsd:complexType>
<xsd:sequence minOccurs="2" maxOccurs="2">
</xsd:sequence>
</xsd:complexType>
</xsd:element>
+
+ <xsd:element name="xdpi" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the actual density in X of the device screen.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:float">
+ <xsd:minExclusive value="0" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+ <xsd:element name="ydpi" minOccurs="0">
+ <xsd:annotation>
+ <xsd:documentation xml:lang="en">
+ Specifies the actual density in Y of the device screen.
+ </xsd:documentation>
+ </xsd:annotation>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:float">
+ <xsd:minExclusive value="0" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
</xsd:all>
</xsd:complexType>
import java.io.InputStream;\r
import java.io.StringReader;\r
\r
-import javax.xml.XMLConstants;\r
import javax.xml.transform.Source;\r
import javax.xml.transform.stream.StreamSource;\r
-import javax.xml.validation.Schema;\r
-import javax.xml.validation.SchemaFactory;\r
import javax.xml.validation.Validator;\r
\r
import junit.framework.TestCase;\r
\r
// --- Helpers ------------\r
\r
- /** Helper method that returns a validator for our XSD */\r
- private Validator getValidator(CaptureErrorHandler handler) throws SAXException {\r
- InputStream xsdStream = LayoutConfigsXsd.getXsdStream();\r
- SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);\r
- Schema schema = factory.newSchema(new StreamSource(xsdStream));\r
- Validator validator = schema.newValidator();\r
- if (handler != null) {\r
- validator.setErrorHandler(handler);\r
+ /** An helper that validates a string against an expected regexp. */\r
+ private void assertRegex(String expectedRegexp, String actualString) {\r
+ assertNotNull(actualString);\r
+ assertTrue(\r
+ String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n",\r
+ expectedRegexp, actualString),\r
+ actualString.matches(expectedRegexp));\r
+ }\r
+\r
+ public void checkFailure(String document, String regexp) throws Exception {\r
+ Source source = new StreamSource(new StringReader(document));\r
+\r
+ // don't capture the validator errors, we want it to fail and catch the exception\r
+ Validator validator = LayoutConfigsXsd.getValidator(null);\r
+ try {\r
+ validator.validate(source);\r
+ } catch (SAXParseException e) {\r
+ // We expect a parse expression referring to this grammar rule\r
+ assertRegex(regexp, e.getMessage());\r
+ return;\r
}\r
+ // If we get here, the validator has not failed as we expected it to.\r
+ fail();\r
+ }\r
\r
- return validator;\r
+ public void checkSuccess(String document) throws Exception {\r
+ Source source = new StreamSource(new StringReader(document));\r
+\r
+ CaptureErrorHandler handler = new CaptureErrorHandler();\r
+ Validator validator = LayoutConfigsXsd.getValidator(null);\r
+ validator.validate(source);\r
+ handler.verify();\r
}\r
\r
+ // --- Tests ------------\r
+\r
/** Validate a valid sample using an InputStream */\r
public void testValidateLocalRepositoryFile() throws Exception {\r
\r
Source source = new StreamSource(xmlStream);\r
\r
CaptureErrorHandler handler = new CaptureErrorHandler();\r
- Validator validator = getValidator(handler);\r
+ Validator validator = LayoutConfigsXsd.getValidator(handler);\r
validator.validate(source);\r
handler.verify();\r
}\r
\r
- /** An helper that validates a string against an expected regexp. */\r
- private void assertRegex(String expectedRegexp, String actualString) {\r
- assertNotNull(actualString);\r
- assertTrue(\r
- String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n",\r
- expectedRegexp, actualString),\r
- actualString.matches(expectedRegexp));\r
- }\r
-\r
- // --- Tests ------------\r
-\r
/** A document should at least have a root to be valid */\r
public void testEmptyXml() throws Exception {\r
- String document = "<?xml version=\"1.0\"?>";\r
-\r
- Source source = new StreamSource(new StringReader(document));\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>",\r
\r
- CaptureErrorHandler handler = new CaptureErrorHandler();\r
- Validator validator = getValidator(handler);\r
-\r
- try {\r
- validator.validate(source);\r
- } catch (SAXParseException e) {\r
- // We expect to get this specific exception message\r
- assertRegex("Premature end of file.*", e.getMessage());\r
- return;\r
- }\r
- // We shouldn't get here\r
- handler.verify();\r
- fail();\r
+ // expected failure\r
+ "Premature end of file.*");\r
}\r
\r
/** A document with an unknown element. */\r
public void testUnknownContentXml() throws Exception {\r
- String document = "<?xml version=\"1.0\"?>" +\r
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
- "<d:unknown />" +\r
- "</d:layout-configs>";\r
-\r
- Source source = new StreamSource(new StringReader(document));\r
-\r
- // don't capture the validator errors, we want it to fail and catch the exception\r
- Validator validator = getValidator(null);\r
- try {\r
- validator.validate(source);\r
- } catch (SAXParseException e) {\r
- // We expect a parse expression referring to this grammar rule\r
- assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage());\r
- return;\r
- }\r
- // If we get here, the validator has not failed as we expected it to.\r
- fail();\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:unknown />" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-complex-type.2.4.a: Invalid content was found.*");\r
}\r
\r
/** A document with an missing attribute in a device element. */\r
public void testIncompleteContentXml() throws Exception {\r
- String document = "<?xml version=\"1.0\"?>" +\r
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
- "<d:device />" +\r
- "</d:layout-configs>";\r
-\r
- Source source = new StreamSource(new StringReader(document));\r
-\r
- // don't capture the validator errors, we want it to fail and catch the exception\r
- Validator validator = getValidator(null);\r
- try {\r
- validator.validate(source);\r
- } catch (SAXParseException e) {\r
- // We expect a parse error referring to this grammar rule\r
- assertRegex("cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'.", e.getMessage());\r
- return;\r
- }\r
- // If we get here, the validator has not failed as we expected it to.\r
- fail();\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device />" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'.");\r
}\r
\r
/** A document with a root element containing no device element is not valid. */\r
public void testEmptyRootXml() throws Exception {\r
- String document = "<?xml version=\"1.0\"?>" +\r
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" />";\r
-\r
- Source source = new StreamSource(new StringReader(document));\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" />",\r
\r
- // don't capture the validator errors, we want it to fail and catch the exception\r
- Validator validator = getValidator(null);\r
- try {\r
- validator.validate(source);\r
- } catch (SAXParseException e) {\r
- // We expect a parse expression referring to this grammar rule\r
- assertRegex("cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*", e.getMessage());\r
- return;\r
- }\r
- // If we get here, the validator has not failed as we expected it to.\r
- fail();\r
+ // expected failure\r
+ "cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*");\r
}\r
\r
/** A document with an empty device element is not valid. */\r
public void testEmptyDeviceXml() throws Exception {\r
- String document = "<?xml version=\"1.0\"?>" +\r
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
- "<d:device name=\"foo\"/>" +\r
- "</d:layout-configs>";\r
-\r
- Source source = new StreamSource(new StringReader(document));\r
-\r
- // don't capture the validator errors, we want it to fail and catch the exception\r
- Validator validator = getValidator(null);\r
- try {\r
- validator.validate(source);\r
- } catch (SAXParseException e) {\r
- // We expect a parse error referring to this grammar rule\r
- assertRegex("cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*", e.getMessage());\r
- return;\r
- }\r
- // If we get here, the validator has not failed as we expected it to.\r
- fail();\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\"/>" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*");\r
}\r
\r
/** A document with two default elements in a device element is not valid. */\r
public void testTwoDefaultsXml() throws Exception {\r
- String document = "<?xml version=\"1.0\"?>" +\r
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
- "<d:device name=\"foo\">" +\r
- " <d:default />" +\r
- " <d:default />" +\r
- "</d:device>" +\r
- "</d:layout-configs>";\r
-\r
- Source source = new StreamSource(new StringReader(document));\r
-\r
- // don't capture the validator errors, we want it to fail and catch the exception\r
- Validator validator = getValidator(null);\r
- try {\r
- validator.validate(source);\r
- } catch (SAXParseException e) {\r
- // We expect a parse error referring to this grammar rule\r
- assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*", e.getMessage());\r
- return;\r
- }\r
- // If we get here, the validator has not failed as we expected it to.\r
- fail();\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\">" +\r
+ " <d:default />" +\r
+ " <d:default />" +\r
+ "</d:device>" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*");\r
}\r
\r
/** The default elements must be defined before the config one. It's invalid if after. */\r
public void testDefaultConfigOrderXml() throws Exception {\r
- String document = "<?xml version=\"1.0\"?>" +\r
- "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
- "<d:device name=\"foo\">" +\r
- " <d:config name=\"must-be-after-default\" />" +\r
- " <d:default />" +\r
- "</d:device>" +\r
- "</d:layout-configs>";\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\">" +\r
+ " <d:config name=\"must-be-after-default\" />" +\r
+ " <d:default />" +\r
+ "</d:device>" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*");\r
+ }\r
\r
- Source source = new StreamSource(new StringReader(document));\r
+ /** Screen dimension cannot be 0. */\r
+ public void testScreenDimZeroXml() throws Exception {\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\">" +\r
+ " <d:default>" +\r
+ " <d:screen-dimension> <d:size>0</d:size> <d:size>1</d:size> </d:screen-dimension>" +\r
+ " </d:default>" +\r
+ "</d:device>" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-minInclusive-valid: Value '0' is not facet-valid with respect to minInclusive '1'.*");\r
+ }\r
\r
- // don't capture the validator errors, we want it to fail and catch the exception\r
- Validator validator = getValidator(null);\r
- try {\r
- validator.validate(source);\r
- } catch (SAXParseException e) {\r
- // We expect a parse error referring to this grammar rule\r
- assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*", e.getMessage());\r
- return;\r
- }\r
- // If we get here, the validator has not failed as we expected it to.\r
- fail();\r
+ /** Screen dimension cannot be negative. */\r
+ public void testScreenDimNegativeXml() throws Exception {\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\">" +\r
+ " <d:default>" +\r
+ " <d:screen-dimension> <d:size>-5</d:size> <d:size>1</d:size> </d:screen-dimension>" +\r
+ " </d:default>" +\r
+ "</d:device>" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-minInclusive-valid: Value '-5' is not facet-valid with respect to minInclusive '1'.*");\r
+ }\r
+\r
+ /** X/Y dpi cannot be 0. */\r
+ public void testXDpiZeroXml() throws Exception {\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\">" +\r
+ " <d:default>" +\r
+ " <d:xdpi>0</d:xdpi>" +\r
+ " </d:default>" +\r
+ "</d:device>" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-minExclusive-valid: Value '0' is not facet-valid with respect to minExclusive '0.0E1'.*");\r
}\r
+\r
+\r
+ /** X/Y dpi cannot be negative. */\r
+ public void testXDpiNegativeXml() throws Exception {\r
+ checkFailure(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\">" +\r
+ " <d:default>" +\r
+ " <d:xdpi>-3.1415926538</d:xdpi>" +\r
+ " </d:default>" +\r
+ "</d:device>" +\r
+ "</d:layout-configs>",\r
+\r
+ // expected failure\r
+ "cvc-minExclusive-valid: Value '-3.1415926538' is not facet-valid with respect to minExclusive '0.0E1'.*");\r
+ }\r
+\r
+ /** WHitespace around token is accepted by the schema. */\r
+ public void testTokenWhitespaceXml() throws Exception {\r
+ checkSuccess(\r
+ // document\r
+ "<?xml version=\"1.0\"?>" +\r
+ "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +\r
+ "<d:device name=\"foo\">" +\r
+ " <d:config name='foo'>" +\r
+ " <d:screen-ratio> \n long \r </d:screen-ratio>" +\r
+ " </d:config>" +\r
+ "</d:device>" +\r
+ "</d:layout-configs>");\r
+ }\r
+\r
}\r
+\r
<d:size>240</d:size> <!-- 2 * int>0 -->\r
<d:size>480</d:size>\r
</d:screen-dimension>\r
+ <d:xdpi>180.81234</d:xdpi>\r
+ <d:ydpi>180.81234</d:ydpi>\r
</d:default>\r
\r
<d:config name="Portrait">\r
<d:config name="screen-size-small">\r
<d:screen-size>small</d:screen-size>\r
</d:config>\r
- <d:config name="screen-size-medium">\r
- <d:screen-size>medium</d:screen-size>\r
+ <d:config name="screen-size-normal">\r
+ <d:screen-size>normal</d:screen-size>\r
</d:config>\r
<d:config name="screen-size-large">\r
<d:screen-size>large</d:screen-size>\r
<d:nav-method>nonav</d:nav-method>\r
</d:config>\r
\r
- </d:device>\r
+ <d:config name="xdpi">\r
+ <d:xdpi>240</d:xdpi>\r
+ </d:config>\r
+ <d:config name="ydpi">\r
+ <d:ydpi>2800</d:ydpi>\r
+ </d:config>\r
\r
+ </d:device>\r
\r
<d:device name="SomePhone"> <!-- 1..n -->\r
- <d:config name="screen-size-medium">\r
- <d:screen-size>medium</d:screen-size>\r
+ <d:config name="screen-size-normal">\r
+ <d:screen-size>normal</d:screen-size>\r
</d:config>\r
</d:device>\r
\r
package com.android.ide.eclipse.tests.functests.layoutRendering;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
+import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
+import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
+import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenRatioQualifier.ScreenRatio;
+import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenSizeQualifier.ScreenSize;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
+import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
null /*projectKey*/,
320,
480,
+ false, //renderFullSize
160, //density
160, //xdpi
160, // ydpi
}
}
+ /**
+ * Returns a config. This must be a valid config like a device would return. This is to
+ * prevent issues where some resources don't exist in all cases and not in the default
+ * (for instance only available in hdpi and mdpi but not in default).
+ * @return
+ */
private FolderConfiguration getConfiguration() {
FolderConfiguration config = new FolderConfiguration();
+ // this matches an ADP1.
+ config.addQualifier(new ScreenSizeQualifier(ScreenSize.NORMAL));
+ config.addQualifier(new ScreenRatioQualifier(ScreenRatio.NOTLONG));
+ config.addQualifier(new ScreenOrientationQualifier(ScreenOrientation.PORTRAIT));
+ config.addQualifier(new PixelDensityQualifier(Density.MEDIUM));
+ config.addQualifier(new TouchScreenQualifier(TouchScreenType.FINGER));
+ config.addQualifier(new KeyboardStateQualifier(KeyboardState.HIDDEN));
+ config.addQualifier(new TextInputMethodQualifier(TextInputMethod.QWERTY));
+ config.addQualifier(new NavigationMethodQualifier(NavigationMethod.TRACKBALL));
+ config.addQualifier(new ScreenDimensionQualifier(480, 320));
+
return config;
}
}
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
+import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier.Density;
import junit.framework.TestCase;
}
public void testCheckAndSet() {
- assertEquals(true, pdq.checkAndSet("123dpi", config));//$NON-NLS-1$
+ assertEquals(true, pdq.checkAndSet("ldpi", config));//$NON-NLS-1$
assertTrue(config.getPixelDensityQualifier() != null);
- assertEquals(123, config.getPixelDensityQualifier().getValue());
- assertEquals("123dpi", config.getPixelDensityQualifier().toString()); //$NON-NLS-1$
+ assertEquals(Density.LOW, config.getPixelDensityQualifier().getValue());
+ assertEquals("ldpi", config.getPixelDensityQualifier().toString()); //$NON-NLS-1$
}
public void testFailures() {
assertEquals(false, pdq.checkAndSet("", config));//$NON-NLS-1$
assertEquals(false, pdq.checkAndSet("dpi", config));//$NON-NLS-1$
- assertEquals(false, pdq.checkAndSet("123DPI", config));//$NON-NLS-1$
+ assertEquals(false, pdq.checkAndSet("123dpi", config));//$NON-NLS-1$
assertEquals(false, pdq.checkAndSet("123", config));//$NON-NLS-1$
assertEquals(false, pdq.checkAndSet("sdfdpi", config));//$NON-NLS-1$
}
null, // network code
null, // language
null, // region
+ null, // screen size
+ null, // screen ratio
null, // screen orientation
null, // dpi
null, // touch mode
null, // keyboard state
null, // text input
null, // navigation
- null); // screen size
+ null, // screen dimension
+ null);// version
addFolder(mResources, defaultConfig, validMemberList);
null, // network code
"en", // language
null, // region
+ null, // screen size
+ null, // screen ratio
null, // screen orientation
null, // dpi
null, // touch mode
KeyboardState.EXPOSED.getValue(), // keyboard state
null, // text input
null, // navigation
- null); // screen size
+ null, // screen dimension
+ null);// version
addFolder(mResources, config1, validMemberList);
null, // network code
"en", // language
null, // region
+ null, // screen size
+ null, // screen ratio
null, // screen orientation
null, // dpi
null, // touch mode
KeyboardState.HIDDEN.getValue(), // keyboard state
null, // text input
null, // navigation
- null); // screen size
+ null, // screen dimension
+ null);// version
addFolder(mResources, config2, validMemberList);
null, // network code
"en", // language
null, // region
+ null, // screen size
+ null, // screen ratio
ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
null, // dpi
null, // touch mode
null, // keyboard state
null, // text input
null, // navigation
- null); // screen size
+ null, // screen dimension
+ null);// version
addFolder(mResources, config3, validMemberList);
"mnc435", // network code
"en", // language
"rUS", // region
+ "normal", // screen size
+ "notlong", // screen ratio
ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
- "160dpi", // dpi
+ "mdpi", // dpi
TouchScreenType.FINGER.getValue(), // touch mode
KeyboardState.EXPOSED.getValue(), // keyboard state
TextInputMethod.QWERTY.getValue(), // text input
NavigationMethod.DPAD.getValue(), // navigation
- "480x320"); // screen size
+ "480x320", // screen dimension
+ "v3"); // version
addFolder(mResources, config4, invalidMemberList);
}
"mnc435", // network code
"en", // language
"rUS", // region
+ "normal", // screen size
+ "notlong", // screen ratio
ScreenOrientation.LANDSCAPE.getValue(), // screen orientation
- "160dpi", // dpi
+ "mdpi", // dpi
TouchScreenType.FINGER.getValue(), // touch mode
KeyboardState.EXPOSED.getValue(), // keyboard state
TextInputMethod.QWERTY.getValue(), // text input
NavigationMethod.DPAD.getValue(), // navigation
- "480x320"); // screen size
+ "480x320", // screen dimension
+ "v3"); // version
ResourceFile result = mResources.getMatchingFile(SEARCHED_FILENAME,
ResourceFolderType.LAYOUT, testConfig);
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name">
- <activity android:name=".ACTIVITY_NAME"
+ <activity android:name="ACTIVITY_ENTRY_NAME"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
-->
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="PACKAGE"
- android:label="Tests for ACTIVITY_NAME"/>
+ android:label="Tests for PACKAGE"/>
</manifest>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<module version="4" relativePaths="true" type="JAVA_MODULE">
- <component name="ModuleRootManager" />
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- </content>
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" name="android" level="project" />
- <orderEntry type="inheritedJdk" />
- <orderEntryProperties />
- </component>
-</module>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4" relativePaths="false">
- <component name="AntConfiguration">
- <defaultAnt bundledAnt="true" />
- <buildFile url="file://$PROJECT_DIR$/build.xml">
- <additionalClassPath />
- <antReference projectDefault="true" />
- <customJdkName value="" />
- <maximumHeapSize value="128" />
- <properties />
- </buildFile>
- </component>
- <component name="BuildJarProjectSettings">
- <option name="BUILD_JARS_ON_MAKE" value="false" />
- </component>
- <component name="CodeStyleProjectProfileManger">
- <option name="PROJECT_PROFILE" />
- <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
- </component>
- <component name="CodeStyleSettingsManager">
- <option name="PER_PROJECT_SETTINGS" />
- <option name="USE_PER_PROJECT_SETTINGS" value="false" />
- </component>
- <component name="CompilerConfiguration">
- <option name="DEFAULT_COMPILER" value="Javac" />
- <option name="DEPLOY_AFTER_MAKE" value="0" />
- <resourceExtensions>
- <entry name=".+\.(properties|xml|html|dtd|tld)" />
- <entry name=".+\.(gif|png|jpeg|jpg)" />
- </resourceExtensions>
- <wildcardResourcePatterns>
- <entry name="?*.properties" />
- <entry name="?*.xml" />
- <entry name="?*.gif" />
- <entry name="?*.png" />
- <entry name="?*.jpeg" />
- <entry name="?*.jpg" />
- <entry name="?*.html" />
- <entry name="?*.dtd" />
- <entry name="?*.tld" />
- </wildcardResourcePatterns>
- </component>
- <component name="DataSourceManagerImpl" />
- <component name="DependenciesAnalyzeManager">
- <option name="myForwardDirection" value="false" />
- </component>
- <component name="DependencyValidationManager" />
- <component name="EclipseCompilerSettings">
- <option name="DEBUGGING_INFO" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="true" />
- <option name="DEPRECATION" value="false" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- <option name="MAXIMUM_HEAP_SIZE" value="128" />
- </component>
- <component name="EclipseEmbeddedCompilerSettings">
- <option name="DEBUGGING_INFO" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="true" />
- <option name="DEPRECATION" value="false" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- <option name="MAXIMUM_HEAP_SIZE" value="128" />
- </component>
- <component name="EntryPointsManager">
- <entry_points />
- </component>
- <component name="ExportToHTMLSettings">
- <option name="PRINT_LINE_NUMBERS" value="false" />
- <option name="OPEN_IN_BROWSER" value="false" />
- <option name="OUTPUT_DIRECTORY" />
- </component>
- <component name="GUI Designer component loader factory" />
- <component name="IdProvider" IDEtalkID="F6EC4D80E2C03FEF19EDD201903A6DFE" />
- <component name="InspectionProjectProfileManager">
- <option name="PROJECT_PROFILE" value="Project Default" />
- <option name="USE_PROJECT_LEVEL_SETTINGS" value="false" />
- <scopes />
- <profiles>
- <profile version="1.0" is_locked="false">
- <option name="myName" value="Project Default" />
- <option name="myLocal" value="false" />
- <used_levels>
- <error>
- <option name="myName" value="ERROR" />
- <option name="myVal" value="400" />
- </error>
- <warning>
- <option name="myName" value="WARNING" />
- <option name="myVal" value="300" />
- </warning>
- <information>
- <option name="myName" value="INFO" />
- <option name="myVal" value="200" />
- </information>
- <server>
- <option name="myName" value="SERVER PROBLEM" />
- <option name="myVal" value="100" />
- </server>
- </used_levels>
- <inspection_tool class="ClassReferencesSubclass" level="WARNING" enabled="true" />
- <inspection_tool class="MissingOverrideAnnotation" level="WARNING" enabled="true" />
- <inspection_tool class="Finalize" level="WARNING" enabled="true" />
- <inspection_tool class="UnusedImport" level="WARNING" enabled="true" />
- <inspection_tool class="StaticInheritance" level="WARNING" enabled="true" />
- <inspection_tool class="RedundantMethodOverride" level="WARNING" enabled="true" />
- <inspection_tool class="AbstractMethodCallInConstructor" level="WARNING" enabled="true" />
- <inspection_tool class="RawUseOfParameterizedType" level="WARNING" enabled="true">
- <option name="ignoreObjectConstruction" value="true" />
- <option name="ignoreTypeCasts" value="false" />
- </inspection_tool>
- <inspection_tool class="SystemGC" level="WARNING" enabled="true" />
- <inspection_tool class="ConstantNamingConvention" level="WARNING" enabled="true">
- <option name="m_regex" value="[A-Z_\d]*" />
- <option name="m_minLength" value="5" />
- <option name="m_maxLength" value="32" />
- </inspection_tool>
- <inspection_tool class="EnumeratedConstantNamingConvention" level="WARNING" enabled="true">
- <option name="m_regex" value="[A-Z][A-Za-z\d]*" />
- <option name="m_minLength" value="5" />
- <option name="m_maxLength" value="32" />
- </inspection_tool>
- <inspection_tool class="DivideByZero" level="WARNING" enabled="true" />
- <inspection_tool class="CloneCallsConstructors" level="WARNING" enabled="true" />
- <inspection_tool class="CloneDeclaresCloneNotSupported" level="WARNING" enabled="false" />
- <inspection_tool class="CloneInNonCloneableClass" level="WARNING" enabled="true" />
- <inspection_tool class="UtilityClassWithoutPrivateConstructor" level="WARNING" enabled="true">
- <option name="ignoreClassesWithOnlyMain" value="false" />
- </inspection_tool>
- <inspection_tool class="UtilityClassWithPublicConstructor" level="WARNING" enabled="true" />
- <inspection_tool class="ConditionalExpressionWithIdenticalBranches" level="WARNING" enabled="true" />
- <inspection_tool class="CanBeFinal" level="WARNING" enabled="false">
- <option name="REPORT_CLASSES" value="false" />
- <option name="REPORT_METHODS" value="false" />
- <option name="REPORT_FIELDS" value="true" />
- </inspection_tool>
- <inspection_tool class="ThisEscapedInConstructor" level="WARNING" enabled="true" />
- <inspection_tool class="NonThreadSafeLazyInitialization" level="WARNING" enabled="true" />
- <inspection_tool class="FieldMayBeStatic" level="WARNING" enabled="true" />
- <inspection_tool class="InnerClassMayBeStatic" level="WARNING" enabled="true" />
- <inspection_tool class="MethodMayBeStatic" level="WARNING" enabled="true">
- <option name="m_onlyPrivateOrFinal" value="false" />
- <option name="m_ignoreEmptyMethods" value="true" />
- </inspection_tool>
- <inspection_tool class="ComponentRegistrationProblems" level="ERROR" enabled="false">
- <option name="CHECK_PLUGIN_XML" value="true" />
- <option name="CHECK_JAVA_CODE" value="true" />
- <option name="CHECK_ACTIONS" value="true" />
- </inspection_tool>
- <inspection_tool class="ComponentNotRegistered" level="WARNING" enabled="false">
- <option name="CHECK_ACTIONS" value="true" />
- <option name="IGNORE_NON_PUBLIC" value="true" />
- </inspection_tool>
- <inspection_tool class="BusyWait" level="WARNING" enabled="true" />
- <inspection_tool class="UnconditionalWait" level="WARNING" enabled="true" />
- <inspection_tool class="WaitNotInLoop" level="WARNING" enabled="true" />
- </profile>
- </profiles>
- </component>
- <component name="JavacSettings">
- <option name="DEBUGGING_INFO" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="false" />
- <option name="DEPRECATION" value="true" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- <option name="MAXIMUM_HEAP_SIZE" value="128" />
- </component>
- <component name="JavadocGenerationManager">
- <option name="OUTPUT_DIRECTORY" />
- <option name="OPTION_SCOPE" value="protected" />
- <option name="OPTION_HIERARCHY" value="true" />
- <option name="OPTION_NAVIGATOR" value="true" />
- <option name="OPTION_INDEX" value="true" />
- <option name="OPTION_SEPARATE_INDEX" value="true" />
- <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
- <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
- <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
- <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
- <option name="OPTION_DEPRECATED_LIST" value="true" />
- <option name="OTHER_OPTIONS" value="" />
- <option name="HEAP_SIZE" />
- <option name="LOCALE" />
- <option name="OPEN_IN_BROWSER" value="true" />
- </component>
- <component name="JikesSettings">
- <option name="JIKES_PATH" value="" />
- <option name="DEBUGGING_INFO" value="true" />
- <option name="DEPRECATION" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="false" />
- <option name="IS_EMACS_ERRORS_MODE" value="true" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- </component>
- <component name="LogConsolePreferences">
- <option name="FILTER_ERRORS" value="false" />
- <option name="FILTER_WARNINGS" value="false" />
- <option name="FILTER_INFO" value="true" />
- <option name="CUSTOM_FILTER" />
- </component>
- <component name="ProjectModuleManager">
- <modules>
- <module fileurl="file://$PROJECT_DIR$/ACTIVITY_NAME.iml" filepath="$PROJECT_DIR$/ACTIVITY_NAME.iml" />
- </modules>
- </component>
- <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="1.5" project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/bin" />
- </component>
- <component name="ProjectRunConfigurationManager" />
- <component name="RmicSettings">
- <option name="IS_EANABLED" value="false" />
- <option name="DEBUGGING_INFO" value="true" />
- <option name="GENERATE_NO_WARNINGS" value="false" />
- <option name="GENERATE_IIOP_STUBS" value="false" />
- <option name="ADDITIONAL_OPTIONS_STRING" value="" />
- </component>
- <component name="StarteamVcsAdapter" />
- <component name="XSLT-Support.FileAssociationsManager" />
- <component name="com.intellij.jsf.UserDefinedFacesConfigs">
- <option name="USER_DEFINED_CONFIGS">
- <value>
- <list size="0" />
- </value>
- </option>
- </component>
- <component name="libraryTable">
- <library name="android">
- <CLASSES>
- <root url="jar://ANDROID_SDK_FOLDER/android.jar!/" />
- </CLASSES>
- <JAVADOC>
- <root url="file://ANDROID_SDK_FOLDER/docs/reference" />
- </JAVADOC>
- <SOURCES />
- </library>
- </component>
- <UsedPathMacros />
-</project>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4" relativePaths="false">
- <component name="AntConfiguration">
- <defaultAnt bundledAnt="true" />
- <buildFile url="file://$PROJECT_DIR$/build.xml">
- <additionalClassPath />
- <antReference projectDefault="true" />
- <customJdkName value="" />
- <maximumHeapSize value="128" />
- <properties />
- </buildFile>
- </component>
- <component name="BookmarkManager" />
- <component name="ChangeBrowserSettings">
- <option name="MAIN_SPLITTER_PROPORTION" value="0.3" />
- <option name="MESSAGES_SPLITTER_PROPORTION" value="0.8" />
- <option name="USE_DATE_BEFORE_FILTER" value="false" />
- <option name="USE_DATE_AFTER_FILTER" value="false" />
- <option name="USE_CHANGE_BEFORE_FILTER" value="false" />
- <option name="USE_CHANGE_AFTER_FILTER" value="false" />
- <option name="DATE_BEFORE" value="" />
- <option name="DATE_AFTER" value="" />
- <option name="CHANGE_BEFORE" value="" />
- <option name="CHANGE_AFTER" value="" />
- <option name="USE_USER_FILTER" value="false" />
- <option name="USER" value="" />
- </component>
- <component name="ChangeListManager">
- <list default="true" name="Default" comment="" />
- </component>
- <component name="ChangeListSynchronizer" />
- <component name="ChangesViewManager" flattened_view="true" />
- <component name="CheckinPanelState" />
- <component name="Commander">
- <leftPanel />
- <rightPanel />
- <splitter proportion="0.5" />
- </component>
- <component name="CompilerWorkspaceConfiguration">
- <option name="COMPILE_IN_BACKGROUND" value="false" />
- <option name="AUTO_SHOW_ERRORS_IN_EDITOR" value="true" />
- <option name="CLOSE_MESSAGE_VIEW_IF_SUCCESS" value="true" />
- <option name="COMPILE_DEPENDENT_FILES" value="false" />
- <option name="CLEAR_OUTPUT_DIRECTORY" value="false" />
- <option name="ASSERT_NOT_NULL" value="true" />
- </component>
- <component name="CoverageDataManager" />
- <component name="Cvs2Configuration">
- <option name="PRUNE_EMPTY_DIRECTORIES" value="true" />
- <option name="MERGING_MODE" value="0" />
- <option name="MERGE_WITH_BRANCH1_NAME" value="HEAD" />
- <option name="MERGE_WITH_BRANCH2_NAME" value="HEAD" />
- <option name="RESET_STICKY" value="false" />
- <option name="CREATE_NEW_DIRECTORIES" value="true" />
- <option name="DEFAULT_TEXT_FILE_SUBSTITUTION" value="kv" />
- <option name="PROCESS_UNKNOWN_FILES" value="false" />
- <option name="PROCESS_DELETED_FILES" value="false" />
- <option name="PROCESS_IGNORED_FILES" value="false" />
- <option name="RESERVED_EDIT" value="false" />
- <option name="CHECKOUT_DATE_OR_REVISION_SETTINGS">
- <value>
- <option name="BRANCH" value="" />
- <option name="DATE" value="" />
- <option name="USE_BRANCH" value="false" />
- <option name="USE_DATE" value="false" />
- </value>
- </option>
- <option name="UPDATE_DATE_OR_REVISION_SETTINGS">
- <value>
- <option name="BRANCH" value="" />
- <option name="DATE" value="" />
- <option name="USE_BRANCH" value="false" />
- <option name="USE_DATE" value="false" />
- </value>
- </option>
- <option name="SHOW_CHANGES_REVISION_SETTINGS">
- <value>
- <option name="BRANCH" value="" />
- <option name="DATE" value="" />
- <option name="USE_BRANCH" value="false" />
- <option name="USE_DATE" value="false" />
- </value>
- </option>
- <option name="SHOW_OUTPUT" value="false" />
- <option name="ADD_WATCH_INDEX" value="0" />
- <option name="REMOVE_WATCH_INDEX" value="0" />
- <option name="UPDATE_KEYWORD_SUBSTITUTION" />
- <option name="MAKE_NEW_FILES_READONLY" value="false" />
- <option name="SHOW_CORRUPTED_PROJECT_FILES" value="0" />
- <option name="TAG_AFTER_PROJECT_COMMIT" value="false" />
- <option name="OVERRIDE_EXISTING_TAG_FOR_PROJECT" value="true" />
- <option name="TAG_AFTER_PROJECT_COMMIT_NAME" value="" />
- <option name="CLEAN_COPY" value="false" />
- </component>
- <component name="DaemonCodeAnalyzer">
- <disable_hints />
- </component>
- <component name="DebuggerManager">
- <breakpoint_any>
- <breakpoint>
- <option name="NOTIFY_CAUGHT" value="true" />
- <option name="NOTIFY_UNCAUGHT" value="true" />
- <option name="ENABLED" value="false" />
- <option name="SUSPEND_POLICY" value="SuspendAll" />
- <option name="LOG_ENABLED" value="false" />
- <option name="LOG_EXPRESSION_ENABLED" value="false" />
- <option name="COUNT_FILTER_ENABLED" value="false" />
- <option name="COUNT_FILTER" value="0" />
- <option name="CONDITION_ENABLED" value="false" />
- <option name="CLASS_FILTERS_ENABLED" value="false" />
- <option name="INSTANCE_FILTERS_ENABLED" value="false" />
- <option name="CONDITION" value="" />
- <option name="LOG_MESSAGE" value="" />
- </breakpoint>
- <breakpoint>
- <option name="NOTIFY_CAUGHT" value="true" />
- <option name="NOTIFY_UNCAUGHT" value="true" />
- <option name="ENABLED" value="false" />
- <option name="SUSPEND_POLICY" value="SuspendAll" />
- <option name="LOG_ENABLED" value="false" />
- <option name="LOG_EXPRESSION_ENABLED" value="false" />
- <option name="COUNT_FILTER_ENABLED" value="false" />
- <option name="COUNT_FILTER" value="0" />
- <option name="CONDITION_ENABLED" value="false" />
- <option name="CLASS_FILTERS_ENABLED" value="false" />
- <option name="INSTANCE_FILTERS_ENABLED" value="false" />
- <option name="CONDITION" value="" />
- <option name="LOG_MESSAGE" value="" />
- </breakpoint>
- </breakpoint_any>
- <breakpoint_rules />
- <ui_properties />
- </component>
- <component name="ErrorTreeViewConfiguration">
- <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
- <option name="HIDE_WARNINGS" value="false" />
- </component>
- <component name="FavoritesManager">
- <favorites_list name="LunarLander" />
- </component>
- <component name="FavoritesProjectViewPane" />
- <component name="FileEditorManager">
- <leaf>
- <file leaf-file-name="ACTIVITY_NAME.java" pinned="false" current="true" current-in-tab="true">
- <entry file="file://$PROJECT_DIR$/src/PACKAGE_PATH/ACTIVITY_NAME.java">
- <provider selected="true" editor-type-id="text-editor">
- <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.08211144">
- <folding />
- </state>
- </provider>
- </entry>
- </file>
- </leaf>
- </component>
- <component name="FindManager">
- <FindUsagesManager>
- <setting name="OPEN_NEW_TAB" value="false" />
- </FindUsagesManager>
- </component>
- <component name="HierarchyBrowserManager">
- <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
- <option name="SORT_ALPHABETICALLY" value="false" />
- <option name="HIDE_CLASSES_WHERE_METHOD_NOT_IMPLEMENTED" value="false" />
- </component>
- <component name="InspectionManager">
- <option name="AUTOSCROLL_TO_SOURCE" value="false" />
- <option name="SPLITTER_PROPORTION" value="0.5" />
- <option name="GROUP_BY_SEVERITY" value="false" />
- <option name="FILTER_RESOLVED_ITEMS" value="true" />
- <option name="ANALYZE_TEST_SOURCES" value="true" />
- <option name="SHOW_DIFF_WITH_PREVIOUS_RUN" value="false" />
- <option name="SCOPE_TYPE" value="1" />
- <option name="CUSTOM_SCOPE_NAME" value="" />
- <option name="SHOW_ONLY_DIFF" value="false" />
- <option name="myCurrentProfileName" value="Default" />
- </component>
- <component name="J2EEProjectPane" />
- <component name="JspContextManager" />
- <component name="ModuleEditorState">
- <option name="LAST_EDITED_MODULE_NAME" />
- <option name="LAST_EDITED_TAB_NAME" />
- </component>
- <component name="NamedScopeManager" />
- <component name="PackagesPane">
- <subPane>
- <PATH>
- <PATH_ELEMENT>
- <option name="myItemId" value="ACTIVITY_NAME.ipr" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="ACTIVITY_NAME" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" />
- </PATH_ELEMENT>
- </PATH>
- </subPane>
- </component>
- <component name="PerforceChangeBrowserSettings">
- <option name="USE_CLIENT_FILTER" value="true" />
- <option name="CLIENT" value="" />
- </component>
- <component name="PerforceDirect.Settings">
- <option name="useP4CONFIG" value="true" />
- <option name="port" value="<perforce_server>:1666" />
- <option name="client" value="" />
- <option name="user" value="" />
- <option name="passwd" value="" />
- <option name="showCmds" value="false" />
- <option name="useNativeApi" value="false" />
- <option name="pathToExec" value="p4" />
- <option name="useCustomPathToExec" value="false" />
- <option name="SYNC_FORCE" value="false" />
- <option name="SYNC_RUN_RESOLVE" value="true" />
- <option name="REVERT_UNCHANGED_FILES" value="true" />
- <option name="CHARSET" value="none" />
- <option name="SHOW_BRANCHES_HISTORY" value="true" />
- <option name="ENABLED" value="true" />
- <option name="USE_LOGIN" value="false" />
- <option name="LOGIN_SILENTLY" value="false" />
- <option name="INTEGRATE_RUN_RESOLVE" value="true" />
- <option name="INTEGRATE_REVERT_UNCHANGED" value="true" />
- <option name="SERVER_TIMEOUT" value="20000" />
- </component>
- <component name="ProjectLevelVcsManager">
- <OptionsSetting value="true" id="Add" />
- <OptionsSetting value="true" id="Remove" />
- <OptionsSetting value="true" id="Checkin" />
- <OptionsSetting value="true" id="Checkout" />
- <OptionsSetting value="true" id="Update" />
- <OptionsSetting value="true" id="Status" />
- <OptionsSetting value="true" id="Edit" />
- <ConfirmationsSetting value="0" id="Add" />
- <ConfirmationsSetting value="0" id="Remove" />
- </component>
- <component name="ProjectPane">
- <subPane>
- <PATH>
- <PATH_ELEMENT>
- <option name="myItemId" value="ACTIVITY_NAME.ipr" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
- </PATH_ELEMENT>
- <PATH_ELEMENT>
- <option name="myItemId" value="ACTIVITY_NAME" />
- <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewModuleNode" />
- </PATH_ELEMENT>
- </PATH>
- </subPane>
- </component>
- <component name="ProjectReloadState">
- <option name="STATE" value="0" />
- </component>
- <component name="ProjectView">
- <navigator currentView="ProjectPane" proportions="0.1" version="1" splitterProportion="0.5">
- <flattenPackages />
- <showMembers />
- <showModules />
- <showLibraryContents />
- <hideEmptyPackages />
- <abbreviatePackageNames />
- <showStructure PackagesPane="false" ProjectPane="false" />
- <autoscrollToSource />
- <autoscrollFromSource />
- <sortByType />
- </navigator>
- </component>
- <component name="PropertiesComponent">
- <property name="MemberChooser.copyJavadoc" value="false" />
- <property name="GoToClass.includeLibraries" value="false" />
- <property name="MemberChooser.showClasses" value="true" />
- <property name="MemberChooser.sorted" value="false" />
- <property name="GoToFile.includeJavaFiles" value="false" />
- <property name="GoToClass.toSaveIncludeLibraries" value="false" />
- </component>
- <component name="ReadonlyStatusHandler">
- <option name="SHOW_DIALOG" value="true" />
- </component>
- <component name="RecentsManager" />
- <component name="RestoreUpdateTree" />
- <component name="RunManager">
- <configuration default="true" type="Application" factoryName="Application" enabled="false" merge="false">
- <option name="MAIN_CLASS_NAME" />
- <option name="VM_PARAMETERS" />
- <option name="PROGRAM_PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="ENABLE_SWING_INSPECTOR" value="false" />
- <module name="" />
- </configuration>
- <configuration default="true" type="Applet" factoryName="Applet">
- <module name="" />
- <option name="MAIN_CLASS_NAME" />
- <option name="HTML_FILE_NAME" />
- <option name="HTML_USED" value="false" />
- <option name="WIDTH" value="400" />
- <option name="HEIGHT" value="300" />
- <option name="POLICY_FILE" value="/Developer/Applications/IntelliJ IDEA 6.0.4.app/bin/appletviewer.policy" />
- <option name="VM_PARAMETERS" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- </configuration>
- <configuration default="true" type="JUnit" factoryName="JUnit" enabled="false" merge="false">
- <module name="" />
- <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
- <option name="ALTERNATIVE_JRE_PATH" />
- <option name="PACKAGE_NAME" />
- <option name="MAIN_CLASS_NAME" />
- <option name="METHOD_NAME" />
- <option name="TEST_OBJECT" value="class" />
- <option name="VM_PARAMETERS" />
- <option name="PARAMETERS" />
- <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
- <option name="ADDITIONAL_CLASS_PATH" />
- <option name="TEST_SEARCH_SCOPE">
- <value defaultName="wholeProject" />
- </option>
- </configuration>
- <configuration default="true" type="Remote" factoryName="Remote">
- <option name="USE_SOCKET_TRANSPORT" value="true" />
- <option name="SERVER_MODE" value="false" />
- <option name="SHMEM_ADDRESS" value="javadebug" />
- <option name="HOST" value="localhost" />
- <option name="PORT" value="5005" />
- </configuration>
- </component>
- <component name="ScopeViewComponent" />
- <component name="SelectInManager" />
- <component name="StarteamConfiguration">
- <option name="SERVER" value="" />
- <option name="PORT" value="49201" />
- <option name="USER" value="" />
- <option name="PASSWORD" value="" />
- <option name="PROJECT" value="" />
- <option name="VIEW" value="" />
- <option name="ALTERNATIVE_WORKING_PATH" value="" />
- <option name="LOCK_ON_CHECKOUT" value="false" />
- <option name="UNLOCK_ON_CHECKIN" value="false" />
- </component>
- <component name="StructuralSearchPlugin" />
- <component name="StructureViewFactory">
- <option name="AUTOSCROLL_MODE" value="true" />
- <option name="AUTOSCROLL_FROM_SOURCE" value="false" />
- <option name="ACTIVE_ACTIONS" value="" />
- </component>
- <component name="Struts Assistant">
- <option name="showInputs" value="true" />
- <option name="resources">
- <value>
- <option name="strutsPath" />
- <option name="strutsHelp" />
- </value>
- </option>
- <option name="selectedTaglibs" />
- <option name="selectedTaglibs" />
- <option name="myStrutsValidationEnabled" value="true" />
- <option name="myTilesValidationEnabled" value="true" />
- <option name="myValidatorValidationEnabled" value="true" />
- <option name="myReportErrorsAsWarnings" value="true" />
- </component>
- <component name="SvnChangesBrowserSettings">
- <option name="USE_AUTHOR_FIELD" value="true" />
- <option name="AUTHOR" value="" />
- <option name="LOCATION" value="" />
- <option name="USE_PROJECT_SETTINGS" value="true" />
- <option name="USE_ALTERNATE_LOCATION" value="false" />
- </component>
- <component name="SvnConfiguration">
- <option name="USER" value="" />
- <option name="PASSWORD" value="" />
- <option name="PROCESS_UNRESOLVED" value="false" />
- <option name="LAST_MERGED_REVISION" />
- <option name="UPDATE_RUN_STATUS" value="false" />
- <option name="UPDATE_RECURSIVELY" value="true" />
- <option name="MERGE_DRY_RUN" value="false" />
- <upgradeMode>auto</upgradeMode>
- </component>
- <component name="TodoView" selected-index="0">
- <todo-panel id="selected-file">
- <are-packages-shown value="false" />
- <are-modules-shown value="false" />
- <flatten-packages value="false" />
- <is-autoscroll-to-source value="true" />
- </todo-panel>
- <todo-panel id="all">
- <are-packages-shown value="true" />
- <are-modules-shown value="false" />
- <flatten-packages value="false" />
- <is-autoscroll-to-source value="true" />
- </todo-panel>
- </component>
- <component name="ToolWindowManager">
- <frame x="0" y="22" width="1440" height="834" extended-state="0" />
- <editor active="false" />
- <layout>
- <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="CVS" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="IDEtalk" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="7" />
- <window_info id="Project" active="true" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24946082" order="0" />
- <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="1" />
- <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="1" />
- <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="6" />
- <window_info id="Module Dependencies" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Dependency Viewer" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="1" />
- <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="2" />
- <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" />
- <window_info id="File View" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="4" />
- <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" order="0" />
- <window_info id="IDEtalk Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="-1" />
- <window_info id="Web" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="2" />
- <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" order="0" />
- <window_info id="EJB" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="3" />
- <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" order="5" />
- </layout>
- </component>
- <component name="VCS.FileViewConfiguration">
- <option name="SELECTED_STATUSES" value="DEFAULT" />
- <option name="SELECTED_COLUMNS" value="DEFAULT" />
- <option name="SHOW_FILTERS" value="true" />
- <option name="CUSTOMIZE_VIEW" value="true" />
- <option name="SHOW_FILE_HISTORY_AS_TREE" value="true" />
- </component>
- <component name="VcsManagerConfiguration">
- <option name="OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT" value="true" />
- <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="true" />
- <option name="PERFORM_UPDATE_IN_BACKGROUND" value="false" />
- <option name="PERFORM_COMMIT_IN_BACKGROUND" value="false" />
- <option name="PUT_FOCUS_INTO_COMMENT" value="false" />
- <option name="FORCE_NON_EMPTY_COMMENT" value="false" />
- <option name="LAST_COMMIT_MESSAGE" />
- <option name="SAVE_LAST_COMMIT_MESSAGE" value="true" />
- <option name="CHECKIN_DIALOG_SPLITTER_PROPORTION" value="0.8" />
- <option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="false" />
- <option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="false" />
- <option name="REFORMAT_BEFORE_FILE_COMMIT" value="false" />
- <option name="FILE_HISTORY_DIALOG_COMMENTS_SPLITTER_PROPORTION" value="0.8" />
- <option name="FILE_HISTORY_DIALOG_SPLITTER_PROPORTION" value="0.5" />
- <option name="ERROR_OCCURED" value="false" />
- <option name="ACTIVE_VCS_NAME" value="CVS" />
- <option name="UPDATE_GROUP_BY_PACKAGES" value="false" />
- <option name="SHOW_FILE_HISTORY_AS_TREE" value="false" />
- <option name="FILE_HISTORY_SPLITTER_PROPORTION" value="0.6" />
- </component>
- <component name="XPathView.XPathProjectComponent">
- <history />
- <find-history />
- </component>
- <component name="XSLT-Support.FileAssociationsSettings" />
- <component name="antWorkspaceConfiguration">
- <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
- <option name="FILTER_TARGETS" value="false" />
- </component>
- <component name="com.intellij.ide.util.scopeChooser.ScopeChooserConfigurable" proportions="" version="1">
- <option name="myLastEditedConfigurable" />
- </component>
- <component name="com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectRootMasterDetailsConfigurable" proportions="0.1" version="1">
- <option name="myPlainMode" value="false" />
- <option name="myLastEditedConfigurable" value="android" />
- </component>
- <component name="com.intellij.profile.ui.ErrorOptionsConfigurable" proportions="" version="1">
- <option name="myLastEditedConfigurable" />
- </component>
- <component name="editorHistoryManager" />
-</project>
\ No newline at end of file
import android.app.Activity;
import android.os.Bundle;
-public class ACTIVITY_NAME extends Activity
+public class ACTIVITY_CLASS_NAME extends Activity
{
/** Called when the activity is first created. */
@Override
* <p/>
* To run this test, you can type:
* adb shell am instrument -w \
- * -e class PACKAGE.ACTIVITY_NAMETest \
+ * -e class ACTIVITY_FQ_NAME \
* PACKAGE.tests/android.test.InstrumentationTestRunner
*/
-public class ACTIVITY_NAMETest extends ActivityInstrumentationTestCase2<ACTIVITY_NAME> {
+public class ACTIVITY_CLASS_NAME extends ActivityInstrumentationTestCase2<ACTIVITY_TESTED_CLASS_NAME> {
- public ACTIVITY_NAMETest() {
- super("PACKAGE", ACTIVITY_NAME.class);
+ public ACTIVITY_CLASS_NAME() {
+ super("PACKAGE", ACTIVITY_TESTED_CLASS_NAME.class);
}
}
\ No newline at end of file
stdout("\nValid actions are composed of a verb and an optional direct object:");
for (String[] action : mActions) {
- stdout("- %1$6s %2$-7s: %3$s",
+ stdout("- %1$6s %2$-12s: %3$s",
action[ACTION_VERB_INDEX],
action[ACTION_OBJECT_INDEX],
action[ACTION_DESC_INDEX]);
import com.android.sdklib.internal.avd.AvdManager.AvdInfo;
import com.android.sdklib.internal.avd.HardwareProperties.HardwareProperty;
import com.android.sdklib.internal.project.ProjectCreator;
+import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectCreator.OutputLevel;
+import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
+import com.android.sdklib.xml.AndroidXPathFactory;
import com.android.sdkmanager.internal.repository.AboutPage;
import com.android.sdkmanager.internal.repository.SettingsPage;
import com.android.sdkuilib.repository.UpdaterWindow;
+import org.xml.sax.InputSource;
+
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+
/**
* Main class for the 'android' application.
*/
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
createProject();
+ } else if (SdkCommandLine.VERB_CREATE.equals(verb) &&
+ SdkCommandLine.OBJECT_TEST_PROJECT.equals(directObject)) {
+ createTestProject();
+
} else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
updateProject();
packageName,
activityName,
target,
- false /* isTestProject*/);
+ null /*pathToMain*/);
+ }
+
+ /**
+ * Creates a new Android test project based on command-line parameters
+ */
+ private void createTestProject() {
+
+ String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+
+ // first check the path of the parent project, and make sure it's valid.
+ String pathToMainProject = mSdkCommandLine.getParamTestProjectMain();
+
+ File parentProject = new File(pathToMainProject);
+ if (parentProject.isAbsolute() == false) {
+ // if the path is not absolute, we need to resolve it based on the
+ // destination path of the project
+ parentProject = new File(projectDir, pathToMainProject);
+ }
+
+ if (parentProject.isDirectory() == false) {
+ errorAndExit("Main project's directory does not exist: %1$s",
+ pathToMainProject);
+ }
+
+ // now look for a manifest in there
+ File manifest = new File(parentProject, SdkConstants.FN_ANDROID_MANIFEST_XML);
+ if (manifest.isFile() == false) {
+ errorAndExit("No AndroidManifest.xml file found in the main project directory: %1$s",
+ parentProject.getAbsolutePath());
+ }
+
+ // now query the manifest for the package file.
+ XPath xpath = AndroidXPathFactory.newXPath();
+ String packageName, activityName;
+
+ try {
+ packageName = xpath.evaluate("/manifest/@package",
+ new InputSource(new FileInputStream(manifest)));
+
+ mSdkLog.printf("Found main project package: %1$s\n", packageName);
+
+ // now get the name of the first activity we find
+ activityName = xpath.evaluate("/manifest/application/activity[1]/@android:name",
+ new InputSource(new FileInputStream(manifest)));
+ // xpath will return empty string when there's no match
+ if (activityName == null || activityName.length() == 0) {
+ activityName = null;
+ } else {
+ mSdkLog.printf("Found main project activity: %1$s\n", activityName);
+ }
+ } catch (FileNotFoundException e) {
+ // this shouldn't happen as we test it above.
+ errorAndExit("No AndroidManifest.xml file found in main project.");
+ return; // this is not strictly needed because errorAndExit will stop the execution,
+ // but this makes the java compiler happy, wrt to uninitialized variables.
+ } catch (XPathExpressionException e) {
+ // looks like the main manifest is not valid.
+ errorAndExit("Unable to parse main project manifest to get information.");
+ return; // this is not strictly needed because errorAndExit will stop the execution,
+ // but this makes the java compiler happy, wrt to uninitialized variables.
+ }
+
+ // now get the target hash
+ ProjectProperties p = ProjectProperties.load(parentProject.getAbsolutePath(),
+ PropertyType.DEFAULT);
+ String targetHash = p.getProperty(ProjectProperties.PROPERTY_TARGET);
+ if (targetHash == null) {
+ errorAndExit("Couldn't find the main project target");
+ }
+
+ // and resolve it.
+ IAndroidTarget target = mSdkManager.getTargetFromHashString(targetHash);
+ if (target == null) {
+ errorAndExit(
+ "Unable to resolve main project target '%1$s'. You may want to install the platform in your SDK.",
+ targetHash);
+ }
+
+ mSdkLog.printf("Found main project target: %1$s\n", target.getFullName());
+
+ ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
+ mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+ mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+ OutputLevel.NORMAL,
+ mSdkLog);
+
+ String projectName = mSdkCommandLine.getParamName();
+
+ if (projectName != null &&
+ !ProjectCreator.RE_PROJECT_NAME.matcher(projectName).matches()) {
+ errorAndExit(
+ "Project name '%1$s' contains invalid characters.\nAllowed characters are: %2$s",
+ projectName, ProjectCreator.CHARS_PROJECT_NAME);
+ return;
+ }
+
+ creator.createProject(projectDir,
+ projectName,
+ packageName,
+ activityName,
+ target,
+ pathToMainProject);
}
+
/**
* Updates an existing Android project based on command-line parameters
*/
public final static String VERB_DELETE = "delete";
public final static String VERB_UPDATE = "update";
- public static final String OBJECT_AVD = "avd";
- public static final String OBJECT_AVDS = "avds";
- public static final String OBJECT_TARGET = "target";
- public static final String OBJECT_TARGETS = "targets";
- public static final String OBJECT_PROJECT = "project";
- public static final String OBJECT_ADB = "adb";
-
- public static final String ARG_ALIAS = "alias";
- public static final String ARG_ACTIVITY = "activity";
-
- public static final String KEY_ACTIVITY = ARG_ACTIVITY;
- public static final String KEY_PACKAGE = "package";
- public static final String KEY_MODE = "mode";
- public static final String KEY_TARGET_ID = OBJECT_TARGET;
- public static final String KEY_NAME = "name";
- public static final String KEY_PATH = "path";
- public static final String KEY_FILTER = "filter";
- public static final String KEY_SKIN = "skin";
- public static final String KEY_SDCARD = "sdcard";
- public static final String KEY_FORCE = "force";
- public static final String KEY_RENAME = "rename";
- public static final String KEY_SUBPROJECTS = "subprojects";
+ public static final String OBJECT_AVD = "avd";
+ public static final String OBJECT_AVDS = "avds";
+ public static final String OBJECT_TARGET = "target";
+ public static final String OBJECT_TARGETS = "targets";
+ public static final String OBJECT_PROJECT = "project";
+ public static final String OBJECT_TEST_PROJECT = "test-project";
+ public static final String OBJECT_ADB = "adb";
+
+ public static final String ARG_ALIAS = "alias";
+ public static final String ARG_ACTIVITY = "activity";
+
+ public static final String KEY_ACTIVITY = ARG_ACTIVITY;
+ public static final String KEY_PACKAGE = "package";
+ public static final String KEY_MODE = "mode";
+ public static final String KEY_TARGET_ID = OBJECT_TARGET;
+ public static final String KEY_NAME = "name";
+ public static final String KEY_PATH = "path";
+ public static final String KEY_FILTER = "filter";
+ public static final String KEY_SKIN = "skin";
+ public static final String KEY_SDCARD = "sdcard";
+ public static final String KEY_FORCE = "force";
+ public static final String KEY_RENAME = "rename";
+ public static final String KEY_SUBPROJECTS = "subprojects";
+ public static final String KEY_MAIN_PROJECT = "main";
/**
* Action definitions for SdkManager command line.
{ VERB_UPDATE, OBJECT_PROJECT,
"Updates an Android Project (must have an AndroidManifest.xml)." },
+ { VERB_CREATE, OBJECT_TEST_PROJECT,
+ "Creates a new Android Test Project." },
+ { VERB_UPDATE, OBJECT_TEST_PROJECT,
+ "Updates an Android Test Project (must have an AndroidManifest.xml)." },
+
{ VERB_UPDATE, OBJECT_ADB,
"Updates adb to support the USB devices declared in the SDK add-ons." },
};
VERB_CREATE, OBJECT_PROJECT, "n", KEY_NAME,
"Project name", null);
+ // --- create test-project ---
+ define(Mode.STRING, true,
+ VERB_CREATE, OBJECT_TEST_PROJECT,
+ "p", KEY_PATH,
+ "Location path of new project", null);
+ define(Mode.STRING, false,
+ VERB_CREATE, OBJECT_TEST_PROJECT, "n", KEY_NAME,
+ "Project name", null);
+ define(Mode.STRING, true,
+ VERB_CREATE, OBJECT_TEST_PROJECT, "m", KEY_MAIN_PROJECT,
+ "Location path of the project to test, relative to the new project", null);
+
// --- update project ---
define(Mode.STRING, true,
VERB_UPDATE, OBJECT_PROJECT,
"s", KEY_SUBPROJECTS,
"Also update any projects in sub-folders, such as test projects.", false);
+
+ // --- update test project ---
+
+ define(Mode.STRING, true,
+ VERB_UPDATE, OBJECT_TEST_PROJECT,
+ "p", KEY_PATH,
+ "Location path of the project", null);
+ define(Mode.STRING, true,
+ VERB_UPDATE, OBJECT_TEST_PROJECT,
+ "m", KEY_MAIN_PROJECT,
+ "Location path of the project to test", null);
}
@Override
public boolean getParamSubProject() {
return ((Boolean) getValue(null, OBJECT_PROJECT, KEY_SUBPROJECTS)).booleanValue();
}
+
+ // -- some helpers for test-project action flags
+
+ /** Helper to retrieve the --main value. */
+ public String getParamTestProjectMain() {
+ return ((String) getValue(null, OBJECT_TEST_PROJECT, KEY_MAIN_PROJECT));
+ }
}
public final static String FN_PLUGIN_PROP = "plugin.prop";
/** add-on manifest file */
public final static String FN_MANIFEST_INI = "manifest.ini";
+ /** add-on layout device XML file. */
+ public final static String FN_DEVICES_XML = "devices.xml";
/** hardware properties definition file */
public final static String FN_HARDWARE_INI = "hardware-properties.ini";
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
+import com.android.sdklib.xml.AndroidManifest;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.xpath.XPathFactory;
/**
- * Creates the basic files needed to get an Android project up and running. Also
- * allows creation of IntelliJ project files.
+ * Creates the basic files needed to get an Android project up and running.
*
* @hide
*/
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". */
+ /** 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}. */
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";
- private final static String FOLDER_TESTS = "tests";
-
/** 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_]+");
* {@link #RE_PROJECT_NAME} regex.
* @param packageName the package of the project. The name must match the
* {@link #RE_PACKAGE_NAME} regex.
- * @param activityName the activity of the project as it will appear in the manifest. Can be
+ * @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 isTestProject whether the project to create is a test project. Caller should
- * initially call this will false. The method will call itself back to create
- * a test project as needed.
+ * @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 activityName, IAndroidTarget target,
- boolean isTestProject) {
+ String packageName, String activityEntry, IAndroidTarget target,
+ String pathToMainProject) {
// create project folder if it does not exist
File projectFolder = new File(folderPath);
}
try {
+ boolean isTestProject = pathToMainProject != null;
+
// first create the project properties.
// location of the SDK goes in localProperty
// create a build.properties file with just the application package
ProjectProperties buildProperties = ProjectProperties.create(folderPath,
PropertyType.BUILD);
- buildProperties.setProperty(ProjectProperties.PROPERTY_APP_PACKAGE, packageName);
- if (isTestProject == true) {
- buildProperties.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, "..");
+
+ // only put application.package for older target where the rules file didn't.
+ // grab it through xpath
+ if (target.getVersion().getApiLevel() < 4) {
+ buildProperties.setProperty(ProjectProperties.PROPERTY_APP_PACKAGE, packageName);
+ }
+
+ if (isTestProject) {
+ buildProperties.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT,
+ pathToMainProject);
}
buildProperties.save();
// 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);
- if (activityName != null) {
- keywords.put(PH_ACTIVITY_NAME, activityName);
+
+
+ // 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 (activityName != null) {
- // Use the activity as project name
- keywords.put(PH_PROJECT_NAME, activityName);
+ 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.
}
}
- // create the source folder and the java package folders.
- String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
- File sourceFolder = createDirs(projectFolder, srcFolderPath);
- String javaTemplate = "java_file.template";
- String activityFileName = activityName + ".java";
- if (isTestProject) {
- javaTemplate = "java_tests_file.template";
- activityFileName = activityName + "Test.java";
- }
- installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
- keywords, target);
+ // create the source folder for the activity
+ if (activityClassName != null) {
+ String srcActivityFolderPath = SdkConstants.FD_SOURCES + File.separator + activityPath;
+ File sourceFolder = createDirs(projectFolder, srcActivityFolderPath);
- // create the generate source folder
- srcFolderPath = SdkConstants.FD_GEN_SOURCES + File.separator + packagePath;
- sourceFolder = createDirs(projectFolder, srcFolderPath);
+ String javaTemplate = isTestProject ? "java_tests_file.template"
+ : "java_file.template";
+ String activityFileName = activityClassName + ".java";
+
+ installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
+ keywords, target);
+ } else {
+ // we should at least create 'src'
+ createDirs(projectFolder, SdkConstants.FD_SOURCES);
+ }
// create other useful folders
File resourceFodler = createDirs(projectFolder, SdkConstants.FD_RESOURCES);
installTemplate("build.template",
new File(projectFolder, SdkConstants.FN_BUILD_XML),
keywords);
-
- // if this is not a test project, then we create one.
- if (isTestProject == false) {
- // create the test project folder.
- createDirs(projectFolder, FOLDER_TESTS);
- File testProjectFolder = new File(folderPath, FOLDER_TESTS);
-
- createProject(testProjectFolder.getAbsolutePath(), projectName, packageName,
- activityName, target, true /*isTestProject*/);
- }
} catch (ProjectCreateException e) {
mLog.error(e, null);
} catch (IOException e) {
writer.write(comment);
}
String value = entry.getValue();
- value = value.replaceAll("\\\\", "\\\\\\\\");
- writer.write(String.format("%s=%s\n", entry.getKey(), value));
+ if (value != null) {
+ value = value.replaceAll("\\\\", "\\\\\\\\");
+ writer.write(String.format("%s=%s\n", entry.getKey(), value));
+ }
}
// close the file to flush
package com.android.sdklib.xml;
/**
- * Constants for nodes and attributes of the AndroidManifest.xml file.
+ * Helper and Constants for the AndroidManifest.xml file.
*
*/
-public final class ManifestConstants {
+public final class AndroidManifest {
public final static String NODE_MANIFEST = "manifest"; //$NON-NLS-1$
public final static String NODE_APPLICATION = "application"; //$NON-NLS-1$
public final static String ATTRIBUTE_MIN_SDK_VERSION = "minSdkVersion"; //$NON-NLS-$
public final static String ATTRIBUTE_TARGET_PACKAGE = "targetPackage"; //$NON-NLS-1$
public final static String ATTRIBUTE_EXPORTED = "exported"; //$NON-NLS-1$
+
+
+ /**
+ * Combines a java package, with a class value from the manifest to make a fully qualified
+ * class name
+ * @param javaPackage the java package from the manifest.
+ * @param className the class name from the manifest.
+ * @return the fully qualified class name.
+ */
+ public static String combinePackageAndClassName(String javaPackage, String className) {
+ if (className == null || className.length() == 0) {
+ return javaPackage;
+ }
+ if (javaPackage == null || javaPackage.length() == 0) {
+ return className;
+ }
+
+ // the class name can be a subpackage (starts with a '.'
+ // char), a simple class name (no dot), or a full java package
+ boolean startWithDot = (className.charAt(0) == '.');
+ boolean hasDot = (className.indexOf('.') != -1);
+ if (startWithDot || hasDot == false) {
+
+ // add the concatenation of the package and class name
+ if (startWithDot) {
+ return javaPackage + className;
+ } else {
+ return javaPackage + '.' + className;
+ }
+ } else {
+ // just add the class as it should be a fully qualified java name.
+ return className;
+ }
+ }
+
}
import com.android.sdklib.SdkConstants;
+import java.util.ArrayList;
import java.util.Iterator;
+import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
private final static AndroidNamespaceContext sThis = new AndroidNamespaceContext(
DEFAULT_NS_PREFIX);
- private String mAndroidPrefix;
+ private final String mAndroidPrefix;
+ private final List<String> mAndroidPrefixes = new ArrayList<String>();
/**
* Returns the default {@link AndroidNamespaceContext}.
*/
public AndroidNamespaceContext(String androidPrefix) {
mAndroidPrefix = androidPrefix;
+ mAndroidPrefixes.add(mAndroidPrefix);
}
public String getNamespaceURI(String prefix) {
}
public String getPrefix(String namespaceURI) {
- // This isn't necessary for our use.
- assert false;
+ if (SdkConstants.NS_RESOURCES.equals(namespaceURI)) {
+ return mAndroidPrefix;
+ }
+
return null;
}
public Iterator<?> getPrefixes(String namespaceURI) {
- // This isn't necessary for our use.
- assert false;
+ if (SdkConstants.NS_RESOURCES.equals(namespaceURI)) {
+ return mAndroidPrefixes.iterator();
+ }
+
return null;
}
}