auto import from //depot/cupcake/@132589
This commit is contained in:
@@ -1,11 +0,0 @@
|
|||||||
LOCAL_PATH:= $(call my-dir)
|
|
||||||
include $(CLEAR_VARS)
|
|
||||||
|
|
||||||
LOCAL_MODULE_TAGS := user
|
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
|
||||||
|
|
||||||
LOCAL_PACKAGE_NAME := CustomLocale
|
|
||||||
LOCAL_CERTIFICATE := platform
|
|
||||||
|
|
||||||
include $(BUILD_PACKAGE)
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<manifest
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="1.0" package="com.android.customlocale">
|
|
||||||
<application
|
|
||||||
android:icon="@drawable/icon"
|
|
||||||
android:label="@string/app_name">
|
|
||||||
<activity
|
|
||||||
android:label="@string/app_name" android:name="CustomLocaleActivity">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
<activity
|
|
||||||
android:name="NewLocaleDialog"
|
|
||||||
android:theme="@android:style/Theme.Dialog" />
|
|
||||||
</application>
|
|
||||||
<uses-sdk android:minSdkVersion="3" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
|
||||||
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
|
|
||||||
</manifest>
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,35 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="5dip">
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/locale_code"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="?android:textAppearanceLarge"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/locale_default" />
|
|
||||||
<TextView
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/locale_name"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="?android:textAppearance"
|
|
||||||
android:layout_weight="1" />
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:text="@string/header_current_locale"
|
|
||||||
android:textAppearance="@style/TextAppearance.header"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:background="@color/header_background" />
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/current_locale"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:padding="5dip" />
|
|
||||||
<TextView
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:text="@string/header_locale_list"
|
|
||||||
android:textAppearance="@style/TextAppearance.header"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:background="@color/header_background" />
|
|
||||||
<ListView
|
|
||||||
android:id="@id/android:list"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:padding="8dip" />
|
|
||||||
<TextView
|
|
||||||
android:id="@id/android:empty"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:text="@string/no_data_label" />
|
|
||||||
<Button
|
|
||||||
android:id="@+id/new_locale"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="0"
|
|
||||||
android:paddingLeft="8dip"
|
|
||||||
android:paddingRight="8dip"
|
|
||||||
android:text="@string/add_new_locale_button" />
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingLeft="8dip"
|
|
||||||
android:paddingRight="8dip">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="@string/new_locale_label" />
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/value"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="@string/locale_default" android:inputType="text"/>
|
|
||||||
<LinearLayout
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
<Button
|
|
||||||
android:id="@+id/add"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/add_button" android:layout_gravity="center_vertical"/>
|
|
||||||
<Button
|
|
||||||
android:id="@+id/add_and_select"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/add_select_button" android:layout_gravity="center_vertical"/>
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<resources>
|
|
||||||
<string name="app_name">Locales Personalisées</string>
|
|
||||||
<string name="add_new_locale_button">Ajouter une nouvelle locale</string>
|
|
||||||
<string name="new_locale_label">Code de la nouvelle locale:</string>
|
|
||||||
<string name="add_button">Ajouter</string>
|
|
||||||
<string name="no_data_label">Aucune locale</string>
|
|
||||||
<string name="header_current_locale">Locale courrante</string>
|
|
||||||
<string name="header_locale_list">Liste des locales</string>
|
|
||||||
<string name="add_select_button">Ajouter et sélectionner</string>
|
|
||||||
</resources>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<resources>
|
|
||||||
<color name="header_background">#888</color>
|
|
||||||
</resources>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<resources>
|
|
||||||
<string name="app_name">Custom Locale</string>
|
|
||||||
<string name="locale_default">ex_EX</string>
|
|
||||||
<string name="add_new_locale_button">Add New Locale</string>
|
|
||||||
<string name="new_locale_label">New locale code:</string>
|
|
||||||
<string name="add_button">Add</string>
|
|
||||||
<string name="no_data_label">No data</string>
|
|
||||||
<string name="header_current_locale">Current Locale</string>
|
|
||||||
<string name="header_locale_list">Locale List</string>
|
|
||||||
<string name="add_select_button">Add and Select</string>
|
|
||||||
</resources>
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<resources>
|
|
||||||
<style name="TextAppearance"
|
|
||||||
parent="android:TextAppearance" />
|
|
||||||
|
|
||||||
<style name="TextAppearance.header">
|
|
||||||
<item name="android:textSize">14sp</item>
|
|
||||||
<item name="android:textStyle">bold</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
</resources>
|
|
||||||
@@ -1,326 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.customlocale;
|
|
||||||
|
|
||||||
|
|
||||||
import android.app.ActivityManagerNative;
|
|
||||||
import android.app.IActivityManager;
|
|
||||||
import android.app.ListActivity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.ContextMenu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ListAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.SimpleAdapter;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the list of system locales as well as maintain a custom list of user
|
|
||||||
* locales. The user can select a locale and apply it or it can create or remove
|
|
||||||
* a custom locale.
|
|
||||||
*/
|
|
||||||
public class CustomLocaleActivity extends ListActivity {
|
|
||||||
|
|
||||||
private static final String CUSTOM_LOCALES_SEP = " ";
|
|
||||||
private static final String CUSTOM_LOCALES = "custom_locales";
|
|
||||||
private static final String KEY_CUSTOM = "custom";
|
|
||||||
private static final String KEY_NAME = "name";
|
|
||||||
private static final String KEY_CODE = "code";
|
|
||||||
|
|
||||||
private static final String TAG = "LocaleSetup";
|
|
||||||
private static final boolean DEBUG = true;
|
|
||||||
|
|
||||||
/** Request code returned when the NewLocaleDialog activity finishes. */
|
|
||||||
private static final int UPDATE_LIST = 42;
|
|
||||||
/** Menu item id for applying a locale */
|
|
||||||
private static final int MENU_APPLY = 43;
|
|
||||||
/** Menu item id for removing a custom locale */
|
|
||||||
private static final int MENU_REMOVE = 44;
|
|
||||||
|
|
||||||
/** List view displaying system and custom locales. */
|
|
||||||
private ListView mListView;
|
|
||||||
/** Textview used to display current locale */
|
|
||||||
private TextView mCurrentLocaleTextView;
|
|
||||||
/** Private shared preferences of this activity. */
|
|
||||||
private SharedPreferences mPrefs;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.main);
|
|
||||||
|
|
||||||
mPrefs = getPreferences(MODE_PRIVATE);
|
|
||||||
|
|
||||||
Button newLocaleButton = (Button) findViewById(R.id.new_locale);
|
|
||||||
|
|
||||||
newLocaleButton.setOnClickListener(new View.OnClickListener() {
|
|
||||||
public void onClick(View v) {
|
|
||||||
Intent i = new Intent(CustomLocaleActivity.this, NewLocaleDialog.class);
|
|
||||||
startActivityForResult(i, UPDATE_LIST);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mListView = (ListView) findViewById(android.R.id.list);
|
|
||||||
mListView.setFocusable(true);
|
|
||||||
mListView.setFocusableInTouchMode(true);
|
|
||||||
mListView.requestFocus();
|
|
||||||
registerForContextMenu(mListView);
|
|
||||||
setupLocaleList();
|
|
||||||
|
|
||||||
mCurrentLocaleTextView = (TextView) findViewById(R.id.current_locale);
|
|
||||||
displayCurrentLocale();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
|
|
||||||
if (requestCode == UPDATE_LIST && resultCode == RESULT_OK && data != null) {
|
|
||||||
String locale = data.getExtras().getString(NewLocaleDialog.INTENT_EXTRA_LOCALE);
|
|
||||||
if (locale != null && locale.length() > 0) {
|
|
||||||
// Get current custom locale list
|
|
||||||
String customLocales = mPrefs.getString(CUSTOM_LOCALES, null);
|
|
||||||
|
|
||||||
// Update
|
|
||||||
if (customLocales == null) {
|
|
||||||
customLocales = locale;
|
|
||||||
} else {
|
|
||||||
customLocales += CUSTOM_LOCALES_SEP + locale;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save prefs
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "add/customLocales: " + customLocales);
|
|
||||||
}
|
|
||||||
mPrefs.edit().putString(CUSTOM_LOCALES, customLocales).commit();
|
|
||||||
|
|
||||||
Toast.makeText(this, "Added custom locale: " + locale, Toast.LENGTH_SHORT).show();
|
|
||||||
|
|
||||||
// Update list view
|
|
||||||
setupLocaleList();
|
|
||||||
|
|
||||||
// Find the item to select it in the list view
|
|
||||||
ListAdapter a = mListView.getAdapter();
|
|
||||||
for (int i = 0; i < a.getCount(); i++) {
|
|
||||||
Object o = a.getItem(i);
|
|
||||||
if (o instanceof Map<?, ?>) {
|
|
||||||
String code = ((Map<String, String>) o).get(KEY_CODE);
|
|
||||||
if (code != null && code.equals(locale)) {
|
|
||||||
mListView.setSelection(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.getExtras().getBoolean(NewLocaleDialog.INTENT_EXTRA_SELECT)) {
|
|
||||||
selectLocale(locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupLocaleList() {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Update locate list");
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Map<String, String>> data = new ArrayList<Map<String, String>>();
|
|
||||||
|
|
||||||
// Insert all system locales
|
|
||||||
String[] locales = getAssets().getLocales();
|
|
||||||
for (String locale : locales) {
|
|
||||||
Locale loc = new Locale(locale);
|
|
||||||
|
|
||||||
Map<String, String> map = new HashMap<String, String>(1);
|
|
||||||
map.put(KEY_CODE, locale);
|
|
||||||
map.put(KEY_NAME, loc.getDisplayName());
|
|
||||||
data.add(map);
|
|
||||||
}
|
|
||||||
locales = null;
|
|
||||||
|
|
||||||
// Insert all custom locales
|
|
||||||
String customLocales = mPrefs.getString(CUSTOM_LOCALES, "");
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "customLocales: " + customLocales);
|
|
||||||
}
|
|
||||||
for (String locale : customLocales.split(CUSTOM_LOCALES_SEP)) {
|
|
||||||
if (locale != null && locale.length() > 0) {
|
|
||||||
Locale loc = new Locale(locale);
|
|
||||||
|
|
||||||
Map<String, String> map = new HashMap<String, String>(1);
|
|
||||||
map.put(KEY_CODE, locale);
|
|
||||||
map.put(KEY_NAME, loc.getDisplayName() + " [Custom]");
|
|
||||||
// the presence of the "custom" key marks it as custom.
|
|
||||||
map.put(KEY_CUSTOM, "");
|
|
||||||
data.add(map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort all locales by code
|
|
||||||
Collections.sort(data, new Comparator<Map<String, String>>() {
|
|
||||||
public int compare(Map<String, String> lhs, Map<String, String> rhs) {
|
|
||||||
return lhs.get(KEY_CODE).compareTo(rhs.get(KEY_CODE));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the list view adapter
|
|
||||||
mListView.setAdapter(new SimpleAdapter(this, data, R.layout.list_item, new String[] {
|
|
||||||
KEY_CODE, KEY_NAME}, new int[] {R.id.locale_code, R.id.locale_name}));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
|
||||||
|
|
||||||
if (menuInfo instanceof AdapterContextMenuInfo) {
|
|
||||||
int position = ((AdapterContextMenuInfo) menuInfo).position;
|
|
||||||
Object o = mListView.getItemAtPosition(position);
|
|
||||||
if (o instanceof Map<?, ?>) {
|
|
||||||
String locale = ((Map<String, String>) o).get(KEY_CODE);
|
|
||||||
String custom = ((Map<String, String>) o).get(KEY_CUSTOM);
|
|
||||||
|
|
||||||
if (custom == null) {
|
|
||||||
menu.setHeaderTitle("System Locale");
|
|
||||||
menu.add(0, MENU_APPLY, 0, "Apply");
|
|
||||||
} else {
|
|
||||||
menu.setHeaderTitle("Custom Locale");
|
|
||||||
menu.add(0, MENU_APPLY, 0, "Apply");
|
|
||||||
menu.add(0, MENU_REMOVE, 0, "Remove");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public boolean onContextItemSelected(MenuItem item) {
|
|
||||||
|
|
||||||
String pendingLocale = null;
|
|
||||||
boolean is_custom = false;
|
|
||||||
|
|
||||||
ContextMenuInfo menuInfo = item.getMenuInfo();
|
|
||||||
if (menuInfo instanceof AdapterContextMenuInfo) {
|
|
||||||
int position = ((AdapterContextMenuInfo) menuInfo).position;
|
|
||||||
Object o = mListView.getItemAtPosition(position);
|
|
||||||
if (o instanceof Map<?, ?>) {
|
|
||||||
pendingLocale = ((Map<String, String>) o).get(KEY_CODE);
|
|
||||||
is_custom = ((Map<String, String>) o).get(KEY_CUSTOM) != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pendingLocale == null) {
|
|
||||||
// should never happen
|
|
||||||
return super.onContextItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.getItemId() == MENU_REMOVE) {
|
|
||||||
// Get current custom locale list
|
|
||||||
String customLocales = mPrefs.getString(CUSTOM_LOCALES, "");
|
|
||||||
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Remove " + pendingLocale + " from custom locales: " + customLocales);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (String locale : customLocales.split(CUSTOM_LOCALES_SEP)) {
|
|
||||||
if (locale != null && locale.length() > 0 && !locale.equals(pendingLocale)) {
|
|
||||||
if (sb.length() > 0) {
|
|
||||||
sb.append(CUSTOM_LOCALES_SEP);
|
|
||||||
}
|
|
||||||
sb.append(locale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String newLocales = sb.toString();
|
|
||||||
if (!newLocales.equals(customLocales)) {
|
|
||||||
// Save prefs
|
|
||||||
mPrefs.edit().putString(CUSTOM_LOCALES, customLocales).commit();
|
|
||||||
|
|
||||||
Toast.makeText(this, "Removed custom locale: " + pendingLocale, Toast.LENGTH_SHORT)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (item.getItemId() == MENU_APPLY) {
|
|
||||||
selectLocale(pendingLocale);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onContextItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectLocale(String locale) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "Select locale " + locale);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
IActivityManager am = ActivityManagerNative.getDefault();
|
|
||||||
Configuration config = am.getConfiguration();
|
|
||||||
|
|
||||||
Locale loc = new Locale(locale);
|
|
||||||
config.locale = loc;
|
|
||||||
|
|
||||||
// indicate this isn't some passing default - the user wants this
|
|
||||||
// remembered
|
|
||||||
config.userSetLocale = true;
|
|
||||||
|
|
||||||
am.updateConfiguration(config);
|
|
||||||
|
|
||||||
Toast.makeText(this, "Select locale: " + locale, Toast.LENGTH_SHORT).show();
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.e(TAG, "Select locale failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void displayCurrentLocale() {
|
|
||||||
try {
|
|
||||||
IActivityManager am = ActivityManagerNative.getDefault();
|
|
||||||
Configuration config = am.getConfiguration();
|
|
||||||
|
|
||||||
if (config.locale != null) {
|
|
||||||
String text = String.format("%s - %s",
|
|
||||||
config.locale.toString(),
|
|
||||||
config.locale.getDisplayName());
|
|
||||||
mCurrentLocaleTextView.setText(text);
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.e(TAG, "get current locale failed", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.customlocale;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dialog to ask the user for a new locale. <p/> Returns the locale code (e.g.
|
|
||||||
* "en_US") via an intent with a "locale" extra string and a "select" extra
|
|
||||||
* boolean.
|
|
||||||
*/
|
|
||||||
public class NewLocaleDialog extends Activity
|
|
||||||
implements View.OnClickListener, View.OnKeyListener {
|
|
||||||
|
|
||||||
public static final String INTENT_EXTRA_LOCALE = "locale";
|
|
||||||
public static final String INTENT_EXTRA_SELECT = "select";
|
|
||||||
|
|
||||||
private static final String TAG = "NewLocale";
|
|
||||||
private static final boolean DEBUG = true;
|
|
||||||
private Button mButtonAdd;
|
|
||||||
private Button mButtonAddSelect;
|
|
||||||
private EditText mEditText;
|
|
||||||
private boolean mWasEmpty;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
setContentView(R.layout.new_locale);
|
|
||||||
|
|
||||||
mEditText = (EditText) findViewById(R.id.value);
|
|
||||||
mWasEmpty = true;
|
|
||||||
|
|
||||||
mButtonAdd = (Button) findViewById(R.id.add);
|
|
||||||
mButtonAdd.setOnClickListener(this);
|
|
||||||
mButtonAdd.setEnabled(false);
|
|
||||||
|
|
||||||
mButtonAddSelect = (Button) findViewById(R.id.add_and_select);
|
|
||||||
mButtonAddSelect.setOnClickListener(this);
|
|
||||||
mButtonAddSelect.setEnabled(false);
|
|
||||||
|
|
||||||
mEditText.setOnKeyListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClick(View v) {
|
|
||||||
String locale = mEditText.getText().toString();
|
|
||||||
boolean select = v == mButtonAddSelect;
|
|
||||||
|
|
||||||
if (DEBUG) {
|
|
||||||
Log.d(TAG, "New Locale: " + locale + (select ? " + select" : ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent data = new Intent(NewLocaleDialog.this, NewLocaleDialog.class);
|
|
||||||
data.putExtra(INTENT_EXTRA_LOCALE, locale);
|
|
||||||
data.putExtra(INTENT_EXTRA_SELECT, select);
|
|
||||||
setResult(RESULT_OK, data);
|
|
||||||
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
|
||||||
boolean isEmpty = TextUtils.isEmpty(mEditText.getText());
|
|
||||||
if (isEmpty != mWasEmpty) {
|
|
||||||
mWasEmpty = isEmpty;
|
|
||||||
|
|
||||||
mButtonAdd.setEnabled(!isEmpty);
|
|
||||||
mButtonAddSelect.setEnabled(!isEmpty);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
LOCAL_PATH:= $(call my-dir)
|
LOCAL_PATH:= $(call my-dir)
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_MODULE_TAGS := user
|
LOCAL_MODULE_TAGS := foo
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,6 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_label">Spare Parts</string>
|
<string name="app_label">Spare Parts</string>
|
||||||
|
|
||||||
<string name="device_info_title">Device info</string>
|
|
||||||
|
|
||||||
<string name="title_battery_history">Battery history</string>
|
|
||||||
<string name="summary_battery_history">Summary of how battery has been used</string>
|
|
||||||
|
|
||||||
<string name="title_battery_information">Battery information</string>
|
|
||||||
<string name="summary_battery_information">Current battery status information</string>
|
|
||||||
|
|
||||||
<string name="title_usage_statistics">Usage statistics</string>
|
|
||||||
<string name="summary_usage_statistics">Summary of application usage</string>
|
|
||||||
|
|
||||||
<string name="general_title">General</string>
|
<string name="general_title">General</string>
|
||||||
|
|
||||||
<string name="title_window_animations">Window animations</string>
|
<string name="title_window_animations">Window animations</string>
|
||||||
@@ -59,7 +48,7 @@
|
|||||||
|
|
||||||
<string name="title_accelerometer">Display rotation</string>
|
<string name="title_accelerometer">Display rotation</string>
|
||||||
<string name="summary_on_accelerometer">Display rotates from orientation</string>
|
<string name="summary_on_accelerometer">Display rotates from orientation</string>
|
||||||
<string name="summary_off_accelerometer">Display rotates from orientation</string>
|
<string name="summary_off_accelerometer">Display rotates when lid is open</string>
|
||||||
|
|
||||||
<string name="applications_title">Applications</string>
|
<string name="applications_title">Applications</string>
|
||||||
|
|
||||||
|
|||||||
@@ -18,35 +18,6 @@
|
|||||||
-->
|
-->
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<PreferenceCategory
|
|
||||||
android:title="@string/device_info_title">
|
|
||||||
|
|
||||||
<PreferenceScreen android:key="battery_history_settings"
|
|
||||||
android:title="@string/title_battery_history"
|
|
||||||
android:summary="@string/summary_battery_history">
|
|
||||||
<intent android:action="android.intent.action.MAIN"
|
|
||||||
android:targetPackage="com.android.settings"
|
|
||||||
android:targetClass="com.android.settings.battery_history.BatteryHistory" />
|
|
||||||
</PreferenceScreen>
|
|
||||||
|
|
||||||
<PreferenceScreen android:key="battery_information_settings"
|
|
||||||
android:title="@string/title_battery_information"
|
|
||||||
android:summary="@string/summary_battery_information">
|
|
||||||
<intent android:action="android.intent.action.MAIN"
|
|
||||||
android:targetPackage="com.android.settings"
|
|
||||||
android:targetClass="com.android.settings.BatteryInfo" />
|
|
||||||
</PreferenceScreen>
|
|
||||||
|
|
||||||
<PreferenceScreen android:key="usage_statistics_settings"
|
|
||||||
android:title="@string/title_usage_statistics"
|
|
||||||
android:summary="@string/summary_usage_statistics">
|
|
||||||
<intent android:action="android.intent.action.MAIN"
|
|
||||||
android:targetPackage="com.android.settings"
|
|
||||||
android:targetClass="com.android.settings.UsageStats" />
|
|
||||||
</PreferenceScreen>
|
|
||||||
|
|
||||||
</PreferenceCategory>
|
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/general_title">
|
android:title="@string/general_title">
|
||||||
|
|
||||||
|
|||||||
@@ -19,11 +19,7 @@ package com.android.spare_parts;
|
|||||||
|
|
||||||
import android.app.ActivityManagerNative;
|
import android.app.ActivityManagerNative;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.ApplicationInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
@@ -32,7 +28,6 @@ import android.preference.CheckBoxPreference;
|
|||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.preference.PreferenceGroup;
|
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.SettingNotFoundException;
|
import android.provider.Settings.SettingNotFoundException;
|
||||||
@@ -40,17 +35,11 @@ import android.os.Bundle;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.IWindowManager;
|
import android.view.IWindowManager;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SpareParts extends PreferenceActivity
|
public class SpareParts extends PreferenceActivity
|
||||||
implements Preference.OnPreferenceChangeListener,
|
implements Preference.OnPreferenceChangeListener,
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
private static final String TAG = "SpareParts";
|
private static final String TAG = "SpareParts";
|
||||||
|
|
||||||
private static final String BATTERY_HISTORY_PREF = "battery_history_settings";
|
|
||||||
private static final String BATTERY_INFORMATION_PREF = "battery_information_settings";
|
|
||||||
private static final String USAGE_STATISTICS_PREF = "usage_statistics_settings";
|
|
||||||
|
|
||||||
private static final String WINDOW_ANIMATIONS_PREF = "window_animations";
|
private static final String WINDOW_ANIMATIONS_PREF = "window_animations";
|
||||||
private static final String TRANSITION_ANIMATIONS_PREF = "transition_animations";
|
private static final String TRANSITION_ANIMATIONS_PREF = "transition_animations";
|
||||||
private static final String FANCY_IME_ANIMATIONS_PREF = "fancy_ime_animations";
|
private static final String FANCY_IME_ANIMATIONS_PREF = "fancy_ime_animations";
|
||||||
@@ -73,41 +62,6 @@ public class SpareParts extends PreferenceActivity
|
|||||||
|
|
||||||
private IWindowManager mWindowManager;
|
private IWindowManager mWindowManager;
|
||||||
|
|
||||||
public static boolean updatePreferenceToSpecificActivityOrRemove(Context context,
|
|
||||||
PreferenceGroup parentPreferenceGroup, String preferenceKey, int flags) {
|
|
||||||
|
|
||||||
Preference preference = parentPreferenceGroup.findPreference(preferenceKey);
|
|
||||||
if (preference == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent intent = preference.getIntent();
|
|
||||||
if (intent != null) {
|
|
||||||
// Find the activity that is in the system image
|
|
||||||
PackageManager pm = context.getPackageManager();
|
|
||||||
List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
|
|
||||||
int listSize = list.size();
|
|
||||||
for (int i = 0; i < listSize; i++) {
|
|
||||||
ResolveInfo resolveInfo = list.get(i);
|
|
||||||
if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
|
|
||||||
!= 0) {
|
|
||||||
|
|
||||||
// Replace the intent with this specific activity
|
|
||||||
preference.setIntent(new Intent().setClassName(
|
|
||||||
resolveInfo.activityInfo.packageName,
|
|
||||||
resolveInfo.activityInfo.name));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Did not find a matching activity, so remove the preference
|
|
||||||
parentPreferenceGroup.removePreference(preference);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
super.onCreate(icicle);
|
super.onCreate(icicle);
|
||||||
@@ -130,15 +84,7 @@ public class SpareParts extends PreferenceActivity
|
|||||||
|
|
||||||
mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
|
mWindowManager = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
|
||||||
|
|
||||||
final PreferenceGroup parentPreference = getPreferenceScreen();
|
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||||
updatePreferenceToSpecificActivityOrRemove(this, parentPreference,
|
|
||||||
BATTERY_HISTORY_PREF, 0);
|
|
||||||
updatePreferenceToSpecificActivityOrRemove(this, parentPreference,
|
|
||||||
BATTERY_INFORMATION_PREF, 0);
|
|
||||||
updatePreferenceToSpecificActivityOrRemove(this, parentPreference,
|
|
||||||
USAGE_STATISTICS_PREF, 0);
|
|
||||||
|
|
||||||
parentPreference.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateToggles() {
|
private void updateToggles() {
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ development/samples/NotePad platforms/${PLATFORM_NAME}/samples/NotePad
|
|||||||
development/samples/ApiDemos platforms/${PLATFORM_NAME}/samples/ApiDemos
|
development/samples/ApiDemos platforms/${PLATFORM_NAME}/samples/ApiDemos
|
||||||
development/samples/SkeletonApp platforms/${PLATFORM_NAME}/samples/SkeletonApp
|
development/samples/SkeletonApp platforms/${PLATFORM_NAME}/samples/SkeletonApp
|
||||||
development/samples/Snake platforms/${PLATFORM_NAME}/samples/Snake
|
development/samples/Snake platforms/${PLATFORM_NAME}/samples/Snake
|
||||||
development/samples/SoftKeyboard platforms/${PLATFORM_NAME}/samples/SoftKeyboard
|
|
||||||
|
|
||||||
# dx
|
# dx
|
||||||
bin/dx platforms/${PLATFORM_NAME}/tools/dx
|
bin/dx platforms/${PLATFORM_NAME}/tools/dx
|
||||||
|
|||||||
@@ -146,11 +146,6 @@ function package() {
|
|||||||
echo "Done"
|
echo "Done"
|
||||||
echo
|
echo
|
||||||
echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
|
echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
|
||||||
|
|
||||||
# We want fastboot and adb next to the new SDK
|
|
||||||
for i in fastboot.exe adb.exe AdbWinApi.dll; do
|
|
||||||
mv -vf out/host/windows-x86/bin/$i "$DIST_DIR"/$i
|
|
||||||
done
|
|
||||||
}
|
}
|
||||||
|
|
||||||
check
|
check
|
||||||
|
|||||||
19
pdk/docs/templates/footer.cs
vendored
19
pdk/docs/templates/footer.cs
vendored
@@ -1,19 +0,0 @@
|
|||||||
<div id="footer">
|
|
||||||
|
|
||||||
<?cs if:reference||guide ?>
|
|
||||||
<div id="copyright">
|
|
||||||
<?cs call:custom_copyright() ?>
|
|
||||||
</div>
|
|
||||||
<div id="build_info">
|
|
||||||
<?cs call:custom_buildinfo() ?>
|
|
||||||
</div>
|
|
||||||
<?cs elif:!hide_license_footer ?>
|
|
||||||
<div id="copyright">
|
|
||||||
<?cs call:custom_cc_copyright() ?>
|
|
||||||
</div>
|
|
||||||
<?cs /if ?>
|
|
||||||
<div id="footerlinks">
|
|
||||||
<?cs call:custom_footerlinks() ?>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div> <!-- end footer -->
|
|
||||||
37
pdk/docs/templates/head_tag.cs
vendored
37
pdk/docs/templates/head_tag.cs
vendored
@@ -1,37 +0,0 @@
|
|||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="<?cs var:toroot ?>favicon.ico" />
|
|
||||||
<title><?cs
|
|
||||||
if:page.title ?><?cs
|
|
||||||
var:page.title ?><?cs
|
|
||||||
if:sdk.version ?> (<?cs
|
|
||||||
var:sdk.version ?>)<?cs
|
|
||||||
/if ?> | <?cs
|
|
||||||
/if ?>Android Developers</title><?cs
|
|
||||||
if:guide||sdk ?>
|
|
||||||
<link href="<?cs var:toroot ?>assets/android-developer-docs-devguide.css" rel="stylesheet" type="text/css" /><?cs
|
|
||||||
else ?>
|
|
||||||
<link href="<?cs var:toroot ?>assets/android-developer-docs.css" rel="stylesheet" type="text/css" /><?cs
|
|
||||||
/if ?>
|
|
||||||
<script src="<?cs var:toroot ?>assets/search_autocomplete.js" type="text/javascript"></script>
|
|
||||||
<script src="<?cs var:toroot ?>reference/lists.js" type="text/javascript"></script>
|
|
||||||
<script src="<?cs var:toroot ?>assets/jquery-resizable.min.js" type="text/javascript"></script>
|
|
||||||
<script src="<?cs var:toroot ?>assets/android-developer-docs.js" type="text/javascript"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
setToRoot("<?cs var:toroot ?>");
|
|
||||||
</script><?cs
|
|
||||||
if:reference ?>
|
|
||||||
<script src="<?cs var:toroot ?>navtree_data.js" type="text/javascript"></script>
|
|
||||||
<script src="<?cs var:toroot ?>assets/navtree.js" type="text/javascript"></script><?cs
|
|
||||||
/if ?>
|
|
||||||
<noscript>
|
|
||||||
<style type="text/css">
|
|
||||||
body{overflow:auto;}
|
|
||||||
#body-content{position:relative; top:0;}
|
|
||||||
#doc-content{overflow:visible;border-left:3px solid #666;}
|
|
||||||
#side-nav{padding:0;}
|
|
||||||
#side-nav .toggle-list ul {display:block;}
|
|
||||||
#resize-packages-nav{border-bottom:3px solid #666;}
|
|
||||||
</style>
|
|
||||||
</noscript>
|
|
||||||
</head>
|
|
||||||
3
pdk/docs/templates/header.cs
vendored
3
pdk/docs/templates/header.cs
vendored
@@ -1,3 +0,0 @@
|
|||||||
<?cs call:custom_masthead() ?>
|
|
||||||
<?cs call:custom_left_nav() ?>
|
|
||||||
|
|
||||||
8
pdk/docs/templates/index.cs
vendored
8
pdk/docs/templates/index.cs
vendored
@@ -1,8 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="refresh" content="0;url=packages.html">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<?cs include:"analytics.cs" ?>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
11
pdk/docs/templates/trailer.cs
vendored
11
pdk/docs/templates/trailer.cs
vendored
@@ -1,11 +0,0 @@
|
|||||||
</div> <!-- end body-content --> <?cs # normally opened by header.cs ?>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
init(); /* initialize android-developer-docs.js */
|
|
||||||
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
|
||||||
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
|
||||||
</script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
var pageTracker = _gat._getTracker("UA-5831155-1");
|
|
||||||
pageTracker._trackPageview();
|
|
||||||
</script>
|
|
||||||
@@ -105,7 +105,7 @@ public class ApplicationsStackLayout extends ViewGroup implements View.OnClickLi
|
|||||||
|
|
||||||
a.recycle();
|
a.recycle();
|
||||||
|
|
||||||
mIconSize = 42; //(int) getResources().getDimension(android.R.dimen.app_icon_size);
|
mIconSize = (int) getResources().getDimension(android.R.dimen.app_icon_size);
|
||||||
|
|
||||||
initLayout();
|
initLayout();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,26 +21,28 @@ import android.app.ActivityManager;
|
|||||||
import android.app.SearchManager;
|
import android.app.SearchManager;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.database.ContentObserver;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.PaintFlagsDrawFilter;
|
import android.graphics.PaintFlagsDrawFilter;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.ColorFilter;
|
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.PaintDrawable;
|
import android.graphics.drawable.PaintDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Xml;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -55,19 +57,14 @@ import android.widget.ArrayAdapter;
|
|||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.GridView;
|
import android.widget.GridView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
|
||||||
|
|
||||||
public class Home extends Activity {
|
public class Home extends Activity {
|
||||||
/**
|
/**
|
||||||
* Tag used for logging errors.
|
* Tag used for logging errors.
|
||||||
@@ -79,13 +76,6 @@ public class Home extends Activity {
|
|||||||
*/
|
*/
|
||||||
private static final String KEY_SAVE_GRID_OPENED = "grid.opened";
|
private static final String KEY_SAVE_GRID_OPENED = "grid.opened";
|
||||||
|
|
||||||
private static final String DEFAULT_FAVORITES_PATH = "etc/favorites.xml";
|
|
||||||
|
|
||||||
private static final String TAG_FAVORITES = "favorites";
|
|
||||||
private static final String TAG_FAVORITE = "favorite";
|
|
||||||
private static final String TAG_PACKAGE = "package";
|
|
||||||
private static final String TAG_CLASS = "class";
|
|
||||||
|
|
||||||
// Identifiers for option menu items
|
// Identifiers for option menu items
|
||||||
private static final int MENU_WALLPAPER_SETTINGS = Menu.FIRST + 1;
|
private static final int MENU_WALLPAPER_SETTINGS = Menu.FIRST + 1;
|
||||||
private static final int MENU_SEARCH = MENU_WALLPAPER_SETTINGS + 1;
|
private static final int MENU_SEARCH = MENU_WALLPAPER_SETTINGS + 1;
|
||||||
@@ -100,8 +90,11 @@ public class Home extends Activity {
|
|||||||
private static ArrayList<ApplicationInfo> mApplications;
|
private static ArrayList<ApplicationInfo> mApplications;
|
||||||
private static LinkedList<ApplicationInfo> mFavorites;
|
private static LinkedList<ApplicationInfo> mFavorites;
|
||||||
|
|
||||||
|
private Handler mHandler = new Handler();
|
||||||
|
|
||||||
private final BroadcastReceiver mWallpaperReceiver = new WallpaperIntentReceiver();
|
private final BroadcastReceiver mWallpaperReceiver = new WallpaperIntentReceiver();
|
||||||
private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
|
private final BroadcastReceiver mApplicationsReceiver = new ApplicationsIntentReceiver();
|
||||||
|
private final ContentObserver mObserver = new FavoritesChangeObserver();
|
||||||
|
|
||||||
private GridView mGrid;
|
private GridView mGrid;
|
||||||
|
|
||||||
@@ -127,6 +120,7 @@ public class Home extends Activity {
|
|||||||
setContentView(R.layout.home);
|
setContentView(R.layout.home);
|
||||||
|
|
||||||
registerIntentReceivers();
|
registerIntentReceivers();
|
||||||
|
registerContentObservers();
|
||||||
|
|
||||||
setDefaultWallpaper();
|
setDefaultWallpaper();
|
||||||
|
|
||||||
@@ -162,6 +156,7 @@ public class Home extends Activity {
|
|||||||
mApplications.get(i).icon.setCallback(null);
|
mApplications.get(i).icon.setCallback(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getContentResolver().unregisterContentObserver(mObserver);
|
||||||
unregisterReceiver(mWallpaperReceiver);
|
unregisterReceiver(mWallpaperReceiver);
|
||||||
unregisterReceiver(mApplicationsReceiver);
|
unregisterReceiver(mApplicationsReceiver);
|
||||||
}
|
}
|
||||||
@@ -203,6 +198,16 @@ public class Home extends Activity {
|
|||||||
registerReceiver(mApplicationsReceiver, filter);
|
registerReceiver(mApplicationsReceiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers various content observers. The current implementation registers
|
||||||
|
* only a favorites observer to keep track of the favorites applications.
|
||||||
|
*/
|
||||||
|
private void registerContentObservers() {
|
||||||
|
ContentResolver resolver = getContentResolver();
|
||||||
|
resolver.registerContentObserver(Uri.parse("content://" +
|
||||||
|
android.provider.Settings.AUTHORITY + "/favorites?notify=true"), true, mObserver);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new appplications adapter for the grid view and registers it.
|
* Creates a new appplications adapter for the grid view and registers it.
|
||||||
*/
|
*/
|
||||||
@@ -242,7 +247,7 @@ public class Home extends Activity {
|
|||||||
Log.e(LOG_TAG, "Failed to clear wallpaper " + e);
|
Log.e(LOG_TAG, "Failed to clear wallpaper " + e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getWindow().setBackgroundDrawable(new ClippedDrawable(wallpaper));
|
getWindow().setBackgroundDrawable(wallpaper);
|
||||||
}
|
}
|
||||||
mWallpaperChecked = true;
|
mWallpaperChecked = true;
|
||||||
}
|
}
|
||||||
@@ -254,17 +259,18 @@ public class Home extends Activity {
|
|||||||
*/
|
*/
|
||||||
private void bindFavorites(boolean isLaunching) {
|
private void bindFavorites(boolean isLaunching) {
|
||||||
if (!isLaunching || mFavorites == null) {
|
if (!isLaunching || mFavorites == null) {
|
||||||
|
final Cursor c = getContentResolver().query(Uri.parse("content://" +
|
||||||
|
android.provider.Settings.AUTHORITY + "/favorites?notify=true"),
|
||||||
|
null, null, null, "cellX");
|
||||||
|
|
||||||
FileReader favReader;
|
final int intentIndex = c.getColumnIndexOrThrow("intent");
|
||||||
|
final int titleIndex = c.getColumnIndexOrThrow("title");
|
||||||
|
final int typeIndex = c.getColumnIndexOrThrow("itemType");
|
||||||
|
|
||||||
// Environment.getRootDirectory() is a fancy way of saying ANDROID_ROOT or "/system".
|
final PackageManager manager = getPackageManager();
|
||||||
final File favFile = new File(Environment.getRootDirectory(), DEFAULT_FAVORITES_PATH);
|
|
||||||
try {
|
ApplicationInfo info;
|
||||||
favReader = new FileReader(favFile);
|
String intentDescription;
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Log.e(LOG_TAG, "Couldn't find or open favorites file " + favFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mFavorites == null) {
|
if (mFavorites == null) {
|
||||||
mFavorites = new LinkedList<ApplicationInfo>();
|
mFavorites = new LinkedList<ApplicationInfo>();
|
||||||
@@ -272,77 +278,38 @@ public class Home extends Activity {
|
|||||||
mFavorites.clear();
|
mFavorites.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
|
while (c.moveToNext()) {
|
||||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
final int itemType = c.getInt(typeIndex);
|
||||||
|
|
||||||
final PackageManager packageManager = getPackageManager();
|
if (itemType == 0 || // 0 == application
|
||||||
|
itemType == 1) { // 1 == shortcut
|
||||||
|
|
||||||
try {
|
intentDescription = c.getString(intentIndex);
|
||||||
final XmlPullParser parser = Xml.newPullParser();
|
if (intentDescription == null) {
|
||||||
parser.setInput(favReader);
|
continue;
|
||||||
|
|
||||||
beginDocument(parser, TAG_FAVORITES);
|
|
||||||
|
|
||||||
ApplicationInfo info;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
nextElement(parser);
|
|
||||||
|
|
||||||
String name = parser.getName();
|
|
||||||
if (!TAG_FAVORITE.equals(name)) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final String favoritePackage = parser.getAttributeValue(null, TAG_PACKAGE);
|
Intent intent;
|
||||||
final String favoriteClass = parser.getAttributeValue(null, TAG_CLASS);
|
try {
|
||||||
|
intent = Intent.getIntent(intentDescription);
|
||||||
final ComponentName cn = new ComponentName(favoritePackage, favoriteClass);
|
} catch (java.net.URISyntaxException e) {
|
||||||
intent.setComponent(cn);
|
continue;
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
}
|
||||||
|
info = getApplicationInfo(manager, intent);
|
||||||
info = getApplicationInfo(packageManager, intent);
|
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
|
info.title = c.getString(titleIndex);
|
||||||
info.intent = intent;
|
info.intent = intent;
|
||||||
mFavorites.addFirst(info);
|
mFavorites.addFirst(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
Log.w(LOG_TAG, "Got exception parsing favorites.", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.w(LOG_TAG, "Got exception parsing favorites.", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
mApplicationsStack.setFavorites(mFavorites);
|
mApplicationsStack.setFavorites(mFavorites);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void beginDocument(XmlPullParser parser, String firstElementName)
|
|
||||||
throws XmlPullParserException, IOException {
|
|
||||||
|
|
||||||
int type;
|
|
||||||
while ((type = parser.next()) != XmlPullParser.START_TAG &&
|
|
||||||
type != XmlPullParser.END_DOCUMENT) {
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != XmlPullParser.START_TAG) {
|
|
||||||
throw new XmlPullParserException("No start tag found");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parser.getName().equals(firstElementName)) {
|
|
||||||
throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
|
|
||||||
", expected " + firstElementName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException {
|
|
||||||
int type;
|
|
||||||
while ((type = parser.next()) != XmlPullParser.START_TAG &&
|
|
||||||
type != XmlPullParser.END_DOCUMENT) {
|
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes the recently launched applications stacked over the favorites. The number
|
* Refreshes the recently launched applications stacked over the favorites. The number
|
||||||
* of recents depends on how many favorites are present.
|
* of recents depends on how many favorites are present.
|
||||||
@@ -394,6 +361,14 @@ public class Home extends Activity {
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the notification that favorites have changed is received, requests
|
||||||
|
* a favorites list refresh.
|
||||||
|
*/
|
||||||
|
private void onFavoritesChanged() {
|
||||||
|
bindFavorites(false);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
@@ -555,7 +530,7 @@ public class Home extends Activity {
|
|||||||
private class WallpaperIntentReceiver extends BroadcastReceiver {
|
private class WallpaperIntentReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
getWindow().setBackgroundDrawable(new ClippedDrawable(getWallpaper()));
|
getWindow().setBackgroundDrawable(getWallpaper());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,6 +547,20 @@ public class Home extends Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives notifications whenever the user favorites have changed.
|
||||||
|
*/
|
||||||
|
private class FavoritesChangeObserver extends ContentObserver {
|
||||||
|
public FavoritesChangeObserver() {
|
||||||
|
super(mHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
onFavoritesChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GridView adapter to show the list of all installed applications.
|
* GridView adapter to show the list of all installed applications.
|
||||||
*/
|
*/
|
||||||
@@ -591,12 +580,13 @@ public class Home extends Activity {
|
|||||||
convertView = inflater.inflate(R.layout.application, parent, false);
|
convertView = inflater.inflate(R.layout.application, parent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//final ImageView imageView = (ImageView) convertView.findViewById(R.id.icon);
|
||||||
Drawable icon = info.icon;
|
Drawable icon = info.icon;
|
||||||
|
|
||||||
if (!info.filtered) {
|
if (!info.filtered) {
|
||||||
//final Resources resources = getContext().getResources();
|
final Resources resources = getContext().getResources();
|
||||||
int width = 42;//(int) resources.getDimension(android.R.dimen.app_icon_size);
|
int width = (int) resources.getDimension(android.R.dimen.app_icon_size);
|
||||||
int height = 42;//(int) resources.getDimension(android.R.dimen.app_icon_size);
|
int height = (int) resources.getDimension(android.R.dimen.app_icon_size);
|
||||||
|
|
||||||
final int iconWidth = icon.getIntrinsicWidth();
|
final int iconWidth = icon.getIntrinsicWidth();
|
||||||
final int iconHeight = icon.getIntrinsicHeight();
|
final int iconHeight = icon.getIntrinsicHeight();
|
||||||
@@ -697,47 +687,4 @@ public class Home extends Activity {
|
|||||||
startActivity(app.intent);
|
startActivity(app.intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* When a drawable is attached to a View, the View gives the Drawable its dimensions
|
|
||||||
* by calling Drawable.setBounds(). In this application, the View that draws the
|
|
||||||
* wallpaper has the same size as the screen. However, the wallpaper might be larger
|
|
||||||
* that the screen which means it will be automatically stretched. Because stretching
|
|
||||||
* a bitmap while drawing it is very expensive, we use a ClippedDrawable instead.
|
|
||||||
* This drawable simply draws another wallpaper but makes sure it is not stretched
|
|
||||||
* by always giving it its intrinsic dimensions. If the wallpaper is larger than the
|
|
||||||
* screen, it will simply get clipped but it won't impact performance.
|
|
||||||
*/
|
|
||||||
private class ClippedDrawable extends Drawable {
|
|
||||||
private final Drawable mWallpaper;
|
|
||||||
|
|
||||||
public ClippedDrawable(Drawable wallpaper) {
|
|
||||||
mWallpaper = wallpaper;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setBounds(int left, int top, int right, int bottom) {
|
|
||||||
super.setBounds(left, top, right, bottom);
|
|
||||||
// Ensure the wallpaper is as large as it really is, to avoid stretching it
|
|
||||||
// at drawing time
|
|
||||||
mWallpaper.setBounds(left, top, left + mWallpaper.getIntrinsicWidth(),
|
|
||||||
top + mWallpaper.getIntrinsicHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void draw(Canvas canvas) {
|
|
||||||
mWallpaper.draw(canvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAlpha(int alpha) {
|
|
||||||
mWallpaper.setAlpha(alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColorFilter(ColorFilter cf) {
|
|
||||||
mWallpaper.setColorFilter(cf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getOpacity() {
|
|
||||||
return mWallpaper.getOpacity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 KiB |
@@ -25,7 +25,9 @@
|
|||||||
<string name="word_separators">\u0020.,;:!?\n()[]*&@{}/<>_+=|"</string>
|
<string name="word_separators">\u0020.,;:!?\n()[]*&@{}/<>_+=|"</string>
|
||||||
|
|
||||||
<!-- Labels on soft keys -->
|
<!-- Labels on soft keys -->
|
||||||
<string name="label_go_key">Go</string>
|
<string name="label_done">Done</string>
|
||||||
<string name="label_next_key">Next</string>
|
<string name="label_search">Search</string>
|
||||||
<string name="label_send_key">Send</string>
|
<string name="label_enter">Enter</string>
|
||||||
|
<string name="label_next">Next</string>
|
||||||
|
<string name="label_previous">Previous</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -20,14 +20,9 @@ import android.content.Context;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
import android.inputmethodservice.Keyboard;
|
import android.inputmethodservice.Keyboard;
|
||||||
import android.inputmethodservice.Keyboard.Key;
|
|
||||||
import android.inputmethodservice.Keyboard.Row;
|
|
||||||
import android.view.inputmethod.EditorInfo;
|
|
||||||
|
|
||||||
public class LatinKeyboard extends Keyboard {
|
public class LatinKeyboard extends Keyboard {
|
||||||
|
|
||||||
private Key mEnterKey;
|
|
||||||
|
|
||||||
public LatinKeyboard(Context context, int xmlLayoutResId) {
|
public LatinKeyboard(Context context, int xmlLayoutResId) {
|
||||||
super(context, xmlLayoutResId);
|
super(context, xmlLayoutResId);
|
||||||
}
|
}
|
||||||
@@ -40,49 +35,7 @@ public class LatinKeyboard extends Keyboard {
|
|||||||
@Override
|
@Override
|
||||||
protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
|
protected Key createKeyFromXml(Resources res, Row parent, int x, int y,
|
||||||
XmlResourceParser parser) {
|
XmlResourceParser parser) {
|
||||||
Key key = new LatinKey(res, parent, x, y, parser);
|
return new LatinKey(res, parent, x, y, parser);
|
||||||
if (key.codes[0] == 10) {
|
|
||||||
mEnterKey = key;
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This looks at the ime options given by the current editor, to set the
|
|
||||||
* appropriate label on the keyboard's enter key (if it has one).
|
|
||||||
*/
|
|
||||||
void setImeOptions(Resources res, int options) {
|
|
||||||
if (mEnterKey == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (options&(EditorInfo.IME_MASK_ACTION|EditorInfo.IME_FLAG_NO_ENTER_ACTION)) {
|
|
||||||
case EditorInfo.IME_ACTION_GO:
|
|
||||||
mEnterKey.iconPreview = null;
|
|
||||||
mEnterKey.icon = null;
|
|
||||||
mEnterKey.label = res.getText(R.string.label_go_key);
|
|
||||||
break;
|
|
||||||
case EditorInfo.IME_ACTION_NEXT:
|
|
||||||
mEnterKey.iconPreview = null;
|
|
||||||
mEnterKey.icon = null;
|
|
||||||
mEnterKey.label = res.getText(R.string.label_next_key);
|
|
||||||
break;
|
|
||||||
case EditorInfo.IME_ACTION_SEARCH:
|
|
||||||
mEnterKey.icon = res.getDrawable(
|
|
||||||
R.drawable.sym_keyboard_search);
|
|
||||||
mEnterKey.label = null;
|
|
||||||
break;
|
|
||||||
case EditorInfo.IME_ACTION_SEND:
|
|
||||||
mEnterKey.iconPreview = null;
|
|
||||||
mEnterKey.icon = null;
|
|
||||||
mEnterKey.label = res.getText(R.string.label_send_key);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mEnterKey.icon = res.getDrawable(
|
|
||||||
R.drawable.sym_keyboard_return);
|
|
||||||
mEnterKey.label = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class LatinKey extends Keyboard.Key {
|
static class LatinKey extends Keyboard.Key {
|
||||||
|
|||||||
@@ -65,11 +65,11 @@ public class SoftKeyboard extends InputMethodService
|
|||||||
private long mLastShiftTime;
|
private long mLastShiftTime;
|
||||||
private long mMetaState;
|
private long mMetaState;
|
||||||
|
|
||||||
private LatinKeyboard mSymbolsKeyboard;
|
private Keyboard mSymbolsKeyboard;
|
||||||
private LatinKeyboard mSymbolsShiftedKeyboard;
|
private Keyboard mSymbolsShiftedKeyboard;
|
||||||
private LatinKeyboard mQwertyKeyboard;
|
private Keyboard mQwertyKeyboard;
|
||||||
|
|
||||||
private LatinKeyboard mCurKeyboard;
|
private Keyboard mCurKeyboard;
|
||||||
|
|
||||||
private String mWordSeparators;
|
private String mWordSeparators;
|
||||||
|
|
||||||
@@ -208,10 +208,6 @@ public class SoftKeyboard extends InputMethodService
|
|||||||
// keyboard with no special features.
|
// keyboard with no special features.
|
||||||
mCurKeyboard = mQwertyKeyboard;
|
mCurKeyboard = mQwertyKeyboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the label on the enter key, depending on what the application
|
|
||||||
// says it will do.
|
|
||||||
mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -508,18 +504,6 @@ public class SoftKeyboard extends InputMethodService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onText(CharSequence text) {
|
|
||||||
InputConnection ic = getCurrentInputConnection();
|
|
||||||
if (ic == null) return;
|
|
||||||
ic.beginBatchEdit();
|
|
||||||
if (mComposing.length() > 0) {
|
|
||||||
commitTyped(ic);
|
|
||||||
}
|
|
||||||
ic.commitText(text, 0);
|
|
||||||
ic.endBatchEdit();
|
|
||||||
updateShiftKeyState(getCurrentInputEditorInfo());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the list of available candidates from the current composing
|
* Update the list of available candidates from the current composing
|
||||||
* text. This will need to be filled in by however you are determining
|
* text. This will need to be filled in by however you are determining
|
||||||
|
|||||||
@@ -1,208 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Copyright (C) 2009 The Android Open Source Project
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This file contains standard test definitions for the Android platform
|
|
||||||
|
|
||||||
Tests are defined by <test> tags with the following attributes
|
|
||||||
|
|
||||||
name package [class runner build_path coverage_target continuous]
|
|
||||||
|
|
||||||
Where:
|
|
||||||
name: Self-descriptive name used to uniquely identify the test
|
|
||||||
build_path: File system path, relative to Android build root, to this package's
|
|
||||||
Android.mk file. If omitted, build/sync step for this test will be skipped
|
|
||||||
package: Android application package that contains the tests
|
|
||||||
class: Optional. Fully qualified Java test class to run.
|
|
||||||
runner: Fully qualified InstrumentationTestRunner to execute. If omitted,
|
|
||||||
will default to android.test.InstrumentationTestRunner
|
|
||||||
coverage_target: Build name of Android package this test targets - these targets
|
|
||||||
are defined in the coverage_targets.xml file. Used as basis for code
|
|
||||||
coverage metrics. If omitted, code coverage will not be supported for this
|
|
||||||
test
|
|
||||||
continuous: Optional boolean. Default is false. Set to true if tests are known
|
|
||||||
to be reliable, and should be included in a continuous test system. false if
|
|
||||||
they are under development.
|
|
||||||
|
|
||||||
These attributes map to the following commands:
|
|
||||||
(if class is defined)
|
|
||||||
adb shell am instrument -w <package>/<runner>
|
|
||||||
(else)
|
|
||||||
adb shell am instrument -w -e class <class> <package>/<runner>
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<test-definitions version="1">
|
|
||||||
|
|
||||||
<!-- system-wide tests -->
|
|
||||||
<test name="framework"
|
|
||||||
build_path="frameworks/base/tests/FrameworkTest"
|
|
||||||
package="com.android.frameworktest.tests"
|
|
||||||
class="com.android.frameworktest.AllTests"
|
|
||||||
coverage_target="framework"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="android"
|
|
||||||
build_path="frameworks/base/tests/AndroidTests"
|
|
||||||
package="com.android.unit_tests"
|
|
||||||
class="com.android.unit_tests.AndroidTests"
|
|
||||||
coverage_target="framework"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="smoke"
|
|
||||||
build_path="frameworks/base/tests/SmokeTest"
|
|
||||||
package="com.android.smoketest.tests"
|
|
||||||
coverage_target="framework"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="core"
|
|
||||||
build_path="frameworks/base/tests/CoreTests"
|
|
||||||
package="android.core"
|
|
||||||
class="android.core.CoreTests"
|
|
||||||
coverage_target="framework"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="libcore"
|
|
||||||
build_path="frameworks/base/tests/CoreTests"
|
|
||||||
package="android.core"
|
|
||||||
class="android.core.JavaTests"
|
|
||||||
coverage_target="framework" />
|
|
||||||
|
|
||||||
<test name="apidemos"
|
|
||||||
build_path="development/samples/ApiDemos"
|
|
||||||
package="com.example.android.apis.tests"
|
|
||||||
coverage_target="ApiDemos"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<!-- targeted framework tests -->
|
|
||||||
<test name="heap"
|
|
||||||
build_path="frameworks/base/tests/AndroidTests"
|
|
||||||
package="com.android.unit_tests"
|
|
||||||
class="com.android.unit_tests.HeapTest"
|
|
||||||
coverage_target="framework" />
|
|
||||||
|
|
||||||
<test name="activity"
|
|
||||||
build_path="frameworks/base/tests/AndroidTests"
|
|
||||||
package="com.android.unit_tests"
|
|
||||||
class="com.android.unit_tests.activity.ActivityTests"
|
|
||||||
coverage_target="framework" />
|
|
||||||
|
|
||||||
<!-- obsolete?
|
|
||||||
<test name="deadlock"
|
|
||||||
build_path="frameworks/base/tests/Deadlock"
|
|
||||||
package="com.android.deadlock.tests"
|
|
||||||
coverage_target="framework" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<test name="tablemerger"
|
|
||||||
build_path="frameworks/base/tests/FrameworkTest"
|
|
||||||
package="com.android.frameworktest.tests"
|
|
||||||
class="android.content.AbstractTableMergerTest"
|
|
||||||
coverage_target="framework" />
|
|
||||||
|
|
||||||
|
|
||||||
<!-- selected app tests -->
|
|
||||||
<test name="browser"
|
|
||||||
build_path="packages/apps/Browser"
|
|
||||||
package="com.android.browser"
|
|
||||||
runner=".BrowserTestRunner"
|
|
||||||
coverage_target="Browser" />
|
|
||||||
|
|
||||||
<test name="browserfunc"
|
|
||||||
build_path="packages/apps/Browser"
|
|
||||||
package="com.android.browser"
|
|
||||||
runner=".BrowserFunctionalTestRunner"
|
|
||||||
coverage_target="Browser" />
|
|
||||||
|
|
||||||
<test name="calendar"
|
|
||||||
build_path="packages/apps/Calendar/tests"
|
|
||||||
package="com.android.calendar.tests"
|
|
||||||
coverage_target="Calendar"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="calprov"
|
|
||||||
build_path="packages/providers/CalendarProvider/tests"
|
|
||||||
package="com.android.providers.calendar.tests"
|
|
||||||
coverage_target="CalendarProvider"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="camera"
|
|
||||||
build_path="packages/apps/Camera/tests"
|
|
||||||
package="com.android.cameratests"
|
|
||||||
runner="CameraInstrumentationTestRunner"
|
|
||||||
coverage_target="Camera" />
|
|
||||||
|
|
||||||
<test name="contactsprov"
|
|
||||||
build_path="packages/providers/GoogleContactsProvider/tests"
|
|
||||||
package="com.android.providers.contactstests"
|
|
||||||
coverage_target="ContactsProvider" />
|
|
||||||
|
|
||||||
<test name="email"
|
|
||||||
build_path="packages/apps/Email"
|
|
||||||
package="com.android.email.tests"
|
|
||||||
coverage_target="Email"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="emailsmall"
|
|
||||||
build_path="packages/apps/Email"
|
|
||||||
package="com.android.email.tests"
|
|
||||||
class="com.android.email.SmallTests"
|
|
||||||
coverage_target="Email" />
|
|
||||||
|
|
||||||
<test name="media"
|
|
||||||
build_path="frameworks/base/media/tests/MediaFrameworkTest"
|
|
||||||
package="com.android.mediaframeworktest"
|
|
||||||
runner=".MediaFrameworkTestRunner"
|
|
||||||
coverage_target="framework"
|
|
||||||
continuous="true" />
|
|
||||||
|
|
||||||
<test name="mediaunit"
|
|
||||||
build_path="frameworks/base/media/tests/MediaFrameworkTest"
|
|
||||||
package="com.android.mediaframeworktest"
|
|
||||||
runner=".MediaFrameworkUnitTestRunner"
|
|
||||||
coverage_target="framework" />
|
|
||||||
|
|
||||||
<!-- obsolete?
|
|
||||||
<test name="mediaprov"
|
|
||||||
build_path="tests/MediaProvider"
|
|
||||||
package="com.android.mediaprovidertests"
|
|
||||||
runner=".MediaProviderTestsInstrumentation"
|
|
||||||
coverage_target="MediaProvider" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
<test name="mms"
|
|
||||||
build_path="packages/apps/Mms"
|
|
||||||
package="com.android.mms.tests"
|
|
||||||
runner="com.android.mms.ui.MMSInstrumentationTestRunner"
|
|
||||||
coverage_target="Mms" />
|
|
||||||
|
|
||||||
<test name="mmslaunch"
|
|
||||||
build_path="packages/apps/Mms"
|
|
||||||
package="com.android.mms.tests"
|
|
||||||
runner="com.android.mms.SmsLaunchPerformance"
|
|
||||||
coverage_target="Mms" />
|
|
||||||
|
|
||||||
|
|
||||||
<!-- obsolete?
|
|
||||||
<test name="ringtone"
|
|
||||||
build_path="tests/RingtoneSettings"
|
|
||||||
package="com.android.ringtonesettingstests"
|
|
||||||
runner=".RingtoneSettingsInstrumentationTestRunner"
|
|
||||||
coverage_target="Settings" />
|
|
||||||
-->
|
|
||||||
|
|
||||||
</test-definitions>
|
|
||||||
@@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks,
|
|||||||
rem and set up progdir to be the fully-qualified pathname of its directory.
|
rem and set up progdir to be the fully-qualified pathname of its directory.
|
||||||
set prog=%~f0
|
set prog=%~f0
|
||||||
|
|
||||||
rem Change current directory and drive to where the script is, to avoid
|
rem Change current directory to where ddms is, to avoid issues with directories
|
||||||
rem issues with directories containing whitespaces.
|
rem containing whitespaces.
|
||||||
cd /d %~dp0
|
cd %~dp0
|
||||||
|
|
||||||
set jarfile=apkbuilder.jar
|
set jarfile=apkbuilder.jar
|
||||||
set frameworkdir=
|
set frameworkdir=
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks,
|
|||||||
rem and set up progdir to be the fully-qualified pathname of its directory.
|
rem and set up progdir to be the fully-qualified pathname of its directory.
|
||||||
set prog=%~f0
|
set prog=%~f0
|
||||||
|
|
||||||
rem Change current directory and drive to where the script is, to avoid
|
rem Change current directory to where ddms is, to avoid issues with directories
|
||||||
rem issues with directories containing whitespaces.
|
rem containing whitespaces.
|
||||||
cd /d %~dp0
|
cd %~dp0
|
||||||
|
|
||||||
set jarfile=ddms.jar
|
set jarfile=ddms.jar
|
||||||
set frameworkdir=
|
set frameworkdir=
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class Client {
|
|||||||
* is only used for data generated within Client.
|
* is only used for data generated within Client.
|
||||||
*/
|
*/
|
||||||
private static final int INITIAL_BUF_SIZE = 2*1024;
|
private static final int INITIAL_BUF_SIZE = 2*1024;
|
||||||
private static final int MAX_BUF_SIZE = 200*1024*1024;
|
private static final int MAX_BUF_SIZE = 2*1024*1024;
|
||||||
private ByteBuffer mReadBuffer;
|
private ByteBuffer mReadBuffer;
|
||||||
|
|
||||||
private static final int WRITE_BUF_SIZE = 256;
|
private static final int WRITE_BUF_SIZE = 256;
|
||||||
|
|||||||
@@ -251,15 +251,6 @@ public final class Device implements IDevice {
|
|||||||
AdbHelper.runEventLogService(AndroidDebugBridge.sSocketAddr, this, receiver);
|
AdbHelper.runEventLogService(AndroidDebugBridge.sSocketAddr, this, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.android.ddmlib.IDevice#runLogService(com.android.ddmlib.log.LogReceiver)
|
|
||||||
*/
|
|
||||||
public void runLogService(String logname,
|
|
||||||
LogReceiver receiver) throws IOException {
|
|
||||||
AdbHelper.runLogService(AndroidDebugBridge.sSocketAddr, this, logname, receiver);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see com.android.ddmlib.IDevice#createForward(int, int)
|
* @see com.android.ddmlib.IDevice#createForward(int, int)
|
||||||
|
|||||||
@@ -151,14 +151,6 @@ public interface IDevice {
|
|||||||
*/
|
*/
|
||||||
public void runEventLogService(LogReceiver receiver) throws IOException;
|
public void runEventLogService(LogReceiver receiver) throws IOException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the log service for the given log and outputs the log to the {@link LogReceiver}.
|
|
||||||
* @param logname the logname of the log to read from.
|
|
||||||
* @param receiver the receiver to receive the event log entries.
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
public void runLogService(String logname, LogReceiver receiver) throws IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a port forwarding between a local and a remote port.
|
* Creates a port forwarding between a local and a remote port.
|
||||||
* @param localPort the local port to forward
|
* @param localPort the local port to forward
|
||||||
|
|||||||
@@ -17,69 +17,56 @@
|
|||||||
package com.android.ddmlib.testrunner;
|
package com.android.ddmlib.testrunner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives event notifications during instrumentation test runs.
|
* Listener for instrumentation test runs
|
||||||
* Patterned after {@link junit.runner.TestRunListener}.
|
*
|
||||||
|
* Modeled after junit.runner.TestRunListener
|
||||||
*/
|
*/
|
||||||
public interface ITestRunListener {
|
public interface ITestRunListener {
|
||||||
|
public static final int STATUS_ERROR = 1;
|
||||||
|
public static final int STATUS_FAILURE = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types of test failures.
|
* Reports the start of a test run
|
||||||
*/
|
* @param testCount - total number of tests in test run
|
||||||
enum TestFailure {
|
* */
|
||||||
/** Test failed due to unanticipated uncaught exception. */
|
|
||||||
ERROR,
|
|
||||||
/** Test failed due to a false assertion. */
|
|
||||||
FAILURE
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reports the start of a test run.
|
|
||||||
*
|
|
||||||
* @param testCount total number of tests in test run
|
|
||||||
*/
|
|
||||||
public void testRunStarted(int testCount);
|
public void testRunStarted(int testCount);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports end of test run.
|
* Reports end of test run
|
||||||
*
|
* @param elapsedTime - device reported elapsed time, in milliseconds
|
||||||
* @param elapsedTime device reported elapsed time, in milliseconds
|
|
||||||
*/
|
*/
|
||||||
public void testRunEnded(long elapsedTime);
|
public void testRunEnded(long elapsedTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports test run stopped before completion.
|
* Reports test run stopped before completion
|
||||||
*
|
* @param elapsedTime - device reported elapsed time, in milliseconds
|
||||||
* @param elapsedTime device reported elapsed time, in milliseconds
|
|
||||||
*/
|
*/
|
||||||
public void testRunStopped(long elapsedTime);
|
public void testRunStopped(long elapsedTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports the start of an individual test case.
|
* Reports the start of an individual test case
|
||||||
*
|
|
||||||
* @param test identifies the test
|
|
||||||
*/
|
*/
|
||||||
public void testStarted(TestIdentifier test);
|
public void testStarted(String className, String testName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports the execution end of an individual test case.
|
* Reports the execution end of an individual test case
|
||||||
* If {@link #testFailed} was not invoked, this test passed.
|
* If no testFailed has been reported, this is a passed test
|
||||||
*
|
|
||||||
* @param test identifies the test
|
|
||||||
*/
|
*/
|
||||||
public void testEnded(TestIdentifier test);
|
public void testEnded(String className, String testName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports the failure of a individual test case.
|
* Reports the failure of a individual test case
|
||||||
* Will be called between testStarted and testEnded.
|
* Will be called between testStarted and testEnded
|
||||||
*
|
*
|
||||||
* @param status failure type
|
* @param status - one of STATUS_ERROR, STATUS_FAILURE
|
||||||
* @param test identifies the test
|
* @param className - name of test class
|
||||||
* @param trace stack trace of failure
|
* @param testName - name of test method
|
||||||
|
* @param trace - stack trace of failure
|
||||||
*/
|
*/
|
||||||
public void testFailed(TestFailure status, TestIdentifier test, String trace);
|
public void testFailed(int status, String className, String testName, String trace);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports test run failed to execute due to a fatal error.
|
* Reports test run failed to execute due to a fatal error
|
||||||
*/
|
*/
|
||||||
public void testRunFailed(String errorMessage);
|
public void testRunFailed(String errorMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,21 +20,24 @@ import com.android.ddmlib.IShellOutputReceiver;
|
|||||||
import com.android.ddmlib.Log;
|
import com.android.ddmlib.Log;
|
||||||
import com.android.ddmlib.MultiLineReceiver;
|
import com.android.ddmlib.MultiLineReceiver;
|
||||||
|
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the 'raw output mode' results of an instrumentation test run from shell and informs a
|
* Parses the 'raw output mode' results of an instrument test run from shell, and informs a
|
||||||
* ITestRunListener of the results.
|
* ITestRunListener of the results
|
||||||
*
|
*
|
||||||
* <p>Expects the following output:
|
* Expects the following output:
|
||||||
*
|
*
|
||||||
* <p>If fatal error occurred when attempted to run the tests:
|
* If fatal error occurred when attempted to run the tests:
|
||||||
* <pre> INSTRUMENTATION_FAILED: </pre>
|
* <i> INSTRUMENTATION_FAILED: </i>
|
||||||
*
|
*
|
||||||
* <p>Otherwise, expect a series of test results, each one containing a set of status key/value
|
* Otherwise, expect a series of test results, each one containing a set of status key/value
|
||||||
* pairs, delimited by a start(1)/pass(0)/fail(-2)/error(-1) status code result. At end of test
|
* pairs, delimited by a start(1)/pass(0)/fail(-2)/error(-1) status code result. At end of test
|
||||||
* run, expects that the elapsed test time in seconds will be displayed
|
* run, expects that the elapsed test time in seconds will be displayed
|
||||||
*
|
*
|
||||||
* <p>For example:
|
* i.e.
|
||||||
* <pre>
|
* <i>
|
||||||
* INSTRUMENTATION_STATUS_CODE: 1
|
* INSTRUMENTATION_STATUS_CODE: 1
|
||||||
* INSTRUMENTATION_STATUS: class=com.foo.FooTest
|
* INSTRUMENTATION_STATUS: class=com.foo.FooTest
|
||||||
* INSTRUMENTATION_STATUS: test=testFoo
|
* INSTRUMENTATION_STATUS: test=testFoo
|
||||||
@@ -45,85 +48,64 @@ import com.android.ddmlib.MultiLineReceiver;
|
|||||||
* ...
|
* ...
|
||||||
*
|
*
|
||||||
* Time: X
|
* Time: X
|
||||||
* </pre>
|
* </i>
|
||||||
* <p>Note that the "value" portion of the key-value pair may wrap over several text lines
|
*
|
||||||
|
* Note that the "value" portion of the key-value pair may wrap over several text lines
|
||||||
*/
|
*/
|
||||||
public class InstrumentationResultParser extends MultiLineReceiver {
|
public class InstrumentationResultParser extends MultiLineReceiver {
|
||||||
|
|
||||||
/** Relevant test status keys. */
|
// relevant test status keys
|
||||||
private static class StatusKeys {
|
private static final String CODE_KEY = "code";
|
||||||
private static final String TEST = "test";
|
private static final String TEST_KEY = "test";
|
||||||
private static final String CLASS = "class";
|
private static final String CLASS_KEY = "class";
|
||||||
private static final String STACK = "stack";
|
private static final String STACK_KEY = "stack";
|
||||||
private static final String NUMTESTS = "numtests";
|
private static final String NUMTESTS_KEY = "numtests";
|
||||||
}
|
|
||||||
|
|
||||||
/** Test result status codes. */
|
// test result status codes
|
||||||
private static class StatusCodes {
|
private static final int FAILURE_STATUS_CODE = -2;
|
||||||
private static final int FAILURE = -2;
|
private static final int START_STATUS_CODE = 1;
|
||||||
private static final int START = 1;
|
private static final int ERROR_STATUS_CODE = -1;
|
||||||
private static final int ERROR = -1;
|
private static final int OK_STATUS_CODE = 0;
|
||||||
private static final int OK = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Prefixes used to identify output. */
|
// recognized output patterns
|
||||||
private static class Prefixes {
|
private static final String STATUS_PREFIX = "INSTRUMENTATION_STATUS: ";
|
||||||
private static final String STATUS = "INSTRUMENTATION_STATUS: ";
|
private static final String STATUS_PREFIX_CODE = "INSTRUMENTATION_STATUS_CODE: ";
|
||||||
private static final String STATUS_CODE = "INSTRUMENTATION_STATUS_CODE: ";
|
|
||||||
private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: ";
|
private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: ";
|
||||||
private static final String TIME_REPORT = "Time: ";
|
private static final String TIME_REPORT = "Time: ";
|
||||||
}
|
|
||||||
|
|
||||||
private final ITestRunListener mTestListener;
|
private final ITestRunListener mTestListener;
|
||||||
|
/** key-value map for current test */
|
||||||
/**
|
private Map<String, String> mStatusValues;
|
||||||
* Test result data
|
/** stores the current "key" portion of the status key-value being parsed */
|
||||||
*/
|
private String mCurrentKey;
|
||||||
private static class TestResult {
|
/** stores the current "value" portion of the status key-value being parsed */
|
||||||
private Integer mCode = null;
|
private StringBuilder mCurrentValue;
|
||||||
private String mTestName = null;
|
/** true if start of test has already been reported to listener */
|
||||||
private String mTestClass = null;
|
private boolean mTestStartReported;
|
||||||
private String mStackTrace = null;
|
/** the elapsed time of the test run, in ms */
|
||||||
private Integer mNumTests = null;
|
private long mTestTime;
|
||||||
|
/** true if current test run has been canceled by user */
|
||||||
/** Returns true if all expected values have been parsed */
|
private boolean mIsCancelled;
|
||||||
boolean isComplete() {
|
|
||||||
return mCode != null && mTestName != null && mTestClass != null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Stores the status values for the test result currently being parsed */
|
|
||||||
private TestResult mCurrentTestResult = null;
|
|
||||||
|
|
||||||
/** Stores the current "key" portion of the status key-value being parsed. */
|
|
||||||
private String mCurrentKey = null;
|
|
||||||
|
|
||||||
/** Stores the current "value" portion of the status key-value being parsed. */
|
|
||||||
private StringBuilder mCurrentValue = null;
|
|
||||||
|
|
||||||
/** True if start of test has already been reported to listener. */
|
|
||||||
private boolean mTestStartReported = false;
|
|
||||||
|
|
||||||
/** The elapsed time of the test run, in milliseconds. */
|
|
||||||
private long mTestTime = 0;
|
|
||||||
|
|
||||||
/** True if current test run has been canceled by user. */
|
|
||||||
private boolean mIsCancelled = false;
|
|
||||||
|
|
||||||
private static final String LOG_TAG = "InstrumentationResultParser";
|
private static final String LOG_TAG = "InstrumentationResultParser";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the InstrumentationResultParser.
|
* Creates the InstrumentationResultParser
|
||||||
*
|
* @param listener - listener to report results to. will be informed of test results as the
|
||||||
* @param listener informed of test results as the tests are executing
|
* tests are executing
|
||||||
*/
|
*/
|
||||||
public InstrumentationResultParser(ITestRunListener listener) {
|
public InstrumentationResultParser(ITestRunListener listener) {
|
||||||
|
mStatusValues = new Hashtable<String, String>();
|
||||||
|
mCurrentKey = null;
|
||||||
|
setTrimLine(false);
|
||||||
mTestListener = listener;
|
mTestListener = listener;
|
||||||
|
mTestStartReported = false;
|
||||||
|
mTestTime = 0;
|
||||||
|
mIsCancelled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes the instrumentation test output from shell.
|
* Processes the instrumentation test output from shell
|
||||||
*
|
|
||||||
* @see MultiLineReceiver#processNewLines
|
* @see MultiLineReceiver#processNewLines
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -134,37 +116,31 @@ public class InstrumentationResultParser extends MultiLineReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an individual output line. Expects a line that is one of:
|
* Parse an individual output line. Expects a line that either is:
|
||||||
* <ul>
|
* a) the start of a new status line (ie. starts with STATUS_PREFIX or STATUS_PREFIX_CODE),
|
||||||
* <li>
|
|
||||||
* The start of a new status line (starts with Prefixes.STATUS or Prefixes.STATUS_CODE),
|
|
||||||
* and thus there is a new key=value pair to parse, and the previous key-value pair is
|
* and thus there is a new key=value pair to parse, and the previous key-value pair is
|
||||||
* finished.
|
* finished
|
||||||
* </li>
|
* b) a continuation of the previous status (ie the "value" portion of the key has wrapped
|
||||||
* <li>
|
* to the next line.
|
||||||
* A continuation of the previous status (the "value" portion of the key has wrapped
|
* c) a line reporting a fatal error in the test run (STATUS_FAILED)
|
||||||
* to the next line).
|
* d) a line reporting the total elapsed time of the test run.
|
||||||
* </li>
|
|
||||||
* <li> A line reporting a fatal error in the test run (Prefixes.STATUS_FAILED) </li>
|
|
||||||
* <li> A line reporting the total elapsed time of the test run. (Prefixes.TIME_REPORT) </li>
|
|
||||||
* </ul>
|
|
||||||
*
|
*
|
||||||
* @param line Text output line
|
* @param line - text output line
|
||||||
*/
|
*/
|
||||||
private void parse(String line) {
|
private void parse(String line) {
|
||||||
if (line.startsWith(Prefixes.STATUS_CODE)) {
|
if (line.startsWith(STATUS_PREFIX_CODE)) {
|
||||||
// Previous status key-value has been collected. Store it.
|
// Previous status key-value has been collected. Store it.
|
||||||
submitCurrentKeyValue();
|
submitCurrentKeyValue();
|
||||||
parseStatusCode(line);
|
parseStatusCode(line);
|
||||||
} else if (line.startsWith(Prefixes.STATUS)) {
|
} else if (line.startsWith(STATUS_PREFIX)) {
|
||||||
// Previous status key-value has been collected. Store it.
|
// Previous status key-value has been collected. Store it.
|
||||||
submitCurrentKeyValue();
|
submitCurrentKeyValue();
|
||||||
parseKey(line, Prefixes.STATUS.length());
|
parseKey(line, STATUS_PREFIX.length());
|
||||||
} else if (line.startsWith(Prefixes.STATUS_FAILED)) {
|
} else if (line.startsWith(STATUS_FAILED)) {
|
||||||
Log.e(LOG_TAG, "test run failed " + line);
|
Log.e(LOG_TAG, "test run failed " + line);
|
||||||
mTestListener.testRunFailed(line);
|
mTestListener.testRunFailed(line);
|
||||||
} else if (line.startsWith(Prefixes.TIME_REPORT)) {
|
} else if (line.startsWith(TIME_REPORT)) {
|
||||||
parseTime(line, Prefixes.TIME_REPORT.length());
|
parseTime(line, TIME_REPORT.length());
|
||||||
} else {
|
} else {
|
||||||
if (mCurrentValue != null) {
|
if (mCurrentValue != null) {
|
||||||
// this is a value that has wrapped to next line.
|
// this is a value that has wrapped to next line.
|
||||||
@@ -177,53 +153,21 @@ public class InstrumentationResultParser extends MultiLineReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the currently parsed key-value pair into mCurrentTestInfo.
|
* Stores the currently parsed key-value pair in the status map
|
||||||
*/
|
*/
|
||||||
private void submitCurrentKeyValue() {
|
private void submitCurrentKeyValue() {
|
||||||
if (mCurrentKey != null && mCurrentValue != null) {
|
if (mCurrentKey != null && mCurrentValue != null) {
|
||||||
TestResult testInfo = getCurrentTestInfo();
|
mStatusValues.put(mCurrentKey, mCurrentValue.toString());
|
||||||
String statusValue = mCurrentValue.toString();
|
|
||||||
|
|
||||||
if (mCurrentKey.equals(StatusKeys.CLASS)) {
|
|
||||||
testInfo.mTestClass = statusValue.trim();
|
|
||||||
}
|
|
||||||
else if (mCurrentKey.equals(StatusKeys.TEST)) {
|
|
||||||
testInfo.mTestName = statusValue.trim();
|
|
||||||
}
|
|
||||||
else if (mCurrentKey.equals(StatusKeys.NUMTESTS)) {
|
|
||||||
try {
|
|
||||||
testInfo.mNumTests = Integer.parseInt(statusValue);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e) {
|
|
||||||
Log.e(LOG_TAG, "Unexpected integer number of tests, received " + statusValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (mCurrentKey.equals(StatusKeys.STACK)) {
|
|
||||||
testInfo.mStackTrace = statusValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
mCurrentKey = null;
|
mCurrentKey = null;
|
||||||
mCurrentValue = null;
|
mCurrentValue = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestResult getCurrentTestInfo() {
|
|
||||||
if (mCurrentTestResult == null) {
|
|
||||||
mCurrentTestResult = new TestResult();
|
|
||||||
}
|
|
||||||
return mCurrentTestResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearCurrentTestInfo() {
|
|
||||||
mCurrentTestResult = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the key from the current line.
|
* Parses the key from the current line
|
||||||
* Expects format of "key=value".
|
* Expects format of "key=value",
|
||||||
*
|
* @param line - full line of text to parse
|
||||||
* @param line full line of text to parse
|
* @param keyStartPos - the starting position of the key in the given line
|
||||||
* @param keyStartPos the starting position of the key in the given line
|
|
||||||
*/
|
*/
|
||||||
private void parseKey(String line, int keyStartPos) {
|
private void parseKey(String line, int keyStartPos) {
|
||||||
int endKeyPos = line.indexOf('=', keyStartPos);
|
int endKeyPos = line.indexOf('=', keyStartPos);
|
||||||
@@ -235,7 +179,6 @@ public class InstrumentationResultParser extends MultiLineReceiver {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the start of a key=value pair.
|
* Parses the start of a key=value pair.
|
||||||
*
|
|
||||||
* @param line - full line of text to parse
|
* @param line - full line of text to parse
|
||||||
* @param valueStartPos - the starting position of the value in the given line
|
* @param valueStartPos - the starting position of the value in the given line
|
||||||
*/
|
*/
|
||||||
@@ -245,25 +188,20 @@ public class InstrumentationResultParser extends MultiLineReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses out a status code result.
|
* Parses out a status code result. For consistency, stores the result as a CODE entry in
|
||||||
|
* key-value status map
|
||||||
*/
|
*/
|
||||||
private void parseStatusCode(String line) {
|
private void parseStatusCode(String line) {
|
||||||
String value = line.substring(Prefixes.STATUS_CODE.length()).trim();
|
String value = line.substring(STATUS_PREFIX_CODE.length()).trim();
|
||||||
TestResult testInfo = getCurrentTestInfo();
|
mStatusValues.put(CODE_KEY, value);
|
||||||
try {
|
|
||||||
testInfo.mCode = Integer.parseInt(value);
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e) {
|
|
||||||
Log.e(LOG_TAG, "Expected integer status code, received: " + value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this means we're done with current test result bundle
|
// this means we're done with current test result bundle
|
||||||
reportResult(testInfo);
|
reportResult(mStatusValues);
|
||||||
clearCurrentTestInfo();
|
mStatusValues.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if test run canceled.
|
* Returns true if test run canceled
|
||||||
*
|
*
|
||||||
* @see IShellOutputReceiver#isCancelled()
|
* @see IShellOutputReceiver#isCancelled()
|
||||||
*/
|
*/
|
||||||
@@ -272,7 +210,7 @@ public class InstrumentationResultParser extends MultiLineReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests cancellation of test run.
|
* Requests cancellation of test result parsing
|
||||||
*/
|
*/
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
mIsCancelled = true;
|
mIsCancelled = true;
|
||||||
@@ -281,62 +219,82 @@ public class InstrumentationResultParser extends MultiLineReceiver {
|
|||||||
/**
|
/**
|
||||||
* Reports a test result to the test run listener. Must be called when a individual test
|
* Reports a test result to the test run listener. Must be called when a individual test
|
||||||
* result has been fully parsed.
|
* result has been fully parsed.
|
||||||
*
|
* @param statusMap - key-value status pairs of test result
|
||||||
* @param statusMap key-value status pairs of test result
|
|
||||||
*/
|
*/
|
||||||
private void reportResult(TestResult testInfo) {
|
private void reportResult(Map<String, String> statusMap) {
|
||||||
if (!testInfo.isComplete()) {
|
String className = statusMap.get(CLASS_KEY);
|
||||||
Log.e(LOG_TAG, "invalid instrumentation status bundle " + testInfo.toString());
|
String testName = statusMap.get(TEST_KEY);
|
||||||
|
String statusCodeString = statusMap.get(CODE_KEY);
|
||||||
|
|
||||||
|
if (className == null || testName == null || statusCodeString == null) {
|
||||||
|
Log.e(LOG_TAG, "invalid instrumentation status bundle " + statusMap.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reportTestRunStarted(testInfo);
|
className = className.trim();
|
||||||
TestIdentifier testId = new TestIdentifier(testInfo.mTestClass, testInfo.mTestName);
|
testName = testName.trim();
|
||||||
|
|
||||||
switch (testInfo.mCode) {
|
reportTestStarted(statusMap);
|
||||||
case StatusCodes.START:
|
|
||||||
mTestListener.testStarted(testId);
|
try {
|
||||||
|
int statusCode = Integer.parseInt(statusCodeString);
|
||||||
|
|
||||||
|
switch (statusCode) {
|
||||||
|
case START_STATUS_CODE:
|
||||||
|
mTestListener.testStarted(className, testName);
|
||||||
break;
|
break;
|
||||||
case StatusCodes.FAILURE:
|
case FAILURE_STATUS_CODE:
|
||||||
mTestListener.testFailed(ITestRunListener.TestFailure.FAILURE, testId,
|
mTestListener.testFailed(ITestRunListener.STATUS_FAILURE, className, testName,
|
||||||
getTrace(testInfo));
|
getTrace(statusMap));
|
||||||
mTestListener.testEnded(testId);
|
mTestListener.testEnded(className, testName);
|
||||||
break;
|
break;
|
||||||
case StatusCodes.ERROR:
|
case ERROR_STATUS_CODE:
|
||||||
mTestListener.testFailed(ITestRunListener.TestFailure.ERROR, testId,
|
mTestListener.testFailed(ITestRunListener.STATUS_ERROR, className, testName,
|
||||||
getTrace(testInfo));
|
getTrace(statusMap));
|
||||||
mTestListener.testEnded(testId);
|
mTestListener.testEnded(className, testName);
|
||||||
break;
|
break;
|
||||||
case StatusCodes.OK:
|
case OK_STATUS_CODE:
|
||||||
mTestListener.testEnded(testId);
|
mTestListener.testEnded(className, testName);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.e(LOG_TAG, "Unknown status code received: " + testInfo.mCode);
|
Log.e(LOG_TAG, "Expected status code, received: " + statusCodeString);
|
||||||
mTestListener.testEnded(testId);
|
mTestListener.testEnded(className, testName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
Log.e(LOG_TAG, "Expected integer status code, received: " + statusCodeString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports the start of a test run, and the total test count, if it has not been previously
|
* Reports the start of a test run, and the total test count, if it has not been previously
|
||||||
* reported.
|
* reported
|
||||||
*
|
* @param statusMap - key-value status pairs
|
||||||
* @param testInfo current test status values
|
|
||||||
*/
|
*/
|
||||||
private void reportTestRunStarted(TestResult testInfo) {
|
private void reportTestStarted(Map<String, String> statusMap) {
|
||||||
// if start test run not reported yet
|
// if start test run not reported yet
|
||||||
if (!mTestStartReported && testInfo.mNumTests != null) {
|
if (!mTestStartReported) {
|
||||||
mTestListener.testRunStarted(testInfo.mNumTests);
|
String numTestsString = statusMap.get(NUMTESTS_KEY);
|
||||||
|
if (numTestsString != null) {
|
||||||
|
try {
|
||||||
|
int numTests = Integer.parseInt(numTestsString);
|
||||||
|
mTestListener.testRunStarted(numTests);
|
||||||
mTestStartReported = true;
|
mTestStartReported = true;
|
||||||
}
|
}
|
||||||
|
catch (NumberFormatException e) {
|
||||||
|
Log.e(LOG_TAG, "Unexpected numTests format " + numTestsString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the stack trace of the current failed test, from the provided testInfo.
|
* Returns the stack trace of the current failed test, from the provided key-value status map
|
||||||
*/
|
*/
|
||||||
private String getTrace(TestResult testInfo) {
|
private String getTrace(Map<String, String> statusMap) {
|
||||||
if (testInfo.mStackTrace != null) {
|
String stackTrace = statusMap.get(STACK_KEY);
|
||||||
return testInfo.mStackTrace;
|
if (stackTrace != null) {
|
||||||
|
return stackTrace;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Log.e(LOG_TAG, "Could not find stack trace for failed test ");
|
Log.e(LOG_TAG, "Could not find stack trace for failed test ");
|
||||||
@@ -345,7 +303,7 @@ public class InstrumentationResultParser extends MultiLineReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses out and store the elapsed time.
|
* Parses out and store the elapsed time
|
||||||
*/
|
*/
|
||||||
private void parseTime(String line, int startPos) {
|
private void parseTime(String line, int startPos) {
|
||||||
String timeString = line.substring(startPos);
|
String timeString = line.substring(startPos);
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import com.android.ddmlib.Log;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs a Android test command remotely and reports results.
|
* Runs a Android test command remotely and reports results
|
||||||
*/
|
*/
|
||||||
public class RemoteAndroidTestRunner {
|
public class RemoteAndroidTestRunner {
|
||||||
|
|
||||||
@@ -43,12 +43,11 @@ public class RemoteAndroidTestRunner {
|
|||||||
"android.test.InstrumentationTestRunner";
|
"android.test.InstrumentationTestRunner";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a remote Android test runner.
|
* Creates a remote android test runner.
|
||||||
*
|
* @param packageName - the Android application package that contains the tests to run
|
||||||
* @param packageName the Android application package that contains the tests to run
|
* @param runnerName - the instrumentation test runner to execute. If null, will use default
|
||||||
* @param runnerName the instrumentation test runner to execute. If null, will use default
|
|
||||||
* runner
|
* runner
|
||||||
* @param remoteDevice the Android device to execute tests on
|
* @param remoteDevice - the Android device to execute tests on
|
||||||
*/
|
*/
|
||||||
public RemoteAndroidTestRunner(String packageName,
|
public RemoteAndroidTestRunner(String packageName,
|
||||||
String runnerName,
|
String runnerName,
|
||||||
@@ -63,10 +62,9 @@ public class RemoteAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alternate constructor. Uses default instrumentation runner.
|
* Alternate constructor. Uses default instrumentation runner
|
||||||
*
|
* @param packageName - the Android application package that contains the tests to run
|
||||||
* @param packageName the Android application package that contains the tests to run
|
* @param remoteDevice - the Android device to execute tests on
|
||||||
* @param remoteDevice the Android device to execute tests on
|
|
||||||
*/
|
*/
|
||||||
public RemoteAndroidTestRunner(String packageName,
|
public RemoteAndroidTestRunner(String packageName,
|
||||||
IDevice remoteDevice) {
|
IDevice remoteDevice) {
|
||||||
@@ -74,14 +72,14 @@ public class RemoteAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the application package name.
|
* Returns the application package name
|
||||||
*/
|
*/
|
||||||
public String getPackageName() {
|
public String getPackageName() {
|
||||||
return mPackageName;
|
return mPackageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the runnerName.
|
* Returns the runnerName
|
||||||
*/
|
*/
|
||||||
public String getRunnerName() {
|
public String getRunnerName() {
|
||||||
if (mRunnerName == null) {
|
if (mRunnerName == null) {
|
||||||
@@ -91,7 +89,7 @@ public class RemoteAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the complete instrumentation component path.
|
* Returns the complete instrumentation component path
|
||||||
*/
|
*/
|
||||||
private String getRunnerPath() {
|
private String getRunnerPath() {
|
||||||
return getPackageName() + RUNNER_SEPARATOR + getRunnerName();
|
return getPackageName() + RUNNER_SEPARATOR + getRunnerName();
|
||||||
@@ -99,9 +97,8 @@ public class RemoteAndroidTestRunner {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets to run only tests in this class
|
* Sets to run only tests in this class
|
||||||
* Must be called before 'run'.
|
* Must be called before 'run'
|
||||||
*
|
* @param className - fully qualified class name (eg x.y.z)
|
||||||
* @param className fully qualified class name (eg x.y.z)
|
|
||||||
*/
|
*/
|
||||||
public void setClassName(String className) {
|
public void setClassName(String className) {
|
||||||
mClassArg = className;
|
mClassArg = className;
|
||||||
@@ -109,12 +106,10 @@ public class RemoteAndroidTestRunner {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets to run only tests in the provided classes
|
* Sets to run only tests in the provided classes
|
||||||
* Must be called before 'run'.
|
* Must be called before 'run'
|
||||||
* <p>
|
|
||||||
* If providing more than one class, requires a InstrumentationTestRunner that supports
|
* If providing more than one class, requires a InstrumentationTestRunner that supports
|
||||||
* the multiple class argument syntax.
|
* the multiple class argument syntax
|
||||||
*
|
* @param classNames - array of fully qualified class name (eg x.y.z)
|
||||||
* @param classNames array of fully qualified class names (eg x.y.z)
|
|
||||||
*/
|
*/
|
||||||
public void setClassNames(String[] classNames) {
|
public void setClassNames(String[] classNames) {
|
||||||
StringBuilder classArgBuilder = new StringBuilder();
|
StringBuilder classArgBuilder = new StringBuilder();
|
||||||
@@ -130,10 +125,9 @@ public class RemoteAndroidTestRunner {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets to run only specified test method
|
* Sets to run only specified test method
|
||||||
* Must be called before 'run'.
|
* Must be called before 'run'
|
||||||
*
|
* @param className - fully qualified class name (eg x.y.z)
|
||||||
* @param className fully qualified class name (eg x.y.z)
|
* @param testName - method name
|
||||||
* @param testName method name
|
|
||||||
*/
|
*/
|
||||||
public void setMethodName(String className, String testName) {
|
public void setMethodName(String className, String testName) {
|
||||||
mClassArg = className + METHOD_SEPARATOR + testName;
|
mClassArg = className + METHOD_SEPARATOR + testName;
|
||||||
@@ -141,9 +135,8 @@ public class RemoteAndroidTestRunner {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets extra arguments to include in instrumentation command.
|
* Sets extra arguments to include in instrumentation command.
|
||||||
* Must be called before 'run'.
|
* Must be called before 'run'
|
||||||
*
|
* @param instrumentationArgs - must not be null
|
||||||
* @param instrumentationArgs must not be null
|
|
||||||
*/
|
*/
|
||||||
public void setExtraArgs(String instrumentationArgs) {
|
public void setExtraArgs(String instrumentationArgs) {
|
||||||
if (instrumentationArgs == null) {
|
if (instrumentationArgs == null) {
|
||||||
@@ -153,23 +146,23 @@ public class RemoteAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the extra instrumentation arguments.
|
* Returns the extra instrumentation arguments
|
||||||
*/
|
*/
|
||||||
public String getExtraArgs() {
|
public String getExtraArgs() {
|
||||||
return mExtraArgs;
|
return mExtraArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets this test run to log only mode - skips test execution.
|
* Sets this test run to log only mode - skips test execution
|
||||||
*/
|
*/
|
||||||
public void setLogOnly(boolean logOnly) {
|
public void setLogOnly(boolean logOnly) {
|
||||||
mLogOnlyMode = logOnly;
|
mLogOnlyMode = logOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute this test run.
|
* Execute this test run
|
||||||
*
|
*
|
||||||
* @param listener listens for test results
|
* @param listener - listener to report results to
|
||||||
*/
|
*/
|
||||||
public void run(ITestRunListener listener) {
|
public void run(ITestRunListener listener) {
|
||||||
final String runCaseCommandStr = "am instrument -w -r "
|
final String runCaseCommandStr = "am instrument -w -r "
|
||||||
@@ -186,7 +179,7 @@ public class RemoteAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests cancellation of this test run.
|
* Requests cancellation of this test run
|
||||||
*/
|
*/
|
||||||
public void cancel() {
|
public void cancel() {
|
||||||
if (mParser != null) {
|
if (mParser != null) {
|
||||||
@@ -195,7 +188,7 @@ public class RemoteAndroidTestRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the test class argument.
|
* Returns the test class argument
|
||||||
*/
|
*/
|
||||||
private String getClassArg() {
|
private String getClassArg() {
|
||||||
return mClassArg;
|
return mClassArg;
|
||||||
@@ -203,7 +196,7 @@ public class RemoteAndroidTestRunner {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full instrumentation command which specifies the test classes to execute.
|
* Returns the full instrumentation command which specifies the test classes to execute.
|
||||||
* Returns an empty string if no classes were specified.
|
* Returns an empty string if no classes were specified
|
||||||
*/
|
*/
|
||||||
private String getClassCmd() {
|
private String getClassCmd() {
|
||||||
String classArg = getClassArg();
|
String classArg = getClassArg();
|
||||||
@@ -215,7 +208,7 @@ public class RemoteAndroidTestRunner {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full command to enable log only mode - if specified. Otherwise returns an
|
* Returns the full command to enable log only mode - if specified. Otherwise returns an
|
||||||
* empty string.
|
* empty string
|
||||||
*/
|
*/
|
||||||
private String getLogCmd() {
|
private String getLogCmd() {
|
||||||
if (mLogOnlyMode) {
|
if (mLogOnlyMode) {
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.ddmlib.testrunner;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Identifies a parsed instrumentation test
|
|
||||||
*/
|
|
||||||
public class TestIdentifier {
|
|
||||||
|
|
||||||
private final String mClassName;
|
|
||||||
private final String mTestName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a test identifier
|
|
||||||
*
|
|
||||||
* @param className fully qualified class name of the test. Cannot be null.
|
|
||||||
* @param testName name of the test. Cannot be null.
|
|
||||||
*/
|
|
||||||
public TestIdentifier(String className, String testName) {
|
|
||||||
if (className == null || testName == null) {
|
|
||||||
throw new IllegalArgumentException("className and testName must " +
|
|
||||||
"be non-null");
|
|
||||||
}
|
|
||||||
mClassName = className;
|
|
||||||
mTestName = testName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the fully qualified class name of the test
|
|
||||||
*/
|
|
||||||
public String getClassName() {
|
|
||||||
return mClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the test
|
|
||||||
*/
|
|
||||||
public String getTestName() {
|
|
||||||
return mTestName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests equality by comparing class and method name
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
if (!(other instanceof TestIdentifier)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
TestIdentifier otherTest = (TestIdentifier)other;
|
|
||||||
return getClassName().equals(otherTest.getClassName()) &&
|
|
||||||
getTestName().equals(otherTest.getTestName());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates hashCode based on class and method name.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return getClassName().hashCode() * 31 + getTestName().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ import junit.framework.TestCase;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests InstrumentationResultParser.
|
* Tests InstrumentationResultParser
|
||||||
*/
|
*/
|
||||||
public class InstrumentationResultParserTest extends TestCase {
|
public class InstrumentationResultParserTest extends TestCase {
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that the test run started and test start events is sent on first
|
* Tests that the test run started and test start events is sent on first
|
||||||
* bundle received.
|
* bundle received
|
||||||
*/
|
*/
|
||||||
public void testTestStarted() {
|
public void testTestStarted() {
|
||||||
StringBuilder output = buildCommonResult();
|
StringBuilder output = buildCommonResult();
|
||||||
@@ -63,7 +63,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that a single successful test execution.
|
* Tests that a single successful test execution
|
||||||
*/
|
*/
|
||||||
public void testTestSuccess() {
|
public void testTestSuccess() {
|
||||||
StringBuilder output = buildCommonResult();
|
StringBuilder output = buildCommonResult();
|
||||||
@@ -74,11 +74,11 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
injectTestString(output.toString());
|
injectTestString(output.toString());
|
||||||
assertCommonAttributes();
|
assertCommonAttributes();
|
||||||
assertEquals(1, mTestResult.mNumTestsRun);
|
assertEquals(1, mTestResult.mNumTestsRun);
|
||||||
assertEquals(null, mTestResult.mTestStatus);
|
assertEquals(0, mTestResult.mTestStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test basic parsing of failed test case.
|
* Test basic parsing of failed test case
|
||||||
*/
|
*/
|
||||||
public void testTestFailed() {
|
public void testTestFailed() {
|
||||||
StringBuilder output = buildCommonResult();
|
StringBuilder output = buildCommonResult();
|
||||||
@@ -91,12 +91,12 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
assertCommonAttributes();
|
assertCommonAttributes();
|
||||||
|
|
||||||
assertEquals(1, mTestResult.mNumTestsRun);
|
assertEquals(1, mTestResult.mNumTestsRun);
|
||||||
assertEquals(ITestRunListener.TestFailure.FAILURE, mTestResult.mTestStatus);
|
assertEquals(ITestRunListener.STATUS_FAILURE, mTestResult.mTestStatus);
|
||||||
assertEquals(STACK_TRACE, mTestResult.mTrace);
|
assertEquals(STACK_TRACE, mTestResult.mTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test basic parsing and conversion of time from output.
|
* Test basic parsing and conversion of time from output
|
||||||
*/
|
*/
|
||||||
public void testTimeParsing() {
|
public void testTimeParsing() {
|
||||||
final String timeString = "Time: 4.9";
|
final String timeString = "Time: 4.9";
|
||||||
@@ -105,7 +105,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* builds a common test result using TEST_NAME and TEST_CLASS.
|
* builds a common test result using TEST_NAME and TEST_CLASS
|
||||||
*/
|
*/
|
||||||
private StringBuilder buildCommonResult() {
|
private StringBuilder buildCommonResult() {
|
||||||
StringBuilder output = new StringBuilder();
|
StringBuilder output = new StringBuilder();
|
||||||
@@ -118,7 +118,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds common status results to the provided output.
|
* Adds common status results to the provided output
|
||||||
*/
|
*/
|
||||||
private void addCommonStatus(StringBuilder output) {
|
private void addCommonStatus(StringBuilder output) {
|
||||||
addStatusKey(output, "stream", "\r\n" + CLASS_NAME);
|
addStatusKey(output, "stream", "\r\n" + CLASS_NAME);
|
||||||
@@ -130,7 +130,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a stack trace status bundle to output.
|
* Adds a stack trace status bundle to output
|
||||||
*/
|
*/
|
||||||
private void addStackTrace(StringBuilder output) {
|
private void addStackTrace(StringBuilder output) {
|
||||||
addStatusKey(output, "stack", STACK_TRACE);
|
addStatusKey(output, "stack", STACK_TRACE);
|
||||||
@@ -138,7 +138,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to add a status key-value bundle.
|
* Helper method to add a status key-value bundle
|
||||||
*/
|
*/
|
||||||
private void addStatusKey(StringBuilder outputBuilder, String key,
|
private void addStatusKey(StringBuilder outputBuilder, String key,
|
||||||
String value) {
|
String value) {
|
||||||
@@ -168,7 +168,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* inject a test string into the result parser.
|
* inject a test string into the result parser
|
||||||
*
|
*
|
||||||
* @param result
|
* @param result
|
||||||
*/
|
*/
|
||||||
@@ -185,7 +185,7 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialized test listener that stores a single test events.
|
* A specialized test listener that stores a single test events
|
||||||
*/
|
*/
|
||||||
private class VerifyingTestResult implements ITestRunListener {
|
private class VerifyingTestResult implements ITestRunListener {
|
||||||
|
|
||||||
@@ -194,28 +194,29 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
int mNumTestsRun;
|
int mNumTestsRun;
|
||||||
String mTestName;
|
String mTestName;
|
||||||
long mTestTime;
|
long mTestTime;
|
||||||
TestFailure mTestStatus;
|
int mTestStatus;
|
||||||
String mTrace;
|
String mTrace;
|
||||||
boolean mStopped;
|
boolean mStopped;
|
||||||
|
|
||||||
VerifyingTestResult() {
|
VerifyingTestResult() {
|
||||||
mNumTestsRun = 0;
|
mNumTestsRun = 0;
|
||||||
mTestStatus = null;
|
mTestStatus = 0;
|
||||||
mStopped = false;
|
mStopped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEnded(TestIdentifier test) {
|
public void testEnded(String className, String testName) {
|
||||||
mNumTestsRun++;
|
mNumTestsRun++;
|
||||||
assertEquals("Unexpected class name", mSuiteName, test.getClassName());
|
assertEquals("Unexpected class name", mSuiteName, className);
|
||||||
assertEquals("Unexpected test ended", mTestName, test.getTestName());
|
assertEquals("Unexpected test ended", mTestName, testName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFailed(TestFailure status, TestIdentifier test, String trace) {
|
public void testFailed(int status, String className, String testName,
|
||||||
|
String trace) {
|
||||||
mTestStatus = status;
|
mTestStatus = status;
|
||||||
mTrace = trace;
|
mTrace = trace;
|
||||||
assertEquals("Unexpected class name", mSuiteName, test.getClassName());
|
assertEquals("Unexpected class name", mSuiteName, className);
|
||||||
assertEquals("Unexpected test ended", mTestName, test.getTestName());
|
assertEquals("Unexpected test ended", mTestName, testName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRunEnded(long elapsedTime) {
|
public void testRunEnded(long elapsedTime) {
|
||||||
@@ -232,9 +233,9 @@ public class InstrumentationResultParserTest extends TestCase {
|
|||||||
mStopped = true;
|
mStopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStarted(TestIdentifier test) {
|
public void testStarted(String className, String testName) {
|
||||||
mSuiteName = test.getClassName();
|
mSuiteName = className;
|
||||||
mTestName = test.getTestName();
|
mTestName = testName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRunFailed(String errorMessage) {
|
public void testRunFailed(String errorMessage) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import java.io.IOException;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests RemoteAndroidTestRunner.
|
* Test RemoteAndroidTestRunner.
|
||||||
*/
|
*/
|
||||||
public class RemoteAndroidTestRunnerTest extends TestCase {
|
public class RemoteAndroidTestRunnerTest extends TestCase {
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the basic case building of the instrumentation runner command with no arguments.
|
* Test the basic case building of the instrumentation runner command with no arguments
|
||||||
*/
|
*/
|
||||||
public void testRun() {
|
public void testRun() {
|
||||||
mRunner.run(new EmptyListener());
|
mRunner.run(new EmptyListener());
|
||||||
@@ -60,7 +60,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the building of the instrumentation runner command with log set.
|
* Test the building of the instrumentation runner command with log set
|
||||||
*/
|
*/
|
||||||
public void testRunWithLog() {
|
public void testRunWithLog() {
|
||||||
mRunner.setLogOnly(true);
|
mRunner.setLogOnly(true);
|
||||||
@@ -70,7 +70,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the building of the instrumentation runner command with method set.
|
* Test the building of the instrumentation runner command with method set
|
||||||
*/
|
*/
|
||||||
public void testRunWithMethod() {
|
public void testRunWithMethod() {
|
||||||
final String className = "FooTest";
|
final String className = "FooTest";
|
||||||
@@ -82,7 +82,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the building of the instrumentation runner command with extra args set.
|
* Test the building of the instrumentation runner command with extra args set
|
||||||
*/
|
*/
|
||||||
public void testRunWithExtraArgs() {
|
public void testRunWithExtraArgs() {
|
||||||
final String extraArgs = "blah";
|
final String extraArgs = "blah";
|
||||||
@@ -94,7 +94,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assert two strings are equal ignoring whitespace.
|
* Assert two strings are equal ignoring whitespace
|
||||||
*/
|
*/
|
||||||
private void assertStringsEquals(String str1, String str2) {
|
private void assertStringsEquals(String str1, String str2) {
|
||||||
String strippedStr1 = str1.replaceAll(" ", "");
|
String strippedStr1 = str1.replaceAll(" ", "");
|
||||||
@@ -104,14 +104,14 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A dummy device that does nothing except store the provided executed shell command for
|
* A dummy device that does nothing except store the provided executed shell command for
|
||||||
* later retrieval.
|
* later retrieval
|
||||||
*/
|
*/
|
||||||
private static class MockDevice implements IDevice {
|
private static class MockDevice implements IDevice {
|
||||||
|
|
||||||
private String mLastShellCommand;
|
private String mLastShellCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the provided command for later retrieval from getLastShellCommand.
|
* Stores the provided command for later retrieval from getLastShellCommand
|
||||||
*/
|
*/
|
||||||
public void executeShellCommand(String command,
|
public void executeShellCommand(String command,
|
||||||
IShellOutputReceiver receiver) throws IOException {
|
IShellOutputReceiver receiver) throws IOException {
|
||||||
@@ -119,7 +119,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the last command provided to executeShellCommand.
|
* Get the last command provided to executeShellCommand
|
||||||
*/
|
*/
|
||||||
public String getLastShellCommand() {
|
public String getLastShellCommand() {
|
||||||
return mLastShellCommand;
|
return mLastShellCommand;
|
||||||
@@ -201,26 +201,22 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runLogService(String logname, LogReceiver receiver) throws IOException {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAvdName() {
|
public String getAvdName() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** An empty implementation of TestRunListener
|
||||||
* An empty implementation of ITestRunListener.
|
|
||||||
*/
|
*/
|
||||||
private static class EmptyListener implements ITestRunListener {
|
private static class EmptyListener implements ITestRunListener {
|
||||||
|
|
||||||
public void testEnded(TestIdentifier test) {
|
public void testEnded(String className, String testName) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFailed(TestFailure status, TestIdentifier test, String trace) {
|
public void testFailed(int status, String className, String testName,
|
||||||
|
String trace) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +236,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStarted(TestIdentifier test) {
|
public void testStarted(String className, String testName) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ public final class NativeHeapPanel extends BaseHeapPanel {
|
|||||||
*/
|
*/
|
||||||
private HashMap<Long, NativeStackCallInfo> mSourceCache =
|
private HashMap<Long, NativeStackCallInfo> mSourceCache =
|
||||||
new HashMap<Long,NativeStackCallInfo>();
|
new HashMap<Long,NativeStackCallInfo>();
|
||||||
private long mTotalSize;
|
private int mTotalSize;
|
||||||
private Button mSaveButton;
|
private Button mSaveButton;
|
||||||
private Button mSymbolsButton;
|
private Button mSymbolsButton;
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks,
|
|||||||
rem and set up progdir to be the fully-qualified pathname of its directory.
|
rem and set up progdir to be the fully-qualified pathname of its directory.
|
||||||
set prog=%~f0
|
set prog=%~f0
|
||||||
|
|
||||||
rem Change current directory and drive to where the script is, to avoid
|
rem Change current directory to where ddms is, to avoid issues with directories
|
||||||
rem issues with directories containing whitespaces.
|
rem containing whitespaces.
|
||||||
cd /d %~dp0
|
cd %~dp0
|
||||||
|
|
||||||
set jarfile=draw9patch.jar
|
set jarfile=draw9patch.jar
|
||||||
set frameworkdir=
|
set frameworkdir=
|
||||||
|
|||||||
@@ -1,18 +1,14 @@
|
|||||||
0.9.0 (work in progress)
|
0.9.0 (work in progress)
|
||||||
- Support for the new Android SDK with support for multiple versions of the Android platform and for vendor supplied add-ons.
|
- Support for SDK with multiple versions of the Android platform and vendor supplied add-ons.
|
||||||
* New Project Wizard lets you choose which platform/add-on to target.
|
|
||||||
* Project properties (right click project in Package Explorer, then "Properties"), lets you edit project target.
|
|
||||||
* New Launch configuration option to choose debug deployment target.
|
|
||||||
- Ability to export multiple apk from one project, using resource filters. See the 'android' property for Android projects.
|
|
||||||
|
|
||||||
0.8.1:
|
0.8.1:
|
||||||
|
|
||||||
- Alternate Layout wizard. In the layout editor, the "create" button is now enabled to easily create alternate versions of the current layout.
|
- Alternate Layout wizard. In the layout editor, the "create" button is now enabled, and allows to easily create alternate versions.
|
||||||
- Fixed issue with custom themes/styles in the layout editor.
|
- Fixed issue with custom themes/styles in the layout editor.
|
||||||
- Export Wizard: To export an application for release, and sign it with a non debug key. Accessible from the export menu, from the Android Tools contextual menu, or from the overview page of the manifest editor.
|
- Export Wizard: To export an application for release, sign with a non debug key. Accessible from the export menu, from the Android Tools contextual menu, or from the overview page of the manifest editor.
|
||||||
- New XML File Wizard: To easily create new XML resources file in the /res directory.
|
- New XML File Wizard: To easily create new XML resources file in the /res directory.
|
||||||
- New checks on launch when attempting to debug on a device.
|
- New checks on launch when attempting to debug on a device.
|
||||||
- Basic support for drag'n'drop in Graphical layout editor. You can add new items by drag'n'drop from the palette. There is no support for moving/resizing yet.
|
- Basic support for drag'n'drop in Graphical layout editor. You can add new items by drag'n'drop from the palette. There's is no support for moving/resizing yet.
|
||||||
- Undo/redo support in all XML form editors and Graphical layout editor.
|
- Undo/redo support in all XML form editors and Graphical layout editor.
|
||||||
|
|
||||||
0.8.0:
|
0.8.0:
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 664 B |
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB |
@@ -17,14 +17,6 @@
|
|||||||
<super type="org.eclipse.core.resources.textmarker"/>
|
<super type="org.eclipse.core.resources.textmarker"/>
|
||||||
<persistent value="true"/>
|
<persistent value="true"/>
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
|
||||||
id="com.android.ide.eclipse.common.aapt2Problem"
|
|
||||||
name="Android AAPT Problem"
|
|
||||||
point="org.eclipse.core.resources.markers">
|
|
||||||
<super type="org.eclipse.core.resources.problemmarker"/>
|
|
||||||
<super type="org.eclipse.core.resources.textmarker"/>
|
|
||||||
<persistent value="true"/>
|
|
||||||
</extension>
|
|
||||||
<extension
|
<extension
|
||||||
id="com.android.ide.eclipse.common.aidlProblem"
|
id="com.android.ide.eclipse.common.aidlProblem"
|
||||||
name="Android AIDL Problem"
|
name="Android AIDL Problem"
|
||||||
@@ -472,31 +464,4 @@
|
|||||||
</enabledWhen>
|
</enabledWhen>
|
||||||
</page>
|
</page>
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
|
||||||
point="org.eclipse.ui.actionSets">
|
|
||||||
<actionSet
|
|
||||||
description="Android Wizards"
|
|
||||||
id="adt.actionSet1"
|
|
||||||
label="Android Wizards"
|
|
||||||
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
|
|
||||||
class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
|
|
||||||
icon="icons/new_xml.png"
|
|
||||||
id="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
|
|
||||||
label="New Android XML File"
|
|
||||||
style="push"
|
|
||||||
toolbarPath="android_project"
|
|
||||||
tooltip="Opens a wizard to help create a new Android XML file">
|
|
||||||
</action>
|
|
||||||
</actionSet>
|
|
||||||
</extension>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerIni
|
|||||||
import com.android.ide.eclipse.adt.sdk.AndroidTargetParser;
|
import com.android.ide.eclipse.adt.sdk.AndroidTargetParser;
|
||||||
import com.android.ide.eclipse.adt.sdk.LoadStatus;
|
import com.android.ide.eclipse.adt.sdk.LoadStatus;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
|
|
||||||
import com.android.ide.eclipse.common.AndroidConstants;
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.common.EclipseUiHelper;
|
import com.android.ide.eclipse.common.EclipseUiHelper;
|
||||||
import com.android.ide.eclipse.common.SdkStatsHelper;
|
import com.android.ide.eclipse.common.SdkStatsHelper;
|
||||||
@@ -174,8 +173,7 @@ public class AdtPlugin extends AbstractUIPlugin {
|
|||||||
private final ArrayList<IJavaProject> mPostLoadProjectsToCheck = new ArrayList<IJavaProject>();
|
private final ArrayList<IJavaProject> mPostLoadProjectsToCheck = new ArrayList<IJavaProject>();
|
||||||
|
|
||||||
private ResourceMonitor mResourceMonitor;
|
private ResourceMonitor mResourceMonitor;
|
||||||
private ArrayList<ITargetChangeListener> mTargetChangeListeners =
|
private ArrayList<Runnable> mResourceRefreshListener = new ArrayList<Runnable>();
|
||||||
new ArrayList<ITargetChangeListener>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom PrintStream for Dx output. This class overrides the method
|
* Custom PrintStream for Dx output. This class overrides the method
|
||||||
@@ -863,6 +861,7 @@ public class AdtPlugin extends AbstractUIPlugin {
|
|||||||
/**
|
/**
|
||||||
* Returns the lock object for SDK loading. If you wish to do things while the SDK is loading,
|
* Returns the lock object for SDK loading. If you wish to do things while the SDK is loading,
|
||||||
* you must synchronize on this object.
|
* you must synchronize on this object.
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
public final Object getSdkLockObject() {
|
public final Object getSdkLockObject() {
|
||||||
return mPostLoadProjectsToResolve;
|
return mPostLoadProjectsToResolve;
|
||||||
@@ -987,7 +986,7 @@ public class AdtPlugin extends AbstractUIPlugin {
|
|||||||
Constants.BUNDLE_VERSION);
|
Constants.BUNDLE_VERSION);
|
||||||
Version version = new Version(versionString);
|
Version version = new Version(versionString);
|
||||||
|
|
||||||
SdkStatsHelper.pingUsageServer("adt", version); //$NON-NLS-1$
|
SdkStatsHelper.pingUsageServer("editors", version); //$NON-NLS-1$
|
||||||
|
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@@ -1020,12 +1019,8 @@ public class AdtPlugin extends AbstractUIPlugin {
|
|||||||
|
|
||||||
progress.setTaskName(Messages.AdtPlugin_Parsing_Resources);
|
progress.setTaskName(Messages.AdtPlugin_Parsing_Resources);
|
||||||
|
|
||||||
int n = sdk.getTargets().length;
|
|
||||||
if (n > 0) {
|
|
||||||
int w = 60 / n;
|
|
||||||
for (IAndroidTarget target : sdk.getTargets()) {
|
for (IAndroidTarget target : sdk.getTargets()) {
|
||||||
SubMonitor p2 = progress.newChild(w);
|
IStatus status = new AndroidTargetParser(target).run(progress);
|
||||||
IStatus status = new AndroidTargetParser(target).run(p2);
|
|
||||||
if (status.getCode() != IStatus.OK) {
|
if (status.getCode() != IStatus.OK) {
|
||||||
synchronized (getSdkLockObject()) {
|
synchronized (getSdkLockObject()) {
|
||||||
mSdkIsLoaded = LoadStatus.FAILED;
|
mSdkIsLoaded = LoadStatus.FAILED;
|
||||||
@@ -1034,13 +1029,14 @@ public class AdtPlugin extends AbstractUIPlugin {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
// FIXME: move this per platform, or somewhere else.
|
||||||
|
progress = SubMonitor.convert(monitor,
|
||||||
|
Messages.AdtPlugin_Parsing_Resources, 20);
|
||||||
|
|
||||||
synchronized (getSdkLockObject()) {
|
synchronized (getSdkLockObject()) {
|
||||||
mSdkIsLoaded = LoadStatus.LOADED;
|
mSdkIsLoaded = LoadStatus.LOADED;
|
||||||
|
|
||||||
progress.setTaskName("Check Projects");
|
|
||||||
|
|
||||||
// check the projects that need checking.
|
// check the projects that need checking.
|
||||||
// The method modifies the list (it removes the project that
|
// The method modifies the list (it removes the project that
|
||||||
// do not need to be resolved again).
|
// do not need to be resolved again).
|
||||||
@@ -1056,33 +1052,25 @@ public class AdtPlugin extends AbstractUIPlugin {
|
|||||||
AndroidClasspathContainerInitializer.updateProjects(array);
|
AndroidClasspathContainerInitializer.updateProjects(array);
|
||||||
mPostLoadProjectsToResolve.clear();
|
mPostLoadProjectsToResolve.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.worked(10);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify resource changed listeners
|
// Notify resource changed listeners
|
||||||
progress.setTaskName("Refresh UI");
|
progress.subTask("Refresh UI");
|
||||||
progress.setWorkRemaining(mTargetChangeListeners.size());
|
progress.setWorkRemaining(mResourceRefreshListener.size());
|
||||||
|
|
||||||
// Clone the list before iterating, to avoid Concurrent Modification
|
// Clone the list before iterating, to avoid Concurrent Modification
|
||||||
// exceptions
|
// exceptions
|
||||||
final List<ITargetChangeListener> listeners =
|
List<Runnable> listeners = (List<Runnable>)mResourceRefreshListener.clone();
|
||||||
(List<ITargetChangeListener>)mTargetChangeListeners.clone();
|
for (Runnable listener : listeners) {
|
||||||
final SubMonitor progress2 = progress;
|
|
||||||
AdtPlugin.getDisplay().syncExec(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
for (ITargetChangeListener listener : listeners) {
|
|
||||||
try {
|
try {
|
||||||
listener.onTargetsLoaded();
|
AdtPlugin.getDisplay().syncExec(listener);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
AdtPlugin.log(e, "Failed to update a TargetChangeListener."); //$NON-NLS-1$
|
AdtPlugin.log(e, "ResourceRefreshListener Failed"); //$NON-NLS-1$
|
||||||
} finally {
|
} finally {
|
||||||
progress2.worked(1);
|
progress.worked(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
} finally {
|
} finally {
|
||||||
if (monitor != null) {
|
if (monitor != null) {
|
||||||
monitor.done();
|
monitor.done();
|
||||||
@@ -1328,42 +1316,12 @@ public class AdtPlugin extends AbstractUIPlugin {
|
|||||||
}, IResourceDelta.ADDED | IResourceDelta.CHANGED);
|
}, IResourceDelta.ADDED | IResourceDelta.CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void addResourceChangedListener(Runnable resourceRefreshListener) {
|
||||||
* Adds a new {@link ITargetChangeListener} to be notified when a new SDK is loaded, or when
|
mResourceRefreshListener.add(resourceRefreshListener);
|
||||||
* a project has its target changed.
|
|
||||||
*/
|
|
||||||
public void addTargetListener(ITargetChangeListener listener) {
|
|
||||||
mTargetChangeListeners.add(listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void removeResourceChangedListener(Runnable resourceRefreshListener) {
|
||||||
* Removes an existing {@link ITargetChangeListener}.
|
mResourceRefreshListener.remove(resourceRefreshListener);
|
||||||
* @see #addTargetListener(ITargetChangeListener)
|
|
||||||
*/
|
|
||||||
public void removeTargetListener(ITargetChangeListener listener) {
|
|
||||||
mTargetChangeListeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates all the {@link ITargetChangeListener} that a target has changed for a given project.
|
|
||||||
* <p/>Only editors related to that project should reload.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void updateTargetListener(final IProject project) {
|
|
||||||
final List<ITargetChangeListener> listeners =
|
|
||||||
(List<ITargetChangeListener>)mTargetChangeListeners.clone();
|
|
||||||
|
|
||||||
AdtPlugin.getDisplay().asyncExec(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
for (ITargetChangeListener listener : listeners) {
|
|
||||||
try {
|
|
||||||
listener.onProjectTargetChange(project);
|
|
||||||
} catch (Exception e) {
|
|
||||||
AdtPlugin.log(e, "Failed to update a TargetChangeListener."); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized OutputStream getErrorStream() {
|
public static synchronized OutputStream getErrorStream() {
|
||||||
|
|||||||
@@ -203,9 +203,6 @@ public class ApkBuilder extends BaseBuilder {
|
|||||||
// get a project object
|
// get a project object
|
||||||
IProject project = getProject();
|
IProject project = getProject();
|
||||||
|
|
||||||
// Top level check to make sure the build can move forward.
|
|
||||||
abortOnBadSetup(project);
|
|
||||||
|
|
||||||
// get the list of referenced projects.
|
// get the list of referenced projects.
|
||||||
IProject[] referencedProjects = ProjectHelper.getReferencedProjects(project);
|
IProject[] referencedProjects = ProjectHelper.getReferencedProjects(project);
|
||||||
IJavaProject[] referencedJavaProjects = getJavaProjects(referencedProjects);
|
IJavaProject[] referencedJavaProjects = getJavaProjects(referencedProjects);
|
||||||
@@ -266,11 +263,68 @@ public class ApkBuilder extends BaseBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do some extra check, in case the output files are not present. This
|
||||||
|
// will force to recreate them.
|
||||||
|
IResource tmp = null;
|
||||||
|
|
||||||
|
if (mPackageResources == false && outputFolder != null) {
|
||||||
|
tmp = outputFolder.findMember(AndroidConstants.FN_RESOURCES_AP_);
|
||||||
|
if (tmp == null || tmp.exists() == false) {
|
||||||
|
mPackageResources = true;
|
||||||
|
mBuildFinalPackage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mConvertToDex == false && outputFolder != null) {
|
||||||
|
tmp = outputFolder.findMember(AndroidConstants.FN_CLASSES_DEX);
|
||||||
|
if (tmp == null || tmp.exists() == false) {
|
||||||
|
mConvertToDex = true;
|
||||||
|
mBuildFinalPackage = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the extra configs for the project. This will give us a list of custom apk
|
||||||
|
// to build based on a restricted set of resources.
|
||||||
|
Map<String, String> configs = Sdk.getCurrent().getProjectApkConfigs(project);
|
||||||
|
|
||||||
|
// also check the final file(s)!
|
||||||
|
String finalPackageName = getFileName(project, null /*config*/);
|
||||||
|
if (mBuildFinalPackage == false && outputFolder != null) {
|
||||||
|
tmp = outputFolder.findMember(finalPackageName);
|
||||||
|
if (tmp == null || (tmp instanceof IFile &&
|
||||||
|
tmp.exists() == false)) {
|
||||||
|
String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName);
|
||||||
|
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
|
||||||
|
mBuildFinalPackage = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configs != null) {
|
||||||
|
Set<Entry<String, String>> entrySet = configs.entrySet();
|
||||||
|
|
||||||
|
for (Entry<String, String> entry : entrySet) {
|
||||||
|
String filename = getFileName(project, entry.getKey());
|
||||||
|
|
||||||
|
tmp = outputFolder.findMember(filename);
|
||||||
|
if (tmp == null || (tmp instanceof IFile &&
|
||||||
|
tmp.exists() == false)) {
|
||||||
|
String msg = String.format(Messages.s_Missing_Repackaging,
|
||||||
|
finalPackageName);
|
||||||
|
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
|
||||||
|
mBuildFinalPackage = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// store the build status in the persistent storage
|
// store the build status in the persistent storage
|
||||||
saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , mConvertToDex);
|
saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , mConvertToDex);
|
||||||
saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
|
saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources);
|
||||||
saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
|
saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage);
|
||||||
|
|
||||||
|
// At this point, we can abort the build if we have to, as we have computed
|
||||||
|
// our resource delta and stored the result.
|
||||||
|
abortOnBadSetup(project);
|
||||||
|
|
||||||
if (dv != null && dv.mXmlError) {
|
if (dv != null && dv.mXmlError) {
|
||||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
|
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
|
||||||
Messages.Xml_Error);
|
Messages.Xml_Error);
|
||||||
@@ -297,82 +351,6 @@ public class ApkBuilder extends BaseBuilder {
|
|||||||
return referencedProjects;
|
return referencedProjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the extra configs for the project.
|
|
||||||
// The map contains (name, filter) where 'name' is a name to be used in the apk filename,
|
|
||||||
// and filter is the resource filter to be used in the aapt -c parameters to restrict
|
|
||||||
// which resource configurations to package in the apk.
|
|
||||||
Map<String, String> configs = Sdk.getCurrent().getProjectApkConfigs(project);
|
|
||||||
|
|
||||||
// do some extra check, in case the output files are not present. This
|
|
||||||
// will force to recreate them.
|
|
||||||
IResource tmp = null;
|
|
||||||
|
|
||||||
if (mPackageResources == false) {
|
|
||||||
// check the full resource package
|
|
||||||
tmp = outputFolder.findMember(AndroidConstants.FN_RESOURCES_AP_);
|
|
||||||
if (tmp == null || tmp.exists() == false) {
|
|
||||||
mPackageResources = true;
|
|
||||||
mBuildFinalPackage = true;
|
|
||||||
} else {
|
|
||||||
// if the full package is present, we check the filtered resource packages as well
|
|
||||||
if (configs != null) {
|
|
||||||
Set<Entry<String, String>> entrySet = configs.entrySet();
|
|
||||||
|
|
||||||
for (Entry<String, String> entry : entrySet) {
|
|
||||||
String filename = String.format(AndroidConstants.FN_RESOURCES_S_AP_,
|
|
||||||
entry.getKey());
|
|
||||||
|
|
||||||
tmp = outputFolder.findMember(filename);
|
|
||||||
if (tmp == null || (tmp instanceof IFile &&
|
|
||||||
tmp.exists() == false)) {
|
|
||||||
String msg = String.format(Messages.s_Missing_Repackaging, filename);
|
|
||||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
|
|
||||||
mPackageResources = true;
|
|
||||||
mBuildFinalPackage = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check classes.dex is present. If not we force to recreate it.
|
|
||||||
if (mConvertToDex == false) {
|
|
||||||
tmp = outputFolder.findMember(AndroidConstants.FN_CLASSES_DEX);
|
|
||||||
if (tmp == null || tmp.exists() == false) {
|
|
||||||
mConvertToDex = true;
|
|
||||||
mBuildFinalPackage = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// also check the final file(s)!
|
|
||||||
String finalPackageName = getFileName(project, null /*config*/);
|
|
||||||
if (mBuildFinalPackage == false) {
|
|
||||||
tmp = outputFolder.findMember(finalPackageName);
|
|
||||||
if (tmp == null || (tmp instanceof IFile &&
|
|
||||||
tmp.exists() == false)) {
|
|
||||||
String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName);
|
|
||||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
|
|
||||||
mBuildFinalPackage = true;
|
|
||||||
} else if (configs != null) {
|
|
||||||
// if the full apk is present, we check the filtered apk as well
|
|
||||||
Set<Entry<String, String>> entrySet = configs.entrySet();
|
|
||||||
|
|
||||||
for (Entry<String, String> entry : entrySet) {
|
|
||||||
String filename = getFileName(project, entry.getKey());
|
|
||||||
|
|
||||||
tmp = outputFolder.findMember(filename);
|
|
||||||
if (tmp == null || (tmp instanceof IFile &&
|
|
||||||
tmp.exists() == false)) {
|
|
||||||
String msg = String.format(Messages.s_Missing_Repackaging, filename);
|
|
||||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg);
|
|
||||||
mBuildFinalPackage = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// at this point we know if we need to recreate the temporary apk
|
// at this point we know if we need to recreate the temporary apk
|
||||||
// or the dex file, but we don't know if we simply need to recreate them
|
// or the dex file, but we don't know if we simply need to recreate them
|
||||||
// because they are missing
|
// because they are missing
|
||||||
@@ -418,9 +396,6 @@ public class ApkBuilder extends BaseBuilder {
|
|||||||
|
|
||||||
// first we check if we need to package the resources.
|
// first we check if we need to package the resources.
|
||||||
if (mPackageResources) {
|
if (mPackageResources) {
|
||||||
// remove some aapt_package only markers.
|
|
||||||
removeMarkersFromContainer(project, AndroidConstants.MARKER_AAPT_PACKAGE);
|
|
||||||
|
|
||||||
// need to figure out some path before we can execute aapt;
|
// need to figure out some path before we can execute aapt;
|
||||||
|
|
||||||
// resource to the AndroidManifest.xml file
|
// resource to the AndroidManifest.xml file
|
||||||
@@ -577,8 +552,7 @@ public class ApkBuilder extends BaseBuilder {
|
|||||||
* @param osAssetsPath The path to the assets folder. This can be null.
|
* @param osAssetsPath The path to the assets folder. This can be null.
|
||||||
* @param osOutFilePath The path to the temporary resource file to create.
|
* @param osOutFilePath The path to the temporary resource file to create.
|
||||||
* @param configFilter The configuration filter for the resources to include
|
* @param configFilter The configuration filter for the resources to include
|
||||||
* (used with -c option, for example "port,en,fr" to include portrait, English and French
|
* (used with -c option)
|
||||||
* resources.)
|
|
||||||
* @return true if success, false otherwise.
|
* @return true if success, false otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean executeAapt(IProject project, String osManifestPath,
|
private boolean executeAapt(IProject project, String osManifestPath,
|
||||||
|
|||||||
@@ -149,15 +149,6 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
private final static Pattern sPattern8Line1 = Pattern.compile(
|
private final static Pattern sPattern8Line1 = Pattern.compile(
|
||||||
"^(invalid resource directory name): (.*)$"); //$NON-NLS-1$
|
"^(invalid resource directory name): (.*)$"); //$NON-NLS-1$
|
||||||
|
|
||||||
/**
|
|
||||||
* 2 line aapt error<br>
|
|
||||||
* "ERROR: Invalid configuration: foo"<br>
|
|
||||||
* " ^^^"<br>
|
|
||||||
* There's no need to parse the 2nd line.
|
|
||||||
*/
|
|
||||||
private final static Pattern sPattern9Line1 = Pattern.compile(
|
|
||||||
"^Invalid configuration: (.+)$"); //$NON-NLS-1$
|
|
||||||
|
|
||||||
/** SAX Parser factory. */
|
/** SAX Parser factory. */
|
||||||
private SAXParserFactory mParserFactory;
|
private SAXParserFactory mParserFactory;
|
||||||
|
|
||||||
@@ -449,8 +440,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
String location = m.group(1);
|
String location = m.group(1);
|
||||||
|
|
||||||
// check the values and attempt to mark the file.
|
// check the values and attempt to mark the file.
|
||||||
if (checkAndMark(location, lineStr, msg, osRoot, project,
|
if (checkAndMark(location, lineStr, msg, osRoot,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
|
project, IMarker.SEVERITY_ERROR) == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -474,7 +465,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
|
|
||||||
// display the error
|
// display the error
|
||||||
if (checkAndMark(location, null, msg, osRoot, project,
|
if (checkAndMark(location, null, msg, osRoot, project,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
|
IMarker.SEVERITY_ERROR) == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,8 +488,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
String lineStr = m.group(2);
|
String lineStr = m.group(2);
|
||||||
|
|
||||||
// check the values and attempt to mark the file.
|
// check the values and attempt to mark the file.
|
||||||
if (checkAndMark(location, lineStr, msg, osRoot, project,
|
if (checkAndMark(location, lineStr, msg, osRoot,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
|
project, IMarker.SEVERITY_ERROR) == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -511,8 +502,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
String msg = m.group(3);
|
String msg = m.group(3);
|
||||||
|
|
||||||
// check the values and attempt to mark the file.
|
// check the values and attempt to mark the file.
|
||||||
if (checkAndMark(location, lineStr, msg, osRoot, project,
|
if (checkAndMark(location, lineStr, msg, osRoot,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
|
project, IMarker.SEVERITY_ERROR) == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,8 +526,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
String lineStr = m.group(2);
|
String lineStr = m.group(2);
|
||||||
|
|
||||||
// check the values and attempt to mark the file.
|
// check the values and attempt to mark the file.
|
||||||
if (checkAndMark(location, lineStr, msg, osRoot, project,
|
if (checkAndMark(location, lineStr, msg, osRoot,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
|
project, IMarker.SEVERITY_ERROR) == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,8 +542,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
String msg = m.group(3);
|
String msg = m.group(3);
|
||||||
|
|
||||||
// check the values and attempt to mark the file.
|
// check the values and attempt to mark the file.
|
||||||
if (checkAndMark(location, lineStr, msg, osRoot, project,
|
if (checkAndMark(location, lineStr, msg, osRoot,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_WARNING) == false) {
|
project,IMarker.SEVERITY_WARNING) == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,8 +558,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
String msg = m.group(3);
|
String msg = m.group(3);
|
||||||
|
|
||||||
// check the values and attempt to mark the file.
|
// check the values and attempt to mark the file.
|
||||||
if (checkAndMark(location, lineStr, msg, osRoot, project,
|
if (checkAndMark(location, lineStr, msg, osRoot,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
|
project, IMarker.SEVERITY_ERROR) == false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -583,25 +574,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
|
|
||||||
// check the values and attempt to mark the file.
|
// check the values and attempt to mark the file.
|
||||||
if (checkAndMark(location, null, msg, osRoot, project,
|
if (checkAndMark(location, null, msg, osRoot, project,
|
||||||
AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) {
|
IMarker.SEVERITY_ERROR) == false) {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// success, go to the next line
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m = sPattern9Line1.matcher(p);
|
|
||||||
if (m.matches()) {
|
|
||||||
String badConfig = m.group(1);
|
|
||||||
String msg = String.format("APK Configuration filter '%1$s' is invalid", badConfig);
|
|
||||||
|
|
||||||
// skip the next line
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// check the values and attempt to mark the file.
|
|
||||||
if (checkAndMark(null /*location*/, null, msg, osRoot, project,
|
|
||||||
AndroidConstants.MARKER_AAPT_PACKAGE, IMarker.SEVERITY_ERROR) == false) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -686,26 +659,24 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
/**
|
/**
|
||||||
* Check if the parameters gotten from the error output are valid, and mark
|
* Check if the parameters gotten from the error output are valid, and mark
|
||||||
* the file with an AAPT marker.
|
* the file with an AAPT marker.
|
||||||
* @param location the full OS path of the error file. If null, the project is marked
|
* @param location
|
||||||
* @param lineStr
|
* @param lineStr
|
||||||
* @param message
|
* @param message
|
||||||
* @param root The root directory of the project, in OS specific format.
|
* @param root The root directory of the project, in OS specific format.
|
||||||
* @param project
|
* @param project
|
||||||
* @param markerId The marker id to put.
|
|
||||||
* @param severity The severity of the marker to put (IMarker.SEVERITY_*)
|
* @param severity The severity of the marker to put (IMarker.SEVERITY_*)
|
||||||
* @return true if the parameters were valid and the file was marked successfully.
|
* @return true if the parameters were valid and the file was marked
|
||||||
|
* sucessfully.
|
||||||
*
|
*
|
||||||
* @see IMarker
|
* @see IMarker
|
||||||
*/
|
*/
|
||||||
private final boolean checkAndMark(String location, String lineStr,
|
private final boolean checkAndMark(String location, String lineStr,
|
||||||
String message, String root, IProject project, String markerId, int severity) {
|
String message, String root, IProject project, int severity) {
|
||||||
// check this is in fact a file
|
// check this is in fact a file
|
||||||
if (location != null) {
|
|
||||||
File f = new File(location);
|
File f = new File(location);
|
||||||
if (f.exists() == false) {
|
if (f.exists() == false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// get the line number
|
// get the line number
|
||||||
int line = -1; // default value for error with no line.
|
int line = -1; // default value for error with no line.
|
||||||
@@ -721,18 +692,16 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add the marker
|
// add the marker
|
||||||
IResource f2 = project;
|
IResource f2 = getResourceFromFullPath(location, root, project);
|
||||||
if (location != null) {
|
|
||||||
f2 = getResourceFromFullPath(location, root, project);
|
|
||||||
if (f2 == null) {
|
if (f2 == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// check if there's a similar marker already, since aapt is launched twice
|
// check if there's a similar marker already, since aapt is launched twice
|
||||||
boolean markerAlreadyExists = false;
|
boolean markerAlreadyExists = false;
|
||||||
try {
|
try {
|
||||||
IMarker[] markers = f2.findMarkers(markerId, true, IResource.DEPTH_ZERO);
|
IMarker[] markers = f2.findMarkers(AndroidConstants.MARKER_AAPT, true,
|
||||||
|
IResource.DEPTH_ZERO);
|
||||||
|
|
||||||
for (IMarker marker : markers) {
|
for (IMarker marker : markers) {
|
||||||
int tmpLine = marker.getAttribute(IMarker.LINE_NUMBER, -1);
|
int tmpLine = marker.getAttribute(IMarker.LINE_NUMBER, -1);
|
||||||
@@ -763,10 +732,10 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
|
|
||||||
if (markerAlreadyExists == false) {
|
if (markerAlreadyExists == false) {
|
||||||
if (line != -1) {
|
if (line != -1) {
|
||||||
BaseProjectHelper.addMarker(f2, markerId, message, line,
|
BaseProjectHelper.addMarker(f2, AndroidConstants.MARKER_AAPT, message, line,
|
||||||
severity);
|
severity);
|
||||||
} else {
|
} else {
|
||||||
BaseProjectHelper.addMarker(f2, markerId, message, severity);
|
BaseProjectHelper.addMarker(f2, AndroidConstants.MARKER_AAPT, message, severity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,7 +851,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
|
|||||||
* Aborts the build if the SDK/project setups are broken. This does not
|
* Aborts the build if the SDK/project setups are broken. This does not
|
||||||
* display any errors.
|
* display any errors.
|
||||||
*
|
*
|
||||||
* @param project The {@link IJavaProject} being compiled.
|
* @param javaProject The {@link IJavaProject} being compiled.
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
protected final void abortOnBadSetup(IProject project) throws CoreException {
|
protected final void abortOnBadSetup(IProject project) throws CoreException {
|
||||||
|
|||||||
@@ -57,11 +57,8 @@ public final class DexWrapper {
|
|||||||
private Field mConsoleErr;
|
private Field mConsoleErr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the dex library from a file path.
|
* Loads the dex library from a file path. The loaded library can be used with the
|
||||||
*
|
* {@link DexWrapper} object returned by {@link #getWrapper()}
|
||||||
* The loaded library can be used via
|
|
||||||
* {@link DexWrapper#run(String, String[], boolean, PrintStream, PrintStream)}.
|
|
||||||
*
|
|
||||||
* @param osFilepath the location of the dex.jar file.
|
* @param osFilepath the location of the dex.jar file.
|
||||||
* @return an IStatus indicating the result of the load.
|
* @return an IStatus indicating the result of the load.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -234,10 +234,6 @@ public class PreCompilerBuilder extends BaseBuilder {
|
|||||||
|
|
||||||
// get the project objects
|
// get the project objects
|
||||||
IProject project = getProject();
|
IProject project = getProject();
|
||||||
|
|
||||||
// Top level check to make sure the build can move forward.
|
|
||||||
abortOnBadSetup(project);
|
|
||||||
|
|
||||||
IJavaProject javaProject = JavaCore.create(project);
|
IJavaProject javaProject = JavaCore.create(project);
|
||||||
IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
|
IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project);
|
||||||
|
|
||||||
@@ -288,6 +284,10 @@ public class PreCompilerBuilder extends BaseBuilder {
|
|||||||
saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES , mCompileResources);
|
saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES , mCompileResources);
|
||||||
// TODO also needs to store the list of aidl to compile/remove
|
// TODO also needs to store the list of aidl to compile/remove
|
||||||
|
|
||||||
|
// At this point we have stored what needs to be build, so we can
|
||||||
|
// do some high level test and abort if needed.
|
||||||
|
abortOnBadSetup(project);
|
||||||
|
|
||||||
// if there was some XML errors, we just return w/o doing
|
// if there was some XML errors, we just return w/o doing
|
||||||
// anything since we've put some markers in the files anyway.
|
// anything since we've put some markers in the files anyway.
|
||||||
if (dv != null && dv.mXmlError) {
|
if (dv != null && dv.mXmlError) {
|
||||||
@@ -381,7 +381,7 @@ public class PreCompilerBuilder extends BaseBuilder {
|
|||||||
// mark the manifest file
|
// mark the manifest file
|
||||||
String message = String.format(Messages.Package_s_Doesnt_Exist_Error,
|
String message = String.format(Messages.Package_s_Doesnt_Exist_Error,
|
||||||
mManifestPackage);
|
mManifestPackage);
|
||||||
BaseProjectHelper.addMarker(manifest, AndroidConstants.MARKER_AAPT_COMPILE, message,
|
BaseProjectHelper.addMarker(manifest, AndroidConstants.MARKER_AAPT, message,
|
||||||
IMarker.SEVERITY_ERROR);
|
IMarker.SEVERITY_ERROR);
|
||||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, message);
|
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, message);
|
||||||
|
|
||||||
@@ -409,8 +409,8 @@ public class PreCompilerBuilder extends BaseBuilder {
|
|||||||
String osManifestPath = manifestLocation.toOSString();
|
String osManifestPath = manifestLocation.toOSString();
|
||||||
|
|
||||||
// remove the aapt markers
|
// remove the aapt markers
|
||||||
removeMarkersFromFile(manifest, AndroidConstants.MARKER_AAPT_COMPILE);
|
removeMarkersFromFile(manifest, AndroidConstants.MARKER_AAPT);
|
||||||
removeMarkersFromContainer(resFolder, AndroidConstants.MARKER_AAPT_COMPILE);
|
removeMarkersFromContainer(resFolder, AndroidConstants.MARKER_AAPT);
|
||||||
|
|
||||||
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
|
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
|
||||||
Messages.Preparing_Generated_Files);
|
Messages.Preparing_Generated_Files);
|
||||||
|
|||||||
@@ -17,19 +17,11 @@
|
|||||||
package com.android.ide.eclipse.adt.preferences;
|
package com.android.ide.eclipse.adt.preferences;
|
||||||
|
|
||||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
|
|
||||||
import com.android.sdklib.IAndroidTarget;
|
|
||||||
import com.android.sdkuilib.SdkTargetSelector;
|
|
||||||
|
|
||||||
import org.eclipse.core.resources.IProject;
|
|
||||||
import org.eclipse.jface.preference.DirectoryFieldEditor;
|
import org.eclipse.jface.preference.DirectoryFieldEditor;
|
||||||
import org.eclipse.jface.preference.FieldEditorPreferencePage;
|
import org.eclipse.jface.preference.FieldEditorPreferencePage;
|
||||||
import org.eclipse.jface.resource.JFaceResources;
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.eclipse.swt.widgets.Label;
|
|
||||||
import org.eclipse.swt.widgets.Text;
|
import org.eclipse.swt.widgets.Text;
|
||||||
import org.eclipse.ui.IWorkbench;
|
import org.eclipse.ui.IWorkbench;
|
||||||
import org.eclipse.ui.IWorkbenchPreferencePage;
|
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||||
@@ -88,9 +80,6 @@ public class AndroidPreferencePage extends FieldEditorPreferencePage implements
|
|||||||
*/
|
*/
|
||||||
private static class SdkDirectoryFieldEditor extends DirectoryFieldEditor {
|
private static class SdkDirectoryFieldEditor extends DirectoryFieldEditor {
|
||||||
|
|
||||||
private SdkTargetSelector mTargetSelector;
|
|
||||||
private TargetChangedListener mTargetChangeListener;
|
|
||||||
|
|
||||||
public SdkDirectoryFieldEditor(String name, String labelText, Composite parent) {
|
public SdkDirectoryFieldEditor(String name, String labelText, Composite parent) {
|
||||||
super(name, labelText, parent);
|
super(name, labelText, parent);
|
||||||
setEmptyStringAllowed(false);
|
setEmptyStringAllowed(false);
|
||||||
@@ -142,68 +131,5 @@ public class AndroidPreferencePage extends FieldEditorPreferencePage implements
|
|||||||
setValidateStrategy(VALIDATE_ON_KEY_STROKE);
|
setValidateStrategy(VALIDATE_ON_KEY_STROKE);
|
||||||
return super.getTextControl(parent);
|
return super.getTextControl(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* Method declared on StringFieldEditor (and FieldEditor).
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void doFillIntoGrid(Composite parent, int numColumns) {
|
|
||||||
super.doFillIntoGrid(parent, numColumns);
|
|
||||||
|
|
||||||
GridData gd;
|
|
||||||
Label l = new Label(parent, SWT.NONE);
|
|
||||||
l.setText("Note: The list of SDK Targets below is only reloaded once you hit 'Apply' or 'OK'.");
|
|
||||||
gd = new GridData(GridData.FILL_HORIZONTAL);
|
|
||||||
gd.horizontalSpan = numColumns;
|
|
||||||
l.setLayoutData(gd);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// We may not have an sdk if the sdk path pref is empty or not valid.
|
|
||||||
Sdk sdk = Sdk.getCurrent();
|
|
||||||
IAndroidTarget[] targets = sdk != null ? sdk.getTargets() : null;
|
|
||||||
|
|
||||||
mTargetSelector = new SdkTargetSelector(parent,
|
|
||||||
targets,
|
|
||||||
false, /*allowSelection*/
|
|
||||||
false /*multipleSelection*/);
|
|
||||||
gd = (GridData) mTargetSelector.getLayoutData();
|
|
||||||
gd.horizontalSpan = numColumns;
|
|
||||||
|
|
||||||
if (mTargetChangeListener == null) {
|
|
||||||
mTargetChangeListener = new TargetChangedListener();
|
|
||||||
AdtPlugin.getDefault().addTargetListener(mTargetChangeListener);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// We need to catch *any* exception that arises here, otherwise it disables
|
|
||||||
// the whole pref panel. We can live without the Sdk target selector but
|
|
||||||
// not being able to actually set an sdk path.
|
|
||||||
AdtPlugin.log(e, "SdkTargetSelector failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
super.dispose();
|
|
||||||
if (mTargetChangeListener != null) {
|
|
||||||
AdtPlugin.getDefault().removeTargetListener(mTargetChangeListener);
|
|
||||||
mTargetChangeListener = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TargetChangedListener implements ITargetChangeListener {
|
|
||||||
public void onProjectTargetChange(IProject changedProject) {
|
|
||||||
// do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTargetsLoaded() {
|
|
||||||
if (mTargetSelector != null) {
|
|
||||||
// We may not have an sdk if the sdk path pref is empty or not valid.
|
|
||||||
Sdk sdk = Sdk.getCurrent();
|
|
||||||
IAndroidTarget[] targets = sdk != null ? sdk.getTargets() : null;
|
|
||||||
|
|
||||||
mTargetSelector.setTargets(targets);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,6 +266,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
|
|||||||
// We schedule a new job to put the marker after.
|
// We schedule a new job to put the marker after.
|
||||||
final String fmessage = markerMessage;
|
final String fmessage = markerMessage;
|
||||||
Job markerJob = new Job("Android SDK: Resolving error markers") {
|
Job markerJob = new Job("Android SDK: Resolving error markers") {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected IStatus run(IProgressMonitor monitor) {
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
try {
|
try {
|
||||||
@@ -295,6 +296,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit
|
|||||||
// In some cases, the workspace may be locked for modification when we pass
|
// In some cases, the workspace may be locked for modification when we pass
|
||||||
// here, so we schedule a new job to put the marker after.
|
// here, so we schedule a new job to put the marker after.
|
||||||
Job markerJob = new Job("Android SDK: Resolving error markers") {
|
Job markerJob = new Job("Android SDK: Resolving error markers") {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
protected IStatus run(IProgressMonitor monitor) {
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.android.ide.eclipse.adt.project.properties;
|
|||||||
|
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||||
import com.android.sdklib.IAndroidTarget;
|
import com.android.sdklib.IAndroidTarget;
|
||||||
import com.android.sdkuilib.ApkConfigWidget;
|
|
||||||
import com.android.sdkuilib.SdkTargetSelector;
|
import com.android.sdkuilib.SdkTargetSelector;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
@@ -33,8 +32,6 @@ import org.eclipse.swt.widgets.Label;
|
|||||||
import org.eclipse.ui.IWorkbenchPropertyPage;
|
import org.eclipse.ui.IWorkbenchPropertyPage;
|
||||||
import org.eclipse.ui.dialogs.PropertyPage;
|
import org.eclipse.ui.dialogs.PropertyPage;
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property page for "Android" project.
|
* Property page for "Android" project.
|
||||||
* This is accessible from the Package Explorer when right clicking a project and choosing
|
* This is accessible from the Package Explorer when right clicking a project and choosing
|
||||||
@@ -45,7 +42,6 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
|
|||||||
|
|
||||||
private IProject mProject;
|
private IProject mProject;
|
||||||
private SdkTargetSelector mSelector;
|
private SdkTargetSelector mSelector;
|
||||||
private ApkConfigWidget mApkConfigWidget;
|
|
||||||
|
|
||||||
public AndroidPropertyPage() {
|
public AndroidPropertyPage() {
|
||||||
// pass
|
// pass
|
||||||
@@ -56,13 +52,6 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
|
|||||||
// get the element (this is not yet valid in the constructor).
|
// get the element (this is not yet valid in the constructor).
|
||||||
mProject = (IProject)getElement();
|
mProject = (IProject)getElement();
|
||||||
|
|
||||||
// get the targets from the sdk
|
|
||||||
IAndroidTarget[] targets = null;
|
|
||||||
if (Sdk.getCurrent() != null) {
|
|
||||||
targets = Sdk.getCurrent().getTargets();
|
|
||||||
}
|
|
||||||
|
|
||||||
// build the UI.
|
|
||||||
Composite top = new Composite(parent, SWT.NONE);
|
Composite top = new Composite(parent, SWT.NONE);
|
||||||
top.setLayoutData(new GridData(GridData.FILL_BOTH));
|
top.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||||
top.setLayout(new GridLayout(1, false));
|
top.setLayout(new GridLayout(1, false));
|
||||||
@@ -70,28 +59,20 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
|
|||||||
Label l = new Label(top, SWT.NONE);
|
Label l = new Label(top, SWT.NONE);
|
||||||
l.setText("Project Target");
|
l.setText("Project Target");
|
||||||
|
|
||||||
|
// get the targets from the sdk
|
||||||
|
IAndroidTarget[] targets = null;
|
||||||
|
if (Sdk.getCurrent() != null) {
|
||||||
|
targets = Sdk.getCurrent().getTargets();
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the UI.
|
||||||
mSelector = new SdkTargetSelector(top, targets, false /*allowMultipleSelection*/);
|
mSelector = new SdkTargetSelector(top, targets, false /*allowMultipleSelection*/);
|
||||||
|
|
||||||
l = new Label(top, SWT.SEPARATOR | SWT.HORIZONTAL);
|
if (Sdk.getCurrent() != null) {
|
||||||
l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
|
||||||
|
|
||||||
l = new Label(top, SWT.NONE);
|
|
||||||
l.setText("Project APK Configurations");
|
|
||||||
|
|
||||||
mApkConfigWidget = new ApkConfigWidget(top);
|
|
||||||
|
|
||||||
// fill the ui
|
|
||||||
Sdk currentSdk = Sdk.getCurrent();
|
|
||||||
if (currentSdk != null && mProject.isOpen()) {
|
|
||||||
// get the target
|
|
||||||
IAndroidTarget target = currentSdk.getTarget(mProject);
|
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
mSelector.setSelection(target);
|
mSelector.setSelection(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the apk configurations
|
|
||||||
Map<String, String> configs = currentSdk.getProjectApkConfigs(mProject);
|
|
||||||
mApkConfigWidget.fillTable(configs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mSelector.setSelectionListener(new SelectionAdapter() {
|
mSelector.setSelectionListener(new SelectionAdapter() {
|
||||||
@@ -103,19 +84,13 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (mProject.isOpen() == false) {
|
|
||||||
// disable the ui.
|
|
||||||
}
|
|
||||||
|
|
||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean performOk() {
|
public boolean performOk() {
|
||||||
Sdk currentSdk = Sdk.getCurrent();
|
if (Sdk.getCurrent() != null) {
|
||||||
if (currentSdk != null) {
|
Sdk.getCurrent().setProject(mProject, mSelector.getFirstSelected());
|
||||||
currentSdk.setProject(mProject, mSelector.getFirstSelected(),
|
|
||||||
mApkConfigWidget.getApkConfigs());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
|
|||||||
import com.android.ide.eclipse.editors.xml.descriptors.XmlDescriptors;
|
import com.android.ide.eclipse.editors.xml.descriptors.XmlDescriptors;
|
||||||
import com.android.layoutlib.api.ILayoutBridge;
|
import com.android.layoutlib.api.ILayoutBridge;
|
||||||
import com.android.sdklib.IAndroidTarget;
|
import com.android.sdklib.IAndroidTarget;
|
||||||
import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
|
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -44,7 +43,6 @@ 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 class LayoutBridge {
|
public final static class LayoutBridge {
|
||||||
/** Link to the layout bridge */
|
/** Link to the layout bridge */
|
||||||
@@ -53,8 +51,6 @@ public class AndroidTargetData {
|
|||||||
public LoadStatus status = LoadStatus.LOADING;
|
public LoadStatus status = LoadStatus.LOADING;
|
||||||
|
|
||||||
public ClassLoader classLoader;
|
public ClassLoader classLoader;
|
||||||
|
|
||||||
public int apiLevel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final IAndroidTarget mTarget;
|
private final IAndroidTarget mTarget;
|
||||||
@@ -97,7 +93,6 @@ public class AndroidTargetData {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an AndroidTargetData object.
|
* Creates an AndroidTargetData object.
|
||||||
* @param optionalLibraries
|
|
||||||
*/
|
*/
|
||||||
void setExtraData(IResourceRepository systemResourceRepository,
|
void setExtraData(IResourceRepository systemResourceRepository,
|
||||||
AndroidManifestDescriptors manifestDescriptors,
|
AndroidManifestDescriptors manifestDescriptors,
|
||||||
@@ -110,7 +105,6 @@ public class AndroidTargetData {
|
|||||||
String[] broadcastIntentActionValues,
|
String[] broadcastIntentActionValues,
|
||||||
String[] serviceIntentActionValues,
|
String[] serviceIntentActionValues,
|
||||||
String[] intentCategoryValues,
|
String[] intentCategoryValues,
|
||||||
IOptionalLibrary[] optionalLibraries,
|
|
||||||
ProjectResources resources,
|
ProjectResources resources,
|
||||||
LayoutBridge layoutBridge) {
|
LayoutBridge layoutBridge) {
|
||||||
|
|
||||||
@@ -126,7 +120,6 @@ public class AndroidTargetData {
|
|||||||
setPermissions(permissionValues);
|
setPermissions(permissionValues);
|
||||||
setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues,
|
setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues,
|
||||||
serviceIntentActionValues, intentCategoryValues);
|
serviceIntentActionValues, intentCategoryValues);
|
||||||
setOptionalLibraries(optionalLibraries);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DexWrapper getDexWrapper() {
|
public DexWrapper getDexWrapper() {
|
||||||
@@ -158,8 +151,6 @@ 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:
|
|
||||||
return mXmlDescriptors.getGadgetProvider();
|
|
||||||
case DESCRIPTOR_SEARCHABLE:
|
case DESCRIPTOR_SEARCHABLE:
|
||||||
return mXmlDescriptors.getSearchableProvider();
|
return mXmlDescriptors.getSearchableProvider();
|
||||||
default :
|
default :
|
||||||
@@ -293,20 +284,6 @@ public class AndroidTargetData {
|
|||||||
setValues("(category,android:name)", intentCategoryValues); //$NON-NLS-1$
|
setValues("(category,android:name)", intentCategoryValues); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOptionalLibraries(IOptionalLibrary[] optionalLibraries) {
|
|
||||||
String[] values;
|
|
||||||
|
|
||||||
if (optionalLibraries == null) {
|
|
||||||
values = new String[0];
|
|
||||||
} else {
|
|
||||||
values = new String[optionalLibraries.length];
|
|
||||||
for (int i = 0; i < optionalLibraries.length; i++) {
|
|
||||||
values[i] = optionalLibraries[i].getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setValues("(uses-library,android:name)", values);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a (name, values) pair in the hash map.
|
* Sets a (name, values) pair in the hash map.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public final class AndroidTargetParser {
|
|||||||
try {
|
try {
|
||||||
SubMonitor progress = SubMonitor.convert(monitor,
|
SubMonitor progress = SubMonitor.convert(monitor,
|
||||||
String.format("Parsing SDK %1$s", mAndroidTarget.getName()),
|
String.format("Parsing SDK %1$s", mAndroidTarget.getName()),
|
||||||
14);
|
200);
|
||||||
|
|
||||||
AndroidTargetData targetData = new AndroidTargetData(mAndroidTarget);
|
AndroidTargetData targetData = new AndroidTargetData(mAndroidTarget);
|
||||||
|
|
||||||
@@ -107,14 +107,15 @@ public final class AndroidTargetParser {
|
|||||||
|
|
||||||
// we have loaded dx.
|
// we have loaded dx.
|
||||||
targetData.setDexWrapper(dexWrapper);
|
targetData.setDexWrapper(dexWrapper);
|
||||||
progress.worked(1);
|
|
||||||
|
|
||||||
// parse the rest of the data.
|
// parse the rest of the data.
|
||||||
|
progress.setWorkRemaining(120);
|
||||||
|
|
||||||
AndroidJarLoader classLoader =
|
AndroidJarLoader classLoader =
|
||||||
new AndroidJarLoader(mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR));
|
new AndroidJarLoader(mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR));
|
||||||
|
|
||||||
preload(classLoader, progress.newChild(40, SubMonitor.SUPPRESS_NONE));
|
preload(classLoader, progress.newChild(40, SubMonitor.SUPPRESS_NONE));
|
||||||
|
progress.setWorkRemaining(80);
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -123,7 +124,7 @@ public final class AndroidTargetParser {
|
|||||||
// get the resource Ids.
|
// get the resource Ids.
|
||||||
progress.subTask("Resource IDs");
|
progress.subTask("Resource IDs");
|
||||||
IResourceRepository frameworkRepository = collectResourceIds(classLoader);
|
IResourceRepository frameworkRepository = collectResourceIds(classLoader);
|
||||||
progress.worked(1);
|
progress.worked(5);
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -132,7 +133,7 @@ public final class AndroidTargetParser {
|
|||||||
// get the permissions
|
// get the permissions
|
||||||
progress.subTask("Permissions");
|
progress.subTask("Permissions");
|
||||||
String[] permissionValues = collectPermissions(classLoader);
|
String[] permissionValues = collectPermissions(classLoader);
|
||||||
progress.worked(1);
|
progress.worked(5);
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -146,7 +147,7 @@ public final class AndroidTargetParser {
|
|||||||
ArrayList<String> categories = new ArrayList<String>();
|
ArrayList<String> categories = new ArrayList<String>();
|
||||||
collectIntentFilterActionsAndCategories(activity_actions, broadcast_actions,
|
collectIntentFilterActionsAndCategories(activity_actions, broadcast_actions,
|
||||||
service_actions, categories);
|
service_actions, categories);
|
||||||
progress.worked(1);
|
progress.worked(5);
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -157,14 +158,12 @@ public final class AndroidTargetParser {
|
|||||||
AttrsXmlParser attrsXmlParser = new AttrsXmlParser(
|
AttrsXmlParser attrsXmlParser = new AttrsXmlParser(
|
||||||
mAndroidTarget.getPath(IAndroidTarget.ATTRIBUTES));
|
mAndroidTarget.getPath(IAndroidTarget.ATTRIBUTES));
|
||||||
attrsXmlParser.preload();
|
attrsXmlParser.preload();
|
||||||
progress.worked(1);
|
|
||||||
|
|
||||||
progress.subTask("Manifest definitions");
|
progress.subTask("Manifest definitions");
|
||||||
AttrsXmlParser attrsManifestXmlParser = new AttrsXmlParser(
|
AttrsXmlParser attrsManifestXmlParser = new AttrsXmlParser(
|
||||||
mAndroidTarget.getPath(IAndroidTarget.MANIFEST_ATTRIBUTES),
|
mAndroidTarget.getPath(IAndroidTarget.MANIFEST_ATTRIBUTES),
|
||||||
attrsXmlParser);
|
attrsXmlParser);
|
||||||
attrsManifestXmlParser.preload();
|
attrsManifestXmlParser.preload();
|
||||||
progress.worked(1);
|
|
||||||
|
|
||||||
Collection<ViewClassInfo> mainList = new ArrayList<ViewClassInfo>();
|
Collection<ViewClassInfo> mainList = new ArrayList<ViewClassInfo>();
|
||||||
Collection<ViewClassInfo> groupList = new ArrayList<ViewClassInfo>();
|
Collection<ViewClassInfo> groupList = new ArrayList<ViewClassInfo>();
|
||||||
@@ -172,7 +171,7 @@ public final class AndroidTargetParser {
|
|||||||
// collect the layout/widgets classes
|
// collect the layout/widgets classes
|
||||||
progress.subTask("Widgets and layouts");
|
progress.subTask("Widgets and layouts");
|
||||||
collectLayoutClasses(classLoader, attrsXmlParser, mainList, groupList,
|
collectLayoutClasses(classLoader, attrsXmlParser, mainList, groupList,
|
||||||
progress.newChild(1));
|
progress.newChild(40));
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -186,7 +185,7 @@ public final class AndroidTargetParser {
|
|||||||
mainList.clear();
|
mainList.clear();
|
||||||
groupList.clear();
|
groupList.clear();
|
||||||
collectPreferenceClasses(classLoader, attrsXmlParser, mainList, groupList,
|
collectPreferenceClasses(classLoader, attrsXmlParser, mainList, groupList,
|
||||||
progress.newChild(1));
|
progress.newChild(5));
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -203,11 +202,6 @@ 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;
|
|
||||||
if (mAndroidTarget.getApiVersionNumber() >= 3) {
|
|
||||||
xmlGadgetMap = collectGadgetDefinitions(attrsXmlParser);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
}
|
}
|
||||||
@@ -216,7 +210,7 @@ public final class AndroidTargetParser {
|
|||||||
// the PlatformData object.
|
// the PlatformData object.
|
||||||
AndroidManifestDescriptors manifestDescriptors = new AndroidManifestDescriptors();
|
AndroidManifestDescriptors manifestDescriptors = new AndroidManifestDescriptors();
|
||||||
manifestDescriptors.updateDescriptors(manifestMap);
|
manifestDescriptors.updateDescriptors(manifestMap);
|
||||||
progress.worked(1);
|
progress.worked(10);
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -224,7 +218,7 @@ public final class AndroidTargetParser {
|
|||||||
|
|
||||||
LayoutDescriptors layoutDescriptors = new LayoutDescriptors();
|
LayoutDescriptors layoutDescriptors = new LayoutDescriptors();
|
||||||
layoutDescriptors.updateDescriptors(layoutViewsInfo, layoutGroupsInfo);
|
layoutDescriptors.updateDescriptors(layoutViewsInfo, layoutGroupsInfo);
|
||||||
progress.worked(1);
|
progress.worked(10);
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
@@ -232,28 +226,25 @@ public final class AndroidTargetParser {
|
|||||||
|
|
||||||
MenuDescriptors menuDescriptors = new MenuDescriptors();
|
MenuDescriptors menuDescriptors = new MenuDescriptors();
|
||||||
menuDescriptors.updateDescriptors(xmlMenuMap);
|
menuDescriptors.updateDescriptors(xmlMenuMap);
|
||||||
progress.worked(1);
|
progress.worked(10);
|
||||||
|
|
||||||
if (progress.isCanceled()) {
|
if (progress.isCanceled()) {
|
||||||
return Status.CANCEL_STATUS;
|
return Status.CANCEL_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlDescriptors xmlDescriptors = new XmlDescriptors();
|
XmlDescriptors xmlDescriptors = new XmlDescriptors();
|
||||||
xmlDescriptors.updateDescriptors(
|
xmlDescriptors.updateDescriptors(xmlSearchableMap, preferencesInfo,
|
||||||
xmlSearchableMap,
|
|
||||||
xmlGadgetMap,
|
|
||||||
preferencesInfo,
|
|
||||||
preferenceGroupsInfo);
|
preferenceGroupsInfo);
|
||||||
progress.worked(1);
|
progress.worked(10);
|
||||||
|
|
||||||
// load the framework resources.
|
// load the framework resources.
|
||||||
ProjectResources resources = ResourceManager.getInstance().loadFrameworkResources(
|
ProjectResources resources = ResourceManager.getInstance().loadFrameworkResources(
|
||||||
mAndroidTarget);
|
mAndroidTarget);
|
||||||
progress.worked(1);
|
progress.worked(10);
|
||||||
|
|
||||||
// now load the layout lib bridge
|
// now load the layout lib bridge
|
||||||
LayoutBridge layoutBridge = loadLayoutBridge();
|
LayoutBridge layoutBridge = loadLayoutBridge();
|
||||||
progress.worked(1);
|
progress.worked(10);
|
||||||
|
|
||||||
// and finally create the PlatformData with all that we loaded.
|
// and finally create the PlatformData with all that we loaded.
|
||||||
targetData.setExtraData(frameworkRepository,
|
targetData.setExtraData(frameworkRepository,
|
||||||
@@ -267,7 +258,6 @@ public final class AndroidTargetParser {
|
|||||||
broadcast_actions.toArray(new String[broadcast_actions.size()]),
|
broadcast_actions.toArray(new String[broadcast_actions.size()]),
|
||||||
service_actions.toArray(new String[service_actions.size()]),
|
service_actions.toArray(new String[service_actions.size()]),
|
||||||
categories.toArray(new String[categories.size()]),
|
categories.toArray(new String[categories.size()]),
|
||||||
mAndroidTarget.getOptionalLibraries(),
|
|
||||||
resources,
|
resources,
|
||||||
layoutBridge);
|
layoutBridge);
|
||||||
|
|
||||||
@@ -278,6 +268,10 @@ public final class AndroidTargetParser {
|
|||||||
AdtPlugin.logAndPrintError(e, TAG, "SDK parser failed"); //$NON-NLS-1$
|
AdtPlugin.logAndPrintError(e, TAG, "SDK parser failed"); //$NON-NLS-1$
|
||||||
AdtPlugin.printToConsole("SDK parser failed", e.getMessage());
|
AdtPlugin.printToConsole("SDK parser failed", e.getMessage());
|
||||||
return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "SDK parser failed", e);
|
return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "SDK parser failed", e);
|
||||||
|
} finally {
|
||||||
|
if (monitor != null) {
|
||||||
|
monitor.done();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -610,31 +604,6 @@ public final class AndroidTargetParser {
|
|||||||
return Collections.unmodifiableMap(map2);
|
return Collections.unmodifiableMap(map2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Collects all gadgetProviderInfo definition information from the attrs.xml and returns it.
|
|
||||||
*
|
|
||||||
* @param attrsXmlParser The parser of the attrs.xml file
|
|
||||||
*/
|
|
||||||
private Map<String, DeclareStyleableInfo> collectGadgetDefinitions(
|
|
||||||
AttrsXmlParser attrsXmlParser) {
|
|
||||||
Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList();
|
|
||||||
Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>();
|
|
||||||
for (String key : new String[] { "GadgetProviderInfo" }) { //$NON-NLS-1$
|
|
||||||
if (map.containsKey(key)) {
|
|
||||||
map2.put(key, map.get(key));
|
|
||||||
} else {
|
|
||||||
AdtPlugin.log(IStatus.WARNING,
|
|
||||||
"Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
|
|
||||||
key, attrsXmlParser.getOsAttrsXmlPath());
|
|
||||||
AdtPlugin.printErrorToConsole("Android Framework Parser",
|
|
||||||
String.format("Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$
|
|
||||||
key, attrsXmlParser.getOsAttrsXmlPath()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.unmodifiableMap(map2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collects all manifest definition information from the attrs_manifest.xml and returns it.
|
* Collects all manifest definition information from the attrs_manifest.xml and returns it.
|
||||||
*/
|
*/
|
||||||
@@ -681,15 +650,6 @@ public final class AndroidTargetParser {
|
|||||||
layoutBridge.status = LoadStatus.FAILED;
|
layoutBridge.status = LoadStatus.FAILED;
|
||||||
AdtPlugin.log(IStatus.ERROR, "Failed to load " + AndroidConstants.CLASS_BRIDGE); //$NON-NLS-1$
|
AdtPlugin.log(IStatus.ERROR, "Failed to load " + AndroidConstants.CLASS_BRIDGE); //$NON-NLS-1$
|
||||||
} else {
|
} else {
|
||||||
// get the api level
|
|
||||||
try {
|
|
||||||
layoutBridge.apiLevel = layoutBridge.bridge.getApiLevel();
|
|
||||||
} catch (AbstractMethodError e) {
|
|
||||||
// the first version of the api did not have this method
|
|
||||||
layoutBridge.apiLevel = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// and mark the lib as loaded.
|
|
||||||
layoutBridge.status = LoadStatus.LOADED;
|
layoutBridge.status = LoadStatus.LOADED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.android.ide.eclipse.adt.sdk;
|
|||||||
|
|
||||||
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.adt.sdk.AndroidTargetData.LayoutBridge;
|
|
||||||
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
|
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
|
||||||
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
|
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener;
|
||||||
import com.android.prefs.AndroidLocation.AndroidLocationException;
|
import com.android.prefs.AndroidLocation.AndroidLocationException;
|
||||||
@@ -34,7 +33,6 @@ import com.android.sdklib.project.ProjectProperties.PropertyType;
|
|||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.jdt.core.IJavaProject;
|
import org.eclipse.jdt.core.IJavaProject;
|
||||||
import org.eclipse.jdt.core.JavaCore;
|
import org.eclipse.jdt.core.JavaCore;
|
||||||
@@ -70,22 +68,6 @@ public class Sdk implements IProjectListener {
|
|||||||
new HashMap<IProject, Map<String, String>>();
|
new HashMap<IProject, Map<String, String>>();
|
||||||
private final String mDocBaseUrl;
|
private final String mDocBaseUrl;
|
||||||
|
|
||||||
/**
|
|
||||||
* Classes implementing this interface will receive notification when targets are changed.
|
|
||||||
*/
|
|
||||||
public interface ITargetChangeListener {
|
|
||||||
/**
|
|
||||||
* Sent when project has its target changed.
|
|
||||||
*/
|
|
||||||
void onProjectTargetChange(IProject changedProject);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the targets are loaded (either the SDK finished loading when Eclipse starts,
|
|
||||||
* or the SDK is changed).
|
|
||||||
*/
|
|
||||||
void onTargetsLoaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads an SDK and returns an {@link Sdk} object if success.
|
* Loads an SDK and returns an {@link Sdk} object if success.
|
||||||
* @param sdkLocation the OS path to the SDK.
|
* @param sdkLocation the OS path to the SDK.
|
||||||
@@ -181,87 +163,24 @@ public class Sdk implements IProjectListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a new target and a new list of Apk configuration for a given project.
|
* Associates an {@link IProject} and an {@link IAndroidTarget}.
|
||||||
*
|
|
||||||
* @param project the project to receive the new apk configurations
|
|
||||||
* @param target The new target to set, or <code>null</code> to not change the current target.
|
|
||||||
* @param apkConfigMap a map of apk configurations. The map contains (name, filter) where name
|
|
||||||
* is the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of
|
|
||||||
* resource configuration to include in the apk (see aapt -c). Can be <code>null</code> if the
|
|
||||||
* apk configurations should not be updated.
|
|
||||||
*/
|
*/
|
||||||
public void setProject(IProject project, IAndroidTarget target,
|
public void setProject(IProject project, IAndroidTarget target) {
|
||||||
Map<String, String> apkConfigMap) {
|
|
||||||
synchronized (mProjectTargetMap) {
|
synchronized (mProjectTargetMap) {
|
||||||
boolean resolveProject = false;
|
|
||||||
boolean compileProject = false;
|
|
||||||
boolean cleanProject = false;
|
|
||||||
|
|
||||||
ProjectProperties properties = ProjectProperties.load(
|
|
||||||
project.getLocation().toOSString(), PropertyType.DEFAULT);
|
|
||||||
if (properties == null) {
|
|
||||||
// doesn't exist yet? we create it.
|
|
||||||
properties = ProjectProperties.create(project.getLocation().toOSString(),
|
|
||||||
PropertyType.DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target != null) {
|
|
||||||
// look for the current target of the project
|
// look for the current target of the project
|
||||||
IAndroidTarget previousTarget = mProjectTargetMap.get(project);
|
IAndroidTarget previousTarget = mProjectTargetMap.get(project);
|
||||||
|
|
||||||
if (target != previousTarget) {
|
if (target != previousTarget) {
|
||||||
// save the target hash string in the project persistent property
|
// save the target hash string in the project persistent property
|
||||||
properties.setAndroidTarget(target);
|
setProjectTargetHashString(project, target.hashString());
|
||||||
|
|
||||||
// put it in a local map for easy access.
|
// put it in a local map for easy access.
|
||||||
mProjectTargetMap.put(project, target);
|
mProjectTargetMap.put(project, target);
|
||||||
|
|
||||||
resolveProject = true;
|
// recompile the project if needed.
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apkConfigMap != null) {
|
|
||||||
// save the apk configs in the project persistent property
|
|
||||||
cleanProject = ApkConfigurationHelper.setConfigs(properties, apkConfigMap);
|
|
||||||
|
|
||||||
// put it in a local map for easy access.
|
|
||||||
mProjectApkConfigMap.put(project, apkConfigMap);
|
|
||||||
|
|
||||||
compileProject = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we are done with the modification. Save the property file.
|
|
||||||
try {
|
|
||||||
properties.save();
|
|
||||||
} catch (IOException e) {
|
|
||||||
AdtPlugin.log(e, "Failed to save default.properties for project '%s'",
|
|
||||||
project.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resolveProject) {
|
|
||||||
// force a resolve of the project by updating the classpath container.
|
|
||||||
IJavaProject javaProject = JavaCore.create(project);
|
IJavaProject javaProject = JavaCore.create(project);
|
||||||
AndroidClasspathContainerInitializer.updateProjects(
|
AndroidClasspathContainerInitializer.updateProjects(
|
||||||
new IJavaProject[] { javaProject });
|
new IJavaProject[] { javaProject });
|
||||||
} else if (compileProject) {
|
|
||||||
// If there was removed configs, we clean instead of build
|
|
||||||
// (to remove the obsolete ap_ and apk file from removed configs).
|
|
||||||
try {
|
|
||||||
project.build(cleanProject ?
|
|
||||||
IncrementalProjectBuilder.CLEAN_BUILD :
|
|
||||||
IncrementalProjectBuilder.FULL_BUILD,
|
|
||||||
null);
|
|
||||||
} catch (CoreException e) {
|
|
||||||
// failed to build? force resolve instead.
|
|
||||||
IJavaProject javaProject = JavaCore.create(project);
|
|
||||||
AndroidClasspathContainerInitializer.updateProjects(
|
|
||||||
new IJavaProject[] { javaProject });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally, update the opened editors.
|
|
||||||
if (resolveProject) {
|
|
||||||
AdtPlugin.getDefault().updateTargetListener(project);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -299,12 +218,7 @@ public class Sdk implements IProjectListener {
|
|||||||
*/
|
*/
|
||||||
private static String loadProjectProperties(IProject project, Sdk sdkStorage) {
|
private static String loadProjectProperties(IProject project, Sdk sdkStorage) {
|
||||||
// load the default.properties from the project folder.
|
// load the default.properties from the project folder.
|
||||||
IPath location = project.getLocation();
|
ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(),
|
||||||
if (location == null) { // can return null when the project is being deleted.
|
|
||||||
// do nothing and return null;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ProjectProperties properties = ProjectProperties.load(location.toOSString(),
|
|
||||||
PropertyType.DEFAULT);
|
PropertyType.DEFAULT);
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'",
|
AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'",
|
||||||
@@ -315,7 +229,7 @@ public class Sdk implements IProjectListener {
|
|||||||
if (sdkStorage != null) {
|
if (sdkStorage != null) {
|
||||||
Map<String, String> configMap = ApkConfigurationHelper.getConfigs(properties);
|
Map<String, String> configMap = ApkConfigurationHelper.getConfigs(properties);
|
||||||
|
|
||||||
if (configMap != null) {
|
if (configMap.size() > 0) {
|
||||||
sdkStorage.mProjectApkConfigMap.put(project, configMap);
|
sdkStorage.mProjectApkConfigMap.put(project, configMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,6 +296,40 @@ public class Sdk implements IProjectListener {
|
|||||||
return mProjectApkConfigMap.get(project);
|
return mProjectApkConfigMap.get(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setProjectApkConfigs(IProject project, Map<String, String> configMap)
|
||||||
|
throws CoreException {
|
||||||
|
// first set the new map
|
||||||
|
mProjectApkConfigMap.put(project, configMap);
|
||||||
|
|
||||||
|
// Now we write this in default.properties.
|
||||||
|
// Because we don't want to erase other properties from default.properties, we first load
|
||||||
|
// them
|
||||||
|
ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(),
|
||||||
|
PropertyType.DEFAULT);
|
||||||
|
if (properties == null) {
|
||||||
|
// doesn't exist yet? we create it.
|
||||||
|
properties = ProjectProperties.create(project.getLocation().toOSString(),
|
||||||
|
PropertyType.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets the configs in the property file.
|
||||||
|
boolean hasRemovedConfig = ApkConfigurationHelper.setConfigs(properties, configMap);
|
||||||
|
|
||||||
|
// and rewrite the file.
|
||||||
|
try {
|
||||||
|
properties.save();
|
||||||
|
} catch (IOException e) {
|
||||||
|
AdtPlugin.log(e, "Failed to save default.properties for project '%s'",
|
||||||
|
project.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're done, force a rebuild. If there was removed config, we clean instead of build
|
||||||
|
// (to remove the obsolete ap_ and apk file from removed configs).
|
||||||
|
project.build(hasRemovedConfig ?
|
||||||
|
IncrementalProjectBuilder.CLEAN_BUILD : IncrementalProjectBuilder.FULL_BUILD,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link AvdManager}. If the AvdManager failed to parse the AVD folder, this could
|
* Returns the {@link AvdManager}. If the AvdManager failed to parse the AVD folder, this could
|
||||||
* be <code>null</code>.
|
* be <code>null</code>.
|
||||||
@@ -454,25 +402,9 @@ public class Sdk implements IProjectListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void projectClosed(IProject project) {
|
public void projectClosed(IProject project) {
|
||||||
// get the target project
|
|
||||||
synchronized (mProjectTargetMap) {
|
|
||||||
IAndroidTarget target = mProjectTargetMap.get(project);
|
|
||||||
if (target != null) {
|
|
||||||
// get the bridge for the target, and clear the cache for this project.
|
|
||||||
AndroidTargetData data = mTargetDataMap.get(target);
|
|
||||||
if (data != null) {
|
|
||||||
LayoutBridge bridge = data.getLayoutBridge();
|
|
||||||
if (bridge != null && bridge.status == LoadStatus.LOADED) {
|
|
||||||
bridge.bridge.clearCaches(project);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now remove the project for the maps.
|
|
||||||
mProjectTargetMap.remove(project);
|
mProjectTargetMap.remove(project);
|
||||||
mProjectApkConfigMap.remove(project);
|
mProjectApkConfigMap.remove(project);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void projectDeleted(IProject project) {
|
public void projectDeleted(IProject project) {
|
||||||
projectClosed(project);
|
projectClosed(project);
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.eclipse.org/org/documents/epl-v10.php
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.ide.eclipse.adt.wizards.actions;
|
|
||||||
|
|
||||||
import com.android.ide.eclipse.adt.wizards.newproject.NewProjectWizard;
|
|
||||||
|
|
||||||
import org.eclipse.jface.action.IAction;
|
|
||||||
import org.eclipse.ui.IWorkbenchWizard;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delegate for the toolbar action "Android Project".
|
|
||||||
* It displays the Android New Project wizard.
|
|
||||||
*/
|
|
||||||
public class NewProjectAction extends OpenWizardAction {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IWorkbenchWizard instanciateWizard(IAction action) {
|
|
||||||
return new NewProjectWizard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.eclipse.org/org/documents/epl-v10.php
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.ide.eclipse.adt.wizards.actions;
|
|
||||||
|
|
||||||
import com.android.ide.eclipse.editors.wizards.NewXmlFileWizard;
|
|
||||||
|
|
||||||
import org.eclipse.jface.action.IAction;
|
|
||||||
import org.eclipse.ui.IWorkbenchWizard;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delegate for the toolbar action "Android Project".
|
|
||||||
* It displays the Android New XML file wizard.
|
|
||||||
*/
|
|
||||||
public class NewXmlFileAction extends OpenWizardAction {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected IWorkbenchWizard instanciateWizard(IAction action) {
|
|
||||||
return new NewXmlFileWizard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.eclipse.org/org/documents/epl-v10.php
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.ide.eclipse.adt.wizards.actions;
|
|
||||||
|
|
||||||
import org.eclipse.jface.action.IAction;
|
|
||||||
import org.eclipse.jface.viewers.ISelection;
|
|
||||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
|
||||||
import org.eclipse.jface.viewers.StructuredSelection;
|
|
||||||
import org.eclipse.jface.wizard.WizardDialog;
|
|
||||||
import org.eclipse.swt.graphics.Point;
|
|
||||||
import org.eclipse.swt.widgets.Shell;
|
|
||||||
import org.eclipse.ui.IEditorInput;
|
|
||||||
import org.eclipse.ui.IEditorPart;
|
|
||||||
import org.eclipse.ui.IWorkbench;
|
|
||||||
import org.eclipse.ui.IWorkbenchPart;
|
|
||||||
import org.eclipse.ui.IWorkbenchWindow;
|
|
||||||
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
|
|
||||||
import org.eclipse.ui.IWorkbenchWizard;
|
|
||||||
import org.eclipse.ui.PlatformUI;
|
|
||||||
import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
|
|
||||||
import org.eclipse.ui.internal.LegacyResourceSupport;
|
|
||||||
import org.eclipse.ui.internal.actions.NewWizardShortcutAction;
|
|
||||||
import org.eclipse.ui.internal.util.Util;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An abstract action that displays one of our wizards.
|
|
||||||
* Derived classes must provide the actual wizard to display.
|
|
||||||
*/
|
|
||||||
/*package*/ abstract class OpenWizardAction implements IWorkbenchWindowActionDelegate {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The wizard dialog width, extracted from {@link NewWizardShortcutAction}
|
|
||||||
*/
|
|
||||||
private static final int SIZING_WIZARD_WIDTH = 500;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The wizard dialog height, extracted from {@link NewWizardShortcutAction}
|
|
||||||
*/
|
|
||||||
private static final int SIZING_WIZARD_HEIGHT = 500;
|
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
|
|
||||||
*/
|
|
||||||
public void dispose() {
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
|
|
||||||
*/
|
|
||||||
public void init(IWorkbenchWindow window) {
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens and display the Android New Project Wizard.
|
|
||||||
* <p/>
|
|
||||||
* Most of this implementation is extracted from {@link NewWizardShortcutAction#run()}.
|
|
||||||
*
|
|
||||||
* @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
|
|
||||||
*/
|
|
||||||
public void run(IAction action) {
|
|
||||||
|
|
||||||
// get the workbench and the current window
|
|
||||||
IWorkbench workbench = PlatformUI.getWorkbench();
|
|
||||||
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
|
|
||||||
|
|
||||||
// This code from NewWizardShortcutAction#run() gets the current window selection
|
|
||||||
// and converts it to a workbench structured selection for the wizard, if possible.
|
|
||||||
ISelection selection = window.getSelectionService().getSelection();
|
|
||||||
IStructuredSelection selectionToPass = StructuredSelection.EMPTY;
|
|
||||||
if (selection instanceof IStructuredSelection) {
|
|
||||||
selectionToPass = (IStructuredSelection) selection;
|
|
||||||
} else {
|
|
||||||
// Build the selection from the IFile of the editor
|
|
||||||
IWorkbenchPart part = window.getPartService().getActivePart();
|
|
||||||
if (part instanceof IEditorPart) {
|
|
||||||
IEditorInput input = ((IEditorPart) part).getEditorInput();
|
|
||||||
Class<?> fileClass = LegacyResourceSupport.getFileClass();
|
|
||||||
if (input != null && fileClass != null) {
|
|
||||||
Object file = Util.getAdapter(input, fileClass);
|
|
||||||
if (file != null) {
|
|
||||||
selectionToPass = new StructuredSelection(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the wizard and initialize it with the selection
|
|
||||||
IWorkbenchWizard wizard = instanciateWizard(action);
|
|
||||||
wizard.init(workbench, selectionToPass);
|
|
||||||
|
|
||||||
// It's not visible yet until a dialog is created and opened
|
|
||||||
Shell parent = window.getShell();
|
|
||||||
WizardDialog dialog = new WizardDialog(parent, wizard);
|
|
||||||
dialog.create();
|
|
||||||
|
|
||||||
// This code comes straight from NewWizardShortcutAction#run()
|
|
||||||
Point defaultSize = dialog.getShell().getSize();
|
|
||||||
dialog.getShell().setSize(
|
|
||||||
Math.max(SIZING_WIZARD_WIDTH, defaultSize.x),
|
|
||||||
Math.max(SIZING_WIZARD_HEIGHT, defaultSize.y));
|
|
||||||
window.getWorkbench().getHelpSystem().setHelp(dialog.getShell(),
|
|
||||||
IWorkbenchHelpContextIds.NEW_WIZARD_SHORTCUT);
|
|
||||||
|
|
||||||
dialog.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called by {@link #run(IAction)} to instantiate the actual wizard.
|
|
||||||
*
|
|
||||||
* @param action The action parameter from {@link #run(IAction)}.
|
|
||||||
* @return A new wizard instance. Must not be null.
|
|
||||||
*/
|
|
||||||
protected abstract IWorkbenchWizard instanciateWizard(IAction action);
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
|
|
||||||
*/
|
|
||||||
public void selectionChanged(IAction action, ISelection selection) {
|
|
||||||
// pass
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -105,8 +105,6 @@ public class NewProjectWizard extends Wizard implements INewWizard {
|
|||||||
SdkConstants.FD_LAYOUT + AndroidConstants.WS_SEP;
|
SdkConstants.FD_LAYOUT + AndroidConstants.WS_SEP;
|
||||||
private static final String VALUES_DIRECTORY =
|
private static final String VALUES_DIRECTORY =
|
||||||
SdkConstants.FD_VALUES + AndroidConstants.WS_SEP;
|
SdkConstants.FD_VALUES + AndroidConstants.WS_SEP;
|
||||||
private static final String GEN_SRC_DIRECTORY =
|
|
||||||
SdkConstants.FD_GEN_SOURCES + AndroidConstants.WS_SEP;
|
|
||||||
|
|
||||||
private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$
|
private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$
|
||||||
private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY
|
private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY
|
||||||
@@ -343,20 +341,15 @@ public class NewProjectWizard extends Wizard implements INewWizard {
|
|||||||
|
|
||||||
// Create folders in the project if they don't already exist
|
// Create folders in the project if they don't already exist
|
||||||
addDefaultDirectories(project, AndroidConstants.WS_ROOT, DEFAULT_DIRECTORIES, monitor);
|
addDefaultDirectories(project, AndroidConstants.WS_ROOT, DEFAULT_DIRECTORIES, monitor);
|
||||||
String[] sourceFolders = new String[] {
|
String[] sourceFolder = new String[] { (String) parameters.get(PARAM_SRC_FOLDER) };
|
||||||
(String) parameters.get(PARAM_SRC_FOLDER),
|
addDefaultDirectories(project, AndroidConstants.WS_ROOT, sourceFolder, monitor);
|
||||||
GEN_SRC_DIRECTORY
|
|
||||||
};
|
|
||||||
addDefaultDirectories(project, AndroidConstants.WS_ROOT, sourceFolders, monitor);
|
|
||||||
|
|
||||||
// Create the resource folders in the project if they don't already exist.
|
// Create the resource folders in the project if they don't already exist.
|
||||||
addDefaultDirectories(project, RES_DIRECTORY, RES_DIRECTORIES, monitor);
|
addDefaultDirectories(project, RES_DIRECTORY, RES_DIRECTORIES, monitor);
|
||||||
|
|
||||||
// Setup class path
|
// Setup class path
|
||||||
IJavaProject javaProject = JavaCore.create(project);
|
IJavaProject javaProject = JavaCore.create(project);
|
||||||
for (String sourceFolder : sourceFolders) {
|
setupSourceFolder(javaProject, sourceFolder[0], monitor);
|
||||||
setupSourceFolder(javaProject, sourceFolder, monitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((Boolean) parameters.get(PARAM_IS_NEW_PROJECT)).booleanValue()) {
|
if (((Boolean) parameters.get(PARAM_IS_NEW_PROJECT)).booleanValue()) {
|
||||||
// Create files in the project if they don't already exist
|
// Create files in the project if they don't already exist
|
||||||
@@ -366,7 +359,7 @@ public class NewProjectWizard extends Wizard implements INewWizard {
|
|||||||
addIcon(project, monitor);
|
addIcon(project, monitor);
|
||||||
|
|
||||||
// Create the default package components
|
// Create the default package components
|
||||||
addSampleCode(project, sourceFolders[0], parameters, stringDictionary, monitor);
|
addSampleCode(project, sourceFolder[0], parameters, stringDictionary, monitor);
|
||||||
|
|
||||||
// add the string definition file if needed
|
// add the string definition file if needed
|
||||||
if (stringDictionary.size() > 0) {
|
if (stringDictionary.size() > 0) {
|
||||||
@@ -378,8 +371,7 @@ public class NewProjectWizard extends Wizard implements INewWizard {
|
|||||||
monitor);
|
monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Sdk.getCurrent().setProject(project, (IAndroidTarget) parameters.get(PARAM_SDK_TARGET),
|
Sdk.getCurrent().setProject(project, (IAndroidTarget) parameters.get(PARAM_SDK_TARGET));
|
||||||
null /* apkConfigMap*/);
|
|
||||||
|
|
||||||
// Fix the project to make sure all properties are as expected.
|
// Fix the project to make sure all properties are as expected.
|
||||||
// Necessary for existing projects and good for new ones to.
|
// Necessary for existing projects and good for new ones to.
|
||||||
|
|||||||
@@ -148,11 +148,8 @@ public class AndroidConstants {
|
|||||||
/** The old common plug-in ID. Please do not use for new features. */
|
/** The old common plug-in ID. Please do not use for new features. */
|
||||||
public static final String COMMON_PLUGIN_ID = "com.android.ide.eclipse.common"; //$NON-NLS-1$
|
public static final String COMMON_PLUGIN_ID = "com.android.ide.eclipse.common"; //$NON-NLS-1$
|
||||||
|
|
||||||
/** aapt marker error when running the compile command */
|
/** aapt marker error. */
|
||||||
public final static String MARKER_AAPT_COMPILE = COMMON_PLUGIN_ID + ".aaptProblem"; //$NON-NLS-1$
|
public final static String MARKER_AAPT = COMMON_PLUGIN_ID + ".aaptProblem"; //$NON-NLS-1$
|
||||||
|
|
||||||
/** aapt marker error when running the package command */
|
|
||||||
public final static String MARKER_AAPT_PACKAGE = COMMON_PLUGIN_ID + ".aapt2Problem"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
/** XML marker error. */
|
/** XML marker error. */
|
||||||
public final static String MARKER_XML = COMMON_PLUGIN_ID + ".xmlProblem"; //$NON-NLS-1$
|
public final static String MARKER_XML = COMMON_PLUGIN_ID + ".xmlProblem"; //$NON-NLS-1$
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.android.ide.eclipse.editors;
|
|||||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||||
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
|
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
|
|
||||||
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
|
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
|
||||||
import com.android.sdklib.IAndroidTarget;
|
import com.android.sdklib.IAndroidTarget;
|
||||||
|
|
||||||
@@ -98,9 +97,8 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
|
|||||||
private StructuredTextEditor mTextEditor;
|
private StructuredTextEditor mTextEditor;
|
||||||
/** Listener for the XML model from the StructuredEditor */
|
/** Listener for the XML model from the StructuredEditor */
|
||||||
private XmlModelStateListener mXmlModelStateListener;
|
private XmlModelStateListener mXmlModelStateListener;
|
||||||
/** Listener to update the root node if the target of the file is changed because of a
|
/** Listener to update the root node if the resource framework changes */
|
||||||
* SDK location change or a project target change */
|
private Runnable mResourceRefreshListener;
|
||||||
private ITargetChangeListener mTargetListener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a form editor.
|
* Creates a form editor.
|
||||||
@@ -109,21 +107,15 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
|
|||||||
super();
|
super();
|
||||||
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
|
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
|
||||||
|
|
||||||
mTargetListener = new ITargetChangeListener() {
|
mResourceRefreshListener = new Runnable() {
|
||||||
public void onProjectTargetChange(IProject changedProject) {
|
public void run() {
|
||||||
if (changedProject == getProject()) {
|
|
||||||
onTargetsLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTargetsLoaded() {
|
|
||||||
commitPages(false /* onSave */);
|
commitPages(false /* onSave */);
|
||||||
|
|
||||||
// recreate the ui root node always
|
// recreate the ui root node always
|
||||||
initUiRootNode(true /*force*/);
|
initUiRootNode(true /*force*/);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
AdtPlugin.getDefault().addTargetListener(mTargetListener);
|
AdtPlugin.getDefault().addResourceChangedListener(mResourceRefreshListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Abstract Methods ----
|
// ---- Abstract Methods ----
|
||||||
@@ -348,9 +340,9 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang
|
|||||||
}
|
}
|
||||||
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
|
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
|
||||||
|
|
||||||
if (mTargetListener != null) {
|
if (mResourceRefreshListener != null) {
|
||||||
AdtPlugin.getDefault().removeTargetListener(mTargetListener);
|
AdtPlugin.getDefault().removeResourceChangedListener(mResourceRefreshListener);
|
||||||
mTargetListener = null;
|
mResourceRefreshListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ public final class DescriptorsUtils {
|
|||||||
*
|
*
|
||||||
* @param attributes The list of {@link AttributeDescriptor} to compare to.
|
* @param attributes The list of {@link AttributeDescriptor} to compare to.
|
||||||
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
|
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
|
||||||
* See {@link SdkConstants#NS_RESOURCES} for a common value.
|
* See {@link AndroidConstants#NS_RESOURCES} for a common value.
|
||||||
* @param info The {@link AttributeInfo} to know whether it is included in the above list.
|
* @param info The {@link AttributeInfo} to know whether it is included in the above list.
|
||||||
* @return True if this {@link AttributeInfo} is already present in
|
* @return True if this {@link AttributeInfo} is already present in
|
||||||
* the {@link AttributeDescriptor} list.
|
* the {@link AttributeDescriptor} list.
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
|
|||||||
import com.android.ide.eclipse.adt.sdk.LoadStatus;
|
import com.android.ide.eclipse.adt.sdk.LoadStatus;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk;
|
import com.android.ide.eclipse.adt.sdk.Sdk;
|
||||||
import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge;
|
import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
|
|
||||||
import com.android.ide.eclipse.common.resources.ResourceType;
|
import com.android.ide.eclipse.common.resources.ResourceType;
|
||||||
import com.android.ide.eclipse.editors.IconFactory;
|
import com.android.ide.eclipse.editors.IconFactory;
|
||||||
import com.android.ide.eclipse.editors.layout.LayoutEditor.UiEditorActions;
|
import com.android.ide.eclipse.editors.layout.LayoutEditor.UiEditorActions;
|
||||||
@@ -199,21 +198,13 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
private ProjectCallback mProjectCallback;
|
private ProjectCallback mProjectCallback;
|
||||||
private ILayoutLog mLogger;
|
private ILayoutLog mLogger;
|
||||||
|
|
||||||
private boolean mNeedsXmlReload = false;
|
|
||||||
private boolean mNeedsRecompute = false;
|
private boolean mNeedsRecompute = false;
|
||||||
private int mPlatformThemeCount = 0;
|
private int mPlatformThemeCount = 0;
|
||||||
private boolean mDisableUpdates = false;
|
private boolean mDisableUpdates = false;
|
||||||
|
private boolean mActive = false;
|
||||||
|
|
||||||
/** Listener to update the root node if the target of the file is changed because of a
|
private Runnable mFrameworkResourceChangeListener = new Runnable() {
|
||||||
* SDK location change or a project target change */
|
public void run() {
|
||||||
private ITargetChangeListener mTargetListener = new ITargetChangeListener() {
|
|
||||||
public void onProjectTargetChange(IProject changedProject) {
|
|
||||||
if (changedProject == getLayoutEditor().getProject()) {
|
|
||||||
onTargetsLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTargetsLoaded() {
|
|
||||||
// because the SDK changed we must reset the configured framework resource.
|
// because the SDK changed we must reset the configured framework resource.
|
||||||
mConfiguredFrameworkRes = null;
|
mConfiguredFrameworkRes = null;
|
||||||
|
|
||||||
@@ -237,7 +228,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
|
|
||||||
private final Runnable mConditionalRecomputeRunnable = new Runnable() {
|
private final Runnable mConditionalRecomputeRunnable = new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mLayoutEditor.isGraphicalEditorActive()) {
|
if (mActive) {
|
||||||
recomputeLayout();
|
recomputeLayout();
|
||||||
} else {
|
} else {
|
||||||
mNeedsRecompute = true;
|
mNeedsRecompute = true;
|
||||||
@@ -262,7 +253,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
mMatchImage = factory.getIcon("match"); //$NON-NLS-1$
|
mMatchImage = factory.getIcon("match"); //$NON-NLS-1$
|
||||||
mErrorImage = factory.getIcon("error"); //$NON-NLS-1$
|
mErrorImage = factory.getIcon("error"); //$NON-NLS-1$
|
||||||
|
|
||||||
AdtPlugin.getDefault().addTargetListener(mTargetListener);
|
AdtPlugin.getDefault().addResourceChangedListener(mFrameworkResourceChangeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
@@ -570,9 +561,10 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (mTargetListener != null) {
|
if (mFrameworkResourceChangeListener != null) {
|
||||||
AdtPlugin.getDefault().removeTargetListener(mTargetListener);
|
AdtPlugin.getDefault().removeResourceChangedListener(
|
||||||
mTargetListener = null;
|
mFrameworkResourceChangeListener);
|
||||||
|
mFrameworkResourceChangeListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayoutReloadMonitor.getMonitor().removeListener(mEditedFile.getProject(), this);
|
LayoutReloadMonitor.getMonitor().removeListener(mEditedFile.getProject(), this);
|
||||||
@@ -1034,23 +1026,9 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for XML model changed. Only update/recompute the layout if the editor is visible
|
* Update the layout editor when the Xml model is changed.
|
||||||
*/
|
*/
|
||||||
void onXmlModelChanged() {
|
void onXmlModelChanged() {
|
||||||
if (mLayoutEditor.isGraphicalEditorActive()) {
|
|
||||||
doXmlReload(true /* force */);
|
|
||||||
recomputeLayout();
|
|
||||||
} else {
|
|
||||||
mNeedsXmlReload = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Actually performs the XML reload
|
|
||||||
* @see #onXmlModelChanged()
|
|
||||||
*/
|
|
||||||
private void doXmlReload(boolean force) {
|
|
||||||
if (force || mNeedsXmlReload) {
|
|
||||||
GraphicalViewer viewer = getGraphicalViewer();
|
GraphicalViewer viewer = getGraphicalViewer();
|
||||||
|
|
||||||
// try to preserve the selection before changing the content
|
// try to preserve the selection before changing the content
|
||||||
@@ -1063,7 +1041,10 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
selMan.setSelection(selection);
|
selMan.setSelection(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
mNeedsXmlReload = false;
|
if (mLayoutEditor.isGraphicalEditorActive()) {
|
||||||
|
recomputeLayout();
|
||||||
|
} else {
|
||||||
|
mNeedsRecompute = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1667,9 +1648,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
/**
|
/**
|
||||||
* Recomputes the layout with the help of layoutlib.
|
* Recomputes the layout with the help of layoutlib.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
void recomputeLayout() {
|
void recomputeLayout() {
|
||||||
doXmlReload(false /* force */);
|
|
||||||
try {
|
try {
|
||||||
// check that the resource exists. If the file is opened but the project is closed
|
// check that the resource exists. If the file is opened but the project is closed
|
||||||
// or deleted for some reason (changed from outside of eclipse), then this will
|
// or deleted for some reason (changed from outside of eclipse), then this will
|
||||||
@@ -1784,47 +1763,20 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
if (themeIndex != -1) {
|
if (themeIndex != -1) {
|
||||||
String theme = mThemeCombo.getItem(themeIndex);
|
String theme = mThemeCombo.getItem(themeIndex);
|
||||||
|
|
||||||
// Compute the layout
|
|
||||||
UiElementPullParser parser = new UiElementPullParser(getModel());
|
|
||||||
Rectangle rect = getBounds();
|
|
||||||
ILayoutResult result = null;
|
|
||||||
if (bridge.apiLevel >= 3) {
|
|
||||||
// call the new api with proper theme differentiator and
|
|
||||||
// density/dpi support.
|
|
||||||
boolean isProjectTheme = themeIndex >= mPlatformThemeCount;
|
|
||||||
|
|
||||||
// FIXME pass the density/dpi from somewhere (resource config or skin).
|
|
||||||
result = bridge.bridge.computeLayout(parser,
|
|
||||||
iProject /* projectKey */,
|
|
||||||
rect.width, rect.height, 160, 160.f, 160.f,
|
|
||||||
theme, isProjectTheme,
|
|
||||||
mConfiguredProjectRes, frameworkResources, mProjectCallback,
|
|
||||||
mLogger);
|
|
||||||
} else if (bridge.apiLevel == 2) {
|
|
||||||
// api with boolean for separation of project/framework theme
|
|
||||||
boolean isProjectTheme = themeIndex >= mPlatformThemeCount;
|
|
||||||
|
|
||||||
result = bridge.bridge.computeLayout(parser,
|
|
||||||
iProject /* projectKey */,
|
|
||||||
rect.width, rect.height, theme, isProjectTheme,
|
|
||||||
mConfiguredProjectRes, frameworkResources, mProjectCallback,
|
|
||||||
mLogger);
|
|
||||||
} else {
|
|
||||||
// oldest api with no density/dpi, and project theme boolean mixed
|
|
||||||
// into the theme name.
|
|
||||||
|
|
||||||
// change the string if it's a custom theme to make sure we can
|
// change the string if it's a custom theme to make sure we can
|
||||||
// differentiate them
|
// differentiate them
|
||||||
if (themeIndex >= mPlatformThemeCount) {
|
if (themeIndex >= mPlatformThemeCount) {
|
||||||
theme = "*" + theme; //$NON-NLS-1$
|
theme = "*" + theme; //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
result = bridge.bridge.computeLayout(parser,
|
// Compute the layout
|
||||||
|
UiElementPullParser parser = new UiElementPullParser(getModel());
|
||||||
|
Rectangle rect = getBounds();
|
||||||
|
ILayoutResult result = bridge.bridge.computeLayout(parser,
|
||||||
iProject /* projectKey */,
|
iProject /* projectKey */,
|
||||||
rect.width, rect.height, theme,
|
rect.width, rect.height, theme,
|
||||||
mConfiguredProjectRes, frameworkResources, mProjectCallback,
|
mConfiguredProjectRes, frameworkResources, mProjectCallback,
|
||||||
mLogger);
|
mLogger);
|
||||||
}
|
|
||||||
|
|
||||||
// update the UiElementNode with the layout info.
|
// update the UiElementNode with the layout info.
|
||||||
if (result.getSuccess() == ILayoutResult.SUCCESS) {
|
if (result.getSuccess() == ILayoutResult.SUCCESS) {
|
||||||
@@ -1969,7 +1921,8 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
* Responds to a page change that made the Graphical editor page the activated page.
|
* Responds to a page change that made the Graphical editor page the activated page.
|
||||||
*/
|
*/
|
||||||
void activated() {
|
void activated() {
|
||||||
if (mNeedsRecompute || mNeedsXmlReload) {
|
mActive = true;
|
||||||
|
if (mNeedsRecompute) {
|
||||||
recomputeLayout();
|
recomputeLayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1978,7 +1931,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette
|
|||||||
* Responds to a page change that made the Graphical editor page the deactivated page
|
* Responds to a page change that made the Graphical editor page the deactivated page
|
||||||
*/
|
*/
|
||||||
void deactivated() {
|
void deactivated() {
|
||||||
// nothing to be done here for now.
|
mActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -269,12 +269,8 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa
|
|||||||
protected void pageChange(int newPageIndex) {
|
protected void pageChange(int newPageIndex) {
|
||||||
super.pageChange(newPageIndex);
|
super.pageChange(newPageIndex);
|
||||||
|
|
||||||
if (mGraphicalEditor != null) {
|
if (mGraphicalEditor != null && newPageIndex == mGraphicalEditorIndex) {
|
||||||
if (newPageIndex == mGraphicalEditorIndex) {
|
|
||||||
mGraphicalEditor.activated();
|
mGraphicalEditor.activated();
|
||||||
} else {
|
|
||||||
mGraphicalEditor.deactivated();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,12 +278,8 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa
|
|||||||
|
|
||||||
public void partActivated(IWorkbenchPart part) {
|
public void partActivated(IWorkbenchPart part) {
|
||||||
if (part == this) {
|
if (part == this) {
|
||||||
if (mGraphicalEditor != null) {
|
if (mGraphicalEditor != null && getActivePage() == mGraphicalEditorIndex) {
|
||||||
if (getActivePage() == mGraphicalEditorIndex) {
|
|
||||||
mGraphicalEditor.activated();
|
mGraphicalEditor.activated();
|
||||||
} else {
|
|
||||||
mGraphicalEditor.deactivated();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,15 +334,15 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa
|
|||||||
// ---- Local Methods ----
|
// ---- Local Methods ----
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the Graphics editor page is visible. This <b>must</b> be
|
* Returns true if the Graphics editor page is visible.
|
||||||
* called from the UI thread.
|
* This <b>must</b> be called from the UI thread.
|
||||||
*/
|
*/
|
||||||
boolean isGraphicalEditorActive() {
|
boolean isGraphicalEditorActive() {
|
||||||
IWorkbenchPartSite workbenchSite = getSite();
|
IWorkbenchPartSite workbenchSite = getSite();
|
||||||
IWorkbenchPage workbenchPage = workbenchSite.getPage();
|
IWorkbenchPage workbenchPage = workbenchSite.getPage();
|
||||||
|
|
||||||
// check if the editor is visible in the workbench page
|
// check if the editor is visible in the workbench page
|
||||||
if (workbenchPage.isPartVisible(this) && workbenchPage.getActiveEditor() == this) {
|
if (workbenchPage.isPartVisible(this)) {
|
||||||
// and then if the page of the editor is visible (not to be confused with
|
// and then if the page of the editor is visible (not to be confused with
|
||||||
// the workbench page)
|
// the workbench page)
|
||||||
return mGraphicalEditorIndex == getActivePage();
|
return mGraphicalEditorIndex == getActivePage();
|
||||||
|
|||||||
@@ -195,8 +195,6 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
|
|||||||
overrides.put("*/permission", ListAttributeDescriptor.class); //$NON-NLS-1$
|
overrides.put("*/permission", ListAttributeDescriptor.class); //$NON-NLS-1$
|
||||||
overrides.put("*/targetPackage", PackageAttributeDescriptor.class); //$NON-NLS-1$
|
overrides.put("*/targetPackage", PackageAttributeDescriptor.class); //$NON-NLS-1$
|
||||||
|
|
||||||
overrides.put("uses-library/name", ListAttributeDescriptor.class); //$NON-NLS-1$
|
|
||||||
|
|
||||||
overrides.put("action,category,uses-permission/" + ANDROID_NAME_ATTR, //$NON-NLS-1$
|
overrides.put("action,category,uses-permission/" + ANDROID_NAME_ATTR, //$NON-NLS-1$
|
||||||
ListAttributeDescriptor.class);
|
ListAttributeDescriptor.class);
|
||||||
overrides.put("application/" + ANDROID_NAME_ATTR, ApplicationAttributeDescriptor.class); //$NON-NLS-1$
|
overrides.put("application/" + ANDROID_NAME_ATTR, ApplicationAttributeDescriptor.class); //$NON-NLS-1$
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
package com.android.ide.eclipse.editors.manifest.descriptors;
|
package com.android.ide.eclipse.editors.manifest.descriptors;
|
||||||
|
|
||||||
|
import com.android.ide.eclipse.common.AndroidConstants;
|
||||||
import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
|
import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
|
||||||
import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode;
|
import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode;
|
||||||
import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction;
|
import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction;
|
||||||
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
|
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
|
||||||
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
|
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
|
||||||
import com.android.sdklib.SdkConstants;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes an XML attribute representing a class name.
|
* Describes an XML attribute representing a class name.
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package com.android.ide.eclipse.editors.ui.tree;
|
package com.android.ide.eclipse.editors.ui.tree;
|
||||||
|
|
||||||
import com.android.ide.eclipse.adt.AdtPlugin;
|
import com.android.ide.eclipse.adt.AdtPlugin;
|
||||||
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
|
|
||||||
import com.android.ide.eclipse.editors.AndroidEditor;
|
import com.android.ide.eclipse.editors.AndroidEditor;
|
||||||
import com.android.ide.eclipse.editors.IconFactory;
|
import com.android.ide.eclipse.editors.IconFactory;
|
||||||
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
|
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
|
||||||
@@ -27,7 +26,6 @@ import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener;
|
|||||||
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
|
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
|
||||||
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
|
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IProject;
|
|
||||||
import org.eclipse.jface.action.Action;
|
import org.eclipse.jface.action.Action;
|
||||||
import org.eclipse.jface.action.IMenuListener;
|
import org.eclipse.jface.action.IMenuListener;
|
||||||
import org.eclipse.jface.action.IMenuManager;
|
import org.eclipse.jface.action.IMenuManager;
|
||||||
@@ -287,21 +285,13 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Listener to update the root node if the target of the file is changed because of a
|
final Runnable resourceRefreshListener = new Runnable() {
|
||||||
* SDK location change or a project target change */
|
public void run() {
|
||||||
final ITargetChangeListener targetListener = new ITargetChangeListener() {
|
|
||||||
public void onProjectTargetChange(IProject changedProject) {
|
|
||||||
if (changedProject == mEditor.getProject()) {
|
|
||||||
onTargetsLoaded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onTargetsLoaded() {
|
|
||||||
// If a details part has been created, we need to "refresh" it too.
|
// If a details part has been created, we need to "refresh" it too.
|
||||||
if (mDetailsPart != null) {
|
if (mDetailsPart != null) {
|
||||||
// The details part does not directly expose access to its internal
|
// The details part does not directly expose access to its internal
|
||||||
// page book. Instead it is possible to resize the page book to 0 and then
|
// page book. Instead it is possible to resize the page book to 0 and then
|
||||||
// back to its original value, which has the side effect of removing all
|
// back to its original value, which as the side effect of removing all
|
||||||
// existing cached pages.
|
// existing cached pages.
|
||||||
int limit = mDetailsPart.getPageLimit();
|
int limit = mDetailsPart.getPageLimit();
|
||||||
mDetailsPart.setPageLimit(0);
|
mDetailsPart.setPageLimit(0);
|
||||||
@@ -316,7 +306,7 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml
|
|||||||
changeRootAndDescriptors(mUiRootNode, mDescriptorFilters, false /* refresh */);
|
changeRootAndDescriptors(mUiRootNode, mDescriptorFilters, false /* refresh */);
|
||||||
|
|
||||||
// Listen on resource framework changes to refresh the tree
|
// Listen on resource framework changes to refresh the tree
|
||||||
AdtPlugin.getDefault().addTargetListener(targetListener);
|
AdtPlugin.getDefault().addResourceChangedListener(resourceRefreshListener);
|
||||||
|
|
||||||
// Remove listeners when the tree widget gets disposed.
|
// Remove listeners when the tree widget gets disposed.
|
||||||
tree.addDisposeListener(new DisposeListener() {
|
tree.addDisposeListener(new DisposeListener() {
|
||||||
@@ -328,7 +318,7 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml
|
|||||||
node.removeUpdateListener(mUiRefreshListener);
|
node.removeUpdateListener(mUiRefreshListener);
|
||||||
mUiRootNode.removeUpdateListener(mUiEnableListener);
|
mUiRootNode.removeUpdateListener(mUiEnableListener);
|
||||||
|
|
||||||
AdtPlugin.getDefault().removeTargetListener(targetListener);
|
AdtPlugin.getDefault().removeResourceChangedListener(resourceRefreshListener);
|
||||||
if (mClipboard != null) {
|
if (mClipboard != null) {
|
||||||
mClipboard.dispose();
|
mClipboard.dispose();
|
||||||
mClipboard = null;
|
mClipboard = null;
|
||||||
@@ -590,11 +580,7 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml
|
|||||||
ui_node = ui_node.getUiParent()) {
|
ui_node = ui_node.getUiParent()) {
|
||||||
segments.add(0, ui_node);
|
segments.add(0, ui_node);
|
||||||
}
|
}
|
||||||
if (segments.size() > 0) {
|
|
||||||
mTreeViewer.setSelection(new TreeSelection(new TreePath(segments.toArray())));
|
mTreeViewer.setSelection(new TreeSelection(new TreePath(segments.toArray())));
|
||||||
} else {
|
|
||||||
mTreeViewer.setSelection(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import com.android.ide.eclipse.common.AndroidConstants;
|
|||||||
import com.android.ide.eclipse.common.project.ProjectChooserHelper;
|
import com.android.ide.eclipse.common.project.ProjectChooserHelper;
|
||||||
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.menu.descriptors.MenuDescriptors;
|
import com.android.ide.eclipse.editors.menu.descriptors.MenuDescriptors;
|
||||||
import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
|
import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
|
||||||
import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
|
import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
|
||||||
@@ -82,7 +81,6 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
private final String mXmlns;
|
private final String mXmlns;
|
||||||
private final String mDefaultAttrs;
|
private final String mDefaultAttrs;
|
||||||
private final String mDefaultRoot;
|
private final String mDefaultRoot;
|
||||||
private final int mTargetApiLevel;
|
|
||||||
|
|
||||||
public TypeInfo(String uiName,
|
public TypeInfo(String uiName,
|
||||||
String tooltip,
|
String tooltip,
|
||||||
@@ -90,8 +88,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
Object rootSeed,
|
Object rootSeed,
|
||||||
String defaultRoot,
|
String defaultRoot,
|
||||||
String xmlns,
|
String xmlns,
|
||||||
String defaultAttrs,
|
String defaultAttrs) {
|
||||||
int targetApiLevel) {
|
|
||||||
mUiName = uiName;
|
mUiName = uiName;
|
||||||
mResFolderType = resFolderType;
|
mResFolderType = resFolderType;
|
||||||
mTooltip = tooltip;
|
mTooltip = tooltip;
|
||||||
@@ -99,7 +96,6 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
mDefaultRoot = defaultRoot;
|
mDefaultRoot = defaultRoot;
|
||||||
mXmlns = xmlns;
|
mXmlns = xmlns;
|
||||||
mDefaultAttrs = defaultAttrs;
|
mDefaultAttrs = defaultAttrs;
|
||||||
mTargetApiLevel = targetApiLevel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the UI name for the resource type. Unique. Never null. */
|
/** Returns the UI name for the resource type. Unique. Never null. */
|
||||||
@@ -180,13 +176,6 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
String getDefaultAttrs() {
|
String getDefaultAttrs() {
|
||||||
return mDefaultAttrs;
|
return mDefaultAttrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The minimum API level required by the current SDK target to support this feature.
|
|
||||||
*/
|
|
||||||
public int getTargetApiLevel() {
|
|
||||||
return mTargetApiLevel;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -201,8 +190,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
"LinearLayout", // default root
|
"LinearLayout", // default root
|
||||||
SdkConstants.NS_RESOURCES, // xmlns
|
SdkConstants.NS_RESOURCES, // xmlns
|
||||||
"android:layout_width=\"wrap_content\"\n" + // default attributes
|
"android:layout_width=\"wrap_content\"\n" + // default attributes
|
||||||
"android:layout_height=\"wrap_content\"",
|
"android:layout_height=\"wrap_content\""
|
||||||
1 // target API level
|
|
||||||
),
|
),
|
||||||
new TypeInfo("Values", // UI name
|
new TypeInfo("Values", // UI name
|
||||||
"An XML file with simple values: colors, strings, dimensions, etc.", // tooltip
|
"An XML file with simple values: colors, strings, dimensions, etc.", // tooltip
|
||||||
@@ -210,8 +198,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
ResourcesDescriptors.ROOT_ELEMENT, // root seed
|
ResourcesDescriptors.ROOT_ELEMENT, // root seed
|
||||||
null, // default root
|
null, // default root
|
||||||
null, // xmlns
|
null, // xmlns
|
||||||
null, // default attributes
|
null // default attributes
|
||||||
1 // target API level
|
|
||||||
),
|
),
|
||||||
new TypeInfo("Menu", // UI name
|
new TypeInfo("Menu", // UI name
|
||||||
"An XML file that describes an menu.", // tooltip
|
"An XML file that describes an menu.", // tooltip
|
||||||
@@ -219,17 +206,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
MenuDescriptors.MENU_ROOT_ELEMENT, // root seed
|
MenuDescriptors.MENU_ROOT_ELEMENT, // root seed
|
||||||
null, // default root
|
null, // default root
|
||||||
SdkConstants.NS_RESOURCES, // xmlns
|
SdkConstants.NS_RESOURCES, // xmlns
|
||||||
null, // default attributes
|
null // default attributes
|
||||||
1 // target API level
|
|
||||||
),
|
|
||||||
new TypeInfo("Gadget Provider", // UI name
|
|
||||||
"An XML file that describes a gadget provider.", // tooltip
|
|
||||||
ResourceFolderType.XML, // folder type
|
|
||||||
AndroidTargetData.DESCRIPTOR_GADGET_PROVIDER, // root seed
|
|
||||||
null, // default root
|
|
||||||
SdkConstants.NS_RESOURCES, // xmlns
|
|
||||||
null, // default attributes
|
|
||||||
3 // target API level
|
|
||||||
),
|
),
|
||||||
new TypeInfo("Preference", // UI name
|
new TypeInfo("Preference", // UI name
|
||||||
"An XML file that describes preferences.", // tooltip
|
"An XML file that describes preferences.", // tooltip
|
||||||
@@ -237,17 +214,15 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
AndroidTargetData.DESCRIPTOR_PREFERENCES, // root seed
|
AndroidTargetData.DESCRIPTOR_PREFERENCES, // root seed
|
||||||
AndroidConstants.CLASS_PREFERENCE_SCREEN, // default root
|
AndroidConstants.CLASS_PREFERENCE_SCREEN, // default root
|
||||||
SdkConstants.NS_RESOURCES, // xmlns
|
SdkConstants.NS_RESOURCES, // xmlns
|
||||||
null, // default attributes
|
null // default attributes
|
||||||
1 // target API level
|
|
||||||
),
|
),
|
||||||
new TypeInfo("Searchable", // UI name
|
new TypeInfo("Searchable", // UI name
|
||||||
"An XML file that describes a searchable.", // tooltip
|
"An XML file that describes a searchable [TODO].", // tooltip
|
||||||
ResourceFolderType.XML, // folder type
|
ResourceFolderType.XML, // folder type
|
||||||
AndroidTargetData.DESCRIPTOR_SEARCHABLE, // root seed
|
AndroidTargetData.DESCRIPTOR_SEARCHABLE, // root seed
|
||||||
null, // default root
|
null, // default root
|
||||||
SdkConstants.NS_RESOURCES, // xmlns
|
SdkConstants.NS_RESOURCES, // xmlns
|
||||||
null, // default attributes
|
null // default attributes
|
||||||
1 // target API level
|
|
||||||
),
|
),
|
||||||
new TypeInfo("Animation", // UI name
|
new TypeInfo("Animation", // UI name
|
||||||
"An XML file that describes an animation.", // tooltip
|
"An XML file that describes an animation.", // tooltip
|
||||||
@@ -262,14 +237,10 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
},
|
},
|
||||||
"set", //$NON-NLS-1$ // default root
|
"set", //$NON-NLS-1$ // default root
|
||||||
null, // xmlns
|
null, // xmlns
|
||||||
null, // default attributes
|
null // default attributes
|
||||||
1 // target API level
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Number of columns in the grid layout */
|
|
||||||
final static int NUM_COL = 4;
|
|
||||||
|
|
||||||
/** Absolute destination folder root, e.g. "/res/" */
|
/** Absolute destination folder root, e.g. "/res/" */
|
||||||
private static String sResFolderAbs = AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP;
|
private static String sResFolderAbs = AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP;
|
||||||
/** Relative destination folder root, e.g. "res/" */
|
/** Relative destination folder root, e.g. "res/" */
|
||||||
@@ -319,7 +290,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
|
|
||||||
initializeDialogUnits(parent);
|
initializeDialogUnits(parent);
|
||||||
|
|
||||||
composite.setLayout(new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/));
|
composite.setLayout(new GridLayout(3, false /*makeColumnsEqualWidth*/));
|
||||||
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
|
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||||
|
|
||||||
createProjectGroup(composite);
|
createProjectGroup(composite);
|
||||||
@@ -332,9 +303,8 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
setControl(composite);
|
setControl(composite);
|
||||||
|
|
||||||
// Update state the first time
|
// Update state the first time
|
||||||
initializeFromSelection(mInitialSelection);
|
|
||||||
initializeRootValues();
|
initializeRootValues();
|
||||||
enableTypesBasedOnApi();
|
initializeFromSelection(mInitialSelection);
|
||||||
validatePage();
|
validatePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,35 +418,17 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
new Label(parent, SWT.NONE);
|
new Label(parent, SWT.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Pads the parent with empty cells to match the number of columns of the parent grid.
|
|
||||||
*
|
|
||||||
* @param parent A grid layout with NUM_COL columns
|
|
||||||
* @param col The current number of columns used.
|
|
||||||
* @return 0, the new number of columns used, for convenience.
|
|
||||||
*/
|
|
||||||
private int padWithEmptyCells(Composite parent, int col) {
|
|
||||||
for (; col < NUM_COL; ++col) {
|
|
||||||
emptyCell(parent);
|
|
||||||
}
|
|
||||||
col = 0;
|
|
||||||
return col;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the project & filename fields.
|
* Creates the project & filename fields.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The parent must be a GridLayout with NUM_COL colums.
|
* The parent must be a GridLayout with 3 colums.
|
||||||
*/
|
*/
|
||||||
private void createProjectGroup(Composite parent) {
|
private void createProjectGroup(Composite parent) {
|
||||||
int col = 0;
|
|
||||||
|
|
||||||
// project name
|
// project name
|
||||||
String tooltip = "The Android Project where the new resource file will be created.";
|
String tooltip = "The Android Project where the new resource file will be created.";
|
||||||
Label label = new Label(parent, SWT.NONE);
|
Label label = new Label(parent, SWT.NONE);
|
||||||
label.setText("Project");
|
label.setText("Project");
|
||||||
label.setToolTipText(tooltip);
|
label.setToolTipText(tooltip);
|
||||||
++col;
|
|
||||||
|
|
||||||
mProjectTextField = new Text(parent, SWT.BORDER);
|
mProjectTextField = new Text(parent, SWT.BORDER);
|
||||||
mProjectTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
mProjectTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
@@ -486,7 +438,6 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
onProjectFieldUpdated();
|
onProjectFieldUpdated();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
++col;
|
|
||||||
|
|
||||||
mProjectBrowseButton = new Button(parent, SWT.NONE);
|
mProjectBrowseButton = new Button(parent, SWT.NONE);
|
||||||
mProjectBrowseButton.setText("Browse...");
|
mProjectBrowseButton.setText("Browse...");
|
||||||
@@ -498,16 +449,12 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
|
mProjectChooserHelper = new ProjectChooserHelper(parent.getShell());
|
||||||
++col;
|
|
||||||
|
|
||||||
col = padWithEmptyCells(parent, col);
|
|
||||||
|
|
||||||
// file name
|
// file name
|
||||||
tooltip = "The name of the resource file to create.";
|
tooltip = "The name of the resource file to create.";
|
||||||
label = new Label(parent, SWT.NONE);
|
label = new Label(parent, SWT.NONE);
|
||||||
label.setText("File");
|
label.setText("File");
|
||||||
label.setToolTipText(tooltip);
|
label.setToolTipText(tooltip);
|
||||||
++col;
|
|
||||||
|
|
||||||
mFileNameTextField = new Text(parent, SWT.BORDER);
|
mFileNameTextField = new Text(parent, SWT.BORDER);
|
||||||
mFileNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
mFileNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
@@ -517,32 +464,31 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
validatePage();
|
validatePage();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
++col;
|
|
||||||
|
|
||||||
padWithEmptyCells(parent, col);
|
emptyCell(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the type field, {@link ConfigurationSelector} and the folder field.
|
* Creates the type field, {@link ConfigurationSelector} and the folder field.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The parent must be a GridLayout with NUM_COL colums.
|
* The parent must be a GridLayout with 3 colums.
|
||||||
*/
|
*/
|
||||||
private void createTypeGroup(Composite parent) {
|
private void createTypeGroup(Composite parent) {
|
||||||
// separator
|
// separator
|
||||||
Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
|
Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
|
||||||
label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL));
|
label.setLayoutData(newGridData(3, GridData.GRAB_HORIZONTAL));
|
||||||
|
|
||||||
// label before type radios
|
// label before type radios
|
||||||
label = new Label(parent, SWT.NONE);
|
label = new Label(parent, SWT.NONE);
|
||||||
label.setText("What type of resource would you like to create?");
|
label.setText("What type of resource would you like to create?");
|
||||||
label.setLayoutData(newGridData(NUM_COL));
|
label.setLayoutData(newGridData(3));
|
||||||
|
|
||||||
// display the types on three columns of radio buttons.
|
// display the types on three columns of radio buttons.
|
||||||
emptyCell(parent);
|
emptyCell(parent);
|
||||||
Composite grid = new Composite(parent, SWT.NONE);
|
Composite grid = new Composite(parent, SWT.NONE);
|
||||||
padWithEmptyCells(parent, 2);
|
emptyCell(parent);
|
||||||
|
|
||||||
grid.setLayout(new GridLayout(NUM_COL, true /*makeColumnsEqualWidth*/));
|
grid.setLayout(new GridLayout(3, true /*makeColumnsEqualWidth*/));
|
||||||
|
|
||||||
SelectionListener radioListener = new SelectionAdapter() {
|
SelectionListener radioListener = new SelectionAdapter() {
|
||||||
@Override
|
@Override
|
||||||
@@ -555,27 +501,23 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int n = sTypes.length;
|
int n = sTypes.length;
|
||||||
int num_lines = (n + NUM_COL/2) / NUM_COL;
|
int num_lines = n/3;
|
||||||
for (int line = 0, k = 0; line < num_lines; line++) {
|
for (int line = 0; line < num_lines; line++) {
|
||||||
for (int i = 0; i < NUM_COL; i++, k++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
if (k < n) {
|
TypeInfo type = sTypes[line * 3 + i];
|
||||||
TypeInfo type = sTypes[k];
|
|
||||||
Button radio = new Button(grid, SWT.RADIO);
|
Button radio = new Button(grid, SWT.RADIO);
|
||||||
type.setWidget(radio);
|
type.setWidget(radio);
|
||||||
radio.setSelection(false);
|
radio.setSelection(false);
|
||||||
radio.setText(type.getUiName());
|
radio.setText(type.getUiName());
|
||||||
radio.setToolTipText(type.getTooltip());
|
radio.setToolTipText(type.getTooltip());
|
||||||
radio.addSelectionListener(radioListener);
|
radio.addSelectionListener(radioListener);
|
||||||
} else {
|
|
||||||
emptyCell(grid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// label before configuration selector
|
// label before configuration selector
|
||||||
label = new Label(parent, SWT.NONE);
|
label = new Label(parent, SWT.NONE);
|
||||||
label.setText("What type of resource configuration would you like?");
|
label.setText("What type of resource configuration would you like?");
|
||||||
label.setLayoutData(newGridData(NUM_COL));
|
label.setLayoutData(newGridData(3));
|
||||||
|
|
||||||
// configuration selector
|
// configuration selector
|
||||||
emptyCell(parent);
|
emptyCell(parent);
|
||||||
@@ -585,7 +527,6 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
|
gd.heightHint = ConfigurationSelector.HEIGHT_HINT;
|
||||||
mConfigSelector.setLayoutData(gd);
|
mConfigSelector.setLayoutData(gd);
|
||||||
mConfigSelector.setOnChangeListener(new onConfigSelectorUpdated());
|
mConfigSelector.setOnChangeListener(new onConfigSelectorUpdated());
|
||||||
emptyCell(parent);
|
|
||||||
|
|
||||||
// folder name
|
// folder name
|
||||||
String tooltip = "The folder where the file will be generated, relative to the project.";
|
String tooltip = "The folder where the file will be generated, relative to the project.";
|
||||||
@@ -601,23 +542,25 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
onWsFolderPathUpdated();
|
onWsFolderPathUpdated();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
emptyCell(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the root element combo.
|
* Creates the root element combo.
|
||||||
* <p/>
|
* <p/>
|
||||||
* The parent must be a GridLayout with NUM_COL colums.
|
* The parent must be a GridLayout with 3 colums.
|
||||||
*/
|
*/
|
||||||
private void createRootGroup(Composite parent) {
|
private void createRootGroup(Composite parent) {
|
||||||
// separator
|
// separator
|
||||||
Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
|
Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
|
||||||
label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL));
|
label.setLayoutData(newGridData(3, GridData.GRAB_HORIZONTAL));
|
||||||
|
|
||||||
// label before the root combo
|
// label before the root combo
|
||||||
String tooltip = "The root element to create in the XML file.";
|
String tooltip = "The root element to create in the XML file.";
|
||||||
label = new Label(parent, SWT.NONE);
|
label = new Label(parent, SWT.NONE);
|
||||||
label.setText("Select the root element for the XML file:");
|
label.setText("Select the root element for the XML file:");
|
||||||
label.setLayoutData(newGridData(NUM_COL));
|
label.setLayoutData(newGridData(3));
|
||||||
label.setToolTipText(tooltip);
|
label.setToolTipText(tooltip);
|
||||||
|
|
||||||
// root combo
|
// root combo
|
||||||
@@ -629,7 +572,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
mRootElementCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
mRootElementCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
mRootElementCombo.setToolTipText(tooltip);
|
mRootElementCombo.setToolTipText(tooltip);
|
||||||
|
|
||||||
padWithEmptyCells(parent, 2);
|
emptyCell(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -747,13 +690,11 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
// get the AndroidTargetData from the project
|
// get the AndroidTargetData from the project
|
||||||
IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
|
IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
|
||||||
AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
|
AndroidTargetData data = Sdk.getCurrent().getTargetData(target);
|
||||||
|
ElementDescriptor descriptor = data.getDescriptorProvider(
|
||||||
|
(Integer)rootSeed).getDescriptor();
|
||||||
|
|
||||||
IDescriptorProvider provider = data.getDescriptorProvider((Integer)rootSeed);
|
|
||||||
ElementDescriptor descriptor = provider.getDescriptor();
|
|
||||||
if (descriptor != null) {
|
|
||||||
HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>();
|
HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>();
|
||||||
initRootElementDescriptor(roots, descriptor, visited);
|
initRootElementDescriptor(roots, descriptor, visited);
|
||||||
}
|
|
||||||
|
|
||||||
// Sort alphabetically.
|
// Sort alphabetically.
|
||||||
Collections.sort(roots);
|
Collections.sort(roots);
|
||||||
@@ -802,7 +743,15 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (found != mProject) {
|
if (found != mProject) {
|
||||||
changeProject(found);
|
mProject = found;
|
||||||
|
|
||||||
|
// update the Type with the new descriptors.
|
||||||
|
initializeRootValues();
|
||||||
|
|
||||||
|
// update the combo
|
||||||
|
updateRootCombo(getSelectedType());
|
||||||
|
|
||||||
|
validatePage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,19 +761,8 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
private void onProjectBrowse() {
|
private void onProjectBrowse() {
|
||||||
IJavaProject p = mProjectChooserHelper.chooseJavaProject(mProjectTextField.getText());
|
IJavaProject p = mProjectChooserHelper.chooseJavaProject(mProjectTextField.getText());
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
changeProject(p.getProject());
|
mProject = p.getProject();
|
||||||
mProjectTextField.setText(mProject.getName());
|
mProjectTextField.setText(mProject.getName());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes mProject to the given new project and update the UI accordingly.
|
|
||||||
*/
|
|
||||||
private void changeProject(IProject newProject) {
|
|
||||||
mProject = newProject;
|
|
||||||
|
|
||||||
// enable types based on new API level
|
|
||||||
enableTypesBasedOnApi();
|
|
||||||
|
|
||||||
// update the Type with the new descriptors.
|
// update the Type with the new descriptors.
|
||||||
initializeRootValues();
|
initializeRootValues();
|
||||||
@@ -834,6 +772,7 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
|
|
||||||
validatePage();
|
validatePage();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback called when the Folder text field is changed, either programmatically
|
* Callback called when the Folder text field is changed, either programmatically
|
||||||
@@ -1046,26 +985,6 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to enable the type radio buttons depending on the current API level.
|
|
||||||
* <p/>
|
|
||||||
* A type radio button is enabled either if:
|
|
||||||
* - if mProject is null, API level 1 is considered valid
|
|
||||||
* - if mProject is !null, the project->target->API must be >= to the type's API level.
|
|
||||||
*/
|
|
||||||
private void enableTypesBasedOnApi() {
|
|
||||||
|
|
||||||
IAndroidTarget target = mProject != null ? Sdk.getCurrent().getTarget(mProject) : null;
|
|
||||||
int currentApiLevel = 1;
|
|
||||||
if (target != null) {
|
|
||||||
currentApiLevel = target.getApiVersionNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (TypeInfo type : sTypes) {
|
|
||||||
type.getWidget().setEnabled(type.getTargetApiLevel() <= currentApiLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates the fields, displays errors and warnings.
|
* Validates the fields, displays errors and warnings.
|
||||||
* Enables the finish button if there are no errors.
|
* Enables the finish button if there are no errors.
|
||||||
@@ -1098,22 +1017,6 @@ class NewXmlFileCreationPage extends WizardPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- validate type API level
|
|
||||||
if (error == null) {
|
|
||||||
IAndroidTarget target = Sdk.getCurrent().getTarget(mProject);
|
|
||||||
int currentApiLevel = 1;
|
|
||||||
if (target != null) {
|
|
||||||
currentApiLevel = target.getApiVersionNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeInfo type = getSelectedType();
|
|
||||||
|
|
||||||
if (type.getTargetApiLevel() > currentApiLevel) {
|
|
||||||
error = "The API level of the selected type (e.g. gadget, etc.) is not " +
|
|
||||||
"compatible with the API level of the project.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- validate folder configuration
|
// -- validate folder configuration
|
||||||
if (error == null) {
|
if (error == null) {
|
||||||
ConfigurationState state = mConfigSelector.getState();
|
ConfigurationState state = mConfigSelector.getState();
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ 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. */
|
|
||||||
private DocumentDescriptor mGadgetDescriptor = 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() {
|
||||||
return mDescriptor;
|
return mDescriptor;
|
||||||
@@ -75,11 +72,6 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
return mPrefDescriptor;
|
return mPrefDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return the root descriptor for gadget providers. */
|
|
||||||
public DocumentDescriptor getGadgetDescriptor() {
|
|
||||||
return mGadgetDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDescriptorProvider getSearchableProvider() {
|
public IDescriptorProvider getSearchableProvider() {
|
||||||
return new IDescriptorProvider() {
|
return new IDescriptorProvider() {
|
||||||
public ElementDescriptor getDescriptor() {
|
public ElementDescriptor getDescriptor() {
|
||||||
@@ -104,18 +96,6 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDescriptorProvider getGadgetProvider() {
|
|
||||||
return new IDescriptorProvider() {
|
|
||||||
public ElementDescriptor getDescriptor() {
|
|
||||||
return mGadgetDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ElementDescriptor[] getRootElementDescriptors() {
|
|
||||||
return mGadgetDescriptor.getChildren();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the document descriptor.
|
* Updates the document descriptor.
|
||||||
* <p/>
|
* <p/>
|
||||||
@@ -123,13 +103,11 @@ 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 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,
|
|
||||||
ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
|
ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) {
|
||||||
|
|
||||||
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
|
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
|
||||||
@@ -137,17 +115,12 @@ 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 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) {
|
|
||||||
list.add(gadget);
|
|
||||||
mGadgetDescriptor.setChildren(new ElementDescriptor[]{ gadget });
|
|
||||||
}
|
|
||||||
if (preferences != null) {
|
if (preferences != null) {
|
||||||
list.add(preferences);
|
list.add(preferences);
|
||||||
mPrefDescriptor.setChildren(new ElementDescriptor[]{ preferences });
|
mPrefDescriptor.setChildren(new ElementDescriptor[]{ preferences });
|
||||||
@@ -189,28 +162,6 @@ public final class XmlDescriptors implements IDescriptorProvider {
|
|||||||
return searchable;
|
return searchable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the new ElementDescriptor for <gadget-provider>
|
|
||||||
*/
|
|
||||||
private ElementDescriptor createGadgetProviderInfo(
|
|
||||||
Map<String, DeclareStyleableInfo> gadgetStyleMap,
|
|
||||||
XmlnsAttributeDescriptor xmlns) {
|
|
||||||
|
|
||||||
if (gadgetStyleMap == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ElementDescriptor gadget = createElement(gadgetStyleMap,
|
|
||||||
"GadgetProviderInfo", //$NON-NLS-1$ styleName
|
|
||||||
"gadget-provider", //$NON-NLS-1$ xmlName
|
|
||||||
"Gadget Provider", // uiName
|
|
||||||
null, // sdk url
|
|
||||||
xmlns, // extraAttribute
|
|
||||||
null, // childrenElements
|
|
||||||
false /* mandatory */ );
|
|
||||||
return gadget;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new ElementDescriptor constructed from the information given here
|
* Returns a new ElementDescriptor constructed from the information given here
|
||||||
* and the javadoc & attributes extracted from the style map if any.
|
* and the javadoc & attributes extracted from the style map if any.
|
||||||
|
|||||||
@@ -22,13 +22,6 @@ if [ "-n" == "$1" ]; then
|
|||||||
shift
|
shift
|
||||||
fi
|
fi
|
||||||
|
|
||||||
DIR="frameworks"
|
|
||||||
if [ "-s" == "$1" ]; then
|
|
||||||
shift
|
|
||||||
DIR="$1"
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
SRC="$1"
|
SRC="$1"
|
||||||
DST="$2"
|
DST="$2"
|
||||||
|
|
||||||
@@ -43,7 +36,7 @@ function process() {
|
|||||||
|
|
||||||
N=0
|
N=0
|
||||||
E=0
|
E=0
|
||||||
for i in `find -L "${SRC}/${DIR}" -name "*.java"`; do
|
for i in `find -L "${SRC}/frameworks" -name "*.java"`; do
|
||||||
if [ -f "$i" ]; then
|
if [ -f "$i" ]; then
|
||||||
# look for ^package (android.view.blah);$
|
# look for ^package (android.view.blah);$
|
||||||
PACKAGE=`sed -n '/^package [^ ;]\+; */{s/[^ ]* *\([^ ;]*\).*/\1/p;q}' "$i"`
|
PACKAGE=`sed -n '/^package [^ ;]\+; */{s/[^ ]* *\([^ ;]*\).*/\1/p;q}' "$i"`
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks,
|
|||||||
rem and set up progdir to be the fully-qualified pathname of its directory.
|
rem and set up progdir to be the fully-qualified pathname of its directory.
|
||||||
set prog=%~f0
|
set prog=%~f0
|
||||||
|
|
||||||
rem Change current directory and drive to where the script is, to avoid
|
rem Change current directory to where ddms is, to avoid issues with directories
|
||||||
rem issues with directories containing whitespaces.
|
rem containing whitespaces.
|
||||||
cd /d %~dp0
|
cd %~dp0
|
||||||
|
|
||||||
set jarfile=hierarchyviewer.jar
|
set jarfile=hierarchyviewer.jar
|
||||||
set frameworkdir=
|
set frameworkdir=
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import java.net.Socket;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class ViewHierarchyLoader {
|
public class ViewHierarchyLoader {
|
||||||
@SuppressWarnings("empty-statement")
|
@SuppressWarnings("empty-statement")
|
||||||
@@ -111,8 +110,6 @@ public class ViewHierarchyLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateIndices(scene.getRoot());
|
|
||||||
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -134,14 +131,6 @@ public class ViewHierarchyLoader {
|
|||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateIndices(ViewNode root) {
|
|
||||||
root.computeIndex();
|
|
||||||
|
|
||||||
for (ViewNode node : root.children) {
|
|
||||||
updateIndices(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int countFrontWhitespace(String line) {
|
private static int countFrontWhitespace(String line) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (line.charAt(count) == ' ') {
|
while (line.charAt(count) == ' ') {
|
||||||
|
|||||||
@@ -60,25 +60,22 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Widget attachNodeWidget(ViewNode node) {
|
protected Widget attachNodeWidget(ViewNode node) {
|
||||||
Widget widget = createBox(node, node.name, node.id);
|
Widget widget = createBox(node.name, node.id);
|
||||||
widget.getActions().addAction(createSelectAction());
|
widget.getActions().addAction(createSelectAction());
|
||||||
widget.getActions().addAction(moveAction);
|
widget.getActions().addAction(moveAction);
|
||||||
widgetLayer.addChild(widget);
|
widgetLayer.addChild(widget);
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Widget createBox(ViewNode node, String nodeName, String id) {
|
private Widget createBox(String node, String id) {
|
||||||
final String shortName = getShortName(nodeName);
|
Widget box = new GradientWidget(this);
|
||||||
node.setShortName(shortName);
|
|
||||||
|
|
||||||
GradientWidget box = new GradientWidget(this, node);
|
|
||||||
box.setLayout(LayoutFactory.createVerticalFlowLayout());
|
box.setLayout(LayoutFactory.createVerticalFlowLayout());
|
||||||
box.setBorder(BorderFactory.createLineBorder(2, Color.BLACK));
|
box.setBorder(BorderFactory.createLineBorder(2, Color.BLACK));
|
||||||
box.setOpaque(true);
|
box.setOpaque(true);
|
||||||
|
|
||||||
LabelWidget label = new LabelWidget(this);
|
LabelWidget label = new LabelWidget(this);
|
||||||
label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 12.0f));
|
label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 12.0f));
|
||||||
label.setLabel(shortName);
|
label.setLabel(getShortName(node));
|
||||||
label.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6));
|
label.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6));
|
||||||
label.setAlignment(LabelWidget.Alignment.CENTER);
|
label.setAlignment(LabelWidget.Alignment.CENTER);
|
||||||
|
|
||||||
@@ -86,12 +83,10 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
|
|||||||
|
|
||||||
label = new LabelWidget(this);
|
label = new LabelWidget(this);
|
||||||
label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
|
label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f));
|
||||||
label.setLabel(getAddress(nodeName));
|
label.setLabel(getAddress(node));
|
||||||
label.setBorder(BorderFactory.createEmptyBorder(3, 6, 0, 6));
|
label.setBorder(BorderFactory.createEmptyBorder(3, 6, 0, 6));
|
||||||
label.setAlignment(LabelWidget.Alignment.CENTER);
|
label.setAlignment(LabelWidget.Alignment.CENTER);
|
||||||
|
|
||||||
box.addressWidget = label;
|
|
||||||
|
|
||||||
box.addChild(label);
|
box.addChild(label);
|
||||||
|
|
||||||
label = new LabelWidget(this);
|
label = new LabelWidget(this);
|
||||||
@@ -141,7 +136,7 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
|
|||||||
connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
|
connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class GradientWidget extends Widget implements ViewNode.StateListener {
|
private static class GradientWidget extends Widget {
|
||||||
public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint(
|
public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint(
|
||||||
new Point2D.Double(0, 0),
|
new Point2D.Double(0, 0),
|
||||||
new Color(168, 204, 241),
|
new Color(168, 204, 241),
|
||||||
@@ -182,28 +177,15 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
|
|||||||
new Color(129, 138, 155),
|
new Color(129, 138, 155),
|
||||||
new Point2D.Double(0, 1),
|
new Point2D.Double(0, 1),
|
||||||
new Color(58, 66, 82));
|
new Color(58, 66, 82));
|
||||||
public static final GradientPaint NIGHT_GRAY_VERY_LIGHT = new GradientPaint(
|
|
||||||
new Point2D.Double(0, 0),
|
|
||||||
new Color(129, 138, 155, 60),
|
|
||||||
new Point2D.Double(0, 1),
|
|
||||||
new Color(58, 66, 82, 60));
|
|
||||||
|
|
||||||
private static Color UNSELECTED = Color.BLACK;
|
private static Color UNSELECTED = Color.BLACK;
|
||||||
private static Color SELECTED = Color.WHITE;
|
private static Color SELECTED = Color.WHITE;
|
||||||
|
|
||||||
private final ViewNode node;
|
|
||||||
|
|
||||||
private LabelWidget addressWidget;
|
|
||||||
|
|
||||||
private boolean isSelected = false;
|
private boolean isSelected = false;
|
||||||
private final GradientPaint selectedGradient = MAC_OSX_SELECTED;
|
private GradientPaint gradient = MAC_OSX_SELECTED;
|
||||||
private final GradientPaint filteredGradient = RED_XP;
|
|
||||||
private final GradientPaint focusGradient = NIGHT_GRAY_VERY_LIGHT;
|
|
||||||
|
|
||||||
public GradientWidget(ViewHierarchyScene scene, ViewNode node) {
|
public GradientWidget(ViewHierarchyScene scene) {
|
||||||
super(scene);
|
super(scene);
|
||||||
this.node = node;
|
|
||||||
node.setStateListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -211,12 +193,8 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
|
|||||||
super.notifyStateChanged(previous, state);
|
super.notifyStateChanged(previous, state);
|
||||||
isSelected = state.isSelected() || state.isFocused() || state.isWidgetFocused();
|
isSelected = state.isSelected() || state.isFocused() || state.isWidgetFocused();
|
||||||
|
|
||||||
pickChildrenColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pickChildrenColor() {
|
|
||||||
for (Widget child : getChildren()) {
|
for (Widget child : getChildren()) {
|
||||||
child.setForeground(isSelected || node.filtered ? SELECTED : UNSELECTED);
|
child.setForeground(isSelected ? SELECTED : UNSELECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
repaint();
|
repaint();
|
||||||
@@ -230,33 +208,12 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> {
|
|||||||
Rectangle bounds = getBounds();
|
Rectangle bounds = getBounds();
|
||||||
|
|
||||||
if (!isSelected) {
|
if (!isSelected) {
|
||||||
if (!node.filtered) {
|
|
||||||
if (!node.hasFocus) {
|
|
||||||
g2.setColor(Color.WHITE);
|
g2.setColor(Color.WHITE);
|
||||||
} else {
|
} else {
|
||||||
g2.setPaint(new GradientPaint(bounds.x, bounds.y,
|
g2.setPaint(new GradientPaint(bounds.x, bounds.y, gradient.getColor1(),
|
||||||
focusGradient.getColor1(), bounds.x, bounds.x + bounds.height,
|
bounds.x, bounds.x + bounds.height, gradient.getColor2()));
|
||||||
focusGradient.getColor2()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g2.setPaint(new GradientPaint(bounds.x, bounds.y, filteredGradient.getColor1(),
|
|
||||||
bounds.x, bounds.x + bounds.height, filteredGradient.getColor2()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
g2.setPaint(new GradientPaint(bounds.x, bounds.y, selectedGradient.getColor1(),
|
|
||||||
bounds.x, bounds.x + bounds.height, selectedGradient.getColor2()));
|
|
||||||
}
|
}
|
||||||
g2.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
|
g2.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void nodeStateChanged(ViewNode node) {
|
|
||||||
pickChildrenColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void nodeIndexChanged(ViewNode node) {
|
|
||||||
if (addressWidget != null) {
|
|
||||||
addressWidget.setLabel("#" + node.index + addressWidget.getLabel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.hierarchyviewer.scene;
|
package com.android.hierarchyviewer.scene;
|
||||||
|
|
||||||
import com.android.ddmlib.Device;
|
import com.android.ddmlib.Device;
|
||||||
|
import com.android.hierarchyviewer.device.Configuration;
|
||||||
import com.android.hierarchyviewer.device.Window;
|
import com.android.hierarchyviewer.device.Window;
|
||||||
import com.android.hierarchyviewer.device.DeviceBridge;
|
import com.android.hierarchyviewer.device.DeviceBridge;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class ViewNode {
|
public class ViewNode {
|
||||||
public String id;
|
public String id;
|
||||||
@@ -53,14 +52,7 @@ public class ViewNode {
|
|||||||
public boolean willNotDraw;
|
public boolean willNotDraw;
|
||||||
public boolean hasMargins;
|
public boolean hasMargins;
|
||||||
|
|
||||||
boolean hasFocus;
|
|
||||||
int index;
|
|
||||||
|
|
||||||
public boolean decoded;
|
public boolean decoded;
|
||||||
public boolean filtered;
|
|
||||||
|
|
||||||
private String shortName;
|
|
||||||
private StateListener listener;
|
|
||||||
|
|
||||||
void decode() {
|
void decode() {
|
||||||
id = namedProperties.get("mID").value;
|
id = namedProperties.get("mID").value;
|
||||||
@@ -81,7 +73,6 @@ public class ViewNode {
|
|||||||
marginBottom = getInt("layout_bottomMargin", Integer.MIN_VALUE);
|
marginBottom = getInt("layout_bottomMargin", Integer.MIN_VALUE);
|
||||||
baseline = getInt("getBaseline()", 0);
|
baseline = getInt("getBaseline()", 0);
|
||||||
willNotDraw = getBoolean("willNotDraw()", false);
|
willNotDraw = getBoolean("willNotDraw()", false);
|
||||||
hasFocus = getBoolean("hasFocus()", false);
|
|
||||||
|
|
||||||
hasMargins = marginLeft != Integer.MIN_VALUE &&
|
hasMargins = marginLeft != Integer.MIN_VALUE &&
|
||||||
marginRight != Integer.MIN_VALUE &&
|
marginRight != Integer.MIN_VALUE &&
|
||||||
@@ -115,28 +106,6 @@ public class ViewNode {
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void filter(Pattern pattern) {
|
|
||||||
if (pattern == null || pattern.pattern().length() == 0) {
|
|
||||||
filtered = false;
|
|
||||||
} else {
|
|
||||||
filtered = pattern.matcher(shortName).find() || pattern.matcher(id).find();
|
|
||||||
}
|
|
||||||
listener.nodeStateChanged(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void computeIndex() {
|
|
||||||
index = parent == null ? 0 : parent.children.indexOf(this);
|
|
||||||
listener.nodeIndexChanged(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setShortName(String shortName) {
|
|
||||||
this.shortName = shortName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStateListener(StateListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings({"StringEquality"})
|
@SuppressWarnings({"StringEquality"})
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
@@ -195,9 +164,4 @@ public class ViewNode {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StateListener {
|
|
||||||
void nodeStateChanged(ViewNode node);
|
|
||||||
void nodeIndexChanged(ViewNode node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,9 +76,6 @@ import javax.swing.ListSelectionModel;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.JTree;
|
import javax.swing.JTree;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.JTextField;
|
|
||||||
import javax.swing.text.Document;
|
|
||||||
import javax.swing.text.BadLocationException;
|
|
||||||
import javax.swing.tree.TreePath;
|
import javax.swing.tree.TreePath;
|
||||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
@@ -87,8 +84,6 @@ import javax.swing.event.ListSelectionEvent;
|
|||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.event.TreeSelectionListener;
|
import javax.swing.event.TreeSelectionListener;
|
||||||
import javax.swing.event.TreeSelectionEvent;
|
import javax.swing.event.TreeSelectionEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
|
||||||
import javax.swing.event.DocumentEvent;
|
|
||||||
import javax.swing.table.DefaultTableModel;
|
import javax.swing.table.DefaultTableModel;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
@@ -110,8 +105,6 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.regex.PatternSyntaxException;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public class Workspace extends JFrame {
|
public class Workspace extends JFrame {
|
||||||
@@ -163,8 +156,6 @@ public class Workspace extends JFrame {
|
|||||||
private JTable windows;
|
private JTable windows;
|
||||||
private JLabel minZoomLabel;
|
private JLabel minZoomLabel;
|
||||||
private JLabel maxZoomLabel;
|
private JLabel maxZoomLabel;
|
||||||
private JTextField filterText;
|
|
||||||
private JLabel filterLabel;
|
|
||||||
|
|
||||||
public Workspace() {
|
public Workspace() {
|
||||||
super("Hierarchy Viewer");
|
super("Hierarchy Viewer");
|
||||||
@@ -322,33 +313,10 @@ public class Workspace extends JFrame {
|
|||||||
|
|
||||||
graphViewButton.setSelected(true);
|
graphViewButton.setSelected(true);
|
||||||
|
|
||||||
filterText = new JTextField(20);
|
|
||||||
filterText.putClientProperty("JComponent.sizeVariant", "small");
|
|
||||||
filterText.getDocument().addDocumentListener(new DocumentListener() {
|
|
||||||
public void insertUpdate(DocumentEvent e) {
|
|
||||||
updateFilter(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeUpdate(DocumentEvent e) {
|
|
||||||
updateFilter(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void changedUpdate(DocumentEvent e) {
|
|
||||||
updateFilter(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
filterLabel = new JLabel("Filter by class or id:");
|
|
||||||
filterLabel.putClientProperty("JComponent.sizeVariant", "small");
|
|
||||||
filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6));
|
|
||||||
|
|
||||||
leftSide.add(filterLabel);
|
|
||||||
leftSide.add(filterText);
|
|
||||||
|
|
||||||
minZoomLabel = new JLabel();
|
minZoomLabel = new JLabel();
|
||||||
minZoomLabel.setText("20%");
|
minZoomLabel.setText("20%");
|
||||||
minZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
|
minZoomLabel.putClientProperty("JComponent.sizeVariant", "small");
|
||||||
minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
|
minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0));
|
||||||
leftSide.add(minZoomLabel);
|
leftSide.add(minZoomLabel);
|
||||||
|
|
||||||
zoomSlider = new JSlider();
|
zoomSlider = new JSlider();
|
||||||
@@ -389,18 +357,12 @@ public class Workspace extends JFrame {
|
|||||||
|
|
||||||
statusPanel.add(rightSide, BorderLayout.LINE_END);
|
statusPanel.add(rightSide, BorderLayout.LINE_END);
|
||||||
|
|
||||||
hideStatusBarComponents();
|
|
||||||
|
|
||||||
return statusPanel;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hideStatusBarComponents() {
|
|
||||||
viewCountLabel.setVisible(false);
|
viewCountLabel.setVisible(false);
|
||||||
zoomSlider.setVisible(false);
|
zoomSlider.setVisible(false);
|
||||||
minZoomLabel.setVisible(false);
|
minZoomLabel.setVisible(false);
|
||||||
maxZoomLabel.setVisible(false);
|
maxZoomLabel.setVisible(false);
|
||||||
filterLabel.setVisible(false);
|
|
||||||
filterText.setVisible(false);
|
return statusPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JToolBar buildToolBar() {
|
private JToolBar buildToolBar() {
|
||||||
@@ -551,7 +513,10 @@ public class Workspace extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void toggleGraphView() {
|
private void toggleGraphView() {
|
||||||
showStatusBarComponents();
|
viewCountLabel.setVisible(true);
|
||||||
|
zoomSlider.setVisible(true);
|
||||||
|
minZoomLabel.setVisible(true);
|
||||||
|
maxZoomLabel.setVisible(true);
|
||||||
|
|
||||||
screenViewer.stop();
|
screenViewer.stop();
|
||||||
mainPanel.remove(pixelPerfectPanel);
|
mainPanel.remove(pixelPerfectPanel);
|
||||||
@@ -561,15 +526,6 @@ public class Workspace extends JFrame {
|
|||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showStatusBarComponents() {
|
|
||||||
viewCountLabel.setVisible(true);
|
|
||||||
zoomSlider.setVisible(true);
|
|
||||||
minZoomLabel.setVisible(true);
|
|
||||||
maxZoomLabel.setVisible(true);
|
|
||||||
filterLabel.setVisible(true);
|
|
||||||
filterText.setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void togglePixelPerfectView() {
|
private void togglePixelPerfectView() {
|
||||||
if (pixelPerfectPanel == null) {
|
if (pixelPerfectPanel == null) {
|
||||||
pixelPerfectPanel = buildPixelPerfectPanel();
|
pixelPerfectPanel = buildPixelPerfectPanel();
|
||||||
@@ -578,7 +534,10 @@ public class Workspace extends JFrame {
|
|||||||
screenViewer.start();
|
screenViewer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
hideStatusBarComponents();
|
viewCountLabel.setVisible(false);
|
||||||
|
zoomSlider.setVisible(false);
|
||||||
|
minZoomLabel.setVisible(false);
|
||||||
|
maxZoomLabel.setVisible(false);
|
||||||
|
|
||||||
mainPanel.remove(mainSplitter);
|
mainPanel.remove(mainSplitter);
|
||||||
mainPanel.add(pixelPerfectPanel, BorderLayout.CENTER);
|
mainPanel.add(pixelPerfectPanel, BorderLayout.CENTER);
|
||||||
@@ -643,7 +602,10 @@ public class Workspace extends JFrame {
|
|||||||
graphViewButton.setEnabled(true);
|
graphViewButton.setEnabled(true);
|
||||||
pixelPerfectViewButton.setEnabled(true);
|
pixelPerfectViewButton.setEnabled(true);
|
||||||
|
|
||||||
showStatusBarComponents();
|
viewCountLabel.setVisible(true);
|
||||||
|
zoomSlider.setVisible(true);
|
||||||
|
minZoomLabel.setVisible(true);
|
||||||
|
maxZoomLabel.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
sceneView = scene.createView();
|
sceneView = scene.createView();
|
||||||
@@ -814,7 +776,10 @@ public class Workspace extends JFrame {
|
|||||||
pixelPerfectPanel = mainSplitter = null;
|
pixelPerfectPanel = mainSplitter = null;
|
||||||
graphViewButton.setSelected(true);
|
graphViewButton.setSelected(true);
|
||||||
|
|
||||||
hideStatusBarComponents();
|
viewCountLabel.setVisible(false);
|
||||||
|
zoomSlider.setVisible(false);
|
||||||
|
minZoomLabel.setVisible(false);
|
||||||
|
maxZoomLabel.setVisible(false);
|
||||||
|
|
||||||
saveMenuItem.setEnabled(false);
|
saveMenuItem.setEnabled(false);
|
||||||
showDevicesMenuItem.setEnabled(false);
|
showDevicesMenuItem.setEnabled(false);
|
||||||
@@ -900,34 +865,6 @@ public class Workspace extends JFrame {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateFilter(DocumentEvent e) {
|
|
||||||
final Document document = e.getDocument();
|
|
||||||
try {
|
|
||||||
updateFilteredNodes(document.getText(0, document.getLength()));
|
|
||||||
} catch (BadLocationException e1) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateFilteredNodes(String filterText) {
|
|
||||||
final ViewNode root = scene.getRoot();
|
|
||||||
try {
|
|
||||||
final Pattern pattern = Pattern.compile(filterText, Pattern.CASE_INSENSITIVE);
|
|
||||||
filterNodes(pattern, root);
|
|
||||||
} catch (PatternSyntaxException e) {
|
|
||||||
filterNodes(null, root);
|
|
||||||
}
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void filterNodes(Pattern pattern, ViewNode root) {
|
|
||||||
root.filter(pattern);
|
|
||||||
|
|
||||||
for (ViewNode node : root.children) {
|
|
||||||
filterNodes(pattern, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void beginTask() {
|
public void beginTask() {
|
||||||
progress.setVisible(true);
|
progress.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 #"
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ set prog=%~f0
|
|||||||
rem Grab current directory before we change it
|
rem Grab current directory before we change it
|
||||||
set workdir=%cd%
|
set workdir=%cd%
|
||||||
|
|
||||||
rem Change current directory and drive to where the script is, to avoid
|
rem Change current directory to where ddms is, to avoid issues with directories
|
||||||
rem issues with directories containing whitespaces.
|
rem containing whitespaces.
|
||||||
cd /d %~dp0
|
cd %~dp0
|
||||||
|
|
||||||
set jarfile=sdkmanager.jar
|
set jarfile=sdkmanager.jar
|
||||||
set frameworkdir=
|
set frameworkdir=
|
||||||
|
|||||||
@@ -383,17 +383,13 @@ class Main {
|
|||||||
*/
|
*/
|
||||||
private void displayAvdList() {
|
private void displayAvdList() {
|
||||||
try {
|
try {
|
||||||
AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog);
|
AvdManager avdManager = new AvdManager(mSdkManager, null /* sdklog */);
|
||||||
|
|
||||||
mSdkLog.printf("Available Android Virtual Devices:\n");
|
mSdkLog.printf("Available Android Virtual Devices:\n");
|
||||||
|
|
||||||
AvdInfo[] avds = avdManager.getAvds();
|
int index = 1;
|
||||||
for (int index = 0 ; index < avds.length ; index++) {
|
for (AvdInfo info : avdManager.getAvds()) {
|
||||||
AvdInfo info = avds[index];
|
mSdkLog.printf("[%d] %s\n", index, info.getName());
|
||||||
if (index > 0) {
|
|
||||||
mSdkLog.printf("---------\n");
|
|
||||||
}
|
|
||||||
mSdkLog.printf(" Name: %s\n", info.getName());
|
|
||||||
mSdkLog.printf(" Path: %s\n", info.getPath());
|
mSdkLog.printf(" Path: %s\n", info.getPath());
|
||||||
|
|
||||||
// get the target of the AVD
|
// get the target of the AVD
|
||||||
@@ -421,6 +417,8 @@ class Main {
|
|||||||
if (sdcard != null) {
|
if (sdcard != null) {
|
||||||
mSdkLog.printf(" Sdcard: %s\n", sdcard);
|
mSdkLog.printf(" Sdcard: %s\n", sdcard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index++;
|
||||||
}
|
}
|
||||||
} catch (AndroidLocationException e) {
|
} catch (AndroidLocationException e) {
|
||||||
errorAndExit(e.getMessage());
|
errorAndExit(e.getMessage());
|
||||||
@@ -501,7 +499,7 @@ class Main {
|
|||||||
|
|
||||||
// Is it NNNxMMM?
|
// Is it NNNxMMM?
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches();
|
valid = skin.matches("[0-9]{2,}x[0-9]{2,}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
|
|||||||
@@ -103,8 +103,6 @@ public final class SdkConstants {
|
|||||||
public final static String FD_ASSETS = "assets"; //$NON-NLS-1$
|
public final static String FD_ASSETS = "assets"; //$NON-NLS-1$
|
||||||
/** Default source folder name, i.e. "src" */
|
/** Default source folder name, i.e. "src" */
|
||||||
public final static String FD_SOURCES = "src"; //$NON-NLS-1$
|
public final static String FD_SOURCES = "src"; //$NON-NLS-1$
|
||||||
/** Default generated source folder name, i.e. "gen" */
|
|
||||||
public final static String FD_GEN_SOURCES = "gen"; //$NON-NLS-1$
|
|
||||||
/** Default native library folder name inside the project, i.e. "libs"
|
/** Default native library folder name inside the project, i.e. "libs"
|
||||||
* While the folder inside the .apk is "lib", we call that one libs because
|
* While the folder inside the .apk is "lib", we call that one libs because
|
||||||
* that's what we use in ant for both .jar and .so and we need to make the 2 development ways
|
* that's what we use in ant for both .jar and .so and we need to make the 2 development ways
|
||||||
|
|||||||
@@ -55,12 +55,6 @@ public final class AvdManager {
|
|||||||
public final static String AVD_INI_IMAGES_1 = "image.sysdir.1";
|
public final static String AVD_INI_IMAGES_1 = "image.sysdir.1";
|
||||||
public final static String AVD_INI_IMAGES_2 = "image.sysdir.2";
|
public final static String AVD_INI_IMAGES_2 = "image.sysdir.2";
|
||||||
|
|
||||||
/**
|
|
||||||
* Pattern to match pixel-sized skin "names", e.g. "320x480".
|
|
||||||
*/
|
|
||||||
public final static Pattern NUMERIC_SKIN_SIZE = Pattern.compile("[0-9]{2,}x[0-9]{2,}");
|
|
||||||
|
|
||||||
|
|
||||||
private final static String USERDATA_IMG = "userdata.img";
|
private final static String USERDATA_IMG = "userdata.img";
|
||||||
private final static String CONFIG_INI = "config.ini";
|
private final static String CONFIG_INI = "config.ini";
|
||||||
private final static String SDCARD_IMG = "sdcard.img";
|
private final static String SDCARD_IMG = "sdcard.img";
|
||||||
@@ -261,10 +255,6 @@ public final class AvdManager {
|
|||||||
skinName = target.getDefaultSkin();
|
skinName = target.getDefaultSkin();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NUMERIC_SKIN_SIZE.matcher(skinName).matches()) {
|
|
||||||
// Skin name is an actual screen resolution, no skin.path
|
|
||||||
values.put(AVD_INI_SKIN_NAME, skinName);
|
|
||||||
} 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
|
||||||
String skinPath = getSkinRelativePath(skinName, target, log);
|
String skinPath = getSkinRelativePath(skinName, target, log);
|
||||||
@@ -275,7 +265,6 @@ public final class AvdManager {
|
|||||||
|
|
||||||
values.put(AVD_INI_SKIN_PATH, skinPath);
|
values.put(AVD_INI_SKIN_PATH, skinPath);
|
||||||
values.put(AVD_INI_SKIN_NAME, skinName);
|
values.put(AVD_INI_SKIN_NAME, skinName);
|
||||||
}
|
|
||||||
|
|
||||||
if (sdcard != null) {
|
if (sdcard != null) {
|
||||||
File sdcardFile = new File(sdcard);
|
File sdcardFile = new File(sdcard);
|
||||||
|
|||||||
@@ -25,30 +25,24 @@ import java.util.Map.Entry;
|
|||||||
* Helper class to read and write Apk Configuration into a {@link ProjectProperties} file.
|
* Helper class to read and write Apk Configuration into a {@link ProjectProperties} file.
|
||||||
*/
|
*/
|
||||||
public class ApkConfigurationHelper {
|
public class ApkConfigurationHelper {
|
||||||
/** Prefix for property names for config definition. This prevents having config named
|
|
||||||
* after other valid properties such as "target". */
|
|
||||||
final static String CONFIG_PREFIX = "apk-config-";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the Apk Configurations from a {@link ProjectProperties} file and returns them as a map.
|
* Reads the Apk Configurations from a {@link ProjectProperties} file and returns them as a map.
|
||||||
* <p/>If there are no defined configurations, the returned map will be empty.
|
* <p/>If there are no defined configurations, the returned map will be empty.
|
||||||
* @return a map of apk configurations. The map contains (name, filter) where name is
|
|
||||||
* the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of
|
|
||||||
* resource configuration to include in the apk (see aapt -c)
|
|
||||||
*/
|
*/
|
||||||
public static Map<String, String> getConfigs(ProjectProperties properties) {
|
public static Map<String, String> getConfigs(ProjectProperties properties) {
|
||||||
HashMap<String, String> configMap = new HashMap<String, String>();
|
HashMap<String, String> configMap = new HashMap<String, String>();
|
||||||
|
|
||||||
// get the list of configs.
|
// get the list of configs.
|
||||||
String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
|
String configList = properties.getProperty(ProjectProperties.PROPERTY_CONFIGS);
|
||||||
if (configList != null) {
|
if (configList != null) {
|
||||||
// this is a comma separated list
|
// this is a comma separated list
|
||||||
String[] configs = configList.split(","); //$NON-NLS-1$
|
String[] configs = configList.split(","); //$NON-NLS-1$
|
||||||
|
|
||||||
// read the value of each config and store it in a map
|
// read the value of each config and store it in a map
|
||||||
|
|
||||||
for (String config : configs) {
|
for (String config : configs) {
|
||||||
config = config.trim();
|
String configValue = properties.getProperty(config);
|
||||||
String configValue = properties.getProperty(CONFIG_PREFIX + config);
|
|
||||||
if (configValue != null) {
|
if (configValue != null) {
|
||||||
configMap.put(config, configValue);
|
configMap.put(config, configValue);
|
||||||
}
|
}
|
||||||
@@ -60,10 +54,6 @@ public class ApkConfigurationHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the Apk Configurations from a given map into a {@link ProjectProperties}.
|
* Writes the Apk Configurations from a given map into a {@link ProjectProperties}.
|
||||||
* @param properties the {@link ProjectProperties} in which to store the apk configurations.
|
|
||||||
* @param configMap a map of apk configurations. The map contains (name, filter) where name is
|
|
||||||
* the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of
|
|
||||||
* resource configuration to include in the apk (see aapt -c)
|
|
||||||
* @return true if the {@link ProjectProperties} contained Apk Configuration that were not
|
* @return true if the {@link ProjectProperties} contained Apk Configuration that were not
|
||||||
* present in the map.
|
* present in the map.
|
||||||
*/
|
*/
|
||||||
@@ -72,20 +62,17 @@ public class ApkConfigurationHelper {
|
|||||||
// in case a config was removed.
|
// in case a config was removed.
|
||||||
|
|
||||||
// get the list of configs.
|
// get the list of configs.
|
||||||
String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS);
|
String configList = properties.getProperty(ProjectProperties.PROPERTY_CONFIGS);
|
||||||
|
|
||||||
boolean hasRemovedConfig = false;
|
|
||||||
|
|
||||||
if (configList != null) {
|
|
||||||
// this is a comma separated list
|
// this is a comma separated list
|
||||||
String[] configs = configList.split(","); //$NON-NLS-1$
|
String[] configs = configList.split(","); //$NON-NLS-1$
|
||||||
|
|
||||||
|
boolean hasRemovedConfig = false;
|
||||||
|
|
||||||
for (String config : configs) {
|
for (String config : configs) {
|
||||||
config = config.trim();
|
|
||||||
if (configMap.containsKey(config) == false) {
|
if (configMap.containsKey(config) == false) {
|
||||||
hasRemovedConfig = true;
|
hasRemovedConfig = true;
|
||||||
properties.removeProperty(CONFIG_PREFIX + config);
|
properties.removeProperty(config);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,9 +84,9 @@ public class ApkConfigurationHelper {
|
|||||||
sb.append(",");
|
sb.append(",");
|
||||||
}
|
}
|
||||||
sb.append(entry.getKey());
|
sb.append(entry.getKey());
|
||||||
properties.setProperty(CONFIG_PREFIX + entry.getKey(), entry.getValue());
|
properties.setProperty(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
properties.setProperty(ProjectProperties.PROPERTY_APK_CONFIGS, sb.toString());
|
properties.setProperty(ProjectProperties.PROPERTY_CONFIGS, sb.toString());
|
||||||
|
|
||||||
return hasRemovedConfig;
|
return hasRemovedConfig;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ public class ProjectCreator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create the source folder and the java package folders.
|
// create the source folder and the java package folders.
|
||||||
String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
|
final String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
|
||||||
File sourceFolder = createDirs(projectFolder, srcFolderPath);
|
File sourceFolder = createDirs(projectFolder, srcFolderPath);
|
||||||
String javaTemplate = "java_file.template";
|
String javaTemplate = "java_file.template";
|
||||||
String activityFileName = activityName + ".java";
|
String activityFileName = activityName + ".java";
|
||||||
@@ -220,10 +220,6 @@ public class ProjectCreator {
|
|||||||
installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
|
installTemplate(javaTemplate, new File(sourceFolder, activityFileName),
|
||||||
keywords, target);
|
keywords, target);
|
||||||
|
|
||||||
// create the generate source folder
|
|
||||||
srcFolderPath = SdkConstants.FD_GEN_SOURCES + File.separator + packagePath;
|
|
||||||
sourceFolder = createDirs(projectFolder, srcFolderPath);
|
|
||||||
|
|
||||||
// create other useful folders
|
// create other useful folders
|
||||||
File resourceFodler = createDirs(projectFolder, SdkConstants.FD_RESOURCES);
|
File resourceFodler = createDirs(projectFolder, SdkConstants.FD_RESOURCES);
|
||||||
createDirs(projectFolder, SdkConstants.FD_OUTPUT);
|
createDirs(projectFolder, SdkConstants.FD_OUTPUT);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import java.util.Map.Entry;
|
|||||||
public final class ProjectProperties {
|
public final class ProjectProperties {
|
||||||
/** The property name for the project target */
|
/** The property name for the project target */
|
||||||
public final static String PROPERTY_TARGET = "target";
|
public final static String PROPERTY_TARGET = "target";
|
||||||
public final static String PROPERTY_APK_CONFIGS = "apk-configurations";
|
public final static String PROPERTY_CONFIGS = "configs";
|
||||||
public final static String PROPERTY_SDK = "sdk-location";
|
public final static String PROPERTY_SDK = "sdk-location";
|
||||||
|
|
||||||
public static enum PropertyType {
|
public static enum PropertyType {
|
||||||
@@ -98,19 +98,7 @@ public final class ProjectProperties {
|
|||||||
// 1-------10--------20--------30--------40--------50--------60--------70--------80
|
// 1-------10--------20--------30--------40--------50--------60--------70--------80
|
||||||
COMMENT_MAP.put(PROPERTY_TARGET,
|
COMMENT_MAP.put(PROPERTY_TARGET,
|
||||||
"# Project target.\n");
|
"# Project target.\n");
|
||||||
COMMENT_MAP.put(PROPERTY_APK_CONFIGS,
|
COMMENT_MAP.put(PROPERTY_SDK, "# location of the SDK. This is only used by Ant\n" +
|
||||||
"# apk configurations. This property allows creation of APK files with limited\n" +
|
|
||||||
"# resources. For example, if your application contains many locales and\n" +
|
|
||||||
"# you wish to release multiple smaller apks instead of a large one, you can\n" +
|
|
||||||
"# define configuration to create apks with limited language sets.\n" +
|
|
||||||
"# Format is a comma separated list of configuration names. For each\n" +
|
|
||||||
"# configuration, a property will declare the resource configurations to\n" +
|
|
||||||
"# include. Example:\n" +
|
|
||||||
"# " + PROPERTY_APK_CONFIGS +"=european,northamerica\n" +
|
|
||||||
"# " + ApkConfigurationHelper.CONFIG_PREFIX + "european=en,fr,it,de,es\n" +
|
|
||||||
"# " + ApkConfigurationHelper.CONFIG_PREFIX + "northamerica=en,es\n");
|
|
||||||
COMMENT_MAP.put(PROPERTY_SDK,
|
|
||||||
"# location of the SDK. This is only used by Ant\n" +
|
|
||||||
"# For customization when using a Version Control System, please read the\n" +
|
"# For customization when using a Version Control System, please read the\n" +
|
||||||
"# header note.\n");
|
"# header note.\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,177 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.sdkuilib;
|
|
||||||
|
|
||||||
import org.eclipse.jface.dialogs.Dialog;
|
|
||||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
|
||||||
import org.eclipse.jface.window.Window;
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.ModifyEvent;
|
|
||||||
import org.eclipse.swt.events.ModifyListener;
|
|
||||||
import org.eclipse.swt.events.VerifyEvent;
|
|
||||||
import org.eclipse.swt.events.VerifyListener;
|
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
|
||||||
import org.eclipse.swt.widgets.Button;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Control;
|
|
||||||
import org.eclipse.swt.widgets.Label;
|
|
||||||
import org.eclipse.swt.widgets.Shell;
|
|
||||||
import org.eclipse.swt.widgets.Text;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edit dialog to create/edit APK configuration. The dialog displays 2 text fields for the config
|
|
||||||
* name and its filter.
|
|
||||||
*/
|
|
||||||
class ApkConfigEditDialog extends Dialog implements ModifyListener, VerifyListener {
|
|
||||||
|
|
||||||
private String mName;
|
|
||||||
private String mFilter;
|
|
||||||
private Text mNameField;
|
|
||||||
private Text mFilterField;
|
|
||||||
private Button mOkButton;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an edit dialog with optional initial values for the name and filter.
|
|
||||||
* @param name optional value for the name. Can be null.
|
|
||||||
* @param filter optional value for the filter. Can be null.
|
|
||||||
* @param parentShell the parent shell.
|
|
||||||
*/
|
|
||||||
protected ApkConfigEditDialog(String name, String filter, Shell parentShell) {
|
|
||||||
super(parentShell);
|
|
||||||
mName = name;
|
|
||||||
mFilter = filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of the config. This is only valid if the user clicked OK and {@link #open()}
|
|
||||||
* returned {@link Window#OK}
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the filter for the config. This is only valid if the user clicked OK and
|
|
||||||
* {@link #open()} returned {@link Window#OK}
|
|
||||||
*/
|
|
||||||
public String getFilter() {
|
|
||||||
return mFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Control createContents(Composite parent) {
|
|
||||||
Control control = super.createContents(parent);
|
|
||||||
|
|
||||||
mOkButton = getButton(IDialogConstants.OK_ID);
|
|
||||||
validateButtons();
|
|
||||||
|
|
||||||
return control;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Control createDialogArea(Composite parent) {
|
|
||||||
Composite composite = new Composite(parent, SWT.NONE);
|
|
||||||
GridLayout layout;
|
|
||||||
composite.setLayout(layout = new GridLayout(2, false));
|
|
||||||
layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
|
|
||||||
layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
|
|
||||||
layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
|
|
||||||
layout.horizontalSpacing = convertHorizontalDLUsToPixels(
|
|
||||||
IDialogConstants.HORIZONTAL_SPACING);
|
|
||||||
|
|
||||||
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
|
|
||||||
|
|
||||||
Label l = new Label(composite, SWT.NONE);
|
|
||||||
l.setText("Name");
|
|
||||||
|
|
||||||
mNameField = new Text(composite, SWT.BORDER);
|
|
||||||
mNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
|
||||||
mNameField.addVerifyListener(this);
|
|
||||||
if (mName != null) {
|
|
||||||
mNameField.setText(mName);
|
|
||||||
}
|
|
||||||
mNameField.addModifyListener(this);
|
|
||||||
|
|
||||||
l = new Label(composite, SWT.NONE);
|
|
||||||
l.setText("Filter");
|
|
||||||
|
|
||||||
mFilterField = new Text(composite, SWT.BORDER);
|
|
||||||
mFilterField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
|
||||||
if (mFilter != null) {
|
|
||||||
mFilterField.setText(mFilter);
|
|
||||||
}
|
|
||||||
mFilterField.addVerifyListener(this);
|
|
||||||
mFilterField.addModifyListener(this);
|
|
||||||
|
|
||||||
applyDialogFont(composite);
|
|
||||||
return composite;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validates the OK button based on the content of the 2 text fields.
|
|
||||||
*/
|
|
||||||
private void validateButtons() {
|
|
||||||
mOkButton.setEnabled(mNameField.getText().trim().length() > 0 &&
|
|
||||||
mFilterField.getText().trim().length() > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void okPressed() {
|
|
||||||
mName = mNameField.getText();
|
|
||||||
mFilter = mFilterField.getText().trim();
|
|
||||||
super.okPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback for text modification in the 2 text fields.
|
|
||||||
*/
|
|
||||||
public void modifyText(ModifyEvent e) {
|
|
||||||
validateButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to ensure the content of the text field are proper.
|
|
||||||
*/
|
|
||||||
public void verifyText(VerifyEvent e) {
|
|
||||||
Text source = ((Text)e.getSource());
|
|
||||||
if (source == mNameField) {
|
|
||||||
// check for a-zA-Z0-9.
|
|
||||||
final String text = e.text;
|
|
||||||
final int len = text.length();
|
|
||||||
for (int i = 0 ; i < len; i++) {
|
|
||||||
char letter = text.charAt(i);
|
|
||||||
if (letter > 255 || Character.isLetterOrDigit(letter) == false) {
|
|
||||||
e.doit = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (source == mFilterField) {
|
|
||||||
// we can't validate the content as its typed, but we can at least ensure the characters
|
|
||||||
// are valid. Same as mNameFiled + the comma.
|
|
||||||
final String text = e.text;
|
|
||||||
final int len = text.length();
|
|
||||||
for (int i = 0 ; i < len; i++) {
|
|
||||||
char letter = text.charAt(i);
|
|
||||||
if (letter > 255 || (Character.isLetterOrDigit(letter) == false && letter != ',')) {
|
|
||||||
e.doit = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2009 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.sdkuilib;
|
|
||||||
|
|
||||||
import org.eclipse.jface.dialogs.Dialog;
|
|
||||||
import org.eclipse.jface.dialogs.MessageDialog;
|
|
||||||
import org.eclipse.swt.SWT;
|
|
||||||
import org.eclipse.swt.events.ControlAdapter;
|
|
||||||
import org.eclipse.swt.events.ControlEvent;
|
|
||||||
import org.eclipse.swt.events.SelectionAdapter;
|
|
||||||
import org.eclipse.swt.events.SelectionEvent;
|
|
||||||
import org.eclipse.swt.graphics.Rectangle;
|
|
||||||
import org.eclipse.swt.layout.GridData;
|
|
||||||
import org.eclipse.swt.layout.GridLayout;
|
|
||||||
import org.eclipse.swt.widgets.Button;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
|
||||||
import org.eclipse.swt.widgets.Table;
|
|
||||||
import org.eclipse.swt.widgets.TableColumn;
|
|
||||||
import org.eclipse.swt.widgets.TableItem;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The APK Configuration widget is a table that is added to the given parent composite.
|
|
||||||
* <p/>
|
|
||||||
* To use, create it using {@link #ApkConfigWidget(Composite)} then
|
|
||||||
* call {@link #fillTable(Map) to set the initial list of configurations.
|
|
||||||
*/
|
|
||||||
public class ApkConfigWidget {
|
|
||||||
private final static int INDEX_NAME = 0;
|
|
||||||
private final static int INDEX_FILTER = 1;
|
|
||||||
|
|
||||||
private Table mApkConfigTable;
|
|
||||||
private Button mEditButton;
|
|
||||||
private Button mDelButton;
|
|
||||||
|
|
||||||
public ApkConfigWidget(final Composite parent) {
|
|
||||||
final Composite apkConfigComp = new Composite(parent, SWT.NONE);
|
|
||||||
apkConfigComp.setLayoutData(new GridData(GridData.FILL_BOTH));
|
|
||||||
apkConfigComp.setLayout(new GridLayout(2, false));
|
|
||||||
|
|
||||||
mApkConfigTable = new Table(apkConfigComp, SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
|
|
||||||
mApkConfigTable.setHeaderVisible(true);
|
|
||||||
mApkConfigTable.setLinesVisible(true);
|
|
||||||
|
|
||||||
GridData data = new GridData();
|
|
||||||
data.grabExcessVerticalSpace = true;
|
|
||||||
data.grabExcessHorizontalSpace = true;
|
|
||||||
data.horizontalAlignment = GridData.FILL;
|
|
||||||
data.verticalAlignment = GridData.FILL;
|
|
||||||
mApkConfigTable.setLayoutData(data);
|
|
||||||
|
|
||||||
// create the table columns
|
|
||||||
final TableColumn column0 = new TableColumn(mApkConfigTable, SWT.NONE);
|
|
||||||
column0.setText("Name");
|
|
||||||
column0.setWidth(100);
|
|
||||||
final TableColumn column1 = new TableColumn(mApkConfigTable, SWT.NONE);
|
|
||||||
column1.setText("Configuration");
|
|
||||||
column1.setWidth(100);
|
|
||||||
|
|
||||||
Composite buttonComp = new Composite(apkConfigComp, SWT.NONE);
|
|
||||||
buttonComp.setLayoutData(new GridData(GridData.FILL_VERTICAL));
|
|
||||||
GridLayout gl;
|
|
||||||
buttonComp.setLayout(gl = new GridLayout(1, false));
|
|
||||||
gl.marginHeight = gl.marginWidth = 0;
|
|
||||||
|
|
||||||
Button newButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
|
|
||||||
newButton.setText("New...");
|
|
||||||
newButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
|
||||||
|
|
||||||
mEditButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
|
|
||||||
mEditButton.setText("Edit...");
|
|
||||||
mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
|
||||||
|
|
||||||
mDelButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT);
|
|
||||||
mDelButton.setText("Delete");
|
|
||||||
mDelButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
|
||||||
|
|
||||||
newButton.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
ApkConfigEditDialog dlg = new ApkConfigEditDialog(null /*name*/, null /*filter*/,
|
|
||||||
apkConfigComp.getShell());
|
|
||||||
if (dlg.open() == Dialog.OK) {
|
|
||||||
TableItem item = new TableItem(mApkConfigTable, SWT.NONE);
|
|
||||||
item.setText(INDEX_NAME, dlg.getName());
|
|
||||||
item.setText(INDEX_FILTER, dlg.getFilter());
|
|
||||||
|
|
||||||
onSelectionChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mEditButton.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
// get the current selection (single mode so we don't care about any item beyond
|
|
||||||
// index 0).
|
|
||||||
TableItem[] items = mApkConfigTable.getSelection();
|
|
||||||
if (items.length != 0) {
|
|
||||||
ApkConfigEditDialog dlg = new ApkConfigEditDialog(
|
|
||||||
items[0].getText(INDEX_NAME), items[0].getText(INDEX_FILTER),
|
|
||||||
apkConfigComp.getShell());
|
|
||||||
if (dlg.open() == Dialog.OK) {
|
|
||||||
items[0].setText(INDEX_NAME, dlg.getName());
|
|
||||||
items[0].setText(INDEX_FILTER, dlg.getFilter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mDelButton.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
// get the current selection (single mode so we don't care about any item beyond
|
|
||||||
// index 0).
|
|
||||||
int[] indices = mApkConfigTable.getSelectionIndices();
|
|
||||||
if (indices.length != 0) {
|
|
||||||
TableItem item = mApkConfigTable.getItem(indices[0]);
|
|
||||||
if (MessageDialog.openQuestion(parent.getShell(),
|
|
||||||
"Apk Configuration deletion",
|
|
||||||
String.format(
|
|
||||||
"Are you sure you want to delete configuration '%1$s'?",
|
|
||||||
item.getText(INDEX_NAME)))) {
|
|
||||||
// delete the item.
|
|
||||||
mApkConfigTable.remove(indices[0]);
|
|
||||||
|
|
||||||
onSelectionChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add a listener to resize the column to the full width of the table
|
|
||||||
mApkConfigTable.addControlListener(new ControlAdapter() {
|
|
||||||
@Override
|
|
||||||
public void controlResized(ControlEvent e) {
|
|
||||||
Rectangle r = mApkConfigTable.getClientArea();
|
|
||||||
column0.setWidth(r.width * 30 / 100); // 30%
|
|
||||||
column1.setWidth(r.width * 70 / 100); // 70%
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// add a selection listener on the table, to enable/disable buttons.
|
|
||||||
mApkConfigTable.addSelectionListener(new SelectionAdapter() {
|
|
||||||
@Override
|
|
||||||
public void widgetSelected(SelectionEvent e) {
|
|
||||||
onSelectionChanged();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fillTable(Map<String, String> apkConfigMap) {
|
|
||||||
// get the names in a list so that we can sort them.
|
|
||||||
if (apkConfigMap != null) {
|
|
||||||
Set<String> keys = apkConfigMap.keySet();
|
|
||||||
String[] keyArray = keys.toArray(new String[keys.size()]);
|
|
||||||
Arrays.sort(keyArray);
|
|
||||||
|
|
||||||
for (String key : keyArray) {
|
|
||||||
TableItem item = new TableItem(mApkConfigTable, SWT.NONE);
|
|
||||||
item.setText(INDEX_NAME, key);
|
|
||||||
item.setText(INDEX_FILTER, apkConfigMap.get(key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelectionChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getApkConfigs() {
|
|
||||||
// go through all the items from the table and fill a new map
|
|
||||||
HashMap<String, String> map = new HashMap<String, String>();
|
|
||||||
|
|
||||||
TableItem[] items = mApkConfigTable.getItems();
|
|
||||||
for (TableItem item : items) {
|
|
||||||
map.put(item.getText(INDEX_NAME), item.getText(INDEX_FILTER));
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles table selection changes.
|
|
||||||
*/
|
|
||||||
private void onSelectionChanged() {
|
|
||||||
if (mApkConfigTable.getSelectionCount() > 0) {
|
|
||||||
mEditButton.setEnabled(true);
|
|
||||||
mDelButton.setEnabled(true);
|
|
||||||
} else {
|
|
||||||
mEditButton.setEnabled(false);
|
|
||||||
mDelButton.setEnabled(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -48,57 +48,32 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
public class SdkTargetSelector {
|
public class SdkTargetSelector {
|
||||||
|
|
||||||
private IAndroidTarget[] mTargets;
|
private final IAndroidTarget[] mTargets;
|
||||||
private final boolean mAllowSelection;
|
|
||||||
private final boolean mAllowMultipleSelection;
|
private final boolean mAllowMultipleSelection;
|
||||||
private SelectionListener mSelectionListener;
|
private SelectionListener mSelectionListener;
|
||||||
private Table mTable;
|
private Table mTable;
|
||||||
private Label mDescription;
|
private Label mDescription;
|
||||||
private Composite mInnerGroup;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new SDK Target Selector.
|
* Creates a new SDK Target Selector.
|
||||||
*
|
*
|
||||||
* @param parent The parent composite where the selector will be added.
|
* @param parent The parent composite where the selector will be added.
|
||||||
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
|
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
|
||||||
* Targets can be null or an empty array, in which case the table is disabled.
|
|
||||||
* @param allowMultipleSelection True if more than one SDK target can be selected at the same
|
* @param allowMultipleSelection True if more than one SDK target can be selected at the same
|
||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
|
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
|
||||||
boolean allowMultipleSelection) {
|
boolean allowMultipleSelection) {
|
||||||
this(parent, targets, true /*allowSelection*/, allowMultipleSelection);
|
mTargets = targets;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new SDK Target Selector.
|
|
||||||
*
|
|
||||||
* @param parent The parent composite where the selector will be added.
|
|
||||||
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
|
|
||||||
* Targets can be null or an empty array, in which case the table is disabled.
|
|
||||||
* @param allowSelection True if selection is enabled.
|
|
||||||
* @param allowMultipleSelection True if more than one SDK target can be selected at the same
|
|
||||||
* time. Used only if allowSelection is true.
|
|
||||||
*/
|
|
||||||
public SdkTargetSelector(Composite parent, IAndroidTarget[] targets,
|
|
||||||
boolean allowSelection,
|
|
||||||
boolean allowMultipleSelection) {
|
|
||||||
// Layout has 1 column
|
// Layout has 1 column
|
||||||
mInnerGroup = new Composite(parent, SWT.NONE);
|
Composite group = new Composite(parent, SWT.NONE);
|
||||||
mInnerGroup.setLayout(new GridLayout());
|
group.setLayout(new GridLayout());
|
||||||
mInnerGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
|
group.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||||
mInnerGroup.setFont(parent.getFont());
|
group.setFont(parent.getFont());
|
||||||
|
|
||||||
mAllowSelection = allowSelection;
|
|
||||||
mAllowMultipleSelection = allowMultipleSelection;
|
mAllowMultipleSelection = allowMultipleSelection;
|
||||||
int style = SWT.BORDER;
|
mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
|
||||||
if (allowSelection) {
|
|
||||||
style |= SWT.CHECK | SWT.FULL_SELECTION;
|
|
||||||
}
|
|
||||||
if (!mAllowMultipleSelection) {
|
|
||||||
style |= SWT.SINGLE;
|
|
||||||
}
|
|
||||||
mTable = new Table(mInnerGroup, style);
|
|
||||||
mTable.setHeaderVisible(true);
|
mTable.setHeaderVisible(true);
|
||||||
mTable.setLinesVisible(false);
|
mTable.setLinesVisible(false);
|
||||||
|
|
||||||
@@ -109,7 +84,7 @@ public class SdkTargetSelector {
|
|||||||
data.verticalAlignment = GridData.FILL;
|
data.verticalAlignment = GridData.FILL;
|
||||||
mTable.setLayoutData(data);
|
mTable.setLayoutData(data);
|
||||||
|
|
||||||
mDescription = new Label(mInnerGroup, SWT.WRAP);
|
mDescription = new Label(group, SWT.WRAP);
|
||||||
mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
|
||||||
// create the table columns
|
// create the table columns
|
||||||
@@ -118,27 +93,16 @@ public class SdkTargetSelector {
|
|||||||
final TableColumn column1 = new TableColumn(mTable, SWT.NONE);
|
final TableColumn column1 = new TableColumn(mTable, SWT.NONE);
|
||||||
column1.setText("Vendor");
|
column1.setText("Vendor");
|
||||||
final TableColumn column2 = new TableColumn(mTable, SWT.NONE);
|
final TableColumn column2 = new TableColumn(mTable, SWT.NONE);
|
||||||
column2.setText("Version");
|
column2.setText("API Level");
|
||||||
final TableColumn column3 = new TableColumn(mTable, SWT.NONE);
|
final TableColumn column3 = new TableColumn(mTable, SWT.NONE);
|
||||||
column3.setText("API Level");
|
column3.setText("SDK");
|
||||||
|
|
||||||
adjustColumnsWidth(mTable, column0, column1, column2, column3);
|
adjustColumnsWidth(mTable, column0, column1, column2, column3);
|
||||||
setupSelectionListener(mTable);
|
setupSelectionListener(mTable);
|
||||||
setTargets(targets);
|
fillTable(mTable);
|
||||||
setupTooltip(mTable);
|
setupTooltip(mTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the layout data of the inner composite widget that contains the target selector.
|
|
||||||
* By default the layout data is set to a {@link GridData} with a {@link GridData#FILL_BOTH}
|
|
||||||
* mode.
|
|
||||||
* <p/>
|
|
||||||
* This can be useful if you want to change the {@link GridData#horizontalSpan} for example.
|
|
||||||
*/
|
|
||||||
public Object getLayoutData() {
|
|
||||||
return mInnerGroup.getLayoutData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of known targets.
|
* Returns the list of known targets.
|
||||||
* <p/>
|
* <p/>
|
||||||
@@ -148,16 +112,6 @@ public class SdkTargetSelector {
|
|||||||
return mTargets;
|
return mTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Changes the targets of the SDK Target Selector.
|
|
||||||
*
|
|
||||||
* @param targets The list of targets. This is <em>not</em> copied, the caller must not modify.
|
|
||||||
*/
|
|
||||||
public void setTargets(IAndroidTarget[] targets) {
|
|
||||||
mTargets = targets;
|
|
||||||
fillTable(mTable);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a selection listener. Set it to null to remove it.
|
* Sets a selection listener. Set it to null to remove it.
|
||||||
* The listener will be called <em>after</em> this table processed its selection
|
* The listener will be called <em>after</em> this table processed its selection
|
||||||
@@ -185,10 +139,6 @@ public class SdkTargetSelector {
|
|||||||
* @return true if the target could be selected, false otherwise.
|
* @return true if the target could be selected, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean setSelection(IAndroidTarget target) {
|
public boolean setSelection(IAndroidTarget target) {
|
||||||
if (!mAllowSelection) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
for (TableItem i : mTable.getItems()) {
|
for (TableItem i : mTable.getItems()) {
|
||||||
@@ -274,10 +224,6 @@ public class SdkTargetSelector {
|
|||||||
* double-clicked (aka "the default selection").
|
* double-clicked (aka "the default selection").
|
||||||
*/
|
*/
|
||||||
private void setupSelectionListener(final Table table) {
|
private void setupSelectionListener(final Table table) {
|
||||||
if (!mAllowSelection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 */
|
/** Default selection means double-click on "most" platforms */
|
||||||
@@ -335,9 +281,6 @@ public class SdkTargetSelector {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
private void fillTable(final Table table) {
|
private void fillTable(final Table table) {
|
||||||
|
|
||||||
table.removeAll();
|
|
||||||
|
|
||||||
if (mTargets != null && mTargets.length > 0) {
|
if (mTargets != null && mTargets.length > 0) {
|
||||||
table.setEnabled(true);
|
table.setEnabled(true);
|
||||||
for (IAndroidTarget target : mTargets) {
|
for (IAndroidTarget target : mTargets) {
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks,
|
|||||||
rem and set up progdir to be the fully-qualified pathname of its directory.
|
rem and set up progdir to be the fully-qualified pathname of its directory.
|
||||||
set prog=%~f0
|
set prog=%~f0
|
||||||
|
|
||||||
rem Change current directory and drive to where traceview.bat is, to avoid
|
rem Change current directory to where traceview is, to avoid issues with directories
|
||||||
rem issues with directories containing whitespaces.
|
rem containing whitespaces.
|
||||||
cd /d %~dp0
|
cd %~dp0
|
||||||
|
|
||||||
set jarfile=traceview.jar
|
set jarfile=traceview.jar
|
||||||
set frameworkdir=
|
set frameworkdir=
|
||||||
|
|||||||
Reference in New Issue
Block a user