Merge change 482 into donut
* changes:
location: Location Manager wakelock cleanup, phase 2
diff --git a/api/current.xml b/api/current.xml
index 9708388..37e391c 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -848,6 +848,17 @@
visibility="public"
>
</field>
+<field name="SDCARD_WRITE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.permission.SDCARD_WRITE""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SEND_SMS"
type="java.lang.String"
transient="false"
@@ -1283,6 +1294,17 @@
visibility="public"
>
</field>
+<field name="STORAGE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.permission-group.STORAGE""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SYSTEM_TOOLS"
type="java.lang.String"
transient="false"
@@ -58025,7 +58047,7 @@
type="float"
transient="false"
volatile="false"
- value="0.0010f"
+ value="0.001f"
static="true"
final="true"
deprecated="not deprecated"
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index a0cdb63..3d89ad7 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -16,24 +16,24 @@
package android.app;
+import static android.app.SuggestionsAdapter.getColumnString;
+
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.server.search.SearchableInfo;
import android.speech.RecognizerIntent;
@@ -45,7 +45,10 @@
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
@@ -53,17 +56,14 @@
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
-import android.widget.CursorAdapter;
import android.widget.ImageButton;
-import android.widget.ImageView;
import android.widget.ListView;
-import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
-import android.widget.WrapperListAdapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
-import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
@@ -75,59 +75,66 @@
public class SearchDialog extends Dialog implements OnItemClickListener, OnItemSelectedListener {
// Debugging support
- final static String LOG_TAG = "SearchDialog";
- private static final int DBG_LOG_TIMING = 0;
- final static int DBG_JAM_THREADING = 0;
+ private static final boolean DBG = false;
+ private static final String LOG_TAG = "SearchDialog";
+ private static final boolean DBG_LOG_TIMING = false;
- // interaction with runtime
- IntentFilter mCloseDialogsFilter;
- IntentFilter mPackageFilter;
-
private static final String INSTANCE_KEY_COMPONENT = "comp";
private static final String INSTANCE_KEY_APPDATA = "data";
private static final String INSTANCE_KEY_GLOBALSEARCH = "glob";
private static final String INSTANCE_KEY_DISPLAY_QUERY = "dQry";
private static final String INSTANCE_KEY_DISPLAY_SEL_START = "sel1";
private static final String INSTANCE_KEY_DISPLAY_SEL_END = "sel2";
- private static final String INSTANCE_KEY_USER_QUERY = "uQry";
- private static final String INSTANCE_KEY_SUGGESTION_QUERY = "sQry";
private static final String INSTANCE_KEY_SELECTED_ELEMENT = "slEl";
private static final int INSTANCE_SELECTED_BUTTON = -2;
private static final int INSTANCE_SELECTED_QUERY = -1;
-
+
+ // interaction with runtime
+ private IntentFilter mCloseDialogsFilter;
+ private IntentFilter mPackageFilter;
+
// views & widgets
private TextView mBadgeLabel;
- private AutoCompleteTextView mSearchTextField;
+ private SearchAutoComplete mSearchAutoComplete;
private Button mGoButton;
private ImageButton mVoiceButton;
+ private View mSearchPlate;
// interaction with searchable application
+ private SearchableInfo mSearchable;
private ComponentName mLaunchComponent;
private Bundle mAppSearchData;
private boolean mGlobalSearchMode;
private Context mActivityContext;
+
+ // stack of previous searchables, to support the BACK key after
+ // SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.
+ // The top of the stack (= previous searchable) is the last element of the list,
+ // since adding and removing is efficient at the end of an ArrayList.
+ private ArrayList<ComponentName> mPreviousComponents;
- // interaction with the search manager service
- private SearchableInfo mSearchable;
-
- // support for suggestions
- private String mUserQuery = null;
- private int mUserQuerySelStart;
- private int mUserQuerySelEnd;
- private boolean mLeaveJammedQueryOnRefocus = false;
- private String mPreviousSuggestionQuery = null;
- private int mPresetSelection = -1;
- private String mSuggestionAction = null;
- private Uri mSuggestionData = null;
- private String mSuggestionQuery = null;
-
// For voice searching
private Intent mVoiceWebSearchIntent;
private Intent mVoiceAppSearchIntent;
// support for AutoCompleteTextView suggestions display
private SuggestionsAdapter mSuggestionsAdapter;
-
+
+ // Whether to rewrite queries when selecting suggestions
+ // TODO: This is disabled because of problems with persistent selections
+ // causing non-user-initiated rewrites.
+ private static final boolean REWRITE_QUERIES = false;
+
+ // The query entered by the user. This is not changed when selecting a suggestion
+ // that modifies the contents of the text field. But if the user then edits
+ // the suggestion, the resulting string is saved.
+ private String mUserQuery;
+
+ // A weak map of drawables we've gotten from other packages, so we don't load them
+ // more than once.
+ private final WeakHashMap<String, Drawable> mOutsideDrawablesCache =
+ new WeakHashMap<String, Drawable>();
+
/**
* Constructor - fires it up and makes it look like the search UI.
*
@@ -153,25 +160,29 @@
theWindow.setLayout(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
WindowManager.LayoutParams lp = theWindow.getAttributes();
- lp.setTitle("Search Dialog");
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE;
theWindow.setAttributes(lp);
// get the view elements for local access
mBadgeLabel = (TextView) findViewById(com.android.internal.R.id.search_badge);
- mSearchTextField = (AutoCompleteTextView)
+ mSearchAutoComplete = (SearchAutoComplete)
findViewById(com.android.internal.R.id.search_src_text);
mGoButton = (Button) findViewById(com.android.internal.R.id.search_go_btn);
mVoiceButton = (ImageButton) findViewById(com.android.internal.R.id.search_voice_btn);
+ mSearchPlate = findViewById(com.android.internal.R.id.search_plate);
// attach listeners
- mSearchTextField.addTextChangedListener(mTextWatcher);
- mSearchTextField.setOnKeyListener(mTextKeyListener);
+ mSearchAutoComplete.addTextChangedListener(mTextWatcher);
+ mSearchAutoComplete.setOnKeyListener(mTextKeyListener);
+ mSearchAutoComplete.setOnItemClickListener(this);
+ mSearchAutoComplete.setOnItemSelectedListener(this);
mGoButton.setOnClickListener(mGoButtonClickListener);
mGoButton.setOnKeyListener(mButtonsKeyListener);
mVoiceButton.setOnClickListener(mVoiceButtonClickListener);
mVoiceButton.setOnKeyListener(mButtonsKeyListener);
+ mSearchAutoComplete.setSearchDialog(this);
+
// pre-hide all the extraneous elements
mBadgeLabel.setVisibility(View.GONE);
@@ -199,7 +210,7 @@
/**
* Set up the search dialog
*
- * @param Returns true if search dialog launched, false if not
+ * @return true if search dialog launched, false if not
*/
public boolean show(String initialQuery, boolean selectInitialQuery,
ComponentName componentName, Bundle appSearchData, boolean globalSearch) {
@@ -208,75 +219,65 @@
// in this case, just discard the "show" request
return true;
}
-
- // Get searchable info from search manager and use to set up other elements of UI
- // Do this first so we can get out quickly if there's nothing to search
- ISearchManager sms;
- sms = ISearchManager.Stub.asInterface(ServiceManager.getService(Context.SEARCH_SERVICE));
- try {
- mSearchable = sms.getSearchableInfo(componentName, globalSearch);
- } catch (RemoteException e) {
- mSearchable = null;
+
+ // set up the searchable and show the dialog
+ if (!show(componentName, appSearchData, globalSearch)) {
+ return false;
}
+
+ // finally, load the user's initial text (which may trigger suggestions)
+ setUserQuery(initialQuery);
+ if (selectInitialQuery) {
+ mSearchAutoComplete.selectAll();
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets up the search dialog and shows it.
+ *
+ * @return <code>true</code> if search dialog launched
+ */
+ private boolean show(ComponentName componentName, Bundle appSearchData,
+ boolean globalSearch) {
+
+ if (DBG) {
+ Log.d(LOG_TAG, "show(" + componentName + ", "
+ + appSearchData + ", " + globalSearch + ")");
+ }
+
+ mSearchable = SearchManager.getSearchableInfo(componentName, globalSearch);
if (mSearchable == null) {
// unfortunately, we can't log here. it would be logspam every time the user
// clicks the "search" key on a non-search app
return false;
}
- // OK, we're going to show ourselves
- super.show();
-
- setupSearchableInfo();
-
mLaunchComponent = componentName;
mAppSearchData = appSearchData;
- mGlobalSearchMode = globalSearch;
+ // Using globalSearch here is just an optimization, just calling
+ // isDefaultSearchable() should always give the same result.
+ mGlobalSearchMode = globalSearch || SearchManager.isDefaultSearchable(mSearchable);
+ mActivityContext = mSearchable.getActivityContext(getContext());
+
+ // show the dialog. this will call onStart().
+ if (!isShowing()) {
+ show();
+ }
+ updateUI();
+
+ return true;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
// receive broadcasts
getContext().registerReceiver(mBroadcastReceiver, mCloseDialogsFilter);
getContext().registerReceiver(mBroadcastReceiver, mPackageFilter);
-
- // configure the autocomplete aspects of the input box
- mSearchTextField.setOnItemClickListener(this);
- mSearchTextField.setOnItemSelectedListener(this);
-
- // This conversion is necessary to force a preload of the EditText and thus force
- // suggestions to be presented (even for an empty query)
- if (initialQuery == null) {
- initialQuery = ""; // This forces the preload to happen, triggering suggestions
- }
-
- // attach the suggestions adapter, if suggestions are available
- // The existence of a suggestions authority is the proxy for "suggestions available here"
- if (mSearchable.getSuggestAuthority() == null) {
- mSuggestionsAdapter = null;
- mSearchTextField.setAdapter(mSuggestionsAdapter);
- mSearchTextField.setText(initialQuery);
- } else {
- mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable,
- mSearchTextField);
- mSearchTextField.setAdapter(mSuggestionsAdapter);
-
- // finally, load the user's initial text (which may trigger suggestions)
- mSuggestionsAdapter.setNonUserQuery(false);
- mSearchTextField.setText(initialQuery);
- }
-
- if (selectInitialQuery) {
- mSearchTextField.selectAll();
- } else {
- mSearchTextField.setSelection(initialQuery.length());
- }
- return true;
- }
-
- /**
- * The default show() for this Dialog is not supported.
- */
- @Override
- public void show() {
- return;
}
/**
@@ -289,6 +290,8 @@
public void onStop() {
super.onStop();
+ // TODO: Removing the listeners means that they never get called, since
+ // Dialog.dismissDialog() calls onStop() before sendDismissMessage().
setOnCancelListener(null);
setOnDismissListener(null);
@@ -299,26 +302,36 @@
// This is OK - it just means we didn't have any registered
}
- // close any leftover cursor
- if (mSuggestionsAdapter != null) {
- mSuggestionsAdapter.changeCursor(null);
- }
+ closeSuggestionsAdapter();
// dump extra memory we're hanging on to
mLaunchComponent = null;
mAppSearchData = null;
mSearchable = null;
- mSuggestionAction = null;
- mSuggestionData = null;
- mSuggestionQuery = null;
mActivityContext = null;
- mPreviousSuggestionQuery = null;
mUserQuery = null;
+ mPreviousComponents = null;
+ }
+
+ /**
+ * Closes and gets rid of the suggestions adapter.
+ */
+ private void closeSuggestionsAdapter() {
+ // remove the adapter from the autocomplete first, to avoid any updates
+ // when we drop the cursor
+ mSearchAutoComplete.setAdapter((SuggestionsAdapter)null);
+ // close any leftover cursor
+ if (mSuggestionsAdapter != null) {
+ mSuggestionsAdapter.changeCursor(null);
+ }
+ mSuggestionsAdapter = null;
}
/**
* Save the minimal set of data necessary to recreate the search
*
+ * TODO: go through this and make sure that it saves everything that is needed
+ *
* @return A bundle with the state of the dialog.
*/
@Override
@@ -331,16 +344,14 @@
bundle.putBoolean(INSTANCE_KEY_GLOBALSEARCH, mGlobalSearchMode);
// UI state
- bundle.putString(INSTANCE_KEY_DISPLAY_QUERY, mSearchTextField.getText().toString());
- bundle.putInt(INSTANCE_KEY_DISPLAY_SEL_START, mSearchTextField.getSelectionStart());
- bundle.putInt(INSTANCE_KEY_DISPLAY_SEL_END, mSearchTextField.getSelectionEnd());
- bundle.putString(INSTANCE_KEY_USER_QUERY, mUserQuery);
- bundle.putString(INSTANCE_KEY_SUGGESTION_QUERY, mPreviousSuggestionQuery);
+ bundle.putString(INSTANCE_KEY_DISPLAY_QUERY, mSearchAutoComplete.getText().toString());
+ bundle.putInt(INSTANCE_KEY_DISPLAY_SEL_START, mSearchAutoComplete.getSelectionStart());
+ bundle.putInt(INSTANCE_KEY_DISPLAY_SEL_END, mSearchAutoComplete.getSelectionEnd());
int selectedElement = INSTANCE_SELECTED_QUERY;
if (mGoButton.isFocused()) {
selectedElement = INSTANCE_SELECTED_BUTTON;
- } else if (mSearchTextField.isPopupShowing()) {
+ } else if (mSearchAutoComplete.isPopupShowing()) {
selectedElement = 0; // TODO mSearchTextField.getListSelection() // 0..n
}
bundle.putInt(INSTANCE_KEY_SELECTED_ELEMENT, selectedElement);
@@ -350,6 +361,8 @@
/**
* Restore the state of the dialog from a previously saved bundle.
+ *
+ * TODO: go through this and make sure that it saves everything that is saved
*
* @param savedInstanceState The state of the dialog previously saved by
* {@link #onSaveInstanceState()}.
@@ -365,26 +378,17 @@
String displayQuery = savedInstanceState.getString(INSTANCE_KEY_DISPLAY_QUERY);
int querySelStart = savedInstanceState.getInt(INSTANCE_KEY_DISPLAY_SEL_START, -1);
int querySelEnd = savedInstanceState.getInt(INSTANCE_KEY_DISPLAY_SEL_END, -1);
- String userQuery = savedInstanceState.getString(INSTANCE_KEY_USER_QUERY);
int selectedElement = savedInstanceState.getInt(INSTANCE_KEY_SELECTED_ELEMENT);
- String suggestionQuery = savedInstanceState.getString(INSTANCE_KEY_SUGGESTION_QUERY);
// show the dialog. skip any show/hide animation, we want to go fast.
// send the text that actually generates the suggestions here; we'll replace the display
// text as necessary in a moment.
- if (!show(suggestionQuery, false, launchComponent, appSearchData, globalSearch)) {
+ if (!show(displayQuery, false, launchComponent, appSearchData, globalSearch)) {
// for some reason, we couldn't re-instantiate
return;
}
- if (mSuggestionsAdapter != null) {
- mSuggestionsAdapter.setNonUserQuery(true);
- }
- mSearchTextField.setText(displayQuery);
- // TODO because the new query is (not) processed in another thread, we can't just
- // take away this flag (yet). The better solution here is going to require a new API
- // in AutoCompleteTextView which allows us to change the text w/o changing the suggestions.
-// mSuggestionsAdapter.setNonUserQuery(false);
+ mSearchAutoComplete.setText(displayQuery);
// clean up the selection state
switch (selectedElement) {
@@ -395,21 +399,19 @@
break;
case INSTANCE_SELECTED_QUERY:
if (querySelStart >= 0 && querySelEnd >= 0) {
- mSearchTextField.requestFocus();
- mSearchTextField.setSelection(querySelStart, querySelEnd);
+ mSearchAutoComplete.requestFocus();
+ mSearchAutoComplete.setSelection(querySelStart, querySelEnd);
}
break;
default:
- // defer selecting a list element until suggestion list appears
- mPresetSelection = selectedElement;
- // TODO mSearchTextField.setListSelection(selectedElement)
+ // TODO: defer selecting a list element until suggestion list appears
+// mSearchAutoComplete.setListSelection(selectedElement)
break;
}
}
/**
- * Hook for updating layout on a rotation
- *
+ * Called after resources have changed, e.g. after screen rotation or locale change.
*/
public void onConfigurationChanged(Configuration newConfig) {
if (isShowing()) {
@@ -419,15 +421,13 @@
updateQueryHint();
}
}
-
+
/**
- * Use SearchableInfo record (from search manager service) to preconfigure the UI in various
- * ways.
+ * Update the UI according to the info in the current value of {@link #mSearchable}.
*/
- private void setupSearchableInfo() {
+ private void updateUI() {
if (mSearchable != null) {
- mActivityContext = mSearchable.getActivityContext(getContext());
-
+ updateSearchAutoComplete();
updateSearchButton();
updateSearchBadge();
updateQueryHint();
@@ -449,24 +449,38 @@
inputType |= InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE;
}
}
- mSearchTextField.setInputType(inputType);
- mSearchTextField.setImeOptions(mSearchable.getImeOptions());
+ mSearchAutoComplete.setInputType(inputType);
+ mSearchAutoComplete.setImeOptions(mSearchable.getImeOptions());
+ }
+ }
+
+ /**
+ * Updates the auto-complete text view.
+ */
+ private void updateSearchAutoComplete() {
+ // close any existing suggestions adapter
+ closeSuggestionsAdapter();
+
+ mSearchAutoComplete.setDropDownAnimationStyle(0); // no animation
+ mSearchAutoComplete.setThreshold(0); // always allow zero-query suggestions
+
+ if (mGlobalSearchMode) {
+ mSearchAutoComplete.setDropDownAlwaysVisible(true); // fill space until results come in
+ mSearchAutoComplete.setDropDownDismissedOnCompletion(false);
+ } else {
+ mSearchAutoComplete.setDropDownAlwaysVisible(false);
+ mSearchAutoComplete.setDropDownDismissedOnCompletion(true);
+ }
+
+ // attach the suggestions adapter, if suggestions are available
+ // The existence of a suggestions authority is the proxy for "suggestions available here"
+ if (mSearchable.getSuggestAuthority() != null) {
+ mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable,
+ mOutsideDrawablesCache);
+ mSearchAutoComplete.setAdapter(mSuggestionsAdapter);
}
}
- /**
- * The list of installed packages has just changed. This means that our current context
- * may no longer be valid. This would only happen if a package is installed/removed exactly
- * when the search bar is open. So for now we're just going to close the search
- * bar.
- *
- * Anything fancier would require some checks to see if the user's context was still valid.
- * Which would be messier.
- */
- public void onPackageListChange() {
- cancel();
- }
-
/**
* Update the text in the search button. Note: This is deprecated functionality, for
* 1.0 compatibility only.
@@ -481,26 +495,40 @@
iconLabel = getContext().getResources().
getDrawable(com.android.internal.R.drawable.ic_btn_search);
}
- mGoButton.setText(textLabel);
+ mGoButton.setText(textLabel);
mGoButton.setCompoundDrawablesWithIntrinsicBounds(iconLabel, null, null, null);
}
/**
- * Setup the search "Badge" if request by mode flags.
+ * Setup the search "Badge" if requested by mode flags.
*/
private void updateSearchBadge() {
// assume both hidden
int visibility = View.GONE;
Drawable icon = null;
- String text = null;
+ CharSequence text = null;
// optionally show one or the other.
if (mSearchable.mBadgeIcon) {
icon = mActivityContext.getResources().getDrawable(mSearchable.getIconId());
visibility = View.VISIBLE;
+ if (DBG) Log.d(LOG_TAG, "Using badge icon: " + mSearchable.getIconId());
} else if (mSearchable.mBadgeLabel) {
text = mActivityContext.getResources().getText(mSearchable.getLabelId()).toString();
visibility = View.VISIBLE;
+ if (DBG) Log.d(LOG_TAG, "Using badge label: " + mSearchable.getLabelId());
+ } else if (!mGlobalSearchMode) {
+ // Get the localized name of the application which we are doing search in.
+ try {
+ PackageManager pm = getContext().getPackageManager();
+ ActivityInfo info = pm.getActivityInfo(mLaunchComponent, 0);
+ text = pm.getApplicationLabel(info.applicationInfo);
+ visibility = View.VISIBLE;
+ if (DBG) Log.d(LOG_TAG, "Using application label: " + text);
+ } catch (NameNotFoundException e) {
+ // app not found, fine, don't use its name for the label
+ Log.w(LOG_TAG, mLaunchComponent + " not found.");
+ }
}
mBadgeLabel.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
@@ -520,7 +548,7 @@
hint = mActivityContext.getString(hintId);
}
}
- mSearchTextField.setHint(hint);
+ mSearchAutoComplete.setHint(hint);
}
}
@@ -548,63 +576,129 @@
mVoiceButton.setVisibility(visibility);
}
+ /*
+ * Menu.
+ */
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Show search settings menu item if anyone handles the intent for it
+ Intent settingsIntent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
+ PackageManager pm = getContext().getPackageManager();
+ ActivityInfo activityInfo = settingsIntent.resolveActivityInfo(pm, 0);
+ if (activityInfo != null) {
+ settingsIntent.setClassName(activityInfo.applicationInfo.packageName,
+ activityInfo.name);
+ String label = getActivityLabel(activityInfo);
+ menu.add(Menu.NONE, Menu.NONE, Menu.NONE, label)
+ .setIcon(android.R.drawable.ic_menu_preferences)
+ .setAlphabeticShortcut('P')
+ .setIntent(settingsIntent);
+ return true;
+ }
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ // TODO: shouldn't this be in PackageManager?
+ private String getActivityLabel(ActivityInfo activityInfo) {
+ PackageManager pm = getContext().getPackageManager();
+ try {
+ int labelRes = activityInfo.labelRes;
+ if (labelRes == 0) {
+ return null;
+ }
+ Resources r = pm.getResourcesForApplication(activityInfo.applicationInfo);
+ return r.getString(labelRes);
+ } catch (NameNotFoundException ex) {
+ return null;
+ }
+ }
+
/**
* Listeners of various types
*/
/**
+ * {@link Dialog#onTouchEvent(MotionEvent)} will cancel the dialog only when the
+ * touch is outside the window. But the window includes space for the drop-down,
+ * so we also cancel on taps outside the search bar when the drop-down is not showing.
+ */
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ // cancel if the drop-down is not showing and the touch event was outside the search plate
+ if (!mSearchAutoComplete.isPopupShowing() && isOutOfBounds(mSearchPlate, event)) {
+ if (DBG) Log.d(LOG_TAG, "Pop-up not showing and outside of search plate.");
+ cancel();
+ return true;
+ }
+ // Let Dialog handle events outside the window while the pop-up is showing.
+ return super.onTouchEvent(event);
+ }
+
+ private boolean isOutOfBounds(View v, MotionEvent event) {
+ final int x = (int) event.getX();
+ final int y = (int) event.getY();
+ final int slop = ViewConfiguration.get(mContext).getScaledWindowTouchSlop();
+ return (x < -slop) || (y < -slop)
+ || (x > (v.getWidth()+slop))
+ || (y > (v.getHeight()+slop));
+ }
+
+ /**
* Dialog's OnKeyListener implements various search-specific functionality
*
* @param keyCode This is the keycode of the typed key, and is the same value as
- * found in the KeyEvent parameter.
+ * found in the KeyEvent parameter.
* @param event The complete event record for the typed key
*
* @return Return true if the event was handled here, or false if not.
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_BACK:
- cancel();
+ if (DBG) Log.d(LOG_TAG, "onKeyDown(" + keyCode + "," + event + ")");
+
+ // handle back key to go back to previous searchable, etc.
+ if (handleBackKey(keyCode, event)) {
return true;
- case KeyEvent.KEYCODE_SEARCH:
- if (TextUtils.getTrimmedLength(mSearchTextField.getText()) != 0) {
- launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null);
+ }
+
+ // search or cancel on search key
+ if (keyCode == KeyEvent.KEYCODE_SEARCH) {
+ if (!mSearchAutoComplete.isEmpty()) {
+ launchQuerySearch();
} else {
cancel();
}
return true;
- default:
- SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
- if ((actionKey != null) && (actionKey.mQueryActionMsg != null)) {
- launchQuerySearch(keyCode, actionKey.mQueryActionMsg);
- return true;
- }
- break;
}
+
+ // if it's an action specified by the searchable activity, launch the
+ // entered query with the action key
+ SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
+ if ((actionKey != null) && (actionKey.mQueryActionMsg != null)) {
+ launchQuerySearch(keyCode, actionKey.mQueryActionMsg);
+ return true;
+ }
+
return false;
}
-
+
/**
* Callback to watch the textedit field for empty/non-empty
*/
private TextWatcher mTextWatcher = new TextWatcher() {
- public void beforeTextChanged(CharSequence s, int start, int
- before, int after) { }
+ public void beforeTextChanged(CharSequence s, int start, int before, int after) { }
public void onTextChanged(CharSequence s, int start,
int before, int after) {
- if (DBG_LOG_TIMING == 1) {
+ if (DBG_LOG_TIMING) {
dbgLogTiming("onTextChanged()");
}
updateWidgetState();
- // Only do suggestions if actually typed by user
- if ((mSuggestionsAdapter != null) && !mSuggestionsAdapter.getNonUserQuery()) {
- mPreviousSuggestionQuery = s.toString();
- mUserQuery = mSearchTextField.getText().toString();
- mUserQuerySelStart = mSearchTextField.getSelectionStart();
- mUserQuerySelEnd = mSearchTextField.getSelectionEnd();
+ if (!mSearchAutoComplete.isPerformingCompletion()) {
+ // The user changed the query, remember it.
+ mUserQuery = s == null ? "" : s.toString();
}
}
@@ -616,64 +710,34 @@
*/
private void updateWidgetState() {
// enable the button if we have one or more non-space characters
- boolean enabled =
- TextUtils.getTrimmedLength(mSearchTextField.getText()) != 0;
-
+ boolean enabled = !mSearchAutoComplete.isEmpty();
mGoButton.setEnabled(enabled);
mGoButton.setFocusable(enabled);
}
- private final static String[] ONE_LINE_FROM = {SearchManager.SUGGEST_COLUMN_TEXT_1 };
- private final static String[] ONE_LINE_ICONS_FROM = {SearchManager.SUGGEST_COLUMN_TEXT_1,
- SearchManager.SUGGEST_COLUMN_ICON_1,
- SearchManager.SUGGEST_COLUMN_ICON_2};
- private final static String[] TWO_LINE_FROM = {SearchManager.SUGGEST_COLUMN_TEXT_1,
- SearchManager.SUGGEST_COLUMN_TEXT_2 };
- private final static String[] TWO_LINE_ICONS_FROM = {SearchManager.SUGGEST_COLUMN_TEXT_1,
- SearchManager.SUGGEST_COLUMN_TEXT_2,
- SearchManager.SUGGEST_COLUMN_ICON_1,
- SearchManager.SUGGEST_COLUMN_ICON_2 };
-
- private final static int[] ONE_LINE_TO = {com.android.internal.R.id.text1};
- private final static int[] ONE_LINE_ICONS_TO = {com.android.internal.R.id.text1,
- com.android.internal.R.id.icon1,
- com.android.internal.R.id.icon2};
- private final static int[] TWO_LINE_TO = {com.android.internal.R.id.text1,
- com.android.internal.R.id.text2};
- private final static int[] TWO_LINE_ICONS_TO = {com.android.internal.R.id.text1,
- com.android.internal.R.id.text2,
- com.android.internal.R.id.icon1,
- com.android.internal.R.id.icon2};
-
- /**
- * Safely retrieve the suggestions cursor adapter from the ListView
- *
- * @param adapterView The ListView containing our adapter
- * @result The CursorAdapter that we installed, or null if not set
- */
- private static CursorAdapter getSuggestionsAdapter(AdapterView<?> adapterView) {
- CursorAdapter result = null;
- if (adapterView != null) {
- Object ad = adapterView.getAdapter();
- if (ad instanceof CursorAdapter) {
- result = (CursorAdapter) ad;
- } else if (ad instanceof WrapperListAdapter) {
- result = (CursorAdapter) ((WrapperListAdapter)ad).getWrappedAdapter();
- }
- }
- return result;
- }
-
/**
* React to typing in the GO search button by refocusing to EditText.
* Continue typing the query.
*/
View.OnKeyListener mButtonsKeyListener = new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
- // also guard against possible race conditions (late arrival after dismiss)
- if (mSearchable != null) {
- return refocusingKeyListener(v, keyCode, event);
+ // guard against possible race conditions
+ if (mSearchable == null) {
+ return false;
}
+
+ if (!event.isSystem() &&
+ (keyCode != KeyEvent.KEYCODE_DPAD_UP) &&
+ (keyCode != KeyEvent.KEYCODE_DPAD_DOWN) &&
+ (keyCode != KeyEvent.KEYCODE_DPAD_LEFT) &&
+ (keyCode != KeyEvent.KEYCODE_DPAD_RIGHT) &&
+ (keyCode != KeyEvent.KEYCODE_DPAD_CENTER)) {
+ // restore focus and give key to EditText ...
+ if (mSearchAutoComplete.requestFocus()) {
+ return mSearchAutoComplete.dispatchKeyEvent(event);
+ }
+ }
+
return false;
}
};
@@ -683,10 +747,11 @@
*/
View.OnClickListener mGoButtonClickListener = new View.OnClickListener() {
public void onClick(View v) {
- // also guard against possible race conditions (late arrival after dismiss)
- if (mSearchable != null) {
- launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null);
+ // guard against possible race conditions
+ if (mSearchable == null) {
+ return;
}
+ launchQuerySearch();
}
};
@@ -695,14 +760,16 @@
*/
View.OnClickListener mVoiceButtonClickListener = new View.OnClickListener() {
public void onClick(View v) {
+ // guard against possible race conditions
+ if (mSearchable == null) {
+ return;
+ }
try {
if (mSearchable.getVoiceSearchLaunchWebSearch()) {
getContext().startActivity(mVoiceWebSearchIntent);
- dismiss();
} else if (mSearchable.getVoiceSearchLaunchRecognizer()) {
Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent);
getContext().startActivity(appSearchIntent);
- dismiss();
}
} catch (ActivityNotFoundException e) {
// Should not happen, since we check the availability of
@@ -778,136 +845,56 @@
*/
View.OnKeyListener mTextKeyListener = new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- cancel();
- return true;
+ // guard against possible race conditions
+ if (mSearchable == null) {
+ return false;
}
- // also guard against possible race conditions (late arrival after dismiss)
- if (mSearchable != null &&
- TextUtils.getTrimmedLength(mSearchTextField.getText()) > 0) {
- if (DBG_LOG_TIMING == 1) {
- dbgLogTiming("doTextKey()");
+
+ if (DBG_LOG_TIMING) dbgLogTiming("doTextKey()");
+ if (DBG) {
+ Log.d(LOG_TAG, "mTextListener.onKey(" + keyCode + "," + event
+ + "), selection: " + mSearchAutoComplete.getListSelection());
+ }
+
+ // If a suggestion is selected, handle enter, search key, and action keys
+ // as presses on the selected suggestion
+ if (mSearchAutoComplete.isPopupShowing() &&
+ mSearchAutoComplete.getListSelection() != ListView.INVALID_POSITION) {
+ return onSuggestionsKey(v, keyCode, event);
+ }
+
+ // If there is text in the query box, handle enter, and action keys
+ // The search key is handled by the dialog's onKeyDown().
+ if (!mSearchAutoComplete.isEmpty()) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER
+ && event.getAction() == KeyEvent.ACTION_UP) {
+ v.cancelLongPress();
+ launchQuerySearch();
+ return true;
}
- // dispatch "typing in the list" first
- if (mSearchTextField.isPopupShowing() &&
- mSearchTextField.getListSelection() != ListView.INVALID_POSITION) {
- return onSuggestionsKey(v, keyCode, event);
- }
- // otherwise, dispatch an "edit view" key
- switch (keyCode) {
- case KeyEvent.KEYCODE_ENTER:
- if (event.getAction() == KeyEvent.ACTION_UP) {
- v.cancelLongPress();
- launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null);
+ if (event.getAction() == KeyEvent.ACTION_DOWN) {
+ SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
+ if ((actionKey != null) && (actionKey.mQueryActionMsg != null)) {
+ launchQuerySearch(keyCode, actionKey.mQueryActionMsg);
return true;
}
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- // capture the EditText state, so we can restore the user entry later
- mUserQuery = mSearchTextField.getText().toString();
- mUserQuerySelStart = mSearchTextField.getSelectionStart();
- mUserQuerySelEnd = mSearchTextField.getSelectionEnd();
- // pass through - we're just watching here
- break;
- default:
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- SearchableInfo.ActionKeyInfo actionKey = mSearchable.findActionKey(keyCode);
- if ((actionKey != null) && (actionKey.mQueryActionMsg != null)) {
- launchQuerySearch(keyCode, actionKey.mQueryActionMsg);
- return true;
- }
- }
- break;
}
}
return false;
}
};
-
+
/**
- * React to the user typing while the suggestions are focused. First, check for action
- * keys. If not handled, try refocusing regular characters into the EditText. In this case,
- * replace the query text (start typing fresh text).
- */
- private boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) {
- boolean handled = false;
- // also guard against possible race conditions (late arrival after dismiss)
- if (mSearchable != null) {
- handled = doSuggestionsKey(v, keyCode, event);
- }
- return handled;
- }
-
- /**
- * Per UI design, we're going to "steer" any typed keystrokes back into the EditText
- * box, even if the user has navigated the focus to the dropdown or to the GO button.
- *
- * @param v The view into which the keystroke was typed
- * @param keyCode keyCode of entered key
- * @param event Full KeyEvent record of entered key
- */
- private boolean refocusingKeyListener(View v, int keyCode, KeyEvent event) {
- boolean handled = false;
-
- if (!event.isSystem() &&
- (keyCode != KeyEvent.KEYCODE_DPAD_UP) &&
- (keyCode != KeyEvent.KEYCODE_DPAD_DOWN) &&
- (keyCode != KeyEvent.KEYCODE_DPAD_LEFT) &&
- (keyCode != KeyEvent.KEYCODE_DPAD_RIGHT) &&
- (keyCode != KeyEvent.KEYCODE_DPAD_CENTER)) {
- // restore focus and give key to EditText ...
- // but don't replace the user's query
- mLeaveJammedQueryOnRefocus = true;
- if (mSearchTextField.requestFocus()) {
- handled = mSearchTextField.dispatchKeyEvent(event);
- }
- mLeaveJammedQueryOnRefocus = false;
- }
- return handled;
- }
-
- /**
- * Update query text based on transitions in and out of suggestions list.
- */
- /*
- * TODO - figure out if this logic is required for the autocomplete text view version
-
- OnFocusChangeListener mSuggestFocusListener = new OnFocusChangeListener() {
- public void onFocusChange(View v, boolean hasFocus) {
- // also guard against possible race conditions (late arrival after dismiss)
- if (mSearchable == null) {
- return;
- }
- // Update query text based on navigation in to/out of the suggestions list
- if (hasFocus) {
- // Entering the list view - record selection point from user's query
- mUserQuery = mSearchTextField.getText().toString();
- mUserQuerySelStart = mSearchTextField.getSelectionStart();
- mUserQuerySelEnd = mSearchTextField.getSelectionEnd();
- // then update the query to match the entered selection
- jamSuggestionQuery(true, mSuggestionsList,
- mSuggestionsList.getSelectedItemPosition());
- } else {
- // Exiting the list view
-
- if (mSuggestionsList.getSelectedItemPosition() < 0) {
- // Direct exit - Leave new suggestion in place (do nothing)
- } else {
- // Navigation exit - restore user's query text
- if (!mLeaveJammedQueryOnRefocus) {
- jamSuggestionQuery(false, null, -1);
- }
- }
- }
-
- }
- };
- */
-
- /**
- * This is the listener for the ACTION_CLOSE_SYSTEM_DIALOGS intent. It's an indication that
- * we should close ourselves immediately, in order to allow a higher-priority UI to take over
+ * When the ACTION_CLOSE_SYSTEM_DIALOGS intent is received, we should close ourselves
+ * immediately, in order to allow a higher-priority UI to take over
* (e.g. phone call received).
+ *
+ * When a package is added, removed or changed, our current context
+ * may no longer be valid. This would only happen if a package is installed/removed exactly
+ * when the search bar is open. So for now we're just going to close the search
+ * bar.
+ * Anything fancier would require some checks to see if the user's context was still valid.
+ * Which would be messier.
*/
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
@@ -918,7 +905,7 @@
} else if (Intent.ACTION_PACKAGE_ADDED.equals(action)
|| Intent.ACTION_PACKAGE_REMOVED.equals(action)
|| Intent.ACTION_PACKAGE_CHANGED.equals(action)) {
- onPackageListChange();
+ cancel();
}
}
};
@@ -938,58 +925,45 @@
}
/**
- * Various ways to launch searches
+ * React to the user typing while in the suggestions list. First, check for action
+ * keys. If not handled, try refocusing regular characters into the EditText.
*/
-
- /**
- * React to the user clicking the "GO" button. Hide the UI and launch a search.
- *
- * @param actionKey Pass a keycode if the launch was triggered by an action key. Pass
- * KeyEvent.KEYCODE_UNKNOWN for no actionKey code.
- * @param actionMsg Pass the suggestion-provided message if the launch was triggered by an
- * action key. Pass null for no actionKey message.
- */
- private void launchQuerySearch(int actionKey, final String actionMsg) {
- final String query = mSearchTextField.getText().toString();
- final Bundle appData = mAppSearchData;
- final SearchableInfo si = mSearchable; // cache briefly (dismiss() nulls it)
- dismiss();
- sendLaunchIntent(Intent.ACTION_SEARCH, null, query, appData, actionKey, actionMsg, si);
- }
-
- /**
- * React to the user typing an action key while in the suggestions list
- */
- private boolean doSuggestionsKey(View v, int keyCode, KeyEvent event) {
- // Exit early in case of race condition
+ private boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) {
+ // guard against possible race conditions (late arrival after dismiss)
+ if (mSearchable == null) {
+ return false;
+ }
if (mSuggestionsAdapter == null) {
return false;
}
if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (DBG_LOG_TIMING == 1) {
- dbgLogTiming("doSuggestionsKey()");
+ if (DBG_LOG_TIMING) {
+ dbgLogTiming("onSuggestionsKey()");
}
// First, check for enter or search (both of which we'll treat as a "click")
if (keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_SEARCH) {
- int position = mSearchTextField.getListSelection();
- return launchSuggestion(mSuggestionsAdapter, position);
+ int position = mSearchAutoComplete.getListSelection();
+ return launchSuggestion(position);
}
// Next, check for left/right moves, which we use to "return" the user to the edit view
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
- // give "focus" to text editor, but don't restore the user's original query
+ // give "focus" to text editor, with cursor at the beginning if
+ // left key, at end if right key
+ // TODO: Reverse left/right for right-to-left languages, e.g. Arabic
int selPoint = (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) ?
- 0 : mSearchTextField.length();
- mSearchTextField.setSelection(selPoint);
- mSearchTextField.setListSelection(0);
- mSearchTextField.clearListSelection();
+ 0 : mSearchAutoComplete.length();
+ mSearchAutoComplete.setSelection(selPoint);
+ mSearchAutoComplete.setListSelection(0);
+ mSearchAutoComplete.clearListSelection();
return true;
}
// Next, check for an "up and out" move
- if (keyCode == KeyEvent.KEYCODE_DPAD_UP && 0 == mSearchTextField.getListSelection()) {
- jamSuggestionQuery(false, null, -1);
+ if (keyCode == KeyEvent.KEYCODE_DPAD_UP
+ && 0 == mSearchAutoComplete.getListSelection()) {
+ restoreUserQuery();
// let ACTV complete the move
return false;
}
@@ -999,222 +973,239 @@
if ((actionKey != null) &&
((actionKey.mSuggestActionMsg != null) ||
(actionKey.mSuggestActionMsgColumn != null))) {
- // launch suggestion using action key column
- int position = mSearchTextField.getListSelection();
- if (position >= 0) {
+ // launch suggestion using action key column
+ int position = mSearchAutoComplete.getListSelection();
+ if (position != ListView.INVALID_POSITION) {
Cursor c = mSuggestionsAdapter.getCursor();
if (c.moveToPosition(position)) {
final String actionMsg = getActionKeyMessage(c, actionKey);
if (actionMsg != null && (actionMsg.length() > 0)) {
- // shut down search bar and launch the activity
- // cache everything we need because dismiss releases mems
- setupSuggestionIntent(c, mSearchable);
- final String query = mSearchTextField.getText().toString();
- final Bundle appData = mAppSearchData;
- SearchableInfo si = mSearchable;
- String suggestionAction = mSuggestionAction;
- Uri suggestionData = mSuggestionData;
- String suggestionQuery = mSuggestionQuery;
- dismiss();
- sendLaunchIntent(suggestionAction, suggestionData,
- suggestionQuery, appData,
- keyCode, actionMsg, si);
- return true;
+ return launchSuggestion(position, keyCode, actionMsg);
}
}
}
}
}
return false;
- }
-
+ }
+
/**
- * Set or reset the user query to follow the selections in the suggestions
- *
- * @param jamQuery True means to set the query, false means to reset it to the user's choice
+ * Launch a search for the text in the query text field.
*/
- private void jamSuggestionQuery(boolean jamQuery, AdapterView<?> parent, int position) {
- // quick check against race conditions
- if (mSearchable == null) {
- return;
- }
-
- mSuggestionsAdapter.setNonUserQuery(true); // disables any suggestions processing
- if (jamQuery) {
- CursorAdapter ca = getSuggestionsAdapter(parent);
- Cursor c = ca.getCursor();
- if (c.moveToPosition(position)) {
- setupSuggestionIntent(c, mSearchable);
- String jamText = null;
-
- // Simple heuristic for selecting text with which to rewrite the query.
- if (mSuggestionQuery != null) {
- jamText = mSuggestionQuery;
- } else if (mSearchable.mQueryRewriteFromData && (mSuggestionData != null)) {
- jamText = mSuggestionData.toString();
- } else if (mSearchable.mQueryRewriteFromText) {
- try {
- int column = c.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1);
- jamText = c.getString(column);
- } catch (RuntimeException e) {
- // no work here, jamText is null
- }
- }
- if (jamText != null) {
- mSearchTextField.setText(jamText);
- /* mSearchTextField.selectAll(); */ // this didn't work anyway in the old UI
- // TODO this is only needed in the model where we have a selection in the ACTV
- // and in the dropdown at the same time.
- mSearchTextField.setSelection(jamText.length());
- }
- }
- } else {
- // reset user query
- mSearchTextField.setText(mUserQuery);
- try {
- mSearchTextField.setSelection(mUserQuerySelStart, mUserQuerySelEnd);
- } catch (IndexOutOfBoundsException e) {
- // In case of error, just select all
- Log.e(LOG_TAG, "Caught IndexOutOfBoundsException while setting selection. " +
- "start=" + mUserQuerySelStart + " end=" + mUserQuerySelEnd +
- " text=\"" + mUserQuery + "\"");
- mSearchTextField.selectAll();
- }
- }
- // TODO because the new query is (not) processed in another thread, we can't just
- // take away this flag (yet). The better solution here is going to require a new API
- // in AutoCompleteTextView which allows us to change the text w/o changing the suggestions.
-// mSuggestionsAdapter.setNonUserQuery(false);
+ protected void launchQuerySearch() {
+ launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null);
}
/**
- * Assemble a search intent and send it.
+ * Launch a search for the text in the query text field.
*
- * @param action The intent to send, typically Intent.ACTION_SEARCH
- * @param data The data for the intent
- * @param query The user text entered (so far)
- * @param appData The app data bundle (if supplied)
- * @param actionKey If the intent was triggered by an action key, e.g. KEYCODE_CALL, it will
- * be sent here. Pass KeyEvent.KEYCODE_UNKNOWN for no actionKey code.
- * @param actionMsg If the intent was triggered by an action key, e.g. KEYCODE_CALL, the
- * corresponding tag message will be sent here. Pass null for no actionKey message.
- * @param si Reference to the current SearchableInfo. Passed here so it can be used even after
- * we've called dismiss(), which attempts to null mSearchable.
+ * @param actionKey The key code of the action key that was pressed,
+ * or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
+ * @param actionMsg The message for the action key that was pressed,
+ * or <code>null</code> if none.
*/
- private void sendLaunchIntent(final String action, final Uri data, final String query,
- final Bundle appData, int actionKey, final String actionMsg, final SearchableInfo si) {
- Intent launcher = new Intent(action);
-
- if (query != null) {
- launcher.putExtra(SearchManager.QUERY, query);
- }
-
- if (data != null) {
- launcher.setData(data);
- }
-
- if (appData != null) {
- launcher.putExtra(SearchManager.APP_DATA, appData);
- }
-
- // add launch info (action key, etc.)
- if (actionKey != KeyEvent.KEYCODE_UNKNOWN) {
- launcher.putExtra(SearchManager.ACTION_KEY, actionKey);
- launcher.putExtra(SearchManager.ACTION_MSG, actionMsg);
- }
-
- // attempt to enforce security requirement (no 3rd-party intents)
- launcher.setComponent(si.mSearchActivity);
-
- getContext().startActivity(launcher);
+ protected void launchQuerySearch(int actionKey, String actionMsg) {
+ String query = mSearchAutoComplete.getText().toString();
+ Intent intent = createIntent(Intent.ACTION_SEARCH, null, query, null,
+ actionKey, actionMsg);
+ launchIntent(intent);
}
-
+
/**
- * Shared code for launching a query from a suggestion.
- * @param ca The cursor adapter containing the suggestions
- * @param position The suggestion we'll be launching from
- * @return true if a successful launch, false if could not (e.g. bad position)
+ * Launches an intent based on a suggestion.
+ *
+ * @param position The index of the suggestion to create the intent from.
+ * @return true if a successful launch, false if could not (e.g. bad position).
*/
- private boolean launchSuggestion(CursorAdapter ca, int position) {
- Cursor c = ca.getCursor();
+ protected boolean launchSuggestion(int position) {
+ return launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null);
+ }
+
+ /**
+ * Launches an intent based on a suggestion.
+ *
+ * @param position The index of the suggestion to create the intent from.
+ * @param actionKey The key code of the action key that was pressed,
+ * or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
+ * @param actionMsg The message for the action key that was pressed,
+ * or <code>null</code> if none.
+ * @return true if a successful launch, false if could not (e.g. bad position).
+ */
+ protected boolean launchSuggestion(int position, int actionKey, String actionMsg) {
+ Cursor c = mSuggestionsAdapter.getCursor();
if ((c != null) && c.moveToPosition(position)) {
- setupSuggestionIntent(c, mSearchable);
-
- final Bundle appData = mAppSearchData;
- SearchableInfo si = mSearchable;
- String suggestionAction = mSuggestionAction;
- Uri suggestionData = mSuggestionData;
- String suggestionQuery = mSuggestionQuery;
- dismiss();
- sendLaunchIntent(suggestionAction, suggestionData, suggestionQuery, appData,
- KeyEvent.KEYCODE_UNKNOWN, null, si);
+ Intent intent = createIntentFromSuggestion(c, actionKey, actionMsg);
+ launchIntent(intent);
return true;
}
return false;
}
/**
+ * Launches an intent. Also dismisses the search dialog if not in global search mode.
+ */
+ private void launchIntent(Intent intent) {
+ if (intent == null) {
+ return;
+ }
+ if (handleSpecialIntent(intent)){
+ return;
+ }
+ if (!mGlobalSearchMode) {
+ dismiss();
+ }
+ getContext().startActivity(intent);
+ }
+
+ /**
+ * Handles the special intent actions declared in {@link SearchManager}.
+ *
+ * @return <code>true</code> if the intent was handled.
+ */
+ private boolean handleSpecialIntent(Intent intent) {
+ String action = intent.getAction();
+ if (SearchManager.INTENT_ACTION_CHANGE_SEARCH_SOURCE.equals(action)) {
+ handleChangeSourceIntent(intent);
+ return true;
+ } else if (SearchManager.INTENT_ACTION_CURSOR_RESPOND.equals(action)) {
+ handleCursorRespondIntent(intent);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Handles SearchManager#INTENT_ACTION_CHANGE_SOURCE.
+ */
+ private void handleChangeSourceIntent(Intent intent) {
+ Uri dataUri = intent.getData();
+ if (dataUri == null) {
+ Log.w(LOG_TAG, "SearchManager.INTENT_ACTION_CHANGE_SOURCE without intent data.");
+ return;
+ }
+ ComponentName componentName = ComponentName.unflattenFromString(dataUri.toString());
+ if (componentName == null) {
+ Log.w(LOG_TAG, "Invalid ComponentName: " + dataUri);
+ return;
+ }
+ if (DBG) Log.d(LOG_TAG, "Switching to " + componentName);
+
+ ComponentName previous = mLaunchComponent;
+ if (!show(componentName, mAppSearchData, false)) {
+ Log.w(LOG_TAG, "Failed to switch to source " + componentName);
+ return;
+ }
+ pushPreviousComponent(previous);
+
+ String query = intent.getStringExtra(SearchManager.QUERY);
+ setUserQuery(query);
+ }
+
+ /**
+ * Handles {@link SearchManager#INTENT_ACTION_CURSOR_RESPOND}.
+ */
+ private void handleCursorRespondIntent(Intent intent) {
+ Cursor c = mSuggestionsAdapter.getCursor();
+ if (c != null) {
+ c.respond(intent.getExtras());
+ }
+ }
+
+ /**
+ * Saves the previous component that was searched, so that we can go
+ * back to it.
+ */
+ private void pushPreviousComponent(ComponentName componentName) {
+ if (mPreviousComponents == null) {
+ mPreviousComponents = new ArrayList<ComponentName>();
+ }
+ mPreviousComponents.add(componentName);
+ }
+
+ /**
+ * Pops the previous component off the stack and returns it.
+ *
+ * @return The component name, or <code>null</code> if there was
+ * no previous component.
+ */
+ private ComponentName popPreviousComponent() {
+ if (mPreviousComponents == null) {
+ return null;
+ }
+ int size = mPreviousComponents.size();
+ if (size == 0) {
+ return null;
+ }
+ return mPreviousComponents.remove(size - 1);
+ }
+
+ /**
+ * Goes back to the previous component that was searched, if any.
+ *
+ * @return <code>true</code> if there was a previous component that we could go back to.
+ */
+ private boolean backToPreviousComponent() {
+ ComponentName previous = popPreviousComponent();
+ if (previous == null) {
+ return false;
+ }
+ if (!show(previous, mAppSearchData, false)) {
+ Log.w(LOG_TAG, "Failed to switch to source " + previous);
+ return false;
+ }
+
+ // must touch text to trigger suggestions
+ // TODO: should this be the text as it was when the user left
+ // the source that we are now going back to?
+ String query = mSearchAutoComplete.getText().toString();
+ setUserQuery(query);
+
+ return true;
+ }
+
+ /**
* When a particular suggestion has been selected, perform the various lookups required
* to use the suggestion. This includes checking the cursor for suggestion-specific data,
* and/or falling back to the XML for defaults; It also creates REST style Uri data when
* the suggestion includes a data id.
*
- * NOTE: Return values are in member variables mSuggestionAction & mSuggestionData.
- *
* @param c The suggestions cursor, moved to the row of the user's selection
- * @param si The searchable activity's info record
+ * @param actionKey The key code of the action key that was pressed,
+ * or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
+ * @param actionMsg The message for the action key that was pressed,
+ * or <code>null</code> if none.
+ * @return An intent for the suggestion at the cursor's position.
*/
- void setupSuggestionIntent(Cursor c, SearchableInfo si) {
+ private Intent createIntentFromSuggestion(Cursor c, int actionKey, String actionMsg) {
try {
// use specific action if supplied, or default action if supplied, or fixed default
- mSuggestionAction = null;
- int mColumn = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_ACTION);
- if (mColumn >= 0) {
- final String action = c.getString(mColumn);
- if (action != null) {
- mSuggestionAction = action;
- }
+ String action = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_ACTION);
+ if (action == null) {
+ action = mSearchable.getSuggestIntentAction();
}
- if (mSuggestionAction == null) {
- mSuggestionAction = si.getSuggestIntentAction();
- }
- if (mSuggestionAction == null) {
- mSuggestionAction = Intent.ACTION_SEARCH;
+ if (action == null) {
+ action = Intent.ACTION_SEARCH;
}
// use specific data if supplied, or default data if supplied
- String data = null;
- mColumn = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA);
- if (mColumn >= 0) {
- final String rowData = c.getString(mColumn);
- if (rowData != null) {
- data = rowData;
- }
- }
+ String data = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA);
if (data == null) {
- data = si.getSuggestIntentData();
+ data = mSearchable.getSuggestIntentData();
}
-
// then, if an ID was provided, append it.
if (data != null) {
- mColumn = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
- if (mColumn >= 0) {
- final String id = c.getString(mColumn);
- if (id != null) {
- data = data + "/" + Uri.encode(id);
- }
+ String id = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
+ if (id != null) {
+ data = data + "/" + Uri.encode(id);
}
}
- mSuggestionData = (data == null) ? null : Uri.parse(data);
+ Uri dataUri = (data == null) ? null : Uri.parse(data);
+
+ String extraData = getColumnString(c, SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA);
- mSuggestionQuery = null;
- mColumn = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY);
- if (mColumn >= 0) {
- final String query = c.getString(mColumn);
- if (query != null) {
- mSuggestionQuery = query;
- }
- }
+ String query = getColumnString(c, SearchManager.SUGGEST_COLUMN_QUERY);
+
+ return createIntent(action, dataUri, query, extraData, actionKey, actionMsg);
} catch (RuntimeException e ) {
int rowNum;
try { // be really paranoid now
@@ -1224,10 +1215,49 @@
}
Log.w(LOG_TAG, "Search Suggestions cursor at row " + rowNum +
" returned exception" + e.toString());
+ return null;
}
}
/**
+ * Constructs an intent from the given information and the search dialog state.
+ *
+ * @param action Intent action.
+ * @param data Intent data, or <code>null</code>.
+ * @param query Intent query, or <code>null</code>.
+ * @param extraData Data for {@link SearchManager#EXTRA_DATA_KEY} or <code>null</code>.
+ * @param actionKey The key code of the action key that was pressed,
+ * or {@link KeyEvent#KEYCODE_UNKNOWN} if none.
+ * @param actionMsg The message for the action key that was pressed,
+ * or <code>null</code> if none.
+ * @return The intent.
+ */
+ private Intent createIntent(String action, Uri data, String query, String extraData,
+ int actionKey, String actionMsg) {
+ // Now build the Intent
+ Intent intent = new Intent(action);
+ if (data != null) {
+ intent.setData(data);
+ }
+ if (query != null) {
+ intent.putExtra(SearchManager.QUERY, query);
+ }
+ if (extraData != null) {
+ intent.putExtra(SearchManager.EXTRA_DATA_KEY, extraData);
+ }
+ if (mAppSearchData != null) {
+ intent.putExtra(SearchManager.APP_DATA, mAppSearchData);
+ }
+ if (actionKey != KeyEvent.KEYCODE_UNKNOWN) {
+ intent.putExtra(SearchManager.ACTION_KEY, actionKey);
+ intent.putExtra(SearchManager.ACTION_MSG, actionMsg);
+ }
+ // attempt to enforce security requirement (no 3rd-party intents)
+ intent.setComponent(mSearchable.mSearchActivity);
+ return intent;
+ }
+
+ /**
* For a given suggestion and a given cursor row, get the action message. If not provided
* by the specific row/column, also check for a single definition (for the action key).
*
@@ -1236,17 +1266,12 @@
*
* @return Returns a string, or null if no action key message for this suggestion
*/
- private String getActionKeyMessage(Cursor c, final SearchableInfo.ActionKeyInfo actionKey) {
+ private static String getActionKeyMessage(Cursor c, SearchableInfo.ActionKeyInfo actionKey) {
String result = null;
// check first in the cursor data, for a suggestion-specific message
final String column = actionKey.mSuggestActionMsgColumn;
if (column != null) {
- try {
- int colId = c.getColumnIndexOrThrow(column);
- result = c.getString(colId);
- } catch (RuntimeException e) {
- // OK - result is already null
- }
+ result = SuggestionsAdapter.getColumnString(c, column);
}
// If the cursor didn't give us a message, see if there's a single message defined
// for the actionkey (for all suggestions)
@@ -1257,343 +1282,178 @@
}
/**
- * Local subclass for AutoCompleteTextView
- *
- * This exists entirely to override the threshold method. Otherwise we just use the class
- * as-is.
+ * Local subclass for AutoCompleteTextView.
*/
public static class SearchAutoComplete extends AutoCompleteTextView {
+ private int mThreshold;
+ private SearchDialog mSearchDialog;
+
public SearchAutoComplete(Context context) {
super(null);
+ mThreshold = getThreshold();
}
public SearchAutoComplete(Context context, AttributeSet attrs) {
super(context, attrs);
+ mThreshold = getThreshold();
}
public SearchAutoComplete(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ mThreshold = getThreshold();
+ }
+
+ private void setSearchDialog(SearchDialog searchDialog) {
+ mSearchDialog = searchDialog;
+ }
+
+ @Override
+ public void setThreshold(int threshold) {
+ super.setThreshold(threshold);
+ mThreshold = threshold;
+ }
+
+ /**
+ * Returns true if the text field is empty, or contains only whitespace.
+ */
+ private boolean isEmpty() {
+ return TextUtils.getTrimmedLength(getText()) == 0;
}
/**
- * We never allow ACTV to automatically replace the text, since we use "jamSuggestionQuery"
- * to do that. There's no point in letting ACTV do this here, because in the search UI,
- * as soon as we click a suggestion, we're going to start shutting things down.
+ * Clears the entered text.
+ */
+ private void clear() {
+ setText("");
+ }
+
+ /**
+ * We override this method to avoid replacing the query box text
+ * when a suggestion is clicked.
*/
@Override
- public void replaceText(CharSequence text) {
+ protected void replaceText(CharSequence text) {
}
/**
- * We always return true, so that the effective threshold is "zero". This allows us
- * to provide "null" suggestions such as "just show me some recent entries".
+ * We override this method so that we can allow a threshold of zero, which ACTV does not.
*/
@Override
public boolean enoughToFilter() {
- return true;
+ return mThreshold <= 0 || super.enoughToFilter();
+ }
+
+ /**
+ * {@link AutoCompleteTextView#onKeyPreIme(int, KeyEvent)}) dismisses the drop-down on BACK,
+ * so we must override this method to modify the BACK behavior.
+ */
+ @Override
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ return mSearchDialog.handleBackKey(keyCode, event);
}
}
- /**
- * Support for AutoCompleteTextView-based suggestions
- */
- /**
- * This class provides the filtering-based interface to suggestions providers.
- * It is hardwired in a couple of places to support GoogleSearch - for example, it supports
- * two-line suggestions, but it does not support icons.
- */
- private static class SuggestionsAdapter extends SimpleCursorAdapter {
- private final String TAG = "SuggestionsAdapter";
-
- SearchableInfo mSearchable;
- private Resources mProviderResources;
-
- // These private variables are shared by the filter thread and must be protected
- private WeakReference<Cursor> mRecentCursor = new WeakReference<Cursor>(null);
- private boolean mNonUserQuery = false;
- private AutoCompleteTextView mParentView;
-
- public SuggestionsAdapter(Context context, SearchableInfo searchable,
- AutoCompleteTextView actv) {
- super(context, -1, null, null, null);
- mSearchable = searchable;
- mParentView = actv;
-
- // set up provider resources (gives us icons, etc.)
- Context activityContext = mSearchable.getActivityContext(mContext);
- Context providerContext = mSearchable.getProviderContext(mContext, activityContext);
- mProviderResources = providerContext.getResources();
+ protected boolean handleBackKey(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+ mSearchAutoComplete.dismissDropDown();
+ if (backToPreviousComponent()) {
+ return true;
+ }
+ if (!mSearchAutoComplete.isEmpty()) {
+ mSearchAutoComplete.clear();
+ return true;
+ }
+ cancel();
+ return true;
}
-
- /**
- * Set this field (temporarily!) to disable suggestions updating. This allows us
- * to change the string in the text view without changing the suggestions list.
- */
- public void setNonUserQuery(boolean nonUserQuery) {
- synchronized (this) {
- mNonUserQuery = nonUserQuery;
- }
- }
-
- public boolean getNonUserQuery() {
- synchronized (this) {
- return mNonUserQuery;
- }
- }
-
- /**
- * Use the search suggestions provider to obtain a live cursor. This will be called
- * in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions).
- * The results will be processed in the UI thread and changeCursor() will be called.
- *
- * In order to provide the Search Mgr functionality of seeing your query change as you
- * scroll through the list, we have to be able to jam new text into the string without
- * retriggering the suggestions. We do that here via the "nonUserQuery" flag. In that
- * case we simply return the existing cursor.
- *
- * TODO: Dianne suggests that this should simply be promoted into an AutoCompleteTextView
- * behavior (perhaps optionally).
- *
- * TODO: The "nonuserquery" logic has a race condition because it happens in another thread.
- * This also needs to be fixed.
- */
- @Override
- public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
- String query = (constraint == null) ? "" : constraint.toString();
- Cursor c = null;
- synchronized (this) {
- if (mNonUserQuery) {
- c = mRecentCursor.get();
- mNonUserQuery = false;
- }
- }
- if (c == null) {
- c = getSuggestions(mSearchable, query);
- synchronized (this) {
- mRecentCursor = new WeakReference<Cursor>(c);
- }
- }
- return c;
- }
-
- /**
- * Overriding changeCursor() allows us to change not only the cursor, but by sampling
- * the cursor's columns, the actual display characteristics of the list.
- */
- @Override
- public void changeCursor(Cursor c) {
-
- // first, check for various conditions that disqualify this cursor
- if ((c == null) || (c.getCount() == 0)) {
- // no cursor, or cursor with no data
- changeCursorAndColumns(null, null, null);
- if (c != null) {
- c.close();
- }
- return;
- }
-
- // check cursor before trying to create list views from it
- int colId = c.getColumnIndex("_id");
- int col1 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1);
- int col2 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2);
- int colIc1 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
- int colIc2 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2);
-
- boolean minimal = (colId >= 0) && (col1 >= 0);
- boolean hasIcons = (colIc1 >= 0) && (colIc2 >= 0);
- boolean has2Lines = col2 >= 0;
-
- if (minimal) {
- int layout;
- String[] from;
- int[] to;
-
- if (hasIcons) {
- if (has2Lines) {
- layout = com.android.internal.R.layout.search_dropdown_item_icons_2line;
- from = TWO_LINE_ICONS_FROM;
- to = TWO_LINE_ICONS_TO;
- } else {
- layout = com.android.internal.R.layout.search_dropdown_item_icons_1line;
- from = ONE_LINE_ICONS_FROM;
- to = ONE_LINE_ICONS_TO;
- }
- } else {
- if (has2Lines) {
- layout = com.android.internal.R.layout.search_dropdown_item_2line;
- from = TWO_LINE_FROM;
- to = TWO_LINE_TO;
- } else {
- layout = com.android.internal.R.layout.search_dropdown_item_1line;
- from = ONE_LINE_FROM;
- to = ONE_LINE_TO;
- }
- }
- // Force the underlying ListView to discard and reload all layouts
- // (Note, this should be optimized for cases where layout/cursor remain same)
- mParentView.resetListAndClearViews();
- // Now actually set up the cursor, columns, and the list view
- changeCursorAndColumns(c, from, to);
- setViewResource(layout);
- } else {
- // Provide some help for developers instead of just silently discarding
- Log.w(LOG_TAG, "Suggestions cursor discarded due to missing required columns.");
- changeCursorAndColumns(null, null, null);
- c.close();
- }
- if ((colIc1 >= 0) != (colIc2 >= 0)) {
- Log.w(LOG_TAG, "Suggestion icon column(s) discarded, must be 0 or 2 columns.");
- }
- }
-
- /**
- * Overriding this allows us to write the selected query back into the box.
- * NOTE: This is a vastly simplified version of SearchDialog.jamQuery() and does
- * not universally support the search API. But it is sufficient for Google Search.
- */
- @Override
- public CharSequence convertToString(Cursor cursor) {
- CharSequence result = null;
- if (cursor != null) {
- int column = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_QUERY);
- if (column >= 0) {
- final String query = cursor.getString(column);
- if (query != null) {
- result = query;
- }
- }
- }
- return result;
- }
-
- /**
- * Get the query cursor for the search suggestions.
- *
- * TODO this is functionally identical to the version in SearchDialog.java. Perhaps it
- * could be hoisted into SearchableInfo or some other shared spot.
- *
- * @param query The search text entered (so far)
- * @return Returns a cursor with suggestions, or null if no suggestions
- */
- private Cursor getSuggestions(final SearchableInfo searchable, final String query) {
- Cursor cursor = null;
- if (searchable.getSuggestAuthority() != null) {
- try {
- StringBuilder uriStr = new StringBuilder("content://");
- uriStr.append(searchable.getSuggestAuthority());
-
- // if content path provided, insert it now
- final String contentPath = searchable.getSuggestPath();
- if (contentPath != null) {
- uriStr.append('/');
- uriStr.append(contentPath);
- }
-
- // append standard suggestion query path
- uriStr.append('/' + SearchManager.SUGGEST_URI_PATH_QUERY);
-
- // inject query, either as selection args or inline
- String[] selArgs = null;
- if (searchable.getSuggestSelection() != null) { // use selection if provided
- selArgs = new String[] {query};
- } else {
- uriStr.append('/'); // no sel, use REST pattern
- uriStr.append(Uri.encode(query));
- }
-
- // finally, make the query
- cursor = mContext.getContentResolver().query(
- Uri.parse(uriStr.toString()), null,
- searchable.getSuggestSelection(), selArgs,
- null);
- } catch (RuntimeException e) {
- Log.w(TAG, "Search Suggestions query returned exception " + e.toString());
- cursor = null;
- }
- }
-
- return cursor;
- }
-
- /**
- * Overriding this allows us to affect the way that an icon is loaded. Specifically,
- * we can be more controlling about the resource path (and allow icons to come from other
- * packages).
- *
- * TODO: This is 100% identical to the version in SearchDialog.java
- *
- * @param v ImageView to receive an image
- * @param value the value retrieved from the cursor
- */
- @Override
- public void setViewImage(ImageView v, String value) {
- int resID;
- Drawable img = null;
-
- try {
- resID = Integer.parseInt(value);
- if (resID != 0) {
- img = mProviderResources.getDrawable(resID);
- }
- } catch (NumberFormatException nfe) {
- // img = null;
- } catch (NotFoundException e2) {
- // img = null;
- }
-
- // finally, set the image to whatever we've gotten
- v.setImageDrawable(img);
- }
-
- /**
- * This method is overridden purely to provide a bit of protection against
- * flaky content providers.
- *
- * TODO: This is 100% identical to the version in SearchDialog.java
- *
- * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
- */
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- try {
- return super.getView(position, convertView, parent);
- } catch (RuntimeException e) {
- Log.w(TAG, "Search Suggestions cursor returned exception " + e.toString());
- // what can I return here?
- View v = newView(mContext, mCursor, parent);
- if (v != null) {
- TextView tv = (TextView) v.findViewById(com.android.internal.R.id.text1);
- tv.setText(e.toString());
- }
- return v;
- }
- }
-
+ return false;
}
/**
* Implements OnItemClickListener
*/
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- // Log.d(LOG_TAG, "onItemClick() position " + position);
- launchSuggestion(mSuggestionsAdapter, position);
+ if (DBG) Log.d(LOG_TAG, "onItemClick() position " + position);
+ launchSuggestion(position);
}
-
+
/**
* Implements OnItemSelectedListener
*/
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- // Log.d(LOG_TAG, "onItemSelected() position " + position);
- jamSuggestionQuery(true, parent, position);
+ if (DBG) Log.d(LOG_TAG, "onItemSelected() position " + position);
+ // A suggestion has been selected, rewrite the query if possible,
+ // otherwise the restore the original query.
+ if (REWRITE_QUERIES) {
+ rewriteQueryFromSuggestion(position);
+ }
}
/**
* Implements OnItemSelectedListener
*/
public void onNothingSelected(AdapterView<?> parent) {
- // Log.d(LOG_TAG, "onNothingSelected()");
+ if (DBG) Log.d(LOG_TAG, "onNothingSelected()");
+ }
+
+ /**
+ * Query rewriting.
+ */
+
+ private void rewriteQueryFromSuggestion(int position) {
+ Cursor c = mSuggestionsAdapter.getCursor();
+ if (c == null) {
+ return;
+ }
+ if (c.moveToPosition(position)) {
+ // Get the new query from the suggestion.
+ CharSequence newQuery = mSuggestionsAdapter.convertToString(c);
+ if (newQuery != null) {
+ // The suggestion rewrites the query.
+ if (DBG) Log.d(LOG_TAG, "Rewriting query to '" + newQuery + "'");
+ // Update the text field, without getting new suggestions.
+ setQuery(newQuery);
+ } else {
+ // The suggestion does not rewrite the query, restore the user's query.
+ if (DBG) Log.d(LOG_TAG, "Suggestion gives no rewrite, restoring user query.");
+ restoreUserQuery();
+ }
+ } else {
+ // We got a bad position, restore the user's query.
+ Log.w(LOG_TAG, "Bad suggestion position: " + position);
+ restoreUserQuery();
+ }
+ }
+
+ /**
+ * Restores the query entered by the user if needed.
+ */
+ private void restoreUserQuery() {
+ if (DBG) Log.d(LOG_TAG, "Restoring query to '" + mUserQuery + "'");
+ setQuery(mUserQuery);
+ }
+
+ /**
+ * Sets the text in the query box, without updating the suggestions.
+ */
+ private void setQuery(CharSequence query) {
+ mSearchAutoComplete.setText(query, false);
+ if (query != null) {
+ mSearchAutoComplete.setSelection(query.length());
+ }
+ }
+
+ /**
+ * Sets the text in the query box, updating the suggestions.
+ */
+ private void setUserQuery(String query) {
+ if (query == null) {
+ query = "";
+ }
+ mUserQuery = query;
+ mSearchAutoComplete.setText(query);
+ mSearchAutoComplete.setSelection(query.length());
}
/**
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index ecdd3f8..3e9f3dd 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -17,12 +17,17 @@
package android.app;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
+import android.os.RemoteException;
import android.os.ServiceManager;
+import android.server.search.SearchableInfo;
import android.view.KeyEvent;
/**
@@ -439,20 +444,18 @@
*
* <tr><th>{@link #SUGGEST_COLUMN_ICON_1}</th>
* <td>If your cursor includes this column, then all suggestions will be provided in an
- * icons+text format. This value should be a reference (resource ID) of the icon to
+ * icons+text format. This value should be a reference to the icon to
* draw on the left side, or it can be null or zero to indicate no icon in this row.
- * You must provide both cursor columns, or neither.
* </td>
- * <td align="center">No, but required if you also have {@link #SUGGEST_COLUMN_ICON_2}</td>
+ * <td align="center">No.</td>
* </tr>
*
* <tr><th>{@link #SUGGEST_COLUMN_ICON_2}</th>
* <td>If your cursor includes this column, then all suggestions will be provided in an
- * icons+text format. This value should be a reference (resource ID) of the icon to
+ * icons+text format. This value should be a reference to the icon to
* draw on the right side, or it can be null or zero to indicate no icon in this row.
- * You must provide both cursor columns, or neither.
* </td>
- * <td align="center">No, but required if you also have {@link #SUGGEST_COLUMN_ICON_1}</td>
+ * <td align="center">No.</td>
* </tr>
*
* <tr><th>{@link #SUGGEST_COLUMN_INTENT_ACTION}</th>
@@ -1155,6 +1158,13 @@
public final static String ACTION_KEY = "action_key";
/**
+ * Intent extra data key: This key will be used for the extra populated by the
+ * {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column.
+ * {@hide}
+ */
+ public final static String EXTRA_DATA_KEY = "intent_extra_data_key";
+
+ /**
* Intent extra data key: Use this key with Intent.ACTION_SEARCH and
* {@link android.content.Intent#getStringExtra content.Intent.getStringExtra()}
* to obtain the action message that was defined for a particular search action key and/or
@@ -1195,21 +1205,59 @@
public final static String SUGGEST_COLUMN_TEXT_2 = "suggest_text_2";
/**
* Column name for suggestions cursor. <i>Optional.</i> If your cursor includes this column,
- * then all suggestions will be provided in format that includes space for two small icons,
+ * then all suggestions will be provided in a format that includes space for two small icons,
* one at the left and one at the right of each suggestion. The data in the column must
- * be a a resource ID for the icon you wish to have displayed. If you include this column,
- * you must also include {@link #SUGGEST_COLUMN_ICON_2}.
+ * be a resource ID of a drawable, or a URI in one of the following formats:
+ *
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
+ * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+ * </ul>
+ *
+ * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
+ * for more information on these schemes.
*/
public final static String SUGGEST_COLUMN_ICON_1 = "suggest_icon_1";
/**
* Column name for suggestions cursor. <i>Optional.</i> If your cursor includes this column,
- * then all suggestions will be provided in format that includes space for two small icons,
+ * then all suggestions will be provided in a format that includes space for two small icons,
* one at the left and one at the right of each suggestion. The data in the column must
- * be a a resource ID for the icon you wish to have displayed. If you include this column,
- * you must also include {@link #SUGGEST_COLUMN_ICON_1}.
+ * be a resource ID of a drawable, or a URI in one of the following formats:
+ *
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
+ * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+ * </ul>
+ *
+ * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
+ * for more information on these schemes.
*/
public final static String SUGGEST_COLUMN_ICON_2 = "suggest_icon_2";
/**
+ * Column name for suggestions cursor. <i>Optional.</i> If your cursor includes this column,
+ * then all suggestions will be provided in a format that includes space for two small icons,
+ * one at the left and one at the right of each suggestion. The data in the column must
+ * be a blob that contains a bitmap.
+ *
+ * This column overrides any icon provided in the {@link #SUGGEST_COLUMN_ICON_1} column.
+ *
+ * @hide
+ */
+ public final static String SUGGEST_COLUMN_ICON_1_BITMAP = "suggest_icon_1_bitmap";
+ /**
+ * Column name for suggestions cursor. <i>Optional.</i> If your cursor includes this column,
+ * then all suggestions will be provided in a format that includes space for two small icons,
+ * one at the left and one at the right of each suggestion. The data in the column must
+ * be a blob that contains a bitmap.
+ *
+ * This column overrides any icon provided in the {@link #SUGGEST_COLUMN_ICON_2} column.
+ *
+ * @hide
+ */
+ public final static String SUGGEST_COLUMN_ICON_2_BITMAP = "suggest_icon_2_bitmap";
+ /**
* Column name for suggestions cursor. <i>Optional.</i> If this column exists <i>and</i>
* this element exists at the given row, this is the action that will be used when
* forming the suggestion's intent. If the element is not provided, the action will be taken
@@ -1230,6 +1278,14 @@
*/
public final static String SUGGEST_COLUMN_INTENT_DATA = "suggest_intent_data";
/**
+ * Column name for suggestions cursor. <i>Optional.</i> This column allows suggestions
+ * to provide additional arbitrary data which will be included as an extra under the key
+ * {@link #EXTRA_DATA_KEY}.
+ *
+ * @hide pending API council approval
+ */
+ public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
+ /**
* Column name for suggestions cursor. <i>Optional.</i> If this column exists <i>and</i>
* this element exists at the given row, then "/" and this value will be appended to the data
* field in the Intent. This should only be used if the data field has already been set to an
@@ -1244,6 +1300,54 @@
*/
public final static String SUGGEST_COLUMN_QUERY = "suggest_intent_query";
+ /**
+ * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
+ * the search dialog will switch to a different suggestion source when the
+ * suggestion is clicked.
+ *
+ * {@link #SUGGEST_COLUMN_INTENT_DATA} must contain
+ * the flattened {@link ComponentName} of the activity which is to be searched.
+ *
+ * TODO: Should {@link #SUGGEST_COLUMN_INTENT_DATA} instead contain a URI in the format
+ * used by {@link android.provider.Applications}?
+ *
+ * TODO: This intent should be protected by the same permission that we use
+ * for replacing the global search provider.
+ *
+ * The query text field will be set to the value of {@link #SUGGEST_COLUMN_QUERY}.
+ *
+ * @hide Pending API council approval.
+ */
+ public final static String INTENT_ACTION_CHANGE_SEARCH_SOURCE
+ = "android.search.action.CHANGE_SEARCH_SOURCE";
+
+ /**
+ * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
+ * the search dialog will call {@link Cursor#respond(Bundle)} when the
+ * suggestion is clicked.
+ *
+ * The {@link Bundle} argument will be constructed
+ * in the same way as the "extra" bundle included in an Intent constructed
+ * from the suggestion.
+ *
+ * @hide Pending API council approval.
+ */
+ public final static String INTENT_ACTION_CURSOR_RESPOND
+ = "android.search.action.CURSOR_RESPOND";
+
+ /**
+ * Intent action for starting the global search settings activity.
+ * The global search provider should handle this intent.
+ *
+ * @hide Pending API council approval.
+ */
+ public final static String INTENT_ACTION_SEARCH_SETTINGS
+ = "android.search.action.SEARCH_SETTINGS";
+
+ /**
+ * Reference to the shared system search service.
+ */
+ private static ISearchManager sService = getSearchManagerService();
private final Context mContext;
private final Handler mHandler;
@@ -1257,12 +1361,6 @@
mContext = context;
mHandler = handler;
}
- private static ISearchManager mService;
-
- static {
- mService = ISearchManager.Stub.asInterface(
- ServiceManager.getService(Context.SEARCH_SERVICE));
- }
/**
* Launch search UI.
@@ -1459,5 +1557,93 @@
mSearchDialog.onConfigurationChanged(newConfig);
}
}
-
+
+ private static ISearchManager getSearchManagerService() {
+ return ISearchManager.Stub.asInterface(
+ ServiceManager.getService(Context.SEARCH_SERVICE));
+ }
+
+ /**
+ * Gets information about a searchable activity. This method is static so that it can
+ * be used from non-Activity contexts.
+ *
+ * @param componentName The activity to get searchable information for.
+ * @param globalSearch If <code>false</code>, return information about the given activity.
+ * If <code>true</code>, return information about the global search activity.
+ * @return Searchable information, or <code>null</code> if the activity is not searchable.
+ *
+ * @hide because SearchableInfo is not part of the API.
+ */
+ public static SearchableInfo getSearchableInfo(ComponentName componentName,
+ boolean globalSearch) {
+ try {
+ return sService.getSearchableInfo(componentName, globalSearch);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Checks whether the given searchable is the default searchable.
+ *
+ * @hide because SearchableInfo is not part of the API.
+ */
+ public static boolean isDefaultSearchable(SearchableInfo searchable) {
+ SearchableInfo defaultSearchable = SearchManager.getSearchableInfo(null, true);
+ return defaultSearchable != null
+ && defaultSearchable.mSearchActivity.equals(searchable.mSearchActivity);
+ }
+
+ /**
+ * Gets a cursor with search suggestions. This method is static so that it can
+ * be used from non-Activity context.
+ *
+ * @param searchable Information about how to get the suggestions.
+ * @param query The search text entered (so far).
+ * @return a cursor with suggestions, or <code>null</null> the suggestion query failed.
+ *
+ * @hide because SearchableInfo is not part of the API.
+ */
+ public static Cursor getSuggestions(Context context, SearchableInfo searchable, String query) {
+ if (searchable == null) {
+ return null;
+ }
+
+ String authority = searchable.getSuggestAuthority();
+ if (authority == null) {
+ return null;
+ }
+
+ Uri.Builder uriBuilder = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority);
+
+ // if content path provided, insert it now
+ final String contentPath = searchable.getSuggestPath();
+ if (contentPath != null) {
+ uriBuilder.appendEncodedPath(contentPath);
+ }
+
+ // append standard suggestion query path
+ uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
+
+ // get the query selection, may be null
+ String selection = searchable.getSuggestSelection();
+ // inject query, either as selection args or inline
+ String[] selArgs = null;
+ if (selection != null) { // use selection if provided
+ selArgs = new String[] { query };
+ } else { // no selection, use REST pattern
+ uriBuilder.appendPath(query);
+ }
+
+ Uri uri = uriBuilder
+ .query("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
+ .fragment("") // TODO: Remove, workaround for a bug in Uri.writeToParcel()
+ .build();
+
+ // finally, make the query
+ return context.getContentResolver().query(uri, null, selection, selArgs, null);
+ }
+
}
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
new file mode 100644
index 0000000..0513fe1
--- /dev/null
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -0,0 +1,344 @@
+/*
+ * 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 android.app;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources.NotFoundException;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.server.search.SearchableInfo;
+import android.text.Html;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CursorAdapter;
+import android.widget.ImageView;
+import android.widget.ResourceCursorAdapter;
+import android.widget.TextView;
+
+import java.io.FileNotFoundException;
+import java.util.WeakHashMap;
+
+/**
+ * Provides the contents for the suggestion drop-down list.in {@link SearchDialog}.
+ *
+ * @hide
+ */
+class SuggestionsAdapter extends ResourceCursorAdapter {
+ private static final boolean DBG = false;
+ private static final String LOG_TAG = "SuggestionsAdapter";
+
+ private SearchableInfo mSearchable;
+ private Context mProviderContext;
+ private WeakHashMap<String, Drawable> mOutsideDrawablesCache;
+
+ // Cached column indexes, updated when the cursor changes.
+ private int mFormatCol;
+ private int mText1Col;
+ private int mText2Col;
+ private int mIconName1Col;
+ private int mIconName2Col;
+ private int mIconBitmap1Col;
+ private int mIconBitmap2Col;
+
+ public SuggestionsAdapter(Context context, SearchableInfo searchable,
+ WeakHashMap<String, Drawable> outsideDrawablesCache) {
+ super(context,
+ com.android.internal.R.layout.search_dropdown_item_icons_2line,
+ null, // no initial cursor
+ true); // auto-requery
+ mSearchable = searchable;
+
+ // set up provider resources (gives us icons, etc.)
+ Context activityContext = mSearchable.getActivityContext(mContext);
+ mProviderContext = mSearchable.getProviderContext(mContext, activityContext);
+
+ mOutsideDrawablesCache = outsideDrawablesCache;
+ }
+
+ /**
+ * Overridden to always return <code>false</code>, since we cannot be sure that
+ * suggestion sources return stable IDs.
+ */
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ /**
+ * Use the search suggestions provider to obtain a live cursor. This will be called
+ * in a worker thread, so it's OK if the query is slow (e.g. round trip for suggestions).
+ * The results will be processed in the UI thread and changeCursor() will be called.
+ */
+ @Override
+ public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
+ if (DBG) Log.d(LOG_TAG, "runQueryOnBackgroundThread(" + constraint + ")");
+ String query = (constraint == null) ? "" : constraint.toString();
+ try {
+ return SearchManager.getSuggestions(mContext, mSearchable, query);
+ } catch (RuntimeException e) {
+ Log.w(LOG_TAG, "Search suggestions query threw an exception.", e);
+ return null;
+ }
+ }
+
+ /**
+ * Cache columns.
+ */
+ @Override
+ public void changeCursor(Cursor c) {
+ if (DBG) Log.d(LOG_TAG, "changeCursor(" + c + ")");
+ super.changeCursor(c);
+ if (c != null) {
+ mFormatCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_FORMAT);
+ mText1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1);
+ mText2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2);
+ mIconName1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1);
+ mIconName2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2);
+ mIconBitmap1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1_BITMAP);
+ mIconBitmap2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2_BITMAP);
+ }
+ }
+
+ /**
+ * Tags the view with cached child view look-ups.
+ */
+ @Override
+ public View newView(Context context, Cursor cursor, ViewGroup parent) {
+ View v = super.newView(context, cursor, parent);
+ v.setTag(new ChildViewCache(v));
+ return v;
+ }
+
+ /**
+ * Cache of the child views of drop-drown list items, to avoid looking up the children
+ * each time the contents of a list item are changed.
+ */
+ private final static class ChildViewCache {
+ public final TextView mText1;
+ public final TextView mText2;
+ public final ImageView mIcon1;
+ public final ImageView mIcon2;
+
+ public ChildViewCache(View v) {
+ mText1 = (TextView) v.findViewById(com.android.internal.R.id.text1);
+ mText2 = (TextView) v.findViewById(com.android.internal.R.id.text2);
+ mIcon1 = (ImageView) v.findViewById(com.android.internal.R.id.icon1);
+ mIcon2 = (ImageView) v.findViewById(com.android.internal.R.id.icon2);
+ }
+ }
+
+ @Override
+ public void bindView(View view, Context context, Cursor cursor) {
+ ChildViewCache views = (ChildViewCache) view.getTag();
+ String format = cursor.getString(mFormatCol);
+ boolean isHtml = "html".equals(format);
+ setViewText(cursor, views.mText1, mText1Col, isHtml);
+ setViewText(cursor, views.mText2, mText2Col, isHtml);
+ setViewIcon(cursor, views.mIcon1, mIconBitmap1Col, mIconName1Col);
+ setViewIcon(cursor, views.mIcon2, mIconBitmap2Col, mIconName2Col);
+ }
+
+ private void setViewText(Cursor cursor, TextView v, int textCol, boolean isHtml) {
+ if (v == null) {
+ return;
+ }
+ CharSequence text = null;
+ if (textCol >= 0) {
+ String str = cursor.getString(textCol);
+ text = (str != null && isHtml) ? Html.fromHtml(str) : str;
+ }
+ // Set the text even if it's null, since we need to clear any previous text.
+ v.setText(text);
+
+ if (TextUtils.isEmpty(text)) {
+ v.setVisibility(View.GONE);
+ } else {
+ v.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void setViewIcon(Cursor cursor, ImageView v, int iconBitmapCol, int iconNameCol) {
+ if (v == null) {
+ return;
+ }
+ Drawable drawable = null;
+ // First try the bitmap column
+ if (iconBitmapCol >= 0) {
+ byte[] data = cursor.getBlob(iconBitmapCol);
+ if (data != null) {
+ Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+ if (bitmap != null) {
+ drawable = new BitmapDrawable(bitmap);
+ }
+ }
+ }
+ // If there was no bitmap, try the icon resource column.
+ if (drawable == null && iconNameCol >= 0) {
+ String value = cursor.getString(iconNameCol);
+ drawable = getDrawableFromResourceValue(value);
+ }
+ // Set the icon even if the drawable is null, since we need to clear any
+ // previous icon.
+ v.setImageDrawable(drawable);
+
+ if (drawable == null) {
+ v.setVisibility(View.GONE);
+ } else {
+ v.setVisibility(View.VISIBLE);
+ }
+ }
+
+ /**
+ * Gets the text to show in the query field when a suggestion is selected.
+ *
+ * @param cursor The Cursor to read the suggestion data from. The Cursor should already
+ * be moved to the suggestion that is to be read from.
+ * @return The text to show, or <code>null</code> if the query should not be
+ * changed when selecting this suggestion.
+ */
+ @Override
+ public CharSequence convertToString(Cursor cursor) {
+ if (cursor == null) {
+ return null;
+ }
+
+ String query = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_QUERY);
+ if (query != null) {
+ return query;
+ }
+
+ if (mSearchable.mQueryRewriteFromData) {
+ String data = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_INTENT_DATA);
+ if (data != null) {
+ return data;
+ }
+ }
+
+ if (mSearchable.mQueryRewriteFromText) {
+ String text1 = getColumnString(cursor, SearchManager.SUGGEST_COLUMN_TEXT_1);
+ if (text1 != null) {
+ return text1;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * This method is overridden purely to provide a bit of protection against
+ * flaky content providers.
+ *
+ * @see android.widget.ListAdapter#getView(int, View, ViewGroup)
+ */
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ try {
+ return super.getView(position, convertView, parent);
+ } catch (RuntimeException e) {
+ Log.w(LOG_TAG, "Search suggestions cursor threw exception.", e);
+ // Put exception string in item title
+ View v = newView(mContext, mCursor, parent);
+ if (v != null) {
+ ChildViewCache views = (ChildViewCache) v.getTag();
+ TextView tv = views.mText1;
+ tv.setText(e.toString());
+ }
+ return v;
+ }
+ }
+
+ /**
+ * Gets a drawable given a value provided by a suggestion provider.
+ *
+ * This value could be just the string value of a resource id
+ * (e.g., "2130837524"), in which case we will try to retrieve a drawable from
+ * the provider's resources. If the value is not an integer, it is
+ * treated as a Uri and opened with
+ * {@link ContentResolver#openOutputStream(android.net.Uri, String)}.
+ *
+ * All resources and URIs are read using the suggestion provider's context.
+ *
+ * If the string is not formatted as expected, or no drawable can be found for
+ * the provided value, this method returns null.
+ *
+ * @param drawableId a string like "2130837524",
+ * "android.resource://com.android.alarmclock/2130837524",
+ * or "content://contacts/photos/253".
+ * @return a Drawable, or null if none found
+ */
+ private Drawable getDrawableFromResourceValue(String drawableId) {
+ if (drawableId == null || drawableId.length() == 0 || "0".equals(drawableId)) {
+ return null;
+ }
+
+ // First, check the cache.
+ Drawable drawable = mOutsideDrawablesCache.get(drawableId);
+ if (drawable != null) return drawable;
+
+ try {
+ // Not cached, try using it as a plain resource ID in the provider's context.
+ int resourceId = Integer.parseInt(drawableId);
+ drawable = mProviderContext.getResources().getDrawable(resourceId);
+ } catch (NumberFormatException nfe) {
+ // The id was not an integer resource id.
+ // Let the ContentResolver handle content, android.resource and file URIs.
+ try {
+ Uri uri = Uri.parse(drawableId);
+ drawable = Drawable.createFromStream(
+ mProviderContext.getContentResolver().openInputStream(uri),
+ null);
+ } catch (FileNotFoundException fnfe) {
+ // drawable = null;
+ }
+
+ // If we got a drawable for this resource id, then stick it in the
+ // map so we don't do this lookup again.
+ if (drawable != null) {
+ mOutsideDrawablesCache.put(drawableId, drawable);
+ }
+ } catch (NotFoundException nfe) {
+ // Resource could not be found
+ // drawable = null;
+ }
+
+ return drawable;
+ }
+
+ /**
+ * Gets the value of a string column by name.
+ *
+ * @param cursor Cursor to read the value from.
+ * @param columnName The name of the column to read.
+ * @return The value of the given column, or <code>null</null>
+ * if the cursor does not contain the given column.
+ */
+ public static String getColumnString(Cursor cursor, String columnName) {
+ int col = cursor.getColumnIndex(columnName);
+ if (col == -1) {
+ return null;
+ }
+ return cursor.getString(col);
+ }
+
+}
diff --git a/core/java/android/provider/Applications.java b/core/java/android/provider/Applications.java
new file mode 100644
index 0000000..0b0ce58
--- /dev/null
+++ b/core/java/android/provider/Applications.java
@@ -0,0 +1,82 @@
+/*
+ * 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 android.provider;
+
+import android.app.SearchManager;
+import android.net.Uri;
+import android.widget.SimpleCursorAdapter;
+
+/**
+ * <p>The Applications provider gives information about installed applications.</p>
+ *
+ * <p>This provider provides the following columns:
+ *
+ * <table border="2" width="85%" align="center" frame="hsides" rules="rows">
+ *
+ * <thead>
+ * <tr><th>Column Name</th> <th>Description</th> </tr>
+ * </thead>
+ *
+ * <tbody>
+ * <tr><th>{@link SearchManager#SUGGEST_COLUMN_TEXT_1}</th>
+ * <td>The application name.</td>
+ * </tr>
+ *
+ * <tr><th>{@link SearchManager#SUGGEST_COLUMN_INTENT_COMPONENT}</th>
+ * <td>The component to be used when forming the intent.</td>
+ * </tr>
+ *
+ * <tr><th>{@link SearchManager#SUGGEST_COLUMN_ICON_1}</th>
+ * <td>The application's icon resource id, prepended by its package name and
+ * separated by a colon, e.g., "com.android.alarmclock:2130837524". The
+ * package name is required for an activity interpreting this value to
+ * be able to correctly access the icon drawable, for example, in an override of
+ * {@link SimpleCursorAdapter#setViewImage(android.widget.ImageView, String)}.</td>
+ * </tr>
+ *
+ * <tr><th>{@link SearchManager#SUGGEST_COLUMN_ICON_2}</th>
+ * <td><i>Unused - column provided to conform to the {@link SearchManager} stipulation
+ * that all providers provide either both or neither of
+ * {@link SearchManager#SUGGEST_COLUMN_ICON_1} and
+ * {@link SearchManager#SUGGEST_COLUMN_ICON_2}.</td>
+ * </tr>
+ *
+ * @hide pending API council approval - should be unhidden at the same time as
+ * {@link SearchManager#SUGGEST_COLUMN_INTENT_COMPONENT}
+ */
+public class Applications {
+ private static final String TAG = "Applications";
+
+ /**
+ * The content authority for this provider.
+ *
+ * @hide
+ */
+ public static final String AUTHORITY = "applications";
+
+ /**
+ * The content:// style URL for this provider
+ *
+ * @hide
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
+
+ /**
+ * no public constructor since this is a utility class
+ */
+ private Applications() {}
+}
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index fe15553..eaace6b 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -22,8 +22,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Handler;
-import android.util.Config;
/**
* This is a simplified version of the Search Manager service. It no longer handles
@@ -36,7 +36,6 @@
// general debugging support
private static final String TAG = "SearchManagerService";
private static final boolean DEBUG = false;
- private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
// configuration choices
private static final boolean IMMEDIATE_SEARCHABLES_UPDATE = true;
@@ -45,9 +44,10 @@
private final Context mContext;
private final Handler mHandler;
private boolean mSearchablesDirty;
+ private Searchables mSearchables;
/**
- * Initialize the Search Manager service in the provided system context.
+ * Initializes the Search Manager service in the provided system context.
* Only one instance of this object should be created!
*
* @param context to use for accessing DB, window manager, etc.
@@ -55,6 +55,8 @@
public SearchManagerService(Context context) {
mContext = context;
mHandler = new Handler();
+ mSearchablesDirty = true;
+ mSearchables = new Searchables(context);
// Setup the infrastructure for updating and maintaining the list
// of searchable activities.
@@ -64,7 +66,6 @@
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
- mSearchablesDirty = true;
// After startup settles down, preload the searchables list,
// which will reduce the delay when the search UI is invoked.
@@ -109,34 +110,41 @@
};
/**
- * Update the list of searchables, either at startup or in response to
+ * Updates the list of searchables, either at startup or in response to
* a package add/remove broadcast message.
*/
private void updateSearchables() {
- SearchableInfo.buildSearchableList(mContext);
+ mSearchables.buildSearchableList();
mSearchablesDirty = false;
- // TODO This is a hack. This shouldn't be hardcoded here, it's probably
- // a policy.
-// ComponentName defaultSearch = new ComponentName(
-// "com.android.contacts",
-// "com.android.contacts.ContactsListActivity" );
- ComponentName defaultSearch = new ComponentName(
- "com.android.googlesearch",
- "com.android.googlesearch.GoogleSearch" );
- SearchableInfo.setDefaultSearchable(mContext, defaultSearch);
+ // TODO SearchableInfo should be the source of truth about whether a searchable exists.
+ // As it stands, if the package exists but is misconfigured in some way, then this
+ // would fail, and needs to be fixed.
+ ComponentName defaultSearch = new ComponentName(
+ "com.android.globalsearch",
+ "com.android.globalsearch.GlobalSearch");
+
+ try {
+ mContext.getPackageManager().getActivityInfo(defaultSearch, 0);
+ } catch (NameNotFoundException e) {
+ defaultSearch = new ComponentName(
+ "com.android.googlesearch",
+ "com.android.googlesearch.GoogleSearch");
+ }
+
+ mSearchables.setDefaultSearchable(defaultSearch);
}
/**
- * Return the searchableinfo for a given activity
+ * Returns the SearchableInfo for a given activity
*
* @param launchActivity The activity from which we're launching this search.
- * @return Returns a SearchableInfo record describing the parameters of the search,
- * or null if no searchable metadata was available.
* @param globalSearch If false, this will only launch the search that has been specifically
* defined by the application (which is usually defined as a local search). If no default
* search is defined in the current application or activity, no search will be launched.
* If true, this will always launch a platform-global (e.g. web-based) search instead.
+ * @return Returns a SearchableInfo record describing the parameters of the search,
+ * or null if no searchable metadata was available.
*/
public SearchableInfo getSearchableInfo(ComponentName launchActivity, boolean globalSearch) {
// final check. however we should try to avoid this, because
@@ -146,11 +154,12 @@
}
SearchableInfo si = null;
if (globalSearch) {
- si = SearchableInfo.getDefaultSearchable();
+ si = mSearchables.getDefaultSearchable();
} else {
- si = SearchableInfo.getSearchableInfo(mContext, launchActivity);
+ si = mSearchables.getSearchableInfo(launchActivity);
}
return si;
}
+
}
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index 0c04839..22abd1b 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -21,14 +21,11 @@
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
-import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.InputType;
@@ -38,9 +35,6 @@
import android.view.inputmethod.EditorInfo;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
public final class SearchableInfo implements Parcelable {
@@ -50,19 +44,12 @@
// set this flag to 1 to prevent any apps from providing suggestions
final static int DBG_INHIBIT_SUGGESTIONS = 0;
- // static strings used for XML lookups, etc.
+ // static strings used for XML lookups.
// TODO how should these be documented for the developer, in a more structured way than
// the current long wordy javadoc in SearchManager.java ?
- private static final String MD_LABEL_DEFAULT_SEARCHABLE = "android.app.default_searchable";
private static final String MD_LABEL_SEARCHABLE = "android.app.searchable";
- private static final String MD_SEARCHABLE_SYSTEM_SEARCH = "*";
private static final String MD_XML_ELEMENT_SEARCHABLE = "searchable";
private static final String MD_XML_ELEMENT_SEARCHABLE_ACTION_KEY = "actionkey";
-
- // class maintenance and general shared data
- private static HashMap<ComponentName, SearchableInfo> sSearchablesMap = null;
- private static ArrayList<SearchableInfo> sSearchablesList = null;
- private static SearchableInfo sDefaultSearchable = null;
// true member variables - what we know about the searchability
// TO-DO replace public with getters
@@ -86,7 +73,6 @@
private String mSuggestIntentData = null;
private ActionKeyInfo mActionKeyList = null;
private String mSuggestProviderPackage = null;
- private Context mCacheActivityContext = null; // use during setup only - don't hold memory!
// Flag values for Searchable_voiceSearchMode
private static int VOICE_SEARCH_SHOW_BUTTON = 1;
@@ -97,37 +83,7 @@
private int mVoicePromptTextId; // voicePromptText
private int mVoiceLanguageId; // voiceLanguage
private int mVoiceMaxResults; // voiceMaxResults
-
- /**
- * Set the default searchable activity (when none is specified).
- */
- public static void setDefaultSearchable(Context context,
- ComponentName activity) {
- synchronized (SearchableInfo.class) {
- SearchableInfo si = null;
- if (activity != null) {
- si = getSearchableInfo(context, activity);
- if (si != null) {
- // move to front of list
- sSearchablesList.remove(si);
- sSearchablesList.add(0, si);
- }
- }
- sDefaultSearchable = si;
- }
- }
-
- /**
- * Provides the system-default search activity, which you can use
- * whenever getSearchableInfo() returns null;
- *
- * @return Returns the system-default search activity, null if never defined
- */
- public static SearchableInfo getDefaultSearchable() {
- synchronized (SearchableInfo.class) {
- return sDefaultSearchable;
- }
- }
+
/**
* Retrieve the authority for obtaining search suggestions.
@@ -193,9 +149,16 @@
* @return Returns a context related to the searchable activity
*/
public Context getActivityContext(Context context) {
+ return createActivityContext(context, mSearchActivity);
+ }
+
+ /**
+ * Creates a context for another activity.
+ */
+ private static Context createActivityContext(Context context, ComponentName activity) {
Context theirContext = null;
try {
- theirContext = context.createPackageContext(mSearchActivity.getPackageName(), 0);
+ theirContext = context.createPackageContext(activity.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
// unexpected, but we deal with this by null-checking theirContext
} catch (java.lang.SecurityException e) {
@@ -234,242 +197,68 @@
}
/**
- * Factory. Look up, or construct, based on the activity.
- *
- * The activities fall into three cases, based on meta-data found in
- * the manifest entry:
- * <ol>
- * <li>The activity itself implements search. This is indicated by the
- * presence of a "android.app.searchable" meta-data attribute.
- * The value is a reference to an XML file containing search information.</li>
- * <li>A related activity implements search. This is indicated by the
- * presence of a "android.app.default_searchable" meta-data attribute.
- * The value is a string naming the activity implementing search. In this
- * case the factory will "redirect" and return the searchable data.</li>
- * <li>No searchability data is provided. We return null here and other
- * code will insert the "default" (e.g. contacts) search.
- *
- * TODO: cache the result in the map, and check the map first.
- * TODO: it might make sense to implement the searchable reference as
- * an application meta-data entry. This way we don't have to pepper each
- * and every activity.
- * TODO: can we skip the constructor step if it's a non-searchable?
- * TODO: does it make sense to plug the default into a slot here for
- * automatic return? Probably not, but it's one way to do it.
- *
- * @param activity The name of the current activity, or null if the
- * activity does not define any explicit searchable metadata.
- */
- public static SearchableInfo getSearchableInfo(Context context,
- ComponentName activity) {
- // Step 1. Is the result already hashed? (case 1)
- SearchableInfo result;
- synchronized (SearchableInfo.class) {
- result = sSearchablesMap.get(activity);
- if (result != null) return result;
- }
-
- // Step 2. See if the current activity references a searchable.
- // Note: Conceptually, this could be a while(true) loop, but there's
- // no point in implementing reference chaining here and risking a loop.
- // References must point directly to searchable activities.
-
- ActivityInfo ai = null;
- XmlPullParser xml = null;
- try {
- ai = context.getPackageManager().
- getActivityInfo(activity, PackageManager.GET_META_DATA );
- String refActivityName = null;
-
- // First look for activity-specific reference
- Bundle md = ai.metaData;
- if (md != null) {
- refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
- }
- // If not found, try for app-wide reference
- if (refActivityName == null) {
- md = ai.applicationInfo.metaData;
- if (md != null) {
- refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
- }
- }
-
- // Irrespective of source, if a reference was found, follow it.
- if (refActivityName != null)
- {
- // An app or activity can declare that we should simply launch
- // "system default search" if search is invoked.
- if (refActivityName.equals(MD_SEARCHABLE_SYSTEM_SEARCH)) {
- return getDefaultSearchable();
- }
- String pkg = activity.getPackageName();
- ComponentName referredActivity;
- if (refActivityName.charAt(0) == '.') {
- referredActivity = new ComponentName(pkg, pkg + refActivityName);
- } else {
- referredActivity = new ComponentName(pkg, refActivityName);
- }
-
- // Now try the referred activity, and if found, cache
- // it against the original name so we can skip the check
- synchronized (SearchableInfo.class) {
- result = sSearchablesMap.get(referredActivity);
- if (result != null) {
- sSearchablesMap.put(activity, result);
- return result;
- }
- }
- }
- } catch (PackageManager.NameNotFoundException e) {
- // case 3: no metadata
- }
-
- // Step 3. None found. Return null.
- return null;
-
- }
-
- /**
- * Super-factory. Builds an entire list (suitable for display) of
- * activities that are searchable, by iterating the entire set of
- * ACTION_SEARCH intents.
- *
- * Also clears the hash of all activities -> searches which will
- * refill as the user clicks "search".
- *
- * This should only be done at startup and again if we know that the
- * list has changed.
- *
- * TODO: every activity that provides a ACTION_SEARCH intent should
- * also provide searchability meta-data. There are a bunch of checks here
- * that, if data is not found, silently skip to the next activity. This
- * won't help a developer trying to figure out why their activity isn't
- * showing up in the list, but an exception here is too rough. I would
- * like to find a better notification mechanism.
- *
- * TODO: sort the list somehow? UI choice.
- *
- * @param context a context we can use during this work
- */
- public static void buildSearchableList(Context context) {
-
- // create empty hash & list
- HashMap<ComponentName, SearchableInfo> newSearchablesMap
- = new HashMap<ComponentName, SearchableInfo>();
- ArrayList<SearchableInfo> newSearchablesList
- = new ArrayList<SearchableInfo>();
-
- // use intent resolver to generate list of ACTION_SEARCH receivers
- final PackageManager pm = context.getPackageManager();
- List<ResolveInfo> infoList;
- final Intent intent = new Intent(Intent.ACTION_SEARCH);
- infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
-
- // analyze each one, generate a Searchables record, and record
- if (infoList != null) {
- int count = infoList.size();
- for (int ii = 0; ii < count; ii++) {
- // for each component, try to find metadata
- ResolveInfo info = infoList.get(ii);
- ActivityInfo ai = info.activityInfo;
- XmlResourceParser xml = ai.loadXmlMetaData(context.getPackageManager(),
- MD_LABEL_SEARCHABLE);
- if (xml == null) {
- continue;
- }
- ComponentName cName = new ComponentName(
- info.activityInfo.packageName,
- info.activityInfo.name);
-
- SearchableInfo searchable = getActivityMetaData(context, xml, cName);
- xml.close();
-
- if (searchable != null) {
- // no need to keep the context any longer. setup time is over.
- searchable.mCacheActivityContext = null;
-
- newSearchablesList.add(searchable);
- newSearchablesMap.put(cName, searchable);
- }
- }
- }
-
- // record the final values as a coherent pair
- synchronized (SearchableInfo.class) {
- sSearchablesList = newSearchablesList;
- sSearchablesMap = newSearchablesMap;
- }
- }
-
- /**
* Constructor
*
* Given a ComponentName, get the searchability info
* and build a local copy of it. Use the factory, not this.
*
- * @param context runtime context
+ * @param activityContext runtime context for the activity that the searchable info is about.
* @param attr The attribute set we found in the XML file, contains the values that are used to
* construct the object.
* @param cName The component name of the searchable activity
*/
- private SearchableInfo(Context context, AttributeSet attr, final ComponentName cName) {
+ private SearchableInfo(Context activityContext, AttributeSet attr, final ComponentName cName) {
// initialize as an "unsearchable" object
mSearchable = false;
mSearchActivity = cName;
- // to access another activity's resources, I need its context.
- // BE SURE to release the cache sometime after construction - it's a large object to hold
- mCacheActivityContext = getActivityContext(context);
- if (mCacheActivityContext != null) {
- TypedArray a = mCacheActivityContext.obtainStyledAttributes(attr,
- com.android.internal.R.styleable.Searchable);
- mSearchMode = a.getInt(com.android.internal.R.styleable.Searchable_searchMode, 0);
- mLabelId = a.getResourceId(com.android.internal.R.styleable.Searchable_label, 0);
- mHintId = a.getResourceId(com.android.internal.R.styleable.Searchable_hint, 0);
- mIconId = a.getResourceId(com.android.internal.R.styleable.Searchable_icon, 0);
- mSearchButtonText = a.getResourceId(
- com.android.internal.R.styleable.Searchable_searchButtonText, 0);
- mSearchInputType = a.getInt(com.android.internal.R.styleable.Searchable_inputType,
- InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_VARIATION_NORMAL);
- mSearchImeOptions = a.getInt(com.android.internal.R.styleable.Searchable_imeOptions,
- EditorInfo.IME_ACTION_SEARCH);
+ TypedArray a = activityContext.obtainStyledAttributes(attr,
+ com.android.internal.R.styleable.Searchable);
+ mSearchMode = a.getInt(com.android.internal.R.styleable.Searchable_searchMode, 0);
+ mLabelId = a.getResourceId(com.android.internal.R.styleable.Searchable_label, 0);
+ mHintId = a.getResourceId(com.android.internal.R.styleable.Searchable_hint, 0);
+ mIconId = a.getResourceId(com.android.internal.R.styleable.Searchable_icon, 0);
+ mSearchButtonText = a.getResourceId(
+ com.android.internal.R.styleable.Searchable_searchButtonText, 0);
+ mSearchInputType = a.getInt(com.android.internal.R.styleable.Searchable_inputType,
+ InputType.TYPE_CLASS_TEXT |
+ InputType.TYPE_TEXT_VARIATION_NORMAL);
+ mSearchImeOptions = a.getInt(com.android.internal.R.styleable.Searchable_imeOptions,
+ EditorInfo.IME_ACTION_SEARCH);
- setSearchModeFlags();
- if (DBG_INHIBIT_SUGGESTIONS == 0) {
- mSuggestAuthority = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestAuthority);
- mSuggestPath = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestPath);
- mSuggestSelection = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestSelection);
- mSuggestIntentAction = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestIntentAction);
- mSuggestIntentData = a.getString(
- com.android.internal.R.styleable.Searchable_searchSuggestIntentData);
- }
- mVoiceSearchMode =
- a.getInt(com.android.internal.R.styleable.Searchable_voiceSearchMode, 0);
- // TODO this didn't work - came back zero from YouTube
- mVoiceLanguageModeId =
- a.getResourceId(com.android.internal.R.styleable.Searchable_voiceLanguageModel, 0);
- mVoicePromptTextId =
- a.getResourceId(com.android.internal.R.styleable.Searchable_voicePromptText, 0);
- mVoiceLanguageId =
- a.getResourceId(com.android.internal.R.styleable.Searchable_voiceLanguage, 0);
- mVoiceMaxResults =
- a.getInt(com.android.internal.R.styleable.Searchable_voiceMaxResults, 0);
+ setSearchModeFlags();
+ if (DBG_INHIBIT_SUGGESTIONS == 0) {
+ mSuggestAuthority = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestAuthority);
+ mSuggestPath = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestPath);
+ mSuggestSelection = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestSelection);
+ mSuggestIntentAction = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestIntentAction);
+ mSuggestIntentData = a.getString(
+ com.android.internal.R.styleable.Searchable_searchSuggestIntentData);
+ }
+ mVoiceSearchMode =
+ a.getInt(com.android.internal.R.styleable.Searchable_voiceSearchMode, 0);
+ // TODO this didn't work - came back zero from YouTube
+ mVoiceLanguageModeId =
+ a.getResourceId(com.android.internal.R.styleable.Searchable_voiceLanguageModel, 0);
+ mVoicePromptTextId =
+ a.getResourceId(com.android.internal.R.styleable.Searchable_voicePromptText, 0);
+ mVoiceLanguageId =
+ a.getResourceId(com.android.internal.R.styleable.Searchable_voiceLanguage, 0);
+ mVoiceMaxResults =
+ a.getInt(com.android.internal.R.styleable.Searchable_voiceMaxResults, 0);
- a.recycle();
+ a.recycle();
- // get package info for suggestions provider (if any)
- if (mSuggestAuthority != null) {
- ProviderInfo pi =
- context.getPackageManager().resolveContentProvider(mSuggestAuthority,
- 0);
- if (pi != null) {
- mSuggestProviderPackage = pi.packageName;
- }
+ // get package info for suggestions provider (if any)
+ if (mSuggestAuthority != null) {
+ PackageManager pm = activityContext.getPackageManager();
+ ProviderInfo pi = pm.resolveContentProvider(mSuggestAuthority, 0);
+ if (pi != null) {
+ mSuggestProviderPackage = pi.packageName;
}
}
@@ -496,7 +285,7 @@
/**
* Private class used to hold the "action key" configuration
*/
- public class ActionKeyInfo implements Parcelable {
+ public static class ActionKeyInfo implements Parcelable {
public int mKeyCode = 0;
public String mQueryActionMsg;
@@ -506,14 +295,15 @@
/**
* Create one object using attributeset as input data.
- * @param context runtime context
+ * @param activityContext runtime context of the activity that the action key information
+ * is about.
* @param attr The attribute set we found in the XML file, contains the values that are used to
* construct the object.
* @param next We'll build these up using a simple linked list (since there are usually
* just zero or one).
*/
- public ActionKeyInfo(Context context, AttributeSet attr, ActionKeyInfo next) {
- TypedArray a = mCacheActivityContext.obtainStyledAttributes(attr,
+ public ActionKeyInfo(Context activityContext, AttributeSet attr, ActionKeyInfo next) {
+ TypedArray a = activityContext.obtainStyledAttributes(attr,
com.android.internal.R.styleable.SearchableActionKey);
mKeyCode = a.getInt(
@@ -584,6 +374,20 @@
return null;
}
+ public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
+ // for each component, try to find metadata
+ XmlResourceParser xml =
+ activityInfo.loadXmlMetaData(context.getPackageManager(), MD_LABEL_SEARCHABLE);
+ if (xml == null) {
+ return null;
+ }
+ ComponentName cName = new ComponentName(activityInfo.packageName, activityInfo.name);
+
+ SearchableInfo searchable = getActivityMetaData(context, xml, cName);
+ xml.close();
+ return searchable;
+ }
+
/**
* Get the metadata for a given activity
*
@@ -598,6 +402,7 @@
private static SearchableInfo getActivityMetaData(Context context, XmlPullParser xml,
final ComponentName cName) {
SearchableInfo result = null;
+ Context activityContext = createActivityContext(context, cName);
// in order to use the attributes mechanism, we have to walk the parser
// forward through the file until it's reading the tag of interest.
@@ -608,7 +413,7 @@
if (xml.getName().equals(MD_XML_ELEMENT_SEARCHABLE)) {
AttributeSet attr = Xml.asAttributeSet(xml);
if (attr != null) {
- result = new SearchableInfo(context, attr, cName);
+ result = new SearchableInfo(activityContext, attr, cName);
// if the constructor returned a bad object, exit now.
if (! result.mSearchable) {
return null;
@@ -621,7 +426,7 @@
}
AttributeSet attr = Xml.asAttributeSet(xml);
if (attr != null) {
- ActionKeyInfo keyInfo = result.new ActionKeyInfo(context, attr,
+ ActionKeyInfo keyInfo = new ActionKeyInfo(activityContext, attr,
result.mActionKeyList);
// only add to list if it is was useable
if (keyInfo.mKeyCode != 0) {
@@ -637,6 +442,7 @@
} catch (IOException e) {
throw new RuntimeException(e);
}
+
return result;
}
@@ -757,16 +563,6 @@
}
/**
- * Return the list of searchable activities, for use in the drop-down.
- */
- public static ArrayList<SearchableInfo> getSearchablesList() {
- synchronized (SearchableInfo.class) {
- ArrayList<SearchableInfo> result = new ArrayList<SearchableInfo>(sSearchablesList);
- return result;
- }
- }
-
- /**
* Support for parcelable and aidl operations.
*/
public static final Parcelable.Creator<SearchableInfo> CREATOR
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
new file mode 100644
index 0000000..ba75d21
--- /dev/null
+++ b/core/java/android/server/search/Searchables.java
@@ -0,0 +1,243 @@
+/*
+ * 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 android.server.search;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * This class maintains the information about all searchable activities.
+ */
+public class Searchables {
+
+ // static strings used for XML lookups, etc.
+ // TODO how should these be documented for the developer, in a more structured way than
+ // the current long wordy javadoc in SearchManager.java ?
+ private static final String MD_LABEL_DEFAULT_SEARCHABLE = "android.app.default_searchable";
+ private static final String MD_SEARCHABLE_SYSTEM_SEARCH = "*";
+
+ private Context mContext;
+
+ private HashMap<ComponentName, SearchableInfo> mSearchablesMap = null;
+ private ArrayList<SearchableInfo> mSearchablesList = null;
+ private SearchableInfo mDefaultSearchable = null;
+
+ /**
+ *
+ * @param context Context to use for looking up activities etc.
+ */
+ public Searchables (Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Look up, or construct, based on the activity.
+ *
+ * The activities fall into three cases, based on meta-data found in
+ * the manifest entry:
+ * <ol>
+ * <li>The activity itself implements search. This is indicated by the
+ * presence of a "android.app.searchable" meta-data attribute.
+ * The value is a reference to an XML file containing search information.</li>
+ * <li>A related activity implements search. This is indicated by the
+ * presence of a "android.app.default_searchable" meta-data attribute.
+ * The value is a string naming the activity implementing search. In this
+ * case the factory will "redirect" and return the searchable data.</li>
+ * <li>No searchability data is provided. We return null here and other
+ * code will insert the "default" (e.g. contacts) search.
+ *
+ * TODO: cache the result in the map, and check the map first.
+ * TODO: it might make sense to implement the searchable reference as
+ * an application meta-data entry. This way we don't have to pepper each
+ * and every activity.
+ * TODO: can we skip the constructor step if it's a non-searchable?
+ * TODO: does it make sense to plug the default into a slot here for
+ * automatic return? Probably not, but it's one way to do it.
+ *
+ * @param activity The name of the current activity, or null if the
+ * activity does not define any explicit searchable metadata.
+ */
+ public SearchableInfo getSearchableInfo(ComponentName activity) {
+ // Step 1. Is the result already hashed? (case 1)
+ SearchableInfo result;
+ synchronized (this) {
+ result = mSearchablesMap.get(activity);
+ if (result != null) return result;
+ }
+
+ // Step 2. See if the current activity references a searchable.
+ // Note: Conceptually, this could be a while(true) loop, but there's
+ // no point in implementing reference chaining here and risking a loop.
+ // References must point directly to searchable activities.
+
+ ActivityInfo ai = null;
+ try {
+ ai = mContext.getPackageManager().
+ getActivityInfo(activity, PackageManager.GET_META_DATA );
+ String refActivityName = null;
+
+ // First look for activity-specific reference
+ Bundle md = ai.metaData;
+ if (md != null) {
+ refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
+ }
+ // If not found, try for app-wide reference
+ if (refActivityName == null) {
+ md = ai.applicationInfo.metaData;
+ if (md != null) {
+ refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE);
+ }
+ }
+
+ // Irrespective of source, if a reference was found, follow it.
+ if (refActivityName != null)
+ {
+ // An app or activity can declare that we should simply launch
+ // "system default search" if search is invoked.
+ if (refActivityName.equals(MD_SEARCHABLE_SYSTEM_SEARCH)) {
+ return getDefaultSearchable();
+ }
+ String pkg = activity.getPackageName();
+ ComponentName referredActivity;
+ if (refActivityName.charAt(0) == '.') {
+ referredActivity = new ComponentName(pkg, pkg + refActivityName);
+ } else {
+ referredActivity = new ComponentName(pkg, refActivityName);
+ }
+
+ // Now try the referred activity, and if found, cache
+ // it against the original name so we can skip the check
+ synchronized (this) {
+ result = mSearchablesMap.get(referredActivity);
+ if (result != null) {
+ mSearchablesMap.put(activity, result);
+ return result;
+ }
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // case 3: no metadata
+ }
+
+ // Step 3. None found. Return null.
+ return null;
+
+ }
+
+ /**
+ * Set the default searchable activity (when none is specified).
+ */
+ public synchronized void setDefaultSearchable(ComponentName activity) {
+ SearchableInfo si = null;
+ if (activity != null) {
+ si = getSearchableInfo(activity);
+ if (si != null) {
+ // move to front of list
+ mSearchablesList.remove(si);
+ mSearchablesList.add(0, si);
+ }
+ }
+ mDefaultSearchable = si;
+ }
+
+ /**
+ * Provides the system-default search activity, which you can use
+ * whenever getSearchableInfo() returns null;
+ *
+ * @return Returns the system-default search activity, null if never defined
+ */
+ public synchronized SearchableInfo getDefaultSearchable() {
+ return mDefaultSearchable;
+ }
+
+ public synchronized boolean isDefaultSearchable(SearchableInfo searchable) {
+ return searchable == mDefaultSearchable;
+ }
+
+ /**
+ * Builds an entire list (suitable for display) of
+ * activities that are searchable, by iterating the entire set of
+ * ACTION_SEARCH intents.
+ *
+ * Also clears the hash of all activities -> searches which will
+ * refill as the user clicks "search".
+ *
+ * This should only be done at startup and again if we know that the
+ * list has changed.
+ *
+ * TODO: every activity that provides a ACTION_SEARCH intent should
+ * also provide searchability meta-data. There are a bunch of checks here
+ * that, if data is not found, silently skip to the next activity. This
+ * won't help a developer trying to figure out why their activity isn't
+ * showing up in the list, but an exception here is too rough. I would
+ * like to find a better notification mechanism.
+ *
+ * TODO: sort the list somehow? UI choice.
+ */
+ public void buildSearchableList() {
+
+ // create empty hash & list
+ HashMap<ComponentName, SearchableInfo> newSearchablesMap
+ = new HashMap<ComponentName, SearchableInfo>();
+ ArrayList<SearchableInfo> newSearchablesList
+ = new ArrayList<SearchableInfo>();
+
+ // use intent resolver to generate list of ACTION_SEARCH receivers
+ final PackageManager pm = mContext.getPackageManager();
+ List<ResolveInfo> infoList;
+ final Intent intent = new Intent(Intent.ACTION_SEARCH);
+ infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
+
+ // analyze each one, generate a Searchables record, and record
+ if (infoList != null) {
+ int count = infoList.size();
+ for (int ii = 0; ii < count; ii++) {
+ // for each component, try to find metadata
+ ResolveInfo info = infoList.get(ii);
+ ActivityInfo ai = info.activityInfo;
+ SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai);
+ if (searchable != null) {
+ newSearchablesList.add(searchable);
+ newSearchablesMap.put(searchable.mSearchActivity, searchable);
+ }
+ }
+ }
+
+ // record the final values as a coherent pair
+ synchronized (this) {
+ mSearchablesList = newSearchablesList;
+ mSearchablesMap = newSearchablesMap;
+ }
+ }
+
+ /**
+ * Returns the list of searchable activities.
+ */
+ public synchronized ArrayList<SearchableInfo> getSearchablesList() {
+ ArrayList<SearchableInfo> result = new ArrayList<SearchableInfo>(mSearchablesList);
+ return result;
+ }
+}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 772ad89..b408f27 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -983,18 +983,6 @@
mSelectorRect.setEmpty();
invalidate();
}
-
- /**
- * The list is empty and we need to change the layout, so *really* clear everything out.
- * @hide - for AutoCompleteTextView & SearchDialog only
- */
- /* package */ void resetListAndClearViews() {
- rememberSyncState();
- removeAllViewsInLayout();
- mRecycler.clear();
- mRecycler.setViewTypeCount(mAdapter.getViewTypeCount());
- requestLayout();
- }
@Override
protected int computeVerticalScrollExtent() {
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index dfb971e..e3186b0 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -110,6 +110,10 @@
private final DropDownItemClickListener mDropDownItemClickListener =
new DropDownItemClickListener();
+ private boolean mDropDownAlwaysVisible = false;
+
+ private boolean mDropDownDismissedOnCompletion = true;
+
private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN;
private boolean mOpenBefore;
@@ -211,6 +215,8 @@
* {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
*
* @return the width for the drop down list
+ *
+ * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth
*/
public int getDropDownWidth() {
return mDropDownWidth;
@@ -222,6 +228,8 @@
* {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
*
* @param width the width to use
+ *
+ * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth
*/
public void setDropDownWidth(int width) {
mDropDownWidth = width;
@@ -231,6 +239,8 @@
* <p>Returns the id for the view that the auto-complete drop down list is anchored to.</p>
*
* @return the view's id, or {@link View#NO_ID} if none specified
+ *
+ * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor
*/
public int getDropDownAnchor() {
return mDropDownAnchorId;
@@ -242,13 +252,173 @@
* loading a view which is not yet instantiated.</p>
*
* @param id the id to anchor the drop down list view to
+ *
+ * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor
*/
public void setDropDownAnchor(int id) {
mDropDownAnchorId = id;
mDropDownAnchorView = null;
}
+
+ /**
+ * <p>Gets the background of the auto-complete drop-down list.</p>
+ *
+ * @return the background drawable
+ *
+ * @attr ref android.R.styleable#PopupWindow_popupBackground
+ *
+ * @hide Pending API council approval
+ */
+ public Drawable getDropDownBackground() {
+ return mPopup.getBackground();
+ }
+
+ /**
+ * <p>Sets the background of the auto-complete drop-down list.</p>
+ *
+ * @param d the drawable to set as the background
+ *
+ * @attr ref android.R.styleable#PopupWindow_popupBackground
+ *
+ * @hide Pending API council approval
+ */
+ public void setDropDownBackgroundDrawable(Drawable d) {
+ mPopup.setBackgroundDrawable(d);
+ }
+
+ /**
+ * <p>Sets the background of the auto-complete drop-down list.</p>
+ *
+ * @param id the id of the drawable to set as the background
+ *
+ * @attr ref android.R.styleable#PopupWindow_popupBackground
+ *
+ * @hide Pending API council approval
+ */
+ public void setDropDownBackgroundResource(int id) {
+ mPopup.setBackgroundDrawable(getResources().getDrawable(id));
+ }
/**
+ * <p>Sets the animation style of the auto-complete drop-down list.</p>
+ *
+ * <p>If the drop-down is showing, calling this method will take effect only
+ * the next time the drop-down is shown.</p>
+ *
+ * @param animationStyle animation style to use when the drop-down appears
+ * and disappears. Set to -1 for the default animation, 0 for no
+ * animation, or a resource identifier for an explicit animation.
+ *
+ * @hide Pending API council approval
+ */
+ public void setDropDownAnimationStyle(int animationStyle) {
+ mPopup.setAnimationStyle(animationStyle);
+ }
+
+ /**
+ * <p>Returns the animation style that is used when the drop-down list appears and disappears
+ * </p>
+ *
+ * @return the animation style that is used when the drop-down list appears and disappears
+ *
+ * @hide Pending API council approval
+ */
+ public int getDropDownAnimationStyle() {
+ return mPopup.getAnimationStyle();
+ }
+
+ /**
+ * <p>Sets the vertical offset used for the auto-complete drop-down list.</p>
+ *
+ * @param offset the vertical offset
+ *
+ * @hide Pending API council approval
+ */
+ public void setDropDownVerticalOffset(int offset) {
+ mDropDownVerticalOffset = offset;
+ }
+
+ /**
+ * <p>Gets the vertical offset used for the auto-complete drop-down list.</p>
+ *
+ * @return the vertical offset
+ *
+ * @hide Pending API council approval
+ */
+ public int getDropDownVerticalOffset() {
+ return mDropDownVerticalOffset;
+ }
+
+ /**
+ * <p>Sets the horizontal offset used for the auto-complete drop-down list.</p>
+ *
+ * @param offset the horizontal offset
+ *
+ * @hide Pending API council approval
+ */
+ public void setDropDownHorizontalOffset(int offset) {
+ mDropDownHorizontalOffset = offset;
+ }
+
+ /**
+ * <p>Gets the horizontal offset used for the auto-complete drop-down list.</p>
+ *
+ * @return the horizontal offset
+ *
+ * @hide Pending API council approval
+ */
+ public int getDropDownHorizontalOffset() {
+ return mDropDownHorizontalOffset;
+ }
+
+ /**
+ * @return Whether the drop-down is visible as long as there is {@link #enoughToFilter()}
+ *
+ * @hide Pending API council approval
+ */
+ public boolean isDropDownAlwaysVisible() {
+ return mDropDownAlwaysVisible;
+ }
+
+ /**
+ * Sets whether the drop-down should remain visible as long as there is there is
+ * {@link #enoughToFilter()}. This is useful if an unknown number of results are expected
+ * to show up in the adapter sometime in the future.
+ *
+ * The drop-down will occupy the entire screen below {@link #getDropDownAnchor} regardless
+ * of the size or content of the list. {@link #getDropDownBackground()} will fill any space
+ * that is not used by the list.
+ *
+ * @param dropDownAlwaysVisible Whether to keep the drop-down visible.
+ *
+ * @hide Pending API council approval
+ */
+ public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) {
+ mDropDownAlwaysVisible = dropDownAlwaysVisible;
+ }
+
+ /**
+ * Checks whether the drop-down is dismissed when a suggestion is clicked.
+ *
+ * @hide Pending API council approval
+ */
+ public boolean isDropDownDismissedOnCompletion() {
+ return mDropDownDismissedOnCompletion;
+ }
+
+ /**
+ * Sets whether the drop-down is dismissed when a suggestion is clicked. This is
+ * true by default.
+ *
+ * @param dropDownDismissedOnCompletion Whether to dismiss the drop-down.
+ *
+ * @hide Pending API council approval
+ */
+ public void setDropDownDismissedOnCompletion(boolean dropDownDismissedOnCompletion) {
+ mDropDownDismissedOnCompletion = dropDownDismissedOnCompletion;
+ }
+
+ /**
* <p>Returns the number of characters the user must type before the drop
* down list is shown.</p>
*
@@ -628,16 +798,6 @@
}
return ListView.INVALID_POSITION;
}
-
- /**
- * We're changing the adapter and its views so really, really clear everything out
- * @hide - for SearchDialog only
- */
- public void resetListAndClearViews() {
- if (mDropDownList != null) {
- mDropDownList.resetListAndClearViews();
- }
- }
/**
* <p>Starts filtering the content of the drop down list. The filtering
@@ -709,7 +869,9 @@
}
}
- dismissDropDown();
+ if (mDropDownDismissedOnCompletion) {
+ dismissDropDown();
+ }
}
/**
@@ -721,6 +883,42 @@
}
/**
+ * Like {@link #setText(CharSequence)}, except that it can disable filtering.
+ *
+ * @param filter If <code>false</code>, no filtering will be performed
+ * as a result of this call.
+ *
+ * @hide Pending API council approval.
+ */
+ public void setText(CharSequence text, boolean filter) {
+ if (filter) {
+ setText(text);
+ } else {
+ mBlockCompletion = true;
+ setText(text);
+ mBlockCompletion = false;
+ }
+ }
+
+ /**
+ * Like {@link #setTextKeepState(CharSequence)}, except that it can disable filtering.
+ *
+ * @param filter If <code>false</code>, no filtering will be performed
+ * as a result of this call.
+ *
+ * @hide Pending API council approval.
+ */
+ public void setTextKeepState(CharSequence text, boolean filter) {
+ if (filter) {
+ setTextKeepState(text);
+ } else {
+ mBlockCompletion = true;
+ setTextKeepState(text);
+ mBlockCompletion = false;
+ }
+ }
+
+ /**
* <p>Performs the text completion by replacing the current text by the
* selected item. Subclasses should override this method to avoid replacing
* the whole content of the edit box.</p>
@@ -734,6 +932,7 @@
Selection.setSelection(spannable, spannable.length());
}
+ /** {@inheritDoc} */
public void onFilterComplete(int count) {
if (mAttachCount <= 0) return;
@@ -744,7 +943,7 @@
* to filter.
*/
- if (count > 0 && enoughToFilter()) {
+ if ((count > 0 || mDropDownAlwaysVisible) && enoughToFilter()) {
if (hasFocus() && hasWindowFocus()) {
showDropDown();
}
@@ -809,22 +1008,6 @@
}
/**
- * Set the horizontal offset with respect to {@link #setDropDownAnchor(int)}
- * @hide pending API council review
- */
- public void setDropDownHorizontalOffset(int horizontalOffset) {
- mDropDownHorizontalOffset = horizontalOffset;
- }
-
- /**
- * Set the vertical offset with respect to {@link #setDropDownAnchor(int)}
- * @hide pending API council review
- */
- public void setDropDownVerticalOffset(int verticalOffset) {
- mDropDownVerticalOffset = verticalOffset;
- }
-
- /**
* <p>Used for lazy instantiation of the anchor view from the id we have. If the value of
* the id is NO_ID or we can't find a view for the given id, we return this TextView as
* the default anchoring point.</p>
@@ -856,10 +1039,9 @@
mDropDownVerticalOffset, widthSpec, height);
} else {
if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) {
- mPopup.setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
+ mPopup.setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT, 0);
} else {
- mPopup.setWindowLayoutMode(0, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mPopup.setWindowLayoutMode(0, 0);
if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
mPopup.setWidth(getDropDownAnchorView().getWidth());
} else {
@@ -966,8 +1148,10 @@
final int maxHeight = mPopup.getMaxAvailableHeight(this, mDropDownVerticalOffset);
//otherHeights += dropDownView.getPaddingTop() + dropDownView.getPaddingBottom();
- return mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
+ final int measuredHeight = mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
0, ListView.NO_POSITION, maxHeight - otherHeights, 2) + otherHeights;
+
+ return mDropDownAlwaysVisible ? maxHeight : measuredHeight;
}
private View getHintView(Context context) {
diff --git a/core/java/com/android/internal/util/TypedProperties.java b/core/java/com/android/internal/util/TypedProperties.java
new file mode 100644
index 0000000..48479e3
--- /dev/null
+++ b/core/java/com/android/internal/util/TypedProperties.java
@@ -0,0 +1,692 @@
+/*
+ * 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.internal.util;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StreamTokenizer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * A {@code Map} that publishes a set of typed properties, defined by
+ * zero or more {@code Reader}s containing textual definitions and assignments.
+ */
+public class TypedProperties extends HashMap<String, Object> {
+ /**
+ * Instantiates a {@link java.io.StreamTokenizer} and sets its syntax tables
+ * appropriately for the {@code TypedProperties} file format.
+ *
+ * @param r The {@code Reader} that the {@code StreamTokenizer} will read from
+ * @return a newly-created and initialized {@code StreamTokenizer}
+ */
+ static StreamTokenizer initTokenizer(Reader r) {
+ StreamTokenizer st = new StreamTokenizer(r);
+
+ // Treat everything we don't specify as "ordinary".
+ st.resetSyntax();
+
+ /* The only non-quoted-string words we'll be reading are:
+ * - property names: [._$a-zA-Z0-9]
+ * - type names (case insensitive): [a-zA-Z]
+ * - number literals: [-0-9.eExXA-Za-z] ('x' for 0xNNN hex literals. "NaN", "Infinity")
+ * - "true" or "false" (case insensitive): [a-zA-Z]
+ */
+ st.wordChars('0', '9');
+ st.wordChars('A', 'Z');
+ st.wordChars('a', 'z');
+ st.wordChars('_', '_');
+ st.wordChars('$', '$');
+ st.wordChars('.', '.');
+ st.wordChars('-', '-');
+ st.wordChars('+', '+');
+
+ // Single-character tokens
+ st.ordinaryChar('=');
+
+ // Other special characters
+ st.whitespaceChars(' ', ' ');
+ st.whitespaceChars('\t', '\t');
+
+ st.quoteChar('"');
+
+ st.commentChar('#');
+
+ st.eolIsSignificant(true);
+
+ return st;
+ }
+
+
+ /**
+ * An unchecked exception that is thrown when encountering a syntax
+ * or semantic error in the input.
+ */
+ public static class ParseException extends IllegalArgumentException {
+ ParseException(StreamTokenizer state, String expected) {
+ super("expected " + expected + ", saw " + state.toString());
+ }
+ }
+
+ // A sentinel instance used to indicate a null string.
+ static final String NULL_STRING = new String("<TypedProperties:NULL_STRING>");
+
+ // Constants used to represent the supported types.
+ static final int TYPE_UNSET = 'x';
+ static final int TYPE_BOOLEAN = 'Z';
+ static final int TYPE_BYTE = 'I' | 1 << 8;
+ // TYPE_CHAR: character literal syntax not supported; use short.
+ static final int TYPE_SHORT = 'I' | 2 << 8;
+ static final int TYPE_INT = 'I' | 4 << 8;
+ static final int TYPE_LONG = 'I' | 8 << 8;
+ static final int TYPE_FLOAT = 'F' | 4 << 8;
+ static final int TYPE_DOUBLE = 'F' | 8 << 8;
+ static final int TYPE_STRING = 'L' | 's' << 8;
+ static final int TYPE_ERROR = -1;
+
+ /**
+ * Converts a case-insensitive string to an internal type constant.
+ *
+ * @param typeName the type name to convert
+ * @return the type constant that corresponds to {@code typeName},
+ * or {@code TYPE_ERROR} if the type is unknown
+ */
+ static int interpretType(String typeName) {
+ if ("unset".equalsIgnoreCase(typeName)) {
+ return TYPE_UNSET;
+ } else if ("boolean".equalsIgnoreCase(typeName)) {
+ return TYPE_BOOLEAN;
+ } else if ("byte".equalsIgnoreCase(typeName)) {
+ return TYPE_BYTE;
+ } else if ("short".equalsIgnoreCase(typeName)) {
+ return TYPE_SHORT;
+ } else if ("int".equalsIgnoreCase(typeName)) {
+ return TYPE_INT;
+ } else if ("long".equalsIgnoreCase(typeName)) {
+ return TYPE_LONG;
+ } else if ("float".equalsIgnoreCase(typeName)) {
+ return TYPE_FLOAT;
+ } else if ("double".equalsIgnoreCase(typeName)) {
+ return TYPE_DOUBLE;
+ } else if ("string".equalsIgnoreCase(typeName)) {
+ return TYPE_STRING;
+ }
+ return TYPE_ERROR;
+ }
+
+ /**
+ * Consumes EOL tokens.
+ * Returns when a non-EOL token is found.
+ *
+ * @param st The {@code StreamTokenizer} to read tokens from
+ * @return > 0 if an EOL token was seen, < 0 if EOF was seen,
+ * 0 if no tokens were consumed
+ */
+ static int eatEols(StreamTokenizer st) throws IOException {
+ int token;
+ boolean eolSeen = false;
+ do {
+ token = st.nextToken();
+ if (token == StreamTokenizer.TT_EOF) {
+ return -1;
+ } else if (token == StreamTokenizer.TT_EOL) {
+ eolSeen = true;
+ }
+ } while (token == StreamTokenizer.TT_EOL);
+ st.pushBack();
+ return eolSeen ? 1 : 0;
+ }
+
+ /**
+ * Parses the data in the reader.
+ *
+ * @param r The {@code Reader} containing input data to parse
+ * @param map The {@code Map} to insert parameter values into
+ * @throws ParseException if the input data is malformed
+ * @throws IOException if there is a problem reading from the {@code Reader}
+ */
+ static void parse(Reader r, Map<String, Object> map) throws ParseException, IOException {
+ final StreamTokenizer st = initTokenizer(r);
+
+ /* A property name must be a valid fully-qualified class + package name.
+ * We don't support Unicode, though.
+ */
+ final String identifierPattern = "[a-zA-Z_$][0-9a-zA-Z_$]*";
+ final Pattern propertyNamePattern =
+ Pattern.compile("(" + identifierPattern + "\\.)*" + identifierPattern);
+
+
+ boolean eolNeeded = false;
+ while (true) {
+ int token;
+
+ // Eat one or more EOL, or quit on EOF.
+ int eolStatus = eatEols(st);
+ if (eolStatus < 0) {
+ // EOF occurred.
+ break;
+ } else if (eolNeeded && eolStatus == 0) {
+ throw new ParseException(st, "end of line or end of file");
+ }
+
+ // Read the property name.
+ token = st.nextToken();
+ if (token != StreamTokenizer.TT_WORD) {
+ throw new ParseException(st, "property name");
+ }
+ final String propertyName = st.sval;
+ if (!propertyNamePattern.matcher(propertyName).matches()) {
+ throw new ParseException(st, "valid property name");
+ }
+ st.sval = null;
+
+ // Read the type.
+ token = st.nextToken();
+ if (token != StreamTokenizer.TT_WORD) {
+ throw new ParseException(st, "type name");
+ }
+ final int type = interpretType(st.sval);
+ if (type == TYPE_ERROR) {
+ throw new ParseException(st, "valid type name");
+ }
+ st.sval = null;
+
+ if (type == TYPE_UNSET) {
+ map.remove(propertyName);
+ } else {
+ // Expect '='.
+ token = st.nextToken();
+ if (token != '=') {
+ throw new ParseException(st, "'='");
+ }
+
+ // Read a value of the appropriate type, and insert into the map.
+ final Object value = parseValue(st, type);
+ final Object oldValue = map.remove(propertyName);
+ if (oldValue != null) {
+ // TODO: catch the case where a string is set to null and then
+ // the same property is defined with a different type.
+ if (value.getClass() != oldValue.getClass()) {
+ throw new ParseException(st,
+ "(property previously declared as a different type)");
+ }
+ }
+ map.put(propertyName, value);
+ }
+
+ // Require that we see at least one EOL before the next token.
+ eolNeeded = true;
+ }
+ }
+
+ /**
+ * Parses the next token in the StreamTokenizer as the specified type.
+ *
+ * @param st The token source
+ * @param type The type to interpret next token as
+ * @return a Boolean, Number subclass, or String representing the value.
+ * Null strings are represented by the String instance NULL_STRING
+ * @throws IOException if there is a problem reading from the {@code StreamTokenizer}
+ */
+ static Object parseValue(StreamTokenizer st, final int type) throws IOException {
+ final int token = st.nextToken();
+
+ if (type == TYPE_BOOLEAN) {
+ if (token != StreamTokenizer.TT_WORD) {
+ throw new ParseException(st, "boolean constant");
+ }
+
+ if ("true".equalsIgnoreCase(st.sval)) {
+ return Boolean.TRUE;
+ } else if ("false".equalsIgnoreCase(st.sval)) {
+ return Boolean.FALSE;
+ }
+
+ throw new ParseException(st, "boolean constant");
+ } else if ((type & 0xff) == 'I') {
+ if (token != StreamTokenizer.TT_WORD) {
+ throw new ParseException(st, "integer constant");
+ }
+
+ /* Parse the string. Long.decode() handles C-style integer constants
+ * ("0x" -> hex, "0" -> octal). It also treats numbers with a prefix of "#" as
+ * hex, but our syntax intentionally does not list '#' as a word character.
+ */
+ long value;
+ try {
+ value = Long.decode(st.sval);
+ } catch (NumberFormatException ex) {
+ throw new ParseException(st, "integer constant");
+ }
+
+ // Ensure that the type can hold this value, and return.
+ int width = (type >> 8) & 0xff;
+ switch (width) {
+ case 1:
+ if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
+ throw new ParseException(st, "8-bit integer constant");
+ }
+ return new Byte((byte)value);
+ case 2:
+ if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
+ throw new ParseException(st, "16-bit integer constant");
+ }
+ return new Short((short)value);
+ case 4:
+ if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
+ throw new ParseException(st, "32-bit integer constant");
+ }
+ return new Integer((int)value);
+ case 8:
+ if (value < Long.MIN_VALUE || value > Long.MAX_VALUE) {
+ throw new ParseException(st, "64-bit integer constant");
+ }
+ return new Long(value);
+ default:
+ throw new IllegalStateException(
+ "Internal error; unexpected integer type width " + width);
+ }
+ } else if ((type & 0xff) == 'F') {
+ if (token != StreamTokenizer.TT_WORD) {
+ throw new ParseException(st, "float constant");
+ }
+
+ // Parse the string.
+ /* TODO: Maybe just parse as float or double, losing precision if necessary.
+ * Parsing as double and converting to float can change the value
+ * compared to just parsing as float.
+ */
+ double value;
+ try {
+ /* TODO: detect if the string representation loses precision
+ * when being converted to a double.
+ */
+ value = Double.parseDouble(st.sval);
+ } catch (NumberFormatException ex) {
+ throw new ParseException(st, "float constant");
+ }
+
+ // Ensure that the type can hold this value, and return.
+ if (((type >> 8) & 0xff) == 4) {
+ // This property is a float; make sure the value fits.
+ double absValue = Math.abs(value);
+ if (absValue != 0.0 && !Double.isInfinite(value) && !Double.isNaN(value)) {
+ if (absValue < Float.MIN_VALUE || absValue > Float.MAX_VALUE) {
+ throw new ParseException(st, "32-bit float constant");
+ }
+ }
+ return new Float((float)value);
+ } else {
+ // This property is a double; no need to truncate.
+ return new Double(value);
+ }
+ } else if (type == TYPE_STRING) {
+ // Expect a quoted string or the word "null".
+ if (token == '"') {
+ return st.sval;
+ } else if (token == StreamTokenizer.TT_WORD && "null".equalsIgnoreCase(st.sval)) {
+ return NULL_STRING;
+ }
+ throw new ParseException(st, "double-quoted string or 'null'");
+ }
+
+ throw new IllegalStateException("Internal error; unknown type " + type);
+ }
+
+
+ /**
+ * Creates an empty TypedProperties instance.
+ */
+ public TypedProperties() {
+ super();
+ }
+
+ /**
+ * Loads zero or more properties from the specified Reader.
+ * Properties that have already been loaded are preserved unless
+ * the new Reader overrides or unsets earlier values for the
+ * same properties.
+ *
+ * File syntax:
+ *
+ * <property-name> <type> = <value>
+ * <property-name> unset
+ *
+ * '#' is a comment character; it and anything appearing after it
+ * on the line is ignored.
+ *
+ * Blank lines are ignored.
+ *
+ * The only required whitespace is between the property name
+ * and the type.
+ *
+ * Property assignments may not be split across multiple lines.
+ *
+ * <property-name> is a valid fully-qualified class name
+ * (one or more valid identifiers separated by dot characters).
+ *
+ * <type> is one of {boolean, byte, short, int, long,
+ * float, double, string}, and is case-insensitive.
+ *
+ * <value> depends on the type:
+ * - boolean: one of {true, false} (case-insensitive)
+ * - byte, short, int, long: a valid Java integer constant
+ * (including non-base-10 constants like 0xabc and 074)
+ * whose value does not overflow the type. NOTE: these are
+ * interpreted as Java integer values, so they are all signed.
+ * - float, double: a valid Java floating-point constant.
+ * If the type is float, the value must fit in 32 bits.
+ * - string: a double-quoted string value, or the word {@code null}.
+ * NOTE: the contents of the string must be 7-bit clean ASCII;
+ * C-style octal escapes are recognized, but Unicode escapes are not.
+ *
+ *
+ * @param r The Reader to load properties from
+ * @throws IOException if an error occurs when reading the data
+ * @throws IllegalArgumentException if the data is malformed
+ */
+ public void load(Reader r) throws IOException {
+ parse(r, this);
+ }
+
+ @Override
+ public Object get(Object key) {
+ Object value = super.get(key);
+ if (value == NULL_STRING) {
+ return null;
+ }
+ return value;
+ }
+
+ /*
+ * Getters with explicit defaults
+ */
+
+ /**
+ * An unchecked exception that is thrown if a {@code get<TYPE>()} method
+ * is used to retrieve a parameter whose type does not match the method name.
+ */
+ public static class TypeException extends IllegalArgumentException {
+ TypeException(String property, Object value, String requestedType) {
+ super(property + " has type " + value.getClass().getName() +
+ ", not " + requestedType);
+ }
+ }
+
+ /**
+ * Returns the value of a boolean property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a boolean
+ */
+ public boolean getBoolean(String property, boolean def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value instanceof Boolean) {
+ return ((Boolean)value).booleanValue();
+ }
+ throw new TypeException(property, value, "boolean");
+ }
+
+ /**
+ * Returns the value of a byte property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a byte
+ */
+ public byte getByte(String property, byte def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value instanceof Byte) {
+ return ((Byte)value).byteValue();
+ }
+ throw new TypeException(property, value, "byte");
+ }
+
+ /**
+ * Returns the value of a short property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a short
+ */
+ public short getShort(String property, short def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value instanceof Short) {
+ return ((Short)value).shortValue();
+ }
+ throw new TypeException(property, value, "short");
+ }
+
+ /**
+ * Returns the value of an integer property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not an integer
+ */
+ public int getInt(String property, int def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value instanceof Integer) {
+ return ((Integer)value).intValue();
+ }
+ throw new TypeException(property, value, "int");
+ }
+
+ /**
+ * Returns the value of a long property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a long
+ */
+ public long getLong(String property, long def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value instanceof Long) {
+ return ((Long)value).longValue();
+ }
+ throw new TypeException(property, value, "long");
+ }
+
+ /**
+ * Returns the value of a float property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a float
+ */
+ public float getFloat(String property, float def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value instanceof Float) {
+ return ((Float)value).floatValue();
+ }
+ throw new TypeException(property, value, "float");
+ }
+
+ /**
+ * Returns the value of a double property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a double
+ */
+ public double getDouble(String property, double def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value instanceof Double) {
+ return ((Double)value).doubleValue();
+ }
+ throw new TypeException(property, value, "double");
+ }
+
+ /**
+ * Returns the value of a string property, or the default if the property
+ * has not been defined.
+ *
+ * @param property The name of the property to return
+ * @param def The default value to return if the property is not set
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a string
+ */
+ public String getString(String property, String def) {
+ Object value = super.get(property);
+ if (value == null) {
+ return def;
+ }
+ if (value == NULL_STRING) {
+ return null;
+ } else if (value instanceof String) {
+ return (String)value;
+ }
+ throw new TypeException(property, value, "string");
+ }
+
+ /*
+ * Getters with implicit defaults
+ */
+
+ /**
+ * Returns the value of a boolean property, or false
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a boolean
+ */
+ public boolean getBoolean(String property) {
+ return getBoolean(property, false);
+ }
+
+ /**
+ * Returns the value of a byte property, or 0
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a byte
+ */
+ public byte getByte(String property) {
+ return getByte(property, (byte)0);
+ }
+
+ /**
+ * Returns the value of a short property, or 0
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a short
+ */
+ public short getShort(String property) {
+ return getShort(property, (short)0);
+ }
+
+ /**
+ * Returns the value of an integer property, or 0
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not an integer
+ */
+ public int getInt(String property) {
+ return getInt(property, 0);
+ }
+
+ /**
+ * Returns the value of a long property, or 0
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a long
+ */
+ public long getLong(String property) {
+ return getLong(property, 0L);
+ }
+
+ /**
+ * Returns the value of a float property, or 0.0
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a float
+ */
+ public float getFloat(String property) {
+ return getFloat(property, 0.0f);
+ }
+
+ /**
+ * Returns the value of a double property, or 0.0
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a double
+ */
+ public double getDouble(String property) {
+ return getDouble(property, 0.0);
+ }
+
+ /**
+ * Returns the value of a String property, or ""
+ * if the property has not been defined.
+ *
+ * @param property The name of the property to return
+ * @return the value of the property
+ * @throws TypeException if the property is set and is not a string
+ */
+ public String getString(String property) {
+ return getString(property, "");
+ }
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9f6ebed..caa1318 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -366,6 +366,23 @@
android:label="@string/permlab_readPhoneState"
android:description="@string/permdesc_readPhoneState" />
+ <!-- ================================== -->
+ <!-- Permissions for sdcard interaction -->
+ <!-- ================================== -->
+ <eat-comment />
+
+ <!-- Group of permissions that are related to SD card access. -->
+ <permission-group android:name="android.permission-group.STORAGE"
+ android:label="@string/permgrouplab_storage"
+ android:description="@string/permgroupdesc_storage" />
+
+ <!-- Allows an application to write to the SD card -->
+ <permission android:name="android.permission.SDCARD_WRITE"
+ android:permissionGroup="android.permission-group.STORAGE"
+ android:label="@string/permlab_sdcardWrite"
+ android:description="@string/permdesc_sdcardWrite"
+ android:protectionLevel="normal" />
+
<!-- ============================================ -->
<!-- Permissions for low-level system interaction -->
<!-- ============================================ -->
diff --git a/core/res/res/drawable/btn_global_search.xml b/core/res/res/drawable/btn_global_search.xml
new file mode 100644
index 0000000..531f07e
--- /dev/null
+++ b/core/res/res/drawable/btn_global_search.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- TODO Need different assets for some of these button states. -->
+ <item android:state_window_focused="false" android:state_enabled="true"
+ android:drawable="@drawable/btn_global_search_normal" />
+ <item android:state_window_focused="false" android:state_enabled="false"
+ android:drawable="@drawable/btn_global_search_normal" />
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_default_pressed" />
+ <item android:state_focused="true" android:state_enabled="true"
+ android:drawable="@drawable/btn_default_selected" />
+ <item android:state_enabled="true"
+ android:drawable="@drawable/btn_global_search_normal" />
+ <item android:state_focused="true"
+ android:drawable="@drawable/btn_global_search_normal" />
+ <item
+ android:drawable="@drawable/btn_global_search_normal" />
+</selector>
diff --git a/core/res/res/drawable/btn_global_search_normal.9.png b/core/res/res/drawable/btn_global_search_normal.9.png
new file mode 100644
index 0000000..9b7d3e5
--- /dev/null
+++ b/core/res/res/drawable/btn_global_search_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog.xml b/core/res/res/drawable/btn_search_dialog.xml
new file mode 100644
index 0000000..b7f5187
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_window_focused="false" android:state_enabled="true"
+ android:drawable="@drawable/btn_search_dialog_default" />
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_search_dialog_pressed" />
+
+ <item android:state_focused="true" android:state_enabled="true"
+ android:drawable="@drawable/btn_search_dialog_selected" />
+
+ <item android:state_enabled="true"
+ android:drawable="@drawable/btn_search_dialog_default" />
+
+ <item
+ android:drawable="@drawable/btn_search_dialog_default" />
+</selector>
diff --git a/core/res/res/drawable/btn_search_dialog_default.9.png b/core/res/res/drawable/btn_search_dialog_default.9.png
new file mode 100644
index 0000000..ec39178
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog_default.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_pressed.9.png b/core/res/res/drawable/btn_search_dialog_pressed.9.png
new file mode 100644
index 0000000..5f52fef
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_selected.9.png b/core/res/res/drawable/btn_search_dialog_selected.9.png
new file mode 100644
index 0000000..9fc2fde
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_voice.xml b/core/res/res/drawable/btn_search_dialog_voice.xml
new file mode 100644
index 0000000..748aaf5
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog_voice.xml
@@ -0,0 +1,33 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_window_focused="false" android:state_enabled="true"
+ android:drawable="@drawable/btn_search_dialog_voice_default" />
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_search_dialog_voice_pressed" />
+
+ <item android:state_focused="true" android:state_enabled="true"
+ android:drawable="@drawable/btn_search_dialog_voice_selected" />
+
+ <item android:state_enabled="true"
+ android:drawable="@drawable/btn_search_dialog_voice_default" />
+
+ <item
+ android:drawable="@drawable/btn_search_dialog_voice_default" />
+</selector>
diff --git a/core/res/res/drawable/btn_search_dialog_voice_default.9.png b/core/res/res/drawable/btn_search_dialog_voice_default.9.png
new file mode 100644
index 0000000..2a3366c
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog_voice_default.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_voice_pressed.9.png b/core/res/res/drawable/btn_search_dialog_voice_pressed.9.png
new file mode 100644
index 0000000..57d7a74
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog_voice_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_search_dialog_voice_selected.9.png b/core/res/res/drawable/btn_search_dialog_voice_selected.9.png
new file mode 100644
index 0000000..db3187e
--- /dev/null
+++ b/core/res/res/drawable/btn_search_dialog_voice_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable/search_dropdown_background.9.png b/core/res/res/drawable/search_dropdown_background.9.png
new file mode 100755
index 0000000..a6923b7
--- /dev/null
+++ b/core/res/res/drawable/search_dropdown_background.9.png
Binary files differ
diff --git a/core/res/res/drawable/search_plate_global.9.png b/core/res/res/drawable/search_plate_global.9.png
new file mode 100644
index 0000000..126054b
--- /dev/null
+++ b/core/res/res/drawable/search_plate_global.9.png
Binary files differ
diff --git a/core/res/res/drawable/textfield_search.xml b/core/res/res/drawable/textfield_search.xml
new file mode 100644
index 0000000..2923368
--- /dev/null
+++ b/core/res/res/drawable/textfield_search.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item android:state_window_focused="false" android:state_enabled="true"
+ android:drawable="@drawable/textfield_search_default" />
+
+ <item android:state_pressed="true"
+ android:drawable="@drawable/textfield_search_pressed" />
+
+ <item android:state_enabled="true" android:state_focused="true"
+ android:drawable="@drawable/textfield_search_selected" />
+
+ <item android:drawable="@drawable/textfield_search_default" />
+
+</selector>
+
diff --git a/core/res/res/drawable/textfield_search_default.9.png b/core/res/res/drawable/textfield_search_default.9.png
new file mode 100755
index 0000000..7dc5b27
--- /dev/null
+++ b/core/res/res/drawable/textfield_search_default.9.png
Binary files differ
diff --git a/core/res/res/drawable/textfield_search_pressed.9.png b/core/res/res/drawable/textfield_search_pressed.9.png
new file mode 100644
index 0000000..da00c25
--- /dev/null
+++ b/core/res/res/drawable/textfield_search_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/textfield_search_selected.9.png b/core/res/res/drawable/textfield_search_selected.9.png
new file mode 100755
index 0000000..a9fd3b2
--- /dev/null
+++ b/core/res/res/drawable/textfield_search_selected.9.png
Binary files differ
diff --git a/core/res/res/layout/resolve_list_item.xml b/core/res/res/layout/resolve_list_item.xml
index 5e296c5..4c5c456 100644
--- a/core/res/res/layout/resolve_list_item.xml
+++ b/core/res/res/layout/resolve_list_item.xml
@@ -23,7 +23,7 @@
android:minHeight="?android:attr/listPreferredItemHeight"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
- android:paddingLeft="14dip"
+ android:paddingLeft="10dip"
android:paddingRight="15dip">
<!-- Activity icon when presenting dialog -->
@@ -42,13 +42,13 @@
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingLeft="6dip" />
+ android:paddingLeft="10dip" />
<!-- Extended activity info to distinguish between duplicate activity names -->
<TextView android:id="@android:id/text2"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingLeft="6dip" />
+ android:paddingLeft="10dip" />
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml
index ef347da..6155626 100644
--- a/core/res/res/layout/search_bar.xml
+++ b/core/res/res/layout/search_bar.xml
@@ -26,79 +26,67 @@
android:orientation="vertical"
android:focusable="true"
android:descendantFocusability="afterDescendants">
- <!-- android:paddingBottom="14dip" TODO MUST FIX - it's a hack to get the popup to show -->
+ <!-- android:paddingBottom="200dip" TODO MUST FIX - it's a hack to get the popup to show -->
<!-- Outer layout defines the entire search bar at the top of the screen -->
- <!-- Bottom padding of 16 is due to the graphic, with 9 extra pixels of drop
- shadow, plus the desired padding of "8" against the user-visible (grey)
- pixels, minus "1" to correct for positioning of the edittext & button. -->
<LinearLayout
android:id="@+id/search_plate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingLeft="8dip"
- android:paddingRight="8dip"
- android:paddingTop="6dip"
+ android:paddingLeft="12dip"
+ android:paddingRight="12dip"
+ android:paddingTop="7dip"
android:paddingBottom="16dip"
- android:baselineAligned="false"
- android:background="@android:drawable/search_plate"
- android:addStatesFromChildren="true" >
+ android:background="@drawable/search_plate_global" >
<!-- This is actually used for the badge icon *or* the badge label (or neither) -->
<TextView
android:id="@+id/search_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:paddingLeft="2dip"
+ android:layout_marginBottom="2dip"
android:drawablePadding="0dip"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorPrimary" />
+ android:textColor="?android:attr/textColorPrimaryInverse" />
<!-- Inner layout contains the button(s) and EditText -->
- <!-- The layout_marginTop of "1" corrects for the extra 1 pixel of padding at the top of
- textfield_selected.9.png. The "real" margin as displayed is "2". -->
- <!-- The layout_marginBottom of "-5" corrects for the spacing we see at the
- bottom of the edittext and button images. The "real" margin as displayed is "8" -->
<LinearLayout
android:id="@+id/search_edit_frame"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="1dip"
- android:layout_marginBottom="-5dip"
- android:orientation="horizontal"
- android:addStatesFromChildren="true"
- android:gravity="center_vertical"
- android:baselineAligned="false" >
-
+ android:orientation="horizontal">
+
<view class="android.app.SearchDialog$SearchAutoComplete"
android:id="@+id/search_src_text"
+ android:background="@drawable/textfield_search"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1.0"
android:paddingLeft="8dip"
android:paddingRight="6dip"
+ android:singleLine="true"
android:inputType="text|textAutoComplete"
android:dropDownWidth="fill_parent"
android:dropDownAnchor="@id/search_plate"
- android:dropDownVerticalOffset="-15dip"
+ android:dropDownVerticalOffset="-9dip"
+ android:popupBackground="@android:drawable/search_dropdown_background"
/>
- <!-- android:focusableInTouchMode="false" -->
- <!-- android:singleLine="true" -->
- <!-- android:selectAllOnFocus="true" -->
<!-- This button can switch between text and icon "modes" -->
<Button
android:id="@+id/search_go_btn"
- android:layout_marginLeft="1dip"
+ android:background="@drawable/btn_search_dialog"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableLeft="@android:drawable/ic_btn_search"
+ android:layout_height="fill_parent"
/>
- <ImageButton android:id="@+id/search_voice_btn"
+ <ImageButton
+ android:id="@+id/search_voice_btn"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_marginLeft="8dip"
+ android:background="@drawable/btn_search_dialog_voice"
android:src="@android:drawable/ic_btn_speak_now"
/>
</LinearLayout>
diff --git a/core/res/res/layout/search_dropdown_item_1line.xml b/core/res/res/layout/search_dropdown_item_1line.xml
index 3827206..bf3dd48 100644
--- a/core/res/res/layout/search_dropdown_item_1line.xml
+++ b/core/res/res/layout/search_dropdown_item_1line.xml
@@ -20,7 +20,7 @@
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/dropDownItemStyle"
- android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
android:singleLine="true"
android:layout_width="fill_parent"
- android:layout_height="?android:attr/listPreferredItemHeight" />
+ android:layout_height="?android:attr/searchResultListItemHeight" />
\ No newline at end of file
diff --git a/core/res/res/layout/search_dropdown_item_2line.xml b/core/res/res/layout/search_dropdown_item_2line.xml
index 96d6005..5546b6636 100644
--- a/core/res/res/layout/search_dropdown_item_2line.xml
+++ b/core/res/res/layout/search_dropdown_item_2line.xml
@@ -20,15 +20,16 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_height="?android:attr/searchResultListItemHeight"
android:orientation="horizontal"
android:gravity="center_vertical"
android:baselineAligned="false"
>
<TwoLineListItem
- android:paddingTop="2dip"
- android:paddingBottom="2dip"
+ android:paddingTop="1dip"
+ android:paddingBottom="1dip"
+ android:gravity="center_vertical"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="wrap_content"
@@ -37,7 +38,7 @@
<TextView
android:id="@android:id/text1"
style="?android:attr/dropDownItemStyle"
- android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
android:singleLine="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
@@ -45,7 +46,7 @@
<TextView
android:id="@android:id/text2"
style="?android:attr/dropDownItemStyle"
- android:textAppearance="?android:attr/textAppearanceSmallInverse"
+ android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
android:textColor="?android:attr/textColorSecondaryInverse"
android:singleLine="true"
android:layout_width="fill_parent"
diff --git a/core/res/res/layout/search_dropdown_item_icons_1line.xml b/core/res/res/layout/search_dropdown_item_icons_1line.xml
index c0713d5..4f65d74 100644
--- a/core/res/res/layout/search_dropdown_item_icons_1line.xml
+++ b/core/res/res/layout/search_dropdown_item_icons_1line.xml
@@ -22,31 +22,33 @@
<!-- of the text element in apps/common/res/layout/simple_dropdown_item_1line.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingLeft="4dip"
+ android:paddingRight="2dip"
android:layout_width="fill_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
+ android:layout_height="?android:attr/searchResultListItemHeight"
android:orientation="horizontal"
android:gravity="center_vertical"
android:baselineAligned="false"
>
<ImageView android:id="@android:id/icon1"
- android:layout_width="32dip"
- android:layout_height="32dip"
+ android:layout_width="48dip"
+ android:layout_height="48dip"
android:layout_gravity="center_vertical"
- android:scaleType="fitCenter" />
+ android:scaleType="centerInside" />
<TextView android:id="@android:id/text1"
style="?android:attr/dropDownItemStyle"
- android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
android:singleLine="true"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1" />
<ImageView android:id="@android:id/icon2"
- android:layout_width="32dip"
- android:layout_height="32dip"
+ android:layout_width="48dip"
+ android:layout_height="48dip"
android:layout_gravity="center_vertical"
- android:scaleType="fitCenter" />
+ android:scaleType="centerInside" />
</LinearLayout>
diff --git a/core/res/res/layout/search_dropdown_item_icons_2line.xml b/core/res/res/layout/search_dropdown_item_icons_2line.xml
index ad1c905..0d07490 100644
--- a/core/res/res/layout/search_dropdown_item_icons_2line.xml
+++ b/core/res/res/layout/search_dropdown_item_icons_2line.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
-/* //device/apps/common/assets/res/any/layout/simple_spinner_item.xml
+/*
**
** Copyright 2008, The Android Open Source Project
**
@@ -18,56 +18,62 @@
*/
-->
- <!-- NOTE: The appearance of the inner text element must match the appearance -->
- <!-- of the text element in apps/common/res/layout/simple_dropdown_item_2line.xml -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:paddingLeft="4dip"
+ android:paddingRight="2dip"
android:layout_width="fill_parent"
- android:layout_height="?android:attr/listPreferredItemHeight"
- android:orientation="horizontal"
- android:gravity="center_vertical"
- android:baselineAligned="false"
- >
-
- <ImageView android:id="@android:id/icon1"
- android:layout_width="32dip"
- android:layout_height="32dip"
- android:layout_gravity="center_vertical"
- android:scaleType="fitCenter" />
+ android:layout_height="?android:attr/searchResultListItemHeight" >
- <TwoLineListItem
- android:paddingTop="2dip"
- android:paddingBottom="2dip"
- android:layout_width="0dip"
- android:layout_weight="1"
- android:layout_height="wrap_content"
- android:mode="twoLine" >
-
- <TextView
- android:id="@android:id/text1"
- style="?android:attr/dropDownItemStyle"
- android:textAppearance="?android:attr/textAppearanceMediumInverse"
- android:singleLine="true"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
-
- <TextView
- android:id="@android:id/text2"
- style="?android:attr/dropDownItemStyle"
- android:textAppearance="?android:attr/textAppearanceSmallInverse"
- android:textColor="?android:attr/textColorSecondaryInverse"
- android:singleLine="true"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_below="@android:id/text1"
- android:layout_alignLeft="@android:id/text1" />
-
- </TwoLineListItem>
+ <!-- Icons come first in the layout, since their placement doesn't depend on
+ the placement of the text views. -->
+ <ImageView android:id="@android:id/icon1"
+ android:layout_width="48dip"
+ android:layout_height="48dip"
+ android:scaleType="centerInside"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentBottom="true"
+ android:visibility="gone" />
<ImageView android:id="@android:id/icon2"
- android:layout_width="32dip"
- android:layout_height="32dip"
- android:layout_gravity="center_vertical"
- android:scaleType="fitCenter" />
+ android:layout_width="48dip"
+ android:layout_height="48dip"
+ android:scaleType="centerInside"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_alignParentBottom="true"
+ android:visibility="gone" />
-</LinearLayout>
+ <!-- The subtitle comes before the title, since the height of the title depends on whether the
+ subtitle is visible or gone. -->
+ <TextView android:id="@android:id/text2"
+ style="?android:attr/dropDownItemStyle"
+ android:textAppearance="?android:attr/textAppearanceSearchResultSubtitle"
+ android:singleLine="true"
+ android:layout_width="fill_parent"
+ android:layout_height="29dip"
+ android:paddingBottom="4dip"
+ android:gravity="top"
+ android:layout_toRightOf="@android:id/icon1"
+ android:layout_toLeftOf="@android:id/icon2"
+ android:layout_alignWithParentIfMissing="true"
+ android:layout_alignParentBottom="true"
+ android:visibility="gone" />
+
+ <!-- The title is placed above the subtitle, if there is one. If there is no
+ subtitle, it fills the parent. -->
+ <TextView android:id="@android:id/text1"
+ style="?android:attr/dropDownItemStyle"
+ android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
+ android:singleLine="true"
+ android:layout_width="fill_parent"
+ android:layout_height="29dip"
+ android:paddingTop="4dip"
+ android:gravity="center_vertical"
+ android:layout_alignParentTop="true"
+ android:layout_toRightOf="@android:id/icon1"
+ android:layout_toLeftOf="@android:id/icon2"
+ android:layout_above="@android:id/text2"
+ android:layout_alignWithParentIfMissing="true" />
+
+</RelativeLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b98558e..972953b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -94,6 +94,11 @@
<!-- Text color, typeface, size, and style for "small" inverse text. Defaults to secondary inverse text color. -->
<attr name="textAppearanceSmallInverse" format="reference" />
+ <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. @hide -->
+ <attr name="textAppearanceSearchResultTitle" format="reference" />
+ <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. @hide -->
+ <attr name="textAppearanceSearchResultSubtitle" format="reference" />
+
<!-- Text color, typeface, size, and style for the text inside of a button. -->
<attr name="textAppearanceButton" format="reference" />
@@ -147,6 +152,8 @@
<!-- The preferred list item height -->
<attr name="listPreferredItemHeight" format="dimension" />
<!-- The drawable for the list divider -->
+ <!-- The list item height for search results. @hide -->
+ <attr name="searchResultListItemHeight" format="dimension" />
<attr name="listDivider" format="reference" />
<!-- TextView style for list separators. -->
<attr name="listSeparatorTextViewStyle" format="reference" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8150a96..c35676c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -335,6 +335,11 @@
<string name="permgroupdesc_developmentTools">Features only needed for
application developers.</string>
+ <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permgrouplab_storage">Storage</string>
+ <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permgroupdesc_storage">Access the SD card.</string>
+
<!-- Permissions -->
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1045,6 +1050,11 @@
<string name="permdesc_writeDictionary">Allows an application to write new words into the
user dictionary.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_sdcardWrite">write to SD card</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_sdcardWrite">Allows an application to write to the SD card.</string>
+
<!-- The order of these is important, don't reorder without changing Contacts.java --> <skip />
<!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. -->
<string-array name="phoneTypes">
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index d7b654e..a436f61 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -138,6 +138,7 @@
</style>
<!-- Window animations that are applied to the search bar overlay window.
+ Previously used, but currently unused.
{@hide Pending API council approval} -->
<style name="Animation.SearchBar">
<item name="windowEnterAnimation">@anim/search_bar_enter</item>
@@ -574,6 +575,24 @@
<item name="android:textColor">@android:color/primary_text_light_disable_only</item>
</style>
+ <!-- @hide -->
+ <style name="TextAppearance.SearchResult">
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">?textColorPrimaryInverse</item>
+ <item name="android:textColorHint">?textColorHintInverse</item>
+ </style>
+
+ <!-- @hide -->
+ <style name="TextAppearance.SearchResult.Title">
+ <item name="android:textSize">16sp</item>
+ </style>
+
+ <!-- @hide -->
+ <style name="TextAppearance.SearchResult.Subtitle">
+ <item name="android:textSize">13sp</item>
+ <item name="android:textColor">?textColorSecondaryInverse</item>
+ </style>
+
<style name="TextAppearance.WindowTitle">
<item name="android:textColor">#fff</item>
<item name="android:textSize">14sp</item>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 6b3d740..dfd2391 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -57,6 +57,12 @@
<item name="textAppearanceLargeInverse">@android:style/TextAppearance.Large.Inverse</item>
<item name="textAppearanceMediumInverse">@android:style/TextAppearance.Medium.Inverse</item>
<item name="textAppearanceSmallInverse">@android:style/TextAppearance.Small.Inverse</item>
+
+ <!-- @hide -->
+ <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.SearchResult.Title</item>
+
+ <!-- @hide -->
+ <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.SearchResult.Subtitle</item>
<item name="textAppearanceButton">@android:style/TextAppearance.Widget.Button</item>
@@ -75,6 +81,8 @@
<!-- List attributes -->
<item name="listPreferredItemHeight">64dip</item>
+ <!-- @hide -->
+ <item name="searchResultListItemHeight">58dip</item>
<item name="listDivider">@drawable/divider_horizontal_dark</item>
<item name="listSeparatorTextViewStyle">@android:style/Widget.TextView.ListSeparator</item>
@@ -355,7 +363,6 @@
<!-- Theme for the search input bar. -->
<style name="Theme.SearchBar" parent="Theme.Panel">
<item name="android:backgroundDimEnabled">true</item>
- <item name="android:windowAnimationStyle">@android:style/Animation.SearchBar</item>
<item name="windowContentOverlay">@null</item>
</style>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index b13a292..f80bd6b 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -54,6 +54,10 @@
<group gid="log" />
</permission>
+ <permission name="android.permission.SDCARD_WRITE" >
+ <group gid="sdcard_rw" />
+ </permission>
+
<!-- The group that /cache belongs to, linked to the permission
set on the applications that can access /cache -->
<permission name="android.permission.ACCESS_CACHE_FILESYSTEM" >
diff --git a/include/ui/Camera.h b/include/ui/Camera.h
index e593fea..12fa20f 100644
--- a/include/ui/Camera.h
+++ b/include/ui/Camera.h
@@ -78,8 +78,8 @@
{
public:
// construct a camera client from an existing remote
- Camera(const sp<ICamera>& camera);
-
+ Camera(const sp<ICamera>& camera); // to be removed
+ static sp<Camera> create(const sp<ICamera>& camera);
static sp<Camera> connect();
~Camera();
void init();
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index d01d83f..9b8c302 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -988,119 +988,225 @@
return diffs;
}
- // Return true if 'this' is more specific than 'o'. Optionally, if
- // 'requested' is null, then they will also be compared against the
- // requested configuration and true will only be returned if 'this'
- // is a better candidate than 'o' for the configuration. This assumes that
- // match() has already been used to remove any configurations that don't
- // match the requested configuration at all; if they are not first filtered,
- // non-matching results can be considered better than matching ones.
+ // Return true if 'this' is more specific than 'o'.
inline bool
- isBetterThan(const ResTable_config& o, const ResTable_config* requested = NULL) const {
+ isMoreSpecificThan(const ResTable_config& o) const {
// The order of the following tests defines the importance of one
// configuration parameter over another. Those tests first are more
// important, trumping any values in those following them.
- if (imsi != 0 && (!requested || requested->imsi != 0)) {
- if (mcc != 0 && (!requested || requested->mcc != 0)) {
- if (o.mcc == 0) {
- return true;
- }
+ if (imsi || o.imsi) {
+ if (mcc != o.mcc) {
+ if (!mcc) return false;
+ if (!o.mcc) return true;
}
- if (mnc != 0 && (!requested || requested->mnc != 0)) {
- if (o.mnc == 0) {
- return true;
- }
+
+ if (mnc != o.mnc) {
+ if (!mnc) return false;
+ if (!o.mnc) return true;
}
}
- if (locale != 0 && (!requested || requested->locale != 0)) {
- if (language[0] != 0 && (!requested || requested->language[0] != 0)) {
- if (o.language[0] == 0) {
- return true;
- }
+
+ if (locale || o.locale) {
+ if (language[0] != o.language[0]) {
+ if (!language[0]) return false;
+ if (!o.language[0]) return true;
}
- if (country[0] != 0 && (!requested || requested->country[0] != 0)) {
- if (o.country[0] == 0) {
- return true;
- }
+
+ if (country[0] != o.country[0]) {
+ if (!country[0]) return false;
+ if (!o.country[0]) return true;
}
}
- if (screenType != 0 && (!requested || requested->screenType != 0)) {
- if (orientation != 0 && (!requested || requested->orientation != 0)) {
- if (o.orientation == 0) {
- return true;
- }
+
+ if (screenType || o.screenType) {
+ if (orientation != o.orientation) {
+ if (!orientation) return false;
+ if (!o.orientation) return true;
}
- if (density != 0 && (!requested || requested->density != 0)) {
- if (o.density == 0) {
- return true;
- }
- }
- if (touchscreen != 0 && (!requested || requested->touchscreen != 0)) {
- if (o.touchscreen == 0) {
- return true;
- }
+
+ // density is never 'more specific'
+ // as the default just equals 160
+
+ if (touchscreen != o.touchscreen) {
+ if (!touchscreen) return false;
+ if (!o.touchscreen) return true;
}
}
- if (input != 0 && (!requested || requested->input != 0)) {
- const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
- const int reqKeysHidden = requested
- ? requested->inputFlags&MASK_KEYSHIDDEN : 0;
- if (keysHidden != 0 && reqKeysHidden != 0) {
- const int oKeysHidden = o.inputFlags&MASK_KEYSHIDDEN;
- //LOGI("isBetterThan keysHidden: cur=%d, given=%d, config=%d\n",
- // keysHidden, oKeysHidden, reqKeysHidden);
- if (oKeysHidden == 0) {
- //LOGI("Better because 0!");
- return true;
- }
- // For compatibility, we count KEYSHIDDEN_NO as being
- // the same as KEYSHIDDEN_SOFT. Here we disambiguate these
- // may making an exact match more specific.
- if (keysHidden == reqKeysHidden && oKeysHidden != reqKeysHidden) {
- // The current configuration is an exact match, and
- // the given one is not, so the current one is better.
- //LOGI("Better because other not same!");
- return true;
- }
+
+ if (input || o.input) {
+ if (inputFlags != o.inputFlags) {
+ if (!(inputFlags & MASK_KEYSHIDDEN)) return false;
+ if (!(o.inputFlags & MASK_KEYSHIDDEN)) return true;
}
- if (keyboard != 0 && (!requested || requested->keyboard != 0)) {
- if (o.keyboard == 0) {
- return true;
- }
+
+ if (keyboard != o.keyboard) {
+ if (!keyboard) return false;
+ if (!o.keyboard) return true;
}
- if (navigation != 0 && (!requested || requested->navigation != 0)) {
- if (o.navigation == 0) {
- return true;
- }
+
+ if (navigation != o.navigation) {
+ if (!navigation) return false;
+ if (!o.navigation) return true;
}
}
- if (screenSize != 0 && (!requested || requested->screenSize != 0)) {
- if (screenWidth != 0 && (!requested || requested->screenWidth != 0)) {
- if (o.screenWidth == 0) {
- return true;
- }
+
+ if (screenSize || o.screenSize) {
+ if (screenWidth != o.screenWidth) {
+ if (!screenWidth) return false;
+ if (!o.screenWidth) return true;
}
- if (screenHeight != 0 && (!requested || requested->screenHeight != 0)) {
- if (o.screenHeight == 0) {
- return true;
- }
+
+ if (screenHeight != o.screenHeight) {
+ if (!screenHeight) return false;
+ if (!o.screenHeight) return true;
}
}
- if (version != 0 && (!requested || requested->version != 0)) {
- if (sdkVersion != 0 && (!requested || requested->sdkVersion != 0)) {
- if (o.sdkVersion == 0) {
- return true;
- }
+
+ if (version || o.version) {
+ if (sdkVersion != o.sdkVersion) {
+ if (!sdkVersion) return false;
+ if (!o.sdkVersion) return true;
}
- if (minorVersion != 0 && (!requested || requested->minorVersion != 0)) {
- if (o.minorVersion == 0) {
- return true;
- }
+
+ if (minorVersion != o.minorVersion) {
+ if (!minorVersion) return false;
+ if (!o.minorVersion) return true;
}
}
return false;
}
-
+
+ // Return true if 'this' is a better match than 'o' for the 'requested'
+ // configuration. This assumes that match() has already been used to
+ // remove any configurations that don't match the requested configuration
+ // at all; if they are not first filtered, non-matching results can be
+ // considered better than matching ones.
+ // The general rule per attribute: if the request cares about an attribute
+ // (it normally does), if the two (this and o) are equal it's a tie. If
+ // they are not equal then one must be generic because only generic and
+ // '==requested' will pass the match() call. So if this is not generic,
+ // it wins. If this IS generic, o wins (return false).
+ inline bool
+ isBetterThan(const ResTable_config& o,
+ const ResTable_config* requested) const {
+ if (requested) {
+ if (imsi || o.imsi) {
+ if ((mcc != o.mcc) && requested->mcc) {
+ return (mcc);
+ }
+
+ if ((mnc != o.mnc) && requested->mnc) {
+ return (mnc);
+ }
+ }
+
+ if (locale || o.locale) {
+ if ((language[0] != o.language[0]) && requested->language[0]) {
+ return (language[0]);
+ }
+
+ if ((country[0] != o.country[0]) && requested->country[0]) {
+ return (country[0]);
+ }
+ }
+
+ if (screenType || o.screenType) {
+ if ((orientation != o.orientation) && requested->orientation) {
+ return (orientation);
+ }
+
+ if (density != o.density) {
+ // density is tough. Any density is potentially useful
+ // because the system will scale it. Scaling down
+ // is generally better than scaling up.
+ // Default density counts as 160dpi (the system default)
+ // TODO - remove 160 constants
+ int h = (density?density:160);
+ int l = (o.density?o.density:160);
+ bool bImBigger = true;
+ if (l > h) {
+ int t = h;
+ h = l;
+ l = t;
+ bImBigger = false;
+ }
+
+ int reqValue = (requested->density?requested->density:160);
+ if (reqValue >= h) {
+ // requested value higher than both l and h, give h
+ return bImBigger;
+ }
+ if (l >= reqValue) {
+ // requested value lower than both l and h, give l
+ return !bImBigger;
+ }
+ // saying that scaling down is 2x better than up
+ if (((2 * l) - reqValue) * h > reqValue * reqValue) {
+ return !bImBigger;
+ } else {
+ return bImBigger;
+ }
+ }
+
+ if ((touchscreen != o.touchscreen) && requested->touchscreen) {
+ return (touchscreen);
+ }
+ }
+
+ if (input || o.input) {
+ const int keysHidden = inputFlags & MASK_KEYSHIDDEN;
+ const int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
+ if (keysHidden != oKeysHidden) {
+ const int reqKeysHidden =
+ requested->inputFlags & MASK_KEYSHIDDEN;
+ if (reqKeysHidden) {
+
+ if (!keysHidden) return false;
+ if (!oKeysHidden) return true;
+ // For compatibility, we count KEYSHIDDEN_NO as being
+ // the same as KEYSHIDDEN_SOFT. Here we disambiguate
+ // these by making an exact match more specific.
+ if (reqKeysHidden == keysHidden) return true;
+ if (reqKeysHidden == oKeysHidden) return false;
+ }
+ }
+
+ if ((keyboard != o.keyboard) && requested->keyboard) {
+ return (keyboard);
+ }
+
+ if ((navigation != o.navigation) && requested->navigation) {
+ return (navigation);
+ }
+ }
+
+ if (screenSize || o.screenSize) {
+ if ((screenWidth != o.screenWidth) && requested->screenWidth) {
+ return (screenWidth);
+ }
+
+ if ((screenHeight != o.screenHeight) &&
+ requested->screenHeight) {
+ return (screenHeight);
+ }
+ }
+
+ if (version || o.version) {
+ if ((sdkVersion != o.sdkVersion) && requested->sdkVersion) {
+ return (sdkVersion);
+ }
+
+ if ((minorVersion != o.minorVersion) &&
+ requested->minorVersion) {
+ return (minorVersion);
+ }
+ }
+
+ return false;
+ }
+ return isMoreSpecificThan(o);
+ }
+
// Return true if 'this' can be considered a match for the parameters in
// 'settings'.
// Note this is asymetric. A default piece of data will match every request
@@ -1137,8 +1243,7 @@
&& orientation != settings.orientation) {
return false;
}
- // Density not taken into account, always match, no matter what
- // density is specified for the resource
+ // density always matches - we can scale it. See isBetterThan
if (settings.touchscreen != 0 && touchscreen != 0
&& touchscreen != settings.touchscreen) {
return false;
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
index b3cbda1..0fba82c 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/ui/Camera.cpp
@@ -75,6 +75,19 @@
}
}
+
+sp<Camera> Camera::create(const sp<ICamera>& camera)
+{
+ sp<Camera> c = new Camera();
+ // connect this client to existing camera remote
+ if (camera->connect(c) == NO_ERROR) {
+ c->mStatus = NO_ERROR;
+ c->mCamera = camera;
+ camera->asBinder()->linkToDeath(c);
+ }
+ return c;
+}
+
void Camera::init()
{
mStatus = UNKNOWN_ERROR;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 2ad3bfe..3d12dca 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1820,7 +1820,7 @@
}
}
- if (bestPackage != NULL && bestItem.isBetterThan(thisConfig)) {
+ if (bestPackage != NULL && bestItem.isMoreSpecificThan(thisConfig)) {
continue;
}
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 3b4c041..c44478d 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -1,17 +1,17 @@
-/*
+/*
**
** Copyright 2007 The Android Open Source Project
**
-** Licensed under the Apache License Version 2.0(the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
+** Licensed under the Apache License Version 2.0(the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
**
-** http://www.apache.org/licenses/LICENSE-2.0
+** http://www.apache.org/licenses/LICENSE-2.0
**
-** Unless required by applicable law or agreed to in writing software
-** distributed under the License is distributed on an "AS IS" BASIS
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
-** See the License for the specific language governing permissions and
+** Unless required by applicable law or agreed to in writing software
+** distributed under the License is distributed on an "AS IS" BASIS
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+** See the License for the specific language governing permissions and
** limitations under the License.
*/
@@ -478,22 +478,38 @@
};
static const extention_map_t gExtentionMap[] = {
- { "glDrawTexsOES", (void(*)())&glDrawTexsOES },
- { "glDrawTexiOES", (void(*)())&glDrawTexiOES },
- { "glDrawTexfOES", (void(*)())&glDrawTexfOES },
- { "glDrawTexxOES", (void(*)())&glDrawTexxOES },
- { "glDrawTexsvOES", (void(*)())&glDrawTexsvOES },
- { "glDrawTexivOES", (void(*)())&glDrawTexivOES },
- { "glDrawTexfvOES", (void(*)())&glDrawTexfvOES },
- { "glDrawTexxvOES", (void(*)())&glDrawTexxvOES },
- { "glQueryMatrixxOES", (void(*)())&glQueryMatrixxOES },
- { "glClipPlanef", (void(*)())&glClipPlanef },
- { "glClipPlanex", (void(*)())&glClipPlanex },
- { "glBindBuffer", (void(*)())&glBindBuffer },
- { "glBufferData", (void(*)())&glBufferData },
- { "glBufferSubData", (void(*)())&glBufferSubData },
- { "glDeleteBuffers", (void(*)())&glDeleteBuffers },
- { "glGenBuffers", (void(*)())&glGenBuffers },
+ { "glDrawTexsOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexsOES },
+ { "glDrawTexiOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexiOES },
+ { "glDrawTexfOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexfOES },
+ { "glDrawTexxOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexxOES },
+ { "glDrawTexsvOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexsvOES },
+ { "glDrawTexivOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexivOES },
+ { "glDrawTexfvOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexfvOES },
+ { "glDrawTexxvOES",
+ (__eglMustCastToProperFunctionPointerType)&glDrawTexxvOES },
+ { "glQueryMatrixxOES",
+ (__eglMustCastToProperFunctionPointerType)&glQueryMatrixxOES },
+ { "glClipPlanef",
+ (__eglMustCastToProperFunctionPointerType)&glClipPlanef },
+ { "glClipPlanex",
+ (__eglMustCastToProperFunctionPointerType)&glClipPlanex },
+ { "glBindBuffer",
+ (__eglMustCastToProperFunctionPointerType)&glBindBuffer },
+ { "glBufferData",
+ (__eglMustCastToProperFunctionPointerType)&glBufferData },
+ { "glBufferSubData",
+ (__eglMustCastToProperFunctionPointerType)&glBufferSubData },
+ { "glDeleteBuffers",
+ (__eglMustCastToProperFunctionPointerType)&glDeleteBuffers },
+ { "glGenBuffers",
+ (__eglMustCastToProperFunctionPointerType)&glGenBuffers },
};
/*
@@ -1299,6 +1315,8 @@
}
}
+ // TODO: call connect / disconnect on the surface
+
ogles_context_t* gl = (ogles_context_t*)ctx;
if (makeCurrent(gl) == 0) {
if (ctx) {
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 2ecc7768..d636d73 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -35,7 +35,6 @@
LOCAL_SRC_FILES:= \
GLES_CM/gl.cpp.arm \
- GLES_CM/gl_logger.cpp \
#
LOCAL_SHARED_LIBRARIES += libcutils libutils libui libEGL
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 0b4bcce..6fc0fed 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -14,7 +14,7 @@
** limitations under the License.
*/
-#define LOG_TAG "GLLogger"
+#define LOG_TAG "libEGL"
#include <ctype.h>
#include <string.h>
@@ -69,9 +69,9 @@
struct egl_display_t : public egl_object_t<'_dpy'>
{
- EGLDisplay dpys[2];
- EGLConfig* configs[2];
- EGLint numConfigs[2];
+ EGLDisplay dpys[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+ EGLConfig* configs[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
+ EGLint numConfigs[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
EGLint numTotalConfigs;
char const* extensionsString;
volatile int32_t refs;
@@ -81,7 +81,7 @@
char const * clientApi;
char const * extensions;
};
- strings_t queryString[2];
+ strings_t queryString[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
};
struct egl_surface_t : public egl_object_t<'_srf'>
@@ -143,6 +143,7 @@
static char const * const gl_names[] = {
#include "gl_entries.in"
+ #include "glext_entries.in"
NULL
};
@@ -156,7 +157,7 @@
// ----------------------------------------------------------------------------
-egl_connection_t gEGLImpl[2];
+egl_connection_t gEGLImpl[IMPL_NUM_DRIVERS_IMPLEMENTATIONS];
static egl_display_t gDisplay[NUM_DISPLAYS];
static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t gEGLThreadLocalStorageKey = -1;
@@ -278,29 +279,51 @@
driver, dlerror());
if (dso) {
- void** curr;
+ // first find the symbol for eglGetProcAddress
+
+ typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)(
+ const char*);
+
+ getProcAddressType getProcAddress =
+ (getProcAddressType)dlsym(dso, "eglGetProcAddress");
+
+ LOGE_IF(!getProcAddress,
+ "can't find eglGetProcAddress() in %s", driver);
+
+ __eglMustCastToProperFunctionPointerType* curr;
char const * const * api;
- gl_hooks_t::gl_t* gl = &hooks->gl;
- curr = (void**)gl;
- api = gl_names;
+
+ gl_hooks_t::egl_t* egl = &hooks->egl;
+ curr = (__eglMustCastToProperFunctionPointerType*)egl;
+ api = egl_names;
while (*api) {
- void* f = dlsym(dso, *api);
- //LOGD("<%s> @ 0x%p", *api, f);
+ char const * name = *api;
+ __eglMustCastToProperFunctionPointerType f =
+ (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
if (f == NULL) {
- //LOGW("<%s> not found in %s", *api, driver);
- f = (void*)gl_unimplemented;
+ // couldn't find the entry-point, use eglGetProcAddress()
+ f = getProcAddress(name);
+ if (f == NULL) {
+ f = (__eglMustCastToProperFunctionPointerType)0;
+ }
}
*curr++ = f;
api++;
}
- gl_hooks_t::egl_t* egl = &hooks->egl;
- curr = (void**)egl;
- api = egl_names;
+
+ gl_hooks_t::gl_t* gl = &hooks->gl;
+ curr = (__eglMustCastToProperFunctionPointerType*)gl;
+ api = gl_names;
while (*api) {
- void* f = dlsym(dso, *api);
+ char const * name = *api;
+ __eglMustCastToProperFunctionPointerType f =
+ (__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
if (f == NULL) {
- //LOGW("<%s> not found in %s", *api, driver);
- f = (void*)0;
+ // couldn't find the entry-point, use eglGetProcAddress()
+ f = getProcAddress(name);
+ if (f == NULL) {
+ f = (__eglMustCastToProperFunctionPointerType)gl_unimplemented;
+ }
}
*curr++ = f;
api++;
@@ -429,18 +452,19 @@
return (index >= NUM_DISPLAYS) ? NULL : &gDisplay[index];
}
-static inline
-egl_surface_t* get_surface(EGLSurface surface)
-{
- egl_surface_t* s = (egl_surface_t *)surface;
- return s;
+template<typename NATIVE, typename EGL>
+static inline NATIVE* egl_to_native_cast(EGL arg) {
+ return reinterpret_cast<NATIVE*>(arg);
}
static inline
-egl_context_t* get_context(EGLContext context)
-{
- egl_context_t* c = (egl_context_t *)context;
- return c;
+egl_surface_t* get_surface(EGLSurface surface) {
+ return egl_to_native_cast<egl_surface_t>(surface);
+}
+
+static inline
+egl_context_t* get_context(EGLContext context) {
+ return egl_to_native_cast<egl_context_t>(context);
}
static egl_connection_t* validate_display_config(
@@ -451,7 +475,7 @@
if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL);
impl = uintptr_t(config)>>24;
- if (uint32_t(impl) >= 2) {
+ if (uint32_t(impl) >= IMPL_NUM_DRIVERS_IMPLEMENTATIONS) {
return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
}
index = uintptr_t(config) & 0xFFFFFF;
@@ -491,13 +515,8 @@
return EGL_TRUE;
}
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
-using namespace android;
-
-EGLDisplay eglGetDisplay(NativeDisplayType display)
+EGLDisplay egl_init_displays(NativeDisplayType display)
{
if (sEarlyInitState) {
return EGL_NO_DISPLAY;
@@ -510,7 +529,7 @@
EGLDisplay dpy = EGLDisplay(uintptr_t(display) + 1LU);
egl_display_t* d = &gDisplay[index];
-
+
// dynamically load all our EGL implementations for that display
// and call into the real eglGetGisplay()
egl_connection_t* cnx = &gEGLImpl[IMPL_SOFTWARE];
@@ -573,6 +592,18 @@
return dpy;
}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
+using namespace android;
+
+EGLDisplay eglGetDisplay(NativeDisplayType display)
+{
+ return egl_init_displays(display);
+}
+
// ----------------------------------------------------------------------------
// Initialization
// ----------------------------------------------------------------------------
@@ -594,7 +625,7 @@
// build our own extension string first, based on the extension we know
// and the extension supported by our client implementation
dp->extensionsString = strdup(gExtensionString);
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
cnx->major = -1;
cnx->minor = -1;
@@ -624,7 +655,7 @@
}
EGLBoolean res = EGL_FALSE;
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso && cnx->major>=0 && cnx->minor>=0) {
EGLint n;
@@ -663,7 +694,7 @@
return EGL_TRUE;
EGLBoolean res = EGL_FALSE;
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
cnx->hooks->egl.eglTerminate(dp->dpys[i]);
@@ -706,7 +737,7 @@
return EGL_TRUE;
}
GLint n = 0;
- for (int j=0 ; j<2 ; j++) {
+ for (int j=0 ; j<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; j++) {
for (int i=0 ; i<dp->numConfigs[j] && config_size ; i++) {
*configs++ = MAKE_CONFIG(j, i);
config_size--;
@@ -794,7 +825,7 @@
return res;
}
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->hooks->egl.eglChooseConfig(
@@ -1107,7 +1138,7 @@
EGLint eglGetError(void)
{
EGLint result = EGL_SUCCESS;
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
EGLint err = EGL_SUCCESS;
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso)
@@ -1120,8 +1151,15 @@
return result;
}
-void (*eglGetProcAddress(const char *procname))()
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
{
+ // eglGetProcAddress() could be the very first function called
+ // in which case we must make sure we've initialized ourselves, this
+ // happens the first time egl_get_display() is called.
+
+ if (egl_init_displays(EGL_DEFAULT_DISPLAY) == EGL_NO_DISPLAY)
+ return NULL;
+
__eglMustCastToProperFunctionPointerType addr;
addr = findProcAddress(procname, gExtentionMap, NELEM(gExtentionMap));
if (addr) return addr;
@@ -1133,7 +1171,7 @@
addr = 0;
int slot = -1;
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->hooks->egl.eglGetProcAddress) {
@@ -1266,7 +1304,7 @@
if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
EGLBoolean res = EGL_TRUE;
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->hooks->egl.eglSwapInterval) {
@@ -1309,7 +1347,7 @@
{
// bind this API on all EGLs
EGLBoolean res = EGL_TRUE;
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->hooks->egl.eglBindAPI) {
@@ -1324,7 +1362,7 @@
EGLenum eglQueryAPI(void)
{
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->hooks->egl.eglQueryAPI) {
@@ -1340,7 +1378,7 @@
EGLBoolean eglReleaseThread(void)
{
- for (int i=0 ; i<2 ; i++) {
+ for (int i=0 ; i<IMPL_NUM_DRIVERS_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {
if (cnx->hooks->egl.eglReleaseThread) {
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index 865cf44..0057168 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -29,6 +29,7 @@
#include <cutils/properties.h>
#include "hooks.h"
+#include "egl_impl.h"
using namespace android;
@@ -57,13 +58,6 @@
// Actual GL entry-points
// ----------------------------------------------------------------------------
-#if GL_LOGGER
-# include "gl_logger.h"
-# define GL_LOGGER_IMPL(_x) _x
-#else
-# define GL_LOGGER_IMPL(_x)
-#endif
-
#undef API_ENTRY
#undef CALL_GL_API
#undef CALL_GL_API_RETURN
@@ -96,21 +90,36 @@
#define CALL_GL_API(_api, ...) \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
- GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); ) \
_c->_api(__VA_ARGS__)
#define CALL_GL_API_RETURN(_api, ...) \
gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \
- GL_LOGGER_IMPL( log_##_api(__VA_ARGS__); ) \
return _c->_api(__VA_ARGS__)
#endif
+
extern "C" {
#include "gl_api.in"
+#include "glext_api.in"
}
#undef API_ENTRY
#undef CALL_GL_API
#undef CALL_GL_API_RETURN
+
+/*
+ * These GL calls are special because they need to call into EGL to retrieve
+ * some informations before they can execute.
+ */
+
+
+void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
+{
+}
+
+void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
+{
+}
+
diff --git a/opengl/libs/GLES_CM/gl_api.in b/opengl/libs/GLES_CM/gl_api.in
index 9234ef2..5437d47 100644
--- a/opengl/libs/GLES_CM/gl_api.in
+++ b/opengl/libs/GLES_CM/gl_api.in
@@ -1,532 +1,285 @@
-void API_ENTRY(glActiveTexture)(GLenum texture) {
- CALL_GL_API(glActiveTexture, texture);
-}
-
void API_ENTRY(glAlphaFunc)(GLenum func, GLclampf ref) {
CALL_GL_API(glAlphaFunc, func, ref);
}
-
-void API_ENTRY(glAlphaFuncx)(GLenum func, GLclampx ref) {
- CALL_GL_API(glAlphaFuncx, func, ref);
-}
-
-void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
- CALL_GL_API(glBindTexture, target, texture);
-}
-
-void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
- CALL_GL_API(glBlendFunc, sfactor, dfactor);
-}
-
-void API_ENTRY(glClear)(GLbitfield mask) {
- CALL_GL_API(glClear, mask);
-}
-
void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
CALL_GL_API(glClearColor, red, green, blue, alpha);
}
-
-void API_ENTRY(glClearColorx)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
- CALL_GL_API(glClearColorx, red, green, blue, alpha);
-}
-
void API_ENTRY(glClearDepthf)(GLclampf depth) {
CALL_GL_API(glClearDepthf, depth);
}
-
-void API_ENTRY(glClearDepthx)(GLclampx depth) {
- CALL_GL_API(glClearDepthx, depth);
-}
-
-void API_ENTRY(glClearStencil)(GLint s) {
- CALL_GL_API(glClearStencil, s);
-}
-
-void API_ENTRY(glClientActiveTexture)(GLenum texture) {
- CALL_GL_API(glClientActiveTexture, texture);
-}
-
-void API_ENTRY(glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
- CALL_GL_API(glColor4f, red, green, blue, alpha);
-}
-
-void API_ENTRY(glColor4x)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
- CALL_GL_API(glColor4x, red, green, blue, alpha);
-}
-
-void API_ENTRY(glColorMask)(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
- CALL_GL_API(glColorMask, r, g, b, a);
-}
-
-void API_ENTRY(glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
-{
- CALL_GL_API(glColorPointer, size, type, stride, ptr);
-}
-
-void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLint border,
- GLsizei imageSize, const GLvoid *data) {
- CALL_GL_API(glCompressedTexImage2D, target, level, internalformat,
- width, height, border, imageSize, data);
-}
-
-void API_ENTRY(glCompressedTexSubImage2D)( GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize,
- const GLvoid *data) {
- CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset,
- width, height, format, imageSize, data);
-}
-
-void API_ENTRY(glCopyTexImage2D)( GLenum target, GLint level, GLenum internalformat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border) {
- CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y,
- width, height, border);
-}
-
-void API_ENTRY(glCopyTexSubImage2D)( GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLint x, GLint y, GLsizei width,
- GLsizei height) {
- CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y,
- width, height);
-}
-
-void API_ENTRY(glCullFace)(GLenum mode) {
- CALL_GL_API(glCullFace, mode);
-}
-
-void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) {
- CALL_GL_API(glDeleteTextures, n, textures);
-}
-
-void API_ENTRY(glDepthFunc)(GLenum func) {
- CALL_GL_API(glDepthFunc, func);
-}
-
-void API_ENTRY(glDepthMask)(GLboolean flag) {
- CALL_GL_API(glDepthMask, flag);
-}
-
-void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
- CALL_GL_API(glDepthRangef, zNear, zFar);
-}
-
-void API_ENTRY(glDepthRangex)(GLclampx zNear, GLclampx zFar) {
- CALL_GL_API(glDepthRangex, zNear, zFar);
-}
-
-void API_ENTRY(glDisable)(GLenum cap) {
- CALL_GL_API(glDisable, cap);
-}
-
-void API_ENTRY(glDisableClientState)(GLenum array) {
- CALL_GL_API(glDisableClientState, array);
-}
-
-void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
- CALL_GL_API(glDrawArrays, mode, first, count);
-}
-
-void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count,
- GLenum type, const GLvoid *indices) {
- CALL_GL_API(glDrawElements, mode, count, type, indices);
-}
-
-void API_ENTRY(glEnable)(GLenum cap) {
- CALL_GL_API(glEnable, cap);
-}
-
-void API_ENTRY(glEnableClientState)(GLenum array) {
- CALL_GL_API(glEnableClientState, array);
-}
-
-void API_ENTRY(glFinish)(void) {
- CALL_GL_API(glFinish);
-}
-
-void API_ENTRY(glFlush)(void) {
- CALL_GL_API(glFlush);
-}
-
-void API_ENTRY(glFogf)(GLenum pname, GLfloat param) {
- CALL_GL_API(glFogf, pname, param);
-}
-
-void API_ENTRY(glFogfv)(GLenum pname, const GLfloat *params) {
- CALL_GL_API(glFogfv, pname, params);
-}
-
-void API_ENTRY(glFogx)(GLenum pname, GLfixed param) {
- CALL_GL_API(glFogx, pname, param);
-}
-
-void API_ENTRY(glFogxv)(GLenum pname, const GLfixed *params) {
- CALL_GL_API(glFogxv, pname, params);
-}
-
-void API_ENTRY(glFrontFace)(GLenum mode) {
- CALL_GL_API(glFrontFace, mode);
-}
-
-void API_ENTRY(glFrustumf)(GLfloat left, GLfloat right,
- GLfloat bottom, GLfloat top,
- GLfloat zNear, GLfloat zFar) {
- CALL_GL_API(glFrustumf, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glFrustumx)(GLfixed left, GLfixed right,
- GLfixed bottom, GLfixed top,
- GLfixed zNear, GLfixed zFar) {
- CALL_GL_API(glFrustumx, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) {
- CALL_GL_API(glGenTextures, n, textures);
-}
-
-GLenum API_ENTRY(glGetError)(void) {
- CALL_GL_API_RETURN(glGetError);
-}
-
-void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *params) {
- CALL_GL_API(glGetIntegerv, pname, params);
-}
-
-const GLubyte * API_ENTRY(glGetString)(GLenum name) {
- CALL_GL_API_RETURN(glGetString, name);
-}
-
-void API_ENTRY(glHint)(GLenum target, GLenum mode) {
- CALL_GL_API(glHint, target, mode);
-}
-
-void API_ENTRY(glLightModelf)(GLenum pname, GLfloat param) {
- CALL_GL_API(glLightModelf, pname, param);
-}
-
-void API_ENTRY(glLightModelfv)(GLenum pname, const GLfloat *params) {
- CALL_GL_API(glLightModelfv, pname, params);
-}
-
-void API_ENTRY(glLightModelx)(GLenum pname, GLfixed param) {
- CALL_GL_API(glLightModelx, pname, param);
-}
-
-void API_ENTRY(glLightModelxv)(GLenum pname, const GLfixed *params) {
- CALL_GL_API(glLightModelxv, pname, params);
-}
-
-void API_ENTRY(glLightf)(GLenum light, GLenum pname, GLfloat param) {
- CALL_GL_API(glLightf, light, pname, param);
-}
-
-void API_ENTRY(glLightfv)(GLenum light, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glLightfv, light, pname, params);
-}
-
-void API_ENTRY(glLightx)(GLenum light, GLenum pname, GLfixed param) {
- CALL_GL_API(glLightx, light, pname, param);
-}
-
-void API_ENTRY(glLightxv)(GLenum light, GLenum pname, const GLfixed *params) {
- CALL_GL_API(glLightxv, light, pname, params);
-}
-
-void API_ENTRY(glLineWidth)(GLfloat width) {
- CALL_GL_API(glLineWidth, width);
-}
-
-void API_ENTRY(glLineWidthx)(GLfixed width) {
- CALL_GL_API(glLineWidthx, width);
-}
-
-void API_ENTRY(glLoadIdentity)(void) {
- CALL_GL_API(glLoadIdentity);
-}
-
-void API_ENTRY(glLoadMatrixf)(const GLfloat *m) {
- CALL_GL_API(glLoadMatrixf, m);
-}
-
-void API_ENTRY(glLoadMatrixx)(const GLfixed *m) {
- CALL_GL_API(glLoadMatrixx, m);
-}
-
-void API_ENTRY(glLogicOp)(GLenum opcode) {
- CALL_GL_API(glLogicOp, opcode);
-}
-
-void API_ENTRY(glMaterialf)(GLenum face, GLenum pname, GLfloat param) {
- CALL_GL_API(glMaterialf, face, pname, param);
-}
-
-void API_ENTRY(glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glMaterialfv, face, pname, params);
-}
-
-void API_ENTRY(glMaterialx)(GLenum face, GLenum pname, GLfixed param) {
- CALL_GL_API(glMaterialx, face, pname, param);
-}
-
-void API_ENTRY(glMaterialxv)(GLenum face, GLenum pname, const GLfixed *params) {
- CALL_GL_API(glMaterialxv, face, pname, params);
-}
-
-void API_ENTRY(glMatrixMode)(GLenum mode) {
- CALL_GL_API(glMatrixMode, mode);
-}
-
-void API_ENTRY(glMultMatrixf)(const GLfloat *m) {
- CALL_GL_API(glMultMatrixf, m);
-}
-
-void API_ENTRY(glMultMatrixx)(const GLfixed *m) {
- CALL_GL_API(glMultMatrixx, m);
-}
-
-void API_ENTRY(glMultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
- CALL_GL_API(glMultiTexCoord4f, target, s, t, r, q);
-}
-
-void API_ENTRY(glMultiTexCoord4x)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
- CALL_GL_API(glMultiTexCoord4x, target, s, t, r, q);
-}
-
-void API_ENTRY(glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) {
- CALL_GL_API(glNormal3f, nx, ny, nz);
-}
-
-void API_ENTRY(glNormal3x)(GLfixed nx, GLfixed ny, GLfixed nz) {
- CALL_GL_API(glNormal3x, nx, ny, nz);
-}
-
-void API_ENTRY(glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) {
- CALL_GL_API(glNormalPointer, type, stride, pointer);
-}
-
-void API_ENTRY(glOrthof)( GLfloat left, GLfloat right,
- GLfloat bottom, GLfloat top,
- GLfloat zNear, GLfloat zFar) {
- CALL_GL_API(glOrthof, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glOrthox)( GLfixed left, GLfixed right,
- GLfixed bottom, GLfixed top,
- GLfixed zNear, GLfixed zFar) {
- CALL_GL_API(glOrthox, left, right, bottom, top, zNear, zFar);
-}
-
-void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
- CALL_GL_API(glPixelStorei, pname, param);
-}
-
-void API_ENTRY(glPointSize)(GLfloat size) {
- CALL_GL_API(glPointSize, size);
-}
-
-void API_ENTRY(glPointSizex)(GLfixed size) {
- CALL_GL_API(glPointSizex, size);
-}
-
-void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
- CALL_GL_API(glPolygonOffset, factor, units);
-}
-
-void API_ENTRY(glPolygonOffsetx)(GLfixed factor, GLfixed units) {
- CALL_GL_API(glPolygonOffsetx, factor, units);
-}
-
-void API_ENTRY(glPopMatrix)(void) {
- CALL_GL_API(glPopMatrix);
-}
-
-void API_ENTRY(glPushMatrix)(void) {
- CALL_GL_API(glPushMatrix);
-}
-
-void API_ENTRY(glReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLvoid *pixels) {
- CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
-}
-
-void API_ENTRY(glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glRotatef, angle, x, y, z);
-}
-
-void API_ENTRY(glRotatex)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
- CALL_GL_API(glRotatex, angle, x, y, z);
-}
-
-void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
- CALL_GL_API(glSampleCoverage, value, invert);
-}
-
-void API_ENTRY(glSampleCoveragex)(GLclampx value, GLboolean invert) {
- CALL_GL_API(glSampleCoveragex, value, invert);
-}
-
-void API_ENTRY(glScalef)(GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glScalef, x, y, z);
-}
-
-void API_ENTRY(glScalex)(GLfixed x, GLfixed y, GLfixed z) {
- CALL_GL_API(glScalex, x, y, z);
-}
-
-void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
- CALL_GL_API(glScissor, x, y, width, height);
-}
-
-void API_ENTRY(glShadeModel)(GLenum mode) {
- CALL_GL_API(glShadeModel, mode);
-}
-
-void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
- CALL_GL_API(glStencilFunc, func, ref, mask);
-}
-
-void API_ENTRY(glStencilMask)(GLuint mask) {
- CALL_GL_API(glStencilMask, mask);
-}
-
-void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
- CALL_GL_API(glStencilOp, fail, zfail, zpass);
-}
-
-void API_ENTRY(glTexCoordPointer)( GLint size, GLenum type,
- GLsizei stride, const GLvoid *pointer) {
- CALL_GL_API(glTexCoordPointer, size, type, stride, pointer);
-}
-
-void API_ENTRY(glTexEnvf)(GLenum target, GLenum pname, GLfloat param) {
- CALL_GL_API(glTexEnvf, target, pname, param);
-}
-
-void API_ENTRY(glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glTexEnvfv, target, pname, params);
-}
-
-void API_ENTRY(glTexEnvx)(GLenum target, GLenum pname, GLfixed param) {
- CALL_GL_API(glTexEnvx, target, pname, param);
-}
-
-void API_ENTRY(glTexEnvxv)(GLenum target, GLenum pname, const GLfixed *params) {
- CALL_GL_API(glTexEnvxv, target, pname, params);
-}
-
-void API_ENTRY(glTexImage2D)( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLint border, GLenum format,
- GLenum type, const GLvoid *pixels) {
- CALL_GL_API(glTexImage2D, target, level, internalformat, width, height,
- border, format, type, pixels);
-}
-
-void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
- CALL_GL_API(glTexParameterf, target, pname, param);
-}
-
-void API_ENTRY(glTexParameterx)(GLenum target, GLenum pname, GLfixed param) {
- CALL_GL_API(glTexParameterx, target, pname, param);
-}
-
-void API_ENTRY(glTexSubImage2D)( GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid *pixels) {
- CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset,
- width, height, format, type, pixels);
-}
-
-void API_ENTRY(glTranslatef)(GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glTranslatef, x, y, z);
-}
-
-void API_ENTRY(glTranslatex)(GLfixed x, GLfixed y, GLfixed z) {
- CALL_GL_API(glTranslatex, x, y, z);
-}
-
-void API_ENTRY(glVertexPointer)( GLint size, GLenum type,
- GLsizei stride, const GLvoid *pointer) {
- CALL_GL_API(glVertexPointer, size, type, stride, pointer);
-}
-
-void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
- CALL_GL_API(glViewport, x, y, width, height);
-}
-
-// ES 1.1
void API_ENTRY(glClipPlanef)(GLenum plane, const GLfloat *equation) {
CALL_GL_API(glClipPlanef, plane, equation);
}
-void API_ENTRY(glClipPlanex)(GLenum plane, const GLfixed *equation) {
- CALL_GL_API(glClipPlanex, plane, equation);
+void API_ENTRY(glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
+ CALL_GL_API(glColor4f, red, green, blue, alpha);
}
-void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
- CALL_GL_API(glBindBuffer, target, buffer);
+void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
+ CALL_GL_API(glDepthRangef, zNear, zFar);
}
-void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
- CALL_GL_API(glBufferData, target, size, data, usage);
+void API_ENTRY(glFogf)(GLenum pname, GLfloat param) {
+ CALL_GL_API(glFogf, pname, param);
}
-void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
- CALL_GL_API(glBufferSubData, target, offset, size, data);
+void API_ENTRY(glFogfv)(GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glFogfv, pname, params);
}
-void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) {
- CALL_GL_API(glDeleteBuffers, n, buffers);
-}
-void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) {
- CALL_GL_API(glGenBuffers, n, buffers);
-}
-void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *params) {
- CALL_GL_API(glGetBooleanv, pname, params);
-}
-void API_ENTRY(glGetFixedv)(GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetFixedv, pname, params);
-}
-void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *params) {
- CALL_GL_API(glGetFloatv, pname, params);
-}
-void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
- CALL_GL_API(glGetPointerv, pname, params);
-}
-void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
- CALL_GL_API(glGetBufferParameteriv, target, pname, params);
+void API_ENTRY(glFrustumf)(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+ CALL_GL_API(glFrustumf, left, right, bottom, top, zNear, zFar);
}
void API_ENTRY(glGetClipPlanef)(GLenum pname, GLfloat eqn[4]) {
CALL_GL_API(glGetClipPlanef, pname, eqn);
}
-void API_ENTRY(glGetClipPlanex)(GLenum pname, GLfixed eqn[4]) {
- CALL_GL_API(glGetClipPlanex, pname, eqn);
-}
-void API_ENTRY(glGetLightxv)(GLenum light, GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetLightxv, light, pname, params);
+void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *params) {
+ CALL_GL_API(glGetFloatv, pname, params);
}
void API_ENTRY(glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) {
CALL_GL_API(glGetLightfv, light, pname, params);
}
-void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetMaterialxv, face, pname, params);
-}
void API_ENTRY(glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) {
CALL_GL_API(glGetMaterialfv, face, pname, params);
}
void API_ENTRY(glGetTexEnvfv)(GLenum env, GLenum pname, GLfloat *params) {
CALL_GL_API(glGetTexEnvfv, env, pname, params);
}
+void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) {
+ CALL_GL_API(glGetTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glLightModelf)(GLenum pname, GLfloat param) {
+ CALL_GL_API(glLightModelf, pname, param);
+}
+void API_ENTRY(glLightModelfv)(GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glLightModelfv, pname, params);
+}
+void API_ENTRY(glLightf)(GLenum light, GLenum pname, GLfloat param) {
+ CALL_GL_API(glLightf, light, pname, param);
+}
+void API_ENTRY(glLightfv)(GLenum light, GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glLightfv, light, pname, params);
+}
+void API_ENTRY(glLineWidth)(GLfloat width) {
+ CALL_GL_API(glLineWidth, width);
+}
+void API_ENTRY(glLoadMatrixf)(const GLfloat *m) {
+ CALL_GL_API(glLoadMatrixf, m);
+}
+void API_ENTRY(glMaterialf)(GLenum face, GLenum pname, GLfloat param) {
+ CALL_GL_API(glMaterialf, face, pname, param);
+}
+void API_ENTRY(glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glMaterialfv, face, pname, params);
+}
+void API_ENTRY(glMultMatrixf)(const GLfloat *m) {
+ CALL_GL_API(glMultMatrixf, m);
+}
+void API_ENTRY(glMultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
+ CALL_GL_API(glMultiTexCoord4f, target, s, t, r, q);
+}
+void API_ENTRY(glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) {
+ CALL_GL_API(glNormal3f, nx, ny, nz);
+}
+void API_ENTRY(glOrthof)(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+ CALL_GL_API(glOrthof, left, right, bottom, top, zNear, zFar);
+}
+void API_ENTRY(glPointParameterf)(GLenum pname, GLfloat param) {
+ CALL_GL_API(glPointParameterf, pname, param);
+}
+void API_ENTRY(glPointParameterfv)(GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glPointParameterfv, pname, params);
+}
+void API_ENTRY(glPointSize)(GLfloat size) {
+ CALL_GL_API(glPointSize, size);
+}
+void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
+ CALL_GL_API(glPolygonOffset, factor, units);
+}
+void API_ENTRY(glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
+ CALL_GL_API(glRotatef, angle, x, y, z);
+}
+void API_ENTRY(glScalef)(GLfloat x, GLfloat y, GLfloat z) {
+ CALL_GL_API(glScalef, x, y, z);
+}
+void API_ENTRY(glTexEnvf)(GLenum target, GLenum pname, GLfloat param) {
+ CALL_GL_API(glTexEnvf, target, pname, param);
+}
+void API_ENTRY(glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glTexEnvfv, target, pname, params);
+}
+void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
+ CALL_GL_API(glTexParameterf, target, pname, param);
+}
+void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glTexParameterfv, target, pname, params);
+}
+void API_ENTRY(glTranslatef)(GLfloat x, GLfloat y, GLfloat z) {
+ CALL_GL_API(glTranslatef, x, y, z);
+}
+void API_ENTRY(glActiveTexture)(GLenum texture) {
+ CALL_GL_API(glActiveTexture, texture);
+}
+void API_ENTRY(glAlphaFuncx)(GLenum func, GLclampx ref) {
+ CALL_GL_API(glAlphaFuncx, func, ref);
+}
+void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
+ CALL_GL_API(glBindBuffer, target, buffer);
+}
+void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
+ CALL_GL_API(glBindTexture, target, texture);
+}
+void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
+ CALL_GL_API(glBlendFunc, sfactor, dfactor);
+}
+void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) {
+ CALL_GL_API(glBufferData, target, size, data, usage);
+}
+void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) {
+ CALL_GL_API(glBufferSubData, target, offset, size, data);
+}
+void API_ENTRY(glClear)(GLbitfield mask) {
+ CALL_GL_API(glClear, mask);
+}
+void API_ENTRY(glClearColorx)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+ CALL_GL_API(glClearColorx, red, green, blue, alpha);
+}
+void API_ENTRY(glClearDepthx)(GLclampx depth) {
+ CALL_GL_API(glClearDepthx, depth);
+}
+void API_ENTRY(glClearStencil)(GLint s) {
+ CALL_GL_API(glClearStencil, s);
+}
+void API_ENTRY(glClientActiveTexture)(GLenum texture) {
+ CALL_GL_API(glClientActiveTexture, texture);
+}
+void API_ENTRY(glClipPlanex)(GLenum plane, const GLfixed *equation) {
+ CALL_GL_API(glClipPlanex, plane, equation);
+}
+void API_ENTRY(glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
+ CALL_GL_API(glColor4ub, red, green, blue, alpha);
+}
+void API_ENTRY(glColor4x)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
+ CALL_GL_API(glColor4x, red, green, blue, alpha);
+}
+void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
+ CALL_GL_API(glColorMask, red, green, blue, alpha);
+}
+void API_ENTRY(glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+ CALL_GL_API(glColorPointer, size, type, stride, pointer);
+}
+void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) {
+ CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
+}
+void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) {
+ CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
+}
+void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
+ CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y, width, height, border);
+}
+void API_ENTRY(glCopyTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
+ CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y, width, height);
+}
+void API_ENTRY(glCullFace)(GLenum mode) {
+ CALL_GL_API(glCullFace, mode);
+}
+void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint *buffers) {
+ CALL_GL_API(glDeleteBuffers, n, buffers);
+}
+void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) {
+ CALL_GL_API(glDeleteTextures, n, textures);
+}
+void API_ENTRY(glDepthFunc)(GLenum func) {
+ CALL_GL_API(glDepthFunc, func);
+}
+void API_ENTRY(glDepthMask)(GLboolean flag) {
+ CALL_GL_API(glDepthMask, flag);
+}
+void API_ENTRY(glDepthRangex)(GLclampx zNear, GLclampx zFar) {
+ CALL_GL_API(glDepthRangex, zNear, zFar);
+}
+void API_ENTRY(glDisable)(GLenum cap) {
+ CALL_GL_API(glDisable, cap);
+}
+void API_ENTRY(glDisableClientState)(GLenum array) {
+ CALL_GL_API(glDisableClientState, array);
+}
+void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
+ CALL_GL_API(glDrawArrays, mode, first, count);
+}
+void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
+ CALL_GL_API(glDrawElements, mode, count, type, indices);
+}
+void API_ENTRY(glEnable)(GLenum cap) {
+ CALL_GL_API(glEnable, cap);
+}
+void API_ENTRY(glEnableClientState)(GLenum array) {
+ CALL_GL_API(glEnableClientState, array);
+}
+void API_ENTRY(glFinish)(void) {
+ CALL_GL_API(glFinish);
+}
+void API_ENTRY(glFlush)(void) {
+ CALL_GL_API(glFlush);
+}
+void API_ENTRY(glFogx)(GLenum pname, GLfixed param) {
+ CALL_GL_API(glFogx, pname, param);
+}
+void API_ENTRY(glFogxv)(GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glFogxv, pname, params);
+}
+void API_ENTRY(glFrontFace)(GLenum mode) {
+ CALL_GL_API(glFrontFace, mode);
+}
+void API_ENTRY(glFrustumx)(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+ CALL_GL_API(glFrustumx, left, right, bottom, top, zNear, zFar);
+}
+void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *params) {
+ CALL_GL_API(glGetBooleanv, pname, params);
+}
+void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
+ CALL_GL_API(glGetBufferParameteriv, target, pname, params);
+}
+void API_ENTRY(glGetClipPlanex)(GLenum pname, GLfixed eqn[4]) {
+ CALL_GL_API(glGetClipPlanex, pname, eqn);
+}
+void API_ENTRY(glGenBuffers)(GLsizei n, GLuint *buffers) {
+ CALL_GL_API(glGenBuffers, n, buffers);
+}
+void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) {
+ CALL_GL_API(glGenTextures, n, textures);
+}
+GLenum API_ENTRY(glGetError)(void) {
+ CALL_GL_API_RETURN(glGetError);
+}
+void API_ENTRY(glGetFixedv)(GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetFixedv, pname, params);
+}
+void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *params) {
+ CALL_GL_API(glGetIntegerv, pname, params);
+}
+void API_ENTRY(glGetLightxv)(GLenum light, GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetLightxv, light, pname, params);
+}
+void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetMaterialxv, face, pname, params);
+}
+void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
+ CALL_GL_API(glGetPointerv, pname, params);
+}
+const GLubyte * API_ENTRY(glGetString)(GLenum name) {
+ CALL_GL_API_RETURN(glGetString, name);
+}
void API_ENTRY(glGetTexEnviv)(GLenum env, GLenum pname, GLint *params) {
CALL_GL_API(glGetTexEnviv, env, pname, params);
}
void API_ENTRY(glGetTexEnvxv)(GLenum env, GLenum pname, GLfixed *params) {
CALL_GL_API(glGetTexEnvxv, env, pname, params);
}
-void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) {
- CALL_GL_API(glGetTexParameterfv, target, pname, params);
-}
void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) {
CALL_GL_API(glGetTexParameteriv, target, pname, params);
}
void API_ENTRY(glGetTexParameterxv)(GLenum target, GLenum pname, GLfixed *params) {
CALL_GL_API(glGetTexParameterxv, target, pname, params);
}
+void API_ENTRY(glHint)(GLenum target, GLenum mode) {
+ CALL_GL_API(glHint, target, mode);
+}
GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
CALL_GL_API_RETURN(glIsBuffer, buffer);
}
@@ -536,11 +289,56 @@
GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
CALL_GL_API_RETURN(glIsTexture, texture);
}
-void API_ENTRY(glPointParameterf)(GLenum pname, GLfloat param) {
- CALL_GL_API(glPointParameterf, pname, param);
+void API_ENTRY(glLightModelx)(GLenum pname, GLfixed param) {
+ CALL_GL_API(glLightModelx, pname, param);
}
-void API_ENTRY(glPointParameterfv)(GLenum pname, const GLfloat *params) {
- CALL_GL_API(glPointParameterfv, pname, params);
+void API_ENTRY(glLightModelxv)(GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glLightModelxv, pname, params);
+}
+void API_ENTRY(glLightx)(GLenum light, GLenum pname, GLfixed param) {
+ CALL_GL_API(glLightx, light, pname, param);
+}
+void API_ENTRY(glLightxv)(GLenum light, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glLightxv, light, pname, params);
+}
+void API_ENTRY(glLineWidthx)(GLfixed width) {
+ CALL_GL_API(glLineWidthx, width);
+}
+void API_ENTRY(glLoadIdentity)(void) {
+ CALL_GL_API(glLoadIdentity);
+}
+void API_ENTRY(glLoadMatrixx)(const GLfixed *m) {
+ CALL_GL_API(glLoadMatrixx, m);
+}
+void API_ENTRY(glLogicOp)(GLenum opcode) {
+ CALL_GL_API(glLogicOp, opcode);
+}
+void API_ENTRY(glMaterialx)(GLenum face, GLenum pname, GLfixed param) {
+ CALL_GL_API(glMaterialx, face, pname, param);
+}
+void API_ENTRY(glMaterialxv)(GLenum face, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glMaterialxv, face, pname, params);
+}
+void API_ENTRY(glMatrixMode)(GLenum mode) {
+ CALL_GL_API(glMatrixMode, mode);
+}
+void API_ENTRY(glMultMatrixx)(const GLfixed *m) {
+ CALL_GL_API(glMultMatrixx, m);
+}
+void API_ENTRY(glMultiTexCoord4x)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
+ CALL_GL_API(glMultiTexCoord4x, target, s, t, r, q);
+}
+void API_ENTRY(glNormal3x)(GLfixed nx, GLfixed ny, GLfixed nz) {
+ CALL_GL_API(glNormal3x, nx, ny, nz);
+}
+void API_ENTRY(glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) {
+ CALL_GL_API(glNormalPointer, type, stride, pointer);
+}
+void API_ENTRY(glOrthox)(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+ CALL_GL_API(glOrthox, left, right, bottom, top, zNear, zFar);
+}
+void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
+ CALL_GL_API(glPixelStorei, pname, param);
}
void API_ENTRY(glPointParameterx)(GLenum pname, GLfixed param) {
CALL_GL_API(glPointParameterx, pname, param);
@@ -548,59 +346,90 @@
void API_ENTRY(glPointParameterxv)(GLenum pname, const GLfixed *params) {
CALL_GL_API(glPointParameterxv, pname, params);
}
-void API_ENTRY(glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
- CALL_GL_API(glColor4ub, red, green, blue, alpha);
+void API_ENTRY(glPointSizex)(GLfixed size) {
+ CALL_GL_API(glPointSizex, size);
+}
+void API_ENTRY(glPolygonOffsetx)(GLfixed factor, GLfixed units) {
+ CALL_GL_API(glPolygonOffsetx, factor, units);
+}
+void API_ENTRY(glPopMatrix)(void) {
+ CALL_GL_API(glPopMatrix);
+}
+void API_ENTRY(glPushMatrix)(void) {
+ CALL_GL_API(glPushMatrix);
+}
+void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
+ CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
+}
+void API_ENTRY(glRotatex)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
+ CALL_GL_API(glRotatex, angle, x, y, z);
+}
+void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
+ CALL_GL_API(glSampleCoverage, value, invert);
+}
+void API_ENTRY(glSampleCoveragex)(GLclampx value, GLboolean invert) {
+ CALL_GL_API(glSampleCoveragex, value, invert);
+}
+void API_ENTRY(glScalex)(GLfixed x, GLfixed y, GLfixed z) {
+ CALL_GL_API(glScalex, x, y, z);
+}
+void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
+ CALL_GL_API(glScissor, x, y, width, height);
+}
+void API_ENTRY(glShadeModel)(GLenum mode) {
+ CALL_GL_API(glShadeModel, mode);
+}
+void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
+ CALL_GL_API(glStencilFunc, func, ref, mask);
+}
+void API_ENTRY(glStencilMask)(GLuint mask) {
+ CALL_GL_API(glStencilMask, mask);
+}
+void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
+ CALL_GL_API(glStencilOp, fail, zfail, zpass);
+}
+void API_ENTRY(glTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+ CALL_GL_API(glTexCoordPointer, size, type, stride, pointer);
}
void API_ENTRY(glTexEnvi)(GLenum target, GLenum pname, GLint param) {
CALL_GL_API(glTexEnvi, target, pname, param);
}
+void API_ENTRY(glTexEnvx)(GLenum target, GLenum pname, GLfixed param) {
+ CALL_GL_API(glTexEnvx, target, pname, param);
+}
void API_ENTRY(glTexEnviv)(GLenum target, GLenum pname, const GLint *params) {
CALL_GL_API(glTexEnviv, target, pname, params);
}
-
-void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glTexParameterfv, target, pname, params);
+void API_ENTRY(glTexEnvxv)(GLenum target, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glTexEnvxv, target, pname, params);
}
-
-void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) {
- CALL_GL_API(glTexParameteriv, target, pname, params);
+void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) {
+ CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
}
-
void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
CALL_GL_API(glTexParameteri, target, pname, param);
}
+void API_ENTRY(glTexParameterx)(GLenum target, GLenum pname, GLfixed param) {
+ CALL_GL_API(glTexParameterx, target, pname, param);
+}
+void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) {
+ CALL_GL_API(glTexParameteriv, target, pname, params);
+}
void API_ENTRY(glTexParameterxv)(GLenum target, GLenum pname, const GLfixed *params) {
CALL_GL_API(glTexParameterxv, target, pname, params);
}
+void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
+ CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+void API_ENTRY(glTranslatex)(GLfixed x, GLfixed y, GLfixed z) {
+ CALL_GL_API(glTranslatex, x, y, z);
+}
+void API_ENTRY(glVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+ CALL_GL_API(glVertexPointer, size, type, stride, pointer);
+}
+void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
+ CALL_GL_API(glViewport, x, y, width, height);
+}
void API_ENTRY(glPointSizePointerOES)(GLenum type, GLsizei stride, const GLvoid *pointer) {
CALL_GL_API(glPointSizePointerOES, type, stride, pointer);
}
-
-// Extensions
-void API_ENTRY(glDrawTexsOES)(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
- CALL_GL_API(glDrawTexsOES, x, y, z, w, h);
-}
-void API_ENTRY(glDrawTexiOES)(GLint x, GLint y, GLint z, GLint w, GLint h) {
- CALL_GL_API(glDrawTexiOES, x, y, z, w, h);
-}
-void API_ENTRY(glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h) {
- CALL_GL_API(glDrawTexfOES, x, y, z, w, h);
-}
-void API_ENTRY(glDrawTexxOES)(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
- CALL_GL_API(glDrawTexxOES, x, y, z, w, h);
-}
-void API_ENTRY(glDrawTexsvOES)(const GLshort* coords) {
- CALL_GL_API(glDrawTexsvOES, coords);
-}
-void API_ENTRY(glDrawTexivOES)(const GLint* coords) {
- CALL_GL_API(glDrawTexivOES, coords);
-}
-void API_ENTRY(glDrawTexfvOES)(const GLfloat* coords) {
- CALL_GL_API(glDrawTexfvOES, coords);
-}
-void API_ENTRY(glDrawTexxvOES)(const GLfixed* coords) {
- CALL_GL_API(glDrawTexxvOES, coords);
-}
-GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* mantissa, GLint* exponent) {
- CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent);
-}
diff --git a/opengl/libs/GLES_CM/gl_logger.cpp b/opengl/libs/GLES_CM/gl_logger.cpp
deleted file mode 100644
index 27be5c9..0000000
--- a/opengl/libs/GLES_CM/gl_logger.cpp
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- ** Copyright 2007, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#define LOG_TAG "GLLogger"
-
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <dlfcn.h>
-
-#include <sys/ioctl.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-
-#include <utils/String8.h>
-
-#include "gl_logger.h"
-
-#undef NELEM
-#define NELEM(x) (sizeof(x)/sizeof(*(x)))
-
-// ----------------------------------------------------------------------------
-namespace android {
-// ----------------------------------------------------------------------------
-
-template<typename T>
-static int binarySearch(T const sortedArray[], int first, int last, EGLint key)
-{
- while (first <= last) {
- int mid = (first + last) / 2;
- if (key > sortedArray[mid].key) {
- first = mid + 1;
- } else if (key < sortedArray[mid].key) {
- last = mid - 1;
- } else {
- return mid;
- }
- }
- return -1;
-}
-
-struct pair_t {
- const char* name;
- int key;
-};
-
-static const pair_t gEnumMap[] = {
- #define GLENUM(NAME, VALUE) { #NAME, VALUE },
- #include "gl_enums.in"
- #undef GLENUM
-};
-
-// ----------------------------------------------------------------------------
-
-template<typename TYPE>
-class GLLogValue {
-public:
- GLLogValue(TYPE value) : mValue(value) { }
- const TYPE& getValue() const { return mValue; }
- String8 toString() const {
- return convertToString(mValue);
- }
-private:
- const TYPE& mValue;
- String8 convertToString(unsigned int v) const {
- char buf[16];
- snprintf(buf, 16, "%u", v);
- return String8(buf);
- }
- String8 convertToString(unsigned long v) const {
- char buf[16];
- snprintf(buf, 16, "%lu", v);
- return String8(buf);
- }
- String8 convertToString(int v) const {
- char buf[16];
- snprintf(buf, 16, "%d", v);
- return String8(buf);
- }
- String8 convertToString(long v) const {
- char buf[16];
- snprintf(buf, 16, "%ld", v);
- return String8(buf);
- }
- String8 convertToString(float v) const {
- char buf[16];
- snprintf(buf, 16, "%f", v);
- return String8(buf);
- }
- String8 convertToString(void const* v) const {
- char buf[16];
- snprintf(buf, 16, "%p", v);
- return String8(buf);
- }
-};
-
-class GLLogEnum : public GLLogValue<GLenum> {
-public:
- GLLogEnum(GLenum v) : GLLogValue<GLenum>(v) { }
- String8 toString() const {
- GLenum v = getValue();
- int i = binarySearch<pair_t>(gEnumMap, 0, NELEM(gEnumMap)-1, v);
- if (i >= 0) {
- return String8(gEnumMap[i].name);
- } else {
- char buf[16];
- snprintf(buf, 16, "0x%04x", v);
- return String8(buf);
- }
- }
-};
-
-class GLLogClearBitfield : public GLLogValue<GLbitfield> {
-public:
- GLLogClearBitfield(GLbitfield v) : GLLogValue<GLbitfield>(v) { }
- String8 toString() const {
- char buf[16];
- snprintf(buf, 16, "0x%08x", getValue());
- return String8(buf);
- }
-};
-
-class GLLogBool : public GLLogValue<GLboolean> {
-public:
- GLLogBool(GLboolean v) : GLLogValue<GLboolean>(v) { }
- String8 toString() const {
- GLboolean v = getValue();
- if (v == GL_TRUE) return String8("GL_TRUE");
- if (v == GL_FALSE) return String8("GL_FALSE");
- return GLLogValue<GLboolean>::toString();
- }
-};
-
-class GLLogFixed : public GLLogValue<GLfixed> {
-public:
- GLLogFixed(GLfixed v) : GLLogValue<GLfixed>(v) { }
- String8 toString() const {
- char buf[16];
- snprintf(buf, 16, "0x%08x", getValue());
- return String8(buf);
- }
-};
-
-
-template <typename TYPE>
-class GLLogBuffer : public GLLogValue<TYPE *> {
-public:
- GLLogBuffer(TYPE* buffer, size_t count = -1)
- : GLLogValue<TYPE*>(buffer)
- { // output buffer
- }
- GLLogBuffer(TYPE const* buffer, size_t count = -1)
- : GLLogValue<TYPE*>(const_cast<TYPE*>(buffer))
- { // input buffer
- }
-};
-
-class GLLog
-{
-public:
- GLLog(const char* name) : mNumParams(0) {
- mString.append(name);
- mString.append("(");
- }
-
- ~GLLog() {
- LOGD("%s);", mString.string());
- }
-
- GLLog& operator << (unsigned char v) {
- return *this << GLLogValue<unsigned int>(v);
- }
- GLLog& operator << (short v) {
- return *this << GLLogValue<unsigned int>(v);
- }
- GLLog& operator << (unsigned int v) {
- return *this << GLLogValue<unsigned int>(v);
- }
- GLLog& operator << (int v) {
- return *this << GLLogValue<int>(v);
- }
- GLLog& operator << (long v) {
- return *this << GLLogValue<long>(v);
- }
- GLLog& operator << (unsigned long v) {
- return *this << GLLogValue<unsigned long>(v);
- }
- GLLog& operator << (float v) {
- return *this << GLLogValue<float>(v);
- }
- GLLog& operator << (const void* v) {
- return *this << GLLogValue<const void* >(v);
- }
-
- template <typename TYPE>
- GLLog& operator << (const TYPE& rhs) {
- if (mNumParams > 0)
- mString.append(", ");
- mString.append(rhs.toString());
- mNumParams++;
- return *this;
- }
-
- const String8& string() const { return mString; }
-private:
- GLLog(const GLLog&);
-
- String8 mString;
- int mNumParams;
-};
-
-#define API_ENTRY(api) log_##api
-#define CALL_GL_API(_x, ...)
-#define CALL_GL_API_RETURN(_x, ...) return(0);
-
-void API_ENTRY(glActiveTexture)(GLenum texture) {
- CALL_GL_API(glActiveTexture, texture);
- GLLog("glActiveTexture") << GLLogEnum(texture);
-}
-
-void API_ENTRY(glAlphaFunc)(GLenum func, GLclampf ref) {
- CALL_GL_API(glAlphaFunc, func, ref);
- GLLog("glAlphaFunc") << GLLogEnum(func) << ref;
-}
-
-void API_ENTRY(glAlphaFuncx)(GLenum func, GLclampx ref) {
- CALL_GL_API(glAlphaFuncx, func, ref);
- GLLog("glAlphaFuncx") << GLLogEnum(func) << GLLogFixed(ref);
-}
-
-void API_ENTRY(glBindTexture)(GLenum target, GLuint texture) {
- CALL_GL_API(glBindTexture, target, texture);
- GLLog("glBindTexture") << GLLogEnum(target) << texture;
-}
-
-void API_ENTRY(glBlendFunc)(GLenum sfactor, GLenum dfactor) {
- CALL_GL_API(glBlendFunc, sfactor, dfactor);
- GLLog("glBlendFunc") << GLLogEnum(sfactor) << GLLogEnum(dfactor);
-}
-
-void API_ENTRY(glClear)(GLbitfield mask) {
- CALL_GL_API(glClear, mask);
- GLLog("glClear") << GLLogClearBitfield(mask);
-}
-
-void API_ENTRY(glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
- CALL_GL_API(glClearColor, red, green, blue, alpha);
- GLLog("glClearColor") << red << green << blue << alpha;
-}
-
-void API_ENTRY(glClearColorx)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
- CALL_GL_API(glClearColorx, red, green, blue, alpha);
- GLLog("glClearColorx") << GLLogFixed(red) << GLLogFixed(green) << GLLogFixed(blue) << GLLogFixed(alpha);
-}
-
-void API_ENTRY(glClearDepthf)(GLclampf depth) {
- CALL_GL_API(glClearDepthf, depth);
- GLLog("glClearDepthf") << depth;
-}
-
-void API_ENTRY(glClearDepthx)(GLclampx depth) {
- CALL_GL_API(glClearDepthx, depth);
- GLLog("glClearDepthx") << GLLogFixed(depth);
-}
-
-void API_ENTRY(glClearStencil)(GLint s) {
- CALL_GL_API(glClearStencil, s);
- GLLog("glClearStencil") << s;
-}
-
-void API_ENTRY(glClientActiveTexture)(GLenum texture) {
- CALL_GL_API(glClientActiveTexture, texture);
- GLLog("glClientActiveTexture") << GLLogEnum(texture);
-}
-
-void API_ENTRY(glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
- CALL_GL_API(glColor4f, red, green, blue, alpha);
- GLLog("glColor4f") << red << green << blue << alpha;
-}
-
-void API_ENTRY(glColor4x)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
- CALL_GL_API(glColor4x, red, green, blue, alpha);
- GLLog("glColor4x") << GLLogFixed(red) << GLLogFixed(green) << GLLogFixed(blue) << GLLogFixed(alpha);
-}
-
-void API_ENTRY(glColorMask)(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
- CALL_GL_API(glColorMask, r, g, b, a);
- GLLog("glColorMask") << GLLogBool(r) << GLLogBool(g) << GLLogBool(b) << GLLogBool(a);
-}
-
-void API_ENTRY(glColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
-{
- CALL_GL_API(glColorPointer, size, type, stride, ptr);
- GLLog("glColorPointer") << size << GLLogEnum(type) << stride << ptr;
-}
-
-void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLint border,
- GLsizei imageSize, const GLvoid *data) {
- CALL_GL_API(glCompressedTexImage2D, target, level, internalformat,
- width, height, border, imageSize, data);
- GLLog("glCompressedTexImage2D")
- << GLLogEnum(target) << level << GLLogEnum(internalformat)
- << width << height << border << imageSize << data;
-}
-
-void API_ENTRY(glCompressedTexSubImage2D)( GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize,
- const GLvoid *data) {
- CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset,
- width, height, format, imageSize, data);
- GLLog("glCompressedTexSubImage2D")
- << GLLogEnum(target) << level << xoffset << yoffset
- << width << height << GLLogEnum(format) << imageSize << data;
-}
-
-void API_ENTRY(glCopyTexImage2D)( GLenum target, GLint level, GLenum internalformat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border) {
- CALL_GL_API(glCopyTexImage2D, target, level, internalformat, x, y,
- width, height, border);
- GLLog("glCopyTexImage2D")
- << GLLogEnum(target) << level << GLLogEnum(internalformat)
- << x << y << width << height << border;
-}
-
-void API_ENTRY(glCopyTexSubImage2D)( GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLint x, GLint y, GLsizei width,
- GLsizei height) {
- CALL_GL_API(glCopyTexSubImage2D, target, level, xoffset, yoffset, x, y,
- width, height);
- GLLog("glCopyTexSubImage2D")
- << GLLogEnum(target) << level << xoffset << yoffset
- << x << y << width << height;
-}
-
-void API_ENTRY(glCullFace)(GLenum mode) {
- CALL_GL_API(glCullFace, mode);
- GLLog("glCullFace") << GLLogEnum(mode);
-}
-
-void API_ENTRY(glDeleteTextures)(GLsizei n, const GLuint *textures) {
- CALL_GL_API(glDeleteTextures, n, textures);
- GLLog("glDeleteTextures") << n << GLLogBuffer<GLuint>(textures, n);
-}
-
-void API_ENTRY(glDepthFunc)(GLenum func) {
- CALL_GL_API(glDepthFunc, func);
- GLLog("glDepthFunc") << GLLogEnum(func);
-}
-
-void API_ENTRY(glDepthMask)(GLboolean flag) {
- CALL_GL_API(glDepthMask, flag);
- GLLog("glDepthMask") << GLLogBool(flag);
-}
-
-void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar) {
- CALL_GL_API(glDepthRangef, zNear, zFar);
- GLLog("glDepthRangef") << zNear << zFar;
-}
-
-void API_ENTRY(glDepthRangex)(GLclampx zNear, GLclampx zFar) {
- CALL_GL_API(glDepthRangex, zNear, zFar);
- GLLog("glDepthRangex") << GLLogFixed(zNear) << GLLogFixed(zFar);
-}
-
-void API_ENTRY(glDisable)(GLenum cap) {
- CALL_GL_API(glDisable, cap);
- GLLog("glDisable") << GLLogEnum(cap);
-}
-
-void API_ENTRY(glDisableClientState)(GLenum array) {
- CALL_GL_API(glDisableClientState, array);
- GLLog("glDisableClientState") << GLLogEnum(array);
-}
-
-void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
- CALL_GL_API(glDrawArrays, mode, first, count);
- GLLog("glDrawArrays") << GLLogEnum(mode) << first << count;
-}
-
-void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count,
- GLenum type, const GLvoid *indices) {
- CALL_GL_API(glDrawElements, mode, count, type, indices);
- GLLog log("glDrawElements");
- log << GLLogEnum(mode) << count << GLLogEnum(type);
- if (type == GL_UNSIGNED_BYTE) {
- log << GLLogBuffer<GLubyte>(static_cast<const GLubyte*>(indices), count);
- } else {
- log << GLLogBuffer<GLushort>(static_cast<const GLushort*>(indices), count);
- }
- log;
-}
-
-void API_ENTRY(glEnable)(GLenum cap) {
- CALL_GL_API(glEnable, cap);
- GLLog("glEnable") << GLLogEnum(cap);
-}
-
-void API_ENTRY(glEnableClientState)(GLenum array) {
- CALL_GL_API(glEnableClientState, array);
- GLLog("glEnableClientState") << GLLogEnum(array);
-}
-
-void API_ENTRY(glFinish)(void) {
- CALL_GL_API(glFinish);
- GLLog("glFinish");
-}
-
-void API_ENTRY(glFlush)(void) {
- CALL_GL_API(glFlush);
- GLLog("glFlush");
-}
-
-void API_ENTRY(glFogf)(GLenum pname, GLfloat param) {
- CALL_GL_API(glFogf, pname, param);
- GLLog("glFogf") << GLLogEnum(pname) << param;
-}
-
-void API_ENTRY(glFogfv)(GLenum pname, const GLfloat *params) {
- CALL_GL_API(glFogfv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glFogfv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-
-void API_ENTRY(glFogx)(GLenum pname, GLfixed param) {
- CALL_GL_API(glFogx, pname, param);
- GLLog("glFogx") << GLLogEnum(pname) << GLLogFixed(param);
-}
-
-void API_ENTRY(glFogxv)(GLenum pname, const GLfixed *params) {
- CALL_GL_API(glFogxv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glFogfx") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-
-void API_ENTRY(glFrontFace)(GLenum mode) {
- CALL_GL_API(glFrontFace, mode);
- GLLog("glFrontFace") << GLLogEnum(mode);
- }
-
-void API_ENTRY(glFrustumf)(GLfloat left, GLfloat right,
- GLfloat bottom, GLfloat top,
- GLfloat zNear, GLfloat zFar) {
- CALL_GL_API(glFrustumf, left, right, bottom, top, zNear, zFar);
- GLLog("glFrustumf") << left << right << bottom << top << zNear << zFar;
-}
-
-void API_ENTRY(glFrustumx)(GLfixed left, GLfixed right,
- GLfixed bottom, GLfixed top,
- GLfixed zNear, GLfixed zFar) {
- CALL_GL_API(glFrustumx, left, right, bottom, top, zNear, zFar);
- GLLog("glFrustumx")
- << GLLogFixed(left) << GLLogFixed(right)
- << GLLogFixed(bottom) << GLLogFixed(top)
- << GLLogFixed(zNear) << GLLogFixed(zFar);
-}
-
-void API_ENTRY(glGenTextures)(GLsizei n, GLuint *textures) {
- CALL_GL_API(glGenTextures, n, textures);
- GLLog("glGenTextures") << n << GLLogBuffer<GLuint>(textures, n);
-}
-
-GLenum API_ENTRY(glGetError)(void) {
- GLLog("glGetError");
- CALL_GL_API_RETURN(glGetError);
-}
-
-void API_ENTRY(glGetIntegerv)(GLenum pname, GLint *params) {
- CALL_GL_API(glGetIntegerv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetIntegerv") << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
-}
-
-const GLubyte * API_ENTRY(glGetString)(GLenum name) {
- GLLog("glGetString") << GLLogEnum(name);
- CALL_GL_API_RETURN(glGetString, name);
-}
-
-void API_ENTRY(glHint)(GLenum target, GLenum mode) {
- CALL_GL_API(glHint, target, mode);
- GLLog("GLenum") << GLLogEnum(target) << GLLogEnum(mode);
-}
-
-void API_ENTRY(glLightModelf)(GLenum pname, GLfloat param) {
- CALL_GL_API(glLightModelf, pname, param);
- GLLog("glLightModelf") << GLLogEnum(pname) << param;
-}
-
-void API_ENTRY(glLightModelfv)(GLenum pname, const GLfloat *params) {
- CALL_GL_API(glLightModelfv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glLightModelfv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-
-void API_ENTRY(glLightModelx)(GLenum pname, GLfixed param) {
- CALL_GL_API(glLightModelx, pname, param);
- GLLog("glLightModelx") << GLLogEnum(pname) << GLLogFixed(param);
-}
-
-void API_ENTRY(glLightModelxv)(GLenum pname, const GLfixed *params) {
- CALL_GL_API(glLightModelxv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glLightModelxv") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-
-void API_ENTRY(glLightf)(GLenum light, GLenum pname, GLfloat param) {
- CALL_GL_API(glLightf, light, pname, param);
- GLLog("glLightf") << GLLogEnum(light) << GLLogEnum(pname) << param;
-}
-
-void API_ENTRY(glLightfv)(GLenum light, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glLightfv, light, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glLightfv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-
-void API_ENTRY(glLightx)(GLenum light, GLenum pname, GLfixed param) {
- CALL_GL_API(glLightx, light, pname, param);
- GLLog("glLightx") << GLLogEnum(light) << GLLogEnum(pname) << GLLogFixed(param);
-}
-
-void API_ENTRY(glLightxv)(GLenum light, GLenum pname, const GLfixed *params) {
- CALL_GL_API(glLightxv, light, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glLightxv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-
-void API_ENTRY(glLineWidth)(GLfloat width) {
- CALL_GL_API(glLineWidth, width);
- GLLog("glLineWidth") << width;
-}
-
-void API_ENTRY(glLineWidthx)(GLfixed width) {
- CALL_GL_API(glLineWidthx, width);
- GLLog("glLineWidth") << GLLogFixed(width);
-}
-
-void API_ENTRY(glLoadIdentity)(void) {
- CALL_GL_API(glLoadIdentity);
- GLLog("glLoadIdentity");
-}
-
-void API_ENTRY(glLoadMatrixf)(const GLfloat *m) {
- CALL_GL_API(glLoadMatrixf, m);
- GLLog("glLoadMatrixf") << GLLogBuffer<GLfloat>(m, 16);
-}
-
-void API_ENTRY(glLoadMatrixx)(const GLfixed *m) {
- CALL_GL_API(glLoadMatrixx, m);
- GLLog("glLoadMatrixx") << GLLogBuffer<GLfixed>(m, 16);
-}
-
-void API_ENTRY(glLogicOp)(GLenum opcode) {
- CALL_GL_API(glLogicOp, opcode);
- GLLog("glLogicOp") << GLLogEnum(opcode);
-}
-
-void API_ENTRY(glMaterialf)(GLenum face, GLenum pname, GLfloat param) {
- CALL_GL_API(glMaterialf, face, pname, param);
- GLLog("glMaterialf") << GLLogEnum(face) << GLLogEnum(pname) << param;
-}
-
-void API_ENTRY(glMaterialfv)(GLenum face, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glMaterialfv, face, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glMaterialfv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-
-void API_ENTRY(glMaterialx)(GLenum face, GLenum pname, GLfixed param) {
- CALL_GL_API(glMaterialx, face, pname, param);
- GLLog("glMaterialx") << GLLogEnum(face) << GLLogEnum(pname) << GLLogFixed(param);
-}
-
-void API_ENTRY(glMaterialxv)(GLenum face, GLenum pname, const GLfixed *params) {
- CALL_GL_API(glMaterialxv, face, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glMaterialxv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-
-void API_ENTRY(glMatrixMode)(GLenum mode) {
- CALL_GL_API(glMatrixMode, mode);
- GLLog("glMatrixMode") << GLLogEnum(mode);
-}
-
-void API_ENTRY(glMultMatrixf)(const GLfloat *m) {
- CALL_GL_API(glMultMatrixf, m);
- GLLog("glMultMatrixf") << GLLogBuffer<GLfloat>(m, 16);
-}
-
-void API_ENTRY(glMultMatrixx)(const GLfixed *m) {
- CALL_GL_API(glMultMatrixx, m);
- GLLog("glMultMatrixx") << GLLogBuffer<GLfixed>(m, 16);
-}
-
-void API_ENTRY(glMultiTexCoord4f)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
- CALL_GL_API(glMultiTexCoord4f, target, s, t, r, q);
- GLLog("glMultiTexCoord4f") << GLLogEnum(target) << s << t << r << q;
-}
-
-void API_ENTRY(glMultiTexCoord4x)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
- CALL_GL_API(glMultiTexCoord4x, target, s, t, r, q);
- GLLog("glMultiTexCoord4x") << GLLogEnum(target)
- << GLLogFixed(s) << GLLogFixed(t) << GLLogFixed(r) << GLLogFixed(q);
-}
-
-void API_ENTRY(glNormal3f)(GLfloat nx, GLfloat ny, GLfloat nz) {
- CALL_GL_API(glNormal3f, nx, ny, nz);
- GLLog("glNormal3f") << nx << ny << nz;
-}
-
-void API_ENTRY(glNormal3x)(GLfixed nx, GLfixed ny, GLfixed nz) {
- CALL_GL_API(glNormal3x, nx, ny, nz);
- GLLog("glNormal3x") << GLLogFixed(nx) << GLLogFixed(ny) << GLLogFixed(nz);
-}
-
-void API_ENTRY(glNormalPointer)(GLenum type, GLsizei stride, const GLvoid *pointer) {
- CALL_GL_API(glNormalPointer, type, stride, pointer);
- GLLog("glNormalPointer") << GLLogEnum(type) << stride << pointer;
-}
-
-void API_ENTRY(glOrthof)( GLfloat left, GLfloat right,
- GLfloat bottom, GLfloat top,
- GLfloat zNear, GLfloat zFar) {
- CALL_GL_API(glOrthof, left, right, bottom, top, zNear, zFar);
- GLLog("glOrthof") << left << right << bottom << top << zNear << zFar;
-}
-
-void API_ENTRY(glOrthox)( GLfixed left, GLfixed right,
- GLfixed bottom, GLfixed top,
- GLfixed zNear, GLfixed zFar) {
- CALL_GL_API(glOrthox, left, right, bottom, top, zNear, zFar);
- GLLog("glOrthox") << GLLogFixed(left) << GLLogFixed(right)
- << GLLogFixed(bottom) << GLLogFixed(top)
- << GLLogFixed(zNear) << GLLogFixed(zFar);
-}
-
-void API_ENTRY(glPixelStorei)(GLenum pname, GLint param) {
- CALL_GL_API(glPixelStorei, pname, param);
- GLLog("glPixelStorei") << GLLogEnum(pname) << param;
-}
-
-void API_ENTRY(glPointSize)(GLfloat size) {
- CALL_GL_API(glPointSize, size);
- GLLog("glPointSize") << size;
-}
-
-void API_ENTRY(glPointSizex)(GLfixed size) {
- CALL_GL_API(glPointSizex, size);
- GLLog("glPointSizex") << GLLogFixed(size);
-}
-
-void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
- CALL_GL_API(glPolygonOffset, factor, units);
- GLLog("glPolygonOffset") << factor << units;
-}
-
-void API_ENTRY(glPolygonOffsetx)(GLfixed factor, GLfixed units) {
- CALL_GL_API(glPolygonOffsetx, factor, units);
- GLLog("glPolygonOffsetx") << GLLogFixed(factor) << GLLogFixed(units);
-}
-
-void API_ENTRY(glPopMatrix)(void) {
- CALL_GL_API(glPopMatrix);
- GLLog("glPopMatrix");
-}
-
-void API_ENTRY(glPushMatrix)(void) {
- CALL_GL_API(glPushMatrix);
- GLLog("glPushMatrix");
-}
-
-void API_ENTRY(glReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type, GLvoid *pixels) {
- CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
- // XXX: we need to compute the size of this buffer
- GLLog("glReadPixels") << x << y << width << height << GLLogEnum(format) << GLLogEnum(type)
- << GLLogBuffer<unsigned char>(static_cast<unsigned char *>(pixels));
-}
-
-void API_ENTRY(glRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glRotatef, angle, x, y, z);
- GLLog("glRotatef") << angle << x << y << z;
-}
-
-void API_ENTRY(glRotatex)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
- CALL_GL_API(glRotatex, angle, x, y, z);
- GLLog("glRotatex") << GLLogFixed(angle) << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z);
-}
-
-void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert) {
- CALL_GL_API(glSampleCoverage, value, invert);
- GLLog("glSampleCoverage") << value << GLLogBool(invert);
-}
-
-void API_ENTRY(glSampleCoveragex)(GLclampx value, GLboolean invert) {
- CALL_GL_API(glSampleCoveragex, value, invert);
- GLLog("glSampleCoveragex") << GLLogFixed(value) << GLLogBool(invert);
-}
-
-void API_ENTRY(glScalef)(GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glScalef, x, y, z);
- GLLog("glScalef") << x << y << z;
-}
-
-void API_ENTRY(glScalex)(GLfixed x, GLfixed y, GLfixed z) {
- CALL_GL_API(glScalex, x, y, z);
- GLLog("glScalex") << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z);
-}
-
-void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
- CALL_GL_API(glScissor, x, y, width, height);
- GLLog("glScissor") << x << y << width << height;
-}
-
-void API_ENTRY(glShadeModel)(GLenum mode) {
- CALL_GL_API(glShadeModel, mode);
- GLLog("glShadeModel") << GLLogEnum(mode);
-}
-
-void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
- CALL_GL_API(glStencilFunc, func, ref, mask);
- GLLog("glStencilFunc") << GLLogEnum(func) << ref << mask;
-}
-
-void API_ENTRY(glStencilMask)(GLuint mask) {
- CALL_GL_API(glStencilMask, mask);
- GLLog("glStencilMask") << mask;
-}
-
-void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass) {
- CALL_GL_API(glStencilOp, fail, zfail, zpass);
- GLLog("glStencilOp") << GLLogEnum(fail) << GLLogEnum(zfail) << GLLogEnum(zpass);
-}
-
-void API_ENTRY(glTexCoordPointer)( GLint size, GLenum type,
- GLsizei stride, const GLvoid *pointer) {
- CALL_GL_API(glTexCoordPointer, size, type, stride, pointer);
- GLLog("glTexCoordPointer") << size << GLLogEnum(type) << stride << pointer;
-}
-
-void API_ENTRY(glTexEnvf)(GLenum target, GLenum pname, GLfloat param) {
- CALL_GL_API(glTexEnvf, target, pname, param);
- GLLog("glTexEnvf") << GLLogEnum(target) << GLLogEnum(pname) << param;
-}
-
-void API_ENTRY(glTexEnvfv)(GLenum target, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glTexEnvfv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glTexEnvx") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-
-void API_ENTRY(glTexEnvx)(GLenum target, GLenum pname, GLfixed param) {
- CALL_GL_API(glTexEnvx, target, pname, param);
- GLLog("glTexEnvx") << GLLogEnum(target) << GLLogEnum(pname) << GLLogFixed(param);
-}
-
-void API_ENTRY(glTexEnvxv)(GLenum target, GLenum pname, const GLfixed *params) {
- CALL_GL_API(glTexEnvxv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glTexEnvxv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-
-void API_ENTRY(glTexImage2D)( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLint border, GLenum format,
- GLenum type, const GLvoid *pixels) {
- CALL_GL_API(glTexImage2D, target, level, internalformat, width, height,
- border, format, type, pixels);
- GLLog("glTexImage2D") << GLLogEnum(target) << level << GLLogEnum(internalformat)
- << width << height << border << GLLogEnum(format) << GLLogEnum(type)
- << GLLogBuffer<unsigned char>( static_cast<const unsigned char *>(pixels));
-}
-
-void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
- CALL_GL_API(glTexParameterf, target, pname, param);
- GLLog("glTexParameterf") << GLLogEnum(target) << GLLogEnum(pname) << param;
-}
-
-void API_ENTRY(glTexParameterx)(GLenum target, GLenum pname, GLfixed param) {
- CALL_GL_API(glTexParameterx, target, pname, param);
- GLLog("glTexParameterx") << GLLogEnum(target) << GLLogEnum(pname) << GLLogFixed(param);
-}
-
-void API_ENTRY(glTexSubImage2D)( GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLenum type, const GLvoid *pixels) {
- CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset,
- width, height, format, type, pixels);
- GLLog("glTexSubImage2D") << GLLogEnum(target) << level << xoffset << yoffset
- << width << height << GLLogEnum(format) << GLLogEnum(type)
- << GLLogBuffer<unsigned char>( static_cast<const unsigned char *>(pixels));
-}
-
-void API_ENTRY(glTranslatef)(GLfloat x, GLfloat y, GLfloat z) {
- CALL_GL_API(glTranslatef, x, y, z);
- GLLog("glTranslatef") << x << y << z;
-}
-
-void API_ENTRY(glTranslatex)(GLfixed x, GLfixed y, GLfixed z) {
- CALL_GL_API(glTranslatex, x, y, z);
- GLLog("glTranslatex") << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z);
-}
-
-void API_ENTRY(glVertexPointer)( GLint size, GLenum type,
- GLsizei stride, const GLvoid *pointer) {
- CALL_GL_API(glVertexPointer, size, type, stride, pointer);
- GLLog("glVertexPointer") << size << GLLogEnum(type) << stride << pointer;
-}
-
-void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
- CALL_GL_API(glViewport, x, y, width, height);
- GLLog("glViewport") << x << y << width << height;
-}
-
-// ES 1.1
-void API_ENTRY(glClipPlanef)(GLenum plane, const GLfloat *equation) {
- CALL_GL_API(glClipPlanef, plane, equation);
- GLLog("glClipPlanef") << GLLogEnum(plane) << GLLogBuffer<GLfloat>(equation, 4);
-}
-void API_ENTRY(glClipPlanex)(GLenum plane, const GLfixed *equation) {
- CALL_GL_API(glClipPlanex, plane, equation);
- GLLog("glClipPlanex") << GLLogEnum(plane) << GLLogBuffer<GLfixed>(equation, 4);
-}
-void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
- CALL_GL_API(glBindBuffer, target, buffer);
- GLLog("glBindBuffer") << GLLogEnum(target) << buffer;
-}
-void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
- CALL_GL_API(glBufferData, target, size, data, usage);
- GLLog("glBufferData") << GLLogEnum(target) << size
- << GLLogBuffer<unsigned char>(static_cast<const unsigned char*>(data), size);
-}
-void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
- CALL_GL_API(glBufferSubData, target, offset, size, data);
- GLLog("glBufferSubData") << GLLogEnum(target) << offset << size
- << GLLogBuffer<unsigned char>(static_cast<const unsigned char*>(data), size);
-}
-void API_ENTRY(glDeleteBuffers)(GLsizei n, const GLuint* buffers) {
- CALL_GL_API(glDeleteBuffers, n, buffers);
- GLLog("glDeleteBuffers") << n << GLLogBuffer<GLuint>(buffers, n);
-}
-void API_ENTRY(glGenBuffers)(GLsizei n, GLuint* buffers) {
- CALL_GL_API(glGenBuffers, n, buffers);
- GLLog("glGenBuffers") << n << GLLogBuffer<GLuint>(buffers, n);
-}
-void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean *params) {
- CALL_GL_API(glGetBooleanv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetBooleanv") << GLLogEnum(pname) << GLLogBuffer<GLboolean>(params);
-}
-void API_ENTRY(glGetFixedv)(GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetFixedv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetFixedv") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat *params) {
- CALL_GL_API(glGetFloatv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetFloatv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
- CALL_GL_API(glGetPointerv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetPointerv") << GLLogEnum(pname) << GLLogBuffer<void*>(params);
-}
-void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint *params) {
- // XXX: we need to compute the size of this buffer
- CALL_GL_API(glGetBufferParameteriv, target, pname, params);
- GLLog("glGetBufferParameteriv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
-}
-void API_ENTRY(glGetClipPlanef)(GLenum pname, GLfloat eqn[4]) {
- CALL_GL_API(glGetClipPlanef, pname, eqn);
- GLLog("glGetClipPlanef") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(eqn, 4);
-}
-void API_ENTRY(glGetClipPlanex)(GLenum pname, GLfixed eqn[4]) {
- CALL_GL_API(glGetClipPlanex, pname, eqn);
- GLLog("glGetClipPlanex") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(eqn, 4);
-}
-void API_ENTRY(glGetLightxv)(GLenum light, GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetLightxv, light, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetLightxv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-void API_ENTRY(glGetLightfv)(GLenum light, GLenum pname, GLfloat *params) {
- CALL_GL_API(glGetLightfv, light, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetLightfv") << GLLogEnum(light) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetMaterialxv, face, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetMaterialxv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-void API_ENTRY(glGetMaterialfv)(GLenum face, GLenum pname, GLfloat *params) {
- CALL_GL_API(glGetMaterialfv, face, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetMaterialfv") << GLLogEnum(face) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-void API_ENTRY(glGetTexEnvfv)(GLenum env, GLenum pname, GLfloat *params) {
- CALL_GL_API(glGetTexEnvfv, env, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetTexEnvfv") << GLLogEnum(env) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-void API_ENTRY(glGetTexEnviv)(GLenum env, GLenum pname, GLint *params) {
- CALL_GL_API(glGetTexEnviv, env, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetTexEnviv") << GLLogEnum(env) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
-}
-void API_ENTRY(glGetTexEnvxv)(GLenum env, GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetTexEnvxv, env, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetTexEnvxv") << GLLogEnum(env) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat *params) {
- CALL_GL_API(glGetTexParameterfv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetTexParameterfv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint *params) {
- CALL_GL_API(glGetTexParameteriv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetTexParameteriv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
-}
-void API_ENTRY(glGetTexParameterxv)(GLenum target, GLenum pname, GLfixed *params) {
- CALL_GL_API(glGetTexParameterxv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glGetTexParameterxv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-GLboolean API_ENTRY(glIsBuffer)(GLuint buffer) {
- GLLog("glIsBuffer") << buffer;
- CALL_GL_API_RETURN(glIsBuffer, buffer);
-}
-GLboolean API_ENTRY(glIsEnabled)(GLenum cap) {
- GLLog("glIsEnabled") << GLLogEnum(cap);
- CALL_GL_API_RETURN(glIsEnabled, cap);
-}
-GLboolean API_ENTRY(glIsTexture)(GLuint texture) {
- GLLog("glIsTexture") << texture;
- CALL_GL_API_RETURN(glIsTexture, texture);
-}
-void API_ENTRY(glPointParameterf)(GLenum pname, GLfloat param) {
- CALL_GL_API(glPointParameterf, pname, param);
- GLLog("glPointParameterf") << GLLogEnum(pname) << param;
-}
-void API_ENTRY(glPointParameterfv)(GLenum pname, const GLfloat *params) {
- CALL_GL_API(glPointParameterfv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glPointParameterfv") << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-void API_ENTRY(glPointParameterx)(GLenum pname, GLfixed param) {
- CALL_GL_API(glPointParameterx, pname, param);
- GLLog("glPointParameterx") << GLLogEnum(pname) << GLLogFixed(param);
-}
-void API_ENTRY(glPointParameterxv)(GLenum pname, const GLfixed *params) {
- CALL_GL_API(glPointParameterxv, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glPointParameterxv") << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-void API_ENTRY(glColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
- CALL_GL_API(glColor4ub, red, green, blue, alpha);
- GLLog("glColor4ub") << red << green << blue << alpha;
-}
-void API_ENTRY(glTexEnvi)(GLenum target, GLenum pname, GLint param) {
- CALL_GL_API(glTexEnvi, target, pname, param);
- GLLog("glTexEnvi") << GLLogEnum(target) << GLLogEnum(pname) << param;
-}
-void API_ENTRY(glTexEnviv)(GLenum target, GLenum pname, const GLint *params) {
- CALL_GL_API(glTexEnviv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glTexEnviv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
-}
-
-void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat *params) {
- CALL_GL_API(glTexParameterfv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glTexParameterfv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfloat>(params);
-}
-
-void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint *params) {
- CALL_GL_API(glTexParameteriv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glTexParameteriv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLint>(params);
-}
-
-void API_ENTRY(glTexParameteri)(GLenum target, GLenum pname, GLint param) {
- CALL_GL_API(glTexParameteri, target, pname, param);
- GLLog("glTexParameteri") << GLLogEnum(target) << GLLogEnum(pname) << param;
-}
-void API_ENTRY(glTexParameterxv)(GLenum target, GLenum pname, const GLfixed *params) {
- CALL_GL_API(glTexParameterxv, target, pname, params);
- // XXX: we need to compute the size of this buffer
- GLLog("glTexParameterxv") << GLLogEnum(target) << GLLogEnum(pname) << GLLogBuffer<GLfixed>(params);
-}
-void API_ENTRY(glPointSizePointerOES)(GLenum type, GLsizei stride, const GLvoid *pointer) {
- CALL_GL_API(glPointSizePointerOES, type, stride, pointer);
- GLLog("glPointSizePointerOES") << GLLogEnum(type) << stride << pointer;
-}
-
-// Extensions
-void API_ENTRY(glDrawTexsOES)(GLshort x , GLshort y, GLshort z, GLshort w, GLshort h) {
- CALL_GL_API(glDrawTexsOES, x, y, z, w, h);
- GLLog("glDrawTexsOES") << x << y << z << w << h;
-}
-void API_ENTRY(glDrawTexiOES)(GLint x, GLint y, GLint z, GLint w, GLint h) {
- CALL_GL_API(glDrawTexiOES, x, y, z, w, h);
- GLLog("glDrawTexiOES") << x << y << z << w << h;
-}
-void API_ENTRY(glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h) {
- CALL_GL_API(glDrawTexfOES, x, y, z, w, h);
- GLLog("glDrawTexfOES") << x << y << z << w << h;
-}
-void API_ENTRY(glDrawTexxOES)(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) {
- CALL_GL_API(glDrawTexxOES, x, y, z, w, h);
- GLLog("glDrawTexfOES") << GLLogFixed(x) << GLLogFixed(y) << GLLogFixed(z) << GLLogFixed(w) << GLLogFixed(h);
-}
-void API_ENTRY(glDrawTexsvOES)(const GLshort* coords) {
- CALL_GL_API(glDrawTexsvOES, coords);
- GLLog("glDrawTexsvOES") << GLLogBuffer<GLshort>(coords, 5);
-}
-void API_ENTRY(glDrawTexivOES)(const GLint* coords) {
- CALL_GL_API(glDrawTexivOES, coords);
- GLLog("glDrawTexivOES") << GLLogBuffer<GLint>(coords, 5);
-}
-void API_ENTRY(glDrawTexfvOES)(const GLfloat* coords) {
- CALL_GL_API(glDrawTexfvOES, coords);
- GLLog("glDrawTexfvOES") << GLLogBuffer<GLfloat>(coords, 5);
-}
-void API_ENTRY(glDrawTexxvOES)(const GLfixed* coords) {
- CALL_GL_API(glDrawTexxvOES, coords);
- GLLog("glDrawTexxvOES") << GLLogBuffer<GLfixed>(coords, 5);
-}
-GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed* mantissa, GLint* exponent) {
- GLLog("glQueryMatrixxOES") << GLLogBuffer<GLfixed>(mantissa, 16) << GLLogBuffer<GLfixed>(exponent, 16);
- CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent);
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
diff --git a/opengl/libs/GLES_CM/glext_api.in b/opengl/libs/GLES_CM/glext_api.in
new file mode 100644
index 0000000..2c8648e
--- /dev/null
+++ b/opengl/libs/GLES_CM/glext_api.in
@@ -0,0 +1,270 @@
+void API_ENTRY(glBlendEquationSeparateOES)(GLenum modeRGB, GLenum modeAlpha) {
+ CALL_GL_API(glBlendEquationSeparateOES, modeRGB, modeAlpha);
+}
+void API_ENTRY(glBlendFuncSeparateOES)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
+ CALL_GL_API(glBlendFuncSeparateOES, srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+void API_ENTRY(glBlendEquationOES)(GLenum mode) {
+ CALL_GL_API(glBlendEquationOES, mode);
+}
+void API_ENTRY(glDrawTexsOES)(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) {
+ CALL_GL_API(glDrawTexsOES, x, y, z, width, height);
+}
+void API_ENTRY(glDrawTexiOES)(GLint x, GLint y, GLint z, GLint width, GLint height) {
+ CALL_GL_API(glDrawTexiOES, x, y, z, width, height);
+}
+void API_ENTRY(glDrawTexxOES)(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) {
+ CALL_GL_API(glDrawTexxOES, x, y, z, width, height);
+}
+void API_ENTRY(glDrawTexsvOES)(const GLshort *coords) {
+ CALL_GL_API(glDrawTexsvOES, coords);
+}
+void API_ENTRY(glDrawTexivOES)(const GLint *coords) {
+ CALL_GL_API(glDrawTexivOES, coords);
+}
+void API_ENTRY(glDrawTexxvOES)(const GLfixed *coords) {
+ CALL_GL_API(glDrawTexxvOES, coords);
+}
+void API_ENTRY(glDrawTexfOES)(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) {
+ CALL_GL_API(glDrawTexfOES, x, y, z, width, height);
+}
+void API_ENTRY(glDrawTexfvOES)(const GLfloat *coords) {
+ CALL_GL_API(glDrawTexfvOES, coords);
+}
+void API_ENTRY(__glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) {
+ CALL_GL_API(glEGLImageTargetTexture2DOES, target, image);
+}
+void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
+ CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image);
+}
+void API_ENTRY(glAlphaFuncxOES)(GLenum func, GLclampx ref) {
+ CALL_GL_API(glAlphaFuncxOES, func, ref);
+}
+void API_ENTRY(glClearColorxOES)(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
+ CALL_GL_API(glClearColorxOES, red, green, blue, alpha);
+}
+void API_ENTRY(glClearDepthxOES)(GLclampx depth) {
+ CALL_GL_API(glClearDepthxOES, depth);
+}
+void API_ENTRY(glClipPlanexOES)(GLenum plane, const GLfixed *equation) {
+ CALL_GL_API(glClipPlanexOES, plane, equation);
+}
+void API_ENTRY(glColor4xOES)(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
+ CALL_GL_API(glColor4xOES, red, green, blue, alpha);
+}
+void API_ENTRY(glDepthRangexOES)(GLclampx zNear, GLclampx zFar) {
+ CALL_GL_API(glDepthRangexOES, zNear, zFar);
+}
+void API_ENTRY(glFogxOES)(GLenum pname, GLfixed param) {
+ CALL_GL_API(glFogxOES, pname, param);
+}
+void API_ENTRY(glFogxvOES)(GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glFogxvOES, pname, params);
+}
+void API_ENTRY(glFrustumxOES)(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+ CALL_GL_API(glFrustumxOES, left, right, bottom, top, zNear, zFar);
+}
+void API_ENTRY(glGetClipPlanexOES)(GLenum pname, GLfixed eqn[4]) {
+ CALL_GL_API(glGetClipPlanexOES, pname, eqn);
+}
+void API_ENTRY(glGetFixedvOES)(GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetFixedvOES, pname, params);
+}
+void API_ENTRY(glGetLightxvOES)(GLenum light, GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetLightxvOES, light, pname, params);
+}
+void API_ENTRY(glGetMaterialxvOES)(GLenum face, GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetMaterialxvOES, face, pname, params);
+}
+void API_ENTRY(glGetTexEnvxvOES)(GLenum env, GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetTexEnvxvOES, env, pname, params);
+}
+void API_ENTRY(glGetTexParameterxvOES)(GLenum target, GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetTexParameterxvOES, target, pname, params);
+}
+void API_ENTRY(glLightModelxOES)(GLenum pname, GLfixed param) {
+ CALL_GL_API(glLightModelxOES, pname, param);
+}
+void API_ENTRY(glLightModelxvOES)(GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glLightModelxvOES, pname, params);
+}
+void API_ENTRY(glLightxOES)(GLenum light, GLenum pname, GLfixed param) {
+ CALL_GL_API(glLightxOES, light, pname, param);
+}
+void API_ENTRY(glLightxvOES)(GLenum light, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glLightxvOES, light, pname, params);
+}
+void API_ENTRY(glLineWidthxOES)(GLfixed width) {
+ CALL_GL_API(glLineWidthxOES, width);
+}
+void API_ENTRY(glLoadMatrixxOES)(const GLfixed *m) {
+ CALL_GL_API(glLoadMatrixxOES, m);
+}
+void API_ENTRY(glMaterialxOES)(GLenum face, GLenum pname, GLfixed param) {
+ CALL_GL_API(glMaterialxOES, face, pname, param);
+}
+void API_ENTRY(glMaterialxvOES)(GLenum face, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glMaterialxvOES, face, pname, params);
+}
+void API_ENTRY(glMultMatrixxOES)(const GLfixed *m) {
+ CALL_GL_API(glMultMatrixxOES, m);
+}
+void API_ENTRY(glMultiTexCoord4xOES)(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) {
+ CALL_GL_API(glMultiTexCoord4xOES, target, s, t, r, q);
+}
+void API_ENTRY(glNormal3xOES)(GLfixed nx, GLfixed ny, GLfixed nz) {
+ CALL_GL_API(glNormal3xOES, nx, ny, nz);
+}
+void API_ENTRY(glOrthoxOES)(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) {
+ CALL_GL_API(glOrthoxOES, left, right, bottom, top, zNear, zFar);
+}
+void API_ENTRY(glPointParameterxOES)(GLenum pname, GLfixed param) {
+ CALL_GL_API(glPointParameterxOES, pname, param);
+}
+void API_ENTRY(glPointParameterxvOES)(GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glPointParameterxvOES, pname, params);
+}
+void API_ENTRY(glPointSizexOES)(GLfixed size) {
+ CALL_GL_API(glPointSizexOES, size);
+}
+void API_ENTRY(glPolygonOffsetxOES)(GLfixed factor, GLfixed units) {
+ CALL_GL_API(glPolygonOffsetxOES, factor, units);
+}
+void API_ENTRY(glRotatexOES)(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) {
+ CALL_GL_API(glRotatexOES, angle, x, y, z);
+}
+void API_ENTRY(glSampleCoveragexOES)(GLclampx value, GLboolean invert) {
+ CALL_GL_API(glSampleCoveragexOES, value, invert);
+}
+void API_ENTRY(glScalexOES)(GLfixed x, GLfixed y, GLfixed z) {
+ CALL_GL_API(glScalexOES, x, y, z);
+}
+void API_ENTRY(glTexEnvxOES)(GLenum target, GLenum pname, GLfixed param) {
+ CALL_GL_API(glTexEnvxOES, target, pname, param);
+}
+void API_ENTRY(glTexEnvxvOES)(GLenum target, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glTexEnvxvOES, target, pname, params);
+}
+void API_ENTRY(glTexParameterxOES)(GLenum target, GLenum pname, GLfixed param) {
+ CALL_GL_API(glTexParameterxOES, target, pname, param);
+}
+void API_ENTRY(glTexParameterxvOES)(GLenum target, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glTexParameterxvOES, target, pname, params);
+}
+void API_ENTRY(glTranslatexOES)(GLfixed x, GLfixed y, GLfixed z) {
+ CALL_GL_API(glTranslatexOES, x, y, z);
+}
+GLboolean API_ENTRY(glIsRenderbufferOES)(GLuint renderbuffer) {
+ CALL_GL_API_RETURN(glIsRenderbufferOES, renderbuffer);
+}
+void API_ENTRY(glBindRenderbufferOES)(GLenum target, GLuint renderbuffer) {
+ CALL_GL_API(glBindRenderbufferOES, target, renderbuffer);
+}
+void API_ENTRY(glDeleteRenderbuffersOES)(GLsizei n, const GLuint* renderbuffers) {
+ CALL_GL_API(glDeleteRenderbuffersOES, n, renderbuffers);
+}
+void API_ENTRY(glGenRenderbuffersOES)(GLsizei n, GLuint* renderbuffers) {
+ CALL_GL_API(glGenRenderbuffersOES, n, renderbuffers);
+}
+void API_ENTRY(glRenderbufferStorageOES)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
+ CALL_GL_API(glRenderbufferStorageOES, target, internalformat, width, height);
+}
+void API_ENTRY(glGetRenderbufferParameterivOES)(GLenum target, GLenum pname, GLint* params) {
+ CALL_GL_API(glGetRenderbufferParameterivOES, target, pname, params);
+}
+GLboolean API_ENTRY(glIsFramebufferOES)(GLuint framebuffer) {
+ CALL_GL_API_RETURN(glIsFramebufferOES, framebuffer);
+}
+void API_ENTRY(glBindFramebufferOES)(GLenum target, GLuint framebuffer) {
+ CALL_GL_API(glBindFramebufferOES, target, framebuffer);
+}
+void API_ENTRY(glDeleteFramebuffersOES)(GLsizei n, const GLuint* framebuffers) {
+ CALL_GL_API(glDeleteFramebuffersOES, n, framebuffers);
+}
+void API_ENTRY(glGenFramebuffersOES)(GLsizei n, GLuint* framebuffers) {
+ CALL_GL_API(glGenFramebuffersOES, n, framebuffers);
+}
+GLenum API_ENTRY(glCheckFramebufferStatusOES)(GLenum target) {
+ CALL_GL_API_RETURN(glCheckFramebufferStatusOES, target);
+}
+void API_ENTRY(glFramebufferRenderbufferOES)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {
+ CALL_GL_API(glFramebufferRenderbufferOES, target, attachment, renderbuffertarget, renderbuffer);
+}
+void API_ENTRY(glFramebufferTexture2DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
+ CALL_GL_API(glFramebufferTexture2DOES, target, attachment, textarget, texture, level);
+}
+void API_ENTRY(glGetFramebufferAttachmentParameterivOES)(GLenum target, GLenum attachment, GLenum pname, GLint* params) {
+ CALL_GL_API(glGetFramebufferAttachmentParameterivOES, target, attachment, pname, params);
+}
+void API_ENTRY(glGenerateMipmapOES)(GLenum target) {
+ CALL_GL_API(glGenerateMipmapOES, target);
+}
+void* API_ENTRY(glMapBufferOES)(GLenum target, GLenum access) {
+ CALL_GL_API_RETURN(glMapBufferOES, target, access);
+}
+GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) {
+ CALL_GL_API_RETURN(glUnmapBufferOES, target);
+}
+void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void** params) {
+ CALL_GL_API(glGetBufferPointervOES, target, pname, params);
+}
+void API_ENTRY(glCurrentPaletteMatrixOES)(GLuint matrixpaletteindex) {
+ CALL_GL_API(glCurrentPaletteMatrixOES, matrixpaletteindex);
+}
+void API_ENTRY(glLoadPaletteFromModelViewMatrixOES)(void) {
+ CALL_GL_API(glLoadPaletteFromModelViewMatrixOES);
+}
+void API_ENTRY(glMatrixIndexPointerOES)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+ CALL_GL_API(glMatrixIndexPointerOES, size, type, stride, pointer);
+}
+void API_ENTRY(glWeightPointerOES)(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) {
+ CALL_GL_API(glWeightPointerOES, size, type, stride, pointer);
+}
+GLbitfield API_ENTRY(glQueryMatrixxOES)(GLfixed mantissa[16], GLint exponent[16]) {
+ CALL_GL_API_RETURN(glQueryMatrixxOES, mantissa, exponent);
+}
+void API_ENTRY(glDepthRangefOES)(GLclampf zNear, GLclampf zFar) {
+ CALL_GL_API(glDepthRangefOES, zNear, zFar);
+}
+void API_ENTRY(glFrustumfOES)(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+ CALL_GL_API(glFrustumfOES, left, right, bottom, top, zNear, zFar);
+}
+void API_ENTRY(glOrthofOES)(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
+ CALL_GL_API(glOrthofOES, left, right, bottom, top, zNear, zFar);
+}
+void API_ENTRY(glClipPlanefOES)(GLenum plane, const GLfloat *equation) {
+ CALL_GL_API(glClipPlanefOES, plane, equation);
+}
+void API_ENTRY(glGetClipPlanefOES)(GLenum pname, GLfloat eqn[4]) {
+ CALL_GL_API(glGetClipPlanefOES, pname, eqn);
+}
+void API_ENTRY(glClearDepthfOES)(GLclampf depth) {
+ CALL_GL_API(glClearDepthfOES, depth);
+}
+void API_ENTRY(glTexGenfOES)(GLenum coord, GLenum pname, GLfloat param) {
+ CALL_GL_API(glTexGenfOES, coord, pname, param);
+}
+void API_ENTRY(glTexGenfvOES)(GLenum coord, GLenum pname, const GLfloat *params) {
+ CALL_GL_API(glTexGenfvOES, coord, pname, params);
+}
+void API_ENTRY(glTexGeniOES)(GLenum coord, GLenum pname, GLint param) {
+ CALL_GL_API(glTexGeniOES, coord, pname, param);
+}
+void API_ENTRY(glTexGenivOES)(GLenum coord, GLenum pname, const GLint *params) {
+ CALL_GL_API(glTexGenivOES, coord, pname, params);
+}
+void API_ENTRY(glTexGenxOES)(GLenum coord, GLenum pname, GLfixed param) {
+ CALL_GL_API(glTexGenxOES, coord, pname, param);
+}
+void API_ENTRY(glTexGenxvOES)(GLenum coord, GLenum pname, const GLfixed *params) {
+ CALL_GL_API(glTexGenxvOES, coord, pname, params);
+}
+void API_ENTRY(glGetTexGenfvOES)(GLenum coord, GLenum pname, GLfloat *params) {
+ CALL_GL_API(glGetTexGenfvOES, coord, pname, params);
+}
+void API_ENTRY(glGetTexGenivOES)(GLenum coord, GLenum pname, GLint *params) {
+ CALL_GL_API(glGetTexGenivOES, coord, pname, params);
+}
+void API_ENTRY(glGetTexGenxvOES)(GLenum coord, GLenum pname, GLfixed *params) {
+ CALL_GL_API(glGetTexGenxvOES, coord, pname, params);
+}
diff --git a/opengl/libs/egl_entries.in b/opengl/libs/egl_entries.in
index 33b4c65..3b4551b 100644
--- a/opengl/libs/egl_entries.in
+++ b/opengl/libs/egl_entries.in
@@ -43,3 +43,10 @@
/* EGL 1.3 */
/* EGL 1.4 */
+
+/* EGL_EGLEXT_VERSION 3 */
+
+EGL_ENTRY(EGLBoolean, eglLockSurfaceKHR, EGLDisplay, EGLSurface, const EGLint *)
+EGL_ENTRY(EGLBoolean, eglUnlockSurfaceKHR, EGLDisplay, EGLSurface)
+EGL_ENTRY(EGLImageKHR, eglCreateImageKHR, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *)
+EGL_ENTRY(EGLBoolean, eglDestroyImageKHR, EGLDisplay, EGLImageKHR)
diff --git a/opengl/libs/gl_entries.in b/opengl/libs/gl_entries.in
index b97e8fe..d7cc5da 100644
--- a/opengl/libs/gl_entries.in
+++ b/opengl/libs/gl_entries.in
@@ -1,159 +1,145 @@
-GL_ENTRY(void, glColor4f, GLfloat, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glColor4x, GLfixed, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glNormal3f, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glNormal3x, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glCullFace, GLenum)
-GL_ENTRY(void, glFrontFace, GLenum)
-GL_ENTRY(void, glDisable, GLenum)
-GL_ENTRY(void, glEnable, GLenum)
-GL_ENTRY(void, glFinish, void)
-GL_ENTRY(void, glFlush, void)
-GL_ENTRY(GLenum, glGetError, void)
-GL_ENTRY(const GLubyte*, glGetString, GLenum)
-GL_ENTRY(void, glGetIntegerv, GLenum, GLint *)
-GL_ENTRY(void, glColorMask, GLboolean, GLboolean, GLboolean, GLboolean)
-GL_ENTRY(void, glDepthMask, GLboolean)
-GL_ENTRY(void, glStencilMask, GLuint)
-GL_ENTRY(void, glDepthFunc, GLenum)
-GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
-GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar)
-GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
-GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
-GL_ENTRY(void, glLogicOp, GLenum opcode)
-GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref)
GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref)
-GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
-GL_ENTRY(void, glClear, GLbitfield mask)
-GL_ENTRY(void, glClearColor, GLclampf r, GLclampf g, GLclampf b, GLclampf a)
-GL_ENTRY(void, glClearColorx, GLclampx r, GLclampx g, GLclampx b, GLclampx a)
+GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
GL_ENTRY(void, glClearDepthf, GLclampf depth)
+GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation)
+GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
+GL_ENTRY(void, glFogf, GLenum pname, GLfloat param)
+GL_ENTRY(void, glFogfv, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glFrustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat eqn[4])
+GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetLightfv, GLenum light, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetMaterialfv, GLenum face, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param)
+GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glLightf, GLenum light, GLenum pname, GLfloat param)
+GL_ENTRY(void, glLightfv, GLenum light, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glLineWidth, GLfloat width)
+GL_ENTRY(void, glLoadMatrixf, const GLfloat *m)
+GL_ENTRY(void, glMaterialf, GLenum face, GLenum pname, GLfloat param)
+GL_ENTRY(void, glMaterialfv, GLenum face, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glMultMatrixf, const GLfloat *m)
+GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
+GL_ENTRY(void, glNormal3f, GLfloat nx, GLfloat ny, GLfloat nz)
+GL_ENTRY(void, glOrthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glPointParameterf, GLenum pname, GLfloat param)
+GL_ENTRY(void, glPointParameterfv, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glPointSize, GLfloat size)
+GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units)
+GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glScalef, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glTexEnvf, GLenum target, GLenum pname, GLfloat param)
+GL_ENTRY(void, glTexEnvfv, GLenum target, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param)
+GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z)
+GL_ENTRY(void, glActiveTexture, GLenum texture)
+GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref)
+GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
+GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
+GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor)
+GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)
+GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)
+GL_ENTRY(void, glClear, GLbitfield mask)
+GL_ENTRY(void, glClearColorx, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
GL_ENTRY(void, glClearDepthx, GLclampx depth)
GL_ENTRY(void, glClearStencil, GLint s)
-GL_ENTRY(void, glPointSize, GLfloat)
-GL_ENTRY(void, glPointSizex, GLfixed)
-GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
-GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert)
-GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
-GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
-GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
-GL_ENTRY(void, glHint, GLenum, GLenum mode)
-GL_ENTRY(void, glLineWidth, GLfloat width)
+GL_ENTRY(void, glClientActiveTexture, GLenum texture)
+GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed *equation)
+GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
+GL_ENTRY(void, glColor4x, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
+GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
+GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glCullFace, GLenum mode)
+GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers)
+GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures)
+GL_ENTRY(void, glDepthFunc, GLenum func)
+GL_ENTRY(void, glDepthMask, GLboolean flag)
+GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar)
+GL_ENTRY(void, glDisable, GLenum cap)
+GL_ENTRY(void, glDisableClientState, GLenum array)
+GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
+GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
+GL_ENTRY(void, glEnable, GLenum cap)
+GL_ENTRY(void, glEnableClientState, GLenum array)
+GL_ENTRY(void, glFinish, void)
+GL_ENTRY(void, glFlush, void)
+GL_ENTRY(void, glFogx, GLenum pname, GLfixed param)
+GL_ENTRY(void, glFogxv, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glFrontFace, GLenum mode)
+GL_ENTRY(void, glFrustumx, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params)
+GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed eqn[4])
+GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint *buffers)
+GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures)
+GL_ENTRY(GLenum, glGetError, void)
+GL_ENTRY(void, glGetFixedv, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetLightxv, GLenum light, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetPointerv, GLenum pname, void **params)
+GL_ENTRY(const GLubyte *, glGetString, GLenum name)
+GL_ENTRY(void, glGetTexEnviv, GLenum env, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetTexEnvxv, GLenum env, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glHint, GLenum target, GLenum mode)
+GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer)
+GL_ENTRY(GLboolean, glIsEnabled, GLenum cap)
+GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
+GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightModelxv, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glLightx, GLenum light, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightxv, GLenum light, GLenum pname, const GLfixed *params)
GL_ENTRY(void, glLineWidthx, GLfixed width)
-GL_ENTRY(void, glShadeModel, GLenum)
-GL_ENTRY(void, glLightModelf, GLenum, GLfloat)
-GL_ENTRY(void, glLightModelfv, GLenum, const GLfloat *)
-GL_ENTRY(void, glLightModelx, GLenum, GLfixed)
-GL_ENTRY(void, glLightModelxv, GLenum, const GLfixed *)
-GL_ENTRY(void, glLightf, GLenum, GLenum, GLfloat)
-GL_ENTRY(void, glLightfv, GLenum, GLenum, const GLfloat *)
-GL_ENTRY(void, glLightx, GLenum, GLenum, GLfixed)
-GL_ENTRY(void, glLightxv, GLenum, GLenum, const GLfixed *)
-GL_ENTRY(void, glMaterialf, GLenum, GLenum, GLfloat)
-GL_ENTRY(void, glMaterialfv, GLenum, GLenum, const GLfloat *)
-GL_ENTRY(void, glMaterialx, GLenum, GLenum, GLfixed)
-GL_ENTRY(void, glMaterialxv, GLenum, GLenum, const GLfixed *)
-GL_ENTRY(void, glFogf, GLenum, GLfloat)
-GL_ENTRY(void, glFogfv, GLenum, const GLfloat *)
-GL_ENTRY(void, glFogx, GLenum, GLfixed)
-GL_ENTRY(void, glFogxv, GLenum, const GLfixed *)
-GL_ENTRY(void, glVertexPointer, GLint, GLenum, GLsizei, const GLvoid *)
-GL_ENTRY(void, glColorPointer, GLint, GLenum, GLsizei, const GLvoid *)
-GL_ENTRY(void, glNormalPointer, GLenum, GLsizei, const GLvoid *)
-GL_ENTRY(void, glTexCoordPointer, GLint, GLenum, GLsizei, const GLvoid *)
-GL_ENTRY(void, glEnableClientState, GLenum)
-GL_ENTRY(void, glDisableClientState, GLenum)
-GL_ENTRY(void, glClientActiveTexture, GLenum)
-GL_ENTRY(void, glDrawArrays, GLenum, GLint first, GLsizei)
-GL_ENTRY(void, glDrawElements, GLenum, GLsizei, GLenum, const GLvoid *)
GL_ENTRY(void, glLoadIdentity, void)
-GL_ENTRY(void, glLoadMatrixf, const GLfloat*)
-GL_ENTRY(void, glLoadMatrixx, const GLfixed*)
+GL_ENTRY(void, glLoadMatrixx, const GLfixed *m)
+GL_ENTRY(void, glLogicOp, GLenum opcode)
+GL_ENTRY(void, glMaterialx, GLenum face, GLenum pname, GLfixed param)
+GL_ENTRY(void, glMaterialxv, GLenum face, GLenum pname, const GLfixed *params)
GL_ENTRY(void, glMatrixMode, GLenum mode)
-GL_ENTRY(void, glMultMatrixf, const GLfloat*)
-GL_ENTRY(void, glMultMatrixx, const GLfixed*)
+GL_ENTRY(void, glMultMatrixx, const GLfixed *m)
+GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+GL_ENTRY(void, glNormal3x, GLfixed nx, GLfixed ny, GLfixed nz)
+GL_ENTRY(void, glNormalPointer, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glOrthox, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param)
+GL_ENTRY(void, glPointParameterx, GLenum pname, GLfixed param)
+GL_ENTRY(void, glPointParameterxv, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glPointSizex, GLfixed size)
+GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
GL_ENTRY(void, glPopMatrix, void)
GL_ENTRY(void, glPushMatrix, void)
-GL_ENTRY(void, glFrustumf, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glFrustumx, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glOrthof, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glOrthox, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glRotatef, GLfloat, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glRotatex, GLfixed, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glScalef, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glScalex, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glTranslatef, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glTranslatex, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glViewport, GLint, GLint, GLsizei, GLsizei)
-GL_ENTRY(void, glActiveTexture, GLenum)
-GL_ENTRY(void, glBindTexture, GLenum, GLuint)
-GL_ENTRY(void, glGenTextures, GLsizei, GLuint*)
-GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *)
-GL_ENTRY(void, glMultiTexCoord4f, GLenum, GLfloat, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glMultiTexCoord4x, GLenum, GLfixed, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glPixelStorei, GLenum, GLint)
-GL_ENTRY(void, glTexEnvf, GLenum, GLenum, GLfloat)
-GL_ENTRY(void, glTexEnvfv, GLenum, GLenum, const GLfloat*)
-GL_ENTRY(void, glTexEnvx, GLenum, GLenum, GLfixed)
-GL_ENTRY(void, glTexEnvxv, GLenum, GLenum, const GLfixed*)
-GL_ENTRY(void, glTexParameterf, GLenum, GLenum, GLfloat)
-GL_ENTRY(void, glTexParameterx, GLenum, GLenum, GLfixed)
-GL_ENTRY(void, glCompressedTexImage2D, GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)
-GL_ENTRY(void, glCompressedTexSubImage2D, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)
-GL_ENTRY(void, glCopyTexImage2D, GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint)
-GL_ENTRY(void, glCopyTexSubImage2D, GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei)
-GL_ENTRY(void, glTexImage2D, GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)
-GL_ENTRY(void, glTexSubImage2D, GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)
-GL_ENTRY(void, glReadPixels, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid *)
-
-// 1.1 additions
-GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat*)
-GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed*)
-GL_ENTRY(void, glBindBuffer, GLenum, GLuint)
-GL_ENTRY(void, glBufferData, GLenum, GLsizeiptr, const GLvoid*, GLenum)
-GL_ENTRY(void, glBufferSubData, GLenum, GLintptr, GLsizeiptr, const GLvoid*)
-GL_ENTRY(void, glDeleteBuffers, GLsizei, const GLuint*)
-GL_ENTRY(void, glGenBuffers, GLsizei, GLuint*)
-GL_ENTRY(void, glGetBooleanv, GLenum, GLboolean *)
-GL_ENTRY(void, glGetFixedv, GLenum, GLfixed *)
-GL_ENTRY(void, glGetFloatv, GLenum, GLfloat *)
-GL_ENTRY(void, glGetPointerv, GLenum, void **)
-GL_ENTRY(void, glGetBufferParameteriv, GLenum, GLenum, GLint *)
-GL_ENTRY(void, glGetClipPlanef, GLenum, GLfloat[4])
-GL_ENTRY(void, glGetClipPlanex, GLenum, GLfixed[4])
-GL_ENTRY(void, glGetLightxv, GLenum, GLenum, GLfixed *)
-GL_ENTRY(void, glGetLightfv, GLenum, GLenum, GLfloat *)
-GL_ENTRY(void, glGetMaterialxv, GLenum, GLenum, GLfixed *)
-GL_ENTRY(void, glGetMaterialfv, GLenum, GLenum, GLfloat *)
-GL_ENTRY(void, glGetTexEnvfv, GLenum, GLenum, GLfloat *)
-GL_ENTRY(void, glGetTexEnviv, GLenum, GLenum, GLint *)
-GL_ENTRY(void, glGetTexEnvxv, GLenum, GLenum, GLfixed *)
-GL_ENTRY(void, glGetTexParameterfv, GLenum, GLenum, GLfloat *)
-GL_ENTRY(void, glGetTexParameteriv, GLenum, GLenum, GLint *)
-GL_ENTRY(void, glGetTexParameterxv, GLenum, GLenum, GLfixed *)
-GL_ENTRY(GLboolean, glIsBuffer, GLuint)
-GL_ENTRY(GLboolean, glIsEnabled, GLenum)
-GL_ENTRY(GLboolean, glIsTexture, GLuint)
-GL_ENTRY(void, glPointParameterf, GLenum, GLfloat)
-GL_ENTRY(void, glPointParameterfv, GLenum, const GLfloat *)
-GL_ENTRY(void, glPointParameterx, GLenum, GLfixed)
-GL_ENTRY(void, glPointParameterxv, GLenum, const GLfixed *)
-GL_ENTRY(void, glColor4ub, GLubyte, GLubyte, GLubyte, GLubyte)
-GL_ENTRY(void, glTexEnvi, GLenum, GLenum, GLint)
-GL_ENTRY(void, glTexEnviv, GLenum, GLenum, const GLint *)
-GL_ENTRY(void, glTexParameterfv, GLenum, GLenum, const GLfloat *)
-GL_ENTRY(void, glTexParameteriv, GLenum, GLenum, const GLint *)
-GL_ENTRY(void, glTexParameteri, GLenum, GLenum, GLint)
-GL_ENTRY(void, glTexParameterxv, GLenum, GLenum, const GLfixed *)
-GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid*)
-
-// Extensions
-GL_ENTRY(void, glDrawTexsOES, GLshort, GLshort, GLshort, GLshort, GLshort)
-GL_ENTRY(void, glDrawTexiOES, GLint, GLint, GLint, GLint, GLint)
-GL_ENTRY(void, glDrawTexfOES, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat)
-GL_ENTRY(void, glDrawTexxOES, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed)
-GL_ENTRY(void, glDrawTexsvOES, const GLshort*)
-GL_ENTRY(void, glDrawTexivOES, const GLint*)
-GL_ENTRY(void, glDrawTexfvOES, const GLfloat*)
-GL_ENTRY(void, glDrawTexxvOES, const GLfixed*)
-GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed* mantissa, GLint* exponent)
-
+GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
+GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert)
+GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert)
+GL_ENTRY(void, glScalex, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glShadeModel, GLenum mode)
+GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
+GL_ENTRY(void, glStencilMask, GLuint mask)
+GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass)
+GL_ENTRY(void, glTexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glTexEnvi, GLenum target, GLenum pname, GLint param)
+GL_ENTRY(void, glTexEnvx, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexEnviv, GLenum target, GLenum pname, const GLint *params)
+GL_ENTRY(void, glTexEnvxv, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param)
+GL_ENTRY(void, glTexParameterx, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint *params)
+GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
+GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid *pointer)
diff --git a/opengl/libs/gl_logger.h b/opengl/libs/gl_logger.h
deleted file mode 100644
index ce85dd1..0000000
--- a/opengl/libs/gl_logger.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- ** Copyright 2007, The Android Open Source Project
- **
- ** Licensed under the Apache License, Version 2.0 (the "License");
- ** you may not use this file except in compliance with the License.
- ** You may obtain a copy of the License at
- **
- ** http://www.apache.org/licenses/LICENSE-2.0
- **
- ** Unless required by applicable law or agreed to in writing, software
- ** distributed under the License is distributed on an "AS IS" BASIS,
- ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ** See the License for the specific language governing permissions and
- ** limitations under the License.
- */
-
-#ifndef ANDROID_GL_LOGGER_H
-#define ANDROID_GL_LOGGER_H
-
-namespace android {
-#define GL_ENTRY(r, api, ...) r log_##api(__VA_ARGS__);
-#include "gl_entries.in"
-#undef GL_ENTRY
-}; // namespace android
-
-#endif /* ANDROID_GL_LOGGER_H */
diff --git a/opengl/libs/glext_entries.in b/opengl/libs/glext_entries.in
new file mode 100644
index 0000000..dd09c71
--- /dev/null
+++ b/opengl/libs/glext_entries.in
@@ -0,0 +1,90 @@
+GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha)
+GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+GL_ENTRY(void, glBlendEquationOES, GLenum mode)
+GL_ENTRY(void, glDrawTexsOES, GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
+GL_ENTRY(void, glDrawTexiOES, GLint x, GLint y, GLint z, GLint width, GLint height)
+GL_ENTRY(void, glDrawTexxOES, GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
+GL_ENTRY(void, glDrawTexsvOES, const GLshort *coords)
+GL_ENTRY(void, glDrawTexivOES, const GLint *coords)
+GL_ENTRY(void, glDrawTexxvOES, const GLfixed *coords)
+GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
+GL_ENTRY(void, glDrawTexfvOES, const GLfloat *coords)
+GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image)
+GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image)
+GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref)
+GL_ENTRY(void, glClearColorxOES, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
+GL_ENTRY(void, glClearDepthxOES, GLclampx depth)
+GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed *equation)
+GL_ENTRY(void, glColor4xOES, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
+GL_ENTRY(void, glDepthRangexOES, GLclampx zNear, GLclampx zFar)
+GL_ENTRY(void, glFogxOES, GLenum pname, GLfixed param)
+GL_ENTRY(void, glFogxvOES, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glFrustumxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed eqn[4])
+GL_ENTRY(void, glGetFixedvOES, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetLightxvOES, GLenum light, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetTexEnvxvOES, GLenum env, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params)
+GL_ENTRY(void, glLightModelxOES, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightModelxvOES, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glLightxOES, GLenum light, GLenum pname, GLfixed param)
+GL_ENTRY(void, glLightxvOES, GLenum light, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glLineWidthxOES, GLfixed width)
+GL_ENTRY(void, glLoadMatrixxOES, const GLfixed *m)
+GL_ENTRY(void, glMaterialxOES, GLenum face, GLenum pname, GLfixed param)
+GL_ENTRY(void, glMaterialxvOES, GLenum face, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m)
+GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
+GL_ENTRY(void, glNormal3xOES, GLfixed nx, GLfixed ny, GLfixed nz)
+GL_ENTRY(void, glOrthoxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
+GL_ENTRY(void, glPointParameterxOES, GLenum pname, GLfixed param)
+GL_ENTRY(void, glPointParameterxvOES, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glPointSizexOES, GLfixed size)
+GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units)
+GL_ENTRY(void, glRotatexOES, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glSampleCoveragexOES, GLclampx value, GLboolean invert)
+GL_ENTRY(void, glScalexOES, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(void, glTexEnvxOES, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexEnvxvOES, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTexParameterxOES, GLenum target, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z)
+GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer)
+GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer)
+GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers)
+GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers)
+GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params)
+GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint framebuffer)
+GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer)
+GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei n, const GLuint* framebuffers)
+GL_ENTRY(void, glGenFramebuffersOES, GLsizei n, GLuint* framebuffers)
+GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum target)
+GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum target, GLenum attachment, GLenum pname, GLint* params)
+GL_ENTRY(void, glGenerateMipmapOES, GLenum target)
+GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access)
+GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target)
+GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params)
+GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint matrixpaletteindex)
+GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void)
+GL_ENTRY(void, glMatrixIndexPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
+GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16])
+GL_ENTRY(void, glDepthRangefOES, GLclampf zNear, GLclampf zFar)
+GL_ENTRY(void, glFrustumfOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glOrthofOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
+GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation)
+GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat eqn[4])
+GL_ENTRY(void, glClearDepthfOES, GLclampf depth)
+GL_ENTRY(void, glTexGenfOES, GLenum coord, GLenum pname, GLfloat param)
+GL_ENTRY(void, glTexGenfvOES, GLenum coord, GLenum pname, const GLfloat *params)
+GL_ENTRY(void, glTexGeniOES, GLenum coord, GLenum pname, GLint param)
+GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params)
+GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param)
+GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params)
+GL_ENTRY(void, glGetTexGenfvOES, GLenum coord, GLenum pname, GLfloat *params)
+GL_ENTRY(void, glGetTexGenivOES, GLenum coord, GLenum pname, GLint *params)
+GL_ENTRY(void, glGetTexGenxvOES, GLenum coord, GLenum pname, GLfixed *params)
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index 63fb017..fd97254 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -22,9 +22,10 @@
#include <errno.h>
#include <EGL/egl.h>
+#include <EGL/eglext.h>
#include <GLES/gl.h>
+#include <GLES/glext.h>
-#define GL_LOGGER 0
#if !defined(__arm__)
#define USE_SLOW_BINDING 1
#else
@@ -35,7 +36,7 @@
#define MAX_NUMBER_OF_GL_EXTENSIONS 32
-#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && !GL_LOGGER && __OPTIMIZE__
+#if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__
#define USE_FAST_TLS_KEY 1
#else
#define USE_FAST_TLS_KEY 0
@@ -55,7 +56,10 @@
enum {
IMPL_HARDWARE = 0,
IMPL_SOFTWARE,
- IMPL_CONTEXT_LOST,
+
+ IMPL_NUM_DRIVERS_IMPLEMENTATIONS,
+
+ IMPL_CONTEXT_LOST = IMPL_NUM_DRIVERS_IMPLEMENTATIONS,
IMPL_NO_CONTEXT,
IMPL_NUM_IMPLEMENTATIONS
@@ -73,6 +77,7 @@
struct gl_hooks_t {
struct gl_t {
#include "gl_entries.in"
+ #include "glext_entries.in"
} gl;
struct egl_t {
#include "egl_entries.in"
diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles
new file mode 100755
index 0000000..107768b
--- /dev/null
+++ b/opengl/libs/tools/genfiles
@@ -0,0 +1,20 @@
+#! /bin/sh
+#
+# Copyright (C) 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./glapigen ../../include/GLES/gl.h > ../GLES_CM/gl_api.in
+./glentrygen ../../include/GLES/gl.h > ../gl_entries.in
+./glapigen ../../include/GLES/glext.h > ../GLES_CM/glext_api.in
+./glentrygen ../../include/GLES/glext.h > ../glext_entries.in
diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen
new file mode 100755
index 0000000..a2c3a7b
--- /dev/null
+++ b/opengl/libs/tools/glapigen
@@ -0,0 +1,72 @@
+#! /usr/bin/perl
+#
+# Copyright (C) 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+use strict;
+
+while (my $line = <>) {
+ next if $line =~ /^\//;
+ next if $line =~ /^#/;
+ next if $line =~ /^\s*$/;
+ if ($line !~ /^GL_API\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
+ next;
+ }
+ my $type = $1;
+ my $name = $2;
+ my $args = $3;
+
+ #printf("%s", $line);
+
+ my $prefix = "";
+ if ($name eq "glEGLImageTargetTexture2DOES") {
+ $prefix = "__";
+ }
+ if ($name eq "glEGLImageTargetRenderbufferStorageOES") {
+ $prefix = "__";
+ }
+
+ printf("%s API_ENTRY(%s%s)(%s)", $type, $prefix, $name, $args);
+
+ printf(" {\n");
+ if ($type eq "void") {
+ printf(" CALL_GL_API(%s", $name);
+ } else {
+ printf(" CALL_GL_API_RETURN(%s", $name);
+ }
+ my @args = split ',', $args;
+ my $len = scalar(@args);
+ for (my $num = 0; $num < $len; $num++) {
+ if ($args[$num] ne "void") {
+ print ", ";
+ #
+ # extract the name from the parameter
+ # type name
+ # const type *name
+ # type *name
+ # type name[4]
+ #
+ if ($args[$num] =~ /(\S+\s)+\**\s*([\w]+)/) {
+ printf("%s", $2);
+ }
+ }
+ }
+ printf(");\n");
+ printf("}\n");
+}
+
+
+
+
+
diff --git a/opengl/libs/tools/glentrygen b/opengl/libs/tools/glentrygen
new file mode 100755
index 0000000..5e0f7b6
--- /dev/null
+++ b/opengl/libs/tools/glentrygen
@@ -0,0 +1,31 @@
+#! /usr/bin/perl
+#
+# Copyright (C) 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+use strict;
+
+while (my $line = <>) {
+ next if $line =~ /^\//;
+ next if $line =~ /^#/;
+ next if $line =~ /^\s*$/;
+ if ($line !~ /^GL_API\s+(.+)\s+GL_APIENTRY\s+([\w]+)\s*\(([^\)]+)\);/) {
+ next;
+ }
+ my $type = $1;
+ my $name = $2;
+ my $args = $3;
+
+ printf("GL_ENTRY(%s, %s, %s)\n", $type, $name, $args);
+}
diff --git a/tests/AndroidTests/res/values-320x200/configVarying.xml b/tests/AndroidTests/res/values-320x200/configVarying.xml
deleted file mode 100644
index ca2a286..0000000
--- a/tests/AndroidTests/res/values-320x200/configVarying.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <item type="configVarying" name="simple">simple 320x200</item>
- <bag type="configVarying" name="bag">
- <item name="testString">bag 320x200</item>
- </bag>
-</resources>
diff --git a/tests/AndroidTests/res/values-finger/configVarying.xml b/tests/AndroidTests/res/values-32dpi/configVarying.xml
similarity index 86%
copy from tests/AndroidTests/res/values-finger/configVarying.xml
copy to tests/AndroidTests/res/values-32dpi/configVarying.xml
index 674787e..f903f0f 100644
--- a/tests/AndroidTests/res/values-finger/configVarying.xml
+++ b/tests/AndroidTests/res/values-32dpi/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple finger</item>
+ <item type="configVarying" name="simple">simple 32dpi</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag finger</item>
+ <item name="testString">bag 32dpi</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-finger/configVarying.xml b/tests/AndroidTests/res/values-640x400/configVarying.xml
similarity index 86%
copy from tests/AndroidTests/res/values-finger/configVarying.xml
copy to tests/AndroidTests/res/values-640x400/configVarying.xml
index 674787e..30332c0 100644
--- a/tests/AndroidTests/res/values-finger/configVarying.xml
+++ b/tests/AndroidTests/res/values-640x400/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple finger</item>
+ <item type="configVarying" name="simple">simple 640x400</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag finger</item>
+ <item name="testString">bag 640x400</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-finger/configVarying.xml b/tests/AndroidTests/res/values-fr-rFR/configVarying.xml
similarity index 86%
rename from tests/AndroidTests/res/values-finger/configVarying.xml
rename to tests/AndroidTests/res/values-fr-rFR/configVarying.xml
index 674787e..5ecac7c 100644
--- a/tests/AndroidTests/res/values-finger/configVarying.xml
+++ b/tests/AndroidTests/res/values-fr-rFR/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple finger</item>
+ <item type="configVarying" name="simple">simple fr FR</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag finger</item>
+ <item name="testString">bag fr FR</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-finger/configVarying.xml b/tests/AndroidTests/res/values-fr/configVarying.xml
similarity index 86%
copy from tests/AndroidTests/res/values-finger/configVarying.xml
copy to tests/AndroidTests/res/values-fr/configVarying.xml
index 674787e..8413b5a 100644
--- a/tests/AndroidTests/res/values-finger/configVarying.xml
+++ b/tests/AndroidTests/res/values-fr/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple finger</item>
+ <item type="configVarying" name="simple">simple fr</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag finger</item>
+ <item name="testString">bag fr</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-keyshidden/configVarying.xml b/tests/AndroidTests/res/values-keyshidden/configVarying.xml
deleted file mode 100644
index fdffc4d..0000000
--- a/tests/AndroidTests/res/values-keyshidden/configVarying.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <item type="configVarying" name="simple">simple keyshidden</item>
- <bag type="configVarying" name="bag">
- <item name="testString">bag keyshidden</item>
- </bag>
-</resources>
diff --git a/tests/AndroidTests/res/values-trackball/configVarying.xml b/tests/AndroidTests/res/values-mcc110-xx/configVarying.xml
similarity index 86%
copy from tests/AndroidTests/res/values-trackball/configVarying.xml
copy to tests/AndroidTests/res/values-mcc110-xx/configVarying.xml
index 0dec300..82e2435 100644
--- a/tests/AndroidTests/res/values-trackball/configVarying.xml
+++ b/tests/AndroidTests/res/values-mcc110-xx/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple trackball</item>
+ <item type="configVarying" name="simple">simple mcc110 xx</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag trackball</item>
+ <item name="testString">bag mcc110 xx</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-finger/configVarying.xml b/tests/AndroidTests/res/values-mcc112/configVarying.xml
similarity index 86%
copy from tests/AndroidTests/res/values-finger/configVarying.xml
copy to tests/AndroidTests/res/values-mcc112/configVarying.xml
index 674787e..9c05d77 100644
--- a/tests/AndroidTests/res/values-finger/configVarying.xml
+++ b/tests/AndroidTests/res/values-mcc112/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple finger</item>
+ <item type="configVarying" name="simple">simple mcc112</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag finger</item>
+ <item name="testString">bag mcc112</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-trackball/configVarying.xml b/tests/AndroidTests/res/values-mnc220-xx/configVarying.xml
similarity index 86%
rename from tests/AndroidTests/res/values-trackball/configVarying.xml
rename to tests/AndroidTests/res/values-mnc220-xx/configVarying.xml
index 0dec300..fbc7888 100644
--- a/tests/AndroidTests/res/values-trackball/configVarying.xml
+++ b/tests/AndroidTests/res/values-mnc220-xx/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple trackball</item>
+ <item type="configVarying" name="simple">simple mnc220 xx</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag trackball</item>
+ <item name="testString">bag mnc220 xx</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-finger/configVarying.xml b/tests/AndroidTests/res/values-mnc222-32dpi/configVarying.xml
similarity index 85%
copy from tests/AndroidTests/res/values-finger/configVarying.xml
copy to tests/AndroidTests/res/values-mnc222-32dpi/configVarying.xml
index 674787e..03bea33 100644
--- a/tests/AndroidTests/res/values-finger/configVarying.xml
+++ b/tests/AndroidTests/res/values-mnc222-32dpi/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple finger</item>
+ <item type="configVarying" name="simple">simple mnc222 32dpi</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag finger</item>
+ <item name="testString">bag mnc222 32dpi</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-finger/configVarying.xml b/tests/AndroidTests/res/values-mnc223/configVarying.xml
similarity index 86%
copy from tests/AndroidTests/res/values-finger/configVarying.xml
copy to tests/AndroidTests/res/values-mnc223/configVarying.xml
index 674787e..8936cbc 100644
--- a/tests/AndroidTests/res/values-finger/configVarying.xml
+++ b/tests/AndroidTests/res/values-mnc223/configVarying.xml
@@ -15,8 +15,8 @@
-->
<resources>
- <item type="configVarying" name="simple">simple finger</item>
+ <item type="configVarying" name="simple">simple mnc223</item>
<bag type="configVarying" name="bag">
- <item name="testString">bag finger</item>
+ <item name="testString">bag mnc223</item>
</bag>
</resources>
diff --git a/tests/AndroidTests/res/values-port/configVarying.xml b/tests/AndroidTests/res/values-port/configVarying.xml
deleted file mode 100644
index 0e1f247..0000000
--- a/tests/AndroidTests/res/values-port/configVarying.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <item type="configVarying" name="simple">simple portrait</item>
- <bag type="configVarying" name="bag">
- <item name="testString">bag portrait</item>
- </bag>
-</resources>
diff --git a/tests/AndroidTests/res/values-qwerty/configVarying.xml b/tests/AndroidTests/res/values-qwerty/configVarying.xml
deleted file mode 100644
index 939f682..0000000
--- a/tests/AndroidTests/res/values-qwerty/configVarying.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<resources>
- <item type="configVarying" name="simple">simple qwerty</item>
- <bag type="configVarying" name="bag">
- <item name="testString">bag qwerty</item>
- </bag>
-</resources>
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
index 09e3b02..f3c1542 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java
@@ -23,27 +23,11 @@
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
import android.os.ServiceManager;
-import android.server.search.SearchableInfo;
-import android.server.search.SearchableInfo.ActionKeyInfo;
-import android.test.ActivityInstrumentationTestCase;
-import android.test.MoreAsserts;
-import android.test.mock.MockContext;
-import android.test.mock.MockPackageManager;
+import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.AndroidRuntimeException;
-import android.view.KeyEvent;
-
-import java.util.ArrayList;
-import java.util.List;
/**
* To launch this test from the command line:
@@ -52,7 +36,7 @@
* -e class com.android.unit_tests.SearchManagerTest \
* com.android.unit_tests/android.test.InstrumentationTestRunner
*/
-public class SearchManagerTest extends ActivityInstrumentationTestCase<LocalActivity> {
+public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalActivity> {
// If non-zero, enable a set of tests that start and stop the search manager.
// This is currently disabled because it's causing an unwanted jump from the unit test
@@ -71,18 +55,6 @@
* testSearchManagerInvocations()
* FIX - make it work again
* stress test with a very long string
- *
- * SearchableInfo tests
- * Mock the context so I can provide very specific input data
- * Confirm OK with "zero" searchables
- * Confirm "good" metadata read properly
- * Confirm "bad" metadata skipped properly
- * Confirm ordering of searchables
- * Confirm "good" actionkeys
- * confirm "bad" actionkeys are rejected
- * confirm XML ordering enforced (will fail today - bug in SearchableInfo)
- * findActionKey works
- * getIcon works
*
* SearchManager tests
* confirm proper identification of "default" activity based on policy, not hardcoded contacts
@@ -195,348 +167,6 @@
searchManager.stopSearch();
}
}
-
- /**
- * The goal of this test is to confirm proper operation of the
- * SearchableInfo helper class.
- *
- * TODO: The metadata source needs to be mocked out because adding
- * searchability metadata via this test is causing it to leak into the
- * real system. So for now I'm just going to test for existence of the
- * GoogleSearch app (which is searchable).
- */
- @LargeTest
- public void testSearchableGoogleSearch() {
- // test basic array & hashmap
- SearchableInfo.buildSearchableList(mContext);
- // test linkage from another activity
- // TODO inject this via mocking into the package manager.
- // TODO for now, just check for searchable GoogleSearch app (this isn't really a unit test)
- ComponentName thisActivity = new ComponentName(
- "com.android.googlesearch",
- "com.android.googlesearch.GoogleSearch");
-
- SearchableInfo si = SearchableInfo.getSearchableInfo(mContext, thisActivity);
- assertNotNull(si);
- assertTrue(si.mSearchable);
- assertEquals(thisActivity, si.mSearchActivity);
-
- Context appContext = si.getActivityContext(mContext);
- assertNotNull(appContext);
- MoreAsserts.assertNotEqual(appContext, mContext);
- assertEquals("Google Search", appContext.getString(si.getHintId()));
- assertEquals("Google", appContext.getString(si.getLabelId()));
- }
-
- /**
- * Test that non-searchable activities return no searchable info (this would typically
- * trigger the use of the default searchable e.g. contacts)
- */
- @LargeTest
- public void testNonSearchable() {
- // test basic array & hashmap
- SearchableInfo.buildSearchableList(mContext);
-
- // confirm that we return null for non-searchy activities
- ComponentName nonActivity = new ComponentName(
- "com.android.unit_tests",
- "com.android.unit_tests.NO_SEARCH_ACTIVITY");
- SearchableInfo si = SearchableInfo.getSearchableInfo(mContext, nonActivity);
- assertNull(si);
- }
-
- /**
- * This is an attempt to run the searchable info list with a mocked context. Here are some
- * things I'd like to test.
- *
- * Confirm OK with "zero" searchables
- * Confirm "good" metadata read properly
- * Confirm "bad" metadata skipped properly
- * Confirm ordering of searchables
- * Confirm "good" actionkeys
- * confirm "bad" actionkeys are rejected
- * confirm XML ordering enforced (will fail today - bug in SearchableInfo)
- * findActionKey works
- * getIcon works
-
- */
- @LargeTest
- public void testSearchableMocked() {
- MyMockPackageManager mockPM = new MyMockPackageManager(mContext.getPackageManager());
- MyMockContext mockContext = new MyMockContext(mContext, mockPM);
- ArrayList<SearchableInfo> searchables;
- int count;
-
- // build item list with real-world source data
- mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_PASSTHROUGH);
- SearchableInfo.buildSearchableList(mockContext);
- // tests with "real" searchables (deprecate, this should be a unit test)
- searchables = SearchableInfo.getSearchablesList();
- count = searchables.size();
- assertTrue(count >= 1); // this isn't really a unit test
- checkSearchables(searchables);
-
- // build item list with mocked search data
- // this round of tests confirms good operations with "zero" searchables found
- // This should return either a null pointer or an empty list
- mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_MOCK_ZERO);
- SearchableInfo.buildSearchableList(mockContext);
- searchables = SearchableInfo.getSearchablesList();
- if (searchables != null) {
- count = searchables.size();
- assertTrue(count == 0);
- }
- }
-
- /**
- * Generic health checker for an array of searchables.
- *
- * This is designed to pass for any semi-legal searchable, without knowing much about
- * the format of the underlying data. It's fairly easy for a non-compliant application
- * to provide meta-data that will pass here (e.g. a non-existent suggestions authority).
- *
- * @param searchables The list of searchables to examine.
- */
- private void checkSearchables(ArrayList<SearchableInfo> searchablesList) {
- assertNotNull(searchablesList);
- int count = searchablesList.size();
- for (int ii = 0; ii < count; ii++) {
- SearchableInfo si = searchablesList.get(ii);
- assertNotNull(si);
- assertTrue(si.mSearchable);
- assertTrue(si.getLabelId() != 0); // This must be a useable string
- assertNotEmpty(si.mSearchActivity.getClassName());
- assertNotEmpty(si.mSearchActivity.getPackageName());
- if (si.getSuggestAuthority() != null) {
- // The suggestion fields are largely optional, so we'll just confirm basic health
- assertNotEmpty(si.getSuggestAuthority());
- assertNullOrNotEmpty(si.getSuggestPath());
- assertNullOrNotEmpty(si.getSuggestSelection());
- assertNullOrNotEmpty(si.getSuggestIntentAction());
- assertNullOrNotEmpty(si.getSuggestIntentData());
- }
- /* Add a way to get the entire action key list, then explicitly test its elements */
- /* For now, test the most common action key (CALL) */
- ActionKeyInfo ai = si.findActionKey(KeyEvent.KEYCODE_CALL);
- if (ai != null) {
- assertEquals(ai.mKeyCode, KeyEvent.KEYCODE_CALL);
- // one of these three fields must be non-null & non-empty
- boolean m1 = (ai.mQueryActionMsg != null) && (ai.mQueryActionMsg.length() > 0);
- boolean m2 = (ai.mSuggestActionMsg != null) && (ai.mSuggestActionMsg.length() > 0);
- boolean m3 = (ai.mSuggestActionMsgColumn != null) &&
- (ai.mSuggestActionMsgColumn.length() > 0);
- assertTrue(m1 || m2 || m3);
- }
-
- /*
- * Find ways to test these:
- *
- * private int mSearchMode
- * private Drawable mIcon
- */
-
- /*
- * Explicitly not tested here:
- *
- * Can be null, so not much to see:
- * public String mSearchHint
- * private String mZeroQueryBanner
- *
- * To be deprecated/removed, so don't bother:
- * public boolean mFilterMode
- * public boolean mQuickStart
- * private boolean mIconResized
- * private int mIconResizeWidth
- * private int mIconResizeHeight
- *
- * All of these are "internal" working variables, not part of any contract
- * private ActivityInfo mActivityInfo
- * private Rect mTempRect
- * private String mSuggestProviderPackage
- * private String mCacheActivityContext
- */
- }
- }
-
- /**
- * Combo assert for "string not null and not empty"
- */
- private void assertNotEmpty(final String s) {
- assertNotNull(s);
- MoreAsserts.assertNotEqual(s, "");
- }
-
- /**
- * Combo assert for "string null or (not null and not empty)"
- */
- private void assertNullOrNotEmpty(final String s) {
- if (s != null) {
- MoreAsserts.assertNotEqual(s, "");
- }
- }
-
- /**
- * This is a mock for context. Used to perform a true unit test on SearchableInfo.
- *
- */
- private class MyMockContext extends MockContext {
-
- protected Context mRealContext;
- protected PackageManager mPackageManager;
-
- /**
- * Constructor.
- *
- * @param realContext Please pass in a real context for some pass-throughs to function.
- */
- MyMockContext(Context realContext, PackageManager packageManager) {
- mRealContext = realContext;
- mPackageManager = packageManager;
- }
-
- /**
- * Resources. Pass through for now.
- */
- @Override
- public Resources getResources() {
- return mRealContext.getResources();
- }
-
- /**
- * Package manager. Pass through for now.
- */
- @Override
- public PackageManager getPackageManager() {
- return mPackageManager;
- }
-
- /**
- * Package manager. Pass through for now.
- */
- @Override
- public Context createPackageContext(String packageName, int flags)
- throws PackageManager.NameNotFoundException {
- return mRealContext.createPackageContext(packageName, flags);
- }
- }
-
-/**
- * This is a mock for package manager. Used to perform a true unit test on SearchableInfo.
- *
- */
- private class MyMockPackageManager extends MockPackageManager {
-
- public final static int SEARCHABLES_PASSTHROUGH = 0;
- public final static int SEARCHABLES_MOCK_ZERO = 1;
- public final static int SEARCHABLES_MOCK_ONEGOOD = 2;
- public final static int SEARCHABLES_MOCK_ONEGOOD_ONEBAD = 3;
-
- protected PackageManager mRealPackageManager;
- protected int mSearchablesMode;
-
- public MyMockPackageManager(PackageManager realPM) {
- mRealPackageManager = realPM;
- mSearchablesMode = SEARCHABLES_PASSTHROUGH;
- }
-
- /**
- * Set the mode for various tests.
- */
- public void setSearchablesMode(int newMode) {
- switch (newMode) {
- case SEARCHABLES_PASSTHROUGH:
- case SEARCHABLES_MOCK_ZERO:
- mSearchablesMode = newMode;
- break;
-
- default:
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Find activities that support a given intent.
- *
- * Retrieve all activities that can be performed for the given intent.
- *
- * @param intent The desired intent as per resolveActivity().
- * @param flags Additional option flags. The most important is
- * MATCH_DEFAULT_ONLY, to limit the resolution to only
- * those activities that support the CATEGORY_DEFAULT.
- *
- * @return A List<ResolveInfo> containing one entry for each matching
- * Activity. These are ordered from best to worst match -- that
- * is, the first item in the list is what is returned by
- * resolveActivity(). If there are no matching activities, an empty
- * list is returned.
- */
- @Override
- public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
- assertNotNull(intent);
- assertEquals(intent.getAction(), Intent.ACTION_SEARCH);
- switch (mSearchablesMode) {
- case SEARCHABLES_PASSTHROUGH:
- return mRealPackageManager.queryIntentActivities(intent, flags);
- case SEARCHABLES_MOCK_ZERO:
- return null;
- default:
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Retrieve an XML file from a package. This is a low-level API used to
- * retrieve XML meta data.
- *
- * @param packageName The name of the package that this xml is coming from.
- * Can not be null.
- * @param resid The resource identifier of the desired xml. Can not be 0.
- * @param appInfo Overall information about <var>packageName</var>. This
- * may be null, in which case the application information will be retrieved
- * for you if needed; if you already have this information around, it can
- * be much more efficient to supply it here.
- *
- * @return Returns an XmlPullParser allowing you to parse out the XML
- * data. Returns null if the xml resource could not be found for any
- * reason.
- */
- @Override
- public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
- assertNotNull(packageName);
- MoreAsserts.assertNotEqual(packageName, "");
- MoreAsserts.assertNotEqual(resid, 0);
- switch (mSearchablesMode) {
- case SEARCHABLES_PASSTHROUGH:
- return mRealPackageManager.getXml(packageName, resid, appInfo);
- case SEARCHABLES_MOCK_ZERO:
- default:
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Find a single content provider by its base path name.
- *
- * @param name The name of the provider to find.
- * @param flags Additional option flags. Currently should always be 0.
- *
- * @return ContentProviderInfo Information about the provider, if found,
- * else null.
- */
- @Override
- public ProviderInfo resolveContentProvider(String name, int flags) {
- assertNotNull(name);
- MoreAsserts.assertNotEqual(name, "");
- assertEquals(flags, 0);
- switch (mSearchablesMode) {
- case SEARCHABLES_PASSTHROUGH:
- return mRealPackageManager.resolveContentProvider(name, flags);
- case SEARCHABLES_MOCK_ZERO:
- default:
- throw new UnsupportedOperationException();
- }
- }
- }
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
new file mode 100644
index 0000000..c299b10
--- /dev/null
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
@@ -0,0 +1,411 @@
+/*
+ * 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.unit_tests;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.server.search.SearchableInfo;
+import android.server.search.Searchables;
+import android.server.search.SearchableInfo.ActionKeyInfo;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.test.mock.MockContext;
+import android.test.mock.MockPackageManager;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.KeyEvent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * To launch this test from the command line:
+ *
+ * adb shell am instrument -w \
+ * -e class com.android.unit_tests.SearchablesTest \
+ * com.android.unit_tests/android.test.InstrumentationTestRunner
+ */
+@SmallTest
+public class SearchablesTest extends AndroidTestCase {
+
+ /*
+ * SearchableInfo tests
+ * Mock the context so I can provide very specific input data
+ * Confirm OK with "zero" searchables
+ * Confirm "good" metadata read properly
+ * Confirm "bad" metadata skipped properly
+ * Confirm ordering of searchables
+ * Confirm "good" actionkeys
+ * confirm "bad" actionkeys are rejected
+ * confirm XML ordering enforced (will fail today - bug in SearchableInfo)
+ * findActionKey works
+ * getIcon works
+ */
+
+ /**
+ * The goal of this test is to confirm proper operation of the
+ * SearchableInfo helper class.
+ *
+ * TODO: The metadata source needs to be mocked out because adding
+ * searchability metadata via this test is causing it to leak into the
+ * real system. So for now I'm just going to test for existence of the
+ * GoogleSearch app (which is searchable).
+ */
+ public void testSearchableGoogleSearch() {
+ // test basic array & hashmap
+ Searchables searchables = new Searchables(mContext);
+ searchables.buildSearchableList();
+
+ // test linkage from another activity
+ // TODO inject this via mocking into the package manager.
+ // TODO for now, just check for searchable GoogleSearch app (this isn't really a unit test)
+ ComponentName thisActivity = new ComponentName(
+ "com.android.googlesearch",
+ "com.android.googlesearch.GoogleSearch");
+
+ SearchableInfo si = searchables.getSearchableInfo(thisActivity);
+ assertNotNull(si);
+ assertTrue(si.mSearchable);
+ assertEquals(thisActivity, si.mSearchActivity);
+
+ Context appContext = si.getActivityContext(mContext);
+ assertNotNull(appContext);
+ MoreAsserts.assertNotEqual(appContext, mContext);
+ assertEquals("Google Search", appContext.getString(si.getHintId()));
+ assertEquals("Google", appContext.getString(si.getLabelId()));
+ }
+
+ /**
+ * Test that non-searchable activities return no searchable info (this would typically
+ * trigger the use of the default searchable e.g. contacts)
+ */
+ public void testNonSearchable() {
+ // test basic array & hashmap
+ Searchables searchables = new Searchables(mContext);
+ searchables.buildSearchableList();
+
+ // confirm that we return null for non-searchy activities
+ ComponentName nonActivity = new ComponentName(
+ "com.android.unit_tests",
+ "com.android.unit_tests.NO_SEARCH_ACTIVITY");
+ SearchableInfo si = searchables.getSearchableInfo(nonActivity);
+ assertNull(si);
+ }
+
+ /**
+ * This is an attempt to run the searchable info list with a mocked context. Here are some
+ * things I'd like to test.
+ *
+ * Confirm OK with "zero" searchables
+ * Confirm "good" metadata read properly
+ * Confirm "bad" metadata skipped properly
+ * Confirm ordering of searchables
+ * Confirm "good" actionkeys
+ * confirm "bad" actionkeys are rejected
+ * confirm XML ordering enforced (will fail today - bug in SearchableInfo)
+ * findActionKey works
+ * getIcon works
+
+ */
+ public void testSearchableMocked() {
+ MyMockPackageManager mockPM = new MyMockPackageManager(mContext.getPackageManager());
+ MyMockContext mockContext = new MyMockContext(mContext, mockPM);
+ Searchables searchables;
+ ArrayList<SearchableInfo> searchablesList;
+ int count;
+
+
+ // build item list with real-world source data
+ mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_PASSTHROUGH);
+ searchables = new Searchables(mockContext);
+ searchables.buildSearchableList();
+ // tests with "real" searchables (deprecate, this should be a unit test)
+ searchablesList = searchables.getSearchablesList();
+ count = searchablesList.size();
+ assertTrue(count >= 1); // this isn't really a unit test
+ checkSearchables(searchablesList);
+
+ // build item list with mocked search data
+ // this round of tests confirms good operations with "zero" searchables found
+ // This should return either a null pointer or an empty list
+ mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_MOCK_ZERO);
+ searchables = new Searchables(mockContext);
+ searchables.buildSearchableList();
+ searchablesList = searchables.getSearchablesList();
+ if (searchablesList != null) {
+ count = searchablesList.size();
+ assertTrue(count == 0);
+ }
+ }
+
+ /**
+ * Generic health checker for an array of searchables.
+ *
+ * This is designed to pass for any semi-legal searchable, without knowing much about
+ * the format of the underlying data. It's fairly easy for a non-compliant application
+ * to provide meta-data that will pass here (e.g. a non-existent suggestions authority).
+ *
+ * @param searchables The list of searchables to examine.
+ */
+ private void checkSearchables(ArrayList<SearchableInfo> searchablesList) {
+ assertNotNull(searchablesList);
+ int count = searchablesList.size();
+ for (int ii = 0; ii < count; ii++) {
+ SearchableInfo si = searchablesList.get(ii);
+ assertNotNull(si);
+ assertTrue(si.mSearchable);
+ assertTrue(si.getLabelId() != 0); // This must be a useable string
+ assertNotEmpty(si.mSearchActivity.getClassName());
+ assertNotEmpty(si.mSearchActivity.getPackageName());
+ if (si.getSuggestAuthority() != null) {
+ // The suggestion fields are largely optional, so we'll just confirm basic health
+ assertNotEmpty(si.getSuggestAuthority());
+ assertNullOrNotEmpty(si.getSuggestPath());
+ assertNullOrNotEmpty(si.getSuggestSelection());
+ assertNullOrNotEmpty(si.getSuggestIntentAction());
+ assertNullOrNotEmpty(si.getSuggestIntentData());
+ }
+ /* Add a way to get the entire action key list, then explicitly test its elements */
+ /* For now, test the most common action key (CALL) */
+ ActionKeyInfo ai = si.findActionKey(KeyEvent.KEYCODE_CALL);
+ if (ai != null) {
+ assertEquals(ai.mKeyCode, KeyEvent.KEYCODE_CALL);
+ // one of these three fields must be non-null & non-empty
+ boolean m1 = (ai.mQueryActionMsg != null) && (ai.mQueryActionMsg.length() > 0);
+ boolean m2 = (ai.mSuggestActionMsg != null) && (ai.mSuggestActionMsg.length() > 0);
+ boolean m3 = (ai.mSuggestActionMsgColumn != null) &&
+ (ai.mSuggestActionMsgColumn.length() > 0);
+ assertTrue(m1 || m2 || m3);
+ }
+
+ /*
+ * Find ways to test these:
+ *
+ * private int mSearchMode
+ * private Drawable mIcon
+ */
+
+ /*
+ * Explicitly not tested here:
+ *
+ * Can be null, so not much to see:
+ * public String mSearchHint
+ * private String mZeroQueryBanner
+ *
+ * To be deprecated/removed, so don't bother:
+ * public boolean mFilterMode
+ * public boolean mQuickStart
+ * private boolean mIconResized
+ * private int mIconResizeWidth
+ * private int mIconResizeHeight
+ *
+ * All of these are "internal" working variables, not part of any contract
+ * private ActivityInfo mActivityInfo
+ * private Rect mTempRect
+ * private String mSuggestProviderPackage
+ * private String mCacheActivityContext
+ */
+ }
+ }
+
+ /**
+ * Combo assert for "string not null and not empty"
+ */
+ private void assertNotEmpty(final String s) {
+ assertNotNull(s);
+ MoreAsserts.assertNotEqual(s, "");
+ }
+
+ /**
+ * Combo assert for "string null or (not null and not empty)"
+ */
+ private void assertNullOrNotEmpty(final String s) {
+ if (s != null) {
+ MoreAsserts.assertNotEqual(s, "");
+ }
+ }
+
+ /**
+ * This is a mock for context. Used to perform a true unit test on SearchableInfo.
+ *
+ */
+ private class MyMockContext extends MockContext {
+
+ protected Context mRealContext;
+ protected PackageManager mPackageManager;
+
+ /**
+ * Constructor.
+ *
+ * @param realContext Please pass in a real context for some pass-throughs to function.
+ */
+ MyMockContext(Context realContext, PackageManager packageManager) {
+ mRealContext = realContext;
+ mPackageManager = packageManager;
+ }
+
+ /**
+ * Resources. Pass through for now.
+ */
+ @Override
+ public Resources getResources() {
+ return mRealContext.getResources();
+ }
+
+ /**
+ * Package manager. Pass through for now.
+ */
+ @Override
+ public PackageManager getPackageManager() {
+ return mPackageManager;
+ }
+
+ /**
+ * Package manager. Pass through for now.
+ */
+ @Override
+ public Context createPackageContext(String packageName, int flags)
+ throws PackageManager.NameNotFoundException {
+ return mRealContext.createPackageContext(packageName, flags);
+ }
+ }
+
+/**
+ * This is a mock for package manager. Used to perform a true unit test on SearchableInfo.
+ *
+ */
+ private class MyMockPackageManager extends MockPackageManager {
+
+ public final static int SEARCHABLES_PASSTHROUGH = 0;
+ public final static int SEARCHABLES_MOCK_ZERO = 1;
+ public final static int SEARCHABLES_MOCK_ONEGOOD = 2;
+ public final static int SEARCHABLES_MOCK_ONEGOOD_ONEBAD = 3;
+
+ protected PackageManager mRealPackageManager;
+ protected int mSearchablesMode;
+
+ public MyMockPackageManager(PackageManager realPM) {
+ mRealPackageManager = realPM;
+ mSearchablesMode = SEARCHABLES_PASSTHROUGH;
+ }
+
+ /**
+ * Set the mode for various tests.
+ */
+ public void setSearchablesMode(int newMode) {
+ switch (newMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ case SEARCHABLES_MOCK_ZERO:
+ mSearchablesMode = newMode;
+ break;
+
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Find activities that support a given intent.
+ *
+ * Retrieve all activities that can be performed for the given intent.
+ *
+ * @param intent The desired intent as per resolveActivity().
+ * @param flags Additional option flags. The most important is
+ * MATCH_DEFAULT_ONLY, to limit the resolution to only
+ * those activities that support the CATEGORY_DEFAULT.
+ *
+ * @return A List<ResolveInfo> containing one entry for each matching
+ * Activity. These are ordered from best to worst match -- that
+ * is, the first item in the list is what is returned by
+ * resolveActivity(). If there are no matching activities, an empty
+ * list is returned.
+ */
+ @Override
+ public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
+ assertNotNull(intent);
+ assertEquals(intent.getAction(), Intent.ACTION_SEARCH);
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.queryIntentActivities(intent, flags);
+ case SEARCHABLES_MOCK_ZERO:
+ return null;
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Retrieve an XML file from a package. This is a low-level API used to
+ * retrieve XML meta data.
+ *
+ * @param packageName The name of the package that this xml is coming from.
+ * Can not be null.
+ * @param resid The resource identifier of the desired xml. Can not be 0.
+ * @param appInfo Overall information about <var>packageName</var>. This
+ * may be null, in which case the application information will be retrieved
+ * for you if needed; if you already have this information around, it can
+ * be much more efficient to supply it here.
+ *
+ * @return Returns an XmlPullParser allowing you to parse out the XML
+ * data. Returns null if the xml resource could not be found for any
+ * reason.
+ */
+ @Override
+ public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
+ assertNotNull(packageName);
+ MoreAsserts.assertNotEqual(packageName, "");
+ MoreAsserts.assertNotEqual(resid, 0);
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.getXml(packageName, resid, appInfo);
+ case SEARCHABLES_MOCK_ZERO:
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Find a single content provider by its base path name.
+ *
+ * @param name The name of the provider to find.
+ * @param flags Additional option flags. Currently should always be 0.
+ *
+ * @return ContentProviderInfo Information about the provider, if found,
+ * else null.
+ */
+ @Override
+ public ProviderInfo resolveContentProvider(String name, int flags) {
+ assertNotNull(name);
+ MoreAsserts.assertNotEqual(name, "");
+ assertEquals(flags, 0);
+ switch (mSearchablesMode) {
+ case SEARCHABLES_PASSTHROUGH:
+ return mRealPackageManager.resolveContentProvider(name, flags);
+ case SEARCHABLES_MOCK_ZERO:
+ default:
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+}
+
diff --git a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java b/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
index 1ea83c3..e6639d3 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/content/ConfigTest.java
@@ -98,7 +98,7 @@
mMetrics = new DisplayMetrics();
mMetrics.widthPixels = 200;
mMetrics.heightPixels = 320;
- mMetrics.density = 120;
+ mMetrics.density = 1;
}
void setProperty(properties p, int value) {
@@ -131,7 +131,9 @@
mMetrics.heightPixels = value;
break;
case DENSITY:
- mMetrics.density = value;
+ // this is the ratio from the standard
+
+ mMetrics.density = (((float)value)/((float)DisplayMetrics.DEFAULT_DENSITY));
break;
default:
assert(false);
@@ -187,18 +189,16 @@
*/
TotalConfig config = new TotalConfig();
Resources res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple default");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag default"});
+ checkValue(res, R.configVarying.simple, "simple default");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag default"});
config = new TotalConfig();
config.setProperty(properties.LANGUAGE, "xx");
res = config.getResources();
-// got simple xx 32dpi
-// checkValue(res, R.configVarying.simple, "simple xx");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag xx"});
+ checkValue(res, R.configVarying.simple, "simple xx");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag xx"});
config = new TotalConfig();
config.setProperty(properties.LANGUAGE, "xx");
@@ -225,116 +225,66 @@
config = new TotalConfig();
config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_NOTOUCH);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple notouch");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag notouch"});
-
- config = new TotalConfig();
- config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_FINGER);
- res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple finger");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag finger"});
+ checkValue(res, R.configVarying.simple, "simple notouch");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag notouch"});
config = new TotalConfig();
config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_STYLUS);
res = config.getResources();
-// got simple 32dpi stylus
-// checkValue(res, R.configVarying.simple, "simple stylus");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag stylus"});
+ checkValue(res, R.configVarying.simple, "simple stylus");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag stylus"});
config = new TotalConfig();
config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_NOKEYS);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple nokeys");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag nokeys"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_QWERTY);
- res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple qwerty");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag qwerty"});
+ checkValue(res, R.configVarying.simple, "simple nokeys");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag nokeys"});
config = new TotalConfig();
config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple 12key");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag 12key"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_YES);
- res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple keyshidden");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag keyshidden"});
+ checkValue(res, R.configVarying.simple, "simple 12key");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 12key"});
config = new TotalConfig();
config.setProperty(properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
res = config.getResources();
-// got simple 32dpi keysexposed
-// checkValue(res, R.configVarying.simple, "simple keysexposed");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag keysexposed"});
+ checkValue(res, R.configVarying.simple, "simple keysexposed");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag keysexposed"});
config = new TotalConfig();
config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_NONAV);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple nonav");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag nonav"});
+ checkValue(res, R.configVarying.simple, "simple nonav");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag nonav"});
config = new TotalConfig();
config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_DPAD);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple dpad");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag dpad"});
-
- config = new TotalConfig();
- config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_TRACKBALL);
- res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple trackball");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag trackball"});
+ checkValue(res, R.configVarying.simple, "simple dpad");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag dpad"});
config = new TotalConfig();
config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_WHEEL);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple wheel");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag wheel"});
-
- config = new TotalConfig();
- config.setProperty(properties.HEIGHT, 320);
- config.setProperty(properties.WIDTH, 200);
- res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple 320x200");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag 320x200"});
+ checkValue(res, R.configVarying.simple, "simple wheel");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag wheel"});
config = new TotalConfig();
config.setProperty(properties.HEIGHT, 480);
config.setProperty(properties.WIDTH, 320);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple 480x320");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag 480x320"});
+ checkValue(res, R.configVarying.simple, "simple 480x320");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 480x320"});
config = new TotalConfig();
config.setProperty(properties.DENSITY, 240);
@@ -344,36 +294,91 @@
R.styleable.TestConfig, new String[]{"bag 240dpi"});
config = new TotalConfig();
- config.setProperty(properties.DENSITY, 120);
- res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple 120dpi");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag 120dpi"});
-
- config = new TotalConfig();
config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple landscape");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag landscape"});
-
- config = new TotalConfig();
- config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_PORTRAIT);
- res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple portrait");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag portrait"});
+ checkValue(res, R.configVarying.simple, "simple landscape");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag landscape"});
config = new TotalConfig();
config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_SQUARE);
res = config.getResources();
-// got simple square 32dpi
-// checkValue(res, R.configVarying.simple, "simple square");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag square"});
+ checkValue(res, R.configVarying.simple, "simple square");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag square"});
+ }
+
+ @MediumTest
+ public void testDensity() throws Exception {
+ // have 32, 240 and the default 160 content.
+ // rule is that closest wins, with down scaling (larger content)
+ // being twice as nice as upscaling.
+ // transition at H/2 * (-1 +/- sqrt(1+8L/H))
+ // SO, X < 49 goes to 32
+ // 49 >= X < 182 goes to 160
+ // X >= 182 goes to 240
+ TotalConfig config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 2);
+ Resources res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple 32dpi");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 32dpi"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 32);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple 32dpi");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 32dpi"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 48);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple 32dpi");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 32dpi"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 49);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple default");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag default"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 150);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple default");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag default"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 181);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple default");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag default"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 182);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple 240dpi");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 240dpi"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 239);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple 240dpi");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 240dpi"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 490);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple 240dpi");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 240dpi"});
}
// TODO - add tests for special cases - ie, other key params seem ignored if
@@ -407,10 +412,9 @@
config = new TotalConfig();
config.setProperty(properties.MNC, 333);
res = config.getResources();
-// got simple 24dpi
-// checkValue(res, R.configVarying.simple, "simple default");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag default"});
+ checkValue(res, R.configVarying.simple, "simple default");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag default"});
}
@MediumTest
@@ -419,13 +423,31 @@
* Verify that in cases of ties, the specific ordering is followed
*/
- /* full A + B + C doesn't exist. Do we get A + C or B + C?
+ /**
+ * Precidence order: mcc, mnc, locale, orientation, density,
+ * touchscreen, hidden, keyboard, navigation, width-height
+ */
+
+ /**
+ * verify mcc trumps mnc. Have 110-xx, 220-xx but no 110-220
+ * so with is selected? Should be mcc110-xx.
*/
TotalConfig config = new TotalConfig();
+ config.setProperty(properties.MCC, 110);
+ config.setProperty(properties.MNC, 220);
+ config.setProperty(properties.LANGUAGE, "xx");
+ Resources res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple mcc110 xx");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag mcc110 xx"});
+
+ /* full A + B + C doesn't exist. Do we get A + C or B + C?
+ */
+ config = new TotalConfig();
config.setProperty(properties.MCC, 111);
config.setProperty(properties.MNC, 222);
config.setProperty(properties.LANGUAGE, "xx");
- Resources res = config.getResources();
+ res = config.getResources();
checkValue(res, R.configVarying.simple, "simple mcc111 mnc222");
checkValue(res, R.configVarying.bag,
R.styleable.TestConfig, new String[]{"bag mcc111 mnc222"});
@@ -433,7 +455,8 @@
config = new TotalConfig();
config.setProperty(properties.MNC, 222);
config.setProperty(properties.LANGUAGE, "xx");
- config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_SQUARE);
+ config.setProperty(properties.ORIENTATION,
+ Configuration.ORIENTATION_SQUARE);
res = config.getResources();
checkValue(res, R.configVarying.simple, "simple mnc222 xx");
checkValue(res, R.configVarying.bag,
@@ -441,60 +464,77 @@
config = new TotalConfig();
config.setProperty(properties.LANGUAGE, "xx");
- config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_SQUARE);
+ config.setProperty(properties.ORIENTATION,
+ Configuration.ORIENTATION_SQUARE);
config.setProperty(properties.DENSITY, 32);
res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple xx 32dpi");
+ checkValue(res, R.configVarying.simple, "simple xx square");
checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag xx 32dpi"});
+ R.styleable.TestConfig, new String[]{"bag xx square"});
config = new TotalConfig();
- config.setProperty(properties.ORIENTATION, Configuration.ORIENTATION_SQUARE);
+ config.setProperty(properties.ORIENTATION,
+ Configuration.ORIENTATION_SQUARE);
config.setProperty(properties.DENSITY, 32);
- config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_STYLUS);
+ config.setProperty(properties.TOUCHSCREEN,
+ Configuration.TOUCHSCREEN_STYLUS);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple square 32dpi");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag square 32dpi"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.DENSITY, 32);
+ config.setProperty(properties.TOUCHSCREEN,
+ Configuration.TOUCHSCREEN_STYLUS);
+ config.setProperty(properties.KEYBOARDHIDDEN,
+ Configuration.KEYBOARDHIDDEN_NO);
res = config.getResources();
checkValue(res, R.configVarying.simple, "simple 32dpi stylus");
checkValue(res, R.configVarying.bag,
R.styleable.TestConfig, new String[]{"bag 32dpi stylus"});
config = new TotalConfig();
- config.setProperty(properties.DENSITY, 32);
- config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_STYLUS);
- config.setProperty(properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
+ config.setProperty(properties.TOUCHSCREEN,
+ Configuration.TOUCHSCREEN_STYLUS);
+ config.setProperty(properties.KEYBOARDHIDDEN,
+ Configuration.KEYBOARDHIDDEN_NO);
+ config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
res = config.getResources();
- checkValue(res, R.configVarying.simple, "simple 32dpi stylus");
+ checkValue(res, R.configVarying.simple, "simple stylus keysexposed");
checkValue(res, R.configVarying.bag,
- R.styleable.TestConfig, new String[]{"bag 32dpi stylus"});
+ R.styleable.TestConfig, new String[]{"bag stylus keysexposed"});
config = new TotalConfig();
- config.setProperty(properties.TOUCHSCREEN, Configuration.TOUCHSCREEN_STYLUS);
- config.setProperty(properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
+ config.setProperty(properties.KEYBOARDHIDDEN,
+ Configuration.KEYBOARDHIDDEN_NO);
config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
+ config.setProperty(properties.NAVIGATION,
+ Configuration.NAVIGATION_DPAD);
res = config.getResources();
-// got simple 32dpi stylus
-// checkValue(res, R.configVarying.simple, "simple stylus 12key");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag stylus 12key"});
-
- config = new TotalConfig();
- config.setProperty(properties.KEYBOARDHIDDEN, Configuration.KEYBOARDHIDDEN_NO);
- config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
- config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_DPAD);
- res = config.getResources();
-// got simple 32dpi exposed
-// checkValue(res, R.configVarying.simple, "simple stylus keysexposed");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag stylus keysexposed"});
+ checkValue(res, R.configVarying.simple, "simple keysexposed 12key");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag keysexposed 12key"});
config = new TotalConfig();
config.setProperty(properties.KEYBOARD, Configuration.KEYBOARD_12KEY);
- config.setProperty(properties.NAVIGATION, Configuration.NAVIGATION_DPAD);
+ config.setProperty(properties.NAVIGATION,
+ Configuration.NAVIGATION_DPAD);
config.setProperty(properties.HEIGHT, 63);
config.setProperty(properties.WIDTH, 57);
res = config.getResources();
-// got simple 240dpi
-// checkValue(res, R.configVarying.simple, "simple 12key dpad");
-// checkValue(res, R.configVarying.bag,
-// R.styleable.TestConfig, new String[]{"bag 12key dpad"});
+ checkValue(res, R.configVarying.simple, "simple 12key dpad");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag 12key dpad"});
+
+ config = new TotalConfig();
+ config.setProperty(properties.NAVIGATION,
+ Configuration.NAVIGATION_DPAD);
+ config.setProperty(properties.HEIGHT, 640);
+ config.setProperty(properties.WIDTH, 400);
+ res = config.getResources();
+ checkValue(res, R.configVarying.simple, "simple dpad");
+ checkValue(res, R.configVarying.bag,
+ R.styleable.TestConfig, new String[]{"bag dpad"});
}
}
diff --git a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
index 663b7a4..6f89fce 100644
--- a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
+++ b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
@@ -147,4 +147,56 @@
// now try moving "down" - nothing should happen since there's no longer an adapter
sendKeys("DPAD_DOWN");
}
+
+ /** Test the show/hide behavior of the drop-down. */
+ @MediumTest
+ public void testPopupShow() throws Throwable {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ final AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // Drop-down should not be showing when no text has been entered
+ assertFalse("isPopupShowing() on start", textView.isPopupShowing());
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // Drop-down should now be visible
+ assertTrue("isPopupShowing() after typing", textView.isPopupShowing());
+
+ // Clear the text
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ textView.setText("");
+ }
+ });
+ instrumentation.waitForIdleSync();
+
+ // Drop-down should be hidden when text is cleared
+ assertFalse("isPopupShowing() after text cleared", textView.isPopupShowing());
+
+ // Set the text, without filtering
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ textView.setText("a", false);
+ }
+ });
+ instrumentation.waitForIdleSync();
+
+ // Drop-down should still be hidden
+ assertFalse("isPopupShowing() after setText(\"a\", false)", textView.isPopupShowing());
+
+ // Set the text, now with filtering
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ textView.setText("a");
+ }
+ });
+ instrumentation.waitForIdleSync();
+
+ // Drop-down should show up after setText() with filtering
+ assertTrue("isPopupShowing() after text set", textView.isPopupShowing());
+ }
}