(r));
return r;
@@ -3624,7 +3634,7 @@ public final class ActivityThread {
Locale.setDefault(config.locale);
}
- Resources.updateSystemConfiguration(config, null);
+ Resources.updateSystemConfiguration(config, dm);
ApplicationContext.ApplicationPackageManager.configurationChanged();
//Log.i(TAG, "Configuration changed in " + currentPackageName());
@@ -3743,6 +3753,14 @@ public final class ActivityThread {
data.info = getPackageInfoNoCheck(data.appInfo);
+ /**
+ * Switch this process to density compatibility mode if needed.
+ */
+ if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
+ == 0) {
+ Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
+ }
+
if (data.debugMode != IApplicationThread.DEBUG_OFF) {
// XXX should have option to change the port.
Debug.changeDebugPort(8100);
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index afb2fe99c2e06..92929ea56748e 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -541,7 +541,10 @@ class ApplicationContext extends Context {
if (fd != null) {
Bitmap bm = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());
if (bm != null) {
- return new BitmapDrawable(bm);
+ // For now clear the density until we figure out how
+ // to deal with it for wallpapers.
+ bm.setDensity(0);
+ return new BitmapDrawable(getResources(), bm);
}
}
} catch (RemoteException e) {
@@ -1949,6 +1952,15 @@ class ApplicationContext extends Context {
try {
Resources r = getResourcesForApplication(appInfo);
dr = r.getDrawable(resid);
+ if (false) {
+ RuntimeException e = new RuntimeException("here");
+ e.fillInStackTrace();
+ Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
+ + " from package " + packageName
+ + ": app scale=" + r.getCompatibilityInfo().applicationScale
+ + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
+ e);
+ }
if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
+ Integer.toHexString(resid) + " from " + r
+ ": " + dr);
@@ -2036,10 +2048,9 @@ class ApplicationContext extends Context {
if (app.packageName.equals("system")) {
return mContext.mMainThread.getSystemContext().getResources();
}
- ActivityThread.PackageInfo pi = mContext.mMainThread.getPackageInfoNoCheck(app);
Resources r = mContext.mMainThread.getTopLevelResources(
app.uid == Process.myUid() ? app.sourceDir
- : app.publicSourceDir, pi);
+ : app.publicSourceDir, mContext.mPackageInfo);
if (r != null) {
return r;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 95b376cce673d..f6ef549d84277 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -266,7 +266,11 @@ public interface IActivityManager extends IInterface {
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, boolean onlyIfNeeded)
throws RemoteException;
-
+
+ public void killApplicationWithUid(String pkg, int uid) throws RemoteException;
+
+ public void closeSystemDialogs(String reason) throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -421,4 +425,6 @@ public interface IActivityManager extends IInterface {
int REGISTER_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
int UNREGISTER_ACTIVITY_WATCHER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
+ int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
+ int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
}
diff --git a/core/java/android/app/IActivityWatcher.aidl b/core/java/android/app/IActivityWatcher.aidl
index 5d36e3fdb5993..6737545de88f4 100644
--- a/core/java/android/app/IActivityWatcher.aidl
+++ b/core/java/android/app/IActivityWatcher.aidl
@@ -23,4 +23,5 @@ package android.app;
*/
oneway interface IActivityWatcher {
void activityResuming(int activityId);
+ void closingSystemDialogs(String reason);
}
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
index accdda9ba599b..d788c43d7d632 100644
--- a/core/java/android/app/LauncherActivity.java
+++ b/core/java/android/app/LauncherActivity.java
@@ -297,7 +297,7 @@ public abstract class LauncherActivity extends ListActivity {
icon.setBounds(x, y, x + width, y + height);
icon.draw(canvas);
icon.setBounds(mOldBounds);
- icon = new BitmapDrawable(thumb);
+ icon = new BitmapDrawable(getResources(), thumb);
} else if (iconWidth < width && iconHeight < height) {
final Bitmap.Config c = Bitmap.Config.ARGB_8888;
final Bitmap thumb = Bitmap.createBitmap(mIconWidth, mIconHeight, c);
@@ -309,7 +309,7 @@ public abstract class LauncherActivity extends ListActivity {
icon.setBounds(x, y, x + iconWidth, y + iconHeight);
icon.draw(canvas);
icon.setBounds(mOldBounds);
- icon = new BitmapDrawable(thumb);
+ icon = new BitmapDrawable(getResources(), thumb);
}
}
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index f9c38f998c35a..f7479bcdb8bf0 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -273,11 +273,6 @@ public final class PendingIntent implements Parcelable {
return null;
}
- private class IntentSenderWrapper extends IntentSender {
- protected IntentSenderWrapper(IIntentSender target) {
- super(target);
- }
- }
/**
* Retrieve a IntentSender object that wraps the existing sender of the PendingIntent
*
@@ -285,7 +280,7 @@ public final class PendingIntent implements Parcelable {
*
*/
public IntentSender getIntentSender() {
- return new IntentSenderWrapper(mTarget);
+ return new IntentSender(mTarget);
}
/**
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 27c637652d5ef..18e4a528ec46b 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -34,7 +34,10 @@ import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
import android.os.SystemClock;
+import android.provider.Browser;
import android.server.search.SearchableInfo;
import android.speech.RecognizerIntent;
import android.text.Editable;
@@ -42,11 +45,13 @@ import android.text.InputType;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.util.Regex;
+import android.util.AndroidRuntimeException;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -240,7 +245,12 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
return success;
}
-
+
+ private boolean isInRealAppSearch() {
+ return !mGlobalSearchMode
+ && (mPreviousComponents == null || mPreviousComponents.isEmpty());
+ }
+
/**
* Called in response to a press of the hard search button in
* {@link #onKeyDown(int, KeyEvent)}, this method toggles between in-app
@@ -260,6 +270,16 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
if (!mGlobalSearchMode) {
mStoredComponentName = mLaunchComponent;
mStoredAppSearchData = mAppSearchData;
+
+ // If this is the browser, we have a special case to not show the icon to the left
+ // of the text field, for extra space for url entry (this should be reconciled in
+ // Eclair). So special case a second tap of the search button to remove any
+ // already-entered text so that we can be sure to show the "Quick Search Box" hint
+ // text to still make it clear to the user that we've jumped out to global search.
+ //
+ // TODO: When the browser icon issue is reconciled in Eclair, remove this special case.
+ if (isBrowserSearch()) currentSearchText = "";
+
return doShow(currentSearchText, false, null, mAppSearchData, true);
} else {
if (mStoredComponentName != null) {
@@ -531,12 +551,14 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// we dismiss the entire dialog instead
mSearchAutoComplete.setDropDownDismissedOnCompletion(false);
- if (mGlobalSearchMode) {
+ if (!isInRealAppSearch()) {
mSearchAutoComplete.setDropDownAlwaysVisible(true); // fill space until results come in
} else {
mSearchAutoComplete.setDropDownAlwaysVisible(false);
}
+ mSearchAutoComplete.setForceIgnoreOutsideTouch(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) {
@@ -565,7 +587,11 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
private void updateSearchAppIcon() {
- if (mGlobalSearchMode) {
+ // In Donut, we special-case the case of the browser to hide the app icon as if it were
+ // global search, for extra space for url entry.
+ //
+ // TODO: Remove this special case once the issue has been reconciled in Eclair.
+ if (mGlobalSearchMode || isBrowserSearch()) {
mAppIcon.setImageResource(0);
mAppIcon.setVisibility(View.GONE);
mSearchPlate.setPadding(SEARCH_PLATE_LEFT_PADDING_GLOBAL,
@@ -657,6 +683,49 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
mVoiceButton.setVisibility(visibility);
}
+ /**
+ * Hack to determine whether this is the browser, so we can remove the browser icon
+ * to the left of the search field, as a special requirement for Donut.
+ *
+ * TODO: For Eclair, reconcile this with the rest of the global search UI.
+ */
+ private boolean isBrowserSearch() {
+ return mLaunchComponent.flattenToShortString().startsWith("com.android.browser/");
+ }
+
+ /*
+ * 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);
+ settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ PackageManager pm = getContext().getPackageManager();
+ ActivityInfo activityInfo = settingsIntent.resolveActivityInfo(pm, 0);
+ if (activityInfo != null) {
+ settingsIntent.setClassName(activityInfo.applicationInfo.packageName,
+ activityInfo.name);
+ CharSequence label = activityInfo.loadLabel(getContext().getPackageManager());
+ 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);
+ }
+
+ @Override
+ public boolean onMenuOpened(int featureId, Menu menu) {
+ // The menu shows up above the IME, regardless of whether it is in front
+ // of the drop-down or not. This looks weird when there is no IME, so
+ // we make sure it is visible.
+ mSearchAutoComplete.ensureImeVisible();
+ return super.onMenuOpened(featureId, menu);
+ }
+
/**
* Listeners of various types
*/
@@ -794,7 +863,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
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)) {
@@ -835,6 +903,12 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
getContext().startActivity(mVoiceWebSearchIntent);
} else if (mSearchable.getVoiceSearchLaunchRecognizer()) {
Intent appSearchIntent = createVoiceAppSearchIntent(mVoiceAppSearchIntent);
+
+ // Stop the existing search before starting voice search, or else we'll end
+ // up showing the search dialog again once we return to the app.
+ ((SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE)).
+ stopSearch();
+
getContext().startActivity(appSearchIntent);
}
} catch (ActivityNotFoundException e) {
@@ -1093,7 +1167,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
*/
protected void launchQuerySearch(int actionKey, String actionMsg) {
String query = mSearchAutoComplete.getText().toString();
- Intent intent = createIntent(Intent.ACTION_SEARCH, null, null, query, null,
+ String action = mGlobalSearchMode ? Intent.ACTION_WEB_SEARCH : Intent.ACTION_SEARCH;
+ Intent intent = createIntent(action, null, null, query, null,
actionKey, actionMsg);
launchIntent(intent);
}
@@ -1169,11 +1244,11 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// ensure the icons will work for global search
cv.put(SearchManager.SUGGEST_COLUMN_ICON_1,
wrapIconForPackage(
- source,
+ mSearchable.getSuggestPackage(),
getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_1)));
cv.put(SearchManager.SUGGEST_COLUMN_ICON_2,
wrapIconForPackage(
- source,
+ mSearchable.getSuggestPackage(),
getColumnString(c, SearchManager.SUGGEST_COLUMN_ICON_2)));
// the rest can be passed through directly
@@ -1212,11 +1287,11 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
* Wraps an icon for a particular package. If the icon is a resource id, it is converted into
* an android.resource:// URI.
*
- * @param source The source of the icon
+ * @param packageName The source of the icon
* @param icon The icon retrieved from a suggestion column
* @return An icon string appropriate for the package.
*/
- private String wrapIconForPackage(ComponentName source, String icon) {
+ private String wrapIconForPackage(String packageName, String icon) {
if (icon == null || icon.length() == 0 || "0".equals(icon)) {
// SearchManager specifies that null or zero can be returned to indicate
// no icon. We also allow empty string.
@@ -1224,7 +1299,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
} else if (!Character.isDigit(icon.charAt(0))){
return icon;
} else {
- String packageName = source.getPackageName();
return new Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(packageName)
@@ -1245,16 +1319,133 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
return;
}
Log.d(LOG_TAG, "launching " + intent);
- getContext().startActivity(intent);
-
- // in global search mode, SearchDialogWrapper#performActivityResuming will handle hiding
- // the dialog when the next activity starts, but for in-app search, we still need to
- // dismiss the dialog.
- if (!mGlobalSearchMode) {
- dismiss();
+ try {
+ // in global search mode, we send the activity straight to the original suggestion
+ // source. this is because GlobalSearch may not have permission to launch the
+ // intent, and to avoid the extra step of going through GlobalSearch.
+ if (mGlobalSearchMode) {
+ launchGlobalSearchIntent(intent);
+ } else {
+ // If the intent was created from a suggestion, it will always have an explicit
+ // component here.
+ Log.i(LOG_TAG, "Starting (as ourselves) " + intent.toURI());
+ getContext().startActivity(intent);
+ // If the search switches to a different activity,
+ // SearchDialogWrapper#performActivityResuming
+ // will handle hiding the dialog when the next activity starts, but for
+ // real in-app search, we still need to dismiss the dialog.
+ if (isInRealAppSearch()) {
+ dismiss();
+ }
+ }
+ } catch (RuntimeException ex) {
+ Log.e(LOG_TAG, "Failed launch activity: " + intent, ex);
}
}
-
+
+ private void launchGlobalSearchIntent(Intent intent) {
+ final String packageName;
+ // GlobalSearch puts the original source of the suggestion in the
+ // 'component name' column. If set, we send the intent to that activity.
+ // We trust GlobalSearch to always set this to the suggestion source.
+ String intentComponent = intent.getStringExtra(SearchManager.COMPONENT_NAME_KEY);
+ if (intentComponent != null) {
+ ComponentName componentName = ComponentName.unflattenFromString(intentComponent);
+ intent.setComponent(componentName);
+ intent.removeExtra(SearchManager.COMPONENT_NAME_KEY);
+ // Launch the intent as the suggestion source.
+ // This prevents sources from using the search dialog to launch
+ // intents that they don't have permission for themselves.
+ packageName = componentName.getPackageName();
+ } else {
+ // If there is no component in the suggestion, it must be a built-in suggestion
+ // from GlobalSearch (e.g. "Search the web for") or the intent
+ // launched when pressing the search/go button in the search dialog.
+ // Launch the intent with the permissions of GlobalSearch.
+ packageName = mSearchable.getSearchActivity().getPackageName();
+ }
+
+ // Launch all global search suggestions as new tasks, since they don't relate
+ // to the current task.
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ setBrowserApplicationId(intent);
+
+ startActivityInPackage(intent, packageName);
+ }
+
+ /**
+ * If the intent is to open an HTTP or HTTPS URL, we set
+ * {@link Browser#EXTRA_APPLICATION_ID} so that any existing browser window that
+ * has been opened by us for the same URL will be reused.
+ */
+ private void setBrowserApplicationId(Intent intent) {
+ Uri data = intent.getData();
+ if (Intent.ACTION_VIEW.equals(intent.getAction()) && data != null) {
+ String scheme = data.getScheme();
+ if (scheme != null && scheme.startsWith("http")) {
+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, data.toString());
+ }
+ }
+ }
+
+ /**
+ * Starts an activity as if it had been started by the given package.
+ *
+ * @param intent The description of the activity to start.
+ * @param packageName
+ * @throws ActivityNotFoundException If the intent could not be resolved to
+ * and existing activity.
+ * @throws SecurityException If the package does not have permission to start
+ * start the activity.
+ * @throws AndroidRuntimeException If some other error occurs.
+ */
+ private void startActivityInPackage(Intent intent, String packageName) {
+ try {
+ int uid = ActivityThread.getPackageManager().getPackageUid(packageName);
+ if (uid < 0) {
+ throw new AndroidRuntimeException("Package UID not found " + packageName);
+ }
+ String resolvedType = intent.resolveTypeIfNeeded(getContext().getContentResolver());
+ IBinder resultTo = null;
+ String resultWho = null;
+ int requestCode = -1;
+ boolean onlyIfNeeded = false;
+ Log.i(LOG_TAG, "Starting (uid " + uid + ", " + packageName + ") " + intent.toURI());
+ int result = ActivityManagerNative.getDefault().startActivityInPackage(
+ uid, intent, resolvedType, resultTo, resultWho, requestCode, onlyIfNeeded);
+ checkStartActivityResult(result, intent);
+ } catch (RemoteException ex) {
+ throw new AndroidRuntimeException(ex);
+ }
+ }
+
+ // Stolen from Instrumentation.checkStartActivityResult()
+ private static void checkStartActivityResult(int res, Intent intent) {
+ if (res >= IActivityManager.START_SUCCESS) {
+ return;
+ }
+ switch (res) {
+ case IActivityManager.START_INTENT_NOT_RESOLVED:
+ case IActivityManager.START_CLASS_NOT_FOUND:
+ if (intent.getComponent() != null)
+ throw new ActivityNotFoundException(
+ "Unable to find explicit activity class "
+ + intent.getComponent().toShortString()
+ + "; have you declared this activity in your AndroidManifest.xml?");
+ throw new ActivityNotFoundException(
+ "No Activity found to handle " + intent);
+ case IActivityManager.START_PERMISSION_DENIED:
+ throw new SecurityException("Not allowed to start activity "
+ + intent);
+ case IActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
+ throw new AndroidRuntimeException(
+ "FORWARD_RESULT_FLAG used while also requesting a result");
+ default:
+ throw new AndroidRuntimeException("Unknown error code "
+ + res + " when starting " + intent);
+ }
+ }
+
/**
* Handles the special intent actions declared in {@link SearchManager}.
*
@@ -1284,13 +1475,13 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
return;
}
if (DBG) Log.d(LOG_TAG, "Switching to " + componentName);
-
- ComponentName previous = mLaunchComponent;
+
+ pushPreviousComponent(mLaunchComponent);
if (!show(componentName, mAppSearchData, false)) {
Log.w(LOG_TAG, "Failed to switch to source " + componentName);
+ popPreviousComponent();
return;
}
- pushPreviousComponent(previous);
String query = intent.getStringExtra(SearchManager.QUERY);
setUserQuery(query);
@@ -1460,8 +1651,10 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
intent.putExtra(SearchManager.ACTION_KEY, actionKey);
intent.putExtra(SearchManager.ACTION_MSG, actionMsg);
}
- // attempt to enforce security requirement (no 3rd-party intents)
- intent.setComponent(mSearchable.getSearchActivity());
+ // Only allow 3rd-party intents from GlobalSearch
+ if (!mGlobalSearchMode) {
+ intent.setComponent(mSearchable.getSearchActivity());
+ }
return intent;
}
@@ -1582,6 +1775,12 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
if (mSearchDialog.backToPreviousComponent()) {
return true;
}
+ // If the drop-down obscures the keyboard, the user wouldn't see anything
+ // happening when pressing back, so we dismiss the entire dialog instead.
+ if (isInputMethodNotNeeded()) {
+ mSearchDialog.cancel();
+ return true;
+ }
return false; // will dismiss soft keyboard if necessary
}
return false;
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 0631ad58929ba..fd559d66cba1f 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1214,19 +1214,14 @@ public class SearchManager
public final static String POST_REFRESH_RECEIVE_DISPLAY_NOTIFY
= "DialogCursorProtocol.POST_REFRESH.displayNotify";
- /**
- * Just before closing the cursor.
- */
- public final static int PRE_CLOSE = 1;
- public final static String PRE_CLOSE_SEND_MAX_DISPLAY_POS
- = "DialogCursorProtocol.PRE_CLOSE.sendDisplayPosition";
-
/**
* When a position has been clicked.
*/
public final static int CLICK = 2;
public final static String CLICK_SEND_POSITION
= "DialogCursorProtocol.CLICK.sendPosition";
+ public final static String CLICK_SEND_MAX_DISPLAY_POS
+ = "DialogCursorProtocol.CLICK.sendDisplayPosition";
public final static String CLICK_RECEIVE_SELECTED_POS
= "DialogCursorProtocol.CLICK.receiveSelectedPosition";
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 593b7b736cfaa..4a00e485f5670 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -27,6 +27,7 @@ import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.DrawableContainer;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.os.Bundle;
@@ -135,6 +136,8 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
private int mPreviousLength = 0;
public long getPostingDelay(CharSequence constraint) {
+ if (constraint == null) return 0;
+
long delay = constraint.length() < mPreviousLength ? DELETE_KEY_POST_DELAY : 0;
mPreviousLength = constraint.length();
return delay;
@@ -191,35 +194,19 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
public void changeCursor(Cursor c) {
if (DBG) Log.d(LOG_TAG, "changeCursor(" + c + ")");
- if (mCursor != null) {
- callCursorPreClose(mCursor);
+ try {
+ 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);
+ mBackgroundColorCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_BACKGROUND_COLOR);
+ }
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "error changing cursor and caching columns", e);
}
-
- 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);
- mBackgroundColorCol = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_BACKGROUND_COLOR);
- }
- }
-
- /**
- * Handle sending and receiving information associated with
- * {@link DialogCursorProtocol#PRE_CLOSE}.
- *
- * @param cursor The cursor to call.
- */
- private void callCursorPreClose(Cursor cursor) {
- if (!mGlobalSearchMode) return;
- final Bundle request = new Bundle();
- request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.PRE_CLOSE);
- request.putInt(DialogCursorProtocol.PRE_CLOSE_SEND_MAX_DISPLAY_POS, mMaxDisplayed);
- final Bundle response = cursor.respond(request);
-
- mMaxDisplayed = -1;
}
@Override
@@ -267,7 +254,9 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
final Bundle request = new Bundle(1);
request.putInt(DialogCursorProtocol.METHOD, DialogCursorProtocol.CLICK);
request.putInt(DialogCursorProtocol.CLICK_SEND_POSITION, position);
+ request.putInt(DialogCursorProtocol.CLICK_SEND_MAX_DISPLAY_POS, mMaxDisplayed);
final Bundle response = cursor.respond(request);
+ mMaxDisplayed = -1;
mListItemToSelect = response.getInt(
DialogCursorProtocol.CLICK_RECEIVE_SELECTED_POS, SuggestionsAdapter.NONE);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9e37ae448731c..25b5de37128f6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1283,7 +1283,8 @@ public abstract class Context {
* Use with {@link #getSystemService} to retrieve an
* {@blink android.backup.IBackupManager IBackupManager} for communicating
* with the backup mechanism.
- *
+ * @hide
+ *
* @see #getSystemService
*/
public static final String BACKUP_SERVICE = "backup";
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 45a082a9520ee..15612cefcc27a 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -135,6 +135,7 @@ public class ContextWrapper extends Context {
return mBase.getPackageCodePath();
}
+ /** @hide */
@Override
public File getSharedPrefsFile(String name) {
return mBase.getSharedPrefsFile(name);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index a5f298c5b7c9f..c62d66bc55329 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1683,53 +1683,7 @@ public class Intent implements Parcelable {
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_REBOOT =
"android.intent.action.REBOOT";
- /**
- * Broadcast Action: Triggers the platform Text-To-Speech engine to
- * start the activity that installs the resource files on the device
- * that are required for TTS to be operational. Since the installation
- * of the data can be interrupted or declined by the user, the application
- * shouldn't expect successful installation upon return from that intent,
- * and if need be, should check installation status with
- * {@link #ACTION_TTS_CHECK_TTS_DATA}.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TTS_INSTALL_TTS_DATA =
- "android.intent.action.INSTALL_TTS_DATA";
- /**
- * Broadcast Action: Starts the activity from the platform Text-To-Speech
- * engine to verify the proper installation and availability of the
- * resource files on the system. Upon completion, the activity will
- * return one of the following codes:
- * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_PASS},
- * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_FAIL},
- * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_BAD_DATA},
- * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_DATA}, or
- * {@link android.speech.tts.TextToSpeech.Engine#CHECK_VOICE_DATA_MISSING_VOLUME}.
- * Moreover, the data received in the activity result will contain the following
- * fields:
- *
- * - {@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_ROOT_DIRECTORY} which
- * indicates the path to the location of the resource files
,
- * - {@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES} which contains
- * the list of all the resource files
,
- * - and {@link android.speech.tts.TextToSpeech.Engine#VOICE_DATA_FILES_INFO} which
- * contains, for each resource file, the description of the language covered by
- * the file in the xxx-YYY format, where xxx is the 3-letter ISO language code,
- * and YYY is the 3-letter ISO country code.
- *
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TTS_CHECK_TTS_DATA =
- "android.intent.action.CHECK_TTS_DATA";
-
- /**
- * Broadcast Action: The TextToSpeech synthesizer has completed processing
- * all of the text in the speech queue.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED =
- "android.intent.action.TTS_QUEUE_PROCESSING_COMPLETED";
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
@@ -2390,7 +2344,7 @@ public class Intent implements Parcelable {
/**
* Create an intent from a URI. This URI may encode the action,
* category, and other intent fields, if it was returned by
- * {@link #toUri}.. If the Intent was not generate by toUri(), its data
+ * {@link #toUri}. If the Intent was not generate by toUri(), its data
* will be the entire URI and its action will be ACTION_VIEW.
*
* The URI given here must not be relative -- that is, it must include
diff --git a/core/java/android/content/IntentSender.java b/core/java/android/content/IntentSender.java
index 4da49d974fd53..0e4d98498e8fe 100644
--- a/core/java/android/content/IntentSender.java
+++ b/core/java/android/content/IntentSender.java
@@ -52,6 +52,9 @@ import android.util.AndroidException;
* categories, and components, and same flags), it will receive a IntentSender
* representing the same token if that is still valid.
*
+ *
Instances of this class can not be made directly, but rather must be
+ * created from an existing {@link android.app.PendingIntent} with
+ * {@link android.app.PendingIntent#getIntentSender() PendingIntent.getIntentSender()}.
*/
public class IntentSender implements Parcelable {
private final IIntentSender mTarget;
@@ -245,11 +248,13 @@ public class IntentSender implements Parcelable {
return b != null ? new IntentSender(b) : null;
}
- protected IntentSender(IIntentSender target) {
+ /** @hide */
+ public IntentSender(IIntentSender target) {
mTarget = target;
}
- protected IntentSender(IBinder target) {
+ /** @hide */
+ public IntentSender(IBinder target) {
mTarget = IIntentSender.Stub.asInterface(target);
}
}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 4a3137fc95a0f..0a42a6faf9f4b 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -131,8 +131,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
/**
- * Value for {@link #flags}: this is set of the application has set
- * its android:targetSdkVersion to something >= the current SDK version.
+ * Value for {@link #flags}: this is set of the application has specified
+ * {@link android.R.styleable#AndroidManifestApplication_testOnly
+ * android:testOnly} to be true.
*/
public static final int FLAG_TEST_ONLY = 1<<8;
@@ -168,21 +169,22 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
public static final int FLAG_RESIZEABLE_FOR_SCREENS = 1<<12;
+ /**
+ * Value for {@link #flags}: true when the application knows how to
+ * accomodate different screen densities. Corresponds to
+ * {@link android.R.styleable#AndroidManifestSupportsScreens_anyDensity
+ * android:anyDensity}.
+ */
+ public static final int FLAG_SUPPORTS_SCREEN_DENSITIES = 1<<13;
+
/**
* Value for {@link #flags}: this is false if the application has set
* its android:allowBackup to false, true otherwise.
*
* {@hide}
*/
- public static final int FLAG_ALLOW_BACKUP = 1<<13;
+ public static final int FLAG_ALLOW_BACKUP = 1<<14;
- /**
- * Indicates that the application supports any densities;
- * {@hide}
- */
- public static final int ANY_DENSITY = -1;
- static final int[] ANY_DENSITIES_ARRAY = { ANY_DENSITY };
-
/**
* Flags associated with the application. Any combination of
* {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
@@ -227,13 +229,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
public int uid;
- /**
- * The list of densities in DPI that application supprots. This
- * field is only set if the {@link PackageManager#GET_SUPPORTS_DENSITIES} flag was
- * used when retrieving the structure.
- */
- public int[] supportsDensities;
-
/**
* The minimum SDK version this application targets. It may run on earilier
* versions, but it knows how to work with any new behavior added at this
@@ -267,7 +262,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
pw.println(prefix + "enabled=" + enabled);
pw.println(prefix + "manageSpaceActivityName="+manageSpaceActivityName);
pw.println(prefix + "description=0x"+Integer.toHexString(descriptionRes));
- pw.println(prefix + "supportsDensities=" + supportsDensities);
super.dumpBack(pw, prefix);
}
@@ -314,7 +308,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
enabled = orig.enabled;
manageSpaceActivityName = orig.manageSpaceActivityName;
descriptionRes = orig.descriptionRes;
- supportsDensities = orig.supportsDensities;
}
@@ -346,7 +339,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
dest.writeString(manageSpaceActivityName);
dest.writeString(backupAgentName);
dest.writeInt(descriptionRes);
- dest.writeIntArray(supportsDensities);
}
public static final Parcelable.Creator CREATOR
@@ -377,7 +369,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
manageSpaceActivityName = source.readString();
backupAgentName = source.readString();
descriptionRes = source.readInt();
- supportsDensities = source.createIntArray();
}
/**
@@ -408,7 +399,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
*/
public void disableCompatibilityMode() {
flags |= (FLAG_SUPPORTS_LARGE_SCREENS | FLAG_SUPPORTS_NORMAL_SCREENS |
- FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS);
- supportsDensities = ANY_DENSITIES_ARRAY;
+ FLAG_SUPPORTS_SMALL_SCREENS | FLAG_RESIZEABLE_FOR_SCREENS |
+ FLAG_SUPPORTS_SCREEN_DENSITIES);
}
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 941ca9e5bb74e..67bd1acd989c0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -164,12 +164,6 @@ public abstract class PackageManager {
*/
public static final int GET_CONFIGURATIONS = 0x00004000;
- /**
- * {@link ApplicationInfo} flag: return the
- * {@link ApplicationInfo#supportsDensities} that the package supports.
- */
- public static final int GET_SUPPORTS_DENSITIES = 0x00008000;
-
/**
* Resolution and querying flag: if set, only filters that support the
* {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 93ba9599be061..33f4b52e2f94a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -675,6 +675,7 @@ public class PackageParser {
int supportsNormalScreens = 1;
int supportsLargeScreens = 1;
int resizeable = 1;
+ int anyDensity = 1;
int outerDepth = parser.getDepth();
while ((type=parser.next()) != parser.END_DOCUMENT
@@ -854,21 +855,6 @@ public class PackageParser {
XmlUtils.skipCurrentTag(parser);
- } else if (tagName.equals("supports-density")) {
- sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestSupportsDensity);
-
- int density = sa.getInteger(
- com.android.internal.R.styleable.AndroidManifestSupportsDensity_density, -1);
-
- sa.recycle();
-
- if (density != -1 && !pkg.supportsDensityList.contains(density)) {
- pkg.supportsDensityList.add(density);
- }
-
- XmlUtils.skipCurrentTag(parser);
-
} else if (tagName.equals("supports-screens")) {
sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.AndroidManifestSupportsScreens);
@@ -887,6 +873,9 @@ public class PackageParser {
resizeable = sa.getInteger(
com.android.internal.R.styleable.AndroidManifestSupportsScreens_resizeable,
supportsLargeScreens);
+ anyDensity = sa.getInteger(
+ com.android.internal.R.styleable.AndroidManifestSupportsScreens_anyDensity,
+ anyDensity);
sa.recycle();
@@ -962,7 +951,7 @@ public class PackageParser {
if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
&& pkg.applicationInfo.targetSdkVersion
- >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+ >= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
}
if (supportsNormalScreens != 0) {
@@ -970,32 +959,19 @@ public class PackageParser {
}
if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
&& pkg.applicationInfo.targetSdkVersion
- >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+ >= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
}
if (resizeable < 0 || (resizeable > 0
&& pkg.applicationInfo.targetSdkVersion
- >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
+ >= android.os.Build.VERSION_CODES.DONUT)) {
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS;
}
- int densities[] = null;
- int size = pkg.supportsDensityList.size();
- if (size > 0) {
- densities = pkg.supportsDensities = new int[size];
- List densityList = pkg.supportsDensityList;
- for (int i = 0; i < size; i++) {
- densities[i] = densityList.get(i);
- }
+ if (anyDensity < 0 || (anyDensity > 0
+ && pkg.applicationInfo.targetSdkVersion
+ >= android.os.Build.VERSION_CODES.DONUT)) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
}
- /**
- * TODO: enable this before code freeze. b/1967935
- * *
- if ((densities == null || densities.length == 0)
- && (pkg.applicationInfo.targetSdkVersion
- >= android.os.Build.VERSION_CODES.CUR_DEVELOPMENT)) {
- pkg.supportsDensities = ApplicationInfo.ANY_DENSITIES_ARRAY;
- }
- */
return pkg;
}
@@ -2446,9 +2422,6 @@ public class PackageParser {
// We store the application meta-data independently to avoid multiple unwanted references
public Bundle mAppMetaData = null;
- public final ArrayList supportsDensityList = new ArrayList();
- public int[] supportsDensities = null;
-
// If this is a 3rd party app, this is the path of the zip file.
public String mPath;
@@ -2630,10 +2603,6 @@ public class PackageParser {
&& p.usesLibraryFiles != null) {
return true;
}
- if ((flags & PackageManager.GET_SUPPORTS_DENSITIES) != 0
- && p.supportsDensities != null) {
- return true;
- }
return false;
}
@@ -2656,9 +2625,6 @@ public class PackageParser {
if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0) {
ai.sharedLibraryFiles = p.usesLibraryFiles;
}
- if ((flags & PackageManager.GET_SUPPORTS_DENSITIES) != 0) {
- ai.supportsDensities = p.supportsDensities;
- }
if (!sCompatibilityModeEnabled) {
ai.disableCompatibilityMode();
}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 5c7b01fa0ccb0..8ebe0932c2140 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -637,12 +637,13 @@ public final class AssetManager {
* mRetData. */
private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
boolean resolve);
- /*package*/ static final int STYLE_NUM_ENTRIES = 5;
+ /*package*/ static final int STYLE_NUM_ENTRIES = 6;
/*package*/ static final int STYLE_TYPE = 0;
/*package*/ static final int STYLE_DATA = 1;
/*package*/ static final int STYLE_ASSET_COOKIE = 2;
/*package*/ static final int STYLE_RESOURCE_ID = 3;
/*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
+ /*package*/ static final int STYLE_DENSITY = 5;
/*package*/ native static final boolean applyStyle(int theme,
int defStyleAttr, int defStyleRes, int xmlParser,
int[] inAttrs, int[] outValues, int[] outIndices);
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 517551ec8e149..50faf57a096f7 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -131,41 +131,15 @@ public class CompatibilityInfo {
mCompatibilityFlags |= EXPANDABLE | CONFIGURED_EXPANDABLE;
}
- float packageDensityScale = -1.0f;
- int packageDensity = 0;
- if (appInfo.supportsDensities != null) {
- int minDiff = Integer.MAX_VALUE;
- for (int density : appInfo.supportsDensities) {
- if (density == ApplicationInfo.ANY_DENSITY) {
- packageDensity = DisplayMetrics.DENSITY_DEVICE;
- packageDensityScale = 1.0f;
- break;
- }
- int tmpDiff = Math.abs(DisplayMetrics.DENSITY_DEVICE - density);
- if (tmpDiff == 0) {
- packageDensity = DisplayMetrics.DENSITY_DEVICE;
- packageDensityScale = 1.0f;
- break;
- }
- // prefer higher density (appScale>1.0), unless that's only option.
- if (tmpDiff < minDiff && packageDensityScale < 1.0f) {
- packageDensity = density;
- packageDensityScale = DisplayMetrics.DENSITY_DEVICE / (float) density;
- minDiff = tmpDiff;
- }
- }
- }
- if (packageDensityScale > 0.0f) {
- applicationDensity = packageDensity;
- applicationScale = packageDensityScale;
+ if ((appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
+ applicationDensity = DisplayMetrics.DENSITY_DEVICE;
+ applicationScale = 1.0f;
+ applicationInvertedScale = 1.0f;
} else {
applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
- applicationScale =
- DisplayMetrics.DENSITY_DEVICE / (float) DisplayMetrics.DENSITY_DEFAULT;
- }
-
- applicationInvertedScale = 1.0f / applicationScale;
- if (applicationScale != 1.0f) {
+ applicationScale = DisplayMetrics.DENSITY_DEVICE
+ / (float) DisplayMetrics.DENSITY_DEFAULT;
+ applicationInvertedScale = 1.0f / applicationScale;
mCompatibilityFlags |= SCALING_REQUIRED;
}
}
@@ -254,20 +228,11 @@ public class CompatibilityInfo {
}
/**
- * Returns the translator which can translate the coordinates of the window.
- * There are five different types of Translator.
+ * Returns the translator which translates the coordinates in compatibility mode.
* @param params the window's parameter
*/
- public Translator getTranslator(WindowManager.LayoutParams params) {
- if ( (mCompatibilityFlags & SCALING_EXPANDABLE_MASK)
- == (EXPANDABLE|LARGE_SCREENS)) {
- if (DBG) Log.d(TAG, "no translation required");
- return null;
- }
- if (!isScalingRequired()) {
- return null;
- }
- return new Translator();
+ public Translator getTranslator() {
+ return isScalingRequired() ? new Translator() : null;
}
/**
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 3a32c03122025..016ee7f4c7df2 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -654,6 +654,7 @@ public class TypedArray {
outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS];
+ outValue.density = data[index+AssetManager.STYLE_DENSITY];
if (type == TypedValue.TYPE_STRING) {
outValue.string = loadStringValueAt(index);
}
diff --git a/core/java/android/database/MatrixCursor.java b/core/java/android/database/MatrixCursor.java
index cf5a57358c986..d5c3a32d884d2 100644
--- a/core/java/android/database/MatrixCursor.java
+++ b/core/java/android/database/MatrixCursor.java
@@ -214,53 +214,64 @@ public class MatrixCursor extends AbstractCursor {
// AbstractCursor implementation.
+ @Override
public int getCount() {
return rowCount;
}
+ @Override
public String[] getColumnNames() {
return columnNames;
}
+ @Override
public String getString(int column) {
- return String.valueOf(get(column));
+ Object value = get(column);
+ if (value == null) return null;
+ return value.toString();
}
+ @Override
public short getShort(int column) {
Object value = get(column);
- return (value instanceof String)
- ? Short.valueOf((String) value)
- : ((Number) value).shortValue();
+ if (value == null) return 0;
+ if (value instanceof Number) return ((Number) value).shortValue();
+ return Short.parseShort(value.toString());
}
+ @Override
public int getInt(int column) {
Object value = get(column);
- return (value instanceof String)
- ? Integer.valueOf((String) value)
- : ((Number) value).intValue();
+ if (value == null) return 0;
+ if (value instanceof Number) return ((Number) value).intValue();
+ return Integer.parseInt(value.toString());
}
+ @Override
public long getLong(int column) {
Object value = get(column);
- return (value instanceof String)
- ? Long.valueOf((String) value)
- : ((Number) value).longValue();
+ if (value == null) return 0;
+ if (value instanceof Number) return ((Number) value).longValue();
+ return Long.parseLong(value.toString());
}
+ @Override
public float getFloat(int column) {
Object value = get(column);
- return (value instanceof String)
- ? Float.valueOf((String) value)
- : ((Number) value).floatValue();
+ if (value == null) return 0.0f;
+ if (value instanceof Number) return ((Number) value).floatValue();
+ return Float.parseFloat(value.toString());
}
+ @Override
public double getDouble(int column) {
Object value = get(column);
- return (value instanceof String)
- ? Double.valueOf((String) value)
- : ((Number) value).doubleValue();
+ if (value == null) return 0.0d;
+ if (value instanceof Number) return ((Number) value).doubleValue();
+ return Double.parseDouble(value.toString());
}
+ @Override
public boolean isNull(int column) {
return get(column) == null;
}
diff --git a/core/java/android/gesture/GestureLibrary.java b/core/java/android/gesture/GestureLibrary.java
index a29c2c83cfbf0..ec2e78c9df2f3 100644
--- a/core/java/android/gesture/GestureLibrary.java
+++ b/core/java/android/gesture/GestureLibrary.java
@@ -35,6 +35,7 @@ public abstract class GestureLibrary {
return false;
}
+ /** @hide */
public Learner getLearner() {
return mStore.getLearner();
}
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 8b474d567ac90..9c9c14395f15a 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -32,6 +32,7 @@ import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -161,8 +162,8 @@ public class KeyboardView extends View implements View.OnClickListener {
private static final int MSG_REMOVE_PREVIEW = 2;
private static final int MSG_REPEAT = 3;
private static final int MSG_LONGPRESS = 4;
-
- private static final int DELAY_BEFORE_PREVIEW = 70;
+
+ private static final int DELAY_BEFORE_PREVIEW = 40;
private static final int DELAY_AFTER_PREVIEW = 60;
private int mVerticalCorrection;
@@ -825,10 +826,10 @@ public class KeyboardView extends View implements View.OnClickListener {
mPreviewText.setCompoundDrawables(null, null, null, null);
mPreviewText.setText(getPreviewText(key));
if (key.label.length() > 1 && key.codes.length < 2) {
- mPreviewText.setTextSize(mKeyTextSize);
+ mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mKeyTextSize);
mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
- mPreviewText.setTextSize(mPreviewTextSizeLarge);
+ mPreviewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mPreviewTextSizeLarge);
mPreviewText.setTypeface(Typeface.DEFAULT);
}
}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 7d03801d7bd10..afe219c8fe88d 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -151,34 +151,20 @@ public class CallLog {
int presentation, int callType, long start, int duration) {
final ContentResolver resolver = context.getContentResolver();
- // TODO(Moto): Which is correct: original code, this only changes the
- // number if the number is empty and never changes the caller info name.
- if (false) {
- if (TextUtils.isEmpty(number)) {
- if (presentation == Connection.PRESENTATION_RESTRICTED) {
- number = CallerInfo.PRIVATE_NUMBER;
- } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
- number = CallerInfo.PAYPHONE_NUMBER;
- } else {
- number = CallerInfo.UNKNOWN_NUMBER;
- }
- }
- } else {
- // NEWCODE: From Motorola
-
- //If this is a private number then set the number to Private, otherwise check
- //if the number field is empty and set the number to Unavailable
+ // If this is a private number then set the number to Private, otherwise check
+ // if the number field is empty and set the number to Unavailable
if (presentation == Connection.PRESENTATION_RESTRICTED) {
number = CallerInfo.PRIVATE_NUMBER;
- ci.name = "";
+ if (ci != null) ci.name = "";
} else if (presentation == Connection.PRESENTATION_PAYPHONE) {
number = CallerInfo.PAYPHONE_NUMBER;
- ci.name = "";
- } else if (TextUtils.isEmpty(number) || presentation == Connection.PRESENTATION_UNKNOWN) {
+ if (ci != null) ci.name = "";
+ } else if (TextUtils.isEmpty(number)
+ || presentation == Connection.PRESENTATION_UNKNOWN) {
number = CallerInfo.UNKNOWN_NUMBER;
- ci.name = "";
+ if (ci != null) ci.name = "";
}
- }
+
ContentValues values = new ContentValues(5);
values.put(NUMBER, number);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b5440f2446261..9a9ddc9f39ae5 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2916,6 +2916,13 @@ public final class Settings {
*/
public static final String VENDING_TOS_URL = "vending_tos_url";
+ /**
+ * URL to navigate to in browser (not Market) when the terms of service
+ * for Vending Machine could not be accessed due to bad network
+ * connection.
+ */
+ public static final String VENDING_TOS_MISSING_URL = "vending_tos_missing_url";
+
/**
* Whether to use sierraqa instead of sierra tokens for the purchase flow in
* Vending Machine.
diff --git a/core/java/android/server/search/SearchDialogWrapper.java b/core/java/android/server/search/SearchDialogWrapper.java
index d3ef5de8634fb..49718cb0acd0f 100644
--- a/core/java/android/server/search/SearchDialogWrapper.java
+++ b/core/java/android/server/search/SearchDialogWrapper.java
@@ -63,6 +63,8 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
private static final int MSG_STOP_SEARCH = 2;
// arg1 is activity id
private static final int MSG_ACTIVITY_RESUMING = 3;
+ // obj is the reason
+ private static final int MSG_CLOSING_SYSTEM_DIALOGS = 4;
private static final String KEY_INITIAL_QUERY = "q";
private static final String KEY_LAUNCH_ACTIVITY = "a";
@@ -127,8 +129,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
private void registerBroadcastReceiver() {
if (!mReceiverRegistered) {
IntentFilter filter = new IntentFilter(
- Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
+ Intent.ACTION_CONFIGURATION_CHANGED);
mContext.registerReceiver(mBroadcastReceiver, filter, null,
mSearchUiThread);
mReceiverRegistered = true;
@@ -149,12 +150,7 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
- if (!"search".equals(intent.getStringExtra("reason"))) {
- if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- performStopSearch();
- }
- } else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
+ if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) {
if (DBG) debug(Intent.ACTION_CONFIGURATION_CHANGED);
performOnConfigurationChanged();
}
@@ -190,6 +186,9 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
msgData.putBundle(KEY_APP_SEARCH_DATA, appSearchData);
msgData.putInt(KEY_IDENT, ident);
mSearchUiThread.sendMessage(msg);
+ // be a little more eager in setting this so isVisible will return the correct value if
+ // called immediately after startSearch
+ mVisible = true;
}
/**
@@ -199,6 +198,9 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
public void stopSearch() {
if (DBG) debug("stopSearch()");
mSearchUiThread.sendEmptyMessage(MSG_STOP_SEARCH);
+ // be a little more eager in setting this so isVisible will return the correct value if
+ // called immediately after stopSearch
+ mVisible = false;
}
/**
@@ -213,6 +215,18 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
mSearchUiThread.sendMessage(msg);
}
+ /**
+ * Handles closing of system windows/dialogs
+ * Can be called from any thread.
+ */
+ public void closingSystemDialogs(String reason) {
+ if (DBG) debug("closingSystemDialogs(reason=" + reason + ")");
+ Message msg = Message.obtain();
+ msg.what = MSG_CLOSING_SYSTEM_DIALOGS;
+ msg.obj = reason;
+ mSearchUiThread.sendMessage(msg);
+ }
+
//
// Implementation methods that run on the search UI thread
//
@@ -238,6 +252,9 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
case MSG_ACTIVITY_RESUMING:
performActivityResuming(msg.arg1);
break;
+ case MSG_CLOSING_SYSTEM_DIALOGS:
+ performClosingSystemDialogs((String)msg.obj);
+ break;
}
}
@@ -323,6 +340,19 @@ implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
}
}
+ /**
+ * Updates due to system dialogs being closed
+ * This must be called on the search UI thread.
+ */
+ void performClosingSystemDialogs(String reason) {
+ if (DBG) debug("performClosingSystemDialogs(): mStartedIdent="
+ + mStartedIdent + ", reason: " + reason);
+ if (!"search".equals(reason)) {
+ if (DBG) debug(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+ performStopSearch();
+ }
+ }
+
/**
* Must be called from the search UI thread.
*/
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index fdeb8f9e3fc23..afed4a4968ce2 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -138,6 +138,11 @@ public class SearchManagerService extends ISearchManager.Stub {
if (mSearchDialog == null) return;
mSearchDialog.activityResuming(activityId);
}
+ public void closingSystemDialogs(String reason) {
+ if (DBG) Log.i("foo", "********************** closing dialogs: " + reason);
+ if (mSearchDialog == null) return;
+ mSearchDialog.closingSystemDialogs(reason);
+ }
};
/**
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index 045b0c2f0874f..69ef98c0c3ce8 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -102,6 +102,14 @@ public final class SearchableInfo implements Parcelable {
return mSuggestAuthority;
}
+ /**
+ * Gets the name of the package where the suggestion provider lives,
+ * or {@code null}.
+ */
+ public String getSuggestPackage() {
+ return mSuggestProviderPackage;
+ }
+
/**
* Gets the component name of the searchable activity.
*/
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index bb6b4b0385d84..b033c6a7cdc23 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -18,6 +18,8 @@ package android.speech.tts;
import android.speech.tts.ITts;
import android.speech.tts.ITtsCallback;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -41,51 +43,60 @@ public class TextToSpeech {
/**
* Denotes a successful operation.
*/
- public static final int TTS_SUCCESS = 0;
+ public static final int SUCCESS = 0;
/**
* Denotes a generic operation failure.
*/
- public static final int TTS_ERROR = -1;
+ public static final int ERROR = -1;
/**
* Queue mode where all entries in the playback queue (media to be played
* and text to be synthesized) are dropped and replaced by the new entry.
*/
- public static final int TTS_QUEUE_FLUSH = 0;
+ public static final int QUEUE_FLUSH = 0;
/**
* Queue mode where the new entry is added at the end of the playback queue.
*/
- public static final int TTS_QUEUE_ADD = 1;
+ public static final int QUEUE_ADD = 1;
/**
* Denotes the language is available exactly as specified by the locale
*/
- public static final int TTS_LANG_COUNTRY_VAR_AVAILABLE = 2;
+ public static final int LANG_COUNTRY_VAR_AVAILABLE = 2;
/**
* Denotes the language is available for the language and country specified
* by the locale, but not the variant.
*/
- public static final int TTS_LANG_COUNTRY_AVAILABLE = 1;
+ public static final int LANG_COUNTRY_AVAILABLE = 1;
/**
* Denotes the language is available for the language by the locale,
* but not the country and variant.
*/
- public static final int TTS_LANG_AVAILABLE = 0;
+ public static final int LANG_AVAILABLE = 0;
/**
* Denotes the language data is missing.
*/
- public static final int TTS_LANG_MISSING_DATA = -1;
+ public static final int LANG_MISSING_DATA = -1;
/**
* Denotes the language is not supported by the current TTS engine.
*/
- public static final int TTS_LANG_NOT_SUPPORTED = -2;
+ public static final int LANG_NOT_SUPPORTED = -2;
+
+
+ /**
+ * Broadcast Action: The TextToSpeech synthesizer has completed processing
+ * of all the text in the speech queue.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_TTS_QUEUE_PROCESSING_COMPLETED =
+ "android.speech.tts.TTS_QUEUE_PROCESSING_COMPLETED";
/**
@@ -119,126 +130,167 @@ public class TextToSpeech {
/**
* {@hide}
*/
- public static final int FALLBACK_TTS_DEFAULT_RATE = 100; // 1x
+ public static final int DEFAULT_RATE = 100; // 1x
/**
* {@hide}
*/
- public static final int FALLBACK_TTS_DEFAULT_PITCH = 100;// 1x
+ public static final int DEFAULT_PITCH = 100;// 1x
/**
* {@hide}
*/
- public static final int FALLBACK_TTS_USE_DEFAULTS = 0; // false
+ public static final int USE_DEFAULTS = 0; // false
/**
* {@hide}
*/
- public static final String FALLBACK_TTS_DEFAULT_SYNTH = "com.svox.pico";
+ public static final String DEFAULT_SYNTH = "com.svox.pico";
// default values for rendering
- public static final int TTS_DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
+ public static final int DEFAULT_STREAM = AudioManager.STREAM_MUSIC;
// return codes for a TTS engine's check data activity
/**
* Indicates success when checking the installation status of the resources used by the
- * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+ * text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
*/
public static final int CHECK_VOICE_DATA_PASS = 1;
/**
* Indicates failure when checking the installation status of the resources used by the
- * text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+ * text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
*/
public static final int CHECK_VOICE_DATA_FAIL = 0;
/**
* Indicates erroneous data when checking the installation status of the resources used by
- * the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+ * the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
*/
public static final int CHECK_VOICE_DATA_BAD_DATA = -1;
/**
* Indicates missing resources when checking the installation status of the resources used
- * by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+ * by the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
*/
public static final int CHECK_VOICE_DATA_MISSING_DATA = -2;
/**
* Indicates missing storage volume when checking the installation status of the resources
- * used by the text-to-speech engine with the android.intent.action.CHECK_TTS_DATA intent.
+ * used by the text-to-speech engine with the {@link #ACTION_CHECK_TTS_DATA} intent.
*/
public static final int CHECK_VOICE_DATA_MISSING_VOLUME = -3;
- // return codes for a TTS engine's check data activity
+ // intents to ask engine to install data or check its data
/**
- * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+ * Broadcast Action: Triggers the platform Text-To-Speech engine to
+ * start the activity that installs the resource files on the device
+ * that are required for TTS to be operational. Since the installation
+ * of the data can be interrupted or declined by the user, the application
+ * shouldn't expect successful installation upon return from that intent,
+ * and if need be, should check installation status with
+ * {@link #ACTION_CHECK_TTS_DATA}.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_INSTALL_TTS_DATA =
+ "android.speech.tts.engine.INSTALL_TTS_DATA";
+
+ /**
+ * Broadcast Action: Starts the activity from the platform Text-To-Speech
+ * engine to verify the proper installation and availability of the
+ * resource files on the system. Upon completion, the activity will
+ * return one of the following codes:
+ * {@link #CHECK_VOICE_DATA_PASS},
+ * {@link #CHECK_VOICE_DATA_FAIL},
+ * {@link #CHECK_VOICE_DATA_BAD_DATA},
+ * {@link #CHECK_VOICE_DATA_MISSING_DATA}, or
+ * {@link #CHECK_VOICE_DATA_MISSING_VOLUME}.
+ * Moreover, the data received in the activity result will contain the following
+ * fields:
+ *
+ * - {@link #EXTRA_VOICE_DATA_ROOT_DIRECTORY} which
+ * indicates the path to the location of the resource files
,
+ * - {@link #EXTRA_VOICE_DATA_FILES} which contains
+ * the list of all the resource files
,
+ * - and {@link #EXTRA_VOICE_DATA_FILES_INFO} which
+ * contains, for each resource file, the description of the language covered by
+ * the file in the xxx-YYY format, where xxx is the 3-letter ISO language code,
+ * and YYY is the 3-letter ISO country code.
+ *
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CHECK_TTS_DATA =
+ "android.speech.tts.engine.CHECK_TTS_DATA";
+
+ // extras for a TTS engine's check data activity
+ /**
+ * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
* the text-to-speech engine specifies the path to its resources.
*/
- public static final String VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
+ public static final String EXTRA_VOICE_DATA_ROOT_DIRECTORY = "dataRoot";
/**
- * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+ * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
* the text-to-speech engine specifies the file names of its resources under the
* resource path.
*/
- public static final String VOICE_DATA_FILES = "dataFiles";
+ public static final String EXTRA_VOICE_DATA_FILES = "dataFiles";
/**
- * Extra information received with the android.intent.action.CHECK_TTS_DATA intent where
+ * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
* the text-to-speech engine specifies the locale associated with each resource file.
*/
- public static final String VOICE_DATA_FILES_INFO = "dataFilesInfo";
+ public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo";
// keys for the parameters passed with speak commands. Hidden keys are used internally
// to maintain engine state for each TextToSpeech instance.
/**
* {@hide}
*/
- public static final String TTS_KEY_PARAM_RATE = "rate";
+ public static final String KEY_PARAM_RATE = "rate";
/**
* {@hide}
*/
- public static final String TTS_KEY_PARAM_LANGUAGE = "language";
+ public static final String KEY_PARAM_LANGUAGE = "language";
/**
* {@hide}
*/
- public static final String TTS_KEY_PARAM_COUNTRY = "country";
+ public static final String KEY_PARAM_COUNTRY = "country";
/**
* {@hide}
*/
- public static final String TTS_KEY_PARAM_VARIANT = "variant";
+ public static final String KEY_PARAM_VARIANT = "variant";
/**
* Parameter key to specify the audio stream type to be used when speaking text
* or playing back a file.
*/
- public static final String TTS_KEY_PARAM_STREAM = "streamType";
+ public static final String KEY_PARAM_STREAM = "streamType";
/**
* Parameter key to identify an utterance in the completion listener after text has been
* spoken, a file has been played back or a silence duration has elapsed.
*/
- public static final String TTS_KEY_PARAM_UTTERANCE_ID = "utteranceId";
+ public static final String KEY_PARAM_UTTERANCE_ID = "utteranceId";
// key positions in the array of cached parameters
/**
* {@hide}
*/
- protected static final int TTS_PARAM_POSITION_RATE = 0;
+ protected static final int PARAM_POSITION_RATE = 0;
/**
* {@hide}
*/
- protected static final int TTS_PARAM_POSITION_LANGUAGE = 2;
+ protected static final int PARAM_POSITION_LANGUAGE = 2;
/**
* {@hide}
*/
- protected static final int TTS_PARAM_POSITION_COUNTRY = 4;
+ protected static final int PARAM_POSITION_COUNTRY = 4;
/**
* {@hide}
*/
- protected static final int TTS_PARAM_POSITION_VARIANT = 6;
+ protected static final int PARAM_POSITION_VARIANT = 6;
/**
* {@hide}
*/
- protected static final int TTS_PARAM_POSITION_STREAM = 8;
+ protected static final int PARAM_POSITION_STREAM = 8;
/**
* {@hide}
*/
- protected static final int TTS_PARAM_POSITION_UTTERANCE_ID = 10;
+ protected static final int PARAM_POSITION_UTTERANCE_ID = 10;
/**
* {@hide}
*/
- protected static final int TTS_NB_CACHED_PARAMS = 6;
+ protected static final int NB_CACHED_PARAMS = 6;
}
/**
@@ -273,25 +325,25 @@ public class TextToSpeech {
mPackageName = mContext.getPackageName();
mInitListener = listener;
- mCachedParams = new String[2*Engine.TTS_NB_CACHED_PARAMS]; // store key and value
- mCachedParams[Engine.TTS_PARAM_POSITION_RATE] = Engine.TTS_KEY_PARAM_RATE;
- mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE] = Engine.TTS_KEY_PARAM_LANGUAGE;
- mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY] = Engine.TTS_KEY_PARAM_COUNTRY;
- mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT] = Engine.TTS_KEY_PARAM_VARIANT;
- mCachedParams[Engine.TTS_PARAM_POSITION_STREAM] = Engine.TTS_KEY_PARAM_STREAM;
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID] = Engine.TTS_KEY_PARAM_UTTERANCE_ID;
+ mCachedParams = new String[2*Engine.NB_CACHED_PARAMS]; // store key and value
+ mCachedParams[Engine.PARAM_POSITION_RATE] = Engine.KEY_PARAM_RATE;
+ mCachedParams[Engine.PARAM_POSITION_LANGUAGE] = Engine.KEY_PARAM_LANGUAGE;
+ mCachedParams[Engine.PARAM_POSITION_COUNTRY] = Engine.KEY_PARAM_COUNTRY;
+ mCachedParams[Engine.PARAM_POSITION_VARIANT] = Engine.KEY_PARAM_VARIANT;
+ mCachedParams[Engine.PARAM_POSITION_STREAM] = Engine.KEY_PARAM_STREAM;
+ mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID] = Engine.KEY_PARAM_UTTERANCE_ID;
- mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] =
- String.valueOf(Engine.FALLBACK_TTS_DEFAULT_RATE);
+ mCachedParams[Engine.PARAM_POSITION_RATE + 1] =
+ String.valueOf(Engine.DEFAULT_RATE);
// initialize the language cached parameters with the current Locale
Locale defaultLoc = Locale.getDefault();
- mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language();
- mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country();
- mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant();
+ mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = defaultLoc.getISO3Language();
+ mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = defaultLoc.getISO3Country();
+ mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = defaultLoc.getVariant();
- mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] =
- String.valueOf(Engine.TTS_DEFAULT_STREAM);
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = "";
+ mCachedParams[Engine.PARAM_POSITION_STREAM + 1] =
+ String.valueOf(Engine.DEFAULT_STREAM);
+ mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = "";
initTts();
}
@@ -308,7 +360,7 @@ public class TextToSpeech {
mStarted = true;
if (mInitListener != null) {
// TODO manage failures and missing resources
- mInitListener.onInit(TTS_SUCCESS);
+ mInitListener.onInit(SUCCESS);
}
}
}
@@ -349,8 +401,7 @@ public class TextToSpeech {
/**
* Adds a mapping between a string of text and a sound resource in a
* package.
- *
- * @see #TTS.speak(String text, int queueMode, String[] params)
+ * @see #speak(String, int, HashMap)
*
* @param text
* Example: "south_south_east"
@@ -371,16 +422,16 @@ public class TextToSpeech {
* @param resourceId
* Example: R.raw.south_south_east
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int addSpeech(String text, String packagename, int resourceId) {
synchronized(mStartLock) {
if (!mStarted) {
- return TTS_ERROR;
+ return ERROR;
}
try {
mITts.addSpeech(mPackageName, text, packagename, resourceId);
- return TTS_SUCCESS;
+ return SUCCESS;
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - addSpeech", "RemoteException");
@@ -400,7 +451,7 @@ public class TextToSpeech {
mStarted = false;
initTts();
}
- return TTS_ERROR;
+ return ERROR;
}
}
@@ -415,16 +466,16 @@ public class TextToSpeech {
* The full path to the sound file (for example:
* "/sdcard/mysounds/hello.wav")
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int addSpeech(String text, String filename) {
synchronized (mStartLock) {
if (!mStarted) {
- return TTS_ERROR;
+ return ERROR;
}
try {
mITts.addSpeechFile(mPackageName, text, filename);
- return TTS_SUCCESS;
+ return SUCCESS;
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - addSpeech", "RemoteException");
@@ -444,7 +495,7 @@ public class TextToSpeech {
mStarted = false;
initTts();
}
- return TTS_ERROR;
+ return ERROR;
}
}
@@ -453,7 +504,7 @@ public class TextToSpeech {
* Adds a mapping between a string of text and a sound resource in a
* package.
*
- * @see #TTS.playEarcon(String earcon, int queueMode, String[] params)
+ * @see #playEarcon(String, int, HashMap)
*
* @param earcon The name of the earcon
* Example: "[tick]"
@@ -474,16 +525,16 @@ public class TextToSpeech {
* @param resourceId
* Example: R.raw.tick_snd
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int addEarcon(String earcon, String packagename, int resourceId) {
synchronized(mStartLock) {
if (!mStarted) {
- return TTS_ERROR;
+ return ERROR;
}
try {
mITts.addEarcon(mPackageName, earcon, packagename, resourceId);
- return TTS_SUCCESS;
+ return SUCCESS;
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - addEarcon", "RemoteException");
@@ -503,7 +554,7 @@ public class TextToSpeech {
mStarted = false;
initTts();
}
- return TTS_ERROR;
+ return ERROR;
}
}
@@ -518,16 +569,16 @@ public class TextToSpeech {
* The full path to the sound file (for example:
* "/sdcard/mysounds/tick.wav")
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int addEarcon(String earcon, String filename) {
synchronized (mStartLock) {
if (!mStarted) {
- return TTS_ERROR;
+ return ERROR;
}
try {
mITts.addEarconFile(mPackageName, earcon, filename);
- return TTS_SUCCESS;
+ return SUCCESS;
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - addEarcon", "RemoteException");
@@ -547,7 +598,7 @@ public class TextToSpeech {
mStarted = false;
initTts();
}
- return TTS_ERROR;
+ return ERROR;
}
}
@@ -563,29 +614,29 @@ public class TextToSpeech {
* The string of text to be spoken.
* @param queueMode
* The queuing strategy to use.
- * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
+ * See QUEUE_ADD and QUEUE_FLUSH.
* @param params
* The hashmap of speech parameters to be used.
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int speak(String text, int queueMode, HashMap params)
{
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
Log.i("TTS received: ", text);
if (!mStarted) {
return result;
}
try {
if ((params != null) && (!params.isEmpty())) {
- String extra = params.get(Engine.TTS_KEY_PARAM_STREAM);
+ String extra = params.get(Engine.KEY_PARAM_STREAM);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra;
+ mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra;
}
- extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+ extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+ mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
}
}
result = mITts.speak(mPackageName, text, queueMode, mCachedParams);
@@ -621,28 +672,28 @@ public class TextToSpeech {
* @param earcon
* The earcon that should be played
* @param queueMode
- * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
+ * See QUEUE_ADD and QUEUE_FLUSH.
* @param params
* The hashmap of parameters to be used.
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int playEarcon(String earcon, int queueMode,
HashMap params) {
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
if (!mStarted) {
return result;
}
try {
if ((params != null) && (!params.isEmpty())) {
- String extra = params.get(Engine.TTS_KEY_PARAM_STREAM);
+ String extra = params.get(Engine.KEY_PARAM_STREAM);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] = extra;
+ mCachedParams[Engine.PARAM_POSITION_STREAM + 1] = extra;
}
- extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+ extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+ mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
}
}
result = mITts.playEarcon(mPackageName, earcon, queueMode, null);
@@ -678,21 +729,21 @@ public class TextToSpeech {
* @param durationInMs
* A long that indicates how long the silence should last.
* @param queueMode
- * See TTS_QUEUE_ADD and TTS_QUEUE_FLUSH.
+ * See QUEUE_ADD and QUEUE_FLUSH.
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int playSilence(long durationInMs, int queueMode, HashMap params) {
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
if (!mStarted) {
return result;
}
try {
if ((params != null) && (!params.isEmpty())) {
- String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+ String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+ mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
}
}
result = mITts.playSilence(mPackageName, durationInMs, queueMode, mCachedParams);
@@ -760,11 +811,11 @@ public class TextToSpeech {
/**
* Stops speech from the TTS.
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int stop() {
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
if (!mStarted) {
return result;
}
@@ -808,24 +859,24 @@ public class TextToSpeech {
* lower values slow down the speech (0.5 is half the normal speech rate),
* greater values accelerate it (2 is twice the normal speech rate).
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int setSpeechRate(float speechRate) {
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
if (!mStarted) {
return result;
}
try {
if (speechRate > 0) {
int rate = (int)(speechRate*100);
- mCachedParams[Engine.TTS_PARAM_POSITION_RATE + 1] = String.valueOf(rate);
+ mCachedParams[Engine.PARAM_POSITION_RATE + 1] = String.valueOf(rate);
// the rate is not set here, instead it is cached so it will be associated
// with all upcoming utterances.
if (speechRate > 0.0f) {
- result = TTS_SUCCESS;
+ result = SUCCESS;
} else {
- result = TTS_ERROR;
+ result = ERROR;
}
}
} catch (NullPointerException e) {
@@ -860,11 +911,11 @@ public class TextToSpeech {
* lower values lower the tone of the synthesized voice,
* greater values increase it.
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int setPitch(float pitch) {
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
if (!mStarted) {
return result;
}
@@ -907,25 +958,27 @@ public class TextToSpeech {
* @param loc
* The locale describing the language to be used.
*
- * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE},
- * {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE},
- * {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}.
+ * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE},
+ * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE},
+ * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}.
*/
public int setLanguage(Locale loc) {
synchronized (mStartLock) {
- int result = TTS_LANG_NOT_SUPPORTED;
+ int result = LANG_NOT_SUPPORTED;
if (!mStarted) {
return result;
}
try {
- mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
- mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
- mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] = loc.getVariant();
-
- result = mITts.setLanguage(mPackageName,
- mCachedParams[Engine.TTS_PARAM_POSITION_LANGUAGE + 1],
- mCachedParams[Engine.TTS_PARAM_POSITION_COUNTRY + 1],
- mCachedParams[Engine.TTS_PARAM_POSITION_VARIANT + 1] );
+ mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1] = loc.getISO3Language();
+ mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1] = loc.getISO3Country();
+ mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] = loc.getVariant();
+ // the language is not set here, instead it is cached so it will be associated
+ // with all upcoming utterances. But we still need to report the language support,
+ // which is achieved by calling isLanguageAvailable()
+ result = mITts.isLanguageAvailable(
+ mCachedParams[Engine.PARAM_POSITION_LANGUAGE + 1],
+ mCachedParams[Engine.PARAM_POSITION_COUNTRY + 1],
+ mCachedParams[Engine.PARAM_POSITION_VARIANT + 1] );
} catch (RemoteException e) {
// TTS died; restart it.
Log.e("TextToSpeech.java - setLanguage", "RemoteException");
@@ -997,13 +1050,13 @@ public class TextToSpeech {
* @param loc
* The Locale describing the language to be used.
*
- * @return code indicating the support status for the locale. See {@link #TTS_LANG_AVAILABLE},
- * {@link #TTS_LANG_COUNTRY_AVAILABLE}, {@link #TTS_LANG_COUNTRY_VAR_AVAILABLE},
- * {@link #TTS_LANG_MISSING_DATA} and {@link #TTS_LANG_NOT_SUPPORTED}.
+ * @return code indicating the support status for the locale. See {@link #LANG_AVAILABLE},
+ * {@link #LANG_COUNTRY_AVAILABLE}, {@link #LANG_COUNTRY_VAR_AVAILABLE},
+ * {@link #LANG_MISSING_DATA} and {@link #LANG_NOT_SUPPORTED}.
*/
public int isLanguageAvailable(Locale loc) {
synchronized (mStartLock) {
- int result = TTS_LANG_NOT_SUPPORTED;
+ int result = LANG_NOT_SUPPORTED;
if (!mStarted) {
return result;
}
@@ -1046,25 +1099,25 @@ public class TextToSpeech {
* The string that gives the full output filename; it should be
* something like "/sdcard/myappsounds/mysound.wav".
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int synthesizeToFile(String text, HashMap params,
String filename) {
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
if (!mStarted) {
return result;
}
try {
if ((params != null) && (!params.isEmpty())) {
// no need to read the stream type here
- String extra = params.get(Engine.TTS_KEY_PARAM_UTTERANCE_ID);
+ String extra = params.get(Engine.KEY_PARAM_UTTERANCE_ID);
if (extra != null) {
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID + 1] = extra;
+ mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID + 1] = extra;
}
}
if (mITts.synthesizeToFile(mPackageName, text, mCachedParams, filename)){
- result = TTS_SUCCESS;
+ result = SUCCESS;
}
} catch (RemoteException e) {
// TTS died; restart it.
@@ -1097,9 +1150,9 @@ public class TextToSpeech {
* if they are not persistent between calls to the service.
*/
private void resetCachedParams() {
- mCachedParams[Engine.TTS_PARAM_POSITION_STREAM + 1] =
- String.valueOf(Engine.TTS_DEFAULT_STREAM);
- mCachedParams[Engine.TTS_PARAM_POSITION_UTTERANCE_ID+ 1] = "";
+ mCachedParams[Engine.PARAM_POSITION_STREAM + 1] =
+ String.valueOf(Engine.DEFAULT_STREAM);
+ mCachedParams[Engine.PARAM_POSITION_UTTERANCE_ID+ 1] = "";
}
/**
@@ -1108,12 +1161,12 @@ public class TextToSpeech {
* @param listener
* The OnUtteranceCompletedListener
*
- * @return Code indicating success or failure. See TTS_ERROR and TTS_SUCCESS.
+ * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
*/
public int setOnUtteranceCompletedListener(
final OnUtteranceCompletedListener listener) {
synchronized (mStartLock) {
- int result = TTS_ERROR;
+ int result = ERROR;
if (!mStarted) {
return result;
}
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 3d10f171538c5..524f9418c00b8 100644
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -284,6 +284,12 @@ public class DateFormat {
*/
public static java.text.DateFormat getDateFormatForSetting(Context context,
String value) {
+ String format = getDateFormatStringForSetting(context, value);
+
+ return new java.text.SimpleDateFormat(format);
+ }
+
+ private static String getDateFormatStringForSetting(Context context, String value) {
if (value != null) {
int month = value.indexOf('M');
int day = value.indexOf('d');
@@ -291,7 +297,7 @@ public class DateFormat {
if (month >= 0 && day >= 0 && year >= 0) {
String template = context.getString(R.string.numeric_date_template);
- if (year < month) {
+ if (year < month && year < day) {
if (month < day) {
value = String.format(template, "yyyy", "MM", "dd");
} else {
@@ -311,7 +317,7 @@ public class DateFormat {
}
}
- return new java.text.SimpleDateFormat(value);
+ return value;
}
}
@@ -321,7 +327,7 @@ public class DateFormat {
* so that we get a four-digit year instead a two-digit year.
*/
value = context.getString(R.string.numeric_date_format);
- return new java.text.SimpleDateFormat(value);
+ return value;
}
/**
@@ -347,7 +353,11 @@ public class DateFormat {
/**
* Gets the current date format stored as a char array. The array will contain
* 3 elements ({@link #DATE}, {@link #MONTH}, and {@link #YEAR}) in the order
- * preferred by the user.
+ * specified by the user's format preference. Note that this order is
+ * only appropriate for all-numeric dates; spelled-out (MEDIUM and LONG)
+ * dates will generally contain other punctuation, spaces, or words,
+ * not just the day, month, and year, and not necessarily in the same
+ * order returned here.
*/
public static final char[] getDateFormatOrder(Context context) {
char[] order = new char[] {DATE, MONTH, YEAR};
@@ -380,22 +390,10 @@ public class DateFormat {
}
private static String getDateFormatString(Context context) {
- java.text.DateFormat df;
- df = java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT);
- if (df instanceof SimpleDateFormat) {
- return ((SimpleDateFormat) df).toPattern();
- }
-
String value = Settings.System.getString(context.getContentResolver(),
Settings.System.DATE_FORMAT);
- if (value == null || value.length() < 6) {
- /*
- * No need to localize -- this is an emergency fallback in case
- * the setting is missing, but it should always be set.
- */
- value = "MM-dd-yyyy";
- }
- return value;
+
+ return getDateFormatStringForSetting(context, value);
}
/**
diff --git a/core/java/android/text/style/ImageSpan.java b/core/java/android/text/style/ImageSpan.java
index 29c0c76ad1b11..86ef5f68bc7c0 100644
--- a/core/java/android/text/style/ImageSpan.java
+++ b/core/java/android/text/style/ImageSpan.java
@@ -33,17 +33,34 @@ public class ImageSpan extends DynamicDrawableSpan {
private Context mContext;
private String mSource;
+ /**
+ * @deprecated Use {@link #ImageSpan(Context, Bitmap)} instead.
+ */
public ImageSpan(Bitmap b) {
- this(b, ALIGN_BOTTOM);
+ this(null, b, ALIGN_BOTTOM);
+ }
+
+ /**
+ * @deprecated Use {@link #ImageSpan(Context, Bitmap, int) instead.
+ */
+ public ImageSpan(Bitmap b, int verticalAlignment) {
+ this(null, b, verticalAlignment);
+ }
+
+ public ImageSpan(Context context, Bitmap b) {
+ this(context, b, ALIGN_BOTTOM);
}
/**
* @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
* {@link DynamicDrawableSpan#ALIGN_BASELINE}.
*/
- public ImageSpan(Bitmap b, int verticalAlignment) {
+ public ImageSpan(Context context, Bitmap b, int verticalAlignment) {
super(verticalAlignment);
- mDrawable = new BitmapDrawable(b);
+ mContext = context;
+ mDrawable = context != null
+ ? new BitmapDrawable(context.getResources(), b)
+ : new BitmapDrawable(b);
int width = mDrawable.getIntrinsicWidth();
int height = mDrawable.getIntrinsicHeight();
mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0);
@@ -117,7 +134,7 @@ public class ImageSpan extends DynamicDrawableSpan {
InputStream is = mContext.getContentResolver().openInputStream(
mContentUri);
bitmap = BitmapFactory.decodeStream(is);
- drawable = new BitmapDrawable(bitmap);
+ drawable = new BitmapDrawable(mContext.getResources(), bitmap);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
is.close();
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 061f98a5a53ed..dd5a4401c4d51 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -79,6 +79,11 @@ public class DisplayMetrics {
* @see #DENSITY_DEFAULT
*/
public float density;
+ /**
+ * The screen density expressed as dots-per-inch. May be either
+ * {@link #DENSITY_LOW}, {@link #DENSITY_MEDIUM}, or {@link #DENSITY_HIGH}.
+ */
+ public int densityDpi;
/**
* A scaling factor for fonts displayed on the display. This is the same
* as {@link #density}, except that it may be adjusted in smaller
@@ -101,6 +106,7 @@ public class DisplayMetrics {
widthPixels = o.widthPixels;
heightPixels = o.heightPixels;
density = o.density;
+ densityDpi = o.densityDpi;
scaledDensity = o.scaledDensity;
xdpi = o.xdpi;
ydpi = o.ydpi;
@@ -110,6 +116,7 @@ public class DisplayMetrics {
widthPixels = 0;
heightPixels = 0;
density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
+ densityDpi = DENSITY_DEVICE;
scaledDensity = density;
xdpi = DENSITY_DEVICE;
ydpi = DENSITY_DEVICE;
@@ -186,9 +193,11 @@ public class DisplayMetrics {
heightPixels = defaultHeight;
}
}
+
if (compatibilityInfo.isScalingRequired()) {
float invertedRatio = compatibilityInfo.applicationInvertedScale;
density *= invertedRatio;
+ densityDpi = (int)((density*DisplayMetrics.DENSITY_DEFAULT)+.5f);
scaledDensity *= invertedRatio;
xdpi *= invertedRatio;
ydpi *= invertedRatio;
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 5551f64bcde34..b055d51c1b40a 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -94,6 +94,7 @@ public class Display
outMetrics.widthPixels = getWidth();
outMetrics.heightPixels = getHeight();
outMetrics.density = mDensity;
+ outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f);
outMetrics.scaledDensity= outMetrics.density;
outMetrics.xdpi = mDpiX;
outMetrics.ydpi = mDpiY;
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 83c30e1855f96..5100fff2b5938 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -16,6 +16,7 @@
package android.view;
+import android.content.res.CompatibilityInfo.Translator;
import android.graphics.*;
import android.os.Parcelable;
import android.os.Parcel;
@@ -106,8 +107,14 @@ public class Surface implements Parcelable {
public static final int SURFACE_HIDDEN = 0x01;
/** Freeze the surface. Equivalent to calling freeze() */
+ public static final int SURFACE_FROZEN = 0x02;
+
+ /**
+ * @deprecated use {@link #SURFACE_FROZEN} instead.
+ */
+ @Deprecated
public static final int SURACE_FROZEN = 0x02;
-
+
/** Enable dithering when compositing this surface */
public static final int SURFACE_DITHER = 0x04;
@@ -133,8 +140,12 @@ public class Surface implements Parcelable {
private Canvas mCanvas;
// The display metrics used to provide the pseudo canvas size for applications
- // running in compatibility mode. This is set to null for regular mode.
- private DisplayMetrics mDisplayMetrics;
+ // running in compatibility mode. This is set to null for non compatibility mode.
+ private DisplayMetrics mCompatibleDisplayMetrics;
+
+ // A matrix to scale the matrix set by application. This is set to null for
+ // non compatibility mode.
+ private Matrix mCompatibleMatrix;
/**
* Exception thrown when a surface couldn't be created or resized
@@ -172,23 +183,70 @@ public class Surface implements Parcelable {
* {@hide}
*/
public Surface() {
- mCanvas = new Canvas() {
- @Override
- public int getWidth() {
- return mDisplayMetrics == null ? super.getWidth() : mDisplayMetrics.widthPixels;
- }
- @Override
- public int getHeight() {
- return mDisplayMetrics == null ? super.getHeight() : mDisplayMetrics.heightPixels;
- }
- };
+ mCanvas = new CompatibleCanvas();
}
+ /**
+ * A Canvas class that can handle the compatibility mode. This does two things differently.
+ *
+ * - Returns the width and height of the target metrics, rather than native.
+ * For example, the canvas returns 320x480 even if an app is running in WVGA high density.
+ *
- Scales the matrix in setMatrix by the application scale, except if the matrix looks
+ * like obtained from getMatrix. This is a hack to handle the case that an application
+ * uses getMatrix to keep the original matrix, set matrix of its own, then set the original
+ * matrix back. There is no perfect solution that works for all cases, and there are a lot of
+ * cases that this model dose not work, but we hope this works for many apps.
+ *
+ */
+ private class CompatibleCanvas extends Canvas {
+ // A temp matrix to remember what an application obtained via {@link getMatrix}
+ private Matrix mOrigMatrix = null;
+
+ @Override
+ public int getWidth() {
+ return mCompatibleDisplayMetrics == null ?
+ super.getWidth() : mCompatibleDisplayMetrics.widthPixels;
+ }
+
+ @Override
+ public int getHeight() {
+ return mCompatibleDisplayMetrics == null ?
+ super.getHeight() : mCompatibleDisplayMetrics.heightPixels;
+ }
+
+ @Override
+ public void setMatrix(Matrix matrix) {
+ if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
+ // don't scale the matrix if it's not compatibility mode, or
+ // the matrix was obtained from getMatrix.
+ super.setMatrix(matrix);
+ } else {
+ Matrix m = new Matrix(mCompatibleMatrix);
+ m.preConcat(matrix);
+ super.setMatrix(m);
+ }
+ }
+
+ @Override
+ public void getMatrix(Matrix m) {
+ super.getMatrix(m);
+ if (mOrigMatrix == null) {
+ mOrigMatrix = new Matrix();
+ }
+ mOrigMatrix.set(m);
+ }
+ };
+
/**
* Sets the display metrics used to provide canva's width/height in comaptibility mode.
*/
- void setCompatibleDisplayMetrics(DisplayMetrics metrics) {
- mDisplayMetrics = metrics;
+ void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) {
+ mCompatibleDisplayMetrics = metrics;
+ if (translator != null) {
+ float appScale = translator.applicationScale;
+ mCompatibleMatrix = new Matrix();
+ mCompatibleMatrix.setScale(appScale, appScale);
+ }
}
/**
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 95bba97c75977..9cf7092491c4b 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -140,7 +140,7 @@ public class SurfaceView extends View {
int mType = -1;
final Rect mSurfaceFrame = new Rect();
private Translator mTranslator;
-
+
public SurfaceView(Context context) {
super(context);
setWillNotDraw(true);
@@ -252,23 +252,6 @@ public class SurfaceView extends View {
super.draw(canvas);
}
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- // SurfaceView uses pre-scaled size unless fixed size is requested. This hook
- // scales the event back to the pre-scaled coordinates for such surface.
- if (mScaled) {
- MotionEvent scaledBack = MotionEvent.obtain(event);
- mTranslator.translateEventInScreenToAppWindow(event);
- try {
- return super.dispatchTouchEvent(scaledBack);
- } finally {
- scaledBack.recycle();
- }
- } else {
- return super.dispatchTouchEvent(event);
- }
- }
-
@Override
protected void dispatchDraw(Canvas canvas) {
// if SKIP_DRAW is cleared, draw() has already punched a hole
@@ -291,8 +274,6 @@ public class SurfaceView extends View {
mWindowType = type;
}
- boolean mScaled = false;
-
private void updateWindow(boolean force) {
if (!mHaveFrame) {
return;
@@ -300,11 +281,9 @@ public class SurfaceView extends View {
ViewRoot viewRoot = (ViewRoot) getRootView().getParent();
mTranslator = viewRoot.mTranslator;
- float appScale = mTranslator == null ? 1.0f : mTranslator.applicationScale;
-
Resources res = getContext().getResources();
if (mTranslator != null || !res.getCompatibilityInfo().supportsScreen()) {
- mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics());
+ mSurface.setCompatibleDisplayMetrics(res.getDisplayMetrics(), mTranslator);
}
int myWidth = mRequestedWidth;
@@ -312,16 +291,6 @@ public class SurfaceView extends View {
int myHeight = mRequestedHeight;
if (myHeight <= 0) myHeight = getHeight();
- // Use original size if the app specified the size of the view,
- // and let the flinger to scale up.
- if (mRequestedWidth <= 0 && mTranslator != null) {
- myWidth = (int) (myWidth * appScale + 0.5f);
- myHeight = (int) (myHeight * appScale + 0.5f);
- mScaled = true;
- } else {
- mScaled = false;
- }
-
getLocationInWindow(mLocation);
final boolean creating = mWindow == null;
final boolean formatChanged = mFormat != mRequestedFormat;
@@ -394,10 +363,17 @@ public class SurfaceView extends View {
if (localLOGV) Log.i(TAG, "New surface: " + mSurface
+ ", vis=" + visible + ", frame=" + mWinFrame);
+
mSurfaceFrame.left = 0;
mSurfaceFrame.top = 0;
- mSurfaceFrame.right = mWinFrame.width();
- mSurfaceFrame.bottom = mWinFrame.height();
+ if (mTranslator == null) {
+ mSurfaceFrame.right = mWinFrame.width();
+ mSurfaceFrame.bottom = mWinFrame.height();
+ } else {
+ float appInvertedScale = mTranslator.applicationInvertedScale;
+ mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
+ mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
+ }
mSurfaceLock.unlock();
try {
@@ -641,10 +617,6 @@ public class SurfaceView extends View {
if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
if (c != null) {
mLastLockTime = SystemClock.uptimeMillis();
- if (mScaled) {
- mSaveCount = c.save();
- mTranslator.translateCanvas(c);
- }
return c;
}
@@ -667,9 +639,6 @@ public class SurfaceView extends View {
}
public void unlockCanvasAndPost(Canvas canvas) {
- if (mScaled) {
- canvas.restoreToCount(mSaveCount);
- }
mSurface.unlockCanvasAndPost(canvas);
mSurfaceLock.unlock();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ff8868bb0f2fb..7ed2712dc7503 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -46,6 +46,7 @@ import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.Config;
+import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.Pool;
@@ -5976,6 +5977,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
try {
bitmap = Bitmap.createBitmap(width, height, quality);
+ bitmap.setDensity(getResources().getDisplayMetrics().densityDpi);
if (autoScale) {
mDrawingCache = new SoftReference(bitmap);
} else {
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 46aea022912be..4baf61211feef 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -16,6 +16,7 @@
package android.view;
+import android.util.Config;
import android.util.Log;
import android.util.DisplayMetrics;
import android.content.res.Resources;
@@ -140,7 +141,9 @@ public class ViewDebug {
public static boolean consistencyCheckEnabled = false;
static {
- Debug.setFieldsOn(ViewDebug.class, true);
+ if (Config.DEBUG) {
+ Debug.setFieldsOn(ViewDebug.class, true);
+ }
}
/**
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 2f92b32e53f1c..f7cb06b226547 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -21,7 +21,6 @@ import com.android.internal.view.IInputMethodSession;
import android.graphics.Canvas;
import android.graphics.PixelFormat;
-import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
@@ -187,7 +186,7 @@ public final class ViewRoot extends Handler implements ViewParent,
*/
AudioManager mAudioManager;
- private final float mDensity;
+ private final int mDensity;
public ViewRoot(Context context) {
super();
@@ -229,7 +228,7 @@ public final class ViewRoot extends Handler implements ViewParent,
mAdded = false;
mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, this);
mViewConfiguration = ViewConfiguration.get(context);
- mDensity = context.getResources().getDisplayMetrics().density;
+ mDensity = context.getResources().getDisplayMetrics().densityDpi;
}
@Override
@@ -389,10 +388,11 @@ public final class ViewRoot extends Handler implements ViewParent,
attrs = mWindowAttributes;
Resources resources = mView.getContext().getResources();
CompatibilityInfo compatibilityInfo = resources.getCompatibilityInfo();
- mTranslator = compatibilityInfo.getTranslator(attrs);
+ mTranslator = compatibilityInfo.getTranslator();
if (mTranslator != null || !compatibilityInfo.supportsScreen()) {
- mSurface.setCompatibleDisplayMetrics(resources.getDisplayMetrics());
+ mSurface.setCompatibleDisplayMetrics(resources.getDisplayMetrics(),
+ mTranslator);
}
boolean restore = false;
@@ -1212,6 +1212,8 @@ public final class ViewRoot extends Handler implements ViewParent,
if (mTranslator != null) {
mTranslator.translateCanvas(canvas);
}
+ canvas.setScreenDensity(scalingRequired
+ ? DisplayMetrics.DENSITY_DEVICE : 0);
mView.draw(canvas);
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
@@ -1269,7 +1271,7 @@ public final class ViewRoot extends Handler implements ViewParent,
}
// TODO: Do this in native
- canvas.setDensityScale(mDensity);
+ canvas.setDensity(mDensity);
} catch (Surface.OutOfResourcesException e) {
Log.e("ViewRoot", "OutOfResourcesException locking surface", e);
// TODO: we should ask the window manager to do something!
@@ -1320,6 +1322,8 @@ public final class ViewRoot extends Handler implements ViewParent,
if (mTranslator != null) {
mTranslator.translateCanvas(canvas);
}
+ canvas.setScreenDensity(scalingRequired
+ ? DisplayMetrics.DENSITY_DEVICE : 0);
mView.draw(canvas);
} finally {
mAttachInfo.mIgnoreDirtyState = false;
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 474fa82db2d74..9ca2909483115 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -31,7 +31,6 @@ import android.os.Message;
import android.security.CertTool;
import android.util.Log;
import android.webkit.CacheManager.CacheResult;
-import android.widget.Toast;
import com.android.internal.R;
@@ -77,6 +76,7 @@ class LoadListener extends Handler implements EventHandler {
static {
sCertificateMimeTypeMap = new HashSet();
sCertificateMimeTypeMap.add("application/x-x509-ca-cert");
+ sCertificateMimeTypeMap.add("application/x-x509-user-cert");
sCertificateMimeTypeMap.add("application/x-pkcs12");
}
@@ -1016,8 +1016,6 @@ class LoadListener extends Handler implements EventHandler {
mDataBuilder.releaseChunk(c);
}
CertTool.getInstance().addCertificate(cert, mContext);
- Toast.makeText(mContext, R.string.certificateSaved,
- Toast.LENGTH_SHORT).show();
mBrowserFrame.stopLoading();
return;
}
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index fdbc692bf271d..9fdde6192e672 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -357,6 +357,7 @@ public /* package */ class MimeTypeMap {
sMimeTypeMap.loadEntry(
"application/x-webarchive", "webarchive", false); // added
sMimeTypeMap.loadEntry("application/x-x509-ca-cert", "crt", false);
+ sMimeTypeMap.loadEntry("application/x-x509-user-cert", "crt", false);
sMimeTypeMap.loadEntry("application/x-xcf", "xcf", false);
sMimeTypeMap.loadEntry("application/x-xfig", "fig", false);
sMimeTypeMap.loadEntry("audio/basic", "snd", false);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index fcf946f7d12a7..69364350690b1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -545,7 +545,6 @@ public class WebView extends AbsoluteLayout
private ZoomButtonsController mZoomButtonsController;
private ImageView mZoomOverviewButton;
- private ImageView mZoomFitPageButton;
// These keep track of the center point of the zoom. They are used to
// determine the point around which we should zoom.
@@ -617,6 +616,16 @@ public class WebView extends AbsoluteLayout
// Create the buttons controller
mZoomButtonsController = new ZoomButtonsController(this);
mZoomButtonsController.setOnZoomListener(mZoomListener);
+ // ZoomButtonsController positions the buttons at the bottom, but in
+ // the middle. Change their layout parameters so they appear on the
+ // right.
+ View controls = mZoomButtonsController.getZoomControls();
+ ViewGroup.LayoutParams params = controls.getLayoutParams();
+ if (params instanceof FrameLayout.LayoutParams) {
+ FrameLayout.LayoutParams frameParams = (FrameLayout.LayoutParams)
+ params;
+ frameParams.gravity = Gravity.RIGHT;
+ }
// Create the accessory buttons
LayoutInflater inflater =
@@ -636,15 +645,6 @@ public class WebView extends AbsoluteLayout
}
}
});
- mZoomFitPageButton =
- (ImageView) container.findViewById(com.android.internal.R.id.zoom_fit_page);
- mZoomFitPageButton.setOnClickListener(
- new View.OnClickListener() {
- public void onClick(View v) {
- zoomWithPreview(mDefaultScale);
- updateZoomButtonsEnabled();
- }
- });
}
private void updateZoomButtonsEnabled() {
@@ -654,17 +654,14 @@ public class WebView extends AbsoluteLayout
// Hide the zoom in and out buttons, as well as the fit to page
// button, if the page cannot zoom
mZoomButtonsController.getZoomControls().setVisibility(View.GONE);
- mZoomFitPageButton.setVisibility(View.GONE);
} else {
// Bring back the hidden zoom controls.
mZoomButtonsController.getZoomControls()
.setVisibility(View.VISIBLE);
- mZoomFitPageButton.setVisibility(View.VISIBLE);
// Set each one individually, as a page may be able to zoom in
// or out.
mZoomButtonsController.setZoomInEnabled(canZoomIn);
mZoomButtonsController.setZoomOutEnabled(canZoomOut);
- mZoomFitPageButton.setEnabled(mActualScale != mDefaultScale);
}
mZoomOverviewButton.setVisibility(canZoomScrollOut() ? View.VISIBLE:
View.GONE);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 777beed7ed138..eea97dc2dbd1a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1535,6 +1535,9 @@ public abstract class AbsListView extends AdapterView implements Te
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
+ // Dismiss the popup in case onSaveInstanceState() was not invoked
+ dismissPopup();
+
final ViewTreeObserver treeObserver = getViewTreeObserver();
if (treeObserver != null) {
treeObserver.removeOnTouchModeChangeListener(this);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 4bc00de33e815..456f8ed845a42 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -104,6 +104,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
private View mDropDownAnchorView; // view is retrieved lazily from id once needed
private int mDropDownWidth;
private int mDropDownHeight;
+ private final Rect mTempRect = new Rect();
private Drawable mDropDownListHighlight;
@@ -116,6 +117,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
private boolean mDropDownAlwaysVisible = false;
private boolean mDropDownDismissedOnCompletion = true;
+
+ private boolean mForceIgnoreOutsideTouch = false;
private int mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN;
private boolean mOpenBefore;
@@ -205,11 +208,9 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
* Private hook into the on click event, dispatched from {@link PassThroughClickListener}
*/
private void onClickImpl() {
- // if drop down should always visible, bring it back in front of the soft
- // keyboard when the user touches the text field
- if (mDropDownAlwaysVisible
- && mPopup.isShowing()
- && mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED) {
+ // If the dropdown is showing, bring it back in front of the soft
+ // keyboard when the user touches the text field.
+ if (mPopup.isShowing() && isInputMethodNotNeeded()) {
ensureImeVisible();
}
}
@@ -1101,6 +1102,13 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
showDropDown();
}
+ /**
+ * @hide internal used only here and SearchDialog
+ */
+ public boolean isInputMethodNotNeeded() {
+ return mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
+ }
+
/**
* Displays the drop down on screen.
*/
@@ -1110,7 +1118,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
int widthSpec = 0;
int heightSpec = 0;
- boolean noInputMethod = mPopup.getInputMethodMode() == PopupWindow.INPUT_METHOD_NOT_NEEDED;
+ boolean noInputMethod = isInputMethodNotNeeded();
if (mPopup.isShowing()) {
if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) {
@@ -1143,6 +1151,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
heightSpec = mDropDownHeight;
}
+ mPopup.setOutsideTouchable(mForceIgnoreOutsideTouch ? false : !mDropDownAlwaysVisible);
+
mPopup.update(getDropDownAnchorView(), mDropDownHorizontalOffset,
mDropDownVerticalOffset, widthSpec, heightSpec);
} else {
@@ -1171,7 +1181,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
// use outside touchable to dismiss drop down when touching outside of it, so
// only set this if the dropdown is not always visible
- mPopup.setOutsideTouchable(!mDropDownAlwaysVisible);
+ mPopup.setOutsideTouchable(mForceIgnoreOutsideTouch ? false : !mDropDownAlwaysVisible);
mPopup.setTouchInterceptor(new PopupTouchIntercepter());
mPopup.showAsDropDown(getDropDownAnchorView(),
mDropDownHorizontalOffset, mDropDownVerticalOffset);
@@ -1180,6 +1190,17 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
post(mHideSelector);
}
}
+
+ /**
+ * Forces outside touches to be ignored. Normally if {@link #isDropDownAlwaysVisible()} is
+ * false, we allow outside touch to dismiss the dropdown. If this is set to true, then we
+ * ignore outside touch even when the drop down is not set to always visible.
+ *
+ * @hide used only by SearchDialog
+ */
+ public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) {
+ mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch;
+ }
/**
* Builds the popup window's content and returns the height the popup
@@ -1303,7 +1324,15 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
getDropDownAnchorView(), mDropDownVerticalOffset, ignoreBottomDecorations);
if (mDropDownAlwaysVisible) {
- return maxHeight;
+ // getMaxAvailableHeight() subtracts the padding, so we put it back,
+ // to get the available height for the whole window
+ int padding = 0;
+ Drawable background = mPopup.getBackground();
+ if (background != null) {
+ background.getPadding(mTempRect);
+ padding = mTempRect.top + mTempRect.bottom;
+ }
+ return maxHeight + padding;
}
return mDropDownList.measureHeightOfChildren(MeasureSpec.UNSPECIFIED,
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 3b9f1de4c66c9..5e76cc3a28af9 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -31,6 +31,7 @@ import com.android.internal.widget.NumberPicker;
import com.android.internal.widget.NumberPicker.OnChangedListener;
import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
@@ -101,7 +102,8 @@ public class DatePicker extends FrameLayout {
mMonthPicker = (NumberPicker) findViewById(R.id.month);
mMonthPicker.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
DateFormatSymbols dfs = new DateFormatSymbols();
- mMonthPicker.setRange(1, 12, dfs.getShortMonths());
+ String[] months = dfs.getShortMonths();
+ mMonthPicker.setRange(1, 12, months);
mMonthPicker.setSpeed(200);
mMonthPicker.setOnChangeListener(new OnChangedListener() {
public void onChanged(NumberPicker picker, int oldVal, int newVal) {
@@ -146,7 +148,7 @@ public class DatePicker extends FrameLayout {
init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), null);
// re-order the number pickers to match the current date format
- reorderPickers();
+ reorderPickers(months);
if (!isEnabled()) {
setEnabled(false);
@@ -161,29 +163,69 @@ public class DatePicker extends FrameLayout {
mYearPicker.setEnabled(enabled);
}
- private void reorderPickers() {
- char[] order = DateFormat.getDateFormatOrder(mContext);
-
- /* Default order is month, date, year so if that's the order then
- * do nothing.
+ private void reorderPickers(String[] months) {
+ java.text.DateFormat format;
+ String order;
+
+ /*
+ * If the user is in a locale where the medium date format is
+ * still numeric (Japanese and Czech, for example), respect
+ * the date format order setting. Otherwise, use the order
+ * that the locale says is appropriate for a spelled-out date.
*/
- if ((order[0] == DateFormat.MONTH) && (order[1] == DateFormat.DATE)) {
- return;
+
+ if (months[0].startsWith("1")) {
+ format = DateFormat.getDateFormat(getContext());
+ } else {
+ format = DateFormat.getMediumDateFormat(getContext());
}
-
+
+ if (format instanceof SimpleDateFormat) {
+ order = ((SimpleDateFormat) format).toPattern();
+ } else {
+ // Shouldn't happen, but just in case.
+ order = new String(DateFormat.getDateFormatOrder(getContext()));
+ }
+
/* Remove the 3 pickers from their parent and then add them back in the
* required order.
*/
LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
parent.removeAllViews();
- for (char c : order) {
- if (c == DateFormat.DATE) {
- parent.addView(mDayPicker);
- } else if (c == DateFormat.MONTH) {
- parent.addView(mMonthPicker);
- } else {
- parent.addView (mYearPicker);
+
+ boolean quoted = false;
+ boolean didDay = false, didMonth = false, didYear = false;
+
+ for (int i = 0; i < order.length(); i++) {
+ char c = order.charAt(i);
+
+ if (c == '\'') {
+ quoted = !quoted;
}
+
+ if (!quoted) {
+ if (c == DateFormat.DATE && !didDay) {
+ parent.addView(mDayPicker);
+ didDay = true;
+ } else if ((c == DateFormat.MONTH || c == 'L') && !didMonth) {
+ parent.addView(mMonthPicker);
+ didMonth = true;
+ } else if (c == DateFormat.YEAR && !didYear) {
+ parent.addView (mYearPicker);
+ didYear = true;
+ }
+ }
+ }
+
+ // Shouldn't happen, but just in case.
+ if (!didMonth) {
+ parent.addView(mMonthPicker);
+ }
+ if (!didDay) {
+ parent.addView(mDayPicker);
+ }
+ if (!didYear) {
+ parent.addView(mYearPicker);
}
}
@@ -192,6 +234,7 @@ public class DatePicker extends FrameLayout {
mMonth = monthOfYear;
mDay = dayOfMonth;
updateSpinners();
+ reorderPickers(new DateFormatSymbols().getShortMonths());
}
private static class SavedState extends BaseSavedState {
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 27967742a135d..b8f0a7e16f73b 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -317,7 +317,7 @@ public class ImageView extends View {
public void setImageBitmap(Bitmap bm) {
// if this is used frequently, may handle bitmaps explicitly
// to reduce the intermediate drawable object
- setImageDrawable(new BitmapDrawable(bm));
+ setImageDrawable(new BitmapDrawable(mContext.getResources(), bm));
}
public void setImageState(int[] state, boolean merge) {
@@ -463,6 +463,7 @@ public class ImageView extends View {
if (matrix == null && !mMatrix.isIdentity() ||
matrix != null && !mMatrix.equals(matrix)) {
mMatrix.set(matrix);
+ configureBounds();
invalidate();
}
}
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 24c0e2a4a2d9b..e19a93dc64ea5 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -432,7 +432,7 @@ public class RelativeLayout extends ViewGroup {
width = resolveSize(width, widthMeasureSpec);
if (offsetHorizontalAxis) {
- for (int i = 0; i < count; i++) {
+ for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
LayoutParams params = (LayoutParams) child.getLayoutParams();
@@ -486,10 +486,14 @@ public class RelativeLayout extends ViewGroup {
View child = getChildAt(i);
if (child.getVisibility() != GONE && child != ignore) {
LayoutParams params = (LayoutParams) child.getLayoutParams();
- params.mLeft += horizontalOffset;
- params.mRight += horizontalOffset;
- params.mTop += verticalOffset;
- params.mBottom += verticalOffset;
+ if (horizontalGravity) {
+ params.mLeft += horizontalOffset;
+ params.mRight += horizontalOffset;
+ }
+ if (verticalGravity) {
+ params.mTop += verticalOffset;
+ params.mBottom += verticalOffset;
+ }
}
}
}
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index a26bfa23eff81..47f5c6c264da2 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -277,7 +277,7 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
if (child.getLayoutParams() == null) {
final LinearLayout.LayoutParams lp = new LayoutParams(
0,
- ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+ ViewGroup.LayoutParams.FILL_PARENT, 1.0f);
lp.setMargins(0, 0, 0, 0);
child.setLayoutParams(lp);
}
@@ -289,10 +289,10 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
// If we have dividers between the tabs and we already have at least one
// tab, then add a divider before adding the next tab.
if (mDividerDrawable != null && getTabCount() > 0) {
- View divider = new View(mContext);
+ ImageView divider = new ImageView(mContext);
final LinearLayout.LayoutParams lp = new LayoutParams(
mDividerDrawable.getIntrinsicWidth(),
- mDividerDrawable.getIntrinsicHeight());
+ LayoutParams.FILL_PARENT);
lp.setMargins(0, 0, 0, 0);
divider.setLayoutParams(lp);
divider.setBackgroundDrawable(mDividerDrawable);
diff --git a/core/java/com/android/internal/widget/EditStyledText.java b/core/java/com/android/internal/widget/EditStyledText.java
index f0ad7b3bb3b51..82197c0151f21 100644
--- a/core/java/com/android/internal/widget/EditStyledText.java
+++ b/core/java/com/android/internal/widget/EditStyledText.java
@@ -1242,7 +1242,8 @@ public class EditStyledText extends EditText {
try {
InputStream is = mEST.getContext().getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(is);
- Drawable drawable = new BitmapDrawable(bitmap);
+ Drawable drawable = new BitmapDrawable(
+ getContext().getResources(), bitmap);
drawable.setBounds(0, 0,
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight());
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 93d68cbfe0aea..1c2e055cfcf93 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -462,17 +462,27 @@ public:
static void drawBitmap__BitmapFFPaint(JNIEnv* env, jobject jcanvas,
SkCanvas* canvas, SkBitmap* bitmap,
jfloat left, jfloat top,
- SkPaint* paint,
- jboolean autoScale, jfloat densityScale) {
+ SkPaint* paint, jint canvasDensity,
+ jint screenDensity, jint bitmapDensity) {
SkScalar left_ = SkFloatToScalar(left);
SkScalar top_ = SkFloatToScalar(top);
- if (!autoScale || densityScale <= 0.0f) {
- canvas->drawBitmap(*bitmap, left_, top_, paint);
+ if (canvasDensity == bitmapDensity || canvasDensity == 0
+ || bitmapDensity == 0) {
+ if (screenDensity != 0 && screenDensity != bitmapDensity) {
+ SkPaint filteredPaint;
+ if (paint) {
+ filteredPaint = *paint;
+ }
+ filteredPaint.setFilterBitmap(true);
+ canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
+ } else {
+ canvas->drawBitmap(*bitmap, left_, top_, paint);
+ }
} else {
canvas->save();
- SkScalar canvasScale = GraphicsJNI::getCanvasDensityScale(env, jcanvas);
- SkScalar scale = canvasScale / SkFloatToScalar(densityScale);
+ SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
+ canvas->translate(left_, top_);
canvas->scale(scale, scale);
SkPaint filteredPaint;
@@ -481,37 +491,52 @@ public:
}
filteredPaint.setFilterBitmap(true);
- canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
+ canvas->drawBitmap(*bitmap, 0, 0, &filteredPaint);
canvas->restore();
}
}
static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
- jobject srcIRect, const SkRect& dst, SkPaint* paint) {
+ jobject srcIRect, const SkRect& dst, SkPaint* paint,
+ jint screenDensity, jint bitmapDensity) {
SkIRect src, *srcPtr = NULL;
if (NULL != srcIRect) {
GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
srcPtr = &src;
}
- canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
+
+ if (screenDensity != 0 && screenDensity != bitmapDensity) {
+ SkPaint filteredPaint;
+ if (paint) {
+ filteredPaint = *paint;
+ }
+ filteredPaint.setFilterBitmap(true);
+ canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
+ } else {
+ canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
+ }
}
static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
SkBitmap* bitmap, jobject srcIRect,
- jobject dstRectF, SkPaint* paint) {
+ jobject dstRectF, SkPaint* paint,
+ jint screenDensity, jint bitmapDensity) {
SkRect dst;
GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
- doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
+ doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
+ screenDensity, bitmapDensity);
}
static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
SkBitmap* bitmap, jobject srcIRect,
- jobject dstRect, SkPaint* paint) {
+ jobject dstRect, SkPaint* paint,
+ jint screenDensity, jint bitmapDensity) {
SkRect dst;
GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
- doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
+ doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
+ screenDensity, bitmapDensity);
}
static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas,
@@ -905,11 +930,11 @@ static JNINativeMethod gCanvasMethods[] = {
{"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
(void*) SkCanvasGlue::drawRoundRect},
{"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
- {"native_drawBitmap","(IIFFIZF)V",
+ {"native_drawBitmap","(IIFFIIII)V",
(void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
- {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;I)V",
+ {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
(void*) SkCanvasGlue::drawBitmapRF},
- {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;I)V",
+ {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
(void*) SkCanvasGlue::drawBitmapRR},
{"native_drawBitmap", "(I[IIIFFIIZI)V",
(void*)SkCanvasGlue::drawBitmapArray},
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 6e159a8853d59..ca1cb7d652019 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -163,7 +163,6 @@ static jfieldID gBitmapConfig_nativeInstanceID;
static jclass gCanvas_class;
static jfieldID gCanvas_nativeInstanceID;
-static jfieldID gCanvas_densityScaleID;
static jclass gPaint_class;
static jfieldID gPaint_nativeInstanceID;
@@ -320,13 +319,6 @@ SkCanvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) {
return c;
}
-SkScalar GraphicsJNI::getCanvasDensityScale(JNIEnv* env, jobject canvas) {
- SkASSERT(env);
- SkASSERT(canvas);
- SkASSERT(env->IsInstanceOf(canvas, gCanvas_class));
- return SkFloatToScalar(env->GetFloatField(canvas, gCanvas_densityScaleID));
-}
-
SkPaint* GraphicsJNI::getNativePaint(JNIEnv* env, jobject paint) {
SkASSERT(env);
SkASSERT(paint);
@@ -557,7 +549,6 @@ int register_android_graphics_Graphics(JNIEnv* env)
gCanvas_class = make_globalref(env, "android/graphics/Canvas");
gCanvas_nativeInstanceID = getFieldIDCheck(env, gCanvas_class, "mNativeCanvas", "I");
- gCanvas_densityScaleID = getFieldIDCheck(env, gCanvas_class, "mDensityScale", "F");
gPaint_class = make_globalref(env, "android/graphics/Paint");
gPaint_nativeInstanceID = getFieldIDCheck(env, gPaint_class, "mNativePaint", "I");
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 16925e41ab4f3..f8b60a805e1ba 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -38,7 +38,6 @@ public:
static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
static SkPicture* getNativePicture(JNIEnv*, jobject picture);
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
- static SkScalar getCanvasDensityScale(JNIEnv*, jobject canvas);
/** Return the corresponding native config from the java Config enum,
or kNo_Config if the java object is null.
diff --git a/core/jni/android/graphics/MaskFilter.cpp b/core/jni/android/graphics/MaskFilter.cpp
index e6048cdcea6a2..0f8dff1210551 100644
--- a/core/jni/android/graphics/MaskFilter.cpp
+++ b/core/jni/android/graphics/MaskFilter.cpp
@@ -4,15 +4,23 @@
#include
+static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
+ if (NULL == ptr) {
+ doThrowIAE(env);
+ }
+}
+
class SkMaskFilterGlue {
public:
static void destructor(JNIEnv* env, jobject, SkMaskFilter* filter) {
- SkASSERT(filter);
- filter->unref();
+ filter->safeUnref();
}
static SkMaskFilter* createBlur(JNIEnv* env, jobject, float radius, int blurStyle) {
- return SkBlurMaskFilter::Create(SkFloatToScalar(radius), (SkBlurMaskFilter::BlurStyle)blurStyle);
+ SkMaskFilter* filter = SkBlurMaskFilter::Create(SkFloatToScalar(radius),
+ (SkBlurMaskFilter::BlurStyle)blurStyle);
+ ThrowIAE_IfNull(env, filter);
+ return filter;
}
static SkMaskFilter* createEmboss(JNIEnv* env, jobject, jfloatArray dirArray, float ambient, float specular, float radius) {
@@ -24,8 +32,12 @@ public:
direction[i] = SkFloatToScalar(values[i]);
}
- return SkBlurMaskFilter::CreateEmboss(direction, SkFloatToScalar(ambient),
- SkFloatToScalar(specular), SkFloatToScalar(radius));
+ SkMaskFilter* filter = SkBlurMaskFilter::CreateEmboss(direction,
+ SkFloatToScalar(ambient),
+ SkFloatToScalar(specular),
+ SkFloatToScalar(radius));
+ ThrowIAE_IfNull(env, filter);
+ return filter;
}
};
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index b11edfc07436e..fd5271e4c18b0 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -1,5 +1,6 @@
#include
+#include "SkCanvas.h"
#include "SkRegion.h"
#include "GraphicsJNI.h"
@@ -45,7 +46,8 @@ public:
}
static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds,
- const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint)
+ const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
+ jint destDensity, jint srcDensity)
{
size_t chunkSize = env->GetArrayLength(chunkObj);
void* storage = alloca(chunkSize);
@@ -56,13 +58,32 @@ public:
Res_png_9patch* chunk = static_cast(storage);
assert(chunkSize == chunk->serializedSize());
// this relies on deserialization being done in place
- Res_png_9patch::deserialize(chunk);
- NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
+ Res_png_9patch::deserialize(chunk);
+
+ if (destDensity == srcDensity || destDensity == 0
+ || srcDensity == 0) {
+ NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
+ } else {
+ canvas->save();
+
+ SkScalar scale = SkFloatToScalar(destDensity / (float)srcDensity);
+ canvas->translate(bounds.fLeft, bounds.fTop);
+ canvas->scale(scale, scale);
+
+ bounds.fRight = SkScalarDiv(bounds.fRight-bounds.fLeft, scale);
+ bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale);
+ bounds.fLeft = bounds.fTop = 0;
+
+ NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL);
+
+ canvas->restore();
+ }
}
}
static void drawF(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRectF,
- const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint)
+ const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
+ jint destDensity, jint srcDensity)
{
SkASSERT(canvas);
SkASSERT(boundsRectF);
@@ -73,11 +94,12 @@ public:
SkRect bounds;
GraphicsJNI::jrectf_to_rect(env, boundsRectF, &bounds);
- draw(env, canvas, bounds, bitmap, chunkObj, paint);
+ draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity);
}
static void drawI(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRect,
- const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint)
+ const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint,
+ jint destDensity, jint srcDensity)
{
SkASSERT(canvas);
SkASSERT(boundsRect);
@@ -87,7 +109,7 @@ public:
SkRect bounds;
GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds);
- draw(env, canvas, bounds, bitmap, chunkObj, paint);
+ draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity);
}
static jint getTransparentRegion(JNIEnv* env, jobject,
@@ -126,8 +148,8 @@ public:
static JNINativeMethod gNinePatchMethods[] = {
{ "isNinePatchChunk", "([B)Z", (void*)SkNinePatchGlue::isNinePatchChunk },
{ "validateNinePatchChunk", "(I[B)V", (void*)SkNinePatchGlue::validateNinePatchChunk },
- { "nativeDraw", "(ILandroid/graphics/RectF;I[BI)V", (void*)SkNinePatchGlue::drawF },
- { "nativeDraw", "(ILandroid/graphics/Rect;I[BI)V", (void*)SkNinePatchGlue::drawI },
+ { "nativeDraw", "(ILandroid/graphics/RectF;I[BIII)V", (void*)SkNinePatchGlue::drawF },
+ { "nativeDraw", "(ILandroid/graphics/Rect;I[BIII)V", (void*)SkNinePatchGlue::drawI },
{ "nativeGetTransparentRegion", "(I[BLandroid/graphics/Rect;)I",
(void*)SkNinePatchGlue::getTransparentRegion }
};
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index b28eb900242cd..b09c62b7d2b3e 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -43,25 +43,23 @@ static int Color_HSVToColor(JNIEnv* env, jobject, int alpha, jfloatArray hsvArra
static void Shader_destructor(JNIEnv* env, jobject, SkShader* shader)
{
- SkASSERT(shader != NULL);
- shader->unref();
+ shader->safeUnref();
}
static bool Shader_getLocalMatrix(JNIEnv* env, jobject, const SkShader* shader, SkMatrix* matrix)
{
- SkASSERT(shader != NULL);
- return shader->getLocalMatrix(matrix);
+ return shader ? shader->getLocalMatrix(matrix) : false;
}
static void Shader_setLocalMatrix(JNIEnv* env, jobject, SkShader* shader, const SkMatrix* matrix)
{
- SkASSERT(shader != NULL);
-
- if (NULL == matrix) {
- shader->resetLocalMatrix();
- }
- else {
- shader->setLocalMatrix(*matrix);
+ if (shader) {
+ if (NULL == matrix) {
+ shader->resetLocalMatrix();
+ }
+ else {
+ shader->setLocalMatrix(*matrix);
+ }
}
}
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 59f40670c41bb..66b250670fee3 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -74,12 +74,13 @@ static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
}
enum {
- STYLE_NUM_ENTRIES = 5,
+ STYLE_NUM_ENTRIES = 6,
STYLE_TYPE = 0,
STYLE_DATA = 1,
STYLE_ASSET_COOKIE = 2,
STYLE_RESOURCE_ID = 3,
- STYLE_CHANGING_CONFIGURATIONS = 4
+ STYLE_CHANGING_CONFIGURATIONS = 4,
+ STYLE_DENSITY = 5
};
static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
@@ -896,6 +897,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
ResTable::Theme* theme = (ResTable::Theme*)themeToken;
const ResTable& res = theme->getResTable();
ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
+ ResTable_config config;
Res_value value;
const jsize NI = env->GetArrayLength(attrs);
@@ -995,6 +997,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
value.dataType = Res_value::TYPE_NULL;
value.data = 0;
typeSetFlags = 0;
+ config.density = 0;
// Skip through XML attributes until the end or the next possible match.
while (ix < NX && curIdent > curXmlAttr) {
@@ -1042,7 +1045,8 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
if (value.dataType != Res_value::TYPE_NULL) {
// Take care of resolving the found resource to its final value.
//printf("Resolving attribute reference\n");
- ssize_t newBlock = theme->resolveAttributeReference(&value, block, &resid, &typeSetFlags);
+ ssize_t newBlock = theme->resolveAttributeReference(&value, block,
+ &resid, &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
} else {
// If we still don't have a value for this attribute, try to find
@@ -1051,7 +1055,8 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
ssize_t newBlock = theme->getAttribute(curIdent, &value, &typeSetFlags);
if (newBlock >= 0) {
//printf("Resolving resource reference\n");
- newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+ newBlock = res.resolveReference(&value, block, &resid,
+ &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
}
}
@@ -1070,6 +1075,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
dest[STYLE_RESOURCE_ID] = resid;
dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+ dest[STYLE_DENSITY] = config.density;
if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
indicesIdx++;
@@ -1108,6 +1114,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
}
const ResTable& res(am->getResources());
ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
+ ResTable_config config;
Res_value value;
const jsize NI = env->GetArrayLength(attrs);
@@ -1160,6 +1167,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
value.dataType = Res_value::TYPE_NULL;
value.data = 0;
typeSetFlags = 0;
+ config.density = 0;
// Skip through XML attributes until the end or the next possible match.
while (ix < NX && curIdent > curXmlAttr) {
@@ -1179,7 +1187,8 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
if (value.dataType != Res_value::TYPE_NULL) {
// Take care of resolving the found resource to its final value.
//printf("Resolving attribute reference\n");
- ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+ ssize_t newBlock = res.resolveReference(&value, block, &resid,
+ &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
}
@@ -1197,6 +1206,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
dest[STYLE_RESOURCE_ID] = resid;
dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+ dest[STYLE_DENSITY] = config.density;
if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
indicesIdx++;
@@ -1250,6 +1260,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
return JNI_FALSE;
}
const ResTable& res(am->getResources());
+ ResTable_config config;
Res_value value;
ssize_t block;
@@ -1276,13 +1287,15 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
while (i < NV && arrayEnt < endArrayEnt) {
block = arrayEnt->stringBlock;
typeSetFlags = arrayTypeSetFlags;
+ config.density = 0;
value = arrayEnt->map.value;
uint32_t resid = 0;
if (value.dataType != Res_value::TYPE_NULL) {
// Take care of resolving the found resource to its final value.
//printf("Resolving attribute reference\n");
- ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
+ ssize_t newBlock = res.resolveReference(&value, block, &resid,
+ &typeSetFlags, &config);
if (newBlock >= 0) block = newBlock;
}
@@ -1299,6 +1312,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
dest[STYLE_ASSET_COOKIE] = (jint)res.getTableCookie(block);
dest[STYLE_RESOURCE_ID] = resid;
dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
+ dest[STYLE_DENSITY] = config.density;
dest += STYLE_NUM_ENTRIES;
i+= STYLE_NUM_ENTRIES;
arrayEnt++;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 00d9cf6152e49..4558660899c83 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -209,7 +209,7 @@
-
-
+ to put the higher-level system there into a shutdown state.
+ @hide -->
+ critical UI such as the home screen.
+ @hide -->
-
-
diff --git a/core/res/res/values-bg-rBG/donottranslate-cldr.xml b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
index b8b50cccdd789..527cdb9a7db50 100644
--- a/core/res/res/values-bg-rBG/donottranslate-cldr.xml
+++ b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
@@ -111,7 +111,7 @@
%-e %b
%b
%b %Y
- %1$s - %2$s
+ %1$s-%2$s
%2$s - %5$s
%3$s.%2$s - %8$s.%7$s
%3$s.%2$s, %1$s - %8$s.%7$s, %6$s
diff --git a/core/res/res/values-cs-rCZ/donottranslate-cldr.xml b/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
deleted file mode 100644
index 41f5dea81f009..0000000000000
--- a/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
+++ /dev/null
@@ -1,147 +0,0 @@
-
-
- leden
- únor
- březen
- duben
- květen
- červen
- červenec
- srpen
- září
- říjen
- listopad
- prosinec
-
- ledna
- února
- března
- dubna
- května
- června
- července
- srpna
- září
- října
- listopadu
- prosince
-
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
-
- l
- ú
- b
- d
- k
- č
- č
- s
- z
- ř
- l
- p
-
- neděle
- pondělí
- úterý
- středa
- čtvrtek
- pátek
- sobota
-
- ne
- po
- út
- st
- čt
- pá
- so
-
- ne
- po
- út
- st
- čt
- pá
- so
-
- N
- P
- Ú
- S
- Č
- P
- S
-
- dop.
- odp.
- Včera
- Dnes
- Zítra
-
- %-k:%M
- %-l:%M %p
- %-l:%M %^p
- h:mm a
- H:mm
- %-e.%-m.%Y
- d.M.yyyy
- "%s.%s.%s"
- %-e. %B %Y
- %-k:%M:%S
- %-k:%M:%S %-e.%-m.%Y
- %2$s %1$s
- %1$s %3$s
- %-e.%-m.%Y
- %-e. %B
- %-B
- %-B %Y
- %-e.%-m
- %-B
- %-B %Y
- %1$s - %2$s
- %2$s - %5$s
- %3$s.%2$s. - %8$s.%7$s.
- %1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.
- %3$s.%2$s.%4$s - %8$s.%7$s.%9$s
- %1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s
- %5$s %1$s, %3$s.%2$s.%4$s - %10$s %6$s, %8$s.%7$s.%9$s
- %5$s %3$s.%2$s - %10$s %8$s.%7$s
- %5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.
- %5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s
- %3$s %1$s, %2$s - %6$s %4$s, %5$s
- %1$s, %2$s - %4$s, %5$s
- %3$s %2$s - %6$s %5$s
- %1$s %2$s, %3$s
- %2$s, %3$s
- %1$s %2$s
- %3$s. %2$s - %8$s. %7$s
- %1$s, %3$s. %2$s - %6$s, %8$s. %7$s
- %5$s %3$s. %2$s - %10$s %8$s. %7$s
- %5$s %3$s. %2$s - %10$s %8$s. %7$s
- %5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s
- %5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s
- %5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s
- %5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s
- %5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s
- %5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s
- %1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s
- %3$s.-%8$s. %2$s
- %1$s, %3$s. %2$s - %6$s, %8$s. %7$s
- %3$s. %2$s - %8$s. %7$s %9$s
- %3$s.-%8$s. %2$s %9$s
- %1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s
- %B
-
diff --git a/core/res/res/values-cs/donottranslate-cldr.xml b/core/res/res/values-cs/donottranslate-cldr.xml
index 41f5dea81f009..53dc3121b4ad9 100644
--- a/core/res/res/values-cs/donottranslate-cldr.xml
+++ b/core/res/res/values-cs/donottranslate-cldr.xml
@@ -27,18 +27,18 @@
listopadu
prosince
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
+ 1.
+ 2.
+ 3.
+ 4.
+ 5.
+ 6.
+ 7.
+ 8.
+ 9.
+ 10.
+ 11.
+ 12.
l
ú
@@ -96,52 +96,52 @@
%-l:%M %^p
h:mm a
H:mm
- %-e.%-m.%Y
- d.M.yyyy
- "%s.%s.%s"
+ %-e. %-m. %Y
+ d. M. yyyy
+ "%s. %s. %s"
%-e. %B %Y
%-k:%M:%S
- %-k:%M:%S %-e.%-m.%Y
+ %-k:%M:%S %-e. %-m. %Y
%2$s %1$s
%1$s %3$s
- %-e.%-m.%Y
+ %-e. %-m. %Y
%-e. %B
%-B
%-B %Y
- %-e.%-m
+ %-e. %-m.
%-B
%-B %Y
- %1$s - %2$s
+ %1$s-%2$s
%2$s - %5$s
- %3$s.%2$s. - %8$s.%7$s.
- %1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.
- %3$s.%2$s.%4$s - %8$s.%7$s.%9$s
- %1$s, %3$s.%2$s.%4$s - %6$s, %8$s.%7$s.%9$s
- %5$s %1$s, %3$s.%2$s.%4$s - %10$s %6$s, %8$s.%7$s.%9$s
- %5$s %3$s.%2$s - %10$s %8$s.%7$s
- %5$s %1$s, %3$s.%2$s. - %10$s %6$s, %8$s.%7$s.
- %5$s %3$s.%2$s.%4$s - %10$s %8$s.%7$s.%9$s
- %3$s %1$s, %2$s - %6$s %4$s, %5$s
- %1$s, %2$s - %4$s, %5$s
+ %3$s. %2$s. - %8$s. %7$s.
+ %1$s %3$s. %2$s. - %6$s %8$s. %7$s.
+ %3$s. %2$s. %4$s - %8$s. %7$s. %9$s
+ %1$s %3$s. %2$s. %4$s - %6$s %8$s. %7$s. %9$s
+ %5$s %1$s %3$s. %2$s. %4$s - %10$s %6$s %8$s. %7$s. %9$s
+ %5$s %3$s. %2$s. - %10$s %8$s. %7$s.
+ %5$s %1$s %3$s. %2$s. - %10$s %6$s %8$s. %7$s.
+ %5$s %3$s. %2$s. %4$s - %10$s %8$s. %7$s. %9$s
+ %3$s %1$s %2$s - %6$s %4$s %5$s
+ %1$s %2$s - %4$s %5$s
%3$s %2$s - %6$s %5$s
- %1$s %2$s, %3$s
- %2$s, %3$s
+ %1$s %2$s %3$s
+ %2$s %3$s
%1$s %2$s
%3$s. %2$s - %8$s. %7$s
- %1$s, %3$s. %2$s - %6$s, %8$s. %7$s
+ %1$s %3$s. %2$s - %6$s %8$s. %7$s
%5$s %3$s. %2$s - %10$s %8$s. %7$s
%5$s %3$s. %2$s - %10$s %8$s. %7$s
- %5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s
- %5$s %1$s, %3$s. %2$s - %10$s %6$s, %8$s. %7$s
+ %5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s
+ %5$s %1$s %3$s. %2$s - %10$s %6$s %8$s. %7$s
%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s
%5$s %3$s. %2$s %4$s - %10$s %8$s. %7$s %9$s
- %5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s
- %5$s %1$s, %3$s. %2$s %4$s - %10$s %6$s, %8$s. %7$s %9$s
- %1$s, %3$s. %2$s %4$s - %6$s, %8$s. %7$s %9$s
+ %5$s %1$s %3$s. %2$s %4$s - %10$s %6$s %8$s. %7$s %9$s
+ %5$s %1$s %3$s. %2$s %4$s - %10$s %6$s %8$s. %7$s %9$s
+ %1$s %3$s. %2$s %4$s - %6$s %8$s. %7$s %9$s
%3$s.-%8$s. %2$s
- %1$s, %3$s. %2$s - %6$s, %8$s. %7$s
+ %1$s %3$s. %2$s - %6$s %8$s. %7$s
%3$s. %2$s - %8$s. %7$s %9$s
%3$s.-%8$s. %2$s %9$s
- %1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s
- %B
+ %1$s %3$s. %2$s - %6$s %8$s. %7$s %9$s
+ %b
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7160b41f49301..35a169f85cad7 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -111,7 +111,6 @@