auto import from //branches/cupcake/...@137873
This commit is contained in:
7
emulator/keymaps/AVRCP.kl
Normal file
7
emulator/keymaps/AVRCP.kl
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
key 164 PLAYPAUSE WAKE
|
||||||
|
key 128 STOP WAKE
|
||||||
|
key 163 NEXTSONG WAKE
|
||||||
|
key 165 PREVIOUSSONG WAKE
|
||||||
|
key 168 REWIND WAKE
|
||||||
|
key 159 FORWARD WAKE
|
||||||
|
|
||||||
@@ -11,3 +11,8 @@ file := $(TARGET_OUT_KEYLAYOUT)/qwerty.kl
|
|||||||
ALL_PREBUILT += $(file)
|
ALL_PREBUILT += $(file)
|
||||||
$(file): $(LOCAL_PATH)/qwerty.kl | $(ACP)
|
$(file): $(LOCAL_PATH)/qwerty.kl | $(ACP)
|
||||||
$(transform-prebuilt-to-target)
|
$(transform-prebuilt-to-target)
|
||||||
|
|
||||||
|
file := $(TARGET_OUT_KEYLAYOUT)/AVRCP.kl
|
||||||
|
ALL_PREBUILT += $(file)
|
||||||
|
$(file) : $(LOCAL_PATH)/AVRCP.kl | $(ACP)
|
||||||
|
$(transform-prebuilt-to-target)
|
||||||
|
|||||||
Binary file not shown.
@@ -1653,18 +1653,18 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<!-- ************************************* -->
|
<!-- ************************************* -->
|
||||||
<!-- GADGET PACKAGE SAMPLES -->
|
<!-- APPWIDGET PACKAGE SAMPLES -->
|
||||||
<!-- ************************************* -->
|
<!-- ************************************* -->
|
||||||
|
|
||||||
<receiver android:name=".gadget.ExampleGadgetProvider">
|
<receiver android:name=".appwidget.ExampleAppWidgetProvider">
|
||||||
<meta-data android:name="android.gadget.provider"
|
<meta-data android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/gadget_provider" />
|
android:resource="@xml/appwidget_provider" />
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.gadget.action.GADGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver android:name=".gadget.ExampleBroadcastReceiver" android:enabled="false">
|
<receiver android:name=".appwidget.ExampleBroadcastReceiver" android:enabled="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.ACTION_TIMEZONE_CHANGED" />
|
<action android:name="android.intent.ACTION_TIMEZONE_CHANGED" />
|
||||||
<action android:name="android.intent.ACTION_TIME" />
|
<action android:name="android.intent.ACTION_TIME" />
|
||||||
|
|||||||
@@ -23,11 +23,11 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/gadget_configure_instructions"
|
android:text="@string/appwidget_configure_instructions"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/gadget_prefix"
|
android:id="@+id/appwidget_prefix"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
/>
|
/>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/gadget_text"
|
android:id="@+id/appwidget_text"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="#ff000000"
|
android:textColor="#ff000000"
|
||||||
@@ -814,11 +814,11 @@
|
|||||||
<string name="listSeparatorTextViewStyle">listSeparatorTextViewStyle</string>
|
<string name="listSeparatorTextViewStyle">listSeparatorTextViewStyle</string>
|
||||||
|
|
||||||
<!-- ============================ -->
|
<!-- ============================ -->
|
||||||
<!-- gadget examples strings -->
|
<!-- AppWidget examples strings -->
|
||||||
<!-- ============================ -->
|
<!-- ============================ -->
|
||||||
|
|
||||||
<string name="gadget_configure_instructions">This text will be shown before the date in our example gadget.</string>
|
<string name="appwidget_configure_instructions">This text will be shown before the date in our example widget.</string>
|
||||||
<string name="gadget_prefix_default">Oh hai</string>
|
<string name="appwidget_prefix_default">Oh hai</string>
|
||||||
<string name="gadget_text_format"><xliff:g id="prefix">%1$s</xliff:g>: <xliff:g id="time">%2$s</xliff:g></string>
|
<string name="appwidget_text_format"><xliff:g id="prefix">%1$s</xliff:g>: <xliff:g id="time">%2$s</xliff:g></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,14 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<gadget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:minWidth="60dp"
|
android:minWidth="60dp"
|
||||||
android:minHeight="30dp"
|
android:minHeight="30dp"
|
||||||
android:updatePeriodMillis="86400000"
|
android:updatePeriodMillis="86400000"
|
||||||
android:initialLayout="@layout/gadget_provider"
|
android:initialLayout="@layout/appwidget_provider"
|
||||||
android:configure="com.example.android.apis.gadget.ExampleGadgetConfigure"
|
android:configure="com.example.android.apis.appwidget.ExampleAppWidgetConfigure"
|
||||||
>
|
>
|
||||||
</gadget-provider>
|
</appwidget-provider>
|
||||||
|
|
||||||
<!-- 86400000 is the value of AlarmManager.INTERVAL_DAY - or once per day. -->
|
<!-- 86400000 is the value of AlarmManager.INTERVAL_DAY - or once per day. -->
|
||||||
|
|
||||||
@@ -14,13 +14,13 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.example.android.apis.gadget;
|
package com.example.android.apis.appwidget;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.gadget.GadgetManager;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -33,19 +33,19 @@ import java.util.ArrayList;
|
|||||||
import com.example.android.apis.R;
|
import com.example.android.apis.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The configuration screen for the ExampleGadgetProvider gadget sample.
|
* The configuration screen for the ExampleAppWidgetProvider widget sample.
|
||||||
*/
|
*/
|
||||||
public class ExampleGadgetConfigure extends Activity {
|
public class ExampleAppWidgetConfigure extends Activity {
|
||||||
static final String TAG = "ExampleGadgetConfigure";
|
static final String TAG = "ExampleAppWidgetConfigure";
|
||||||
|
|
||||||
private static final String PREFS_NAME
|
private static final String PREFS_NAME
|
||||||
= "com.example.android.apis.gadget.ExampleGadgetProvider";
|
= "com.example.android.apis.appwidget.ExampleAppWidgetProvider";
|
||||||
private static final String PREF_PREFIX_KEY = "prefix_";
|
private static final String PREF_PREFIX_KEY = "prefix_";
|
||||||
|
|
||||||
int mGadgetId = GadgetManager.INVALID_GADGET_ID;
|
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
|
||||||
EditText mGadgetPrefix;
|
EditText mAppWidgetPrefix;
|
||||||
|
|
||||||
public ExampleGadgetConfigure() {
|
public ExampleAppWidgetConfigure() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,70 +53,70 @@ public class ExampleGadgetConfigure extends Activity {
|
|||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
|
|
||||||
// Set the result to CANCELED. This will cause the gadget host to cancel
|
// Set the result to CANCELED. This will cause the widget host to cancel
|
||||||
// out of the gadget placement if they press the back button.
|
// out of the widget placement if they press the back button.
|
||||||
setResult(RESULT_CANCELED);
|
setResult(RESULT_CANCELED);
|
||||||
|
|
||||||
// Set the view layout resource to use.
|
// Set the view layout resource to use.
|
||||||
setContentView(R.layout.gadget_configure);
|
setContentView(R.layout.appwidget_configure);
|
||||||
|
|
||||||
// Find the EditText
|
// Find the EditText
|
||||||
mGadgetPrefix = (EditText)findViewById(R.id.gadget_prefix);
|
mAppWidgetPrefix = (EditText)findViewById(R.id.appwidget_prefix);
|
||||||
|
|
||||||
// Bind the action for the save button.
|
// Bind the action for the save button.
|
||||||
findViewById(R.id.save_button).setOnClickListener(mOnClickListener);
|
findViewById(R.id.save_button).setOnClickListener(mOnClickListener);
|
||||||
|
|
||||||
// Find the gadget id from the intent.
|
// Find the widget id from the intent.
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
if (extras != null) {
|
if (extras != null) {
|
||||||
mGadgetId = extras.getInt(
|
mAppWidgetId = extras.getInt(
|
||||||
GadgetManager.EXTRA_GADGET_ID, GadgetManager.INVALID_GADGET_ID);
|
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If they gave us an intent without the gadget id, just bail.
|
// If they gave us an intent without the widget id, just bail.
|
||||||
if (mGadgetId == GadgetManager.INVALID_GADGET_ID) {
|
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
mGadgetPrefix.setText(loadTitlePref(ExampleGadgetConfigure.this, mGadgetId));
|
mAppWidgetPrefix.setText(loadTitlePref(ExampleAppWidgetConfigure.this, mAppWidgetId));
|
||||||
}
|
}
|
||||||
|
|
||||||
View.OnClickListener mOnClickListener = new View.OnClickListener() {
|
View.OnClickListener mOnClickListener = new View.OnClickListener() {
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// When the button is clicked, save the string in our prefs and return that they
|
// When the button is clicked, save the string in our prefs and return that they
|
||||||
// clicked OK.
|
// clicked OK.
|
||||||
saveTitlePref(ExampleGadgetConfigure.this, mGadgetId,
|
saveTitlePref(ExampleAppWidgetConfigure.this, mAppWidgetId,
|
||||||
mGadgetPrefix.getText().toString());
|
mAppWidgetPrefix.getText().toString());
|
||||||
|
|
||||||
setResult(RESULT_OK);
|
setResult(RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write the prefix to the SharedPreferences object for this gadget
|
// Write the prefix to the SharedPreferences object for this widget
|
||||||
static void saveTitlePref(Context context, int gadgetId, String text) {
|
static void saveTitlePref(Context context, int appWidgetId, String text) {
|
||||||
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
|
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
|
||||||
prefs.putString(PREF_PREFIX_KEY + gadgetId, text);
|
prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);
|
||||||
prefs.commit();
|
prefs.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the prefix from the SharedPreferences object for this gadget.
|
// Read the prefix from the SharedPreferences object for this widget.
|
||||||
// If there is no preference saved, get the default from a resource
|
// If there is no preference saved, get the default from a resource
|
||||||
static String loadTitlePref(Context context, int gadgetId) {
|
static String loadTitlePref(Context context, int appWidgetId) {
|
||||||
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
|
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
|
||||||
String prefix = prefs.getString(PREF_PREFIX_KEY, null);
|
String prefix = prefs.getString(PREF_PREFIX_KEY, null);
|
||||||
if (prefix != null) {
|
if (prefix != null) {
|
||||||
return prefix;
|
return prefix;
|
||||||
} else {
|
} else {
|
||||||
return context.getString(R.string.gadget_prefix_default);
|
return context.getString(R.string.appwidget_prefix_default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deleteTitlePref(Context context, int gadgetId) {
|
static void deleteTitlePref(Context context, int appWidgetId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadAllTitlePrefs(Context context, ArrayList<Integer> gadgetIds,
|
static void loadAllTitlePrefs(Context context, ArrayList<Integer> appWidgetIds,
|
||||||
ArrayList<String> texts) {
|
ArrayList<String> texts) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,14 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.example.android.apis.gadget;
|
package com.example.android.apis.appwidget;
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.appwidget.AppWidgetProvider;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.gadget.GadgetManager;
|
|
||||||
import android.gadget.GadgetProvider;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
@@ -33,89 +33,89 @@ import java.util.ArrayList;
|
|||||||
import com.example.android.apis.R;
|
import com.example.android.apis.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A gadget provider. We have a string that we pull from a preference in order to show
|
* A widget provider. We have a string that we pull from a preference in order to show
|
||||||
* the configuration settings and the current time when the gadget was updated. We also
|
* the configuration settings and the current time when the widget was updated. We also
|
||||||
* register a BroadcastReceiver for time-changed and timezone-changed broadcasts, and
|
* register a BroadcastReceiver for time-changed and timezone-changed broadcasts, and
|
||||||
* update then too.
|
* update then too.
|
||||||
*
|
*
|
||||||
* <p>See also the following files:
|
* <p>See also the following files:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>ExampleGadgetConfigure.java</li>
|
* <li>ExampleAppWidgetConfigure.java</li>
|
||||||
* <li>ExampleBroadcastReceiver.java</li>
|
* <li>ExampleBroadcastReceiver.java</li>
|
||||||
* <li>res/layout/gadget_configure.xml</li>
|
* <li>res/layout/appwidget_configure.xml</li>
|
||||||
* <li>res/layout/gadget_provider.xml</li>
|
* <li>res/layout/appwidget_provider.xml</li>
|
||||||
* <li>res/xml/gadget_provider.xml</li>
|
* <li>res/xml/appwidget_provider.xml</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public class ExampleGadgetProvider extends GadgetProvider {
|
public class ExampleAppWidgetProvider extends AppWidgetProvider {
|
||||||
// log tag
|
// log tag
|
||||||
private static final String TAG = "ExampleGadgetProvider";
|
private static final String TAG = "ExampleAppWidgetProvider";
|
||||||
|
|
||||||
public void onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds) {
|
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
|
||||||
Log.d(TAG, "onUpdate");
|
Log.d(TAG, "onUpdate");
|
||||||
// For each gadget that needs an update, get the text that we should display:
|
// For each widget that needs an update, get the text that we should display:
|
||||||
// - Create a RemoteViews object for it
|
// - Create a RemoteViews object for it
|
||||||
// - Set the text in the RemoteViews object
|
// - Set the text in the RemoteViews object
|
||||||
// - Tell the GadgetManager to show that views object for the gadget.
|
// - Tell the AppWidgetManager to show that views object for the widget.
|
||||||
final int N = gadgetIds.length;
|
final int N = appWidgetIds.length;
|
||||||
for (int i=0; i<N; i++) {
|
for (int i=0; i<N; i++) {
|
||||||
int gadgetId = gadgetIds[i];
|
int appWidgetId = appWidgetIds[i];
|
||||||
String titlePrefix = ExampleGadgetConfigure.loadTitlePref(context, gadgetId);
|
String titlePrefix = ExampleAppWidgetConfigure.loadTitlePref(context, appWidgetId);
|
||||||
updateGadget(context, gadgetManager, gadgetId, titlePrefix);
|
updateAppWidget(context, appWidgetManager, appWidgetId, titlePrefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDeleted(Context context, int[] gadgetIds) {
|
public void onDeleted(Context context, int[] appWidgetIds) {
|
||||||
Log.d(TAG, "onDeleted");
|
Log.d(TAG, "onDeleted");
|
||||||
// When the user deletes the gadget, delete the preference associated with it.
|
// When the user deletes the widget, delete the preference associated with it.
|
||||||
final int N = gadgetIds.length;
|
final int N = appWidgetIds.length;
|
||||||
for (int i=0; i<N; i++) {
|
for (int i=0; i<N; i++) {
|
||||||
ExampleGadgetConfigure.deleteTitlePref(context, gadgetIds[i]);
|
ExampleAppWidgetConfigure.deleteTitlePref(context, appWidgetIds[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEnabled(Context context) {
|
public void onEnabled(Context context) {
|
||||||
Log.d(TAG, "onEnabled");
|
Log.d(TAG, "onEnabled");
|
||||||
// When the first gadget is created, register for the TIMEZONE_CHANGED and TIME_CHANGED
|
// When the first widget is created, register for the TIMEZONE_CHANGED and TIME_CHANGED
|
||||||
// broadcasts. We don't want to be listening for these if nobody has our gadget active.
|
// broadcasts. We don't want to be listening for these if nobody has our widget active.
|
||||||
// This setting is sticky across reboots, but that doesn't matter, because this will
|
// This setting is sticky across reboots, but that doesn't matter, because this will
|
||||||
// be called after boot if there is a gadget instance for this provider.
|
// be called after boot if there is a widget instance for this provider.
|
||||||
PackageManager pm = context.getPackageManager();
|
PackageManager pm = context.getPackageManager();
|
||||||
pm.setComponentEnabledSetting(
|
pm.setComponentEnabledSetting(
|
||||||
new ComponentName("com.example.android.apis", ".gadget.ExampleBroadcastReceiver"),
|
new ComponentName("com.example.android.apis", ".appwidget.ExampleBroadcastReceiver"),
|
||||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||||
PackageManager.DONT_KILL_APP);
|
PackageManager.DONT_KILL_APP);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDisabled(Context context) {
|
public void onDisabled(Context context) {
|
||||||
// When the first gadget is created, stop listening for the TIMEZONE_CHANGED and
|
// When the first widget is created, stop listening for the TIMEZONE_CHANGED and
|
||||||
// TIME_CHANGED broadcasts.
|
// TIME_CHANGED broadcasts.
|
||||||
Log.d(TAG, "onDisabled");
|
Log.d(TAG, "onDisabled");
|
||||||
Class clazz = ExampleBroadcastReceiver.class;
|
Class clazz = ExampleBroadcastReceiver.class;
|
||||||
PackageManager pm = context.getPackageManager();
|
PackageManager pm = context.getPackageManager();
|
||||||
pm.setComponentEnabledSetting(
|
pm.setComponentEnabledSetting(
|
||||||
new ComponentName("com.example.android.apis", ".gadget.ExampleBroadcastReceiver"),
|
new ComponentName("com.example.android.apis", ".appwidget.ExampleBroadcastReceiver"),
|
||||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||||
PackageManager.DONT_KILL_APP);
|
PackageManager.DONT_KILL_APP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateGadget(Context context, GadgetManager gadgetManager,
|
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
|
||||||
int gadgetId, String titlePrefix) {
|
int appWidgetId, String titlePrefix) {
|
||||||
Log.d(TAG, "updateGadget gadgetId=" + gadgetId + " titlePrefix=" + titlePrefix);
|
Log.d(TAG, "updateAppWidget appWidgetId=" + appWidgetId + " titlePrefix=" + titlePrefix);
|
||||||
// Getting the string this way allows the string to be localized. The format
|
// Getting the string this way allows the string to be localized. The format
|
||||||
// string is filled in using java.util.Formatter-style format strings.
|
// string is filled in using java.util.Formatter-style format strings.
|
||||||
CharSequence text = context.getString(R.string.gadget_text_format,
|
CharSequence text = context.getString(R.string.appwidget_text_format,
|
||||||
ExampleGadgetConfigure.loadTitlePref(context, gadgetId),
|
ExampleAppWidgetConfigure.loadTitlePref(context, appWidgetId),
|
||||||
"0x" + Long.toHexString(SystemClock.elapsedRealtime()));
|
"0x" + Long.toHexString(SystemClock.elapsedRealtime()));
|
||||||
|
|
||||||
// Construct the RemoteViews object. It takes the package name (in our case, it's our
|
// Construct the RemoteViews object. It takes the package name (in our case, it's our
|
||||||
// package, but it needs this because on the other side it's the gadget host inflating
|
// package, but it needs this because on the other side it's the widget host inflating
|
||||||
// the layout from our package).
|
// the layout from our package).
|
||||||
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.gadget_provider);
|
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider);
|
||||||
views.setTextViewText(R.id.gadget_text, text);
|
views.setTextViewText(R.id.appwidget_text, text);
|
||||||
|
|
||||||
// Tell the gadget manager
|
// Tell the widget manager
|
||||||
gadgetManager.updateGadget(gadgetId, views);
|
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,14 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.example.android.apis.gadget;
|
package com.example.android.apis.appwidget;
|
||||||
|
|
||||||
|
import android.appwidget.AppWidgetManager;
|
||||||
|
import android.appwidget.AppWidgetProvider;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.gadget.GadgetManager;
|
|
||||||
import android.gadget.GadgetProvider;
|
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
@@ -33,8 +33,8 @@ import java.util.ArrayList;
|
|||||||
import com.example.android.apis.R;
|
import com.example.android.apis.R;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A BroadcastReceiver that listens for updates for the ExampleGadgetProvider. This
|
* A BroadcastReceiver that listens for updates for the ExampleAppWidgetProvider. This
|
||||||
* BroadcastReceiver starts off disabled, and we only enable it when there is a gadget
|
* BroadcastReceiver starts off disabled, and we only enable it when there is a widget
|
||||||
* instance created, in order to only receive notifications when we need them.
|
* instance created, in order to only receive notifications when we need them.
|
||||||
*/
|
*/
|
||||||
public class ExampleBroadcastReceiver extends BroadcastReceiver {
|
public class ExampleBroadcastReceiver extends BroadcastReceiver {
|
||||||
@@ -42,20 +42,20 @@ public class ExampleBroadcastReceiver extends BroadcastReceiver {
|
|||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
Log.d("ExmampleBroadcastReceiver", "intent=" + intent);
|
Log.d("ExmampleBroadcastReceiver", "intent=" + intent);
|
||||||
|
|
||||||
// For our example, we'll also update all of the gadgets when the timezone
|
// For our example, we'll also update all of the widgets when the timezone
|
||||||
// changes, or the user or network sets the time.
|
// changes, or the user or network sets the time.
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)
|
if (action.equals(Intent.ACTION_TIMEZONE_CHANGED)
|
||||||
|| action.equals(Intent.ACTION_TIME_CHANGED)) {
|
|| action.equals(Intent.ACTION_TIME_CHANGED)) {
|
||||||
GadgetManager gm = GadgetManager.getInstance(context);
|
AppWidgetManager gm = AppWidgetManager.getInstance(context);
|
||||||
ArrayList<Integer> gadgetIds = new ArrayList();
|
ArrayList<Integer> appWidgetIds = new ArrayList();
|
||||||
ArrayList<String> texts = new ArrayList();
|
ArrayList<String> texts = new ArrayList();
|
||||||
|
|
||||||
ExampleGadgetConfigure.loadAllTitlePrefs(context, gadgetIds, texts);
|
ExampleAppWidgetConfigure.loadAllTitlePrefs(context, appWidgetIds, texts);
|
||||||
|
|
||||||
final int N = gadgetIds.size();
|
final int N = appWidgetIds.size();
|
||||||
for (int i=0; i<N; i++) {
|
for (int i=0; i<N; i++) {
|
||||||
ExampleGadgetProvider.updateGadget(context, gm, gadgetIds.get(i), texts.get(i));
|
ExampleAppWidgetProvider.updateAppWidget(context, gm, appWidgetIds.get(i), texts.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -473,15 +473,6 @@
|
|||||||
id="adt.actionSet1"
|
id="adt.actionSet1"
|
||||||
label="Android Wizards"
|
label="Android Wizards"
|
||||||
visible="true">
|
visible="true">
|
||||||
<action
|
|
||||||
class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
|
|
||||||
icon="icons/new_adt_project.png"
|
|
||||||
id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
|
|
||||||
label="New Android Project"
|
|
||||||
style="push"
|
|
||||||
toolbarPath="android_project"
|
|
||||||
tooltip="Opens a wizard to help create a new Android project">
|
|
||||||
</action>
|
|
||||||
<action
|
<action
|
||||||
class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
|
class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
|
||||||
icon="icons/new_xml.png"
|
icon="icons/new_xml.png"
|
||||||
@@ -491,6 +482,15 @@
|
|||||||
toolbarPath="android_project"
|
toolbarPath="android_project"
|
||||||
tooltip="Opens a wizard to help create a new Android XML file">
|
tooltip="Opens a wizard to help create a new Android XML file">
|
||||||
</action>
|
</action>
|
||||||
|
<action
|
||||||
|
class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
|
||||||
|
icon="icons/new_adt_project.png"
|
||||||
|
id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
|
||||||
|
label="New Android Project"
|
||||||
|
style="push"
|
||||||
|
toolbarPath="android_project"
|
||||||
|
tooltip="Opens a wizard to help create a new Android project">
|
||||||
|
</action>
|
||||||
</actionSet>
|
</actionSet>
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
<extension
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import com.android.ide.eclipse.adt.AdtPlugin;
|
|||||||
import com.android.ide.eclipse.adt.project.FixLaunchConfig;
|
import com.android.ide.eclipse.adt.project.FixLaunchConfig;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
|
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
import com.android.ide.eclipse.common.project.BaseProjectHelper;
|
import com.android.ide.eclipse.common.project.BaseProjectHelper;
|
||||||
import com.android.ide.eclipse.common.project.XmlErrorHandler.BasicXmlErrorListener;
|
import com.android.ide.eclipse.common.project.XmlErrorHandler.BasicXmlErrorListener;
|
||||||
@@ -272,7 +271,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
|||||||
|
|
||||||
|
|
||||||
// get the manifest file
|
// get the manifest file
|
||||||
IFile manifest = AndroidManifestHelper.getManifest(project);
|
IFile manifest = AndroidManifestParser.getManifest(project);
|
||||||
|
|
||||||
if (manifest == null) {
|
if (manifest == null) {
|
||||||
String msg = String.format(Messages.s_File_Missing,
|
String msg = String.format(Messages.s_File_Missing,
|
||||||
@@ -743,7 +742,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
|||||||
// create it if needed
|
// create it if needed
|
||||||
if (destinationFolder.exists() == false && createFolders) {
|
if (destinationFolder.exists() == false && createFolders) {
|
||||||
destinationFolder.create(true /*force*/, true /*local*/,
|
destinationFolder.create(true /*force*/, true /*local*/,
|
||||||
new SubProgressMonitor(monitor, 10));;
|
new SubProgressMonitor(monitor, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the Java file name from the aidl name.
|
// Build the Java file name from the aidl name.
|
||||||
@@ -824,7 +823,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
|||||||
/**
|
/**
|
||||||
* Scans a folder and fills the list of aidl files to compile.
|
* Scans a folder and fills the list of aidl files to compile.
|
||||||
* @param sourceFolder the root source folder.
|
* @param sourceFolder the root source folder.
|
||||||
* @param container The folder to scan.
|
* @param folder The folder to scan.
|
||||||
*/
|
*/
|
||||||
private void scanFolderForAidl(IFolder sourceFolder, IFolder folder) {
|
private void scanFolderForAidl(IFolder sourceFolder, IFolder folder) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ public class ResourceManagerBuilder extends BaseBuilder {
|
|||||||
"Creating 'gen' source folder for generated Java files");
|
"Creating 'gen' source folder for generated Java files");
|
||||||
genFolder.create(true /* force */, true /* local */,
|
genFolder.create(true /* force */, true /* local */,
|
||||||
new SubProgressMonitor(monitor, 10));
|
new SubProgressMonitor(monitor, 10));
|
||||||
|
genFolder.setDerived(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add it to the source folder list, if needed only (or it will throw)
|
// add it to the source folder list, if needed only (or it will throw)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.android.ide.eclipse.adt.AdtPlugin;
|
|||||||
import com.android.ide.eclipse.adt.launch.DeviceChooserDialog.DeviceChooserResponse;
|
import com.android.ide.eclipse.adt.launch.DeviceChooserDialog.DeviceChooserResponse;
|
||||||
import com.android.ide.eclipse.adt.project.ProjectHelper;
|
import com.android.ide.eclipse.adt.project.ProjectHelper;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
import com.android.sdklib.IAndroidTarget;
|
import com.android.sdklib.IAndroidTarget;
|
||||||
import com.android.sdklib.SdkManager;
|
import com.android.sdklib.SdkManager;
|
||||||
import com.android.sdklib.avd.AvdManager;
|
import com.android.sdklib.avd.AvdManager;
|
||||||
@@ -584,8 +584,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener
|
|||||||
ArrayList<IResource> array = new ArrayList<IResource>(2);
|
ArrayList<IResource> array = new ArrayList<IResource>(2);
|
||||||
array.add(project);
|
array.add(project);
|
||||||
|
|
||||||
AndroidManifestHelper helper = new AndroidManifestHelper(project);
|
IFile manifest = AndroidManifestParser.getManifest(project);
|
||||||
IFile manifest = helper.getManifestIFile();
|
|
||||||
if (manifest != null) {
|
if (manifest != null) {
|
||||||
array.add(manifest);
|
array.add(manifest);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,12 +36,8 @@ import com.android.sdkuilib.AvdSelector;
|
|||||||
import org.eclipse.jface.dialogs.Dialog;
|
import org.eclipse.jface.dialogs.Dialog;
|
||||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||||
import org.eclipse.jface.preference.IPreferenceStore;
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
import org.eclipse.jface.viewers.DoubleClickEvent;
|
|
||||||
import org.eclipse.jface.viewers.IDoubleClickListener;
|
|
||||||
import org.eclipse.jface.viewers.ILabelProviderListener;
|
import org.eclipse.jface.viewers.ILabelProviderListener;
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
|
||||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
|
||||||
import org.eclipse.jface.viewers.ITableLabelProvider;
|
import org.eclipse.jface.viewers.ITableLabelProvider;
|
||||||
import org.eclipse.jface.viewers.StructuredSelection;
|
import org.eclipse.jface.viewers.StructuredSelection;
|
||||||
import org.eclipse.jface.viewers.TableViewer;
|
import org.eclipse.jface.viewers.TableViewer;
|
||||||
@@ -62,6 +58,12 @@ import org.eclipse.swt.widgets.Table;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A dialog that lets the user choose a device to deploy an application.
|
||||||
|
* The user can either choose an exiting running device (including running emulators)
|
||||||
|
* or start a new emulator using an Android Virtual Device configuration that matches
|
||||||
|
* the current project.
|
||||||
|
*/
|
||||||
public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener {
|
public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener {
|
||||||
|
|
||||||
private final static int ICON_WIDTH = 16;
|
private final static int ICON_WIDTH = 16;
|
||||||
@@ -373,15 +375,27 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
|
|||||||
mViewer.setContentProvider(new ContentProvider());
|
mViewer.setContentProvider(new ContentProvider());
|
||||||
mViewer.setLabelProvider(new LabelProvider());
|
mViewer.setLabelProvider(new LabelProvider());
|
||||||
mViewer.setInput(AndroidDebugBridge.getBridge());
|
mViewer.setInput(AndroidDebugBridge.getBridge());
|
||||||
mViewer.addDoubleClickListener(new IDoubleClickListener() {
|
|
||||||
public void doubleClick(DoubleClickEvent event) {
|
mDeviceTable.addSelectionListener(new SelectionAdapter() {
|
||||||
ISelection selection = event.getSelection();
|
/**
|
||||||
if (selection instanceof IStructuredSelection) {
|
* Handles single-click selection on the device selector.
|
||||||
IStructuredSelection structuredSelection = (IStructuredSelection)selection;
|
* {@inheritDoc}
|
||||||
Object object = structuredSelection.getFirstElement();
|
*/
|
||||||
if (object instanceof Device) {
|
@Override
|
||||||
mResponse.setDeviceToUse((Device)object);
|
public void widgetSelected(SelectionEvent e) {
|
||||||
}
|
handleDeviceSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles double-click selection on the device selector.
|
||||||
|
* Note that the single-click handler will probably already have been called.
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void widgetDefaultSelected(SelectionEvent e) {
|
||||||
|
handleDeviceSelection();
|
||||||
|
if (isOkButtonEnabled()) {
|
||||||
|
okPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -397,18 +411,14 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
|
|||||||
layout.marginLeft = 30;
|
layout.marginLeft = 30;
|
||||||
offsetComp.setLayout(layout);
|
offsetComp.setLayout(layout);
|
||||||
|
|
||||||
mPreferredAvdSelector = new AvdSelector(offsetComp, getNonRunningAvds(), mProjectTarget,
|
mPreferredAvdSelector = new AvdSelector(offsetComp, getNonRunningAvds(), mProjectTarget);
|
||||||
false /*allowMultipleSelection*/);
|
|
||||||
mPreferredAvdSelector.setTableHeightHint(100);
|
mPreferredAvdSelector.setTableHeightHint(100);
|
||||||
mPreferredAvdSelector.setEnabled(false);
|
mPreferredAvdSelector.setEnabled(false);
|
||||||
mDeviceTable.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
handleDeviceSelection();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
|
mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
|
||||||
|
/**
|
||||||
|
* Handles single-click selection on the AVD selector.
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
if (mDisableAvdSelectionChange == false) {
|
if (mDisableAvdSelectionChange == false) {
|
||||||
@@ -416,6 +426,22 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
|
|||||||
enableOkButton();
|
enableOkButton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles double-click selection on the AVD selector.
|
||||||
|
*
|
||||||
|
* Note that the single-click handler will probably already have been called
|
||||||
|
* but the selected item can have changed in between.
|
||||||
|
*
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void widgetDefaultSelected(SelectionEvent e) {
|
||||||
|
widgetSelected(e);
|
||||||
|
if (isOkButtonEnabled()) {
|
||||||
|
okPressed();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AndroidDebugBridge.addDeviceChangeListener(this);
|
AndroidDebugBridge.addDeviceChangeListener(this);
|
||||||
@@ -586,6 +612,14 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener
|
|||||||
okButton.setEnabled(mResponse.getAvdToLaunch() != null);
|
okButton.setEnabled(mResponse.getAvdToLaunch() != null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the ok button is enabled.
|
||||||
|
*/
|
||||||
|
private boolean isOkButtonEnabled() {
|
||||||
|
Button okButton = getButton(IDialogConstants.OK_ID);
|
||||||
|
return okButton.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the {@link Runnable} in the UI thread.
|
* Executes the {@link Runnable} in the UI thread.
|
||||||
|
|||||||
@@ -178,8 +178,7 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab {
|
|||||||
mPreferredAvdLabel = new Label(offsetComp, SWT.NONE);
|
mPreferredAvdLabel = new Label(offsetComp, SWT.NONE);
|
||||||
mPreferredAvdLabel.setText("Select a preferred Android Virtual Device:");
|
mPreferredAvdLabel.setText("Select a preferred Android Virtual Device:");
|
||||||
AvdInfo[] avds = new AvdInfo[0];
|
AvdInfo[] avds = new AvdInfo[0];
|
||||||
mPreferredAvdSelector = new AvdSelector(offsetComp, avds,
|
mPreferredAvdSelector = new AvdSelector(offsetComp, avds);
|
||||||
false /*allowMultipleSelection*/);
|
|
||||||
mPreferredAvdSelector.setTableHeightHint(100);
|
mPreferredAvdSelector.setTableHeightHint(100);
|
||||||
mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
|
mPreferredAvdSelector.setSelectionListener(new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -19,9 +19,9 @@ package com.android.ide.eclipse.adt.project;
|
|||||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||||
import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
|
import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
|
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IMarker;
|
import org.eclipse.core.resources.IMarker;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IProjectDescription;
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
@@ -389,18 +389,16 @@ public final class ProjectHelper {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidManifestHelper androidManifest = new AndroidManifestHelper(p);
|
|
||||||
|
|
||||||
// check that there is indeed a manifest file.
|
// check that there is indeed a manifest file.
|
||||||
if (androidManifest.getManifestIFile() == null) {
|
IFile manifestFile = AndroidManifestParser.getManifest(p);
|
||||||
|
if (manifestFile == null) {
|
||||||
// no file? skip this project.
|
// no file? skip this project.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidManifestParser parser = null;
|
AndroidManifestParser parser = null;
|
||||||
try {
|
try {
|
||||||
parser = AndroidManifestParser.parseForData(
|
parser = AndroidManifestParser.parseForData(manifestFile);
|
||||||
androidManifest.getManifestIFile());
|
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
// skip this project.
|
// skip this project.
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class AndroidTargetData {
|
|||||||
public final static int DESCRIPTOR_RESOURCES = 5;
|
public final static int DESCRIPTOR_RESOURCES = 5;
|
||||||
public final static int DESCRIPTOR_SEARCHABLE = 6;
|
public final static int DESCRIPTOR_SEARCHABLE = 6;
|
||||||
public final static int DESCRIPTOR_PREFERENCES = 7;
|
public final static int DESCRIPTOR_PREFERENCES = 7;
|
||||||
public final static int DESCRIPTOR_GADGET_PROVIDER = 8;
|
public final static int DESCRIPTOR_APPWIDGET_PROVIDER = 8;
|
||||||
|
|
||||||
public final static class LayoutBridge {
|
public final static class LayoutBridge {
|
||||||
/** Link to the layout bridge */
|
/** Link to the layout bridge */
|
||||||
@@ -158,8 +158,8 @@ public class AndroidTargetData {
|
|||||||
return ResourcesDescriptors.getInstance();
|
return ResourcesDescriptors.getInstance();
|
||||||
case DESCRIPTOR_PREFERENCES:
|
case DESCRIPTOR_PREFERENCES:
|
||||||
return mXmlDescriptors.getPreferencesProvider();
|
return mXmlDescriptors.getPreferencesProvider();
|
||||||
case DESCRIPTOR_GADGET_PROVIDER:
|
case DESCRIPTOR_APPWIDGET_PROVIDER:
|
||||||
return mXmlDescriptors.getGadgetProvider();
|
return mXmlDescriptors.getAppWidgetProvider();
|
||||||
case DESCRIPTOR_SEARCHABLE:
|
case DESCRIPTOR_SEARCHABLE:
|
||||||
return mXmlDescriptors.getSearchableProvider();
|
return mXmlDescriptors.getSearchableProvider();
|
||||||
default :
|
default :
|
||||||
|
|||||||
@@ -203,9 +203,9 @@ public final class AndroidTargetParser {
|
|||||||
attrsManifestXmlParser);
|
attrsManifestXmlParser);
|
||||||
Map<String, Map<String, Integer>> enumValueMap = attrsXmlParser.getEnumFlagValues();
|
Map<String, Map<String, Integer>> enumValueMap = attrsXmlParser.getEnumFlagValues();
|
||||||
|
|
||||||
Map<String, DeclareStyleableInfo> xmlGadgetMap = null;
|
Map<String, DeclareStyleableInfo> xmlAppWidgetMap = null;
|
||||||
if (mAndroidTarget.getApiVersionNumber() >= 3) {
|
if (mAndroidTarget.getApiVersionNumber() >= 3) {
|
||||||
xmlGadgetMap = collectGadgetDefinitions(attrsXmlParser);
|
xmlAppWidgetMap = collectAppWidgetDefinitions(attrsXmlParser);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
@@ -241,7 +241,7 @@ public final class AndroidTargetParser {
|
|||||||
XmlDescriptors xmlDescriptors = new XmlDescriptors();
|
XmlDescriptors xmlDescriptors = new XmlDescriptors();
|
||||||
xmlDescriptors.updateDescriptors(
|
xmlDescriptors.updateDescriptors(
|
||||||
xmlSearchableMap,
|
xmlSearchableMap,
|
||||||
xmlGadgetMap,
|
xmlAppWidgetMap,
|
||||||
preferencesInfo,
|
preferencesInfo,
|
||||||
preferenceGroupsInfo);
|
preferenceGroupsInfo);
|
||||||
progress.worked(1);
|
progress.worked(1);
|
||||||
@@ -611,23 +611,23 @@ public final class AndroidTargetParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all gadgetProviderInfo definition information from the attrs.xml and returns it.
|
* Collects all appWidgetProviderInfo definition information from the attrs.xml and returns it.
|
||||||
*
|
*
|
||||||
* @param attrsXmlParser The parser of the attrs.xml file
|
* @param attrsXmlParser The parser of the attrs.xml file
|
||||||
*/
|
*/
|
||||||
private Map<String, DeclareStyleableInfo> collectGadgetDefinitions(
|
private Map<String, DeclareStyleableInfo> collectAppWidgetDefinitions(
|
||||||
AttrsXmlParser attrsXmlParser) {
|
AttrsXmlParser attrsXmlParser) {
|
||||||
Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
|
Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
|
||||||
Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
|
Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
|
||||||
for (String key : new String[] { "GadgetProviderInfo" }) { //$NON-NLS-1$
|
for (String key : new String[] { "AppWidgetProviderInfo" }) { //$NON-NLS-1$
|
||||||
if (map.containsKey(key)) {
|
if (map.containsKey(key)) {
|
||||||
map2.put(key, map.get(key));
|
map2.put(key, map.get(key));
|
||||||
} else {
|
} else {
|
||||||
AdtPlugin.log(IStatus.WARNING,
|
AdtPlugin.log(IStatus.WARNING,
|
||||||
"Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
|
"AppWidget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
|
||||||
key, attrsXmlParser.getOsAttrsXmlPath());
|
key, attrsXmlParser.getOsAttrsXmlPath());
|
||||||
AdtPlugin.printErrorToConsole("Android Framework Parser",
|
AdtPlugin.printErrorToConsole("Android Framework Parser",
|
||||||
String.format("Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
|
String.format("AppWidget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
|
||||||
key, attrsXmlParser.getOsAttrsXmlPath()));
|
key, attrsXmlParser.getOsAttrsXmlPath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ package com.android.ide.eclipse.adt.wizards.newproject;
|
|||||||
|
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
import com.android.sdklib.IAndroidTarget;
|
import com.android.sdklib.IAndroidTarget;
|
||||||
import com.android.sdklib.SdkConstants;
|
import com.android.sdklib.SdkConstants;
|
||||||
import com.android.sdklib.project.ProjectProperties;
|
import com.android.sdklib.project.ProjectProperties;
|
||||||
@@ -36,6 +36,7 @@ import org.eclipse.core.resources.IProject;
|
|||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.resources.IWorkspace;
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Path;
|
import org.eclipse.core.runtime.Path;
|
||||||
@@ -821,26 +822,41 @@ public class NewProjectCreationPage extends WizardPage {
|
|||||||
|
|
||||||
Path path = new Path(f.getPath());
|
Path path = new Path(f.getPath());
|
||||||
String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
|
String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
|
||||||
AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
|
|
||||||
if (!manifest.exists()) {
|
AndroidManifestParser manifestData = null;
|
||||||
|
try {
|
||||||
|
manifestData = AndroidManifestParser.parseForData(osPath);
|
||||||
|
} catch (CoreException e1) {
|
||||||
|
// ignore any parsing issue
|
||||||
|
}
|
||||||
|
if (manifestData == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String packageName = null;
|
String packageName = null;
|
||||||
String activityName = null;
|
String activityName = null;
|
||||||
String minSdkVersion = null;
|
int minSdkVersion = 0; // 0 means no minSdkVersion provided in the manifest
|
||||||
try {
|
try {
|
||||||
packageName = manifest.getPackageName();
|
packageName = manifestData.getPackage();
|
||||||
activityName = manifest.getActivityName(1);
|
minSdkVersion = manifestData.getApiLevelRequirement();
|
||||||
minSdkVersion = manifest.getMinSdkVersion();
|
|
||||||
|
// try to get the first launcher activity. If none, just take the first activity.
|
||||||
|
activityName = manifestData.getLauncherActivity();
|
||||||
|
if (activityName == null) {
|
||||||
|
String[] activities = manifestData.getActivities();
|
||||||
|
if (activities != null && activities.length > 0) {
|
||||||
|
activityName = activities[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// ignore exceptions
|
// ignore exceptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (packageName != null && packageName.length() > 0) {
|
if (packageName != null && packageName.length() > 0) {
|
||||||
mPackageNameField.setText(packageName);
|
mPackageNameField.setText(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activityName = AndroidManifestParser.extractActivityName(activityName, packageName);
|
||||||
|
|
||||||
if (activityName != null && activityName.length() > 0) {
|
if (activityName != null && activityName.length() > 0) {
|
||||||
mInternalActivityNameUpdate = true;
|
mInternalActivityNameUpdate = true;
|
||||||
@@ -917,12 +933,10 @@ public class NewProjectCreationPage extends WizardPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundTarget && minSdkVersion != null) {
|
if (!foundTarget && minSdkVersion > 0) {
|
||||||
try {
|
try {
|
||||||
int sdkVersion = Integer.parseInt(minSdkVersion);
|
|
||||||
|
|
||||||
for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
|
for (IAndroidTarget target : mSdkTargetSelector.getTargets()) {
|
||||||
if (target.getApiVersionNumber() == sdkVersion) {
|
if (target.getApiVersionNumber() == minSdkVersion) {
|
||||||
mSdkTargetSelector.setSelection(target);
|
mSdkTargetSelector.setSelection(target);
|
||||||
foundTarget = true;
|
foundTarget = true;
|
||||||
break;
|
break;
|
||||||
@@ -945,7 +959,8 @@ public class NewProjectCreationPage extends WizardPage {
|
|||||||
|
|
||||||
if (!foundTarget) {
|
if (!foundTarget) {
|
||||||
mInternalMinSdkVersionUpdate = true;
|
mInternalMinSdkVersionUpdate = true;
|
||||||
mMinSdkVersionField.setText(minSdkVersion == null ? "" : minSdkVersion); //$NON-NLS-1$
|
mMinSdkVersionField.setText(
|
||||||
|
minSdkVersion <= 0 ? "" : Integer.toString(minSdkVersion)); //$NON-NLS-1$
|
||||||
mInternalMinSdkVersionUpdate = false;
|
mInternalMinSdkVersionUpdate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1072,8 +1087,8 @@ public class NewProjectCreationPage extends WizardPage {
|
|||||||
|
|
||||||
// Check there's an android manifest in the directory
|
// Check there's an android manifest in the directory
|
||||||
String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
|
String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString();
|
||||||
AndroidManifestHelper manifest = new AndroidManifestHelper(osPath);
|
File manifestFile = new File(osPath);
|
||||||
if (!manifest.exists()) {
|
if (!manifestFile.isFile()) {
|
||||||
return setStatus(
|
return setStatus(
|
||||||
String.format("File %1$s not found in %2$s.",
|
String.format("File %1$s not found in %2$s.",
|
||||||
AndroidConstants.FN_ANDROID_MANIFEST, f.getName()),
|
AndroidConstants.FN_ANDROID_MANIFEST, f.getName()),
|
||||||
@@ -1081,15 +1096,24 @@ public class NewProjectCreationPage extends WizardPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse it and check the important fields.
|
// Parse it and check the important fields.
|
||||||
String packageName = manifest.getPackageName();
|
AndroidManifestParser manifestData;
|
||||||
|
try {
|
||||||
|
manifestData = AndroidManifestParser.parseForData(osPath);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
return setStatus(
|
||||||
|
String.format("File %1$s could not be parsed.", osPath),
|
||||||
|
MSG_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
String packageName = manifestData.getPackage();
|
||||||
if (packageName == null || packageName.length() == 0) {
|
if (packageName == null || packageName.length() == 0) {
|
||||||
return setStatus(
|
return setStatus(
|
||||||
String.format("No package name defined in %1$s.", osPath),
|
String.format("No package name defined in %1$s.", osPath),
|
||||||
MSG_ERROR);
|
MSG_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
String activityName = manifest.getActivityName(1);
|
String[] activities = manifestData.getActivities();
|
||||||
if (activityName == null || activityName.length() == 0) {
|
if (activities == null || activities.length == 0) {
|
||||||
// This is acceptable now as long as no activity needs to be created
|
// This is acceptable now as long as no activity needs to be created
|
||||||
if (isCreateActivity()) {
|
if (isCreateActivity()) {
|
||||||
return setStatus(
|
return setStatus(
|
||||||
@@ -1097,7 +1121,7 @@ public class NewProjectCreationPage extends WizardPage {
|
|||||||
MSG_ERROR);
|
MSG_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there's already a .project, tell the user to use import instead.
|
// If there's already a .project, tell the user to use import instead.
|
||||||
if (path.append(".project").toFile().exists()) { //$NON-NLS-1$
|
if (path.append(".project").toFile().exists()) { //$NON-NLS-1$
|
||||||
return setStatus("An Eclipse project already exists in this directory. Consider using File > Import > Existing Project instead.",
|
return setStatus("An Eclipse project already exists in this directory. Consider using File > Import > Existing Project instead.",
|
||||||
|
|||||||
@@ -1,241 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 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.common.project;
|
|
||||||
|
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
|
||||||
|
|
||||||
import org.eclipse.core.resources.IFile;
|
|
||||||
import org.eclipse.core.resources.IProject;
|
|
||||||
import org.eclipse.core.resources.IResource;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileReader;
|
|
||||||
|
|
||||||
import javax.xml.xpath.XPath;
|
|
||||||
import javax.xml.xpath.XPathExpressionException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility class that manages the AndroidManifest.xml file.
|
|
||||||
* <p/>
|
|
||||||
* All the get method work by XPath. Repeated calls to those may warrant using
|
|
||||||
* {@link AndroidManifestParser} instead.
|
|
||||||
*/
|
|
||||||
public class AndroidManifestHelper {
|
|
||||||
private IFile mManifestIFile;
|
|
||||||
private File mManifestFile;
|
|
||||||
private XPath mXPath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an AndroidManifest based on an existing Eclipse {@link IProject} object.
|
|
||||||
* </p>
|
|
||||||
* Use {@link #exists()} to check if the manifest file really exists in the project.
|
|
||||||
*
|
|
||||||
* @param project The project to search for the manifest.
|
|
||||||
*/
|
|
||||||
public AndroidManifestHelper(IProject project) {
|
|
||||||
mXPath = AndroidXPathFactory.newXPath();
|
|
||||||
mManifestIFile = getManifest(project);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an AndroidManifest based on a file path.
|
|
||||||
* <p/>
|
|
||||||
* Use {@link #exists()} to check if the manifest file really exists.
|
|
||||||
*
|
|
||||||
* @param osManifestFilePath the os path to the AndroidManifest.xml file.
|
|
||||||
*/
|
|
||||||
public AndroidManifestHelper(String osManifestFilePath) {
|
|
||||||
mXPath = AndroidXPathFactory.newXPath();
|
|
||||||
mManifestFile = new File(osManifestFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the underlying {@link IFile} for the android manifest XML file, if found in the
|
|
||||||
* given Eclipse project.
|
|
||||||
*
|
|
||||||
* Always return null if the constructor that takes an {@link IProject} was NOT called.
|
|
||||||
*
|
|
||||||
* @return The IFile for the androidManifest.xml or null if no such file could be found.
|
|
||||||
*/
|
|
||||||
public IFile getManifestIFile() {
|
|
||||||
return mManifestIFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the underlying {@link File} for the android manifest XML file.
|
|
||||||
*/
|
|
||||||
public File getManifestFile() {
|
|
||||||
if (mManifestIFile != null) {
|
|
||||||
return mManifestIFile.getLocation().toFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
return mManifestFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the package name defined in the manifest file.
|
|
||||||
*
|
|
||||||
* @return A String object with the package or null if any error happened.
|
|
||||||
*/
|
|
||||||
public String getPackageName() {
|
|
||||||
try {
|
|
||||||
return mXPath.evaluate("/manifest/@package", getSource()); //$NON-NLS-1$
|
|
||||||
} catch (XPathExpressionException e1) {
|
|
||||||
// If the XPath failed to evaluate, we'll return null.
|
|
||||||
} catch (Exception e) {
|
|
||||||
// if this happens this is due to the resource being out of sync.
|
|
||||||
// so we must refresh it and do it again
|
|
||||||
|
|
||||||
// for any other kind of exception we must return null as well;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the minSdkVersion defined in the manifest file.
|
|
||||||
*
|
|
||||||
* @return A String object with the package or null if any error happened.
|
|
||||||
*/
|
|
||||||
public String getMinSdkVersion() {
|
|
||||||
try {
|
|
||||||
return mXPath.evaluate("/manifest/uses-sdk/@" //$NON-NLS-1$
|
|
||||||
+ AndroidXPathFactory.DEFAULT_NS_PREFIX
|
|
||||||
+ ":minSdkVersion", getSource()); //$NON-NLS-1$
|
|
||||||
} catch (XPathExpressionException e1) {
|
|
||||||
// If the XPath failed to evaluate, we'll return null.
|
|
||||||
} catch (Exception e) {
|
|
||||||
// if this happens this is due to the resource being out of sync.
|
|
||||||
// so we must refresh it and do it again
|
|
||||||
|
|
||||||
// for any other kind of exception we must return null as well;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns the i-th activity defined in the manifest file.
|
|
||||||
*
|
|
||||||
* @param index The 1-based index of the activity to return.
|
|
||||||
* @return A String object with the activity or null if any error happened.
|
|
||||||
*/
|
|
||||||
public String getActivityName(int index) {
|
|
||||||
try {
|
|
||||||
return mXPath.evaluate("/manifest/application/activity[" //$NON-NLS-1$
|
|
||||||
+ index
|
|
||||||
+ "]/@" //$NON-NLS-1$
|
|
||||||
+ AndroidXPathFactory.DEFAULT_NS_PREFIX +":name", //$NON-NLS-1$
|
|
||||||
getSource());
|
|
||||||
} catch (XPathExpressionException e1) {
|
|
||||||
// If the XPath failed to evaluate, we'll return null.
|
|
||||||
} catch (Exception e) {
|
|
||||||
// if this happens this is due to the resource being out of sync.
|
|
||||||
// so we must refresh it and do it again
|
|
||||||
|
|
||||||
// for any other kind of exception we must return null as well;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an IFile object representing the manifest for the specified
|
|
||||||
* project.
|
|
||||||
*
|
|
||||||
* @param project The project containing the manifest file.
|
|
||||||
* @return An IFile object pointing to the manifest or null if the manifest
|
|
||||||
* is missing.
|
|
||||||
*/
|
|
||||||
public static IFile getManifest(IProject project) {
|
|
||||||
IResource r = project.findMember(AndroidConstants.WS_SEP
|
|
||||||
+ AndroidConstants.FN_ANDROID_MANIFEST);
|
|
||||||
|
|
||||||
if (r == null || r.exists() == false || (r instanceof IFile) == false) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return (IFile) r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true either if an androidManifest.xml file was found in the project
|
|
||||||
* or if the given file path exists.
|
|
||||||
*/
|
|
||||||
public boolean exists() {
|
|
||||||
if (mManifestIFile != null) {
|
|
||||||
return mManifestIFile.exists();
|
|
||||||
} else if (mManifestFile != null) {
|
|
||||||
return mManifestFile.exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an InputSource for XPath.
|
|
||||||
*
|
|
||||||
* @throws FileNotFoundException if file does not exist.
|
|
||||||
* @throws CoreException if the {@link IFile} does not exist.
|
|
||||||
*/
|
|
||||||
private InputSource getSource() throws FileNotFoundException, CoreException {
|
|
||||||
if (mManifestIFile != null) {
|
|
||||||
return new InputSource(mManifestIFile.getContents());
|
|
||||||
} else if (mManifestFile != null) {
|
|
||||||
return new InputSource(new FileReader(mManifestFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,8 @@ import com.android.sdklib.SdkConstants;
|
|||||||
|
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IMarker;
|
import org.eclipse.core.resources.IMarker;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.jdt.core.IJavaProject;
|
import org.eclipse.jdt.core.IJavaProject;
|
||||||
import org.xml.sax.Attributes;
|
import org.xml.sax.Attributes;
|
||||||
@@ -30,6 +32,8 @@ import org.xml.sax.Locator;
|
|||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -56,6 +60,8 @@ public class AndroidManifestParser {
|
|||||||
private final static String NODE_ACTION = "action"; //$NON-NLS-1$
|
private final static String NODE_ACTION = "action"; //$NON-NLS-1$
|
||||||
private final static String NODE_CATEGORY = "category"; //$NON-NLS-1$
|
private final static String NODE_CATEGORY = "category"; //$NON-NLS-1$
|
||||||
private final static String NODE_USES_SDK = "uses-sdk"; //$NON-NLS-1$
|
private final static String NODE_USES_SDK = "uses-sdk"; //$NON-NLS-1$
|
||||||
|
private final static String NODE_INSTRUMENTATION = "instrumentation"; //$NON-NLS-1$
|
||||||
|
private final static String NODE_USES_LIBRARY = "uses-library"; //$NON-NLS-1$
|
||||||
|
|
||||||
private final static int LEVEL_MANIFEST = 0;
|
private final static int LEVEL_MANIFEST = 0;
|
||||||
private final static int LEVEL_APPLICATION = 1;
|
private final static int LEVEL_APPLICATION = 1;
|
||||||
@@ -66,6 +72,12 @@ public class AndroidManifestParser {
|
|||||||
private final static String ACTION_MAIN = "android.intent.action.MAIN"; //$NON-NLS-1$
|
private final static String ACTION_MAIN = "android.intent.action.MAIN"; //$NON-NLS-1$
|
||||||
private final static String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; //$NON-NLS-1$
|
private final static String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XML error & data handler used when parsing the AndroidManifest.xml file.
|
||||||
|
* <p/>
|
||||||
|
* This serves both as an {@link XmlErrorHandler} to report errors and as a data repository
|
||||||
|
* to collect data from the manifest.
|
||||||
|
*/
|
||||||
private static class ManifestHandler extends XmlErrorHandler {
|
private static class ManifestHandler extends XmlErrorHandler {
|
||||||
|
|
||||||
//--- data read from the parsing
|
//--- data read from the parsing
|
||||||
@@ -82,6 +94,10 @@ public class AndroidManifestParser {
|
|||||||
private Boolean mDebuggable = null;
|
private Boolean mDebuggable = null;
|
||||||
/** API level requirement. if 0 the attribute was not present. */
|
/** API level requirement. if 0 the attribute was not present. */
|
||||||
private int mApiLevelRequirement = 0;
|
private int mApiLevelRequirement = 0;
|
||||||
|
/** List of all instrumentations declared by the manifest */
|
||||||
|
private final ArrayList<String> mInstrumentations = new ArrayList<String>();
|
||||||
|
/** List of all libraries in use declared by the manifest */
|
||||||
|
private final ArrayList<String> mLibraries = new ArrayList<String>();
|
||||||
|
|
||||||
//--- temporary data/flags used during parsing
|
//--- temporary data/flags used during parsing
|
||||||
private IJavaProject mJavaProject;
|
private IJavaProject mJavaProject;
|
||||||
@@ -95,12 +111,13 @@ public class AndroidManifestParser {
|
|||||||
private Locator mLocator;
|
private Locator mLocator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Creates a new {@link ManifestHandler}, which is also an {@link XmlErrorHandler}.
|
||||||
* @param manifestFile
|
*
|
||||||
* @param errorListener
|
* @param manifestFile The manifest file being parsed. Can be null.
|
||||||
* @param gatherData
|
* @param errorListener An optional error listener.
|
||||||
* @param javaProject
|
* @param gatherData True if data should be gathered.
|
||||||
* @param markErrors
|
* @param javaProject The java project holding the manifest file. Can be null.
|
||||||
|
* @param markErrors True if errors should be marked as Eclipse Markers on the resource.
|
||||||
*/
|
*/
|
||||||
ManifestHandler(IFile manifestFile, XmlErrorListener errorListener,
|
ManifestHandler(IFile manifestFile, XmlErrorListener errorListener,
|
||||||
boolean gatherData, IJavaProject javaProject, boolean markErrors) {
|
boolean gatherData, IJavaProject javaProject, boolean markErrors) {
|
||||||
@@ -160,6 +177,23 @@ public class AndroidManifestParser {
|
|||||||
return mApiLevelRequirement;
|
return mApiLevelRequirement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of instrumentations found in the manifest.
|
||||||
|
* @return An array of instrumentation names, or empty if no instrumentations were
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
String[] getInstrumentations() {
|
||||||
|
return mInstrumentations.toArray(new String[mInstrumentations.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of libraries in use found in the manifest.
|
||||||
|
* @return An array of library names, or empty if no libraries were found.
|
||||||
|
*/
|
||||||
|
String[] getUsesLibraries() {
|
||||||
|
return mLibraries.toArray(new String[mLibraries.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
|
* @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
|
||||||
*/
|
*/
|
||||||
@@ -217,7 +251,13 @@ public class AndroidManifestParser {
|
|||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
handleError(e, -1 /* lineNumber */);
|
handleError(e, -1 /* lineNumber */);
|
||||||
}
|
}
|
||||||
}
|
} else if (NODE_INSTRUMENTATION.equals(localName)) {
|
||||||
|
value = getAttributeValue(attributes, ATTRIBUTE_NAME,
|
||||||
|
true /* hasNamespace */);
|
||||||
|
if (value != null) {
|
||||||
|
mInstrumentations.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LEVEL_ACTIVITY:
|
case LEVEL_ACTIVITY:
|
||||||
if (NODE_ACTIVITY.equals(localName)) {
|
if (NODE_ACTIVITY.equals(localName)) {
|
||||||
@@ -232,7 +272,13 @@ public class AndroidManifestParser {
|
|||||||
} else if (NODE_PROVIDER.equals(localName)) {
|
} else if (NODE_PROVIDER.equals(localName)) {
|
||||||
processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
|
processNode(attributes, AndroidConstants.CLASS_CONTENTPROVIDER);
|
||||||
mValidLevel++;
|
mValidLevel++;
|
||||||
}
|
} else if (NODE_USES_LIBRARY.equals(localName)) {
|
||||||
|
value = getAttributeValue(attributes, ATTRIBUTE_NAME,
|
||||||
|
true /* hasNamespace */);
|
||||||
|
if (value != null) {
|
||||||
|
mLibraries.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case LEVEL_INTENT_FILTER:
|
case LEVEL_INTENT_FILTER:
|
||||||
// only process this level if we are in an activity
|
// only process this level if we are in an activity
|
||||||
@@ -355,8 +401,7 @@ public class AndroidManifestParser {
|
|||||||
String activityName = getAttributeValue(attributes, ATTRIBUTE_NAME,
|
String activityName = getAttributeValue(attributes, ATTRIBUTE_NAME,
|
||||||
true /* hasNamespace */);
|
true /* hasNamespace */);
|
||||||
if (activityName != null) {
|
if (activityName != null) {
|
||||||
mCurrentActivity = AndroidManifestHelper.combinePackageAndClassName(mPackage,
|
mCurrentActivity = combinePackageAndClassName(mPackage, activityName);
|
||||||
activityName);
|
|
||||||
mActivities.add(mCurrentActivity);
|
mActivities.add(mCurrentActivity);
|
||||||
|
|
||||||
if (mMarkErrors) {
|
if (mMarkErrors) {
|
||||||
@@ -387,8 +432,7 @@ public class AndroidManifestParser {
|
|||||||
String serviceName = getAttributeValue(attributes, ATTRIBUTE_NAME,
|
String serviceName = getAttributeValue(attributes, ATTRIBUTE_NAME,
|
||||||
true /* hasNamespace */);
|
true /* hasNamespace */);
|
||||||
if (serviceName != null) {
|
if (serviceName != null) {
|
||||||
serviceName = AndroidManifestHelper.combinePackageAndClassName(mPackage,
|
serviceName = combinePackageAndClassName(mPackage, serviceName);
|
||||||
serviceName);
|
|
||||||
|
|
||||||
if (mMarkErrors) {
|
if (mMarkErrors) {
|
||||||
checkClass(serviceName, superClassName, false /* testVisibility */);
|
checkClass(serviceName, superClassName, false /* testVisibility */);
|
||||||
@@ -412,6 +456,9 @@ public class AndroidManifestParser {
|
|||||||
* the class or of its constructors.
|
* the class or of its constructors.
|
||||||
*/
|
*/
|
||||||
private void checkClass(String className, String superClassName, boolean testVisibility) {
|
private void checkClass(String className, String superClassName, boolean testVisibility) {
|
||||||
|
if (mJavaProject == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// we need to check the validity of the activity.
|
// we need to check the validity of the activity.
|
||||||
String result = BaseProjectHelper.testClassForManifest(mJavaProject,
|
String result = BaseProjectHelper.testClassForManifest(mJavaProject,
|
||||||
className, superClassName, testVisibility);
|
className, superClassName, testVisibility);
|
||||||
@@ -477,6 +524,8 @@ public class AndroidManifestParser {
|
|||||||
private final String[] mProcesses;
|
private final String[] mProcesses;
|
||||||
private final Boolean mDebuggable;
|
private final Boolean mDebuggable;
|
||||||
private final int mApiLevelRequirement;
|
private final int mApiLevelRequirement;
|
||||||
|
private final String[] mInstrumentations;
|
||||||
|
private final String[] mLibraries;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
sParserFactory = SAXParserFactory.newInstance();
|
sParserFactory = SAXParserFactory.newInstance();
|
||||||
@@ -484,8 +533,12 @@ public class AndroidManifestParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the Android Manifest, and returns an object containing
|
* Parses the Android Manifest, and returns an object containing the result of the parsing.
|
||||||
* the result of the parsing.
|
* <p/>
|
||||||
|
* This method is useful to parse a specific {@link IFile} in a Java project.
|
||||||
|
* <p/>
|
||||||
|
* If you only want to gather data, consider {@link #parseForData(IFile)} instead.
|
||||||
|
*
|
||||||
* @param javaProject The java project.
|
* @param javaProject The java project.
|
||||||
* @param manifestFile the {@link IFile} representing the manifest file.
|
* @param manifestFile the {@link IFile} representing the manifest file.
|
||||||
* @param errorListener
|
* @param errorListener
|
||||||
@@ -496,8 +549,12 @@ public class AndroidManifestParser {
|
|||||||
* @return an {@link AndroidManifestParser} or null if the parsing failed.
|
* @return an {@link AndroidManifestParser} or null if the parsing failed.
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
public static AndroidManifestParser parse(IJavaProject javaProject, IFile manifestFile,
|
public static AndroidManifestParser parse(
|
||||||
XmlErrorListener errorListener, boolean gatherData, boolean markErrors)
|
IJavaProject javaProject,
|
||||||
|
IFile manifestFile,
|
||||||
|
XmlErrorListener errorListener,
|
||||||
|
boolean gatherData,
|
||||||
|
boolean markErrors)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
try {
|
try {
|
||||||
SAXParser parser = sParserFactory.newSAXParser();
|
SAXParser parser = sParserFactory.newSAXParser();
|
||||||
@@ -512,7 +569,51 @@ public class AndroidManifestParser {
|
|||||||
return new AndroidManifestParser(manifestHandler.getPackage(),
|
return new AndroidManifestParser(manifestHandler.getPackage(),
|
||||||
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
|
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
|
||||||
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
|
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
|
||||||
manifestHandler.getApiLevelRequirement());
|
manifestHandler.getApiLevelRequirement(), manifestHandler.getInstrumentations(),
|
||||||
|
manifestHandler.getUsesLibraries());
|
||||||
|
} catch (ParserConfigurationException e) {
|
||||||
|
} catch (SAXException e) {
|
||||||
|
} catch (IOException e) {
|
||||||
|
} finally {
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the Android Manifest, and returns an object containing the result of the parsing.
|
||||||
|
* <p/>
|
||||||
|
* This version parses a real {@link File} file given by an actual path, which is useful for
|
||||||
|
* parsing a file that is not part of an Eclipse Java project.
|
||||||
|
* <p/>
|
||||||
|
* It assumes errors cannot be marked on the file and that data gathering is enabled.
|
||||||
|
*
|
||||||
|
* @param manifestFile the manifest file to parse.
|
||||||
|
* @return an {@link AndroidManifestParser} or null if the parsing failed.
|
||||||
|
* @throws CoreException
|
||||||
|
*/
|
||||||
|
private static AndroidManifestParser parse(File manifestFile)
|
||||||
|
throws CoreException {
|
||||||
|
try {
|
||||||
|
SAXParser parser = sParserFactory.newSAXParser();
|
||||||
|
|
||||||
|
ManifestHandler manifestHandler = new ManifestHandler(
|
||||||
|
null, //manifestFile
|
||||||
|
null, //errorListener
|
||||||
|
true, //gatherData
|
||||||
|
null, //javaProject
|
||||||
|
false //markErrors
|
||||||
|
);
|
||||||
|
|
||||||
|
parser.parse(new InputSource(new FileReader(manifestFile)), manifestHandler);
|
||||||
|
|
||||||
|
// get the result from the handler
|
||||||
|
|
||||||
|
return new AndroidManifestParser(manifestHandler.getPackage(),
|
||||||
|
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
|
||||||
|
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
|
||||||
|
manifestHandler.getApiLevelRequirement(), manifestHandler.getInstrumentations(),
|
||||||
|
manifestHandler.getUsesLibraries());
|
||||||
} catch (ParserConfigurationException e) {
|
} catch (ParserConfigurationException e) {
|
||||||
} catch (SAXException e) {
|
} catch (SAXException e) {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -535,13 +636,16 @@ public class AndroidManifestParser {
|
|||||||
* @return an {@link AndroidManifestParser} or null if the parsing failed.
|
* @return an {@link AndroidManifestParser} or null if the parsing failed.
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
public static AndroidManifestParser parse(IJavaProject javaProject,
|
public static AndroidManifestParser parse(
|
||||||
XmlErrorListener errorListener, boolean gatherData, boolean markErrors)
|
IJavaProject javaProject,
|
||||||
|
XmlErrorListener errorListener,
|
||||||
|
boolean gatherData,
|
||||||
|
boolean markErrors)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
try {
|
try {
|
||||||
SAXParser parser = sParserFactory.newSAXParser();
|
SAXParser parser = sParserFactory.newSAXParser();
|
||||||
|
|
||||||
IFile manifestFile = AndroidManifestHelper.getManifest(javaProject.getProject());
|
IFile manifestFile = getManifest(javaProject.getProject());
|
||||||
if (manifestFile != null) {
|
if (manifestFile != null) {
|
||||||
ManifestHandler manifestHandler = new ManifestHandler(manifestFile,
|
ManifestHandler manifestHandler = new ManifestHandler(manifestFile,
|
||||||
errorListener, gatherData, javaProject, markErrors);
|
errorListener, gatherData, javaProject, markErrors);
|
||||||
@@ -552,7 +656,8 @@ public class AndroidManifestParser {
|
|||||||
return new AndroidManifestParser(manifestHandler.getPackage(),
|
return new AndroidManifestParser(manifestHandler.getPackage(),
|
||||||
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
|
manifestHandler.getActivities(), manifestHandler.getLauncherActivity(),
|
||||||
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
|
manifestHandler.getProcesses(), manifestHandler.getDebuggable(),
|
||||||
manifestHandler.getApiLevelRequirement());
|
manifestHandler.getApiLevelRequirement(),
|
||||||
|
manifestHandler.getInstrumentations(), manifestHandler.getUsesLibraries());
|
||||||
}
|
}
|
||||||
} catch (ParserConfigurationException e) {
|
} catch (ParserConfigurationException e) {
|
||||||
} catch (SAXException e) {
|
} catch (SAXException e) {
|
||||||
@@ -588,6 +693,18 @@ public class AndroidManifestParser {
|
|||||||
true /* gatherData */, false /* markErrors */);
|
true /* gatherData */, false /* markErrors */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the manifest file, and collects data.
|
||||||
|
*
|
||||||
|
* @param osManifestFilePath The OS path of the manifest file to parse.
|
||||||
|
* @return an {@link AndroidManifestParser} or null if the parsing failed.
|
||||||
|
* @throws CoreException
|
||||||
|
*/
|
||||||
|
public static AndroidManifestParser parseForData(String osManifestFilePath)
|
||||||
|
throws CoreException {
|
||||||
|
return parse(new File(osManifestFilePath));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the package defined in the manifest, if found.
|
* Returns the package defined in the manifest, if found.
|
||||||
* @return The package name or null if not found.
|
* @return The package name or null if not found.
|
||||||
@@ -633,6 +750,22 @@ public class AndroidManifestParser {
|
|||||||
public int getApiLevelRequirement() {
|
public int getApiLevelRequirement() {
|
||||||
return mApiLevelRequirement;
|
return mApiLevelRequirement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of instrumentations found in the manifest.
|
||||||
|
* @return An array of fully qualified class names, or empty if no instrumentations were found.
|
||||||
|
*/
|
||||||
|
public String[] getInstrumentations() {
|
||||||
|
return mInstrumentations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the list of libraries in use found in the manifest.
|
||||||
|
* @return An array of library names, or empty if no uses-library declarations were found.
|
||||||
|
*/
|
||||||
|
public String[] getUsesLibraries() {
|
||||||
|
return mLibraries;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -647,15 +780,92 @@ public class AndroidManifestParser {
|
|||||||
* @param processes the list of custom processes declared in the manifest.
|
* @param processes the list of custom processes declared in the manifest.
|
||||||
* @param debuggable the debuggable attribute, or null if not set.
|
* @param debuggable the debuggable attribute, or null if not set.
|
||||||
* @param apiLevelRequirement the minSdkVersion attribute value or 0 if not set.
|
* @param apiLevelRequirement the minSdkVersion attribute value or 0 if not set.
|
||||||
|
* @param instrumentations the list of instrumentations parsed from the manifest.
|
||||||
|
* @param libraries the list of libraries in use parsed from the manifest.
|
||||||
*/
|
*/
|
||||||
private AndroidManifestParser(String javaPackage, String[] activities,
|
private AndroidManifestParser(String javaPackage, String[] activities,
|
||||||
String launcherActivity, String[] processes, Boolean debuggable,
|
String launcherActivity, String[] processes, Boolean debuggable,
|
||||||
int apiLevelRequirement) {
|
int apiLevelRequirement, String[] instrumentations, String[] libraries) {
|
||||||
mJavaPackage = javaPackage;
|
mJavaPackage = javaPackage;
|
||||||
mActivities = activities;
|
mActivities = activities;
|
||||||
mLauncherActivity = launcherActivity;
|
mLauncherActivity = launcherActivity;
|
||||||
mProcesses = processes;
|
mProcesses = processes;
|
||||||
mDebuggable = debuggable;
|
mDebuggable = debuggable;
|
||||||
mApiLevelRequirement = apiLevelRequirement;
|
mApiLevelRequirement = apiLevelRequirement;
|
||||||
|
mInstrumentations = instrumentations;
|
||||||
|
mLibraries = libraries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an IFile object representing the manifest for the specified
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* @param project The project containing the manifest file.
|
||||||
|
* @return An IFile object pointing to the manifest or null if the manifest
|
||||||
|
* is missing.
|
||||||
|
*/
|
||||||
|
public static IFile getManifest(IProject project) {
|
||||||
|
IResource r = project.findMember(AndroidConstants.WS_SEP
|
||||||
|
+ AndroidConstants.FN_ANDROID_MANIFEST);
|
||||||
|
|
||||||
|
if (r == null || r.exists() == false || (r instanceof IFile) == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (IFile) r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 fullActivityName a fully qualified activity class name, e.g. "com.foo.test.MyClass"
|
||||||
|
* @param packageName The project base package name, e.g. "com.foo"
|
||||||
|
* @return The relative activity name if it can be computed or the original fullActivityName.
|
||||||
|
*/
|
||||||
|
public static String extractActivityName(String fullActivityName, String packageName) {
|
||||||
|
if (packageName != null && fullActivityName != null) {
|
||||||
|
if (packageName.length() > 0 && fullActivityName.startsWith(packageName)) {
|
||||||
|
String name = fullActivityName.substring(packageName.length());
|
||||||
|
if (name.length() > 0 && name.charAt(0) == '.') {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullActivityName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,8 +86,13 @@ public class XmlErrorHandler extends DefaultHandler {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void warning(SAXParseException exception) throws SAXException {
|
public void warning(SAXParseException exception) throws SAXException {
|
||||||
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
|
if (mFile != null) {
|
||||||
exception.getLineNumber(), IMarker.SEVERITY_WARNING);
|
BaseProjectHelper.addMarker(mFile,
|
||||||
|
AndroidConstants.MARKER_XML,
|
||||||
|
exception.getMessage(),
|
||||||
|
exception.getLineNumber(),
|
||||||
|
IMarker.SEVERITY_WARNING);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final IFile getFile() {
|
protected final IFile getFile() {
|
||||||
@@ -104,12 +109,19 @@ public class XmlErrorHandler extends DefaultHandler {
|
|||||||
mErrorListener.errorFound();
|
mErrorListener.errorFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lineNumber != -1) {
|
if (mFile != null) {
|
||||||
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
|
if (lineNumber != -1) {
|
||||||
lineNumber, IMarker.SEVERITY_ERROR);
|
BaseProjectHelper.addMarker(mFile,
|
||||||
} else {
|
AndroidConstants.MARKER_XML,
|
||||||
BaseProjectHelper.addMarker(mFile, AndroidConstants.MARKER_XML, exception.getMessage(),
|
exception.getMessage(),
|
||||||
IMarker.SEVERITY_ERROR);
|
lineNumber,
|
||||||
|
IMarker.SEVERITY_ERROR);
|
||||||
|
} else {
|
||||||
|
BaseProjectHelper.addMarker(mFile,
|
||||||
|
AndroidConstants.MARKER_XML,
|
||||||
|
exception.getMessage(),
|
||||||
|
IMarker.SEVERITY_ERROR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -442,11 +442,15 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
|
|||||||
tooltip = ((TextAttributeDescriptor) choice).getTooltip();
|
tooltip = ((TextAttributeDescriptor) choice).getTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the namespace URI for the attribute. Note that some attributes
|
||||||
|
// do not have a namespace and thus return null here.
|
||||||
String nsUri = ((AttributeDescriptor)choice).getNamespaceUri();
|
String nsUri = ((AttributeDescriptor)choice).getNamespaceUri();
|
||||||
nsPrefix = nsUriMap.get(nsUri);
|
if (nsUri != null) {
|
||||||
if (nsPrefix == null) {
|
nsPrefix = nsUriMap.get(nsUri);
|
||||||
nsPrefix = lookupNamespacePrefix(currentNode, nsUri);
|
if (nsPrefix == null) {
|
||||||
nsUriMap.put(nsUri, nsPrefix);
|
nsPrefix = lookupNamespacePrefix(currentNode, nsUri);
|
||||||
|
nsUriMap.put(nsUri, nsPrefix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (nsPrefix != null) {
|
if (nsPrefix != null) {
|
||||||
nsPrefix += ":"; //$NON-NLS-1$
|
nsPrefix += ":"; //$NON-NLS-1$
|
||||||
|
|||||||
@@ -18,12 +18,14 @@ package com.android.ide.eclipse.editors.layout;
|
|||||||
|
|
||||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
import com.android.ide.eclipse.editors.resources.manager.ProjectClassLoader;
|
import com.android.ide.eclipse.editors.resources.manager.ProjectClassLoader;
|
||||||
import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
|
import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
|
||||||
import com.android.layoutlib.api.IProjectCallback;
|
import com.android.layoutlib.api.IProjectCallback;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -83,17 +85,20 @@ public final class ProjectCallback implements IProjectCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* Returns the namespace for the project. The namespace contains a standard part + the
|
* Returns the namespace for the project. The namespace contains a standard part + the
|
||||||
* application package.
|
* application package.
|
||||||
|
*
|
||||||
|
* @return The package namespace of the project or null in case of error.
|
||||||
*/
|
*/
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
if (mNamespace == null) {
|
if (mNamespace == null) {
|
||||||
AndroidManifestHelper manifest = new AndroidManifestHelper(mProject);
|
IFile manifestFile = AndroidManifestParser.getManifest(mProject);
|
||||||
String javaPackage = manifest.getPackageName();
|
try {
|
||||||
|
AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile);
|
||||||
mNamespace = String.format(AndroidConstants.NS_CUSTOM_RESOURCES, javaPackage);
|
String javaPackage = data.getPackage();
|
||||||
|
mNamespace = String.format(AndroidConstants.NS_CUSTOM_RESOURCES, javaPackage);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mNamespace;
|
return mNamespace;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package com.android.ide.eclipse.editors.layout.descriptors;
|
package com.android.ide.eclipse.editors.layout.descriptors;
|
||||||
|
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
|
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
|
||||||
|
import com.android.ide.eclipse.common.resources.ResourceType;
|
||||||
import com.android.ide.eclipse.common.resources.ViewClassInfo;
|
import com.android.ide.eclipse.common.resources.ViewClassInfo;
|
||||||
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
|
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
|
||||||
import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
|
import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo;
|
||||||
@@ -25,6 +27,7 @@ import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
|
|||||||
import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
|
import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
|
||||||
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
|
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
|
||||||
import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
|
import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
|
||||||
|
import com.android.ide.eclipse.editors.descriptors.ReferenceAttributeDescriptor;
|
||||||
import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
|
import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
|
||||||
import com.android.sdklib.SdkConstants;
|
import com.android.sdklib.SdkConstants;
|
||||||
|
|
||||||
@@ -131,8 +134,23 @@ public final class LayoutDescriptors implements IDescriptorProvider {
|
|||||||
String xml_name = info.getShortClassName();
|
String xml_name = info.getShortClassName();
|
||||||
String tooltip = info.getJavaDoc();
|
String tooltip = info.getJavaDoc();
|
||||||
|
|
||||||
// Process all View attributes
|
|
||||||
ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
|
ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
|
||||||
|
|
||||||
|
// All views and groups have an implicit "style" attribute which is a reference.
|
||||||
|
AttributeInfo styleInfo = new DeclareStyleableInfo.AttributeInfo(
|
||||||
|
"style", //$NON-NLS-1$ xmlLocalName
|
||||||
|
new DeclareStyleableInfo.AttributeInfo.Format[] {
|
||||||
|
DeclareStyleableInfo.AttributeInfo.Format.REFERENCE
|
||||||
|
});
|
||||||
|
styleInfo.setJavaDoc("A reference to a custom style"); //tooltip
|
||||||
|
DescriptorsUtils.appendAttribute(attributes,
|
||||||
|
"style", //$NON-NLS-1$
|
||||||
|
null, //nsUri
|
||||||
|
styleInfo,
|
||||||
|
false, //required
|
||||||
|
null); // overrides
|
||||||
|
|
||||||
|
// Process all View attributes
|
||||||
DescriptorsUtils.appendAttributes(attributes,
|
DescriptorsUtils.appendAttributes(attributes,
|
||||||
null, // elementName
|
null, // elementName
|
||||||
SdkConstants.NS_RESOURCES,
|
SdkConstants.NS_RESOURCES,
|
||||||
@@ -155,7 +173,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
|
|||||||
null /* overrides */);
|
null /* overrides */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process all LayoutParams attributes
|
// Process all LayoutParams attributes
|
||||||
ArrayList<AttributeDescriptor> layoutAttributes = new ArrayList<AttributeDescriptor>();
|
ArrayList<AttributeDescriptor> layoutAttributes = new ArrayList<AttributeDescriptor>();
|
||||||
LayoutParamsInfo layoutParams = info.getLayoutData();
|
LayoutParamsInfo layoutParams = info.getLayoutData();
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
package com.android.ide.eclipse.editors.manifest.model;
|
package com.android.ide.eclipse.editors.manifest.model;
|
||||||
|
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
import com.android.ide.eclipse.common.project.BaseProjectHelper;
|
import com.android.ide.eclipse.common.project.BaseProjectHelper;
|
||||||
import com.android.ide.eclipse.editors.AndroidEditor;
|
import com.android.ide.eclipse.editors.AndroidEditor;
|
||||||
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
|
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
|
||||||
@@ -251,8 +251,8 @@ public class UiClassAttributeNode extends UiTextAttributeNode {
|
|||||||
String javaPackage = getManifestPackage();
|
String javaPackage = getManifestPackage();
|
||||||
|
|
||||||
// build the fully qualified name of the class
|
// build the fully qualified name of the class
|
||||||
String className = AndroidManifestHelper.combinePackageAndClassName(javaPackage,
|
String className = AndroidManifestParser.combinePackageAndClassName(
|
||||||
textValue);
|
javaPackage, textValue);
|
||||||
|
|
||||||
// only test the vilibility for activities.
|
// only test the vilibility for activities.
|
||||||
boolean testVisibility = AndroidConstants.CLASS_ACTIVITY.equals(
|
boolean testVisibility = AndroidConstants.CLASS_ACTIVITY.equals(
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package com.android.ide.eclipse.editors.resources.manager;
|
|||||||
|
|
||||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.common.project.AndroidManifestHelper;
|
import com.android.ide.eclipse.common.project.AndroidManifestParser;
|
||||||
import com.android.ide.eclipse.common.resources.ResourceType;
|
import com.android.ide.eclipse.common.resources.ResourceType;
|
||||||
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
|
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
|
||||||
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
|
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
|
||||||
@@ -28,6 +28,7 @@ import org.eclipse.core.resources.IMarkerDelta;
|
|||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IResourceDelta;
|
import org.eclipse.core.resources.IResourceDelta;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -120,7 +121,14 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi
|
|||||||
if (projectResources != null) {
|
if (projectResources != null) {
|
||||||
// create the classname
|
// create the classname
|
||||||
String className = getRClassName(project);
|
String className = getRClassName(project);
|
||||||
|
if (className == null) {
|
||||||
|
// We need to abort.
|
||||||
|
AdtPlugin.log(IStatus.ERROR,
|
||||||
|
"loadAndParseRClass: failed to find manifest package for project %1$s", //$NON-NLS-1$
|
||||||
|
project.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// create a temporary class loader to load it.
|
// create a temporary class loader to load it.
|
||||||
ProjectClassLoader loader = new ProjectClassLoader(null /* parentClassLoader */,
|
ProjectClassLoader loader = new ProjectClassLoader(null /* parentClassLoader */,
|
||||||
project);
|
project);
|
||||||
@@ -199,13 +207,28 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the class name of the R class, based on the project's manifest's package.
|
||||||
|
*
|
||||||
|
* @return A class name (e.g. "my.app.R") or null if there's no valid package in the manifest.
|
||||||
|
*/
|
||||||
private String getRClassName(IProject project) {
|
private String getRClassName(IProject project) {
|
||||||
// create the classname
|
try {
|
||||||
AndroidManifestHelper manifest = new AndroidManifestHelper(project);
|
IFile manifestFile = AndroidManifestParser.getManifest(project);
|
||||||
String javaPackage = manifest.getPackageName();
|
AndroidManifestParser data = AndroidManifestParser.parseForData(manifestFile);
|
||||||
|
String javaPackage = data.getPackage();
|
||||||
return javaPackage + ".R"; //$NON-NLS-1$
|
return javaPackage + ".R"; //$NON-NLS-1$
|
||||||
|
} catch (CoreException e) {
|
||||||
|
// This will typically happen either because the manifest file is not present
|
||||||
|
// and/or the workspace needs to be refreshed.
|
||||||
|
AdtPlugin.logAndPrintError(e,
|
||||||
|
"Android Resources",
|
||||||
|
"Failed to find the package of the AndroidManifest of project %1$s. Reason: %2$s",
|
||||||
|
project.getName(),
|
||||||
|
e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,10 +222,10 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
null, // default attributes
|
null, // default attributes
|
||||||
1 // target API level
|
1 // target API level
|
||||||
),
|
),
|
||||||
new TypeInfo("Gadget Provider", // UI name
|
new TypeInfo("AppWidget Provider", // UI name
|
||||||
"An XML file that describes a gadget provider.", // tooltip
|
"An XML file that describes a widget provider.", // tooltip
|
||||||
ResourceFolderType.XML, // folder type
|
ResourceFolderType.XML, // folder type
|
||||||
AndroidTargetData.DESCRIPTOR_GADGET_PROVIDER, // root seed
|
AndroidTargetData.DESCRIPTOR_APPWIDGET_PROVIDER, // root seed
|
||||||
null, // default root
|
null, // default root
|
||||||
SdkConstants.NS_RESOURCES, // xmlns
|
SdkConstants.NS_RESOURCES, // xmlns
|
||||||
null, // default attributes
|
null, // default attributes
|
||||||
@@ -1109,7 +1109,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
TypeInfo type = getSelectedType();
|
TypeInfo type = getSelectedType();
|
||||||
|
|
||||||
if (type.getTargetApiLevel() > currentApiLevel) {
|
if (type.getTargetApiLevel() > currentApiLevel) {
|
||||||
error = "The API level of the selected type (e.g. gadget, etc.) is not " +
|
error = "The API level of the selected type (e.g. AppWidget, etc.) is not " +
|
||||||
"compatible with the API level of the project.";
|
"compatible with the API level of the project.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
/** The root document descriptor for preferences. */
|
/** The root document descriptor for preferences. */
|
||||||
private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
|
private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
|
||||||
|
|
||||||
/** The root document descriptor for gadget provider. */
|
/** The root document descriptor for widget provider. */
|
||||||
private DocumentDescriptor mGadgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
|
private DocumentDescriptor mAppWidgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$
|
||||||
|
|
||||||
/** @return the root descriptor for both searchable and preferences. */
|
/** @return the root descriptor for both searchable and preferences. */
|
||||||
public DocumentDescriptor getDescriptor() {
|
public DocumentDescriptor getDescriptor() {
|
||||||
@@ -75,9 +75,9 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
return mPrefDescriptor;
|
return mPrefDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the root descriptor for gadget providers. */
|
/** @return the root descriptor for widget providers. */
|
||||||
public DocumentDescriptor getGadgetDescriptor() {
|
public DocumentDescriptor getAppWidgetDescriptor() {
|
||||||
return mGadgetDescriptor;
|
return mAppWidgetDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDescriptorProvider getSearchableProvider() {
|
public IDescriptorProvider getSearchableProvider() {
|
||||||
@@ -104,14 +104,14 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDescriptorProvider getGadgetProvider() {
|
public IDescriptorProvider getAppWidgetProvider() {
|
||||||
return new IDescriptorProvider() {
|
return new IDescriptorProvider() {
|
||||||
public ElementDescriptor getDescriptor() {
|
public ElementDescriptor getDescriptor() {
|
||||||
return mGadgetDescriptor;
|
return mAppWidgetDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ElementDescriptor[] getRootElementDescriptors() {
|
public ElementDescriptor[] getRootElementDescriptors() {
|
||||||
return mGadgetDescriptor.getChildren();
|
return mAppWidgetDescriptor.getChildren();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -123,13 +123,13 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
* all at once.
|
* all at once.
|
||||||
*
|
*
|
||||||
* @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file
|
* @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file
|
||||||
* @param gadgetStyleMap The map style=>attributes for <gadget-provider> from the attrs.xml file
|
* @param appWidgetStyleMap The map style=>attributes for <appwidget-provider> from the attrs.xml file
|
||||||
* @param prefs The list of non-group preference descriptions
|
* @param prefs The list of non-group preference descriptions
|
||||||
* @param prefGroups The list of preference group descriptions
|
* @param prefGroups The list of preference group descriptions
|
||||||
*/
|
*/
|
||||||
public synchronized void updateDescriptors(
|
public synchronized void updateDescriptors(
|
||||||
Map<String, DeclareStyleableInfo> searchableStyleMap,
|
Map<String, DeclareStyleableInfo> searchableStyleMap,
|
||||||
Map<String, DeclareStyleableInfo> gadgetStyleMap,
|
Map<String, DeclareStyleableInfo> appWidgetStyleMap,
|
||||||
ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
|
ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
|
||||||
|
|
||||||
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
|
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
|
||||||
@@ -137,16 +137,16 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
SdkConstants.NS_RESOURCES);
|
SdkConstants.NS_RESOURCES);
|
||||||
|
|
||||||
ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);
|
ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);
|
||||||
ElementDescriptor gadget = createGadgetProviderInfo(gadgetStyleMap, xmlns);
|
ElementDescriptor appWidget = createAppWidgetProviderInfo(appWidgetStyleMap, xmlns);
|
||||||
ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns);
|
ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns);
|
||||||
ArrayList<ElementDescriptor> list = new ArrayList<ElementDescriptor>();
|
ArrayList<ElementDescriptor> list = new ArrayList<ElementDescriptor>();
|
||||||
if (searchable != null) {
|
if (searchable != null) {
|
||||||
list.add(searchable);
|
list.add(searchable);
|
||||||
mSearchDescriptor.setChildren(new ElementDescriptor[]{ searchable });
|
mSearchDescriptor.setChildren(new ElementDescriptor[]{ searchable });
|
||||||
}
|
}
|
||||||
if (gadget != null) {
|
if (appWidget != null) {
|
||||||
list.add(gadget);
|
list.add(appWidget);
|
||||||
mGadgetDescriptor.setChildren(new ElementDescriptor[]{ gadget });
|
mAppWidgetDescriptor.setChildren(new ElementDescriptor[]{ appWidget });
|
||||||
}
|
}
|
||||||
if (preferences != null) {
|
if (preferences != null) {
|
||||||
list.add(preferences);
|
list.add(preferences);
|
||||||
@@ -190,25 +190,25 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the new ElementDescriptor for <gadget-provider>
|
* Returns the new ElementDescriptor for <appwidget-provider>
|
||||||
*/
|
*/
|
||||||
private ElementDescriptor createGadgetProviderInfo(
|
private ElementDescriptor createAppWidgetProviderInfo(
|
||||||
Map<String, DeclareStyleableInfo> gadgetStyleMap,
|
Map<String, DeclareStyleableInfo> appWidgetStyleMap,
|
||||||
XmlnsAttributeDescriptor xmlns) {
|
XmlnsAttributeDescriptor xmlns) {
|
||||||
|
|
||||||
if (gadgetStyleMap == null) {
|
if (appWidgetStyleMap == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementDescriptor gadget = createElement(gadgetStyleMap,
|
ElementDescriptor appWidget = createElement(appWidgetStyleMap,
|
||||||
"GadgetProviderInfo", //$NON-NLS-1$ styleName
|
"AppWidgetProviderInfo", //$NON-NLS-1$ styleName
|
||||||
"gadget-provider", //$NON-NLS-1$ xmlName
|
"appwidget-provider", //$NON-NLS-1$ xmlName
|
||||||
"Gadget Provider", // uiName
|
"AppWidget Provider", // uiName
|
||||||
null, // sdk url
|
null, // sdk url
|
||||||
xmlns, // extraAttribute
|
xmlns, // extraAttribute
|
||||||
null, // childrenElements
|
null, // childrenElements
|
||||||
false /* mandatory */ );
|
false /* mandatory */ );
|
||||||
return gadget;
|
return appWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,6 +5,6 @@
|
|||||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
|
<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
|
||||||
<classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
|
<classpathentry kind="lib" path="/adt/sdklib.jar" sourcepath="/SdkLib"/>
|
||||||
<classpathentry kind="output" path="bin"/>
|
<classpathentry kind="output" path="bin"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
|
|||||||
@@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2007 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.common.project;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
public class AndroidManifestHelperTest extends TestCase {
|
|
||||||
private File mFile;
|
|
||||||
private AndroidManifestHelper mManifest;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
mFile = File.createTempFile("androidManifest", "xml"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
assertNotNull(mFile);
|
|
||||||
|
|
||||||
FileWriter fw = new FileWriter(mFile);
|
|
||||||
fw.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); //$NON-NLS-1$
|
|
||||||
fw.write("<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" package=\"com.android.testapp\">\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <application android:icon=\"@drawable/icon\">\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <activity android:name=\".MainActivity\" android:label=\"@string/app_name\">\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <intent-filter>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <action android:name=\"android.intent.action.MAIN\" />\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <category android:name=\"android.intent.category.LAUNCHER\" />\"\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <category android:name=\"android.intent.category.DEFAULT\" />\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" </intent-filter>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" </activity>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <activity android:name=\".OptionsActivity\" android:label=\"@string/options\"\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" android:theme=\"@style/Theme.Floating\">\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <intent-filter>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <action android:name=\"com.android.mandelbrot.action.EDIT_OPTIONS\" />\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <category android:name=\"android.intent.category.PREFERENCE_CATEGORY\" />\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" </intent-filter>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" </activity>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <activity android:name=\".InfoActivity\" android:label=\"@string/options\"\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" android:theme=\"@style/Theme.Floating\">\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <intent-filter>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" <action android:name=\"com.android.mandelbrot.action.DISPLAY_INFO\" />\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" </intent-filter>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" </activity>\n"); //$NON-NLS-1$
|
|
||||||
fw.write(" </application>\n"); //$NON-NLS-1$
|
|
||||||
fw.write("</manifest>\n"); //$NON-NLS-1$
|
|
||||||
fw.flush();
|
|
||||||
fw.close();
|
|
||||||
|
|
||||||
mManifest = new AndroidManifestHelper(mFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void tearDown() throws Exception {
|
|
||||||
assertTrue(mFile.delete());
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testExists() {
|
|
||||||
assertTrue(mManifest.exists());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNotExists() throws IOException {
|
|
||||||
File f = File.createTempFile("androidManifest2", "xml"); //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
assertTrue(f.delete());
|
|
||||||
AndroidManifestHelper manifest = new AndroidManifestHelper(f.getAbsolutePath());
|
|
||||||
assertFalse(manifest.exists());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetPackageName() {
|
|
||||||
assertEquals("com.android.testapp", mManifest.getPackageName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testGetActivityName() {
|
|
||||||
assertEquals("", mManifest.getActivityName(0)); //$NON-NLS-1$
|
|
||||||
assertEquals(".MainActivity", mManifest.getActivityName(1)); //$NON-NLS-1$
|
|
||||||
assertEquals(".OptionsActivity", mManifest.getActivityName(2)); //$NON-NLS-1$
|
|
||||||
assertEquals(".InfoActivity", mManifest.getActivityName(3)); //$NON-NLS-1$
|
|
||||||
assertEquals("", mManifest.getActivityName(4)); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2007 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.common.project;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import com.android.ide.eclipse.mock.FileMock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link AndroidManifestParser}
|
||||||
|
*/
|
||||||
|
public class AndroidManifestParserTest extends TestCase {
|
||||||
|
private AndroidManifestParser mManifest;
|
||||||
|
|
||||||
|
private static final String PACKAGE_NAME = "com.android.testapp"; //$NON-NLS-1$
|
||||||
|
private static final String ACTIVITY_NAME = "com.android.testapp.MainActivity"; //$NON-NLS-1$
|
||||||
|
private static final String LIBRARY_NAME = "android.test.runner"; //$NON-NLS-1$
|
||||||
|
private static final String INSTRUMENTATION_NAME = "android.test.InstrumentationTestRunner"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
// create the test data
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); //$NON-NLS-1$
|
||||||
|
sb.append("<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" package=\""); //$NON-NLS-1$
|
||||||
|
sb.append(PACKAGE_NAME);
|
||||||
|
sb.append("\">\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" <application android:icon=\"@drawable/icon\">\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" <activity android:name=\""); //$NON-NLS-1$
|
||||||
|
sb.append(ACTIVITY_NAME);
|
||||||
|
sb.append("\" android:label=\"@string/app_name\">\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" <intent-filter>\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" <action android:name=\"android.intent.action.MAIN\" />\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" <category android:name=\"android.intent.category.LAUNCHER\" />\"\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" <category android:name=\"android.intent.category.DEFAULT\" />\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" </intent-filter>\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" </activity>\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" <uses-library android:name=\""); //$NON-NLS-1$
|
||||||
|
sb.append(LIBRARY_NAME);
|
||||||
|
sb.append("\" />\n"); //$NON-NLS-1$
|
||||||
|
sb.append(" </application>"); //$NON-NLS-1$
|
||||||
|
sb.append(" <instrumentation android:name=\""); //$NON-NLS-1$
|
||||||
|
sb.append(INSTRUMENTATION_NAME);
|
||||||
|
sb.append("\"\n");
|
||||||
|
sb.append(" android:targetPackage=\"com.example.android.apis\"\n");
|
||||||
|
sb.append(" android:label=\"Tests for Api Demos.\"/>\n");
|
||||||
|
sb.append("</manifest>\n"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
FileMock mockFile = new FileMock("AndroidManifest.xml", sb.toString().getBytes());
|
||||||
|
|
||||||
|
mManifest = AndroidManifestParser.parseForData(mockFile);
|
||||||
|
assertNotNull(mManifest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetPackage() {
|
||||||
|
assertEquals("com.android.testapp", mManifest.getPackage());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetActivities() {
|
||||||
|
assertEquals(1, mManifest.getActivities().length);
|
||||||
|
assertEquals(ACTIVITY_NAME, mManifest.getActivities()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetLauncherActivity() {
|
||||||
|
assertEquals(ACTIVITY_NAME, mManifest.getLauncherActivity());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetUsesLibraries() {
|
||||||
|
assertEquals(1, mManifest.getUsesLibraries().length);
|
||||||
|
assertEquals(LIBRARY_NAME, mManifest.getUsesLibraries()[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetInstrumentations() {
|
||||||
|
assertEquals(1, mManifest.getInstrumentations().length);
|
||||||
|
assertEquals(INSTRUMENTATION_NAME, mManifest.getInstrumentations()[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,7 @@ import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
|||||||
|
|
||||||
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
@@ -44,16 +45,28 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Mock implementation of {@link IFile}.
|
* Mock implementation of {@link IFile}.
|
||||||
|
*
|
||||||
|
* Optionally backed by an in-memory byte array
|
||||||
|
*
|
||||||
* <p/>Supported methods:
|
* <p/>Supported methods:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
* <li>getName()</li>
|
||||||
|
* <li>getContents()</li>
|
||||||
|
* <li>getContents(boolean force)</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
public class FileMock implements IFile {
|
public class FileMock implements IFile {
|
||||||
|
|
||||||
private String mName;
|
private String mName;
|
||||||
|
private byte[] mContentData;
|
||||||
|
|
||||||
public FileMock(String name) {
|
public FileMock(String name) {
|
||||||
|
this(name, new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileMock(String name, byte[] fileData) {
|
||||||
mName = name;
|
mName = name;
|
||||||
|
mContentData = fileData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------- MOCKED METHODS ----------------
|
// -------- MOCKED METHODS ----------------
|
||||||
@@ -62,6 +75,15 @@ public class FileMock implements IFile {
|
|||||||
return mName;
|
return mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InputStream getContents() throws CoreException {
|
||||||
|
return new ByteArrayInputStream(mContentData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getContents(boolean force) throws CoreException {
|
||||||
|
// ignore force
|
||||||
|
return getContents();
|
||||||
|
}
|
||||||
|
|
||||||
// -------- UNIMPLEMENTED METHODS ----------------
|
// -------- UNIMPLEMENTED METHODS ----------------
|
||||||
|
|
||||||
public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor)
|
public void appendContents(InputStream source, int updateFlags, IProgressMonitor monitor)
|
||||||
@@ -115,14 +137,6 @@ public class FileMock implements IFile {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getContents() throws CoreException {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public InputStream getContents(boolean force) throws CoreException {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getEncoding() throws CoreException {
|
public int getEncoding() throws CoreException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
@@ -139,7 +153,8 @@ public class FileMock implements IFile {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void move(IPath destination, boolean force, boolean keepHistory, IProgressMonitor monitor)
|
public void move(IPath destination, boolean force, boolean keepHistory,
|
||||||
|
IProgressMonitor monitor)
|
||||||
throws CoreException {
|
throws CoreException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
@@ -229,7 +244,8 @@ public class FileMock implements IFile {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteMarkers(String type, boolean includeSubtypes, int depth) throws CoreException {
|
public void deleteMarkers(String type, boolean includeSubtypes, int depth)
|
||||||
|
throws CoreException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,26 +440,26 @@ public class FileMock implements IFile {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Map getPersistentProperties() throws CoreException {
|
public Map getPersistentProperties() throws CoreException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Map getSessionProperties() throws CoreException {
|
public Map getSessionProperties() throws CoreException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDerived(int options) {
|
public boolean isDerived(int options) {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isHidden() {
|
public boolean isHidden() {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHidden(boolean isHidden) throws CoreException {
|
public void setHidden(boolean isHidden) throws CoreException {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.hierarchyviewer.scene;
|
||||||
|
|
||||||
|
import com.android.ddmlib.Device;
|
||||||
|
import com.android.hierarchyviewer.device.Window;
|
||||||
|
import com.android.hierarchyviewer.device.DeviceBridge;
|
||||||
|
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
public class ProfilesLoader {
|
||||||
|
public static double[] loadProfiles(Device device, Window window, String params) {
|
||||||
|
Socket socket = null;
|
||||||
|
BufferedReader in = null;
|
||||||
|
BufferedWriter out = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
socket = new Socket();
|
||||||
|
socket.connect(new InetSocketAddress("127.0.0.1",
|
||||||
|
DeviceBridge.getDeviceLocalPort(device)));
|
||||||
|
|
||||||
|
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
|
||||||
|
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
|
||||||
|
out.write("PROFILE " + window.encode() + " " + params);
|
||||||
|
out.newLine();
|
||||||
|
out.flush();
|
||||||
|
|
||||||
|
String response = in.readLine();
|
||||||
|
String[] data = response.split(" ");
|
||||||
|
|
||||||
|
double[] profiles = new double[data.length];
|
||||||
|
for (int i = 0; i < data.length; i++) {
|
||||||
|
profiles[i] = (Long.parseLong(data[i]) / 1000.0) / 1000.0; // convert to ms
|
||||||
|
}
|
||||||
|
return profiles;
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Empty
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (out != null) {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
if (in != null) {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
if (socket != null) {
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,6 +27,7 @@ import com.android.hierarchyviewer.scene.ViewHierarchyScene;
|
|||||||
import com.android.hierarchyviewer.scene.ViewManager;
|
import com.android.hierarchyviewer.scene.ViewManager;
|
||||||
import com.android.hierarchyviewer.scene.ViewNode;
|
import com.android.hierarchyviewer.scene.ViewNode;
|
||||||
import com.android.hierarchyviewer.scene.WindowsLoader;
|
import com.android.hierarchyviewer.scene.WindowsLoader;
|
||||||
|
import com.android.hierarchyviewer.scene.ProfilesLoader;
|
||||||
import com.android.hierarchyviewer.util.OS;
|
import com.android.hierarchyviewer.util.OS;
|
||||||
import com.android.hierarchyviewer.util.WorkerThread;
|
import com.android.hierarchyviewer.util.WorkerThread;
|
||||||
import com.android.hierarchyviewer.ui.action.ShowDevicesAction;
|
import com.android.hierarchyviewer.ui.action.ShowDevicesAction;
|
||||||
@@ -43,6 +44,7 @@ import com.android.hierarchyviewer.ui.util.PngFileFilter;
|
|||||||
import com.android.hierarchyviewer.ui.util.IconLoader;
|
import com.android.hierarchyviewer.ui.util.IconLoader;
|
||||||
import com.android.hierarchyviewer.ui.model.PropertiesTableModel;
|
import com.android.hierarchyviewer.ui.model.PropertiesTableModel;
|
||||||
import com.android.hierarchyviewer.ui.model.ViewsTreeModel;
|
import com.android.hierarchyviewer.ui.model.ViewsTreeModel;
|
||||||
|
import com.android.hierarchyviewer.ui.model.ProfilesTableModel;
|
||||||
import org.jdesktop.swingworker.SwingWorker;
|
import org.jdesktop.swingworker.SwingWorker;
|
||||||
import org.netbeans.api.visual.graph.layout.TreeGraphLayout;
|
import org.netbeans.api.visual.graph.layout.TreeGraphLayout;
|
||||||
import org.netbeans.api.visual.model.ObjectSceneEvent;
|
import org.netbeans.api.visual.model.ObjectSceneEvent;
|
||||||
@@ -123,6 +125,7 @@ public class Workspace extends JFrame {
|
|||||||
private JSplitPane sideSplitter;
|
private JSplitPane sideSplitter;
|
||||||
private JSplitPane mainSplitter;
|
private JSplitPane mainSplitter;
|
||||||
private JTable propertiesTable;
|
private JTable propertiesTable;
|
||||||
|
private JTable profilingTable;
|
||||||
private JComponent pixelPerfectPanel;
|
private JComponent pixelPerfectPanel;
|
||||||
private JTree pixelPerfectTree;
|
private JTree pixelPerfectTree;
|
||||||
private ScreenViewer screenViewer;
|
private ScreenViewer screenViewer;
|
||||||
@@ -274,11 +277,32 @@ public class Workspace extends JFrame {
|
|||||||
JScrollPane tableScroller = new JScrollPane(propertiesTable);
|
JScrollPane tableScroller = new JScrollPane(propertiesTable);
|
||||||
tableScroller.setBorder(null);
|
tableScroller.setBorder(null);
|
||||||
|
|
||||||
|
profilingTable = new JTable();
|
||||||
|
profilingTable.setModel(new DefaultTableModel(new Object[][] {
|
||||||
|
{ " " , " " }, { " " , " " }, { " " , " " } },
|
||||||
|
new String[] { "Operation", "Duration (ms)" }));
|
||||||
|
profilingTable.setBorder(null);
|
||||||
|
profilingTable.getTableHeader().setBorder(null);
|
||||||
|
|
||||||
|
JScrollPane firstTableScroller = new JScrollPane(profilingTable);
|
||||||
|
firstTableScroller.setBorder(null);
|
||||||
|
|
||||||
|
setVisibleRowCount(profilingTable, 5);
|
||||||
|
firstTableScroller.setMinimumSize(profilingTable.getPreferredScrollableViewportSize());
|
||||||
|
|
||||||
|
JSplitPane tablesSplitter = new JSplitPane();
|
||||||
|
tablesSplitter.setBorder(null);
|
||||||
|
tablesSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
||||||
|
tablesSplitter.setResizeWeight(0);
|
||||||
|
tablesSplitter.setLeftComponent(firstTableScroller);
|
||||||
|
tablesSplitter.setBottomComponent(tableScroller);
|
||||||
|
tablesSplitter.setContinuousLayout(true);
|
||||||
|
|
||||||
sideSplitter = new JSplitPane();
|
sideSplitter = new JSplitPane();
|
||||||
sideSplitter.setBorder(null);
|
sideSplitter.setBorder(null);
|
||||||
sideSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
sideSplitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
||||||
sideSplitter.setResizeWeight(0.5);
|
sideSplitter.setResizeWeight(0.5);
|
||||||
sideSplitter.setLeftComponent(tableScroller);
|
sideSplitter.setLeftComponent(tablesSplitter);
|
||||||
sideSplitter.setBottomComponent(null);
|
sideSplitter.setBottomComponent(null);
|
||||||
sideSplitter.setContinuousLayout(true);
|
sideSplitter.setContinuousLayout(true);
|
||||||
|
|
||||||
@@ -603,6 +627,22 @@ public class Workspace extends JFrame {
|
|||||||
propertiesTable.setModel(new PropertiesTableModel(node));
|
propertiesTable.setModel(new PropertiesTableModel(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateProfiles(double[] profiles) {
|
||||||
|
profilingTable.setModel(new ProfilesTableModel(profiles));
|
||||||
|
setVisibleRowCount(profilingTable, profiles.length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVisibleRowCount(JTable table, int rows) {
|
||||||
|
int height = 0;
|
||||||
|
for (int row = 0; row < rows; row++) {
|
||||||
|
height += table.getRowHeight(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dimension size = new Dimension(table.getPreferredScrollableViewportSize().width, height);
|
||||||
|
table.setPreferredScrollableViewportSize(size);
|
||||||
|
table.revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
private void showPixelPerfectTree() {
|
private void showPixelPerfectTree() {
|
||||||
if (pixelPerfectTree == null) {
|
if (pixelPerfectTree == null) {
|
||||||
return;
|
return;
|
||||||
@@ -1134,22 +1174,24 @@ public class Workspace extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class LoadGraphTask extends SwingWorker<ViewHierarchyScene, Void> {
|
private class LoadGraphTask extends SwingWorker<double[], Void> {
|
||||||
public LoadGraphTask() {
|
public LoadGraphTask() {
|
||||||
beginTask();
|
beginTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
protected ViewHierarchyScene doInBackground() {
|
protected double[] doInBackground() {
|
||||||
scene = ViewHierarchyLoader.loadScene(currentDevice, currentWindow);
|
scene = ViewHierarchyLoader.loadScene(currentDevice, currentWindow);
|
||||||
return scene;
|
return ProfilesLoader.loadProfiles(currentDevice, currentWindow,
|
||||||
|
scene.getRoot().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
try {
|
try {
|
||||||
createGraph(get());
|
createGraph(scene);
|
||||||
|
updateProfiles(get());
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.hierarchyviewer.ui.model;
|
||||||
|
|
||||||
|
import javax.swing.table.DefaultTableModel;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
|
public class ProfilesTableModel extends DefaultTableModel {
|
||||||
|
private static final String[] NAMES = { "measure", "layout", "draw" };
|
||||||
|
|
||||||
|
private final double[] profiles;
|
||||||
|
private final NumberFormat formatter;
|
||||||
|
|
||||||
|
public ProfilesTableModel(double[] profiles) {
|
||||||
|
this.profiles = profiles;
|
||||||
|
formatter = NumberFormat.getNumberInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return profiles == null ? 0 : profiles.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt(int row, int column) {
|
||||||
|
if (profiles == null) return "";
|
||||||
|
|
||||||
|
if (column == 0) {
|
||||||
|
return NAMES[row];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return formatter.format(profiles[row]) + "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName(int column) {
|
||||||
|
return column == 0 ? "Operation" : "Duration (ms)";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCellEditable(int arg0, int arg1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValueAt(Object arg0, int arg1, int arg2) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -113,7 +113,7 @@ knownTests=(
|
|||||||
|
|
||||||
# system-wide tests
|
# system-wide tests
|
||||||
"framework frameworks/base/tests/FrameworkTest # com.android.frameworktest.AllTests com.android.frameworktest.tests #"
|
"framework frameworks/base/tests/FrameworkTest # com.android.frameworktest.AllTests com.android.frameworktest.tests #"
|
||||||
"android frameworks/base/tests/AndroidTests # AndroidTests com.android.unit_tests #"
|
"android frameworks/base/tests/AndroidTests com.android.unit_tests AndroidTests # #"
|
||||||
"smoke frameworks/base/tests/SmokeTest com.android.smoketest # com.android.smoketest.tests #"
|
"smoke frameworks/base/tests/SmokeTest com.android.smoketest # com.android.smoketest.tests #"
|
||||||
"core frameworks/base/tests/CoreTests # android.core.CoreTests android.core #"
|
"core frameworks/base/tests/CoreTests # android.core.CoreTests android.core #"
|
||||||
"libcore frameworks/base/tests/CoreTests # android.core.JavaTests android.core #"
|
"libcore frameworks/base/tests/CoreTests # android.core.JavaTests android.core #"
|
||||||
|
|||||||
@@ -303,8 +303,11 @@ public final class AvdManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (NUMERIC_SKIN_SIZE.matcher(skinName).matches()) {
|
if (NUMERIC_SKIN_SIZE.matcher(skinName).matches()) {
|
||||||
// Skin name is an actual screen resolution, no skin.path
|
// Skin name is an actual screen resolution.
|
||||||
|
// Set skin.name for display purposes in the AVD manager and
|
||||||
|
// set skin.path for use by the emulator.
|
||||||
values.put(AVD_INI_SKIN_NAME, skinName);
|
values.put(AVD_INI_SKIN_NAME, skinName);
|
||||||
|
values.put(AVD_INI_SKIN_PATH, skinName);
|
||||||
} else {
|
} else {
|
||||||
// get the path of the skin (relative to the SDK)
|
// get the path of the skin (relative to the SDK)
|
||||||
// assume skin name is valid
|
// assume skin name is valid
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ import java.util.Set;
|
|||||||
* The APK Configuration widget is a table that is added to the given parent composite.
|
* The APK Configuration widget is a table that is added to the given parent composite.
|
||||||
* <p/>
|
* <p/>
|
||||||
* To use, create it using {@link #ApkConfigWidget(Composite)} then
|
* To use, create it using {@link #ApkConfigWidget(Composite)} then
|
||||||
* call {@link #fillTable(Map) to set the initial list of configurations.
|
* call {@link #fillTable(Map)} to set the initial list of configurations.
|
||||||
*/
|
*/
|
||||||
public class ApkConfigWidget {
|
public class ApkConfigWidget {
|
||||||
private final static int INDEX_NAME = 0;
|
private final static int INDEX_NAME = 0;
|
||||||
|
|||||||
@@ -36,21 +36,17 @@ import org.eclipse.swt.widgets.Table;
|
|||||||
import org.eclipse.swt.widgets.TableColumn;
|
import org.eclipse.swt.widgets.TableColumn;
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
import org.eclipse.swt.widgets.TableItem;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The AVD selector is a table that is added to the given parent composite.
|
* The AVD selector is a table that is added to the given parent composite.
|
||||||
* <p/>
|
* <p/>
|
||||||
* To use, create it using {@link #AvdSelector(Composite, AvdInfo[], boolean)} then
|
* To use, create it using {@link #AvdSelector(Composite, AvdInfo[])} then
|
||||||
* call {@link #setSelection(AvdInfo)}, {@link #setSelectionListener(SelectionListener)}
|
* call {@link #setSelection(AvdInfo)}, {@link #setSelectionListener(SelectionListener)}
|
||||||
* and finally use {@link #getFirstSelected()} or {@link #getAllSelected()} to retrieve the
|
* and finally use {@link #getFirstSelected()} to retrieve the selection.
|
||||||
* selection.
|
|
||||||
*/
|
*/
|
||||||
public final class AvdSelector {
|
public final class AvdSelector {
|
||||||
|
|
||||||
private AvdInfo[] mAvds;
|
private AvdInfo[] mAvds;
|
||||||
private final boolean mAllowMultipleSelection;
|
|
||||||
private SelectionListener mSelectionListener;
|
private SelectionListener mSelectionListener;
|
||||||
private Table mTable;
|
private Table mTable;
|
||||||
private Label mDescription;
|
private Label mDescription;
|
||||||
@@ -63,11 +59,8 @@ public final class AvdSelector {
|
|||||||
*
|
*
|
||||||
* @param parent The parent composite where the selector will be added.
|
* @param parent The parent composite where the selector will be added.
|
||||||
* @param avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
|
* @param avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
|
||||||
* @param allowMultipleSelection True if more than one SDK target can be selected at the same
|
|
||||||
* time.
|
|
||||||
*/
|
*/
|
||||||
public AvdSelector(Composite parent, AvdInfo[] avds, IAndroidTarget filter,
|
public AvdSelector(Composite parent, AvdInfo[] avds, IAndroidTarget filter) {
|
||||||
boolean allowMultipleSelection) {
|
|
||||||
mAvds = avds;
|
mAvds = avds;
|
||||||
|
|
||||||
// Layout has 1 column
|
// Layout has 1 column
|
||||||
@@ -76,7 +69,6 @@ public final class AvdSelector {
|
|||||||
group.setLayoutData(new GridData(GridData.FILL_BOTH));
|
group.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||||
group.setFont(parent.getFont());
|
group.setFont(parent.getFont());
|
||||||
|
|
||||||
mAllowMultipleSelection = allowMultipleSelection;
|
|
||||||
mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
|
mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
|
||||||
mTable.setHeaderVisible(true);
|
mTable.setHeaderVisible(true);
|
||||||
mTable.setLinesVisible(false);
|
mTable.setLinesVisible(false);
|
||||||
@@ -112,11 +104,9 @@ public final class AvdSelector {
|
|||||||
*
|
*
|
||||||
* @param parent The parent composite where the selector will be added.
|
* @param parent The parent composite where the selector will be added.
|
||||||
* @param avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
|
* @param avds The list of AVDs. This is <em>not</em> copied, the caller must not modify.
|
||||||
* @param allowMultipleSelection True if more than one SDK target can be selected at the same
|
|
||||||
* time.
|
|
||||||
*/
|
*/
|
||||||
public AvdSelector(Composite parent, AvdInfo[] avds, boolean allowMultipleSelection) {
|
public AvdSelector(Composite parent, AvdInfo[] avds) {
|
||||||
this(parent, avds, null /* filter */, allowMultipleSelection);
|
this(parent, avds, null /* filter */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -160,8 +150,7 @@ public final class AvdSelector {
|
|||||||
* The event's item contains a {@link TableItem}.
|
* The event's item contains a {@link TableItem}.
|
||||||
* The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
|
* The {@link TableItem#getData()} contains an {@link IAndroidTarget}.
|
||||||
* <p/>
|
* <p/>
|
||||||
* It is recommended that the caller uses the {@link #getFirstSelected()} and
|
* It is recommended that the caller uses the {@link #getFirstSelected()} method instead.
|
||||||
* {@link #getAllSelected()} methods instead.
|
|
||||||
*
|
*
|
||||||
* @param selectionListener The new listener or null to remove it.
|
* @param selectionListener The new listener or null to remove it.
|
||||||
*/
|
*/
|
||||||
@@ -201,28 +190,10 @@ public final class AvdSelector {
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all selected items.
|
|
||||||
* This is useful when the table is in multiple-selection mode.
|
|
||||||
*
|
|
||||||
* @see #getFirstSelected()
|
|
||||||
* @return An array of selected items. The list can be empty but not null.
|
|
||||||
*/
|
|
||||||
public AvdInfo[] getAllSelected() {
|
|
||||||
ArrayList<IAndroidTarget> list = new ArrayList<IAndroidTarget>();
|
|
||||||
for (TableItem i : mTable.getItems()) {
|
|
||||||
if (i.getChecked()) {
|
|
||||||
list.add((IAndroidTarget) i.getData());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list.toArray(new AvdInfo[list.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first selected item.
|
* Returns the first selected item.
|
||||||
* This is useful when the table is in single-selection mode.
|
* This is useful when the table is in single-selection mode.
|
||||||
*
|
*
|
||||||
* @see #getAllSelected()
|
|
||||||
* @return The first selected item or null.
|
* @return The first selected item or null.
|
||||||
*/
|
*/
|
||||||
public AvdInfo getFirstSelected() {
|
public AvdInfo getFirstSelected() {
|
||||||
@@ -278,20 +249,11 @@ public final class AvdSelector {
|
|||||||
private void setupSelectionListener(final Table table) {
|
private void setupSelectionListener(final Table table) {
|
||||||
// Add a selection listener that will check/uncheck items when they are double-clicked
|
// Add a selection listener that will check/uncheck items when they are double-clicked
|
||||||
table.addSelectionListener(new SelectionListener() {
|
table.addSelectionListener(new SelectionListener() {
|
||||||
/** Default selection means double-click on "most" platforms */
|
|
||||||
public void widgetDefaultSelected(SelectionEvent e) {
|
|
||||||
if (e.item instanceof TableItem) {
|
|
||||||
TableItem i = (TableItem) e.item;
|
|
||||||
i.setChecked(!i.getChecked());
|
|
||||||
enforceSingleSelection(i);
|
|
||||||
updateDescription(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSelectionListener != null) {
|
|
||||||
mSelectionListener.widgetDefaultSelected(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles single-click selection on the table.
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public void widgetSelected(SelectionEvent e) {
|
public void widgetSelected(SelectionEvent e) {
|
||||||
if (e.item instanceof TableItem) {
|
if (e.item instanceof TableItem) {
|
||||||
TableItem i = (TableItem) e.item;
|
TableItem i = (TableItem) e.item;
|
||||||
@@ -305,11 +267,32 @@ public final class AvdSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If we're not in multiple selection mode, uncheck all other
|
* Handles double-click selection on the table.
|
||||||
* items when this one is selected.
|
* Note that the single-click handler will probably already have been called.
|
||||||
|
*
|
||||||
|
* On double-click, <em>always</em> check the table item.
|
||||||
|
*
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void widgetDefaultSelected(SelectionEvent e) {
|
||||||
|
if (e.item instanceof TableItem) {
|
||||||
|
TableItem i = (TableItem) e.item;
|
||||||
|
i.setChecked(true);
|
||||||
|
enforceSingleSelection(i);
|
||||||
|
updateDescription(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSelectionListener != null) {
|
||||||
|
mSelectionListener.widgetDefaultSelected(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To ensure single selection, uncheck all other items when this one is selected.
|
||||||
|
* This makes the chekboxes act as radio buttons.
|
||||||
*/
|
*/
|
||||||
private void enforceSingleSelection(TableItem item) {
|
private void enforceSingleSelection(TableItem item) {
|
||||||
if (!mAllowMultipleSelection && item.getChecked()) {
|
if (item.getChecked()) {
|
||||||
Table parentTable = item.getParent();
|
Table parentTable = item.getParent();
|
||||||
for (TableItem i2 : parentTable.getItems()) {
|
for (TableItem i2 : parentTable.getItems()) {
|
||||||
if (i2 != item && i2.getChecked()) {
|
if (i2 != item && i2.getChecked()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user