summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 14:04:24 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 14:04:24 -0800
commit076357b8567458d4b6dfdcf839ef751634cd2bfb (patch)
treeefbb2fd6f1dc67d2d606382fc3b82983e7cb2e1f /core/java
parent3dec7d563a2f3e1eb967ce2054a00b6620e3558c (diff)
downloadframeworks_base-076357b8567458d4b6dfdcf839ef751634cd2bfb.zip
frameworks_base-076357b8567458d4b6dfdcf839ef751634cd2bfb.tar.gz
frameworks_base-076357b8567458d4b6dfdcf839ef751634cd2bfb.tar.bz2
auto import from //depot/cupcake/@132589
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ApplicationContext.java39
-rw-r--r--core/java/android/app/ExpandableListActivity.java23
-rw-r--r--core/java/android/app/IntentService.java74
-rw-r--r--core/java/android/app/ListActivity.java26
-rw-r--r--core/java/android/app/NotificationManager.java4
-rw-r--r--core/java/android/app/SearchDialog.java2
-rw-r--r--core/java/android/app/SearchManager.java8
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java4
-rw-r--r--core/java/android/content/ContentProvider.java75
-rw-r--r--core/java/android/content/ContentProviderNative.java43
-rw-r--r--core/java/android/content/ContentResolver.java320
-rw-r--r--core/java/android/content/ContentServiceNative.java7
-rw-r--r--core/java/android/content/IContentProvider.java4
-rw-r--r--core/java/android/content/Intent.java8
-rw-r--r--core/java/android/content/pm/PackageManager.java20
-rw-r--r--core/java/android/content/res/AssetFileDescriptor.java271
-rw-r--r--core/java/android/content/res/ColorStateList.java19
-rw-r--r--core/java/android/content/res/Resources.java180
-rw-r--r--core/java/android/content/res/StringBlock.java62
-rw-r--r--core/java/android/content/res/TypedArray.java28
-rw-r--r--core/java/android/database/sqlite/SQLiteDatabase.java4
-rw-r--r--core/java/android/database/sqlite/SQLiteStatement.java22
-rw-r--r--core/java/android/gadget/GadgetHost.java12
-rw-r--r--core/java/android/gadget/GadgetHostView.java249
-rw-r--r--core/java/android/gadget/GadgetManager.java16
-rw-r--r--core/java/android/hardware/Camera.java1
-rw-r--r--core/java/android/inputmethodservice/ExtractEditText.java7
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java266
-rwxr-xr-xcore/java/android/inputmethodservice/KeyboardView.java22
-rw-r--r--core/java/android/net/SSLCertificateSocketFactory.java72
-rw-r--r--core/java/android/net/http/AndroidHttpClient.java46
-rw-r--r--core/java/android/net/http/CertificateChainValidator.java154
-rw-r--r--core/java/android/os/BatteryStats.java137
-rw-r--r--core/java/android/os/ParcelFileDescriptor.java18
-rw-r--r--core/java/android/pim/ICalendar.java15
-rw-r--r--core/java/android/provider/Checkin.java10
-rw-r--r--core/java/android/provider/Im.java33
-rw-r--r--core/java/android/provider/Settings.java49
-rw-r--r--core/java/android/server/BluetoothA2dpService.java82
-rw-r--r--core/java/android/server/BluetoothDeviceService.java24
-rw-r--r--core/java/android/server/search/SearchableInfo.java18
-rw-r--r--core/java/android/speech/srec/package.html1
-rw-r--r--core/java/android/text/InputType.java5
-rw-r--r--core/java/android/text/Styled.java249
-rw-r--r--core/java/android/text/format/DateUtils.java216
-rw-r--r--core/java/android/text/method/NumberKeyListener.java5
-rw-r--r--core/java/android/view/GestureDetector.java91
-rw-r--r--core/java/android/view/KeyEvent.java6
-rw-r--r--core/java/android/view/View.java47
-rw-r--r--core/java/android/view/ViewConfiguration.java18
-rw-r--r--core/java/android/view/ViewRoot.java39
-rw-r--r--core/java/android/view/inputmethod/BaseInputConnection.java7
-rw-r--r--core/java/android/view/inputmethod/EditorInfo.java106
-rw-r--r--core/java/android/view/inputmethod/InputConnection.java14
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java18
-rw-r--r--core/java/android/webkit/CallbackProxy.java8
-rw-r--r--core/java/android/webkit/TextDialog.java103
-rw-r--r--core/java/android/webkit/WebView.java100
-rw-r--r--core/java/android/webkit/WebViewCore.java4
-rw-r--r--core/java/android/widget/AbsListView.java29
-rw-r--r--core/java/android/widget/AbsSeekBar.java45
-rw-r--r--core/java/android/widget/AnalogClock.java17
-rw-r--r--core/java/android/widget/AutoCompleteTextView.java103
-rw-r--r--core/java/android/widget/BaseAdapter.java4
-rw-r--r--core/java/android/widget/Chronometer.java19
-rw-r--r--core/java/android/widget/CursorAdapter.java20
-rw-r--r--core/java/android/widget/Filter.java14
-rw-r--r--core/java/android/widget/GridView.java29
-rw-r--r--core/java/android/widget/HorizontalScrollView.java2
-rw-r--r--core/java/android/widget/ImageView.java2
-rw-r--r--core/java/android/widget/ListView.java85
-rw-r--r--core/java/android/widget/MultiAutoCompleteTextView.java4
-rw-r--r--core/java/android/widget/PopupWindow.java63
-rw-r--r--core/java/android/widget/ProgressBar.java1
-rw-r--r--core/java/android/widget/ResourceCursorAdapter.java22
-rw-r--r--core/java/android/widget/TextView.java355
-rw-r--r--core/java/android/widget/ZoomButtonsController.java478
-rw-r--r--core/java/android/widget/ZoomRing.java418
-rw-r--r--core/java/android/widget/ZoomRingController.java462
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl2
-rw-r--r--core/java/com/android/internal/gadget/IGadgetService.aidl1
-rw-r--r--core/java/com/android/internal/logging/AndroidConfig.java11
-rw-r--r--core/java/com/android/internal/logging/AndroidHandler.java69
-rw-r--r--core/java/com/android/internal/net/DbSSLSessionCache.java269
-rw-r--r--core/java/com/android/internal/net/SSLSessionCache.java101
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java323
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java83
-rw-r--r--core/java/com/android/internal/view/IInputConnectionWrapper.java16
-rw-r--r--core/java/com/android/internal/view/IInputContext.aidl2
-rw-r--r--core/java/com/android/internal/view/InputConnectionWrapper.java9
-rw-r--r--core/java/com/android/internal/view/menu/ExpandedMenuView.java5
-rw-r--r--core/java/com/android/internal/widget/EditableInputConnection.java15
-rw-r--r--core/java/com/android/internal/widget/TextProgressBar.java4
-rw-r--r--core/java/com/google/android/gdata/client/AndroidGDataClient.java21
-rw-r--r--core/java/com/google/android/net/GoogleHttpClient.java38
95 files changed, 1538 insertions, 5114 deletions
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index 3b5ad86..394b8e3 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -1487,7 +1487,7 @@ class ApplicationContext extends Context {
static final class ApplicationPackageManager extends PackageManager {
@Override
public PackageInfo getPackageInfo(String packageName, int flags)
- throws NameNotFoundException {
+ throws NameNotFoundException {
try {
PackageInfo pi = mPM.getPackageInfo(packageName, flags);
if (pi != null) {
@@ -1500,43 +1500,6 @@ class ApplicationContext extends Context {
throw new NameNotFoundException(packageName);
}
- public Intent getLaunchIntentForPackage(String packageName)
- throws NameNotFoundException {
- // First see if the package has an INFO activity; the existence of
- // such an activity is implied to be the desired front-door for the
- // overall package (such as if it has multiple launcher entries).
- Intent intent = getLaunchIntentForPackageCategory(this, packageName,
- Intent.CATEGORY_INFO);
- if (intent != null) {
- return intent;
- }
-
- // Otherwise, try to find a main launcher activity.
- return getLaunchIntentForPackageCategory(this, packageName,
- Intent.CATEGORY_LAUNCHER);
- }
-
- // XXX This should be implemented as a call to the package manager,
- // to reduce the work needed.
- static Intent getLaunchIntentForPackageCategory(PackageManager pm,
- String packageName, String category) {
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- Intent intentToResolve = new Intent(Intent.ACTION_MAIN, null);
- intentToResolve.addCategory(category);
- final List<ResolveInfo> apps =
- pm.queryIntentActivities(intentToResolve, 0);
- // I wish there were a way to directly get the "main" activity of a
- // package but ...
- for (ResolveInfo app : apps) {
- if (app.activityInfo.packageName.equals(packageName)) {
- intent.setClassName(packageName, app.activityInfo.name);
- return intent;
- }
- }
- return null;
- }
-
@Override
public int[] getPackageGids(String packageName)
throws NameNotFoundException {
diff --git a/core/java/android/app/ExpandableListActivity.java b/core/java/android/app/ExpandableListActivity.java
index a2e048f..75dfcae 100644
--- a/core/java/android/app/ExpandableListActivity.java
+++ b/core/java/android/app/ExpandableListActivity.java
@@ -63,21 +63,21 @@ import java.util.Map;
*
* <pre>
* &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
- * &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ * &lt;LinearLayout
* android:orientation=&quot;vertical&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;fill_parent&quot;
- * android:paddingLeft=&quot;8dp&quot;
- * android:paddingRight=&quot;8dp&quot;&gt;
+ * android:paddingLeft=&quot;8&quot;
+ * android:paddingRight=&quot;8&quot;&gt;
*
- * &lt;ExpandableListView android:id=&quot;@id/android:list&quot;
+ * &lt;ExpandableListView id=&quot;android:list&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;fill_parent&quot;
* android:background=&quot;#00FF00&quot;
* android:layout_weight=&quot;1&quot;
* android:drawSelectorOnTop=&quot;false&quot;/&gt;
*
- * &lt;TextView android:id=&quot;@id/android:empty&quot;
+ * &lt;TextView id=&quot;android:empty&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;fill_parent&quot;
* android:background=&quot;#FF0000&quot;
@@ -113,19 +113,19 @@ import java.util.Map;
*
* <pre>
* &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
- * &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ * &lt;LinearLayout
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;wrap_content&quot;
* android:orientation=&quot;vertical&quot;&gt;
*
- * &lt;TextView android:id=&quot;@+id/text1&quot;
- * android:textSize=&quot;16sp&quot;
+ * &lt;TextView id=&quot;text1&quot;
+ * android:textSize=&quot;16&quot;
* android:textStyle=&quot;bold&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;wrap_content&quot;/&gt;
*
- * &lt;TextView android:id=&quot;@+id/text2&quot;
- * android:textSize=&quot;16sp&quot;
+ * &lt;TextView id=&quot;text2&quot;
+ * android:textSize=&quot;16&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;wrap_content&quot;/&gt;
* &lt;/LinearLayout&gt;
@@ -162,8 +162,7 @@ public class ExpandableListActivity extends Activity implements
/**
* Override this to populate the context menu when an item is long pressed. menuInfo
- * will contain an {@link android.widget.ExpandableListView.ExpandableListContextMenuInfo}
- * whose packedPosition is a packed position
+ * will contain a {@link AdapterContextMenuInfo} whose position is a packed position
* that should be used with {@link ExpandableListView#getPackedPositionType(long)} and
* the other similar methods.
* <p>
diff --git a/core/java/android/app/IntentService.java b/core/java/android/app/IntentService.java
deleted file mode 100644
index 2b12a2a..0000000
--- a/core/java/android/app/IntentService.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package android.app;
-
-import android.content.Intent;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-
-/**
- * An abstract {@link Service} that serializes the handling of the Intents passed upon service
- * start and handles them on a handler thread.
- *
- * <p>To use this class extend it and implement {@link #onHandleIntent}. The {@link Service} will
- * automatically be stopped when the last enqueued {@link Intent} is handled.
- */
-public abstract class IntentService extends Service {
- private volatile Looper mServiceLooper;
- private volatile ServiceHandler mServiceHandler;
- private String mName;
-
- private final class ServiceHandler extends Handler {
- public ServiceHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- onHandleIntent((Intent)msg.obj);
- stopSelf(msg.arg1);
- }
- }
-
- public IntentService(String name) {
- super();
- mName = name;
- }
-
- @Override
- public void onCreate() {
- super.onCreate();
- HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
- thread.start();
-
- mServiceLooper = thread.getLooper();
- mServiceHandler = new ServiceHandler(mServiceLooper);
- }
-
- @Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- Message msg = mServiceHandler.obtainMessage();
- msg.arg1 = startId;
- msg.obj = intent;
- mServiceHandler.sendMessage(msg);
- }
-
- @Override
- public void onDestroy() {
- mServiceLooper.quit();
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-
- /**
- * Invoked on the Handler thread with the {@link Intent} that is passed to {@link #onStart}.
- * Note that this will be invoked from a different thread than the one that handles the
- * {@link #onStart} call.
- */
- protected abstract void onHandleIntent(Intent intent);
-}
diff --git a/core/java/android/app/ListActivity.java b/core/java/android/app/ListActivity.java
index 5523c18..2818937 100644
--- a/core/java/android/app/ListActivity.java
+++ b/core/java/android/app/ListActivity.java
@@ -53,22 +53,22 @@ import android.widget.ListView;
* </p>
*
* <pre>
- * &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
- * &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ * &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
+ * &lt;LinearLayout
* android:orientation=&quot;vertical&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;fill_parent&quot;
- * android:paddingLeft=&quot;8dp&quot;
- * android:paddingRight=&quot;8dp&quot;&gt;
+ * android:paddingLeft=&quot;8&quot;
+ * android:paddingRight=&quot;8&quot;&gt;
*
- * &lt;ListView android:id=&quot;@id/android:list&quot;
+ * &lt;ListView id=&quot;android:list&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;fill_parent&quot;
* android:background=&quot;#00FF00&quot;
* android:layout_weight=&quot;1&quot;
* android:drawSelectorOnTop=&quot;false&quot;/&gt;
*
- * &lt;TextView id=&quot;@id/android:empty&quot;
+ * &lt;TextView id=&quot;android:empty&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;fill_parent&quot;
* android:background=&quot;#FF0000&quot;
@@ -99,19 +99,19 @@ import android.widget.ListView;
*
* <pre>
* &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
- * &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ * &lt;LinearLayout
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;wrap_content&quot;
* android:orientation=&quot;vertical&quot;&gt;
*
- * &lt;TextView android:id=&quot;@+id/text1&quot;
- * android:textSize=&quot;16sp&quot;
+ * &lt;TextView id=&quot;text1&quot;
+ * android:textSize=&quot;16&quot;
* android:textStyle=&quot;bold&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;wrap_content&quot;/&gt;
*
- * &lt;TextView android:id=&quot;@+id/text2&quot;
- * android:textSize=&quot;16sp&quot;
+ * &lt;TextView id=&quot;text2&quot;
+ * android:textSize=&quot;16&quot;
* android:layout_width=&quot;fill_parent&quot;
* android:layout_height=&quot;wrap_content&quot;/&gt;
* &lt;/LinearLayout&gt;
@@ -142,8 +142,8 @@ import android.widget.ListView;
* public class MyListAdapter extends ListActivity {
*
* &#064;Override
- * protected void onCreate(Bundle savedInstanceState){
- * super.onCreate(savedInstanceState);
+ * protected void onCreate(Bundle icicle){
+ * super.onCreate(icicle);
*
* // We'll define a custom screen layout here (the one shown above), but
* // typically, you could just use the standard ListActivity layout.
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 39edab7..afb3827 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -82,7 +82,9 @@ public class NotificationManager
* @param id An identifier for this notification unique within your
* application.
* @param notification A {@link Notification} object describing how to
- * notify the user, other than the view you're providing. Must not be null.
+ * notify the user, other than the view you're providing. If you
+ * pass null, there will be no persistent notification and no
+ * flashing, vibration, etc.
*/
public void notify(int id, Notification notification)
{
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index d447eb2..7b8256c 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -448,7 +448,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
}
mSearchTextField.setInputType(inputType);
- mSearchTextField.setImeOptions(mSearchable.getImeOptions());
}
}
@@ -794,6 +793,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// otherwise, dispatch an "edit view" key
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
+ case KeyEvent.KEYCODE_DPAD_CENTER:
if (event.getAction() == KeyEvent.ACTION_UP) {
v.cancelLongPress();
launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null);
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index c1d66f4..2cc6de9 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -747,14 +747,6 @@ import android.view.KeyEvent;
* <a href="../R.attr.html#inputType">inputType</a> attribute.</td>
* <td align="center">No</td>
* </tr>
- * <tr><th>android:imeOptions</th>
- * <td>If provided, supplies additional options for the input method.
- * For most searches, in which free form text is expected, this attribute
- * need not be provided, and will default to "actionSearch".
- * Suitable values for this attribute are described in the
- * <a href="../R.attr.html#imeOptions">imeOptions</a> attribute.</td>
- * <td align="center">No</td>
- * </tr>
*
* </tbody>
* </table>
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 1ba1c1e..56b231f 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -63,10 +63,8 @@ public class BluetoothDevice {
public static final int UNBOND_REASON_AUTH_CANCELED = 3;
/** A bond attempt failed because we could not contact the remote device */
public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
- /** A bond attempt failed because a discovery is in progress */
- public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
/** An existing bond was explicitly revoked */
- public static final int UNBOND_REASON_REMOVED = 6;
+ public static final int UNBOND_REASON_REMOVED = 5;
private static final String TAG = "BluetoothDevice";
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 25544de..3a64cee 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -18,7 +18,6 @@ package android.content;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
-import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.database.Cursor;
import android.database.CursorToBulkCursorAdaptor;
@@ -163,13 +162,6 @@ public abstract class ContentProvider implements ComponentCallbacks {
return ContentProvider.this.openFile(uri, mode);
}
- public AssetFileDescriptor openAssetFile(Uri uri, String mode)
- throws FileNotFoundException {
- if (mode != null && mode.startsWith("rw")) checkWritePermission(uri);
- else checkReadPermission(uri);
- return ContentProvider.this.openAssetFile(uri, mode);
- }
-
public ISyncAdapter getSyncAdapter() {
checkWritePermission(null);
return ContentProvider.this.getSyncAdapter().getISyncAdapter();
@@ -446,9 +438,8 @@ public abstract class ContentProvider implements ComponentCallbacks {
* of this method should create a new ParcelFileDescriptor for each call.
*
* @param uri The URI whose file is to be opened.
- * @param mode Access mode for the file. May be "r" for read-only access,
- * "rw" for read and write access, or "rwt" for read and write access
- * that truncates any existing file.
+ * @param mode Access mode for the file. May be "r" for read-only access
+ * or "rw" for read and write access.
*
* @return Returns a new ParcelFileDescriptor which you can use to access
* the file.
@@ -457,66 +448,19 @@ public abstract class ContentProvider implements ComponentCallbacks {
* no file associated with the given URI or the mode is invalid.
* @throws SecurityException Throws SecurityException if the caller does
* not have permission to access the file.
- *
- * @see #openAssetFile(Uri, String)
- * @see #openFileHelper(Uri, String)
- */
+ */
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
throw new FileNotFoundException("No files supported by provider at "
+ uri);
}
-
- /**
- * This is like {@link #openFile}, but can be implemented by providers
- * that need to be able to return sub-sections of files, often assets
- * inside of their .apk. Note that when implementing this your clients
- * must be able to deal with such files, either directly with
- * {@link ContentResolver#openAssetFileDescriptor
- * ContentResolver.openAssetFileDescriptor}, or by using the higher-level
- * {@link ContentResolver#openInputStream ContentResolver.openInputStream}
- * or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
- * methods.
- *
- * <p><em>Note: if you are implementing this to return a full file, you
- * should create the AssetFileDescriptor with
- * {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
- * applications that can not handle sub-sections of files.</em></p>
- *
- * @param uri The URI whose file is to be opened.
- * @param mode Access mode for the file. May be "r" for read-only access,
- * "w" for write-only access (erasing whatever data is currently in
- * the file), "wa" for write-only access to append to any existing data,
- * "rw" for read and write access on any existing data, and "rwt" for read
- * and write access that truncates any existing file.
- *
- * @return Returns a new AssetFileDescriptor which you can use to access
- * the file.
- *
- * @throws FileNotFoundException Throws FileNotFoundException if there is
- * no file associated with the given URI or the mode is invalid.
- * @throws SecurityException Throws SecurityException if the caller does
- * not have permission to access the file.
- *
- * @see #openFile(Uri, String)
- * @see #openFileHelper(Uri, String)
- */
- public AssetFileDescriptor openAssetFile(Uri uri, String mode)
- throws FileNotFoundException {
- ParcelFileDescriptor fd = openFile(uri, mode);
- return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
- }
/**
* Convenience for subclasses that wish to implement {@link #openFile}
* by looking up a column named "_data" at the given URI.
*
* @param uri The URI to be opened.
- * @param mode The file mode. May be "r" for read-only access,
- * "w" for write-only access (erasing whatever data is currently in
- * the file), "wa" for write-only access to append to any existing data,
- * "rw" for read and write access on any existing data, and "rwt" for read
- * and write access that truncates any existing file.
+ * @param mode The file mode.
*
* @return Returns a new ParcelFileDescriptor that can be used by the
* client to access the file.
@@ -545,7 +489,16 @@ public abstract class ContentProvider implements ComponentCallbacks {
throw new FileNotFoundException("Column _data not found.");
}
- int modeBits = ContentResolver.modeToMode(uri, mode);
+ int modeBits;
+ if ("r".equals(mode)) {
+ modeBits = ParcelFileDescriptor.MODE_READ_ONLY;
+ } else if ("rw".equals(mode)) {
+ modeBits = ParcelFileDescriptor.MODE_READ_WRITE
+ | ParcelFileDescriptor.MODE_CREATE;
+ } else {
+ throw new FileNotFoundException("Bad mode for " + uri + ": "
+ + mode);
+ }
return ParcelFileDescriptor.open(new File(path), modeBits);
}
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index e5e3f74..ede2c9b 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -16,7 +16,6 @@
package android.content;
-import android.content.res.AssetFileDescriptor;
import android.database.BulkCursorNative;
import android.database.BulkCursorToCursorAdaptor;
import android.database.Cursor;
@@ -188,25 +187,6 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
return true;
}
- case OPEN_ASSET_FILE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- String mode = data.readString();
-
- AssetFileDescriptor fd;
- fd = openAssetFile(url, mode);
- reply.writeNoException();
- if (fd != null) {
- reply.writeInt(1);
- fd.writeToParcel(reply,
- Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- } else {
- reply.writeInt(0);
- }
- return true;
- }
-
case GET_SYNC_ADAPTER_TRANSACTION:
{
data.enforceInterface(IContentProvider.descriptor);
@@ -433,29 +413,6 @@ final class ContentProviderProxy implements IContentProvider
return fd;
}
- public AssetFileDescriptor openAssetFile(Uri url, String mode)
- throws RemoteException, FileNotFoundException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
- data.writeString(mode);
-
- mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- AssetFileDescriptor fd = has != 0
- ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
- }
-
public ISyncAdapter getSyncAdapter() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0d886ee..52f55b6 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -17,7 +17,6 @@
package android.content;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.Cursor;
@@ -29,7 +28,6 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.text.TextUtils;
-import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -172,100 +170,119 @@ public abstract class ContentResolver {
* <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li>
* <li>file ({@link #SCHEME_FILE})</li>
* </ul>
- *
- * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
- * on these schemes.
- *
- * @param uri The desired URI.
+ * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5>
+ * <p>
+ * A Uri object can be used to reference a resource in an APK file. The
+ * Uri should be one of the following formats:
+ * <ul>
+ * <li><code>android.resource://package_name/id_number</code><br/>
+ * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
+ * For example <code>com.example.myapp</code><br/>
+ * <code>id_number</code> is the int form of the ID.<br/>
+ * The easiest way to construct this form is
+ * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre>
+ * </li>
+ * <li><code>android.resource://package_name/type/name</code><br/>
+ * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
+ * For example <code>com.example.myapp</code><br/>
+ * <code>type</code> is the string form of the resource type. For example, <code>raw</code>
+ * or <code>drawable</code>.
+ * <code>name</code> is the string form of the resource name. That is, whatever the file
+ * name was in your res directory, without the type extension.
+ * The easiest way to construct this form is
+ * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre>
+ * </li>
+ * </ul>
+ * @param uri The desired "content:" URI.
* @return InputStream
* @throws FileNotFoundException if the provided URI could not be opened.
- * @see #openAssetFileDescriptor(Uri, String)
*/
public final InputStream openInputStream(Uri uri)
throws FileNotFoundException {
String scheme = uri.getScheme();
- if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
- // Note: left here to avoid breaking compatibility. May be removed
- // with sufficient testing.
- OpenResourceIdResult r = getResourceId(uri);
+ if (SCHEME_CONTENT.equals(scheme)) {
+ ParcelFileDescriptor fd = openFileDescriptor(uri, "r");
+ return fd != null ? new ParcelFileDescriptor.AutoCloseInputStream(fd) : null;
+ } else if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
+ String authority = uri.getAuthority();
+ Resources r;
+ if (TextUtils.isEmpty(authority)) {
+ throw new FileNotFoundException("No authority: " + uri);
+ } else {
+ try {
+ r = mContext.getPackageManager().getResourcesForApplication(authority);
+ } catch (NameNotFoundException ex) {
+ throw new FileNotFoundException("No package found for authority: " + uri);
+ }
+ }
+ List<String> path = uri.getPathSegments();
+ if (path == null) {
+ throw new FileNotFoundException("No path: " + uri);
+ }
+ int len = path.size();
+ int id;
+ if (len == 1) {
+ try {
+ id = Integer.parseInt(path.get(0));
+ } catch (NumberFormatException e) {
+ throw new FileNotFoundException("Single path segment is not a resource ID: " + uri);
+ }
+ } else if (len == 2) {
+ id = r.getIdentifier(path.get(1), path.get(0), authority);
+ } else {
+ throw new FileNotFoundException("More than two path segments: " + uri);
+ }
+ if (id == 0) {
+ throw new FileNotFoundException("No resource found for: " + uri);
+ }
try {
- InputStream stream = r.r.openRawResource(r.id);
+ InputStream stream = r.openRawResource(id);
return stream;
} catch (Resources.NotFoundException ex) {
- throw new FileNotFoundException("Resource does not exist: " + uri);
+ throw new FileNotFoundException("Resource ID does not exist: " + uri);
}
} else if (SCHEME_FILE.equals(scheme)) {
- // Note: left here to avoid breaking compatibility. May be removed
- // with sufficient testing.
return new FileInputStream(uri.getPath());
} else {
- AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r");
- try {
- return fd != null ? fd.createInputStream() : null;
- } catch (IOException e) {
- throw new FileNotFoundException("Unable to create stream");
- }
+ throw new FileNotFoundException("Unknown scheme: " + uri);
}
}
/**
- * Synonym for {@link #openOutputStream(Uri, String)
- * openOutputStream(uri, "w")}.
- * @throws FileNotFoundException if the provided URI could not be opened.
- */
- public final OutputStream openOutputStream(Uri uri)
- throws FileNotFoundException {
- return openOutputStream(uri, "w");
- }
-
- /**
* Open a stream on to the content associated with a content URI. If there
* is no data associated with the URI, FileNotFoundException is thrown.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
- * <li>file ({@link #SCHEME_FILE})</li>
* </ul>
*
- * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
- * on these schemes.
- *
- * @param uri The desired URI.
- * @param mode May be "w", "wa", "rw", or "rwt".
+ * @param uri The desired "content:" URI.
* @return OutputStream
- * @throws FileNotFoundException if the provided URI could not be opened.
- * @see #openAssetFileDescriptor(Uri, String)
*/
- public final OutputStream openOutputStream(Uri uri, String mode)
+ public final OutputStream openOutputStream(Uri uri)
throws FileNotFoundException {
- AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode);
- try {
- return fd != null ? fd.createOutputStream() : null;
- } catch (IOException e) {
- throw new FileNotFoundException("Unable to create stream");
+ String scheme = uri.getScheme();
+ if (SCHEME_CONTENT.equals(scheme)) {
+ ParcelFileDescriptor fd = openFileDescriptor(uri, "rw");
+ return fd != null
+ ? new ParcelFileDescriptor.AutoCloseOutputStream(fd) : null;
+ } else {
+ throw new FileNotFoundException("Unknown scheme: " + uri);
}
}
/**
* Open a raw file descriptor to access data under a "content:" URI. This
- * is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the
- * underlying {@link ContentProvider#openFile}
- * ContentProvider.openFile()} method, so will <em>not</em> work with
- * providers that return sub-sections of files. If at all possible,
- * you should use {@link #openAssetFileDescriptor(Uri, String)}. You
- * will receive a FileNotFoundException exception if the provider returns a
- * sub-section of a file.
+ * interacts with the underlying {@link ContentProvider#openFile}
+ * ContentProvider.openFile()} method of the provider associated with the
+ * given URI, to retrieve any file stored there.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
- * <li>file ({@link #SCHEME_FILE})</li>
* </ul>
*
- * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
- * on these schemes.
- *
* @param uri The desired URI to open.
* @param mode The file mode to use, as per {@link ContentProvider#openFile
* ContentProvider.openFile}.
@@ -273,189 +290,32 @@ public abstract class ContentResolver {
* own this descriptor and are responsible for closing it when done.
* @throws FileNotFoundException Throws FileNotFoundException of no
* file exists under the URI or the mode is invalid.
- * @see #openAssetFileDescriptor(Uri, String)
*/
public final ParcelFileDescriptor openFileDescriptor(Uri uri,
String mode) throws FileNotFoundException {
- AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode);
- if (afd == null) {
- return null;
- }
-
- if (afd.getDeclaredLength() < 0) {
- // This is a full file!
- return afd.getParcelFileDescriptor();
+ IContentProvider provider = acquireProvider(uri);
+ if (provider == null) {
+ throw new FileNotFoundException("No content provider: " + uri);
}
-
- // Client can't handle a sub-section of a file, so close what
- // we got and bail with an exception.
try {
- afd.close();
- } catch (IOException e) {
- }
-
- throw new FileNotFoundException("Not a whole file");
- }
-
- /**
- * Open a raw file descriptor to access data under a "content:" URI. This
- * interacts with the underlying {@link ContentProvider#openAssetFile}
- * ContentProvider.openAssetFile()} method of the provider associated with the
- * given URI, to retrieve any file stored there.
- *
- * <h5>Accepts the following URI schemes:</h5>
- * <ul>
- * <li>content ({@link #SCHEME_CONTENT})</li>
- * <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li>
- * <li>file ({@link #SCHEME_FILE})</li>
- * </ul>
- * <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5>
- * <p>
- * A Uri object can be used to reference a resource in an APK file. The
- * Uri should be one of the following formats:
- * <ul>
- * <li><code>android.resource://package_name/id_number</code><br/>
- * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
- * For example <code>com.example.myapp</code><br/>
- * <code>id_number</code> is the int form of the ID.<br/>
- * The easiest way to construct this form is
- * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre>
- * </li>
- * <li><code>android.resource://package_name/type/name</code><br/>
- * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
- * For example <code>com.example.myapp</code><br/>
- * <code>type</code> is the string form of the resource type. For example, <code>raw</code>
- * or <code>drawable</code>.
- * <code>name</code> is the string form of the resource name. That is, whatever the file
- * name was in your res directory, without the type extension.
- * The easiest way to construct this form is
- * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre>
- * </li>
- * </ul>
- *
- * @param uri The desired URI to open.
- * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile
- * ContentProvider.openAssetFile}.
- * @return Returns a new ParcelFileDescriptor pointing to the file. You
- * own this descriptor and are responsible for closing it when done.
- * @throws FileNotFoundException Throws FileNotFoundException of no
- * file exists under the URI or the mode is invalid.
- */
- public final AssetFileDescriptor openAssetFileDescriptor(Uri uri,
- String mode) throws FileNotFoundException {
- String scheme = uri.getScheme();
- if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
- if (!"r".equals(mode)) {
- throw new FileNotFoundException("Can't write resources: " + uri);
- }
- OpenResourceIdResult r = getResourceId(uri);
- try {
- return r.r.openRawResourceFd(r.id);
- } catch (Resources.NotFoundException ex) {
- throw new FileNotFoundException("Resource does not exist: " + uri);
- }
- } else if (SCHEME_FILE.equals(scheme)) {
- ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
- new File(uri.getPath()), modeToMode(uri, mode));
- return new AssetFileDescriptor(pfd, 0, -1);
- } else {
- IContentProvider provider = acquireProvider(uri);
- if (provider == null) {
- throw new FileNotFoundException("No content provider: " + uri);
- }
- try {
- AssetFileDescriptor fd = provider.openAssetFile(uri, mode);
- if(fd == null) {
- releaseProvider(provider);
- return null;
- }
- ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
- fd.getParcelFileDescriptor(), provider);
- return new AssetFileDescriptor(pfd, fd.getStartOffset(),
- fd.getDeclaredLength());
- } catch (RemoteException e) {
- releaseProvider(provider);
- throw new FileNotFoundException("Dead content provider: " + uri);
- } catch (FileNotFoundException e) {
+ ParcelFileDescriptor fd = provider.openFile(uri, mode);
+ if(fd == null) {
releaseProvider(provider);
- throw e;
- } catch (RuntimeException e) {
- releaseProvider(provider);
- throw e;
+ return null;
}
+ return new ParcelFileDescriptorInner(fd, provider);
+ } catch (RemoteException e) {
+ releaseProvider(provider);
+ throw new FileNotFoundException("Dead content provider: " + uri);
+ } catch (FileNotFoundException e) {
+ releaseProvider(provider);
+ throw e;
+ } catch (RuntimeException e) {
+ releaseProvider(provider);
+ throw e;
}
}
- class OpenResourceIdResult {
- Resources r;
- int id;
- }
-
- OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException {
- String authority = uri.getAuthority();
- Resources r;
- if (TextUtils.isEmpty(authority)) {
- throw new FileNotFoundException("No authority: " + uri);
- } else {
- try {
- r = mContext.getPackageManager().getResourcesForApplication(authority);
- } catch (NameNotFoundException ex) {
- throw new FileNotFoundException("No package found for authority: " + uri);
- }
- }
- List<String> path = uri.getPathSegments();
- if (path == null) {
- throw new FileNotFoundException("No path: " + uri);
- }
- int len = path.size();
- int id;
- if (len == 1) {
- try {
- id = Integer.parseInt(path.get(0));
- } catch (NumberFormatException e) {
- throw new FileNotFoundException("Single path segment is not a resource ID: " + uri);
- }
- } else if (len == 2) {
- id = r.getIdentifier(path.get(1), path.get(0), authority);
- } else {
- throw new FileNotFoundException("More than two path segments: " + uri);
- }
- if (id == 0) {
- throw new FileNotFoundException("No resource found for: " + uri);
- }
- OpenResourceIdResult res = new OpenResourceIdResult();
- res.r = r;
- res.id = id;
- return res;
- }
-
- /** @hide */
- static public int modeToMode(Uri uri, String mode) throws FileNotFoundException {
- int modeBits;
- if ("r".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_READ_ONLY;
- } else if ("w".equals(mode) || "wt".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
- | ParcelFileDescriptor.MODE_CREATE
- | ParcelFileDescriptor.MODE_TRUNCATE;
- } else if ("wa".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
- | ParcelFileDescriptor.MODE_CREATE
- | ParcelFileDescriptor.MODE_APPEND;
- } else if ("rw".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_READ_WRITE
- | ParcelFileDescriptor.MODE_CREATE;
- } else if ("rwt".equals(mode)) {
- modeBits = ParcelFileDescriptor.MODE_READ_WRITE
- | ParcelFileDescriptor.MODE_CREATE
- | ParcelFileDescriptor.MODE_TRUNCATE;
- } else {
- throw new FileNotFoundException("Bad mode for " + uri + ": "
- + mode);
- }
- return modeBits;
- }
-
/**
* Inserts a row into a table at the given URL.
*
diff --git a/core/java/android/content/ContentServiceNative.java b/core/java/android/content/ContentServiceNative.java
index 364f9ee..f050501 100644
--- a/core/java/android/content/ContentServiceNative.java
+++ b/core/java/android/content/ContentServiceNative.java
@@ -75,13 +75,6 @@ abstract class ContentServiceNative extends Binder implements IContentService
{
try {
switch (code) {
- case 5038: {
- data.readString(); // ignore the interface token that service generated
- Uri uri = Uri.parse(data.readString());
- notifyChange(uri, null, false, false);
- return true;
- }
-
case REGISTER_CONTENT_OBSERVER_TRANSACTION: {
Uri uri = Uri.CREATOR.createFromParcel(data);
boolean notifyForDescendents = data.readInt() != 0;
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
index 0606956..a6ef46f 100644
--- a/core/java/android/content/IContentProvider.java
+++ b/core/java/android/content/IContentProvider.java
@@ -16,7 +16,6 @@
package android.content;
-import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.IBulkCursor;
@@ -53,8 +52,6 @@ public interface IContentProvider extends IInterface {
String[] selectionArgs) throws RemoteException;
public ParcelFileDescriptor openFile(Uri url, String mode)
throws RemoteException, FileNotFoundException;
- public AssetFileDescriptor openAssetFile(Uri url, String mode)
- throws RemoteException, FileNotFoundException;
public ISyncAdapter getSyncAdapter() throws RemoteException;
/* IPC constants */
@@ -68,5 +65,4 @@ public interface IContentProvider extends IInterface {
static final int GET_SYNC_ADAPTER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 10;
static final int BULK_INSERT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 12;
static final int OPEN_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 13;
- static final int OPEN_ASSET_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 14;
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index e1c1f64..c1c3b49 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -522,7 +522,6 @@ import java.util.Set;
* <li> {@link #CATEGORY_ALTERNATIVE}
* <li> {@link #CATEGORY_SELECTED_ALTERNATIVE}
* <li> {@link #CATEGORY_LAUNCHER}
- * <li> {@link #CATEGORY_INFO}
* <li> {@link #CATEGORY_HOME}
* <li> {@link #CATEGORY_PREFERENCE}
* <li> {@link #CATEGORY_GADGET}
@@ -1547,13 +1546,6 @@ public class Intent implements Parcelable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
/**
- * Provides information about the package it is in; typically used if
- * a package does not contain a {@link #CATEGORY_LAUNCHER} to provide
- * a front-door to the user without having to be shown in the all apps list.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_INFO = "android.intent.category.INFO";
- /**
* This is the home activity, that is the first activity that is displayed
* when the device boots.
*/
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 7287d9c..698f27f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -480,26 +480,6 @@ public abstract class PackageManager {
throws NameNotFoundException;
/**
- * Return a "good" intent to launch a front-door activity in a package,
- * for use for example to implement an "open" button when browsing through
- * packages. The current implementation will look first for a main
- * activity in the category {@link Intent#CATEGORY_INFO}, next for a
- * main activity in the category {@link Intent#CATEGORY_LAUNCHER}, or return
- * null if neither are found.
- *
- * <p>Throws {@link NameNotFoundException} if a package with the given
- * name can not be found on the system.
- *
- * @param packageName The name of the package to inspect.
- *
- * @return Returns either a fully-qualified Intent that can be used to
- * launch the main activity in the package, or null if the package does
- * not contain such an activity.
- */
- public abstract Intent getLaunchIntentForPackage(String packageName)
- throws NameNotFoundException;
-
- /**
* Return an array of all of the secondary group-ids that have been
* assigned to a package.
*
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
index 231e3e2..4a073f7 100644
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ b/core/java/android/content/res/AssetFileDescriptor.java
@@ -16,13 +16,9 @@
package android.content.res;
-import android.os.Parcel;
import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
/**
@@ -30,32 +26,16 @@ import java.io.IOException;
* opened FileDescriptor that can be used to read the data, as well as the
* offset and length of that entry's data in the file.
*/
-public class AssetFileDescriptor implements Parcelable {
- /**
- * Length used with {@link #AssetFileDescriptor(ParcelFileDescriptor, long, long)}
- * and {@link #getDeclaredLength} when a length has not been declared. This means
- * the data extends to the end of the file.
- */
- public static final long UNKNOWN_LENGTH = -1;
-
+public class AssetFileDescriptor {
private final ParcelFileDescriptor mFd;
private final long mStartOffset;
private final long mLength;
/**
* Create a new AssetFileDescriptor from the given values.
- * @param fd The underlying file descriptor.
- * @param startOffset The location within the file that the asset starts.
- * This must be 0 if length is UNKNOWN_LENGTH.
- * @param length The number of bytes of the asset, or
- * {@link #UNKNOWN_LENGTH if it extends to the end of the file.
*/
public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset,
long length) {
- if (length < 0 && startOffset != 0) {
- throw new IllegalArgumentException(
- "startOffset must be 0 when using UNKNOWN_LENGTH");
- }
mFd = fd;
mStartOffset = startOffset;
mLength = length;
@@ -86,33 +66,9 @@ public class AssetFileDescriptor implements Parcelable {
}
/**
- * Returns the total number of bytes of this asset entry's data. May be
- * {@link #UNKNOWN_LENGTH} if the asset extends to the end of the file.
- * If the AssetFileDescriptor was constructed with {@link #UNKNOWN_LENGTH},
- * this will use {@link ParcelFileDescriptor#getStatSize()
- * ParcelFileDescriptor.getStatSize()} to find the total size of the file,
- * returning that number if found or {@link #UNKNOWN_LENGTH} if it could
- * not be determined.
- *
- * @see #getDeclaredLength()
+ * Returns the total number of bytes of this asset entry's data.
*/
public long getLength() {
- if (mLength >= 0) {
- return mLength;
- }
- long len = mFd.getStatSize();
- return len >= 0 ? len : UNKNOWN_LENGTH;
- }
-
- /**
- * Return the actual number of bytes that were declared when the
- * AssetFileDescriptor was constructed. Will be
- * {@link #UNKNOWN_LENGTH} if the length was not declared, meaning data
- * should be read to the end of the file.
- *
- * @see #getDeclaredLength()
- */
- public long getDeclaredLength() {
return mLength;
}
@@ -122,227 +78,4 @@ public class AssetFileDescriptor implements Parcelable {
public void close() throws IOException {
mFd.close();
}
-
- /**
- * Create and return a new auto-close input stream for this asset. This
- * will either return a full asset {@link AutoCloseInputStream}, or
- * an underlying {@link ParcelFileDescriptor.AutoCloseInputStream
- * ParcelFileDescriptor.AutoCloseInputStream} depending on whether the
- * the object represents a complete file or sub-section of a file. You
- * should only call this once for a particular asset.
- */
- public FileInputStream createInputStream() throws IOException {
- if (mLength < 0) {
- return new ParcelFileDescriptor.AutoCloseInputStream(mFd);
- }
- return new AutoCloseInputStream(this);
- }
-
- /**
- * Create and return a new auto-close output stream for this asset. This
- * will either return a full asset {@link AutoCloseOutputStream}, or
- * an underlying {@link ParcelFileDescriptor.AutoCloseOutputStream
- * ParcelFileDescriptor.AutoCloseOutputStream} depending on whether the
- * the object represents a complete file or sub-section of a file. You
- * should only call this once for a particular asset.
- */
- public FileOutputStream createOutputStream() throws IOException {
- if (mLength < 0) {
- return new ParcelFileDescriptor.AutoCloseOutputStream(mFd);
- }
- return new AutoCloseOutputStream(this);
- }
-
- @Override
- public String toString() {
- return "{AssetFileDescriptor: " + mFd
- + " start=" + mStartOffset + " len=" + mLength + "}";
- }
-
- /**
- * An InputStream you can create on a ParcelFileDescriptor, which will
- * take care of calling {@link ParcelFileDescriptor#close
- * ParcelFileDescritor.close()} for you when the stream is closed.
- */
- public static class AutoCloseInputStream
- extends ParcelFileDescriptor.AutoCloseInputStream {
- private long mRemaining;
-
- public AutoCloseInputStream(AssetFileDescriptor fd) throws IOException {
- super(fd.getParcelFileDescriptor());
- super.skip(fd.getStartOffset());
- mRemaining = (int)fd.getLength();
- }
-
- @Override
- public int available() throws IOException {
- return mRemaining >= 0
- ? (mRemaining < 0x7fffffff ? (int)mRemaining : 0x7fffffff)
- : super.available();
- }
-
- @Override
- public int read() throws IOException {
- if (mRemaining >= 0) {
- if (mRemaining == 0) return -1;
- int res = super.read();
- if (res >= 0) mRemaining--;
- return res;
- }
-
- return super.read();
- }
-
- @Override
- public int read(byte[] buffer, int offset, int count) throws IOException {
- if (mRemaining >= 0) {
- if (mRemaining == 0) return -1;
- if (count > mRemaining) count = (int)mRemaining;
- int res = super.read(buffer, offset, count);
- if (res >= 0) mRemaining -= res;
- return res;
- }
-
- return super.read(buffer, offset, count);
- }
-
- @Override
- public int read(byte[] buffer) throws IOException {
- if (mRemaining >= 0) {
- if (mRemaining == 0) return -1;
- int count = buffer.length;
- if (count > mRemaining) count = (int)mRemaining;
- int res = super.read(buffer, 0, count);
- if (res >= 0) mRemaining -= res;
- return res;
- }
-
- return super.read(buffer);
- }
-
- @Override
- public long skip(long count) throws IOException {
- if (mRemaining >= 0) {
- if (mRemaining == 0) return -1;
- if (count > mRemaining) count = mRemaining;
- long res = super.skip(count);
- if (res >= 0) mRemaining -= res;
- return res;
- }
-
- // TODO Auto-generated method stub
- return super.skip(count);
- }
-
- @Override
- public void mark(int readlimit) {
- if (mRemaining >= 0) {
- // Not supported.
- return;
- }
- super.mark(readlimit);
- }
-
- @Override
- public boolean markSupported() {
- if (mRemaining >= 0) {
- return false;
- }
- return super.markSupported();
- }
-
- @Override
- public synchronized void reset() throws IOException {
- if (mRemaining >= 0) {
- // Not supported.
- return;
- }
- super.reset();
- }
- }
-
- /**
- * An OutputStream you can create on a ParcelFileDescriptor, which will
- * take care of calling {@link ParcelFileDescriptor#close
- * ParcelFileDescritor.close()} for you when the stream is closed.
- */
- public static class AutoCloseOutputStream
- extends ParcelFileDescriptor.AutoCloseOutputStream {
- private long mRemaining;
-
- public AutoCloseOutputStream(AssetFileDescriptor fd) throws IOException {
- super(fd.getParcelFileDescriptor());
- if (fd.getParcelFileDescriptor().seekTo(fd.getStartOffset()) < 0) {
- throw new IOException("Unable to seek");
- }
- mRemaining = (int)fd.getLength();
- }
-
- @Override
- public void write(byte[] buffer, int offset, int count) throws IOException {
- if (mRemaining >= 0) {
- if (mRemaining == 0) return;
- if (count > mRemaining) count = (int)mRemaining;
- super.write(buffer, offset, count);
- mRemaining -= count;
- return;
- }
-
- super.write(buffer, offset, count);
- }
-
- @Override
- public void write(byte[] buffer) throws IOException {
- if (mRemaining >= 0) {
- if (mRemaining == 0) return;
- int count = buffer.length;
- if (count > mRemaining) count = (int)mRemaining;
- super.write(buffer);
- mRemaining -= count;
- return;
- }
-
- super.write(buffer);
- }
-
- @Override
- public void write(int oneByte) throws IOException {
- if (mRemaining >= 0) {
- if (mRemaining == 0) return;
- super.write(oneByte);
- mRemaining--;
- return;
- }
-
- super.write(oneByte);
- }
- }
-
-
- /* Parcelable interface */
- public int describeContents() {
- return mFd.describeContents();
- }
-
- public void writeToParcel(Parcel out, int flags) {
- mFd.writeToParcel(out, flags);
- out.writeLong(mStartOffset);
- out.writeLong(mLength);
- }
-
- AssetFileDescriptor(Parcel src) {
- mFd = ParcelFileDescriptor.CREATOR.createFromParcel(src);
- mStartOffset = src.readLong();
- mLength = src.readLong();
- }
-
- public static final Parcelable.Creator<AssetFileDescriptor> CREATOR
- = new Parcelable.Creator<AssetFileDescriptor>() {
- public AssetFileDescriptor createFromParcel(Parcel in) {
- return new AssetFileDescriptor(in);
- }
- public AssetFileDescriptor[] newArray(int size) {
- return new AssetFileDescriptor[size];
- }
- };
}
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 0f3f270..17cb687 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -16,6 +16,8 @@
package android.content.res;
+import com.google.android.collect.Lists;
+
import com.android.internal.util.ArrayUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -111,8 +113,7 @@ public class ColorStateList implements Parcelable {
* Create a ColorStateList from an XML document, given a set of {@link Resources}.
*/
public static ColorStateList createFromXml(Resources r, XmlPullParser parser)
- throws XmlPullParserException, IOException {
-
+ throws XmlPullParserException, IOException {
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
@@ -124,16 +125,19 @@ public class ColorStateList implements Parcelable {
throw new XmlPullParserException("No start tag found");
}
- return createFromXmlInner(r, parser, attrs);
+ final ColorStateList colorStateList = createFromXmlInner(r, parser, attrs);
+
+ return colorStateList;
}
/* Create from inside an XML document. Called on a parser positioned at
* a tag in an XML document, tries to create a ColorStateList from that tag.
* Returns null if the tag is not a valid ColorStateList.
*/
- private static ColorStateList createFromXmlInner(Resources r, XmlPullParser parser,
- AttributeSet attrs) throws XmlPullParserException, IOException {
-
+ private static ColorStateList createFromXmlInner(Resources r,
+ XmlPullParser parser,
+ AttributeSet attrs)
+ throws XmlPullParserException, IOException {
ColorStateList colorStateList;
final String name = parser.getName();
@@ -142,7 +146,8 @@ public class ColorStateList implements Parcelable {
colorStateList = new ColorStateList();
} else {
throw new XmlPullParserException(
- parser.getPositionDescription() + ": invalid drawable tag " + name);
+ parser.getPositionDescription() + ": invalid drawable tag "
+ + name);
}
colorStateList.inflate(r, parser, attrs);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 1a963f6..5a0daea 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -46,7 +46,6 @@ public class Resources {
static final String TAG = "Resources";
private static final boolean DEBUG_LOAD = false;
private static final boolean DEBUG_CONFIG = false;
- private static final boolean TRACE_FOR_PRELOAD = false;
private static final int sSdkVersion = SystemProperties.getInt(
"ro.build.version.sdk", 0);
@@ -58,8 +57,6 @@ public class Resources {
// single-threaded, and after that these are immutable.
private static final SparseArray<Drawable.ConstantState> mPreloadedDrawables
= new SparseArray<Drawable.ConstantState>();
- private static final SparseArray<ColorStateList> mPreloadedColorStateLists
- = new SparseArray<ColorStateList>();
private static boolean mPreloaded;
/*package*/ final TypedValue mTmpValue = new TypedValue();
@@ -81,7 +78,7 @@ public class Resources {
private final Configuration mConfiguration = new Configuration();
/*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
PluralRules mPluralRule;
-
+
/**
* This exception is thrown by the resource APIs when a requested resource
* can not be found.
@@ -93,7 +90,7 @@ public class Resources {
public NotFoundException(String name) {
super(name);
}
- }
+ };
/**
* Create a new Resources object on top of an existing set of assets in an
@@ -1232,9 +1229,7 @@ public class Resources {
width = mMetrics.widthPixels;
height = mMetrics.heightPixels;
} else {
- //noinspection SuspiciousNameCombination
width = mMetrics.heightPixels;
- //noinspection SuspiciousNameCombination
height = mMetrics.widthPixels;
}
int keyboardHidden = mConfiguration.keyboardHidden;
@@ -1347,7 +1342,6 @@ public class Resources {
try {
return Integer.parseInt(name);
} catch (Exception e) {
- // Ignore
}
return mAssets.getResourceIdentifier(name, defType, defPackage);
}
@@ -1581,18 +1575,21 @@ public class Resources {
/*package*/ Drawable loadDrawable(TypedValue value, int id)
throws NotFoundException {
-
- if (TRACE_FOR_PRELOAD) {
- // Log only framework resources
- if ((id >>> 24) == 0x1) {
- final String name = getResourceName(id);
- if (name != null) android.util.Log.d("PreloadDrawable", name);
- }
+ if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT
+ && value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
+ // Should we be caching these? If we use constant colors much
+ // at all, most likely...
+ //System.out.println("Creating drawable for color: #" +
+ // Integer.toHexString(value.data));
+ Drawable dr = new ColorDrawable(value.data);
+ dr.setChangingConfigurations(value.changingConfigurations);
+ return dr;
}
- final int key = (value.assetCookie << 24) | value.data;
+ final int key = (value.assetCookie<<24)|value.data;
Drawable dr = getCachedDrawable(key);
-
+ //System.out.println("Cached drawable @ #" +
+ // Integer.toHexString(key.intValue()) + ": " + dr);
if (dr != null) {
return dr;
}
@@ -1600,52 +1597,46 @@ public class Resources {
Drawable.ConstantState cs = mPreloadedDrawables.get(key);
if (cs != null) {
dr = cs.newDrawable();
+
} else {
- if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
- value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
- dr = new ColorDrawable(value.data);
+ if (value.string == null) {
+ throw new NotFoundException(
+ "Resource is not a Drawable (color or path): " + value);
}
-
- if (dr == null) {
- if (value.string == null) {
- throw new NotFoundException(
- "Resource is not a Drawable (color or path): " + value);
+
+ String file = value.string.toString();
+
+ if (DEBUG_LOAD) Log.v(TAG, "Loading drawable for cookie "
+ + value.assetCookie + ": " + file);
+
+ if (file.endsWith(".xml")) {
+ try {
+ XmlResourceParser rp = loadXmlResourceParser(
+ file, id, value.assetCookie, "drawable");
+ dr = Drawable.createFromXml(this, rp);
+ rp.close();
+ } catch (Exception e) {
+ NotFoundException rnf = new NotFoundException(
+ "File " + file + " from drawable resource ID #0x"
+ + Integer.toHexString(id));
+ rnf.initCause(e);
+ throw rnf;
}
-
- String file = value.string.toString();
-
- if (DEBUG_LOAD) Log.v(TAG, "Loading drawable for cookie "
- + value.assetCookie + ": " + file);
-
- if (file.endsWith(".xml")) {
- try {
- XmlResourceParser rp = loadXmlResourceParser(
- file, id, value.assetCookie, "drawable");
- dr = Drawable.createFromXml(this, rp);
- rp.close();
- } catch (Exception e) {
- NotFoundException rnf = new NotFoundException(
- "File " + file + " from drawable resource ID #0x"
- + Integer.toHexString(id));
- rnf.initCause(e);
- throw rnf;
- }
-
- } else {
- try {
- InputStream is = mAssets.openNonAsset(
- value.assetCookie, file, AssetManager.ACCESS_BUFFER);
- // System.out.println("Opened file " + file + ": " + is);
- dr = Drawable.createFromResourceStream(this, value, is, file);
- is.close();
- // System.out.println("Created stream: " + dr);
- } catch (Exception e) {
- NotFoundException rnf = new NotFoundException(
- "File " + file + " from drawable resource ID #0x"
- + Integer.toHexString(id));
- rnf.initCause(e);
- throw rnf;
- }
+
+ } else {
+ try {
+ InputStream is = mAssets.openNonAsset(
+ value.assetCookie, file, AssetManager.ACCESS_BUFFER);
+ // System.out.println("Opened file " + file + ": " + is);
+ dr = Drawable.createFromResourceStream(this, value, is, file);
+ is.close();
+ // System.out.println("Created stream: " + dr);
+ } catch (Exception e) {
+ NotFoundException rnf = new NotFoundException(
+ "File " + file + " from drawable resource ID #0x"
+ + Integer.toHexString(id));
+ rnf.initCause(e);
+ throw rnf;
}
}
}
@@ -1656,13 +1647,13 @@ public class Resources {
if (cs != null) {
if (mPreloading) {
mPreloadedDrawables.put(key, cs);
- } else {
- synchronized (mTmpValue) {
- //Log.i(TAG, "Saving cached drawable @ #" +
- // Integer.toHexString(key.intValue())
- // + " in " + this + ": " + cs);
- mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
- }
+ }
+ synchronized (mTmpValue) {
+ //Log.i(TAG, "Saving cached drawable @ #" +
+ // Integer.toHexString(key.intValue())
+ // + " in " + this + ": " + cs);
+ mDrawableCache.put(
+ key, new WeakReference<Drawable.ConstantState>(cs));
}
}
}
@@ -1670,7 +1661,7 @@ public class Resources {
return dr;
}
- private Drawable getCachedDrawable(int key) {
+ private final Drawable getCachedDrawable(int key) {
synchronized (mTmpValue) {
WeakReference<Drawable.ConstantState> wr = mDrawableCache.get(key);
if (wr != null) { // we have the key
@@ -1691,40 +1682,13 @@ public class Resources {
/*package*/ ColorStateList loadColorStateList(TypedValue value, int id)
throws NotFoundException {
- if (TRACE_FOR_PRELOAD) {
- // Log only framework resources
- if ((id >>> 24) == 0x1) {
- final String name = getResourceName(id);
- if (name != null) android.util.Log.d("PreloadColorStateList", name);
- }
- }
-
- final int key = (value.assetCookie << 24) | value.data;
-
- ColorStateList csl;
-
- if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
- value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
-
- csl = mPreloadedColorStateLists.get(key);
- if (csl != null) {
- return csl;
- }
-
- csl = ColorStateList.valueOf(value.data);
- if (mPreloading) {
- mPreloadedColorStateLists.put(key, csl);
- }
-
- return csl;
+ if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT
+ && value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
+ return ColorStateList.valueOf(value.data);
}
- csl = getCachedColorStateList(key);
- if (csl != null) {
- return csl;
- }
-
- csl = mPreloadedColorStateLists.get(key);
+ final int key = (value.assetCookie<<24)|value.data;
+ ColorStateList csl = getCachedColorStateList(key);
if (csl != null) {
return csl;
}
@@ -1756,16 +1720,12 @@ public class Resources {
}
if (csl != null) {
- if (mPreloading) {
- mPreloadedColorStateLists.put(key, csl);
- } else {
- synchronized (mTmpValue) {
- //Log.i(TAG, "Saving cached color state list @ #" +
- // Integer.toHexString(key.intValue())
- // + " in " + this + ": " + csl);
- mColorStateListCache.put(
- key, new WeakReference<ColorStateList>(csl));
- }
+ synchronized (mTmpValue) {
+ //Log.i(TAG, "Saving cached color state list @ #" +
+ // Integer.toHexString(key.intValue())
+ // + " in " + this + ": " + csl);
+ mColorStateListCache.put(
+ key, new WeakReference<ColorStateList>(csl));
}
}
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
index e684cb8..3df7708 100644
--- a/core/java/android/content/res/StringBlock.java
+++ b/core/java/android/content/res/StringBlock.java
@@ -141,8 +141,6 @@ final class StringBlock {
int type = style[i];
if (localLOGV) Log.v(TAG, "Applying style span id=" + type
+ ", start=" + style[i+1] + ", end=" + style[i+2]);
-
-
if (type == ids.boldId) {
buffer.setSpan(new StyleSpan(Typeface.BOLD),
style[i+1], style[i+2]+1,
@@ -180,8 +178,9 @@ final class StringBlock {
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.listItemId) {
- addParagraphSpan(buffer, new BulletSpan(10),
- style[i+1], style[i+2]+1);
+ buffer.setSpan(new BulletSpan(10),
+ style[i+1], style[i+2]+1,
+ Spannable.SPAN_PARAGRAPH);
} else if (type == ids.marqueeId) {
buffer.setSpan(TextUtils.TruncateAt.MARQUEE,
style[i+1], style[i+2]+1,
@@ -195,8 +194,9 @@ final class StringBlock {
sub = subtag(tag, ";height=");
if (sub != null) {
int size = Integer.parseInt(sub);
- addParagraphSpan(buffer, new Height(size),
- style[i+1], style[i+2]+1);
+ buffer.setSpan(new Height(size),
+ style[i+1], style[i+2]+1,
+ Spannable.SPAN_PARAGRAPH);
}
sub = subtag(tag, ";size=");
@@ -231,28 +231,6 @@ final class StringBlock {
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
- } else if (tag.startsWith("annotation;")) {
- int len = tag.length();
- int next;
-
- for (int t = tag.indexOf(';'); t < len; t = next) {
- int eq = tag.indexOf('=', t);
- if (eq < 0) {
- break;
- }
-
- next = tag.indexOf(';', eq);
- if (next < 0) {
- next = len;
- }
-
- String key = tag.substring(t + 1, eq);
- String value = tag.substring(eq + 1, next);
-
- buffer.setSpan(new Annotation(key, value),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
}
}
@@ -261,34 +239,6 @@ final class StringBlock {
return new SpannedString(buffer);
}
- /**
- * If a translator has messed up the edges of paragraph-level markup,
- * fix it to actually cover the entire paragraph that it is attached to
- * instead of just whatever range they put it on.
- */
- private static void addParagraphSpan(Spannable buffer, Object what,
- int start, int end) {
- int len = buffer.length();
-
- if (start != 0 && start != len && buffer.charAt(start - 1) != '\n') {
- for (start--; start > 0; start--) {
- if (buffer.charAt(start - 1) == '\n') {
- break;
- }
- }
- }
-
- if (end != 0 && end != len && buffer.charAt(end - 1) != '\n') {
- for (end++; end < len; end++) {
- if (buffer.charAt(end - 1) == '\n') {
- break;
- }
- }
- }
-
- buffer.setSpan(what, start, end, Spannable.SPAN_PARAGRAPH);
- }
-
private static String subtag(String full, String attribute) {
int start = full.indexOf(attribute);
if (start < 0) {
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index 3a32c03..82a57dd 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -438,34 +438,6 @@ public class TypedArray {
throw new RuntimeException(getPositionDescription()
+ ": You must supply a " + name + " attribute.");
}
-
- /**
- * Special version of {@link #getDimensionPixelSize} for retrieving
- * {@link android.view.ViewGroup}'s layout_width and layout_height
- * attributes. This is only here for performance reasons; applications
- * should use {@link #getDimensionPixelSize}.
- *
- * @param index Index of the attribute to retrieve.
- * @param defValue The default value to return if this attribute is not
- * default or contains the wrong type of data.
- *
- * @return Attribute dimension value multiplied by the appropriate
- * metric and truncated to integer pixels.
- */
- public int getLayoutDimension(int index, int defValue) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type >= TypedValue.TYPE_FIRST_INT
- && type <= TypedValue.TYPE_LAST_INT) {
- return data[index+AssetManager.STYLE_DATA];
- } else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelSize(
- data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
- }
-
- return defValue;
- }
/**
* Retrieve a fractional unit attribute at <var>index</var>.
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 2af080a..87bb277 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -778,9 +778,9 @@ public class SQLiteDatabase extends SQLiteClosable {
}
/**
- * Returns the current database page size, in bytes.
+ * Returns the maximum size the database may grow to.
*
- * @return the database page size, in bytes
+ * @return the new maximum database size
*/
public long getPageSize() {
SQLiteStatement prog = null;
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 5889ad9..d169259 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -17,7 +17,6 @@
package android.database.sqlite;
import android.os.SystemClock;
-import android.util.Log;
/**
* A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
@@ -27,10 +26,6 @@ import android.util.Log;
*/
public class SQLiteStatement extends SQLiteProgram
{
- private static final String TAG = "SQLiteStatement";
-
- private final String mSql;
-
/**
* Don't use SQLiteStatement constructor directly, please use
* {@link SQLiteDatabase#compileStatement(String)}
@@ -39,11 +34,6 @@ public class SQLiteStatement extends SQLiteProgram
*/
/* package */ SQLiteStatement(SQLiteDatabase db, String sql) {
super(db, sql);
- if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
- mSql = sql;
- } else {
- mSql = null;
- }
}
/**
@@ -60,9 +50,6 @@ public class SQLiteStatement extends SQLiteProgram
acquireReference();
try {
- if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
- Log.v(TAG, "execute() for [" + mSql + "]");
- }
native_execute();
if (logStats) {
mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
@@ -90,9 +77,6 @@ public class SQLiteStatement extends SQLiteProgram
acquireReference();
try {
- if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
- Log.v(TAG, "executeInsert() for [" + mSql + "]");
- }
native_execute();
if (logStats) {
mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
@@ -119,9 +103,6 @@ public class SQLiteStatement extends SQLiteProgram
acquireReference();
try {
- if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
- Log.v(TAG, "simpleQueryForLong() for [" + mSql + "]");
- }
long retValue = native_1x1_long();
if (logStats) {
mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
@@ -148,9 +129,6 @@ public class SQLiteStatement extends SQLiteProgram
acquireReference();
try {
- if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
- Log.v(TAG, "simpleQueryForString() for [" + mSql + "]");
- }
String retValue = native_1x1_string();
if (logStats) {
mDatabase.logTimeStat(false /* write */, startTime, SystemClock.elapsedRealtime());
diff --git a/core/java/android/gadget/GadgetHost.java b/core/java/android/gadget/GadgetHost.java
index 3d88b58..31aed32 100644
--- a/core/java/android/gadget/GadgetHost.java
+++ b/core/java/android/gadget/GadgetHost.java
@@ -19,7 +19,6 @@ package android.gadget;
import android.content.Context;
import android.os.Handler;
import android.os.IBinder;
-import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -63,11 +62,7 @@ public class GadgetHost {
}
}
- class UpdateHandler extends Handler {
- public UpdateHandler(Looper looper) {
- super(looper);
- }
-
+ Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLE_UPDATE: {
@@ -80,9 +75,7 @@ public class GadgetHost {
}
}
}
- }
-
- Handler mHandler;
+ };
int mHostId;
Callbacks mCallbacks = new Callbacks();
@@ -91,7 +84,6 @@ public class GadgetHost {
public GadgetHost(Context context, int hostId) {
mContext = context;
mHostId = hostId;
- mHandler = new UpdateHandler(context.getMainLooper());
synchronized (sServiceLock) {
if (sService == null) {
IBinder b = ServiceManager.getService(Context.GADGET_SERVICE);
diff --git a/core/java/android/gadget/GadgetHostView.java b/core/java/android/gadget/GadgetHostView.java
index 5cbd988..a985bd4 100644
--- a/core/java/android/gadget/GadgetHostView.java
+++ b/core/java/android/gadget/GadgetHostView.java
@@ -18,13 +18,7 @@ package android.gadget;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.Paint;
-import android.os.Handler;
-import android.os.Message;
-import android.os.SystemClock;
import android.util.Config;
import android.util.Log;
import android.view.Gravity;
@@ -35,23 +29,16 @@ import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
+import android.widget.ViewAnimator;
/**
* Provides the glue to show gadget views. This class offers automatic animation
* between updates, and will try recycling old views for each incoming
* {@link RemoteViews}.
*/
-public class GadgetHostView extends FrameLayout {
+public class GadgetHostView extends ViewAnimator implements Animation.AnimationListener {
static final String TAG = "GadgetHostView";
- static final boolean LOGD = false;
- static final boolean CROSSFADE = false;
-
- static final int VIEW_MODE_NOINIT = 0;
- static final int VIEW_MODE_CONTENT = 1;
- static final int VIEW_MODE_ERROR = 2;
- static final int VIEW_MODE_DEFAULT = 3;
-
- static final int FADE_DURATION = 1000;
+ static final boolean LOGD = Config.LOGD || true;
// When we're inflating the initialLayout for a gadget, we only allow
// views that are allowed in RemoteViews.
@@ -60,17 +47,28 @@ public class GadgetHostView extends FrameLayout {
return clazz.isAnnotationPresent(RemoteViews.RemoteView.class);
}
};
-
- Context mContext;
+
+ Context mLocalContext;
int mGadgetId;
GadgetProviderInfo mInfo;
- View mView;
- int mViewMode = VIEW_MODE_NOINIT;
- int mLayoutId = -1;
- long mFadeStartTime = -1;
- Bitmap mOld;
- Paint mOldPaint = new Paint();
+
+ View mActiveView = null;
+ View mStaleView = null;
+
+ int mActiveLayoutId = -1;
+ int mStaleLayoutId = -1;
+
+ /**
+ * Last set of {@link RemoteViews} applied to {@link #mActiveView}
+ */
+ RemoteViews mActiveActions = null;
+
+ /**
+ * Flag indicating that {@link #mActiveActions} has been applied to
+ * {@link #mStaleView}, meaning it's readyto recycle.
+ */
+ boolean mStalePrepared = false;
/**
* Create a host view. Uses default fade animations.
@@ -88,13 +86,27 @@ public class GadgetHostView extends FrameLayout {
*/
public GadgetHostView(Context context, int animationIn, int animationOut) {
super(context);
- mContext = context;
+ mLocalContext = context;
+
+ // Prepare our default transition animations
+ setAnimateFirstView(true);
+ setInAnimation(context, animationIn);
+ setOutAnimation(context, animationOut);
+
+ // Watch for animation events to prepare recycling
+ Animation inAnimation = getInAnimation();
+ if (inAnimation != null) {
+ inAnimation.setAnimationListener(this);
+ }
}
/**
* Set the gadget that will be displayed by this view.
*/
public void setGadget(int gadgetId, GadgetProviderInfo info) {
+ if (mInfo != null) {
+ // TODO: remove the old view, or whatever
+ }
mGadgetId = gadgetId;
mInfo = info;
}
@@ -107,141 +119,92 @@ public class GadgetHostView extends FrameLayout {
return mInfo;
}
+ public void onAnimationEnd(Animation animation) {
+ // When our transition animation finishes, we should try bringing our
+ // newly-stale view up to the current view.
+ if (mActiveActions != null &&
+ mStaleLayoutId == mActiveActions.getLayoutId()) {
+ if (LOGD) Log.d(TAG, "after animation, layoutId matched so we're recycling old view");
+ mActiveActions.reapply(mLocalContext, mStaleView);
+ mStalePrepared = true;
+ }
+ }
+
+ public void onAnimationRepeat(Animation animation) {
+ }
+
+ public void onAnimationStart(Animation animation) {
+ }
+
/**
* Process a set of {@link RemoteViews} coming in as an update from the
* gadget provider. Will animate into these new views as needed.
*/
public void updateGadget(RemoteViews remoteViews) {
- if (LOGD) Log.d(TAG, "updateGadget called mOld=" + mOld);
+ if (LOGD) Log.d(TAG, "updateGadget called");
boolean recycled = false;
- View content = null;
+ View newContent = null;
Exception exception = null;
- // Capture the old view into a bitmap so we can do the crossfade.
- if (CROSSFADE) {
- if (mFadeStartTime < 0) {
- if (mView != null) {
- final int width = mView.getWidth();
- final int height = mView.getHeight();
- try {
- mOld = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- } catch (OutOfMemoryError e) {
- // we just won't do the fade
- mOld = null;
- }
- if (mOld != null) {
- //mView.drawIntoBitmap(mOld);
- }
- }
- }
+ if (remoteViews == null) {
+ newContent = getDefaultView();
}
- if (remoteViews == null) {
- if (mViewMode == VIEW_MODE_DEFAULT) {
- // We've already done this -- nothing to do.
- return;
- }
- content = getDefaultView();
- mLayoutId = -1;
- mViewMode = VIEW_MODE_DEFAULT;
- } else {
- int layoutId = remoteViews.getLayoutId();
-
- // If our stale view has been prepared to match active, and the new
- // layout matches, try recycling it
- if (content == null && layoutId == mLayoutId) {
- try {
- remoteViews.reapply(mContext, mView);
- content = mView;
- recycled = true;
- if (LOGD) Log.d(TAG, "was able to recycled existing layout");
- } catch (RuntimeException e) {
- exception = e;
- }
- }
-
- // Try normal RemoteView inflation
- if (content == null) {
- try {
- content = remoteViews.apply(mContext, this);
- if (LOGD) Log.d(TAG, "had to inflate new layout");
- } catch (RuntimeException e) {
- exception = e;
- }
+ // If our stale view has been prepared to match active, and the new
+ // layout matches, try recycling it
+ if (newContent == null && mStalePrepared &&
+ remoteViews.getLayoutId() == mStaleLayoutId) {
+ try {
+ remoteViews.reapply(mLocalContext, mStaleView);
+ newContent = mStaleView;
+ recycled = true;
+ if (LOGD) Log.d(TAG, "was able to recycled existing layout");
+ } catch (RuntimeException e) {
+ exception = e;
}
-
- mLayoutId = layoutId;
- mViewMode = VIEW_MODE_CONTENT;
}
- if (content == null) {
- if (mViewMode == VIEW_MODE_ERROR) {
- // We've already done this -- nothing to do.
- return ;
+ // Try normal RemoteView inflation
+ if (newContent == null) {
+ try {
+ newContent = remoteViews.apply(mLocalContext, this);
+ if (LOGD) Log.d(TAG, "had to inflate new layout");
+ } catch (RuntimeException e) {
+ exception = e;
}
- Log.w(TAG, "updateGadget couldn't find any view, using error view", exception);
- content = getErrorView();
- mViewMode = VIEW_MODE_ERROR;
}
- if (!recycled) {
- prepareView(content);
- addView(content);
+ if (exception != null && LOGD) {
+ Log.w(TAG, "Error inflating gadget " + getGadgetInfo(), exception);
}
-
- if (mView != content) {
- removeView(mView);
- mView = content;
+
+ if (newContent == null) {
+ // TODO: Should we throw an exception here for the host activity to catch?
+ // Maybe we should show a generic error widget.
+ if (LOGD) Log.d(TAG, "updateGadget couldn't find any view, so inflating error");
+ newContent = getErrorView();
}
-
- if (CROSSFADE) {
- if (mFadeStartTime < 0) {
- // if there is already an animation in progress, don't do anything --
- // the new view will pop in on top of the old one during the cross fade,
- // and that looks okay.
- mFadeStartTime = SystemClock.uptimeMillis();
- invalidate();
- }
+
+ if (!recycled) {
+ prepareView(newContent);
+ addView(newContent);
}
- }
-
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- if (CROSSFADE) {
- int alpha;
- int l = child.getLeft();
- int t = child.getTop();
- if (mFadeStartTime > 0) {
- alpha = (int)(((drawingTime-mFadeStartTime)*255)/FADE_DURATION);
- if (alpha > 255) {
- alpha = 255;
- }
- Log.d(TAG, "drawChild alpha=" + alpha + " l=" + l + " t=" + t
- + " w=" + child.getWidth());
- if (alpha != 255 && mOld != null) {
- mOldPaint.setAlpha(255-alpha);
- //canvas.drawBitmap(mOld, l, t, mOldPaint);
- }
- } else {
- alpha = 255;
- }
- int restoreTo = canvas.saveLayerAlpha(l, t, child.getWidth(), child.getHeight(), alpha,
- Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
- boolean rv = super.drawChild(canvas, child, drawingTime);
- canvas.restoreToCount(restoreTo);
- if (alpha < 255) {
- invalidate();
- } else {
- mFadeStartTime = -1;
- if (mOld != null) {
- mOld.recycle();
- mOld = null;
- }
- }
- return rv;
- } else {
- return super.drawChild(canvas, child, drawingTime);
+
+ showNext();
+
+ if (!recycled) {
+ removeView(mStaleView);
}
+
+ mStalePrepared = false;
+ mActiveActions = remoteViews;
+
+ mStaleView = mActiveView;
+ mActiveView = newContent;
+
+ mStaleLayoutId = mActiveLayoutId;
+ mActiveLayoutId = (remoteViews == null) ? -1 : remoteViews.getLayoutId();
}
/**
@@ -271,7 +234,7 @@ public class GadgetHostView extends FrameLayout {
try {
if (mInfo != null) {
- Context theirContext = mContext.createPackageContext(
+ Context theirContext = mLocalContext.createPackageContext(
mInfo.provider.getPackageName(), 0 /* no flags */);
LayoutInflater inflater = (LayoutInflater)
theirContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -303,9 +266,9 @@ public class GadgetHostView extends FrameLayout {
* Inflate and return a view that represents an error state.
*/
protected View getErrorView() {
- TextView tv = new TextView(mContext);
- tv.setText(com.android.internal.R.string.gadget_host_error_inflating);
- // TODO: get this color from somewhere.
+ TextView tv = new TextView(mLocalContext);
+ // TODO: move this error string and background color into resources
+ tv.setText("Error inflating gadget");
tv.setBackgroundColor(Color.argb(127, 0, 0, 0));
return tv;
}
diff --git a/core/java/android/gadget/GadgetManager.java b/core/java/android/gadget/GadgetManager.java
index d2c4055..a9a2c80 100644
--- a/core/java/android/gadget/GadgetManager.java
+++ b/core/java/android/gadget/GadgetManager.java
@@ -300,21 +300,5 @@ public class GadgetManager {
throw new RuntimeException("system server dead?", e);
}
}
-
- /**
- * Get the list of gadgetIds that have been bound to the given gadget
- * provider.
- *
- * @param provider The {@link android.content.BroadcastReceiver} that is the
- * gadget provider to find gadgetIds for.
- */
- public int[] getGadgetIds(ComponentName provider) {
- try {
- return sService.getGadgetIds(provider);
- }
- catch (RemoteException e) {
- throw new RuntimeException("system server dead?", e);
- }
- }
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 106c920..40a5b47 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -48,6 +48,7 @@ public class Camera {
private static final int ERROR_CALLBACK = 5;
private int mNativeContext; // accessed by native methods
+ private int mListenerContext;
private EventHandler mEventHandler;
private ShutterCallback mShutterCallback;
private PictureCallback mRawImageCallback;
diff --git a/core/java/android/inputmethodservice/ExtractEditText.java b/core/java/android/inputmethodservice/ExtractEditText.java
index 0295f69..52f8209 100644
--- a/core/java/android/inputmethodservice/ExtractEditText.java
+++ b/core/java/android/inputmethodservice/ExtractEditText.java
@@ -98,13 +98,6 @@ public class ExtractEditText extends EditText {
}
/**
- * Return true if the edit text is currently showing a scroll bar.
- */
- public boolean hasVerticalScrollBar() {
- return computeVerticalScrollRange() > computeVerticalScrollExtent();
- }
-
- /**
* Pretend like the window this view is in always has focus, so its
* highlight and cursor will be displayed.
*/
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 1e2e2f3..4be1fc7 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -26,9 +26,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.SystemClock;
import android.provider.Settings;
-import android.text.InputType;
import android.text.Layout;
import android.text.Spannable;
import android.text.method.MovementMethod;
@@ -51,7 +49,6 @@ import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethod;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.EditorInfo;
-import android.widget.Button;
import android.widget.FrameLayout;
import java.io.FileDescriptor;
@@ -244,8 +241,6 @@ public class InputMethodService extends AbstractInputMethodService {
boolean mIsFullscreen;
View mExtractView;
ExtractEditText mExtractEditText;
- ViewGroup mExtractAccessories;
- Button mExtractAction;
ExtractedText mExtractedText;
int mExtractedToken;
@@ -276,21 +271,6 @@ public class InputMethodService extends AbstractInputMethodService {
}
};
- final View.OnClickListener mActionClickListener = new View.OnClickListener() {
- public void onClick(View v) {
- final EditorInfo ei = getCurrentInputEditorInfo();
- final InputConnection ic = getCurrentInputConnection();
- if (ei != null && ic != null) {
- if (ei.actionId != 0) {
- ic.performEditorAction(ei.actionId);
- } else if ((ei.imeOptions&EditorInfo.IME_MASK_ACTION)
- != EditorInfo.IME_ACTION_NONE) {
- ic.performEditorAction(ei.imeOptions&EditorInfo.IME_MASK_ACTION);
- }
- }
- }
- };
-
/**
* Concrete implementation of
* {@link AbstractInputMethodService.AbstractInputMethodImpl} that provides
@@ -542,8 +522,6 @@ public class InputMethodService extends AbstractInputMethodService {
mExtractFrame = (FrameLayout)mRootView.findViewById(android.R.id.extractArea);
mExtractView = null;
mExtractEditText = null;
- mExtractAccessories = null;
- mExtractAction = null;
mFullscreenApplied = false;
mCandidatesFrame = (FrameLayout)mRootView.findViewById(android.R.id.candidatesArea);
@@ -725,7 +703,7 @@ public class InputMethodService extends AbstractInputMethodService {
setExtractView(v);
}
}
- startExtractingText(false);
+ startExtractingText();
}
}
@@ -929,17 +907,9 @@ public class InputMethodService extends AbstractInputMethodService {
mExtractEditText = (ExtractEditText)view.findViewById(
com.android.internal.R.id.inputExtractEditText);
mExtractEditText.setIME(this);
- mExtractAction = (Button)view.findViewById(
- com.android.internal.R.id.inputExtractAction);
- if (mExtractAction != null) {
- mExtractAccessories = (ViewGroup)view.findViewById(
- com.android.internal.R.id.inputExtractAccessories);
- }
- startExtractingText(false);
+ startExtractingText();
} else {
mExtractEditText = null;
- mExtractAccessories = null;
- mExtractAction = null;
}
}
@@ -1196,7 +1166,7 @@ public class InputMethodService extends AbstractInputMethodService {
}
if (doShowInput) {
- startExtractingText(false);
+ startExtractingText();
}
if (!wasVisible) {
@@ -1306,7 +1276,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (DEBUG) Log.v(TAG, "CALL: onStartInputView");
mInputViewStarted = true;
onStartInputView(mInputEditorInfo, restarting);
- startExtractingText(true);
+ startExtractingText();
} else if (mCandidatesVisibility == View.VISIBLE) {
if (DEBUG) Log.v(TAG, "CALL: onStartCandidatesView");
mCandidatesViewStarted = true;
@@ -1483,25 +1453,6 @@ public class InputMethodService extends AbstractInputMethodService {
static final int MOVEMENT_DOWN = -1;
static final int MOVEMENT_UP = -2;
- void reportExtractedMovement(int keyCode, int count) {
- int dx = 0, dy = 0;
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_LEFT:
- dx = -count;
- break;
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- dx = count;
- break;
- case KeyEvent.KEYCODE_DPAD_UP:
- dy = -count;
- break;
- case KeyEvent.KEYCODE_DPAD_DOWN:
- dy = count;
- break;
- }
- onExtractedCursorMovement(dx, dy);
- }
-
boolean doMovementKey(int keyCode, KeyEvent event, int count) {
final ExtractEditText eet = mExtractEditText;
if (isFullscreenMode() && isInputViewShown() && eet != null) {
@@ -1516,7 +1467,6 @@ public class InputMethodService extends AbstractInputMethodService {
if (count == MOVEMENT_DOWN) {
if (movement.onKeyDown(eet,
(Spannable)eet.getText(), keyCode, event)) {
- reportExtractedMovement(keyCode, 1);
return true;
}
} else if (count == MOVEMENT_UP) {
@@ -1525,9 +1475,7 @@ public class InputMethodService extends AbstractInputMethodService {
return true;
}
} else {
- if (movement.onKeyOther(eet, (Spannable)eet.getText(), event)) {
- reportExtractedMovement(keyCode, count);
- } else {
+ if (!movement.onKeyOther(eet, (Spannable)eet.getText(), event)) {
KeyEvent down = new KeyEvent(event, KeyEvent.ACTION_DOWN);
if (movement.onKeyDown(eet,
(Spannable)eet.getText(), keyCode, down)) {
@@ -1540,7 +1488,6 @@ public class InputMethodService extends AbstractInputMethodService {
movement.onKeyUp(eet,
(Spannable)eet.getText(), keyCode, up);
}
- reportExtractedMovement(keyCode, count);
}
}
}
@@ -1560,97 +1507,6 @@ public class InputMethodService extends AbstractInputMethodService {
}
/**
- * Send the given key event code (as defined by {@link KeyEvent}) to the
- * current input connection is a key down + key up event pair. The sent
- * events have {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD}
- * set, so that the recipient can identify them as coming from a software
- * input method, and
- * {@link KeyEvent#FLAG_KEEP_TOUCH_MODE KeyEvent.FLAG_KEEP_TOUCH_MODE}, so
- * that they don't impact the current touch mode of the UI.
- *
- * @param keyEventCode The raw key code to send, as defined by
- * {@link KeyEvent}.
- */
- public void sendDownUpKeyEvents(int keyEventCode) {
- InputConnection ic = getCurrentInputConnection();
- if (ic == null) return;
- long eventTime = SystemClock.uptimeMillis();
- ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
- KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
- ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
- KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
- }
-
- /**
- * Ask the input target to execute its default action via
- * {@link InputConnection#performEditorAction
- * InputConnection.performEditorAction()}.
- *
- * @param fromEnterKey If true, this will be executed as if the user had
- * pressed an enter key on the keyboard, that is it will <em>not</em>
- * be done if the editor has set {@link EditorInfo#IME_FLAG_NO_ENTER_ACTION
- * EditorInfo.IME_FLAG_NO_ENTER_ACTION}. If false, the action will be
- * sent regardless of how the editor has set that flag.
- *
- * @return Returns a boolean indicating whether an action has been sent.
- * If false, either the editor did not specify a default action or it
- * does not want an action from the enter key. If true, the action was
- * sent (or there was no input connection at all).
- */
- public boolean sendDefaultEditorAction(boolean fromEnterKey) {
- EditorInfo ei = getCurrentInputEditorInfo();
- if (ei != null &&
- (!fromEnterKey || (ei.imeOptions &
- EditorInfo.IME_FLAG_NO_ENTER_ACTION) == 0) &&
- (ei.imeOptions & EditorInfo.IME_MASK_ACTION) !=
- EditorInfo.IME_ACTION_NONE) {
- // If the enter key was pressed, and the editor has a default
- // action associated with pressing enter, then send it that
- // explicit action instead of the key event.
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.performEditorAction(ei.imeOptions&EditorInfo.IME_MASK_ACTION);
- }
- return true;
- }
-
- return false;
- }
-
- /**
- * Send the given UTF-16 character to the current input connection. Most
- * characters will be delivered simply by calling
- * {@link InputConnection#commitText InputConnection.commitText()} with
- * the character; some, however, may be handled different. In particular,
- * the enter character ('\n') will either be delivered as an action code
- * or a raw key event, as appropriate.
- *
- * @param charCode The UTF-16 character code to send.
- */
- public void sendKeyChar(char charCode) {
- switch (charCode) {
- case '\n': // Apps may be listening to an enter key to perform an action
- if (!sendDefaultEditorAction(true)) {
- sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER);
- }
- break;
- default:
- // Make sure that digits go through any text watcher on the client side.
- if (charCode >= '0' && charCode <= '9') {
- sendDownUpKeyEvents(charCode - '0' + KeyEvent.KEYCODE_0);
- } else {
- InputConnection ic = getCurrentInputConnection();
- if (ic != null) {
- ic.commitText(String.valueOf((char) charCode), 1);
- }
- }
- break;
- }
- }
-
- /**
* This is called when the user has moved the cursor in the extracted
* text view, when running in fullsreen mode. The default implementation
* performs the corresponding selection change on the underlying text
@@ -1666,36 +1522,11 @@ public class InputMethodService extends AbstractInputMethodService {
/**
* This is called when the user has clicked on the extracted text view,
* when running in fullscreen mode. The default implementation hides
- * the candidates view when this happens, but only if the extracted text
- * editor has a vertical scroll bar because its text doesn't fit.
- * Re-implement this to provide whatever behavior you want.
+ * the candidates view when this happens. Re-implement this to provide
+ * whatever behavior you want.
*/
public void onExtractedTextClicked() {
- if (mExtractEditText == null) {
- return;
- }
- if (mExtractEditText.hasVerticalScrollBar()) {
- setCandidatesViewShown(false);
- }
- }
-
- /**
- * This is called when the user has performed a cursor movement in the
- * extracted text view, when it is running in fullscreen mode. The default
- * implementation hides the candidates view when a vertical movement
- * happens, but only if the extracted text editor has a vertical scroll bar
- * because its text doesn't fit.
- * Re-implement this to provide whatever behavior you want.
- * @param dx The amount of cursor movement in the x dimension.
- * @param dy The amount of cursor movement in the y dimension.
- */
- public void onExtractedCursorMovement(int dx, int dy) {
- if (mExtractEditText == null || dy == 0) {
- return;
- }
- if (mExtractEditText.hasVerticalScrollBar()) {
- setCandidatesViewShown(false);
- }
+ setCandidatesViewShown(false);
}
/**
@@ -1714,74 +1545,7 @@ public class InputMethodService extends AbstractInputMethodService {
return true;
}
- /**
- * Return text that can be used as a button label for the given
- * {@link EditorInfo#imeOptions EditorInfo.imeOptions}. Returns null
- * if there is no action requested. Note that there is no guarantee that
- * the returned text will be relatively short, so you probably do not
- * want to use it as text on a soft keyboard key label.
- *
- * @param imeOptions The value from @link EditorInfo#imeOptions EditorInfo.imeOptions}.
- *
- * @return Returns a label to use, or null if there is no action.
- */
- public CharSequence getTextForImeAction(int imeOptions) {
- switch (imeOptions&EditorInfo.IME_MASK_ACTION) {
- case EditorInfo.IME_ACTION_NONE:
- return null;
- case EditorInfo.IME_ACTION_GO:
- return getText(com.android.internal.R.string.ime_action_go);
- case EditorInfo.IME_ACTION_SEARCH:
- return getText(com.android.internal.R.string.ime_action_search);
- case EditorInfo.IME_ACTION_SEND:
- return getText(com.android.internal.R.string.ime_action_send);
- case EditorInfo.IME_ACTION_NEXT:
- return getText(com.android.internal.R.string.ime_action_next);
- default:
- return getText(com.android.internal.R.string.ime_action_default);
- }
- }
-
- /**
- * Called when it is time to update the actions available from a full-screen
- * IME. You do not need to deal with this if you are using the standard
- * full screen extract UI. If replacing it, you will need to re-implement
- * this to put the action in your own UI and handle it.
- */
- public void onUpdateExtractingAccessories(EditorInfo ei) {
- if (mExtractAccessories == null) {
- return;
- }
- final boolean hasAction = ei.actionLabel != null || (
- (ei.imeOptions&EditorInfo.IME_MASK_ACTION) != EditorInfo.IME_ACTION_NONE &&
- (ei.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0);
- if (hasAction) {
- mExtractAccessories.setVisibility(View.VISIBLE);
- if (ei.actionLabel != null) {
- mExtractAction.setText(ei.actionLabel);
- } else {
- mExtractAction.setText(getTextForImeAction(ei.imeOptions));
- }
- mExtractAction.setOnClickListener(mActionClickListener);
- } else {
- mExtractAccessories.setVisibility(View.GONE);
- mExtractAction.setOnClickListener(null);
- }
- }
-
- /**
- * This is called when, while currently displayed in extract mode, the
- * current input target changes. The default implementation will
- * auto-hide the IME if the new target is not a full editor, since this
- * can be an confusing experience for the user.
- */
- public void onExtractingInputChanged(EditorInfo ei) {
- if (ei.inputType == InputType.TYPE_NULL) {
- dismissSoftInput(InputMethodManager.HIDE_NOT_ALWAYS);
- }
- }
-
- void startExtractingText(boolean inputChanged) {
+ void startExtractingText() {
final ExtractEditText eet = mExtractEditText;
if (eet != null && getCurrentInputStarted()
&& isFullscreenMode()) {
@@ -1793,13 +1557,9 @@ public class InputMethodService extends AbstractInputMethodService {
req.hintMaxChars = 10000;
mExtractedText = getCurrentInputConnection().getExtractedText(req,
InputConnection.GET_EXTRACTED_TEXT_MONITOR);
-
- final EditorInfo ei = getCurrentInputEditorInfo();
-
try {
eet.startInternalChanges();
- onUpdateExtractingAccessories(ei);
- int inputType = ei.inputType;
+ int inputType = getCurrentInputEditorInfo().inputType;
if ((inputType&EditorInfo.TYPE_MASK_CLASS)
== EditorInfo.TYPE_CLASS_TEXT) {
if ((inputType&EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE) != 0) {
@@ -1807,7 +1567,7 @@ public class InputMethodService extends AbstractInputMethodService {
}
}
eet.setInputType(inputType);
- eet.setHint(ei.hintText);
+ eet.setHint(mInputEditorInfo.hintText);
if (mExtractedText != null) {
eet.setEnabled(true);
eet.setExtractedText(mExtractedText);
@@ -1818,10 +1578,6 @@ public class InputMethodService extends AbstractInputMethodService {
} finally {
eet.finishInternalChanges();
}
-
- if (inputChanged) {
- onExtractingInputChanged(ei);
- }
}
}
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index c838779..886e688 100755
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -74,6 +74,7 @@ public class KeyboardView extends View implements View.OnClickListener {
* For keys that repeat, this is only called once.
* @param primaryCode the unicode of the key being pressed. If the touch is not on a valid
* key, the value will be zero.
+ * @hide Pending API Council approval
*/
void onPress(int primaryCode);
@@ -81,6 +82,7 @@ public class KeyboardView extends View implements View.OnClickListener {
* Called when the user releases a key. This is sent after the {@link #onKey} is called.
* For keys that repeat, this is only called once.
* @param primaryCode the code of the key that was released
+ * @hide Pending API Council approval
*/
void onRelease(int primaryCode);
@@ -97,12 +99,6 @@ public class KeyboardView extends View implements View.OnClickListener {
void onKey(int primaryCode, int[] keyCodes);
/**
- * Sends a sequence of characters to the listener.
- * @param text the sequence of characters to be displayed.
- */
- void onText(CharSequence text);
-
- /**
* Called when the user quickly moves the finger from right to left.
*/
void swipeLeft();
@@ -398,7 +394,6 @@ public class KeyboardView extends View implements View.OnClickListener {
requestLayout();
invalidate();
computeProximityThreshold(keyboard);
- mMiniKeyboardCache.clear(); // Not really necessary to do every time, but will free up views
}
/**
@@ -704,7 +699,9 @@ public class KeyboardView extends View implements View.OnClickListener {
if (index != NOT_A_KEY && index < mKeys.length) {
final Key key = mKeys[index];
if (key.text != null) {
- mKeyboardActionListener.onText(key.text);
+ for (int i = 0; i < key.text.length(); i++) {
+ mKeyboardActionListener.onKey(key.text.charAt(i), key.codes);
+ }
mKeyboardActionListener.onRelease(NOT_A_KEY);
} else {
int code = key.codes[0];
@@ -795,7 +792,7 @@ 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(mLabelTextSize);
mPreviewText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
mPreviewText.setTextSize(mPreviewTextSizeLarge);
@@ -899,11 +896,6 @@ public class KeyboardView extends View implements View.OnClickListener {
dismissPopupKeyboard();
}
- public void onText(CharSequence text) {
- mKeyboardActionListener.onText(text);
- dismissPopupKeyboard();
- }
-
public void swipeLeft() { }
public void swipeRight() { }
public void swipeUp() { }
@@ -1110,8 +1102,6 @@ public class KeyboardView extends View implements View.OnClickListener {
mHandler.removeMessages(MSG_SHOW_PREVIEW);
dismissPopupKeyboard();
-
- mMiniKeyboardCache.clear();
}
@Override
diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java
index ccef97e..f816caa 100644
--- a/core/java/android/net/SSLCertificateSocketFactory.java
+++ b/core/java/android/net/SSLCertificateSocketFactory.java
@@ -16,46 +16,39 @@
package android.net;
-import android.content.Context;
+import android.util.Log;
+import android.util.Config;
import android.net.http.DomainNameChecker;
import android.os.SystemProperties;
-import android.util.Config;
-import android.util.Log;
-import com.android.internal.net.SSLSessionCache;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
-import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
+import java.security.GeneralSecurityException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
-import javax.net.SocketFactory;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * SSLSocketFactory that allows skipping the certificate chain validation
- * based on system setting (socket.relaxsslcheck=yes, ro.secure=1 - for
- * testing only).
- *
- * It also adds a readTimeout that will be set on each created socket.
- * The factory will use SSL session persistence if enabled by config.
- */
public class SSLCertificateSocketFactory extends SSLSocketFactory {
+ private static final boolean DBG = true;
private static final String LOG_TAG = "SSLCertificateSocketFactory";
private static X509TrustManager sDefaultTrustManager;
+ private final int socketReadTimeoutForSslHandshake;
+
static {
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
@@ -90,36 +83,14 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
}
};
- private static SSLSocketFactory factory;
-
- /**
- * Initialize a single default factory to be used for all returned
- * sockets.
- *
- * Because of the signature of getDefault(int timeout) it needs to create
- * a new instance which encapsulates the timeout on each call. We want
- * to share a single SSLContext and SSLSessionCache.
- *
- * Can be called multiple times - but only the first will initialize the factory.
- *
- * @param androidContext will be used for SSL session persistence. Null for backward
- * compatibility, no SSL persistence.
- * @hide
- */
- public static synchronized void setupDefaultFactory(Context androidContext) {
- if ( factory != null) {
- // Can only be initialized once, to avoid having multiple caches.
- return;
- }
- factory = SSLSessionCache.getSocketFactory(androidContext, TRUST_MANAGER);
- }
-
- private final int socketReadTimeoutForSslHandshake;
+ private SSLSocketFactory factory;
public SSLCertificateSocketFactory(int socketReadTimeoutForSslHandshake)
throws NoSuchAlgorithmException, KeyManagementException {
- this.socketReadTimeoutForSslHandshake
- = socketReadTimeoutForSslHandshake;
+ SSLContext context = SSLContext.getInstance("TLS");
+ context.init(null, TRUST_MANAGER, new java.security.SecureRandom());
+ factory = (SSLSocketFactory) context.getSocketFactory();
+ this.socketReadTimeoutForSslHandshake = socketReadTimeoutForSslHandshake;
}
/**
@@ -132,11 +103,6 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory {
*/
public static SocketFactory getDefault(int socketReadTimeoutForSslHandshake) {
try {
- if (factory == null) {
- // The delegated factory was not initialized explicitely with a context.
- // Use a default one.
- setupDefaultFactory(null);
- }
return new SSLCertificateSocketFactory(socketReadTimeoutForSslHandshake);
} catch (NoSuchAlgorithmException e) {
Log.e(LOG_TAG,
diff --git a/core/java/android/net/http/AndroidHttpClient.java b/core/java/android/net/http/AndroidHttpClient.java
index 0c4fcda..4fb1499 100644
--- a/core/java/android/net/http/AndroidHttpClient.java
+++ b/core/java/android/net/http/AndroidHttpClient.java
@@ -47,8 +47,6 @@ import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.BasicHttpProcessor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.BasicHttpContext;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
-import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
import java.io.IOException;
import java.io.InputStream;
@@ -57,7 +55,6 @@ import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.net.URI;
-import java.security.KeyManagementException;
import android.util.Log;
import android.content.ContentResolver;
@@ -101,13 +98,10 @@ public final class AndroidHttpClient implements HttpClient {
/**
* Create a new HttpClient with reasonable defaults (which you can update).
- *
* @param userAgent to report in your HTTP requests.
- * @param sessionCache persistent session cache
* @return AndroidHttpClient for you to use for all your requests.
*/
- public static AndroidHttpClient newInstance(String userAgent,
- SSLClientSessionCache sessionCache) {
+ public static AndroidHttpClient newInstance(String userAgent) {
HttpParams params = new BasicHttpParams();
// Turn off stale checking. Our connections break all the time anyway,
@@ -129,8 +123,7 @@ public final class AndroidHttpClient implements HttpClient {
schemeRegistry.register(new Scheme("http",
PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https",
- socketFactoryWithCache(sessionCache), 443));
-
+ SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager manager =
new ThreadSafeClientConnManager(params, schemeRegistry);
@@ -139,41 +132,6 @@ public final class AndroidHttpClient implements HttpClient {
return new AndroidHttpClient(manager, params);
}
- /**
- * Returns a socket factory backed by the given persistent session cache.
- *
- * @param sessionCache to retrieve sessions from, null for no cache
- */
- private static SSLSocketFactory socketFactoryWithCache(
- SSLClientSessionCache sessionCache) {
- if (sessionCache == null) {
- // Use the default factory which doesn't support persistent
- // caching.
- return SSLSocketFactory.getSocketFactory();
- }
-
- // Create a new SSL context backed by the cache.
- // TODO: Keep a weak *identity* hash map of caches to engines. In the
- // mean time, if we have two engines for the same cache, they'll still
- // share sessions but will have to do so through the persistent cache.
- SSLContextImpl sslContext = new SSLContextImpl();
- try {
- sslContext.engineInit(null, null, null, sessionCache, null);
- } catch (KeyManagementException e) {
- throw new AssertionError(e);
- }
- return new SSLSocketFactory(sslContext.engineGetSocketFactory());
- }
-
- /**
- * Create a new HttpClient with reasonable defaults (which you can update).
- * @param userAgent to report in your HTTP requests.
- * @return AndroidHttpClient for you to use for all your requests.
- */
- public static AndroidHttpClient newInstance(String userAgent) {
- return newInstance(userAgent, null /* session cache */);
- }
-
private final HttpClient delegate;
private RuntimeException mLeakedException = new IllegalStateException(
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index 0edbe5b..b7f7368 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -16,6 +16,8 @@
package android.net.http;
+import android.os.SystemClock;
+
import java.io.IOException;
import java.security.cert.Certificate;
@@ -26,13 +28,23 @@ import java.security.cert.X509Certificate;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Enumeration;
+
+import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
+import org.apache.http.HttpHost;
+
+import org.bouncycastle.asn1.x509.X509Name;
+
/**
* Class responsible for all server certificate validation functionality
*
@@ -40,6 +52,9 @@ import javax.net.ssl.X509TrustManager;
*/
class CertificateChainValidator {
+ private static long sTotal = 0;
+ private static long sTotalReused = 0;
+
/**
* The singleton instance of the certificate chain validator
*/
@@ -95,42 +110,91 @@ class CertificateChainValidator {
* @return An SSL error object if there is an error and null otherwise
*/
public SslError doHandshakeAndValidateServerCertificates(
- HttpsConnection connection, SSLSocket sslSocket, String domain)
- throws IOException {
- X509Certificate[] serverCertificates = null;
+ HttpsConnection connection, SSLSocket sslSocket, String domain)
+ throws SSLHandshakeException, IOException {
- // start handshake, close the socket if we fail
- try {
- sslSocket.setUseClientMode(true);
- sslSocket.startHandshake();
- } catch (IOException e) {
- closeSocketThrowException(
- sslSocket, e.getMessage(),
- "failed to perform SSL handshake");
+ ++sTotal;
+
+ SSLContext sslContext = HttpsConnection.getContext();
+ if (sslContext == null) {
+ closeSocketThrowException(sslSocket, "SSL context is null");
}
- // retrieve the chain of the server peer certificates
- Certificate[] peerCertificates =
- sslSocket.getSession().getPeerCertificates();
+ X509Certificate[] serverCertificates = null;
- if (peerCertificates == null || peerCertificates.length <= 0) {
- closeSocketThrowException(
- sslSocket, "failed to retrieve peer certificates");
- } else {
- serverCertificates =
- new X509Certificate[peerCertificates.length];
- for (int i = 0; i < peerCertificates.length; ++i) {
- serverCertificates[i] =
- (X509Certificate)(peerCertificates[i]);
+ long sessionBeforeHandshakeLastAccessedTime = 0;
+ byte[] sessionBeforeHandshakeId = null;
+
+ SSLSession sessionAfterHandshake = null;
+
+ synchronized(sslContext) {
+ // get SSL session before the handshake
+ SSLSession sessionBeforeHandshake =
+ getSSLSession(sslContext, connection.getHost());
+ if (sessionBeforeHandshake != null) {
+ sessionBeforeHandshakeLastAccessedTime =
+ sessionBeforeHandshake.getLastAccessedTime();
+
+ sessionBeforeHandshakeId =
+ sessionBeforeHandshake.getId();
+ }
+
+ // start handshake, close the socket if we fail
+ try {
+ sslSocket.setUseClientMode(true);
+ sslSocket.startHandshake();
+ } catch (IOException e) {
+ closeSocketThrowException(
+ sslSocket, e.getMessage(),
+ "failed to perform SSL handshake");
}
- // update the SSL certificate associated with the connection
- if (connection != null) {
- if (serverCertificates[0] != null) {
- connection.setCertificate(
- new SslCertificate(serverCertificates[0]));
+ // retrieve the chain of the server peer certificates
+ Certificate[] peerCertificates =
+ sslSocket.getSession().getPeerCertificates();
+
+ if (peerCertificates == null || peerCertificates.length <= 0) {
+ closeSocketThrowException(
+ sslSocket, "failed to retrieve peer certificates");
+ } else {
+ serverCertificates =
+ new X509Certificate[peerCertificates.length];
+ for (int i = 0; i < peerCertificates.length; ++i) {
+ serverCertificates[i] =
+ (X509Certificate)(peerCertificates[i]);
+ }
+
+ // update the SSL certificate associated with the connection
+ if (connection != null) {
+ if (serverCertificates[0] != null) {
+ connection.setCertificate(
+ new SslCertificate(serverCertificates[0]));
+ }
}
}
+
+ // get SSL session after the handshake
+ sessionAfterHandshake =
+ getSSLSession(sslContext, connection.getHost());
+ }
+
+ if (sessionBeforeHandshakeLastAccessedTime != 0 &&
+ sessionAfterHandshake != null &&
+ Arrays.equals(
+ sessionBeforeHandshakeId, sessionAfterHandshake.getId()) &&
+ sessionBeforeHandshakeLastAccessedTime <
+ sessionAfterHandshake.getLastAccessedTime()) {
+
+ if (HttpLog.LOGV) {
+ HttpLog.v("SSL session was reused: total reused: "
+ + sTotalReused
+ + " out of total of: " + sTotal);
+
+ ++sTotalReused;
+ }
+
+ // no errors!!!
+ return null;
}
// check if the first certificate in the chain is for this site
@@ -152,6 +216,7 @@ class CertificateChainValidator {
}
}
+ //
// first, we validate the chain using the standard validation
// solution; if we do not find any errors, we are done; if we
// fail the standard validation, we re-validate again below,
@@ -328,14 +393,14 @@ class CertificateChainValidator {
}
private void closeSocketThrowException(
- SSLSocket socket, String errorMessage, String defaultErrorMessage)
- throws IOException {
+ SSLSocket socket, String errorMessage, String defaultErrorMessage)
+ throws SSLHandshakeException, IOException {
closeSocketThrowException(
socket, errorMessage != null ? errorMessage : defaultErrorMessage);
}
- private void closeSocketThrowException(SSLSocket socket,
- String errorMessage) throws IOException {
+ private void closeSocketThrowException(SSLSocket socket, String errorMessage)
+ throws SSLHandshakeException, IOException {
if (HttpLog.LOGV) {
HttpLog.v("validation error: " + errorMessage);
}
@@ -351,4 +416,29 @@ class CertificateChainValidator {
throw new SSLHandshakeException(errorMessage);
}
+
+ /**
+ * @param sslContext The SSL context shared accross all the SSL sessions
+ * @param host The host associated with the session
+ * @return A suitable SSL session from the SSL context
+ */
+ private SSLSession getSSLSession(SSLContext sslContext, HttpHost host) {
+ if (sslContext != null && host != null) {
+ Enumeration en = sslContext.getClientSessionContext().getIds();
+ while (en.hasMoreElements()) {
+ byte[] id = (byte[]) en.nextElement();
+ if (id != null) {
+ SSLSession session =
+ sslContext.getClientSessionContext().getSession(id);
+ if (session.isValid() &&
+ host.getHostName().equals(session.getPeerHost()) &&
+ host.getPort() == session.getPeerPort()) {
+ return session;
+ }
+ }
+ }
+ }
+
+ return null;
+ }
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 7590bfe..6f9d6c6 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -16,8 +16,6 @@ import android.util.SparseArray;
*/
public abstract class BatteryStats implements Parcelable {
- private static final boolean LOCAL_LOGV = false;
-
/**
* A constant indicating a partial wake lock timer.
*/
@@ -74,7 +72,6 @@ public abstract class BatteryStats implements Parcelable {
private static final String WAKELOCK_DATA = "wakelock";
private static final String NETWORK_DATA = "network";
private static final String BATTERY_DATA = "battery";
- private static final String MISC_DATA = "misc";
private final StringBuilder mFormatBuilder = new StringBuilder(8);
private final Formatter mFormatter = new Formatter(mFormatBuilder);
@@ -96,11 +93,11 @@ public abstract class BatteryStats implements Parcelable {
* Returns the total time in microseconds associated with this Timer for the
* selected type of statistics.
*
- * @param batteryRealtime system realtime on battery in microseconds
+ * @param now system uptime time in microseconds
* @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT
* @return a time in microseconds
*/
- public abstract long getTotalTime(long batteryRealtime, int which);
+ public abstract long getTotalTime(long now, int which);
/**
* Temporary for debugging.
@@ -225,11 +222,11 @@ public abstract class BatteryStats implements Parcelable {
/**
* Returns the amount of time spent started.
*
- * @param batteryUptime elapsed uptime on battery in microseconds.
+ * @param now elapsed realtime in microseconds.
* @param which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
* @return
*/
- public abstract long getStartTime(long batteryUptime, int which);
+ public abstract long getStartTime(long now, int which);
/**
* Returns the total number of times startService() has been called.
@@ -259,16 +256,16 @@ public abstract class BatteryStats implements Parcelable {
*
* {@hide}
*/
- public abstract long getScreenOnTime(long batteryRealtime, int which);
+ public abstract long getBatteryScreenOnTime();
/**
- * Returns the time in milliseconds that the phone has been on while the device was
- * running on battery.
+ * Returns the time in milliseconds that the screen has been on while the device was
+ * plugged in.
*
* {@hide}
*/
- public abstract long getPhoneOnTime(long batteryRealtime, int which);
-
+ public abstract long getPluggedScreenOnTime();
+
/**
* Return whether we are currently running on battery.
*/
@@ -385,18 +382,18 @@ public abstract class BatteryStats implements Parcelable {
*
* @param sb a StringBuilder object.
* @param timer a Timer object contining the wakelock times.
- * @param batteryRealtime the current on-battery time in microseconds.
+ * @param now the current time in microseconds.
* @param name the name of the wakelock.
* @param which which one of STATS_TOTAL, STATS_LAST, or STATS_CURRENT.
* @param linePrefix a String to be prepended to each line of output.
* @return the line prefix
*/
- private static final String printWakeLock(StringBuilder sb, Timer timer,
- long batteryRealtime, String name, int which, String linePrefix) {
+ private static final String printWakeLock(StringBuilder sb, Timer timer, long now,
+ String name, int which, String linePrefix) {
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTimeMicros = timer.getTotalTime(batteryRealtime, which);
+ long totalTimeMicros = timer.getTotalTime(now, which);
long totalTimeMillis = (totalTimeMicros + 500) / 1000;
int count = timer.getCount(which);
@@ -473,30 +470,26 @@ public abstract class BatteryStats implements Parcelable {
* @param which
*/
private final void dumpCheckinLocked(PrintWriter pw, int which) {
- final long rawUptime = SystemClock.uptimeMillis() * 1000;
- final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
- final long batteryUptime = getBatteryUptime(rawUptime);
- final long batteryRealtime = getBatteryRealtime(rawRealtime);
- final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
- final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
- final long totalRealtime = computeRealtime(rawRealtime, which);
- final long totalUptime = computeUptime(rawUptime, which);
- final long screenOnTime = getScreenOnTime(batteryRealtime, which);
- final long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
+ long uSecTime = SystemClock.elapsedRealtime() * 1000;
+ final long uSecNow = getBatteryUptime(uSecTime);
StringBuilder sb = new StringBuilder(128);
+ long batteryUptime = computeBatteryUptime(uSecNow, which);
+ long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which);
+ long elapsedRealtime = computeRealtime(uSecTime, which);
+ long uptime = computeUptime(SystemClock.uptimeMillis() * 1000, which);
String category = STAT_NAMES[which];
// Dump "battery" stat
dumpLine(pw, 0 /* uid */, category, BATTERY_DATA,
which == STATS_TOTAL ? getStartCount() : "N/A",
- whichBatteryUptime / 1000, whichBatteryRealtime / 1000,
- totalUptime / 1000, totalRealtime / 1000);
-
- // Dump misc stats
- dumpLine(pw, 0 /* uid */, category, MISC_DATA,
- screenOnTime / 1000, phoneOnTime / 1000);
+ batteryUptime / 1000,
+ formatRatioLocked(batteryUptime, elapsedRealtime),
+ batteryRealtime / 1000,
+ formatRatioLocked(batteryRealtime, elapsedRealtime),
+ uptime / 1000,
+ elapsedRealtime / 1000);
SparseArray<? extends Uid> uidStats = getUidStats();
final int NU = uidStats.size();
@@ -515,11 +508,11 @@ public abstract class BatteryStats implements Parcelable {
Uid.Wakelock wl = ent.getValue();
String linePrefix = "";
sb.setLength(0);
- linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_FULL), uSecNow,
"full", which, linePrefix);
- linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), uSecNow,
"partial", which, linePrefix);
- linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
+ linePrefix = printWakeLockCheckin(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), uSecNow,
"window", which, linePrefix);
// Only log if we had at lease one wakelock...
@@ -538,7 +531,7 @@ public abstract class BatteryStats implements Parcelable {
Timer timer = se.getSensorTime();
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
+ long totalTime = (timer.getTotalTime(uSecNow, which) + 500) / 1000;
int count = timer.getCount(which);
if (totalTime != 0) {
dumpLine(pw, uid, category, SENSOR_DATA, sensorNumber, totalTime, count);
@@ -578,7 +571,7 @@ public abstract class BatteryStats implements Parcelable {
for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
: serviceStats.entrySet()) {
BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
- long startTime = ss.getStartTime(batteryUptime, which);
+ long startTime = ss.getStartTime(uSecNow, which);
int starts = ss.getStarts(which);
int launches = ss.getLaunches(which);
if (startTime != 0 || starts != 0 || launches != 0) {
@@ -598,40 +591,29 @@ public abstract class BatteryStats implements Parcelable {
@SuppressWarnings("unused")
private final void dumpLocked(Printer pw, String prefix, int which) {
- final long rawUptime = SystemClock.uptimeMillis() * 1000;
- final long rawRealtime = SystemClock.elapsedRealtime() * 1000;
- final long batteryUptime = getBatteryUptime(rawUptime);
- final long batteryRealtime = getBatteryUptime(rawRealtime);
-
- final long whichBatteryUptime = computeBatteryUptime(rawUptime, which);
- final long whichBatteryRealtime = computeBatteryRealtime(rawRealtime, which);
- final long totalRealtime = computeRealtime(rawRealtime, which);
- final long totalUptime = computeUptime(rawUptime, which);
-
+ long uSecTime = SystemClock.elapsedRealtime() * 1000;
+ final long uSecNow = getBatteryUptime(uSecTime);
+
StringBuilder sb = new StringBuilder(128);
+ long batteryUptime = computeBatteryUptime(uSecNow, which);
+ long batteryRealtime = computeBatteryRealtime(getBatteryRealtime(uSecTime), which);
+ long elapsedRealtime = computeRealtime(uSecTime, which);
+ long uptime = computeUptime(SystemClock.uptimeMillis() * 1000, which);
pw.println(prefix
- + " Time on battery: " + formatTimeMs(whichBatteryUptime / 1000)
- + "(" + formatRatioLocked(whichBatteryUptime, totalRealtime)
+ + " Time on battery: " + formatTimeMs(batteryUptime / 1000) + "("
+ + formatRatioLocked(batteryUptime, elapsedRealtime)
+ ") uptime, "
- + formatTimeMs(whichBatteryRealtime / 1000) + "("
- + formatRatioLocked(whichBatteryRealtime, totalRealtime)
+ + formatTimeMs(batteryRealtime / 1000) + "("
+ + formatRatioLocked(batteryRealtime, elapsedRealtime)
+ ") realtime");
pw.println(prefix
+ " Total: "
- + formatTimeMs(totalUptime / 1000)
+ + formatTimeMs(uptime / 1000)
+ "uptime, "
- + formatTimeMs(totalRealtime / 1000)
+ + formatTimeMs(elapsedRealtime / 1000)
+ "realtime");
- long screenOnTime = getScreenOnTime(batteryRealtime, which);
- long phoneOnTime = getPhoneOnTime(batteryRealtime, which);
- pw.println(prefix
- + " Time with screen on: " + formatTimeMs(screenOnTime / 1000)
- + "(" + formatRatioLocked(screenOnTime, whichBatteryRealtime)
- + "), time with phone on: " + formatTimeMs(phoneOnTime / 1000)
- + "(" + formatRatioLocked(phoneOnTime, whichBatteryRealtime) + ")");
-
pw.println(" ");
SparseArray<? extends Uid> uidStats = getUidStats();
@@ -659,11 +641,11 @@ public abstract class BatteryStats implements Parcelable {
sb.append(prefix);
sb.append(" Wake lock ");
sb.append(ent.getKey());
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), batteryRealtime,
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_FULL), uSecNow,
"full", which, linePrefix);
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), batteryRealtime,
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_PARTIAL), uSecNow,
"partial", which, linePrefix);
- linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), batteryRealtime,
+ linePrefix = printWakeLock(sb, wl.getWakeTime(WAKE_TYPE_WINDOW), uSecNow,
"window", which, linePrefix);
if (!linePrefix.equals(": ")) {
sb.append(" realtime");
@@ -695,7 +677,7 @@ public abstract class BatteryStats implements Parcelable {
Timer timer = se.getSensorTime();
if (timer != null) {
// Convert from microseconds to milliseconds with rounding
- long totalTime = (timer.getTotalTime(batteryRealtime, which) + 500) / 1000;
+ long totalTime = (timer.getTotalTime(uSecNow, which) + 500) / 1000;
int count = timer.getCount(which);
//timer.logState();
if (totalTime != 0) {
@@ -755,7 +737,7 @@ public abstract class BatteryStats implements Parcelable {
for (Map.Entry<String, ? extends BatteryStats.Uid.Pkg.Serv> sent
: serviceStats.entrySet()) {
BatteryStats.Uid.Pkg.Serv ss = sent.getValue();
- long startTime = ss.getStartTime(batteryUptime, which);
+ long startTime = ss.getStartTime(uSecNow, which);
int starts = ss.getStarts(which);
int launches = ss.getLaunches(which);
if (startTime != 0 || starts != 0 || launches != 0) {
@@ -805,24 +787,9 @@ public abstract class BatteryStats implements Parcelable {
@SuppressWarnings("unused")
public void dumpCheckinLocked(PrintWriter pw, String[] args) {
- boolean isUnpluggedOnly = false;
-
- for (String arg : args) {
- if ("-u".equals(arg)) {
- if (LOCAL_LOGV) Log.v("BatteryStats", "Dumping unplugged data");
- isUnpluggedOnly = true;
- }
- }
-
- if (isUnpluggedOnly) {
- dumpCheckinLocked(pw, STATS_UNPLUGGED);
- }
- else {
- dumpCheckinLocked(pw, STATS_TOTAL);
- dumpCheckinLocked(pw, STATS_LAST);
- dumpCheckinLocked(pw, STATS_UNPLUGGED);
- dumpCheckinLocked(pw, STATS_CURRENT);
- }
+ dumpCheckinLocked(pw, STATS_TOTAL);
+ dumpCheckinLocked(pw, STATS_LAST);
+ dumpCheckinLocked(pw, STATS_UNPLUGGED);
+ dumpCheckinLocked(pw, STATS_CURRENT);
}
-
}
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 3fcb18e..ed138cb 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -76,11 +76,6 @@ public class ParcelFileDescriptor implements Parcelable {
public static final int MODE_TRUNCATE = 0x04000000;
/**
- * For use with {@link #open}: append to end of file while writing.
- */
- public static final int MODE_APPEND = 0x02000000;
-
- /**
* Create a new ParcelFileDescriptor accessing a given file.
*
* @param file The file to be opened.
@@ -143,19 +138,6 @@ public class ParcelFileDescriptor implements Parcelable {
}
/**
- * Return the total size of the file representing this fd, as determined
- * by stat(). Returns -1 if the fd is not a file.
- */
- public native long getStatSize();
-
- /**
- * This is needed for implementing AssetFileDescriptor.AutoCloseOutputStream,
- * and I really don't think we want it to be public.
- * @hide
- */
- public native long seekTo(long pos);
-
- /**
* Close the ParcelFileDescriptor. This implementation closes the underlying
* OS resources allocated to represent this stream.
*
diff --git a/core/java/android/pim/ICalendar.java b/core/java/android/pim/ICalendar.java
index cc0f45e..4a5d7e4 100644
--- a/core/java/android/pim/ICalendar.java
+++ b/core/java/android/pim/ICalendar.java
@@ -405,15 +405,13 @@ public class ICalendar {
// TODO: get rid of this -- handle all of the parsing in one pass through
// the text.
private static String normalizeText(String text) {
+ // first we deal with line folding, by replacing all "\r\n " strings
+ // with nothing
+ text = text.replaceAll("\r\n ", "");
+
// it's supposed to be \r\n, but not everyone does that
text = text.replaceAll("\r\n", "\n");
text = text.replaceAll("\r", "\n");
-
- // we deal with line folding, by replacing all "\n " strings
- // with nothing. The RFC specifies "\r\n " to be folded, but
- // we handle "\n " and "\r " too because we can get those.
- text = text.replaceAll("\n ", "");
-
return text;
}
@@ -442,7 +440,7 @@ public class ICalendar {
current = parseLine(line, state, current);
// if the provided component was null, we will return the root
// NOTE: in this case, if the first line is not a BEGIN, a
- // FormatException will get thrown.
+ // FormatException will get thrown.
if (component == null) {
component = current;
}
@@ -526,7 +524,8 @@ public class ICalendar {
private static String extractValue(ParserState state)
throws FormatException {
String line = state.line;
- if (state.index >= line.length() || line.charAt(state.index) != ':') {
+ char c = line.charAt(state.index);
+ if (c != ':') {
throw new FormatException("Expected ':' before end of line in "
+ line);
}
diff --git a/core/java/android/provider/Checkin.java b/core/java/android/provider/Checkin.java
index 1454089..0cdac53 100644
--- a/core/java/android/provider/Checkin.java
+++ b/core/java/android/provider/Checkin.java
@@ -62,9 +62,6 @@ public final class Checkin {
AUTOTEST_FAILURE,
AUTOTEST_SEQUENCE_BEGIN,
AUTOTEST_SUITE_BEGIN,
- AUTOTEST_TCPDUMP_BEGIN,
- AUTOTEST_TCPDUMP_DATA,
- AUTOTEST_TCPDUMP_END,
AUTOTEST_TEST_BEGIN,
AUTOTEST_TEST_FAILURE,
AUTOTEST_TEST_SUCCESS,
@@ -101,14 +98,14 @@ public final class Checkin {
SETUP_SERVER_ERROR,
SETUP_SERVER_TIMEOUT,
SETUP_NO_DATA_NETWORK,
+ SYSTEM_APP_NOT_RESPONDING,
SYSTEM_BOOT,
SYSTEM_LAST_KMSG,
SYSTEM_RECOVERY_LOG,
SYSTEM_RESTART,
SYSTEM_SERVICE_LOOPING,
SYSTEM_TOMBSTONE,
- TEST,
- BATTERY_DISCHARGE_INFO,
+ TEST,
}
}
@@ -193,9 +190,6 @@ public final class Checkin {
// The category is used for GTalk service messages
public static final String CATEGORY = "android.server.checkin.CHECKIN";
-
- // If true indicates that the checkin should only transfer market related data
- public static final String EXTRA_MARKET_ONLY = "market_only";
}
private static final String TAG = "Checkin";
diff --git a/core/java/android/provider/Im.java b/core/java/android/provider/Im.java
index 19ad158..bea857f 100644
--- a/core/java/android/provider/Im.java
+++ b/core/java/android/provider/Im.java
@@ -2044,37 +2044,4 @@ public class Im {
*/
public static final Uri CONTENT_URI = Uri.parse("content://im/lastRmqId");
}
-
- /**
- * Columns for IM branding resource map cache table. This table caches the result of
- * loading the branding resources to speed up IM landing page start.
- */
- public interface BrandingResourceMapCacheColumns {
- /**
- * The provider ID
- * <P>Type: INTEGER</P>
- */
- String PROVIDER_ID = "provider_id";
- /**
- * The application resource ID
- * <P>Type: INTEGER</P>
- */
- String APP_RES_ID = "app_res_id";
- /**
- * The plugin resource ID
- * <P>Type: INTEGER</P>
- */
- String PLUGIN_RES_ID = "plugin_res_id";
- }
-
- /**
- * The table for caching the result of loading IM branding resources.
- */
- public static final class BrandingResourceMapCache
- implements BaseColumns, BrandingResourceMapCacheColumns {
- /**
- * The content:// style URL for this table.
- */
- public static final Uri CONTENT_URI = Uri.parse("content://im/brandingResMapCache");
- }
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 10ca5d5..4a784c8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2183,12 +2183,6 @@ public final class Settings {
public static final String CHECKIN_INTERVAL = "checkin_interval";
/**
- * Boolean indicating if the market app should force market only checkins on
- * install/uninstall. Any non-0 value is considered true.
- */
- public static final String MARKET_FORCE_CHECKIN = "market_force_checkin";
-
- /**
* How frequently (in seconds) to check the memory status of the
* device.
*/
@@ -2461,14 +2455,6 @@ public final class Settings {
"gtalk_ssl_handshake_timeout_ms";
/**
- * Enable use of ssl session caching.
- * 'db' - save each session in a per-process database
- * not set or any other value - normal java in-memory caching.
- * Other cache types may be added.
- */
- public static final String SSL_SESSION_CACHE = "ssl_session_cache";
-
- /**
* How many bytes long a message has to be, in order to be gzipped.
*/
public static final String SYNC_MIN_GZIP_BYTES =
@@ -2780,29 +2766,11 @@ public final class Settings {
public static final String VOICE_SEARCH_ENCODING_WIFI = "voice_search_encoding_wifi";
/**
- * Whether to use automatic gain control in voice search (0 = disable, 1 = enable).
- * To be factored out of this class.
+ * Prefix for rules that launch automatic instrumentation test cycles.
+ * The format is the InstrumentationTestRunner (or compatible) package and class,
+ * followed optionally by space-separated key value pairs to pass to it.
*/
- public static final String VOICE_SEARCH_ENABLE_AGC = "voice_search_enable_agc";
-
- /**
- * Whether to use noise suppression in voice search (0 = disable, 1 = enable).
- * To be factored out of this class.
- */
- public static final String VOICE_SEARCH_ENABLE_NS = "voice_search_enable_ns";
-
- /**
- * Whether to use the IIR filter in voice search (0 = disable, 1 = enable).
- * To be factored out of this class.
- */
- public static final String VOICE_SEARCH_ENABLE_IIR = "voice_search_enable_iir";
-
- /**
- * List of test suites (local disk filename) for the automatic instrumentation test runner.
- * The file format is similar to automated_suites.xml, see AutoTesterService.
- * If this setting is missing or empty, the automatic test runner will not start.
- */
- public static final String AUTOTEST_SUITES_FILE = "autotest_suites_file";
+ public static final String AUTOTEST_PREFIX = "autotest:";
/**
* Interval between synchronous checkins forced by the automatic test runner.
@@ -2817,15 +2785,6 @@ public final class Settings {
*/
public static final String AUTOTEST_REBOOT_SECONDS = "autotest_reboot_seconds";
-
- /**
- * Threshold values for the duration and level of a discharge cycle, under
- * which we log discharge cycle info.
- */
- public static final String BATTERY_DISCHARGE_DURATION_THRESHOLD =
- "battery_discharge_duration_threshold";
- public static final String BATTERY_DISCHARGE_THRESHOLD = "battery_discharge_threshold";
-
/**
* @deprecated
* @hide
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index f8bc765..58f9491 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -15,7 +15,8 @@
*/
/**
- * TODO: Move this to services.jar
+ * TODO: Move this to
+ * java/services/com/android/server/BluetoothA2dpService.java
* and make the contructor package private again.
* @hide
*/
@@ -34,16 +35,15 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Binder;
-import android.os.Handler;
-import android.os.Message;
import android.provider.Settings;
import android.util.Log;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
+import java.util.HashMap;
+import java.util.Iterator;
public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private static final String TAG = "BluetoothA2dpService";
@@ -57,8 +57,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private static final String A2DP_SINK_ADDRESS = "a2dp_sink_address";
private static final String BLUETOOTH_ENABLED = "bluetooth_enabled";
- private static final int MESSAGE_CONNECT_TO = 1;
-
private final Context mContext;
private final IntentFilter mIntentFilter;
private HashMap<String, SinkState> mAudioDevices;
@@ -88,7 +86,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
mIntentFilter = new IntentFilter(BluetoothIntent.ENABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.BOND_STATE_CHANGED_ACTION);
- mIntentFilter.addAction(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION);
mContext.registerReceiver(mReceiver, mIntentFilter);
if (device.isEnabled()) {
@@ -126,37 +123,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
break;
}
- } else if (action.equals(BluetoothIntent.REMOTE_DEVICE_CONNECTED_ACTION)) {
- if (getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF) {
- // This device is a preferred sink. Make an A2DP connection
- // after a delay. We delay to avoid connection collisions,
- // and to give other profiles such as HFP a chance to
- // connect first.
- Message msg = Message.obtain(mHandler, MESSAGE_CONNECT_TO, address);
- mHandler.sendMessageDelayed(msg, 6000);
- }
- }
- }
- };
-
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MESSAGE_CONNECT_TO:
- String address = (String)msg.obj;
- // check device is still preferred, and nothing is currently
- // connected
- if (getSinkPriority(address) > BluetoothA2dp.PRIORITY_OFF &&
- lookupSinksMatchingStates(new int[] {
- BluetoothA2dp.STATE_CONNECTING,
- BluetoothA2dp.STATE_CONNECTED,
- BluetoothA2dp.STATE_PLAYING,
- BluetoothA2dp.STATE_DISCONNECTING}).size() == 0) {
- log("Auto-connecting A2DP to sink " + address);
- connectSink(address);
- }
- break;
}
}
};
@@ -176,10 +142,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private synchronized void onBluetoothDisable() {
if (mAudioDevices != null) {
- // copy to allow modification during iteration
- String[] paths = new String[mAudioDevices.size()];
- paths = mAudioDevices.keySet().toArray(paths);
- for (String path : paths) {
+ for (String path : mAudioDevices.keySet()) {
switch (mAudioDevices.get(path).state) {
case BluetoothA2dp.STATE_CONNECTING:
case BluetoothA2dp.STATE_CONNECTED:
@@ -271,8 +234,17 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
public synchronized List<String> listConnectedSinks() {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return lookupSinksMatchingStates(new int[] {BluetoothA2dp.STATE_CONNECTED,
- BluetoothA2dp.STATE_PLAYING});
+ List<String> connectedSinks = new ArrayList<String>();
+ if (mAudioDevices == null) {
+ return connectedSinks;
+ }
+ for (SinkState sink : mAudioDevices.values()) {
+ if (sink.state == BluetoothA2dp.STATE_CONNECTED ||
+ sink.state == BluetoothA2dp.STATE_PLAYING) {
+ connectedSinks.add(sink.address);
+ }
+ }
+ return connectedSinks;
}
public synchronized int getSinkState(String address) {
@@ -326,11 +298,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
// bluez 3.36 quietly disconnects the previous sink when a new sink
// is connected, so we need to mark all previously connected sinks as
// disconnected
-
- // copy to allow modification during iteration
- String[] paths = new String[mAudioDevices.size()];
- paths = mAudioDevices.keySet().toArray(paths);
- for (String oldPath : paths) {
+ for (String oldPath : mAudioDevices.keySet()) {
if (path.equals(oldPath)) {
continue;
}
@@ -382,22 +350,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return null;
}
- private synchronized List<String> lookupSinksMatchingStates(int[] states) {
- List<String> sinks = new ArrayList<String>();
- if (mAudioDevices == null) {
- return sinks;
- }
- for (SinkState sink : mAudioDevices.values()) {
- for (int state : states) {
- if (sink.state == state) {
- sinks.add(sink.address);
- break;
- }
- }
- }
- return sinks;
- }
-
private synchronized void updateState(String path, int state) {
if (mAudioDevices == null) return;
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 950ff3a..fa53a60 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -141,20 +141,6 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
mBondState.setBondState(address, BluetoothDevice.BOND_NOT_BONDED,
BluetoothDevice.UNBOND_REASON_AUTH_CANCELED);
}
-
- // Remove remoteServiceChannelCallbacks
- HashMap<String, IBluetoothDeviceCallback> callbacksMap =
- mEventLoop.getRemoteServiceChannelCallbacks();
- IBluetoothDeviceCallback callback;
-
- for (String address : callbacksMap.keySet()) {
- callback = callbacksMap.get(address);
- try {
- callback.onGetRemoteServiceChannelResult(address, BluetoothError.ERROR_DISABLED);
- } catch (RemoteException e) {}
- callbacksMap.remove(address);
- }
-
// update mode
Intent intent = new Intent(BluetoothIntent.SCAN_MODE_CHANGED_ACTION);
intent.putExtra(BluetoothIntent.SCAN_MODE, BluetoothDevice.SCAN_MODE_NONE);
@@ -583,18 +569,10 @@ public class BluetoothDeviceService extends IBluetoothDevice.Stub {
}
address = address.toUpperCase();
- String[] bonding = mBondState.listInState(BluetoothDevice.BOND_BONDING);
- if (bonding.length > 0 && !bonding[0].equals(address)) {
- log("Ignoring createBond(): another device is bonding");
- // a different device is currently bonding, fail
- return false;
- }
-
// Check for bond state only if we are not performing auto
// pairing exponential back-off attempts.
if (!mBondState.isAutoPairingAttemptsInProgress(address) &&
- mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
- log("Ignoring createBond(): this device is already bonding or bonded");
+ mBondState.getBondState(address) != BluetoothDevice.BOND_NOT_BONDED) {
return false;
}
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index 0c04839..c18675e 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -35,7 +35,6 @@ import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
-import android.view.inputmethod.EditorInfo;
import java.io.IOException;
import java.util.ArrayList;
@@ -78,7 +77,6 @@ public final class SearchableInfo implements Parcelable {
private int mIconId = 0;
private int mSearchButtonText = 0;
private int mSearchInputType = 0;
- private int mSearchImeOptions = 0;
private String mSuggestAuthority = null;
private String mSuggestPath = null;
private String mSuggestSelection = null;
@@ -431,9 +429,8 @@ public final class SearchableInfo implements Parcelable {
com.android.internal.R.styleable.Searchable_searchButtonText, 0);
mSearchInputType = a.getInt(com.android.internal.R.styleable.Searchable_inputType,
InputType.TYPE_CLASS_TEXT |
+ InputType.TYPE_TEXT_FLAG_SEARCH |
InputType.TYPE_TEXT_VARIATION_NORMAL);
- mSearchImeOptions = a.getInt(com.android.internal.R.styleable.Searchable_imeOptions,
- EditorInfo.IME_ACTION_SEARCH);
setSearchModeFlags();
if (DBG_INHIBIT_SUGGESTIONS == 0) {
@@ -746,17 +743,6 @@ public final class SearchableInfo implements Parcelable {
}
/**
- * Return the input method options specified in the searchable attributes.
- * This will default to EditorInfo.ACTION_SEARCH if not specified (which is
- * appropriate for a search box).
- *
- * @return the input type
- */
- public int getImeOptions() {
- return mSearchImeOptions;
- }
-
- /**
* Return the list of searchable activities, for use in the drop-down.
*/
public static ArrayList<SearchableInfo> getSearchablesList() {
@@ -796,7 +782,6 @@ public final class SearchableInfo implements Parcelable {
mIconId = in.readInt();
mSearchButtonText = in.readInt();
mSearchInputType = in.readInt();
- mSearchImeOptions = in.readInt();
setSearchModeFlags();
mSuggestAuthority = in.readString();
@@ -833,7 +818,6 @@ public final class SearchableInfo implements Parcelable {
dest.writeInt(mIconId);
dest.writeInt(mSearchButtonText);
dest.writeInt(mSearchInputType);
- dest.writeInt(mSearchImeOptions);
dest.writeString(mSuggestAuthority);
dest.writeString(mSuggestPath);
diff --git a/core/java/android/speech/srec/package.html b/core/java/android/speech/srec/package.html
index 9a99df8..723b30b 100644
--- a/core/java/android/speech/srec/package.html
+++ b/core/java/android/speech/srec/package.html
@@ -1,6 +1,5 @@
<HTML>
<BODY>
Simple, synchronous SREC speech recognition API.
-@hide
</BODY>
</HTML>
diff --git a/core/java/android/text/InputType.java b/core/java/android/text/InputType.java
index f643f92..a073cf4 100644
--- a/core/java/android/text/InputType.java
+++ b/core/java/android/text/InputType.java
@@ -128,6 +128,11 @@ public interface InputType {
*/
public static final int TYPE_TEXT_FLAG_IME_MULTI_LINE = 0x00040000;
+ /**
+ * Flag for {@link #TYPE_CLASS_TEXT}: flags any text being used as a search string
+ */
+ public static final int TYPE_TEXT_FLAG_SEARCH = 0x00080000;
+
// ----------------------------------------------------------------------
/**
diff --git a/core/java/android/text/Styled.java b/core/java/android/text/Styled.java
index 0aa2004..05c27ea 100644
--- a/core/java/android/text/Styled.java
+++ b/core/java/android/text/Styled.java
@@ -16,26 +16,25 @@
package android.text;
-import android.graphics.Canvas;
import android.graphics.Paint;
-import android.text.style.CharacterStyle;
-import android.text.style.MetricAffectingSpan;
-import android.text.style.ReplacementSpan;
-
-/**
- * This class provides static methods for drawing and measuring styled texts, like
- * {@link android.text.Spanned} object with {@link android.text.style.ReplacementSpan}.
- * @hide
- */
-public class Styled
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.graphics.Typeface;
+import android.graphics.MaskFilter;
+import android.graphics.Rasterizer;
+import android.graphics.LayerRasterizer;
+import android.text.style.*;
+
+/* package */ class Styled
{
private static float each(Canvas canvas,
Spanned text, int start, int end,
int dir, boolean reverse,
float x, int top, int y, int bottom,
- Paint.FontMetricsInt fmi,
+ Paint.FontMetricsInt fm,
+ TextPaint realPaint,
TextPaint paint,
- TextPaint workPaint,
boolean needwid) {
boolean havewid = false;
@@ -44,9 +43,9 @@ public class Styled
ReplacementSpan replacement = null;
- paint.bgColor = 0;
- paint.baselineShift = 0;
- workPaint.set(paint);
+ realPaint.bgColor = 0;
+ realPaint.baselineShift = 0;
+ paint.set(realPaint);
if (spans.length > 0) {
for (int i = 0; i < spans.length; i++) {
@@ -56,7 +55,7 @@ public class Styled
replacement = (ReplacementSpan)span;
}
else {
- span.updateDrawState(workPaint);
+ span.updateDrawState(paint);
}
}
}
@@ -75,66 +74,66 @@ public class Styled
tmpend = end;
}
- if (fmi != null) {
- workPaint.getFontMetricsInt(fmi);
+ if (fm != null) {
+ paint.getFontMetricsInt(fm);
}
if (canvas != null) {
- if (workPaint.bgColor != 0) {
- int c = workPaint.getColor();
- Paint.Style s = workPaint.getStyle();
- workPaint.setColor(workPaint.bgColor);
- workPaint.setStyle(Paint.Style.FILL);
+ if (paint.bgColor != 0) {
+ int c = paint.getColor();
+ Paint.Style s = paint.getStyle();
+ paint.setColor(paint.bgColor);
+ paint.setStyle(Paint.Style.FILL);
if (!havewid) {
- ret = workPaint.measureText(tmp, tmpstart, tmpend);
+ ret = paint.measureText(tmp, tmpstart, tmpend);
havewid = true;
}
if (dir == Layout.DIR_RIGHT_TO_LEFT)
- canvas.drawRect(x - ret, top, x, bottom, workPaint);
+ canvas.drawRect(x - ret, top, x, bottom, paint);
else
- canvas.drawRect(x, top, x + ret, bottom, workPaint);
+ canvas.drawRect(x, top, x + ret, bottom, paint);
- workPaint.setStyle(s);
- workPaint.setColor(c);
+ paint.setStyle(s);
+ paint.setColor(c);
}
if (dir == Layout.DIR_RIGHT_TO_LEFT) {
if (!havewid) {
- ret = workPaint.measureText(tmp, tmpstart, tmpend);
+ ret = paint.measureText(tmp, tmpstart, tmpend);
havewid = true;
}
canvas.drawText(tmp, tmpstart, tmpend,
- x - ret, y + workPaint.baselineShift, workPaint);
+ x - ret, y + paint.baselineShift, paint);
} else {
if (needwid) {
if (!havewid) {
- ret = workPaint.measureText(tmp, tmpstart, tmpend);
+ ret = paint.measureText(tmp, tmpstart, tmpend);
havewid = true;
}
}
canvas.drawText(tmp, tmpstart, tmpend,
- x, y + workPaint.baselineShift, workPaint);
+ x, y + paint.baselineShift, paint);
}
} else {
if (needwid && !havewid) {
- ret = workPaint.measureText(tmp, tmpstart, tmpend);
+ ret = paint.measureText(tmp, tmpstart, tmpend);
havewid = true;
}
}
} else {
- ret = replacement.getSize(workPaint, text, start, end, fmi);
+ ret = replacement.getSize(paint, text, start, end, fm);
if (canvas != null) {
if (dir == Layout.DIR_RIGHT_TO_LEFT)
replacement.draw(canvas, text, start, end,
- x - ret, top, y, bottom, workPaint);
+ x - ret, top, y, bottom, paint);
else
replacement.draw(canvas, text, start, end,
- x, top, y, bottom, workPaint);
+ x, top, y, bottom, paint);
}
}
@@ -144,29 +143,15 @@ public class Styled
return ret;
}
- /**
- * Return the advance widths for the characters in the string.
- * See also {@link android.graphics.Paint#getTextWidths(CharSequence, int, int, float[])}.
- *
- * @param paint The main {@link TextPaint} object.
- * @param workPaint The {@link TextPaint} object used for temporal workspace.
- * @param text The text to measure
- * @param start The index of the first char to to measure
- * @param end The end of the text slice to measure
- * @param widths Array to receive the advance widths of the characters.
- * Must be at least a large as (end - start).
- * @param fmi FontMetrics information. Can be null.
- * @return The actual number of widths returned.
- */
- public static int getTextWidths(TextPaint paint,
- TextPaint workPaint,
- Spanned text, int start, int end,
- float[] widths, Paint.FontMetricsInt fmi) {
- // Keep workPaint as is so that developers reuse the workspace.
+ public static int getTextWidths(TextPaint realPaint,
+ TextPaint paint,
+ Spanned text, int start, int end,
+ float[] widths, Paint.FontMetricsInt fm) {
+
MetricAffectingSpan[] spans = text.getSpans(start, end, MetricAffectingSpan.class);
ReplacementSpan replacement = null;
- workPaint.set(paint);
+ paint.set(realPaint);
for (int i = 0; i < spans.length; i++) {
MetricAffectingSpan span = spans[i];
@@ -174,15 +159,15 @@ public class Styled
replacement = (ReplacementSpan)span;
}
else {
- span.updateMeasureState(workPaint);
+ span.updateMeasureState(paint);
}
}
if (replacement == null) {
- workPaint.getFontMetricsInt(fmi);
- workPaint.getTextWidths(text, start, end, widths);
+ paint.getFontMetricsInt(fm);
+ paint.getTextWidths(text, start, end, widths);
} else {
- int wid = replacement.getSize(workPaint, text, start, end, fmi);
+ int wid = replacement.getSize(paint, text, start, end, fm);
if (end > start) {
widths[0] = wid;
@@ -198,10 +183,10 @@ public class Styled
CharSequence text, int start, int end,
int dir, boolean reverse,
float x, int top, int y, int bottom,
- Paint.FontMetricsInt fmi,
+ Paint.FontMetricsInt fm,
TextPaint paint,
TextPaint workPaint,
- boolean needWidth) {
+ boolean needwid) {
if (! (text instanceof Spanned)) {
float ret = 0;
@@ -209,22 +194,22 @@ public class Styled
CharSequence tmp = TextUtils.getReverse(text, start, end);
int tmpend = end - start;
- if (canvas != null || needWidth)
+ if (canvas != null || needwid)
ret = paint.measureText(tmp, 0, tmpend);
if (canvas != null)
canvas.drawText(tmp, 0, tmpend,
x - ret, y, paint);
} else {
- if (needWidth)
+ if (needwid)
ret = paint.measureText(text, start, end);
if (canvas != null)
canvas.drawText(text, start, end, x, y, paint);
}
- if (fmi != null) {
- paint.getFontMetricsInt(fmi);
+ if (fm != null) {
+ paint.getFontMetricsInt(fm);
}
return ret * dir; //Layout.DIR_RIGHT_TO_LEFT == -1
@@ -247,129 +232,67 @@ public class Styled
next = sp.nextSpanTransition(i, end, division);
x += each(canvas, sp, i, next, dir, reverse,
- x, top, y, bottom, fmi, paint, workPaint,
- needWidth || next != end);
-
- if (fmi != null) {
- if (fmi.ascent < asc)
- asc = fmi.ascent;
- if (fmi.descent > desc)
- desc = fmi.descent;
-
- if (fmi.top < ftop)
- ftop = fmi.top;
- if (fmi.bottom > fbot)
- fbot = fmi.bottom;
+ x, top, y, bottom, fm, paint, workPaint,
+ needwid || next != end);
+
+ if (fm != null) {
+ if (fm.ascent < asc)
+ asc = fm.ascent;
+ if (fm.descent > desc)
+ desc = fm.descent;
+
+ if (fm.top < ftop)
+ ftop = fm.top;
+ if (fm.bottom > fbot)
+ fbot = fm.bottom;
}
}
- if (fmi != null) {
+ if (fm != null) {
if (start == end) {
- paint.getFontMetricsInt(fmi);
+ paint.getFontMetricsInt(fm);
} else {
- fmi.ascent = asc;
- fmi.descent = desc;
- fmi.top = ftop;
- fmi.bottom = fbot;
+ fm.ascent = asc;
+ fm.descent = desc;
+ fm.top = ftop;
+ fm.bottom = fbot;
}
}
return x - ox;
}
-
- /* package */ static float drawText(Canvas canvas,
- CharSequence text, int start, int end,
- int direction, boolean reverse,
- float x, int top, int y, int bottom,
- TextPaint paint,
- TextPaint workPaint,
- boolean needWidth) {
- if ((direction == Layout.DIR_RIGHT_TO_LEFT && !reverse) ||
- (reverse && direction == Layout.DIR_LEFT_TO_RIGHT)) {
+ public static float drawText(Canvas canvas,
+ CharSequence text, int start, int end,
+ int dir, boolean reverse,
+ float x, int top, int y, int bottom,
+ TextPaint paint,
+ TextPaint workPaint,
+ boolean needwid) {
+ if ((dir == Layout.DIR_RIGHT_TO_LEFT && !reverse)||(reverse && dir == Layout.DIR_LEFT_TO_RIGHT)) {
float ch = foreach(null, text, start, end, Layout.DIR_LEFT_TO_RIGHT,
false, 0, 0, 0, 0, null, paint, workPaint,
true);
- ch *= direction; // DIR_RIGHT_TO_LEFT == -1
- foreach(canvas, text, start, end, -direction,
+ ch *= dir; // DIR_RIGHT_TO_LEFT == -1
+ foreach(canvas, text, start, end, -dir,
reverse, x + ch, top, y, bottom, null, paint,
workPaint, true);
return ch;
}
- return foreach(canvas, text, start, end, direction, reverse,
+ return foreach(canvas, text, start, end, dir, reverse,
x, top, y, bottom, null, paint, workPaint,
- needWidth);
- }
-
- /**
- * Draw the specified range of text, specified by start/end, with its origin at (x,y),
- * in the specified Paint. The origin is interpreted based on the Align setting in the
- * Paint.
- *
- * This method considers style information in the text
- * (e.g. Even when text is an instance of {@link android.text.Spanned}, this method
- * correctly draws the text).
- * See also
- * {@link android.graphics.Canvas#drawText(CharSequence, int, int, float, float, Paint)}
- * and
- * {@link android.graphics.Canvas#drawRect(float, float, float, float, Paint)}.
- *
- * @param canvas The target canvas.
- * @param text The text to be drawn
- * @param start The index of the first character in text to draw
- * @param end (end - 1) is the index of the last character in text to draw
- * @param direction The direction of the text. This must be
- * {@link android.text.Layout#DIR_LEFT_TO_RIGHT} or
- * {@link android.text.Layout#DIR_RIGHT_TO_LEFT}.
- * @param x The x-coordinate of origin for where to draw the text
- * @param top The top side of the rectangle to be drawn
- * @param y The y-coordinate of origin for where to draw the text
- * @param bottom The bottom side of the rectangle to be drawn
- * @param paint The main {@link TextPaint} object.
- * @param workPaint The {@link TextPaint} object used for temporal workspace.
- * @param needWidth If true, this method returns the width of drawn text.
- * @return Width of the drawn text if needWidth is true.
- */
- public static float drawText(Canvas canvas,
- CharSequence text, int start, int end,
- int direction,
- float x, int top, int y, int bottom,
- TextPaint paint,
- TextPaint workPaint,
- boolean needWidth) {
- // For safety.
- direction = direction >= 0 ? Layout.DIR_LEFT_TO_RIGHT : Layout.DIR_RIGHT_TO_LEFT;
- /*
- * Hided "reverse" parameter since it is meaningless for external developers.
- * Kept workPaint as is so that developers reuse the workspace.
- */
- return drawText(canvas, text, start, end, direction, false,
- x, top, y, bottom, paint, workPaint, needWidth);
+ needwid);
}
-
- /**
- * Return the width of the text, considering style information in the text
- * (e.g. Even when text is an instance of {@link android.text.Spanned}, this method
- * correctly mesures the width of the text).
- *
- * @param paint The main {@link TextPaint} object.
- * @param workPaint The {@link TextPaint} object used for temporal workspace.
- * @param text The text to measure
- * @param start The index of the first character to start measuring
- * @param end 1 beyond the index of the last character to measure
- * @param fmi FontMetrics information. Can be null
- * @return The width of the text
- */
+
public static float measureText(TextPaint paint,
TextPaint workPaint,
CharSequence text, int start, int end,
- Paint.FontMetricsInt fmi) {
- // Keep workPaint as is so that developers reuse the workspace.
+ Paint.FontMetricsInt fm) {
return foreach(null, text, start, end,
Layout.DIR_LEFT_TO_RIGHT, false,
- 0, 0, 0, 0, fmi, paint, workPaint, true);
+ 0, 0, 0, 0, fm, paint, workPaint, true);
}
}
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 8a7cdd9..feae6cf 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -595,17 +595,6 @@ public class DateUtils
* @param elapsedSeconds the elapsed time in seconds.
*/
public static String formatElapsedTime(long elapsedSeconds) {
- return formatElapsedTime(null, elapsedSeconds);
- }
-
- /**
- * Formats an elapsed time in the form "MM:SS" or "H:MM:SS"
- * for display on the call-in-progress screen.
- *
- * @param recycle {@link StringBuilder} to recycle, if possible
- * @param elapsedSeconds the elapsed time in seconds.
- */
- public static String formatElapsedTime(StringBuilder recycle, long elapsedSeconds) {
initFormatStrings();
long hours = 0;
@@ -624,24 +613,18 @@ public class DateUtils
String result;
if (hours > 0) {
- return formatElapsedTime(recycle, sElapsedFormatHMMSS, hours, minutes, seconds);
+ return formatElapsedTime(sElapsedFormatHMMSS, hours, minutes, seconds);
} else {
- return formatElapsedTime(recycle, sElapsedFormatMMSS, minutes, seconds);
+ return formatElapsedTime(sElapsedFormatMMSS, minutes, seconds);
}
}
/**
* Fast formatting of h:mm:ss
*/
- private static String formatElapsedTime(StringBuilder recycle, String format, long hours,
- long minutes, long seconds) {
+ private static String formatElapsedTime(String format, long hours, long minutes, long seconds) {
if (FAST_FORMAT_HMMSS.equals(format)) {
- StringBuilder sb = recycle;
- if (sb == null) {
- sb = new StringBuilder(8);
- } else {
- sb.setLength(0);
- }
+ StringBuffer sb = new StringBuffer(16);
sb.append(hours);
sb.append(TIME_SEPARATOR);
if (minutes < 10) {
@@ -666,15 +649,9 @@ public class DateUtils
/**
* Fast formatting of m:ss
*/
- private static String formatElapsedTime(StringBuilder recycle, String format, long minutes,
- long seconds) {
+ private static String formatElapsedTime(String format, long minutes, long seconds) {
if (FAST_FORMAT_MMSS.equals(format)) {
- StringBuilder sb = recycle;
- if (sb == null) {
- sb = new StringBuilder(8);
- } else {
- sb.setLength(0);
- }
+ StringBuffer sb = new StringBuffer(16);
if (minutes < 10) {
sb.append(TIME_PADDING);
} else {
@@ -1051,9 +1028,8 @@ public class DateUtils
* If FORMAT_NO_YEAR is set, then the year is not shown.
* If neither FORMAT_SHOW_YEAR nor FORMAT_NO_YEAR are set, then the year
* is shown only if it is different from the current year, or if the start
- * and end dates fall on different years. If both are set,
- * FORMAT_SHOW_YEAR takes precedence.
- *
+ * and end dates fall on different years.
+ *
* <p>
* Normally the date is shown unless the start and end day are the same.
* If FORMAT_SHOW_DATE is set, then the date is always shown, even for
@@ -1144,28 +1120,24 @@ public class DateUtils
boolean abbrevMonth = (flags & (FORMAT_ABBREV_MONTH | FORMAT_ABBREV_ALL)) != 0;
boolean noMonthDay = (flags & FORMAT_NO_MONTH_DAY) != 0;
boolean numericDate = (flags & FORMAT_NUMERIC_DATE) != 0;
-
- // If we're getting called with a single instant in time (from
- // e.g. formatDateTime(), below), then we can skip a lot of
- // computation below that'd otherwise be thrown out.
- boolean isInstant = (startMillis == endMillis);
-
- Time startDate = useUTC ? new Time(Time.TIMEZONE_UTC) : new Time();
- startDate.set(startMillis);
-
+
+ Time startDate;
Time endDate;
- int dayDistance;
- if (isInstant) {
- endDate = startDate;
- dayDistance = 0;
+
+ if (useUTC) {
+ startDate = new Time(Time.TIMEZONE_UTC);
+ endDate = new Time(Time.TIMEZONE_UTC);
} else {
- endDate = useUTC ? new Time(Time.TIMEZONE_UTC) : new Time();
- endDate.set(endMillis);
- int startJulianDay = Time.getJulianDay(startMillis, startDate.gmtoff);
- int endJulianDay = Time.getJulianDay(endMillis, endDate.gmtoff);
- dayDistance = endJulianDay - startJulianDay;
+ startDate = new Time();
+ endDate = new Time();
}
-
+
+ startDate.set(startMillis);
+ endDate.set(endMillis);
+ int startJulianDay = Time.getJulianDay(startMillis, startDate.gmtoff);
+ int endJulianDay = Time.getJulianDay(endMillis, endDate.gmtoff);
+ int dayDistance = endJulianDay - startJulianDay;
+
// If the end date ends at 12am at the beginning of a day,
// then modify it to make it look like it ends at midnight on
// the previous day. This will allow us to display "8pm - midnight",
@@ -1180,21 +1152,20 @@ public class DateUtils
// and an end date of Nov 12 at 00:00.
// If the start and end time are the same, then skip this and don't
// adjust the date.
- if (!isInstant
- && (endDate.hour | endDate.minute | endDate.second) == 0
- && (!showTime || dayDistance <= 1)) {
+ if ((endDate.hour | endDate.minute | endDate.second) == 0
+ && (!showTime || dayDistance <= 1) && (startMillis != endMillis)) {
endDate.monthDay -= 1;
endDate.normalize(true /* ignore isDst */);
}
-
+
int startDay = startDate.monthDay;
int startMonthNum = startDate.month;
int startYear = startDate.year;
-
+
int endDay = endDate.monthDay;
int endMonthNum = endDate.month;
int endYear = endDate.year;
-
+
String startWeekDayString = "";
String endWeekDayString = "";
if (showWeekDay) {
@@ -1205,9 +1176,9 @@ public class DateUtils
weekDayFormat = WEEKDAY_FORMAT;
}
startWeekDayString = startDate.format(weekDayFormat);
- endWeekDayString = isInstant ? startWeekDayString : endDate.format(weekDayFormat);
+ endWeekDayString = endDate.format(weekDayFormat);
}
-
+
String startTimeString = "";
String endTimeString = "";
if (showTime) {
@@ -1233,7 +1204,7 @@ public class DateUtils
boolean capNoon = (flags & FORMAT_CAP_NOON) != 0;
boolean noMidnight = (flags & FORMAT_NO_MIDNIGHT) != 0;
boolean capMidnight = (flags & FORMAT_CAP_MIDNIGHT) != 0;
-
+
boolean startOnTheHour = startDate.minute == 0 && startDate.second == 0;
boolean endOnTheHour = endDate.minute == 0 && endDate.second == 0;
if (abbrevTime && startOnTheHour) {
@@ -1249,41 +1220,20 @@ public class DateUtils
startTimeFormat = res.getString(com.android.internal.R.string.hour_minute_ampm);
}
}
-
- // Don't waste time on setting endTimeFormat when
- // we're dealing with an instant, where we'll never
- // need the end point. (It's the same as the start
- // point)
- if (!isInstant) {
- if (abbrevTime && endOnTheHour) {
- if (capAMPM) {
- endTimeFormat = res.getString(com.android.internal.R.string.hour_cap_ampm);
- } else {
- endTimeFormat = res.getString(com.android.internal.R.string.hour_ampm);
- }
+ if (abbrevTime && endOnTheHour) {
+ if (capAMPM) {
+ endTimeFormat = res.getString(com.android.internal.R.string.hour_cap_ampm);
} else {
- if (capAMPM) {
- endTimeFormat = res.getString(com.android.internal.R.string.hour_minute_cap_ampm);
- } else {
- endTimeFormat = res.getString(com.android.internal.R.string.hour_minute_ampm);
- }
+ endTimeFormat = res.getString(com.android.internal.R.string.hour_ampm);
}
-
- if (endDate.hour == 12 && endOnTheHour && !noNoon) {
- if (capNoon) {
- endTimeFormat = res.getString(com.android.internal.R.string.Noon);
- } else {
- endTimeFormat = res.getString(com.android.internal.R.string.noon);
- }
- } else if (endDate.hour == 0 && endOnTheHour && !noMidnight) {
- if (capMidnight) {
- endTimeFormat = res.getString(com.android.internal.R.string.Midnight);
- } else {
- endTimeFormat = res.getString(com.android.internal.R.string.midnight);
- }
+ } else {
+ if (capAMPM) {
+ endTimeFormat = res.getString(com.android.internal.R.string.hour_minute_cap_ampm);
+ } else {
+ endTimeFormat = res.getString(com.android.internal.R.string.hour_minute_ampm);
}
}
-
+
if (startDate.hour == 12 && startOnTheHour && !noNoon) {
if (capNoon) {
startTimeFormat = res.getString(com.android.internal.R.string.Noon);
@@ -1293,32 +1243,37 @@ public class DateUtils
// Don't show the start time starting at midnight. Show
// 12am instead.
}
+
+ if (endDate.hour == 12 && endOnTheHour && !noNoon) {
+ if (capNoon) {
+ endTimeFormat = res.getString(com.android.internal.R.string.Noon);
+ } else {
+ endTimeFormat = res.getString(com.android.internal.R.string.noon);
+ }
+ } else if (endDate.hour == 0 && endOnTheHour && !noMidnight) {
+ if (capMidnight) {
+ endTimeFormat = res.getString(com.android.internal.R.string.Midnight);
+ } else {
+ endTimeFormat = res.getString(com.android.internal.R.string.midnight);
+ }
+ }
}
-
startTimeString = startDate.format(startTimeFormat);
- endTimeString = isInstant ? startTimeString : endDate.format(endTimeFormat);
+ endTimeString = endDate.format(endTimeFormat);
}
-
+
+ // Get the current year
+ long millis = System.currentTimeMillis();
+ Time time = new Time();
+ time.set(millis);
+ int currentYear = time.year;
+
// Show the year if the user specified FORMAT_SHOW_YEAR or if
// the starting and end years are different from each other
// or from the current year. But don't show the year if the
- // user specified FORMAT_NO_YEAR.
- if (showYear) {
- // No code... just a comment for clarity. Keep showYear
- // on, as they enabled it with FORMAT_SHOW_YEAR. This
- // takes precedence over them setting FORMAT_NO_YEAR.
- } else if (noYear) {
- // They explicitly didn't want a year.
- showYear = false;
- } else if (startYear != endYear) {
- showYear = true;
- } else {
- // Show the year if it's not equal to the current year.
- Time currentTime = new Time();
- currentTime.setToNow();
- showYear = startYear != currentTime.year;
- }
-
+ // user specified FORMAT_NO_YEAR;
+ showYear = showYear || (!noYear && (startYear != endYear || startYear != currentYear));
+
String defaultDateFormat, fullFormat, dateRange;
if (numericDate) {
defaultDateFormat = res.getString(com.android.internal.R.string.numeric_date);
@@ -1351,7 +1306,7 @@ public class DateUtils
}
}
}
-
+
if (showWeekDay) {
if (showTime) {
fullFormat = res.getString(com.android.internal.R.string.wday1_date1_time1_wday2_date2_time2);
@@ -1365,20 +1320,20 @@ public class DateUtils
fullFormat = res.getString(com.android.internal.R.string.date1_date2);
}
}
-
+
if (noMonthDay && startMonthNum == endMonthNum) {
// Example: "January, 2008"
String startDateString = startDate.format(defaultDateFormat);
return startDateString;
}
-
+
if (startYear != endYear || noMonthDay) {
// Different year or we are not showing the month day number.
// Example: "December 31, 2007 - January 1, 2008"
// Or: "January - February, 2008"
String startDateString = startDate.format(defaultDateFormat);
String endDateString = endDate.format(defaultDateFormat);
-
+
// The values that are used in a fullFormat string are specified
// by position.
dateRange = String.format(fullFormat,
@@ -1386,7 +1341,7 @@ public class DateUtils
endWeekDayString, endDateString, endTimeString);
return dateRange;
}
-
+
// Get the month, day, and year strings for the start and end dates
String monthFormat;
if (numericDate) {
@@ -1399,17 +1354,16 @@ public class DateUtils
String startMonthString = startDate.format(monthFormat);
String startMonthDayString = startDate.format(MONTH_DAY_FORMAT);
String startYearString = startDate.format(YEAR_FORMAT);
-
- String endMonthString = isInstant ? null : endDate.format(monthFormat);
- String endMonthDayString = isInstant ? null : endDate.format(MONTH_DAY_FORMAT);
- String endYearString = isInstant ? null : endDate.format(YEAR_FORMAT);
-
+ String endMonthString = endDate.format(monthFormat);
+ String endMonthDayString = endDate.format(MONTH_DAY_FORMAT);
+ String endYearString = endDate.format(YEAR_FORMAT);
+
if (startMonthNum != endMonthNum) {
// Same year, different month.
// Example: "October 28 - November 3"
// or: "Wed, Oct 31 - Sat, Nov 3, 2007"
// or: "Oct 31, 8am - Sat, Nov 3, 2007, 5pm"
-
+
int index = 0;
if (showWeekDay) index = 1;
if (showYear) index += 2;
@@ -1417,7 +1371,7 @@ public class DateUtils
if (numericDate) index += 8;
int resId = sameYearTable[index];
fullFormat = res.getString(resId);
-
+
// The values that are used in a fullFormat string are specified
// by position.
dateRange = String.format(fullFormat,
@@ -1427,7 +1381,7 @@ public class DateUtils
endYearString, endTimeString);
return dateRange;
}
-
+
if (startDay != endDay) {
// Same month, different day.
int index = 0;
@@ -1437,7 +1391,7 @@ public class DateUtils
if (numericDate) index += 8;
int resId = sameMonthTable[index];
fullFormat = res.getString(resId);
-
+
// The values that are used in a fullFormat string are specified
// by position.
dateRange = String.format(fullFormat,
@@ -1447,19 +1401,19 @@ public class DateUtils
endYearString, endTimeString);
return dateRange;
}
-
+
// Same start and end day
boolean showDate = (flags & FORMAT_SHOW_DATE) != 0;
-
+
// If nothing was specified, then show the date.
if (!showTime && !showDate && !showWeekDay) showDate = true;
-
+
// Compute the time string (example: "10:00 - 11:00 am")
String timeString = "";
if (showTime) {
// If the start and end time are the same, then just show the
// start time.
- if (isInstant) {
+ if (startMillis == endMillis) {
// Same start and end time.
// Example: "10:15 AM"
timeString = startTimeString;
@@ -1469,7 +1423,7 @@ public class DateUtils
timeString = String.format(timeFormat, startTimeString, endTimeString);
}
}
-
+
// Figure out which full format to use.
fullFormat = "";
String dateString = "";
@@ -1503,7 +1457,7 @@ public class DateUtils
} else if (showTime) {
return timeString;
}
-
+
// The values that are used in a fullFormat string are specified
// by position.
dateRange = String.format(fullFormat, timeString, startWeekDayString, dateString);
diff --git a/core/java/android/text/method/NumberKeyListener.java b/core/java/android/text/method/NumberKeyListener.java
index 9270ca5..e500fae 100644
--- a/core/java/android/text/method/NumberKeyListener.java
+++ b/core/java/android/text/method/NumberKeyListener.java
@@ -101,11 +101,6 @@ public abstract class NumberKeyListener extends BaseKeyListener
selEnd = Math.max(a, b);
}
- if (selStart < 0 || selEnd < 0) {
- selStart = selEnd = 0;
- Selection.setSelection(content, 0);
- }
-
int i = event != null ? lookup(event, content) : 0;
int repeatCount = event != null ? event.getRepeatCount() : 0;
if (repeatCount == 0) {
diff --git a/core/java/android/view/GestureDetector.java b/core/java/android/view/GestureDetector.java
index e0231a7..679c683 100644
--- a/core/java/android/view/GestureDetector.java
+++ b/core/java/android/view/GestureDetector.java
@@ -113,48 +113,20 @@ public class GestureDetector {
}
/**
- * The listener that is used to notify when a double-tap or a confirmed
- * single-tap occur.
+ * @hide pending API council
*/
public interface OnDoubleTapListener {
- /**
- * Notified when a single-tap occurs.
- * <p>
- * Unlike {@link OnGestureListener#onSingleTapUp(MotionEvent)}, this
- * will only be called after the detector is confident that the user's
- * first tap is not followed by a second tap leading to a double-tap
- * gesture.
- *
- * @param e The down motion event of the single-tap.
- * @return true if the event is consumed, else false
- */
boolean onSingleTapConfirmed(MotionEvent e);
-
- /**
- * Notified when a double-tap occurs.
- *
- * @param e The down motion event of the first tap of the double-tap.
- * @return true if the event is consumed, else false
- */
- boolean onDoubleTap(MotionEvent e);
-
- /**
- * Notified when an event within a double-tap gesture occurs, including
- * the down, move, and up events.
- *
- * @param e The motion event that occurred during the double-tap gesture.
- * @return true if the event is consumed, else false
- */
boolean onDoubleTapEvent(MotionEvent e);
}
-
+
/**
- * A convenience class to extend when you only want to listen for a subset
- * of all the gestures. This implements all methods in the
- * {@link OnGestureListener} and {@link OnDoubleTapListener} but does
- * nothing and return {@code false} for all applicable methods.
+ * A convenience class to extend when you only want to listen for a
+ * subset of all the gestures. This implements all methods in the
+ * {@link OnGestureListener} but does nothing and return {@code false}
+ * for all applicable methods.
*/
- public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener {
+ public static class SimpleOnGestureListener implements OnGestureListener {
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@@ -178,25 +150,13 @@ public class GestureDetector {
public boolean onDown(MotionEvent e) {
return false;
}
-
- public boolean onDoubleTap(MotionEvent e) {
- return false;
- }
-
- public boolean onDoubleTapEvent(MotionEvent e) {
- return false;
- }
-
- public boolean onSingleTapConfirmed(MotionEvent e) {
- return false;
- }
}
// TODO: ViewConfiguration
private int mBiggerTouchSlopSquare = 20 * 20;
-
+
private int mTouchSlopSquare;
- private int mDoubleTapSlopSquare;
+ private int mDoubleTapSlopSquare;
private int mMinimumFlingVelocity;
private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
@@ -204,7 +164,7 @@ public class GestureDetector {
// TODO make new double-tap timeout, and define its events (i.e. either time
// between down-down or time between up-down)
private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
-
+
// constants for Message.what used by GestureHandler below
private static final int SHOW_PRESS = 1;
private static final int LONG_PRESS = 2;
@@ -221,13 +181,13 @@ public class GestureDetector {
private MotionEvent mCurrentDownEvent;
private MotionEvent mPreviousUpEvent;
-
+
/**
* True when the user is still touching for the second tap (down, move, and
* up events). Can only be true if there is a double tap listener attached.
*/
private boolean mIsDoubleTapping;
-
+
private float mLastMotionY;
private float mLastMotionX;
@@ -266,7 +226,7 @@ public class GestureDetector {
break;
default:
- throw new RuntimeException("Unknown message " + msg); //never
+ throw new RuntimeException("Unknown message " + msg); //never
}
}
}
@@ -343,9 +303,6 @@ public class GestureDetector {
mHandler = new GestureHandler();
}
mListener = listener;
- if (listener instanceof OnDoubleTapListener) {
- setOnDoubleTapListener((OnDoubleTapListener) listener);
- }
init(context);
}
@@ -374,11 +331,8 @@ public class GestureDetector {
}
/**
- * Sets the listener which will be called for double-tap and related
- * gestures.
- *
- * @param onDoubleTapListener the listener invoked for all the callbacks, or
- * null to stop listening for double-tap gestures.
+ * @hide pending API council
+ * @param onDoubleTapListener
*/
public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) {
mDoubleTapListener = onDoubleTapListener;
@@ -433,10 +387,7 @@ public class GestureDetector {
isConsideredDoubleTap(mCurrentDownEvent, mPreviousUpEvent, ev)) {
// This is a second tap
mIsDoubleTapping = true;
- // Give a callback with the first tap of the double-tap
- handled |= mDoubleTapListener.onDoubleTap(mCurrentDownEvent);
- // Give a callback with down event of the double-tap
- handled |= mDoubleTapListener.onDoubleTapEvent(ev);
+ handled = mDoubleTapListener.onDoubleTapEvent(ev);
} else {
// This is a first tap
mHandler.sendEmptyMessageDelayed(TAP, DOUBLE_TAP_TIMEOUT);
@@ -467,8 +418,7 @@ public class GestureDetector {
final float scrollX = mLastMotionX - x;
final float scrollY = mLastMotionY - y;
if (mIsDoubleTapping) {
- // Give the move events of the double-tap
- handled |= mDoubleTapListener.onDoubleTapEvent(ev);
+ handled = mDoubleTapListener.onDoubleTapEvent(ev);
} else if (mAlwaysInTapRegion) {
final int deltaX = (int) (x - mCurrentDownEvent.getX());
final int deltaY = (int) (y - mCurrentDownEvent.getY());
@@ -496,8 +446,7 @@ public class GestureDetector {
mStillDown = false;
MotionEvent currentUpEvent = MotionEvent.obtain(ev);
if (mIsDoubleTapping) {
- // Finally, give the up event of the double-tap
- handled |= mDoubleTapListener.onDoubleTapEvent(ev);
+ handled = mDoubleTapListener.onDoubleTapEvent(ev);
mIsDoubleTapping = false;
break;
} else if (mInLongPress) {
@@ -546,7 +495,7 @@ public class GestureDetector {
if (!mAlwaysInBiggerTapRegion) {
return false;
}
-
+
if (secondDown.getEventTime() - firstUp.getEventTime() > DOUBLE_TAP_TIMEOUT) {
return false;
}
@@ -555,7 +504,7 @@ public class GestureDetector {
int deltaY = (int) firstDown.getY() - (int) secondDown.getY();
return (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare);
}
-
+
private void dispatchLongPress() {
mHandler.removeMessages(TAP);
mInLongPress = true;
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 430cc71..d6ea91c 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -229,12 +229,6 @@ public class KeyEvent implements Parcelable {
public static final int FLAG_SOFT_KEYBOARD = 0x2;
/**
- * This mask is set if we don't want the key event to cause us to leave
- * touch mode.
- */
- public static final int FLAG_KEEP_TOUCH_MODE = 0x4;
-
- /**
* Returns the maximum keycode.
*/
public static int getMaxKeyCode() {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 406fad8..5ed3a7e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -57,7 +57,6 @@ import com.android.internal.view.menu.MenuBuilder;
import java.util.ArrayList;
import java.util.Arrays;
-import java.lang.ref.SoftReference;
/**
* <p>
@@ -1564,7 +1563,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
private int[] mDrawableState = null;
- private SoftReference<Bitmap> mDrawingCache;
+ private Bitmap mDrawingCache;
/**
* When this view has focus and the next focus is {@link #FOCUS_LEFT},
@@ -3951,16 +3950,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
}
if ((changed & WILL_NOT_CACHE_DRAWING) != 0) {
- destroyDrawingCache();
+ if (mDrawingCache != null) {
+ mDrawingCache.recycle();
+ }
+ mDrawingCache = null;
}
if ((changed & DRAWING_CACHE_ENABLED) != 0) {
- destroyDrawingCache();
+ if (mDrawingCache != null) {
+ mDrawingCache.recycle();
+ }
+ mDrawingCache = null;
mPrivateFlags &= ~DRAWING_CACHE_VALID;
}
if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
- destroyDrawingCache();
+ if (mDrawingCache != null) {
+ mDrawingCache.recycle();
+ }
+ mDrawingCache = null;
mPrivateFlags &= ~DRAWING_CACHE_VALID;
}
@@ -5407,10 +5415,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
if ((mViewFlags & WILL_NOT_CACHE_DRAWING) == WILL_NOT_CACHE_DRAWING) {
return null;
}
- if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED) {
+ if ((mViewFlags & DRAWING_CACHE_ENABLED) == DRAWING_CACHE_ENABLED &&
+ ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mDrawingCache == null)) {
buildDrawingCache();
}
- return mDrawingCache == null ? null : mDrawingCache.get();
+ return mDrawingCache;
}
/**
@@ -5425,8 +5434,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
*/
public void destroyDrawingCache() {
if (mDrawingCache != null) {
- final Bitmap bitmap = mDrawingCache.get();
- if (bitmap != null) bitmap.recycle();
+ mDrawingCache.recycle();
mDrawingCache = null;
}
}
@@ -5466,9 +5474,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
* @see #destroyDrawingCache()
*/
public void buildDrawingCache() {
- if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mDrawingCache == null ||
- mDrawingCache.get() == null) {
-
+ if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mDrawingCache == null) {
if (ViewDebug.TRACE_HIERARCHY) {
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.BUILD_CACHE);
}
@@ -5486,12 +5492,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
if (width <= 0 || height <= 0 ||
(width * height * (opaque ? 2 : 4) >= // Projected bitmap size in bytes
ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize())) {
- destroyDrawingCache();
+ if (mDrawingCache != null) {
+ mDrawingCache.recycle();
+ }
+ mDrawingCache = null;
return;
}
boolean clear = true;
- Bitmap bitmap = mDrawingCache == null ? null : mDrawingCache.get();
+ Bitmap bitmap = mDrawingCache;
if (bitmap == null || bitmap.getWidth() != width || bitmap.getHeight() != height) {
@@ -5516,11 +5525,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
}
// Try to cleanup memory
- if (bitmap != null) bitmap.recycle();
+ if (mDrawingCache != null) {
+ mDrawingCache.recycle();
+ }
try {
- bitmap = Bitmap.createBitmap(width, height, quality);
- mDrawingCache = new SoftReference<Bitmap>(bitmap);
+ mDrawingCache = bitmap = Bitmap.createBitmap(width, height, quality);
} catch (OutOfMemoryError e) {
// If there is not enough memory to create the bitmap cache, just
// ignore the issue as bitmap caches are not required to draw the
@@ -8050,8 +8060,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
shader = new LinearGradient(0, 0, 0, 1, color, 0, Shader.TileMode.CLAMP);
paint.setShader(shader);
- // Restore the default transfer mode (src_over)
- paint.setXfermode(null);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
}
}
}
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index d3f48c6..2f7b0d1 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -56,7 +56,7 @@ public class ViewConfiguration {
/**
* Defines the duration in milliseconds we will wait to see if a touch event
- * is a tap or a scroll. If the user does not move within this interval, it is
+ * is a top or a scroll. If the user does not move within this interval, it is
* considered to be a tap.
*/
private static final int TAP_TIMEOUT = 100;
@@ -213,7 +213,7 @@ public class ViewConfiguration {
}
/**
- * @return the length of the fading edges in pixels
+ * @return Defines the length of the fading edges in pixels
*
* @deprecated Use {@link #getScaledFadingEdgeLength()} instead.
*/
@@ -223,14 +223,14 @@ public class ViewConfiguration {
}
/**
- * @return the length of the fading edges in pixels
+ * @return Defines the length of the fading edges in pixels
*/
public int getScaledFadingEdgeLength() {
return mFadingEdgeLength;
}
/**
- * @return the duration in milliseconds of the pressed state in child
+ * @return Defines the duration in milliseconds of the pressed state in child
* components.
*/
public static int getPressedStateDuration() {
@@ -238,7 +238,7 @@ public class ViewConfiguration {
}
/**
- * @return the duration in milliseconds before a press turns into
+ * @return Defines the duration in milliseconds before a press turns into
* a long press
*/
public static int getLongPressTimeout() {
@@ -246,8 +246,8 @@ public class ViewConfiguration {
}
/**
- * @return the duration in milliseconds we will wait to see if a touch event
- * is a tap or a scroll. If the user does not move within this interval, it is
+ * @return Defines the duration in milliseconds we will wait to see if a touch event
+ * is a top or a scroll. If the user does not move within this interval, it is
* considered to be a tap.
*/
public static int getTapTimeout() {
@@ -255,7 +255,7 @@ public class ViewConfiguration {
}
/**
- * @return the duration in milliseconds we will wait to see if a touch event
+ * @return Defines the duration in milliseconds we will wait to see if a touch event
* is a jump tap. If the user does not move within this interval, it is
* considered to be a tap.
*/
@@ -264,7 +264,7 @@ public class ViewConfiguration {
}
/**
- * @return the duration in milliseconds between the first tap's up event and
+ * @return Defines the duration in milliseconds between the first tap's up event and
* the second tap's down event for an interaction to be considered a
* double-tap.
* @hide pending API council
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index de64d0e..3cfaf1b 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -143,7 +143,6 @@ public final class ViewRoot extends Handler implements ViewParent,
boolean mFullRedrawNeeded;
boolean mNewSurfaceNeeded;
boolean mHasHadWindowFocus;
- boolean mLastWasImTarget;
boolean mWindowAttributesChanged = false;
@@ -999,21 +998,6 @@ public final class ViewRoot extends Handler implements ViewParent,
mNewSurfaceNeeded = false;
mViewVisibility = viewVisibility;
- if (mAttachInfo.mHasWindowFocus) {
- final boolean imTarget = WindowManager.LayoutParams
- .mayUseInputMethod(mWindowAttributes.flags);
- if (imTarget != mLastWasImTarget) {
- mLastWasImTarget = imTarget;
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null && imTarget) {
- imm.startGettingWindowFocus(mView);
- imm.onWindowFocus(mView, mView.findFocus(),
- mWindowAttributes.softInputMode,
- !mHasHadWindowFocus, mWindowAttributes.flags);
- }
- }
- }
-
boolean cancelDraw = attachInfo.mTreeObserver.dispatchOnPreDraw();
if (!cancelDraw && !newSurface) {
@@ -1192,7 +1176,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// properly re-composite its drawing on a transparent
// background. This automatically respects the clip/dirty region
if (!canvas.isOpaque()) {
- canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
+ canvas.drawColor(0xff0000ff, PorterDuff.Mode.CLEAR);
} else if (yoff != 0) {
// If we are applying an offset, we need to clear the area
// where the offset doesn't appear to avoid having garbage
@@ -1624,13 +1608,10 @@ public final class ViewRoot extends Handler implements ViewParent,
}
}
- mLastWasImTarget = WindowManager.LayoutParams
- .mayUseInputMethod(mWindowAttributes.flags);
-
InputMethodManager imm = InputMethodManager.peekInstance();
if (mView != null) {
- if (hasWindowFocus && imm != null && mLastWasImTarget) {
- imm.startGettingWindowFocus(mView);
+ if (hasWindowFocus && imm != null) {
+ imm.startGettingWindowFocus();
}
mView.dispatchWindowFocusChanged(hasWindowFocus);
}
@@ -1638,7 +1619,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// Note: must be done after the focus change callbacks,
// so all of the view state is set up correctly.
if (hasWindowFocus) {
- if (imm != null && mLastWasImTarget) {
+ if (imm != null) {
imm.onWindowFocus(mView, mView.findFocus(),
mWindowAttributes.softInputMode,
!mHasHadWindowFocus, mWindowAttributes.flags);
@@ -1995,9 +1976,6 @@ public final class ViewRoot extends Handler implements ViewParent,
if (event.getAction() != KeyEvent.ACTION_DOWN) {
return false;
}
- if ((event.getFlags()&KeyEvent.FLAG_KEEP_TOUCH_MODE) != 0) {
- return false;
- }
// only relevant if we are in touch mode
if (!mAttachInfo.mInTouchMode) {
@@ -2117,7 +2095,8 @@ public final class ViewRoot extends Handler implements ViewParent,
// If it is possible for this window to interact with the input
// method window, then we want to first dispatch our key events
// to the input method.
- if (mLastWasImTarget) {
+ if (WindowManager.LayoutParams.mayUseInputMethod(
+ mWindowAttributes.flags)) {
InputMethodManager imm = InputMethodManager.peekInstance();
if (imm != null && mView != null) {
int seq = enqueuePendingEvent(event, sendDone);
@@ -2147,10 +2126,6 @@ public final class ViewRoot extends Handler implements ViewParent,
sWindowSession.finishKey(mWindow);
} catch (RemoteException e) {
}
- } else {
- Log.w("ViewRoot", "handleFinishedEvent(seq=" + seq
- + " handled=" + handled + " ev=" + event
- + ") neither delivering nor finishing key");
}
}
}
@@ -2473,8 +2448,6 @@ public final class ViewRoot extends Handler implements ViewParent,
final ViewRoot viewRoot = mViewRoot.get();
if (viewRoot != null) {
viewRoot.dispatchKey(event);
- } else {
- Log.w("ViewRoot.W", "Key event " + event + " but no ViewRoot available!");
}
}
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index 52b4107..6fbc174 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -341,13 +341,6 @@ public class BaseInputConnection implements InputConnection {
/**
* The default implementation does nothing.
*/
- public boolean performEditorAction(int actionCode) {
- return false;
- }
-
- /**
- * The default implementation does nothing.
- */
public boolean performContextMenuAction(int id) {
return false;
}
diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java
index 0405371..b2f26d7 100644
--- a/core/java/android/view/inputmethod/EditorInfo.java
+++ b/core/java/android/view/inputmethod/EditorInfo.java
@@ -25,100 +25,17 @@ public class EditorInfo implements InputType, Parcelable {
public int inputType = TYPE_NULL;
/**
- * Set of bits in {@link #imeOptions} that provide alternative actions
- * associated with the "enter" key. This both helps the IME provide
- * better feedback about what the enter key will do, and also allows it
- * to provide alternative mechanisms for providing that command.
- */
- public static final int IME_MASK_ACTION = 0x000000ff;
-
- /**
- * Bits of {@link #IME_MASK_ACTION}: there is no special action
- * associated with this editor.
- */
- public static final int IME_ACTION_NONE = 0x00000000;
-
- /**
- * Bits of {@link #IME_MASK_ACTION}: the action key performs a "go"
- * operation to take the user to the target of the text they typed.
- * Typically used, for example, when entering a URL.
- */
- public static final int IME_ACTION_GO = 0x00000001;
-
- /**
- * Bits of {@link #IME_MASK_ACTION}: the action key performs a "search"
- * operation, taking the user to the results of searching for the text
- * the have typed (in whatever context is appropriate).
- */
- public static final int IME_ACTION_SEARCH = 0x00000002;
-
- /**
- * Bits of {@link #IME_MASK_ACTION}: the action key performs a "send"
- * operation, delivering the text to its target. This is typically used
- * when composing a message.
- */
- public static final int IME_ACTION_SEND = 0x00000003;
-
- /**
- * Bits of {@link #IME_MASK_ACTION}: the action key performs a "next"
- * operation, taking the user to the next field that will accept text.
- */
- public static final int IME_ACTION_NEXT = 0x00000004;
-
- /**
- * Flag of {@link #imeOptions}: used in conjunction with
- * {@link #IME_MASK_ACTION}, this indicates that the action should not
- * be available in-line as the same as a "enter" key. Typically this is
- * because the action has such a significant impact or is not recoverable
- * enough that accidentally hitting it should be avoided, such as sending
- * a message.
- */
- public static final int IME_FLAG_NO_ENTER_ACTION = 0x40000000;
-
- /**
- * Generic non-special type for {@link #imeOptions}.
- */
- public static final int IME_NORMAL = 0x00000000;
-
- /**
- * Special code for when the ime option has been undefined. This is not
- * used with the EditorInfo structure, but can be used elsewhere.
- */
- public static final int IME_UNDEFINED = 0x80000000;
-
- /**
- * Extended type information for the editor, to help the IME better
- * integrate with it.
- */
- public int imeOptions = IME_NORMAL;
-
- /**
- * A string supplying additional information options that are
- * private to a particular IME implementation. The string must be
+ * A string supplying additional information about the content type that
+ * is private to a particular IME implementation. The string must be
* scoped to a package owned by the implementation, to ensure there are
* no conflicts between implementations, but other than that you can put
* whatever you want in it to communicate with the IME. For example,
* you could have a string that supplies an argument like
* <code>"com.example.myapp.SpecialMode=3"</code>. This field is can be
- * filled in from the {@link android.R.attr#privateImeOptions}
+ * filled in from the {@link android.R.attr#editorPrivateContentType}
* attribute of a TextView.
*/
- public String privateImeOptions = null;
-
- /**
- * In some cases an IME may be able to display an arbitrary label for
- * a command the user can perform, which you can specify here. You can
- * not count on this being used.
- */
- public CharSequence actionLabel = null;
-
- /**
- * If {@link #actionLabel} has been given, this is the id for that command
- * when the user presses its button that is delivered back with
- * {@link InputConnection#performEditorAction(int)
- * InputConnection.performEditorAction()}.
- */
- public int actionId = 0;
+ public String privateContentType = null;
/**
* The text offset of the start of the selection at the time editing
@@ -189,10 +106,7 @@ public class EditorInfo implements InputType, Parcelable {
*/
public void dump(Printer pw, String prefix) {
pw.println(prefix + "inputType=0x" + Integer.toHexString(inputType)
- + " imeOptions=0x" + Integer.toHexString(imeOptions)
- + " privateImeOptions=" + privateImeOptions);
- pw.println(prefix + "actionLabel=" + actionLabel
- + " actionId=" + actionId);
+ + " privateContentType=" + privateContentType);
pw.println(prefix + "initialSelStart=" + initialSelStart
+ " initialSelEnd=" + initialSelEnd
+ " initialCapsMode=0x"
@@ -213,10 +127,7 @@ public class EditorInfo implements InputType, Parcelable {
*/
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(inputType);
- dest.writeInt(imeOptions);
- dest.writeString(privateImeOptions);
- TextUtils.writeToParcel(actionLabel, dest, flags);
- dest.writeInt(actionId);
+ dest.writeString(privateContentType);
dest.writeInt(initialSelStart);
dest.writeInt(initialSelEnd);
dest.writeInt(initialCapsMode);
@@ -235,10 +146,7 @@ public class EditorInfo implements InputType, Parcelable {
public EditorInfo createFromParcel(Parcel source) {
EditorInfo res = new EditorInfo();
res.inputType = source.readInt();
- res.imeOptions = source.readInt();
- res.privateImeOptions = source.readString();
- res.actionLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- res.actionId = source.readInt();
+ res.privateContentType = source.readString();
res.initialSelStart = source.readInt();
res.initialSelEnd = source.readInt();
res.initialCapsMode = source.readInt();
diff --git a/core/java/android/view/inputmethod/InputConnection.java b/core/java/android/view/inputmethod/InputConnection.java
index 32cce35..530127d 100644
--- a/core/java/android/view/inputmethod/InputConnection.java
+++ b/core/java/android/view/inputmethod/InputConnection.java
@@ -208,24 +208,10 @@ public interface InputConnection {
/**
* Set the selection of the text editor. To set the cursor position,
* start and end should have the same value.
- * @return Returns true on success, false if the input connection is no longer
- * valid.
*/
public boolean setSelection(int start, int end);
/**
- * Have the editor perform an action it has said it can do.
- *
- * @param editorAction This must be one of the action constants for
- * {@link EditorInfo#imeOptions EditorInfo.editorType}, such as
- * {@link EditorInfo#IME_ACTION_GO EditorInfo.EDITOR_ACTION_GO}.
- *
- * @return Returns true on success, false if the input connection is no longer
- * valid.
- */
- public boolean performEditorAction(int editorAction);
-
- /**
* Perform a context menu action on the field. The given id may be one of:
* {@link android.R.id#selectAll},
* {@link android.R.id#startSelectingText}, {@link android.R.id#stopSelectingText},
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e9e4703..91fa211 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -222,11 +222,6 @@ public final class InputMethodManager {
// -----------------------------------------------------------
/**
- * This is the root view of the overall window that currently has input
- * method focus.
- */
- View mCurRootView;
- /**
* This is the view that should currently be served by an input method,
* regardless of the state of setting that up.
*/
@@ -845,13 +840,6 @@ public final class InputMethodManager {
void focusInLocked(View view) {
if (DEBUG) Log.v(TAG, "focusIn: " + view);
-
- if (mCurRootView != view.getRootView()) {
- // This is a request from a window that isn't in the window with
- // IME focus, so ignore it.
- return;
- }
-
// Okay we have a new view that is being served.
if (mServedView != view) {
mCurrentTextBoxAttribute = null;
@@ -925,7 +913,7 @@ public final class InputMethodManager {
}
/**
- * Called by ViewRoot when its window gets input focus.
+ * Called by ViewRoot the first time it gets window focus.
* @hide
*/
public void onWindowFocus(View rootView, View focusedView, int softInputMode,
@@ -958,10 +946,9 @@ public final class InputMethodManager {
}
/** @hide */
- public void startGettingWindowFocus(View rootView) {
+ public void startGettingWindowFocus() {
synchronized (mH) {
mWindowFocusedView = null;
- mCurRootView = rootView;
}
}
@@ -1178,7 +1165,6 @@ public final class InputMethodManager {
+ " mBindSequence=" + mBindSequence
+ " mCurId=" + mCurId);
p.println(" mCurMethod=" + mCurMethod);
- p.println(" mCurRootView=" + mCurRootView);
p.println(" mServedView=" + mServedView);
p.println(" mLastServedView=" + mLastServedView);
p.println(" mServedConnecting=" + mServedConnecting);
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 84aeb83..4f8e5e4 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -907,12 +907,10 @@ class CallbackProxy extends Handler {
}
public void onReceivedIcon(Bitmap icon) {
- // The current item might be null if the icon was already stored in the
- // database and this is a new WebView.
- WebHistoryItem i = mBackForwardList.getCurrentItem();
- if (i != null) {
- i.setFavicon(icon);
+ if (Config.DEBUG && mBackForwardList.getCurrentItem() == null) {
+ throw new AssertionError();
}
+ mBackForwardList.getCurrentItem().setFavicon(icon);
// Do an unsynchronized quick check to avoid posting if no callback has
// been set.
if (mWebChromeClient == null) {
diff --git a/core/java/android/webkit/TextDialog.java b/core/java/android/webkit/TextDialog.java
index 8a82411..c2620a5 100644
--- a/core/java/android/webkit/TextDialog.java
+++ b/core/java/android/webkit/TextDialog.java
@@ -25,6 +25,8 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RectShape;
+import android.os.Handler;
+import android.os.Message;
import android.text.Editable;
import android.text.InputFilter;
import android.text.Selection;
@@ -41,6 +43,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewConfiguration;
import android.widget.AbsoluteLayout.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
@@ -79,6 +82,22 @@ import java.util.ArrayList;
// FIXME: This can be replaced with TextView.NO_FILTERS if that
// is made public/protected.
private static final InputFilter[] NO_FILTERS = new InputFilter[0];
+ // The time of the last enter down, so we know whether to perform a long
+ // press.
+ private long mDownTime;
+
+ private boolean mTrackballDown = false;
+ private static int LONGPRESS = 1;
+ private Handler mHandler = new Handler() {
+ public void handleMessage(Message msg) {
+ if (msg.what == LONGPRESS) {
+ if (mTrackballDown) {
+ performLongClick();
+ mTrackballDown = false;
+ }
+ }
+ }
+ };
/**
* Create a new TextDialog.
@@ -116,13 +135,6 @@ import java.util.ArrayList;
}
@Override
- protected boolean shouldAdvanceFocusOnEnter() {
- // In the browser, single line textfields use enter as a form submit,
- // so we never want to advance the focus on enter.
- return false;
- }
-
- @Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.isSystem()) {
return super.dispatchKeyEvent(event);
@@ -140,33 +152,43 @@ import java.util.ArrayList;
return true;
}
- if ((mSingle && KeyEvent.KEYCODE_ENTER == keyCode)) {
+ // For single-line textfields, return key should not be handled
+ // here. Instead, the WebView is passed the key up, so it may fire a
+ // submit/onClick.
+ // Center key should always be passed to a potential onClick
+ if ((mSingle && KeyEvent.KEYCODE_ENTER == keyCode)
+ || KeyEvent.KEYCODE_DPAD_CENTER == keyCode) {
if (isPopupShowing()) {
- return super.dispatchKeyEvent(event);
+ super.dispatchKeyEvent(event);
+ return true;
}
- if (!down) {
- // Hide the keyboard, since the user has just submitted this
- // form. The submission happens thanks to the two calls
- // to sendDomEvent.
+ if (down) {
+ if (event.getRepeatCount() == 0) {
+ mGotEnterDown = true;
+ mDownTime = event.getEventTime();
+ // Send the keydown when the up comes, so that we have
+ // a chance to handle a long press.
+ } else if (mGotEnterDown && event.getEventTime() - mDownTime >
+ ViewConfiguration.getLongPressTimeout()) {
+ performLongClick();
+ mGotEnterDown = false;
+ }
+ } else if (mGotEnterDown) {
+ mGotEnterDown = false;
+ if (KeyEvent.KEYCODE_DPAD_CENTER == keyCode) {
+ mWebView.shortPressOnTextField();
+ return true;
+ }
+ // If we reached here, then this is a single line textfield, and
+ // the user pressed ENTER. In this case, we want to hide the
+ // soft input method.
InputMethodManager.getInstance(mContext)
.hideSoftInputFromWindow(getWindowToken(), 0);
sendDomEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keyCode));
sendDomEvent(event);
}
- return super.dispatchKeyEvent(event);
- } else if (KeyEvent.KEYCODE_DPAD_CENTER == keyCode) {
- // Note that this handles center key and trackball.
- if (isPopupShowing()) {
- return super.dispatchKeyEvent(event);
- }
- // Center key should be passed to a potential onClick
- if (!down) {
- mWebView.shortPressOnTextField();
- }
- // Pass to super to handle longpress.
- return super.dispatchKeyEvent(event);
+ return true;
}
-
// Ensure there is a layout so arrow keys are handled properly.
if (getLayout() == null) {
measure(mWidthSpec, mHeightSpec);
@@ -203,8 +225,9 @@ import java.util.ArrayList;
case KeyEvent.KEYCODE_DPAD_DOWN:
isArrowKey = true;
break;
+ case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
- // For multi-line text boxes, newlines will
+ // For multi-line text boxes, newlines and dpad center will
// trigger onTextChanged for key down (which will send both
// key up and key down) but not key up.
mGotEnterDown = true;
@@ -246,7 +269,7 @@ import java.util.ArrayList;
// with WebCore's notion of the current selection, reset the selection
// to what it was before the key event.
Selection.setSelection(text, oldStart, oldEnd);
- // Ignore the key up event for newlines. This prevents
+ // Ignore the key up event for newlines or dpad center. This prevents
// multiple newlines in the native textarea.
if (mGotEnterDown && !down) {
return true;
@@ -368,8 +391,27 @@ import java.util.ArrayList;
if (isPopupShowing()) {
return super.onTrackballEvent(event);
}
- if (event.getAction() != MotionEvent.ACTION_MOVE) {
- return false;
+ int action = event.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ if (!mTrackballDown) {
+ mTrackballDown = true;
+ mHandler.sendEmptyMessageDelayed(LONGPRESS,
+ ViewConfiguration.getLongPressTimeout());
+ }
+ return true;
+ case MotionEvent.ACTION_UP:
+ if (mTrackballDown) {
+ mWebView.shortPressOnTextField();
+ mTrackballDown = false;
+ mHandler.removeMessages(LONGPRESS);
+ }
+ return true;
+ case MotionEvent.ACTION_CANCEL:
+ mTrackballDown = false;
+ return true;
+ case MotionEvent.ACTION_MOVE:
+ // fall through
}
Spannable text = (Spannable) getText();
MovementMethod move = getMovementMethod();
@@ -400,6 +442,7 @@ import java.util.ArrayList;
// hide the soft keyboard when the edit text is out of focus
InputMethodManager.getInstance(mContext).hideSoftInputFromWindow(
getWindowToken(), 0);
+ mHandler.removeMessages(LONGPRESS);
mWebView.removeView(this);
mWebView.requestFocus();
mScrollToAccommodateCursor = false;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5126ef0..417b657 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -71,7 +71,6 @@ import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.Toast;
-import android.widget.ZoomButtonsController;
import android.widget.ZoomControls;
import android.widget.ZoomRingController;
import android.widget.FrameLayout;
@@ -285,10 +284,8 @@ public class WebView extends AbsoluteLayout
/**
* Customizable constant
*/
- // pre-computed square of ViewConfiguration.getScaledTouchSlop()
+ // pre-computed square of ViewConfiguration.getTouchSlop()
private int mTouchSlopSquare;
- // pre-computed square of ViewConfiguration.getScaledDoubleTapSlop()
- private int mDoubleTapSlopSquare;
// This should be ViewConfiguration.getTapTimeout()
// But system time out is 100ms, which is too short for the browser.
// In the browser, if it switches out of tap too soon, jump tap won't work.
@@ -324,8 +321,6 @@ public class WebView extends AbsoluteLayout
private int mContentHeight; // cache of value from WebViewCore
static int MAX_FLOAT_CONTENT_WIDTH = 480;
- // the calculated minimum content width for calculating the minimum scale.
- // If it is 0, it means don't use it.
private int mMinContentWidth;
// Need to have the separate control for horizontal and vertical scrollbar
@@ -558,9 +553,7 @@ public class WebView extends AbsoluteLayout
return mExtra;
}
}
-
- private ZoomButtonsController mZoomButtonsController;
-
+
private ZoomRingController mZoomRingController;
private ImageView mZoomRingOverview;
private Animation mZoomRingOverviewExitAnimation;
@@ -624,9 +617,6 @@ public class WebView extends AbsoluteLayout
/ ZOOM_RING_STEPS;
}
mZoomRingController.setThumbAngle(angle * MAX_ZOOM_RING_ANGLE);
-
- // Don't show a thumb if the user cannot zoom
- mZoomRingController.setThumbVisible(mMinZoomScale != mMaxZoomScale);
// Show the zoom overview tab on the ring
setZoomOverviewVisible(true);
@@ -743,26 +733,6 @@ public class WebView extends AbsoluteLayout
mZoomRingController.setPannerAcceleration(160);
mZoomRingController.setPannerStartAcceleratingDuration(700);
createZoomRingOverviewTab();
- mZoomButtonsController = new ZoomButtonsController(context, this);
- mZoomButtonsController.setOverviewVisible(true);
- mZoomButtonsController.setCallback(new ZoomButtonsController.OnZoomListener() {
- public void onCenter(int x, int y) {
- mZoomListener.onCenter(x, y);
- }
-
- public void onOverview() {
- mZoomButtonsController.setVisible(false);
- zoomScrollOut();
- }
-
- public void onVisibilityChanged(boolean visible) {
- mZoomListener.onVisibilityChanged(visible);
- }
-
- public void onZoom(boolean zoomIn) {
- mZoomListener.onSimpleZoom(zoomIn);
- }
- });
}
private void init() {
@@ -775,9 +745,6 @@ public class WebView extends AbsoluteLayout
final int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
mTouchSlopSquare = slop * slop;
mMinLockSnapReverseDistance = slop;
- final int doubleTapslop = ViewConfiguration.get(getContext())
- .getScaledDoubleTapSlop();
- mDoubleTapSlopSquare = doubleTapslop * doubleTapslop;
}
private void createZoomRingOverviewTab() {
@@ -796,7 +763,7 @@ public class WebView extends AbsoluteLayout
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER);
// TODO: magic constant that's based on the zoom ring radius + some offset
- lp.topMargin = 200;
+ lp.topMargin = 208;
mZoomRingOverview.setLayoutParams(lp);
mZoomRingOverview.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
@@ -2338,19 +2305,8 @@ public class WebView extends AbsoluteLayout
/**
* Use this function to bind an object to Javascript so that the
* methods can be accessed from Javascript.
- * <p><strong>IMPORTANT:</strong>
- * <ul>
- * <li> Using addJavascriptInterface() allows JavaScript to control your
- * application. This can be a very useful feature or a dangerous security
- * issue. When the HTML in the WebView is untrustworthy (for example, part
- * or all of the HTML is provided by some person or process), then an
- * attacker could inject HTML that will execute your code and possibly any
- * code of the attacker's choosing.<br>
- * Do not use addJavascriptInterface() unless all of the HTML in this
- * WebView was written by you.</li>
- * <li> The Java object that is bound runs in another thread and not in
- * the thread that it was constructed in.</li>
- * </ul></p>
+ * IMPORTANT, the object that is bound runs in another thread and
+ * not in the thread that it was constructed in.
* @param obj The class instance to bind to Javascript
* @param interfaceName The name to used to expose the class in Javascript
*/
@@ -3013,8 +2969,8 @@ public class WebView extends AbsoluteLayout
if (lp != null) {
// Take the last touch and adjust for the location of the
// TextDialog.
- float x = mLastTouchX + (float) (mScrollX - lp.x);
- float y = mLastTouchY + (float) (mScrollY - lp.y);
+ float x = mLastTouchX - lp.x;
+ float y = mLastTouchY - lp.y;
mTextEntry.fakeTouchEvent(x, y);
}
}
@@ -3208,9 +3164,6 @@ public class WebView extends AbsoluteLayout
mSelectX = mScrollX + (int) mLastTouchX;
mSelectY = mScrollY + (int) mLastTouchY;
}
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
- nativeClearFocus(contentX, contentY);
}
if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
@@ -3402,9 +3355,6 @@ public class WebView extends AbsoluteLayout
public void emulateShiftHeld() {
mExtendSelection = false;
mShiftIsPressed = true;
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
- nativeClearFocus(contentX, contentY);
}
private boolean commitCopy() {
@@ -3451,7 +3401,6 @@ public class WebView extends AbsoluteLayout
// Clean up the zoom ring
mZoomRingController.setVisible(false);
- mZoomButtonsController.setVisible(false);
}
// Implementation for OnHierarchyChangeListener
@@ -3500,17 +3449,8 @@ public class WebView extends AbsoluteLayout
// false for the first parameter
}
} else {
- if (!mZoomButtonsController.isVisible()) {
- /*
- * The zoom controls come in their own window, so our window
- * loses focus. Our policy is to not draw the focus ring if
- * our window is not focused, but this is an exception since
- * the user can still navigate the web page with the zoom
- * controls showing.
- */
- // If our window has lost focus, stop drawing the focus ring
- mDrawFocusRing = false;
- }
+ // If our window has lost focus, stop drawing the focus ring
+ mDrawFocusRing = false;
mGotKeyDown = false;
mShiftIsPressed = false;
if (mNativeClass != 0) {
@@ -3652,8 +3592,7 @@ public class WebView extends AbsoluteLayout
+ mTouchMode);
}
- if ((mZoomRingController.isVisible() || mZoomButtonsController.isVisible())
- && mInZoomTapDragMode) {
+ if (mZoomRingController.isVisible() && mInZoomTapDragMode) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
// Just released the second tap, no longer in tap-drag mode
mInZoomTapDragMode = false;
@@ -3691,9 +3630,6 @@ public class WebView extends AbsoluteLayout
mLastSentTouchTime = eventTime;
}
- int deltaX = (int) (mLastTouchX - x);
- int deltaY = (int) (mLastTouchY - y);
-
switch (action) {
case MotionEvent.ACTION_DOWN: {
if (mTouchMode == SCROLL_ZOOM_ANIMATION_IN
@@ -3719,23 +3655,16 @@ public class WebView extends AbsoluteLayout
, viewToContent(mSelectY), false);
mTouchSelection = mExtendSelection = true;
} else if (!ZoomRingController.useOldZoom(mContext) &&
- mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP) &&
- (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare)) {
+ mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
// Found doubletap, invoke the zoom controller
mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
- int contentX = viewToContent((int) mLastTouchX + mScrollX);
- int contentY = viewToContent((int) mLastTouchY + mScrollY);
- if (inEditingMode()) {
- mTextEntry.updateCachedTextfield();
- }
- nativeClearFocus(contentX, contentY);
+ mZoomRingController.setVisible(true);
mInZoomTapDragMode = true;
if (mLogEvent) {
EventLog.writeEvent(EVENT_LOG_DOUBLE_TAP_DURATION,
(eventTime - mLastTouchUpTime), eventTime);
}
- return mZoomRingController.handleDoubleTapEvent(ev) ||
- mZoomButtonsController.handleDoubleTapEvent(ev);
+ return mZoomRingController.handleDoubleTapEvent(ev);
} else {
mTouchMode = TOUCH_INIT_MODE;
mPreventDrag = mForwardTouchEvents;
@@ -3772,6 +3701,9 @@ public class WebView extends AbsoluteLayout
}
mVelocityTracker.addMovement(ev);
+ int deltaX = (int) (mLastTouchX - x);
+ int deltaY = (int) (mLastTouchY - y);
+
if (mTouchMode != TOUCH_DRAG_MODE) {
if (mTouchMode == TOUCH_SELECT_MODE) {
mSelectX = mScrollX + (int) x;
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 6ab088d..a7261c5 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1294,9 +1294,7 @@ final class WebViewCore {
draw.mViewPoint = new Point(mCurrentViewWidth, mCurrentViewHeight);
if (LOGV_ENABLED) Log.v(LOGTAG, "webkitDraw NEW_PICTURE_MSG_ID");
Message.obtain(mWebView.mPrivateHandler,
- WebView.NEW_PICTURE_MSG_ID,
- mViewportMinimumScale == 0 ? nativeGetContentMinPrefWidth()
- : 0,
+ WebView.NEW_PICTURE_MSG_ID, nativeGetContentMinPrefWidth(),
0, draw).sendToTarget();
nativeCheckNavCache();
if (mWebkitScrollX != 0 || mWebkitScrollY != 0) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9da78d0..f362e22 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -17,6 +17,7 @@
package android.widget;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
@@ -27,7 +28,6 @@ import android.os.Handler;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Editable;
-import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.Gravity;
@@ -893,16 +893,25 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mSyncMode = SYNC_FIRST_POSITION;
}
- setFilterText(ss.filter);
+ // Don't restore the type filter window when there is no keyboard
+ if (acceptFilter()) {
+ String filterText = ss.filter;
+ setFilterText(filterText);
+ }
requestLayout();
}
private boolean acceptFilter() {
final Context context = mContext;
+ final Configuration configuration = context.getResources().getConfiguration();
+ final boolean keyboardShowing = configuration.keyboardHidden !=
+ Configuration.KEYBOARDHIDDEN_YES;
+ final boolean hasKeyboard = configuration.keyboard != Configuration.KEYBOARD_NOKEYS;
final InputMethodManager inputManager = (InputMethodManager)
context.getSystemService(Context.INPUT_METHOD_SERVICE);
- return !inputManager.isFullscreenMode();
+ return (hasKeyboard && keyboardShowing) ||
+ (!hasKeyboard && !inputManager.isFullscreenMode());
}
/**
@@ -913,7 +922,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
*/
public void setFilterText(String filterText) {
// TODO: Should we check for acceptFilter()?
- if (mTextFilterEnabled && !TextUtils.isEmpty(filterText)) {
+ if (mTextFilterEnabled && filterText != null && filterText.length() > 0) {
createTextFilter(false);
// This is going to call our listener onTextChanged, but we might not
// be ready to bring up a window yet
@@ -933,18 +942,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
- /**
- * Returns the list's text filter, if available.
- * @return the list's text filter or null if filtering isn't enabled
- * @hide pending API Council approval
- */
- public CharSequence getTextFilter() {
- if (mTextFilterEnabled && mTextFilter != null) {
- return mTextFilter.getText();
- }
- return null;
- }
-
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java
index 1d553f1..b046a6b 100644
--- a/core/java/android/widget/AbsSeekBar.java
+++ b/core/java/android/widget/AbsSeekBar.java
@@ -40,15 +40,9 @@ public abstract class AbsSeekBar extends ProgressBar {
* Whether this is user seekable.
*/
boolean mIsUserSeekable = true;
-
- /**
- * On key presses (right or left), the amount to increment/decrement the
- * progress.
- */
- private int mKeyProgressIncrement = 1;
private static final int NO_ALPHA = 0xFF;
- private float mDisabledAlpha;
+ float mDisabledAlpha;
public AbsSeekBar(Context context) {
super(context);
@@ -107,39 +101,6 @@ public abstract class AbsSeekBar extends ProgressBar {
invalidate();
}
- /**
- * Sets the amount of progress changed via the arrow keys.
- *
- * @param increment The amount to increment or decrement when the user
- * presses the arrow keys.
- */
- public void setKeyProgressIncrement(int increment) {
- mKeyProgressIncrement = increment < 0 ? -increment : increment;
- }
-
- /**
- * Returns the amount of progress changed via the arrow keys.
- * <p>
- * By default, this will be a value that is derived from the max progress.
- *
- * @return The amount to increment or decrement when the user presses the
- * arrow keys. This will be positive.
- */
- public int getKeyProgressIncrement() {
- return mKeyProgressIncrement;
- }
-
- @Override
- public synchronized void setMax(int max) {
- super.setMax(max);
-
- if ((mKeyProgressIncrement == 0) || (getMax() / mKeyProgressIncrement > 20)) {
- // It will take the user too long to change this via keys, change it
- // to something more reasonable
- setKeyProgressIncrement(Math.max(1, Math.round((float) getMax() / 20)));
- }
- }
-
@Override
protected boolean verifyDrawable(Drawable who) {
return who == mThumb || super.verifyDrawable(who);
@@ -360,12 +321,12 @@ public abstract class AbsSeekBar extends ProgressBar {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
if (progress <= 0) break;
- setProgress(progress - mKeyProgressIncrement, true);
+ setProgress(progress - 1, true);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
if (progress >= getMax()) break;
- setProgress(progress + mKeyProgressIncrement, true);
+ setProgress(progress + 1, true);
return true;
}
diff --git a/core/java/android/widget/AnalogClock.java b/core/java/android/widget/AnalogClock.java
index f847bc3..cf9c588 100644
--- a/core/java/android/widget/AnalogClock.java
+++ b/core/java/android/widget/AnalogClock.java
@@ -48,6 +48,7 @@ public class AnalogClock extends View {
private int mDialHeight;
private boolean mAttached;
+ private long mLastTime;
private final Handler mHandler = new Handler();
private float mMinutes;
@@ -95,6 +96,7 @@ public class AnalogClock extends View {
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ onTimeChanged();
if (!mAttached) {
mAttached = true;
IntentFilter filter = new IntentFilter();
@@ -105,15 +107,6 @@ public class AnalogClock extends View {
getContext().registerReceiver(mIntentReceiver, filter, null, mHandler);
}
-
- // NOTE: It's safe to do these after registering the receiver since the receiver always runs
- // in the main thread, therefore the receiver can't run before this method returns.
-
- // The time zone may have changed while the receiver wasn't registered, so update the Time
- mCalendar = new Time();
-
- // Make sure we update to the current time
- onTimeChanged();
}
@Override
@@ -219,7 +212,9 @@ public class AnalogClock extends View {
}
private void onTimeChanged() {
- mCalendar.setToNow();
+ long time = System.currentTimeMillis();
+ mCalendar.set(time);
+ mLastTime = time;
int hour = mCalendar.hour;
int minute = mCalendar.minute;
@@ -236,6 +231,8 @@ public class AnalogClock extends View {
if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)) {
String tz = intent.getStringExtra("time-zone");
mCalendar = new Time(TimeZone.getTimeZone(tz).getID());
+ } else {
+ mCalendar = new Time();
}
onTimeChanged();
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 0c1c72a..7a51676 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -78,8 +78,6 @@ import com.android.internal.R;
* @attr ref android.R.styleable#AutoCompleteTextView_completionThreshold
* @attr ref android.R.styleable#AutoCompleteTextView_completionHintView
* @attr ref android.R.styleable#AutoCompleteTextView_dropDownSelector
- * @attr ref android.R.styleable#AutoCompleteTextView_dropDownAnchor
- * @attr ref android.R.styleable#AutoCompleteTextView_dropDownWidth
*/
public class AutoCompleteTextView extends EditText implements Filter.FilterListener {
static final boolean DEBUG = false;
@@ -98,9 +96,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
private DropDownListView mDropDownList;
private int mDropDownVerticalOffset;
private int mDropDownHorizontalOffset;
- private int mDropDownAnchorId;
- private View mDropDownAnchorView; // view is retrieved lazily from id once needed
- private int mDropDownWidth;
private Drawable mDropDownListHighlight;
@@ -152,18 +147,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
a.getDimension(R.styleable.AutoCompleteTextView_dropDownVerticalOffset, 0.0f);
mDropDownHorizontalOffset = (int)
a.getDimension(R.styleable.AutoCompleteTextView_dropDownHorizontalOffset, 0.0f);
-
- // Get the anchor's id now, but the view won't be ready, so wait to actually get the
- // view and store it in mDropDownAnchorView lazily in getDropDownAnchorView later.
- // Defaults to NO_ID, in which case the getDropDownAnchorView method will simply return
- // this TextView, as a default anchoring point.
- mDropDownAnchorId = a.getResourceId(R.styleable.AutoCompleteTextView_dropDownAnchor,
- View.NO_ID);
-
- // For dropdown width, the developer can specify a specific width, or FILL_PARENT
- // (for full screen width) or WRAP_CONTENT (to match the width of the anchored view).
- mDropDownWidth = a.getLayoutDimension(R.styleable.AutoCompleteTextView_dropDownWidth,
- ViewGroup.LayoutParams.WRAP_CONTENT);
mHintResource = a.getResourceId(R.styleable.AutoCompleteTextView_completionHintView,
R.layout.simple_dropdown_hint);
@@ -204,49 +187,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
public void setCompletionHint(CharSequence hint) {
mHintText = hint;
}
-
- /**
- * <p>Returns the current width for the auto-complete drop down list. This can
- * be a fixed width, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill the screen, or
- * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
- *
- * @return the width for the drop down list
- */
- public int getDropDownWidth() {
- return mDropDownWidth;
- }
-
- /**
- * <p>Sets the current width for the auto-complete drop down list. This can
- * be a fixed width, or {@link ViewGroup.LayoutParams#FILL_PARENT} to fill the screen, or
- * {@link ViewGroup.LayoutParams#WRAP_CONTENT} to fit the width of its anchor view.</p>
- *
- * @param width the width to use
- */
- public void setDropDownWidth(int width) {
- mDropDownWidth = width;
- }
-
- /**
- * <p>Returns the id for the view that the auto-complete drop down list is anchored to.</p>
- *
- * @return the view's id, or {@link View#NO_ID} if none specified
- */
- public int getDropDownAnchor() {
- return mDropDownAnchorId;
- }
-
- /**
- * <p>Sets the view to which the auto-complete drop down list should anchor. The view
- * corresponding to this id will not be loaded until the next time it is needed to avoid
- * loading a view which is not yet instantiated.</p>
- *
- * @param id the id to anchor the drop down list view to
- */
- public void setDropDownAnchor(int id) {
- mDropDownAnchorId = id;
- mDropDownAnchorView = null;
- }
/**
* <p>Returns the number of characters the user must type before the drop
@@ -801,18 +741,6 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
return result;
}
-
- /**
- * <p>Used for lazy instantiation of the anchor view from the id we have. If the value of
- * the id is NO_ID or we can't find a view for the given id, we return this TextView as
- * the default anchoring point.</p>
- */
- private View getDropDownAnchorView() {
- if (mDropDownAnchorView == null && mDropDownAnchorId != View.NO_ID) {
- mDropDownAnchorView = getRootView().findViewById(mDropDownAnchorId);
- }
- return mDropDownAnchorView == null ? this : mDropDownAnchorView;
- }
/**
* <p>Displays the drop down on screen.</p>
@@ -820,37 +748,16 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
public void showDropDown() {
int height = buildDropDown();
if (mPopup.isShowing()) {
- int widthSpec;
- if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) {
- // The call to PopupWindow's update method below can accept -1 for any
- // value you do not want to update.
- widthSpec = -1;
- } else if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
- widthSpec = getDropDownAnchorView().getWidth();
- } else {
- widthSpec = mDropDownWidth;
- }
- mPopup.update(getDropDownAnchorView(), mDropDownHorizontalOffset,
- mDropDownVerticalOffset, widthSpec, height);
+ mPopup.update(this, mDropDownHorizontalOffset, mDropDownVerticalOffset,
+ getWidth(), height);
} else {
- int widthSpec;
- if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) {
- mPopup.setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- } else {
- mPopup.setWindowLayoutMode(0, ViewGroup.LayoutParams.WRAP_CONTENT);
- if (mDropDownWidth == ViewGroup.LayoutParams.WRAP_CONTENT) {
- mPopup.setWidth(getDropDownAnchorView().getWidth());
- } else {
- mPopup.setWidth(mDropDownWidth);
- }
- }
+ mPopup.setWindowLayoutMode(0, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mPopup.setWidth(getWidth());
mPopup.setHeight(height);
mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
mPopup.setOutsideTouchable(true);
mPopup.setTouchInterceptor(new PopupTouchIntercepter());
- mPopup.showAsDropDown(getDropDownAnchorView(),
- mDropDownHorizontalOffset, mDropDownVerticalOffset);
+ mPopup.showAsDropDown(this, mDropDownHorizontalOffset, mDropDownVerticalOffset);
mDropDownList.setSelection(ListView.INVALID_POSITION);
mDropDownList.hideSelector();
mDropDownList.requestFocus();
diff --git a/core/java/android/widget/BaseAdapter.java b/core/java/android/widget/BaseAdapter.java
index 532fd76..1921d73 100644
--- a/core/java/android/widget/BaseAdapter.java
+++ b/core/java/android/widget/BaseAdapter.java
@@ -42,10 +42,6 @@ public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
mDataSetObservable.unregisterObserver(observer);
}
- /**
- * Notifies the attached View that the underlying data has been changed
- * and it should refresh itself.
- */
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
diff --git a/core/java/android/widget/Chronometer.java b/core/java/android/widget/Chronometer.java
index 91add58..369221e 100644
--- a/core/java/android/widget/Chronometer.java
+++ b/core/java/android/widget/Chronometer.java
@@ -69,10 +69,7 @@ public class Chronometer extends TextView {
private Object[] mFormatterArgs = new Object[1];
private StringBuilder mFormatBuilder;
private OnChronometerTickListener mOnChronometerTickListener;
- private StringBuilder mRecycle = new StringBuilder(8);
-
- private static final int TICK_WHAT = 2;
-
+
/**
* Initialize this Chronometer object.
* Sets the base to the current time.
@@ -118,7 +115,6 @@ public class Chronometer extends TextView {
@android.view.RemotableViewMethod
public void setBase(long base) {
mBase = base;
- dispatchChronometerTick();
updateText(SystemClock.elapsedRealtime());
}
@@ -220,10 +216,10 @@ public class Chronometer extends TextView {
updateRunning();
}
- private synchronized void updateText(long now) {
+ private void updateText(long now) {
long seconds = now - mBase;
seconds /= 1000;
- String text = DateUtils.formatElapsedTime(mRecycle, seconds);
+ String text = DateUtils.formatElapsedTime(seconds);
if (mFormat != null) {
Locale loc = Locale.getDefault();
@@ -251,10 +247,7 @@ public class Chronometer extends TextView {
if (running != mRunning) {
if (running) {
updateText(SystemClock.elapsedRealtime());
- dispatchChronometerTick();
- mHandler.sendMessageDelayed(Message.obtain(mHandler, TICK_WHAT), 1000);
- } else {
- mHandler.removeMessages(TICK_WHAT);
+ mHandler.sendMessageDelayed(Message.obtain(), 1000);
}
mRunning = running;
}
@@ -262,10 +255,10 @@ public class Chronometer extends TextView {
private Handler mHandler = new Handler() {
public void handleMessage(Message m) {
- if (mRunning) {
+ if (mStarted) {
updateText(SystemClock.elapsedRealtime());
dispatchChronometerTick();
- sendMessageDelayed(Message.obtain(this, TICK_WHAT), 1000);
+ sendMessageDelayed(Message.obtain(), 1000);
}
}
};
diff --git a/core/java/android/widget/CursorAdapter.java b/core/java/android/widget/CursorAdapter.java
index 898e501..3d758e7 100644
--- a/core/java/android/widget/CursorAdapter.java
+++ b/core/java/android/widget/CursorAdapter.java
@@ -348,21 +348,6 @@ public abstract class CursorAdapter extends BaseAdapter implements Filterable,
mFilterQueryProvider = filterQueryProvider;
}
- /**
- * Called when the {@link ContentObserver} on the cursor receives a change notification.
- * The default implementation provides the auto-requery logic, but may be overridden by
- * sub classes.
- *
- * @see ContentObserver#onChange(boolean)
- * @hide pending API Council approval
- */
- protected void onContentChanged() {
- if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
- if (Config.LOGV) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
- mDataValid = mCursor.requery();
- }
- }
-
private class ChangeObserver extends ContentObserver {
public ChangeObserver() {
super(new Handler());
@@ -375,7 +360,10 @@ public abstract class CursorAdapter extends BaseAdapter implements Filterable,
@Override
public void onChange(boolean selfChange) {
- onContentChanged();
+ if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
+ if (Config.LOGV) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
+ mDataValid = mCursor.requery();
+ }
}
}
diff --git a/core/java/android/widget/Filter.java b/core/java/android/widget/Filter.java
index 1d0fd5e..a2316cf 100644
--- a/core/java/android/widget/Filter.java
+++ b/core/java/android/widget/Filter.java
@@ -45,6 +45,8 @@ public abstract class Filter {
private Handler mThreadHandler;
private Handler mResultHandler;
+ private String mConstraint;
+ private boolean mConstraintIsValid = false;
/**
* <p>Creates a new asynchronous filter.</p>
@@ -82,6 +84,13 @@ public abstract class Filter {
*/
public final void filter(CharSequence constraint, FilterListener listener) {
synchronized (this) {
+ String constraintAsString = constraint != null ? constraint.toString() : null;
+ if (mConstraintIsValid && (
+ (constraintAsString == null && mConstraint == null) ||
+ (constraintAsString != null && constraintAsString.equals(mConstraint)))) {
+ // nothing to do
+ return;
+ }
if (mThreadHandler == null) {
HandlerThread thread = new HandlerThread(THREAD_NAME);
@@ -94,13 +103,16 @@ public abstract class Filter {
RequestArguments args = new RequestArguments();
// make sure we use an immutable copy of the constraint, so that
// it doesn't change while the filter operation is in progress
- args.constraint = constraint != null ? constraint.toString() : null;
+ args.constraint = constraintAsString;
args.listener = listener;
message.obj = args;
mThreadHandler.removeMessages(FILTER_TOKEN);
mThreadHandler.removeMessages(FINISH_TOKEN);
mThreadHandler.sendMessage(message);
+
+ mConstraint = constraintAsString;
+ mConstraintIsValid = true;
}
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 6bbf062..38bfc7c 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -924,23 +924,32 @@ public class GridView extends AbsListView {
final int count = mItemCount;
if (count > 0) {
final View child = obtainView(0);
+ final int childViewType = mAdapter.getItemViewType(0);
- AbsListView.LayoutParams p = (AbsListView.LayoutParams)child.getLayoutParams();
- if (p == null) {
- p = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
+ AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
+ if (lp == null) {
+ lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
+ child.setLayoutParams(lp);
}
- p.viewType = mAdapter.getItemViewType(0);
+ lp.viewType = childViewType;
- int childHeightSpec = getChildMeasureSpec(
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height);
- int childWidthSpec = getChildMeasureSpec(
- MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width);
- child.measure(childWidthSpec, childHeightSpec);
+ final int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
+ mListPadding.left + mListPadding.right, lp.width);
+
+ int lpHeight = lp.height;
+ int childHeightSpec;
+ if (lpHeight > 0) {
+ childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
+ } else {
+ childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ }
+
+ child.measure(childWidthSpec, childHeightSpec);
childHeight = child.getMeasuredHeight();
- if (mRecycler.shouldRecycleViewType(p.viewType)) {
+ if (mRecycler.shouldRecycleViewType(childViewType)) {
mRecycler.addScrapView(child);
}
}
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 652e30c..96fe595 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -875,7 +875,7 @@ public class HorizontalScrollView extends FrameLayout {
int parentHeightMeasureSpec, int heightUsed) {
final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
- final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
+ final int childHeightMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
+ heightUsed, lp.height);
final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index a4523b9..94d1bd1 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -840,7 +840,7 @@ public class ImageView extends View {
@Override
public int getBaseline() {
- return mBaselineAligned ? getMeasuredHeight() : -1;
+ return mBaselineAligned ? getHeight() : -1;
}
/**
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 6df72d4..4e5989c 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1011,13 +1011,34 @@ public class ListView extends AbsListView {
if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED ||
heightMode == MeasureSpec.UNSPECIFIED)) {
final View child = obtainView(0);
+ final int childViewType = mAdapter.getItemViewType(0);
- measureScrapChild(child, 0, widthMeasureSpec);
+ AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
+ if (lp == null) {
+ lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, 0);
+ child.setLayoutParams(lp);
+ }
+ lp.viewType = childViewType;
+
+ final int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
+ mListPadding.left + mListPadding.right, lp.width);
+
+ int lpHeight = lp.height;
+
+ int childHeightSpec;
+ if (lpHeight > 0) {
+ childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
+ } else {
+ childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ }
+
+ child.measure(childWidthSpec, childHeightSpec);
childWidth = child.getMeasuredWidth();
childHeight = child.getMeasuredHeight();
- if (recycleOnMeasure()) {
+ if (mRecycler.shouldRecycleViewType(childViewType)) {
mRecycler.addScrapView(child);
}
}
@@ -1034,40 +1055,13 @@ public class ListView extends AbsListView {
if (heightMode == MeasureSpec.AT_MOST) {
// TODO: after first layout we should maybe start at the first visible position, not 0
- heightSize = measureHeightOfChildren(widthMeasureSpec, 0, NO_POSITION, heightSize, -1);
+ heightSize = measureHeightOfChildren(
+ MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY),
+ 0, NO_POSITION, heightSize, -1);
}
setMeasuredDimension(widthSize, heightSize);
- mWidthMeasureSpec = widthMeasureSpec;
- }
-
- private void measureScrapChild(View child, int position, int widthMeasureSpec) {
- LayoutParams p = (LayoutParams) child.getLayoutParams();
- if (p == null) {
- p = new LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT, 0);
- }
- p.viewType = mAdapter.getItemViewType(position);
-
- int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec,
- mListPadding.left + mListPadding.right, p.width);
- int lpHeight = p.height;
- int childHeightSpec;
- if (lpHeight > 0) {
- childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
- } else {
- childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- }
- child.measure(childWidthSpec, childHeightSpec);
- }
-
- /**
- * @return True to recycle the views used to measure this ListView in
- * UNSPECIFIED/AT_MOST modes, false otherwise.
- * @hide
- */
- protected boolean recycleOnMeasure() {
- return true;
+ mWidthMeasureSpec = widthMeasureSpec;
}
/**
@@ -1096,8 +1090,8 @@ public class ListView extends AbsListView {
* startPosition is 0).
* @return The height of this ListView with the given children.
*/
- final int measureHeightOfChildren(int widthMeasureSpec, int startPosition, int endPosition,
- final int maxHeight, int disallowPartialChildPosition) {
+ final int measureHeightOfChildren(final int widthMeasureSpec, final int startPosition,
+ int endPosition, final int maxHeight, int disallowPartialChildPosition) {
final ListAdapter adapter = mAdapter;
if (adapter == null) {
@@ -1116,20 +1110,29 @@ public class ListView extends AbsListView {
// mItemCount - 1 since endPosition parameter is inclusive
endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition;
final AbsListView.RecycleBin recycleBin = mRecycler;
- final boolean recyle = recycleOnMeasure();
-
for (i = startPosition; i <= endPosition; ++i) {
child = obtainView(i);
+ final int childViewType = adapter.getItemViewType(i);
- measureScrapChild(child, i, widthMeasureSpec);
+ AbsListView.LayoutParams lp = (AbsListView.LayoutParams) child.getLayoutParams();
+ if (lp == null) {
+ lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, 0);
+ child.setLayoutParams(lp);
+ }
+ lp.viewType = childViewType;
if (i > 0) {
// Count the divider for all but one child
returnedHeight += dividerHeight;
}
+ child.measure(widthMeasureSpec, lp.height >= 0
+ ? MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY)
+ : MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+
// Recycle the view before we possibly return from the method
- if (recyle) {
+ if (recycleBin.shouldRecycleViewType(childViewType)) {
recycleBin.addScrapView(child);
}
@@ -1653,7 +1656,7 @@ public class ListView extends AbsListView {
// Respect layout params that are already in the view. Otherwise make some up...
// noinspection unchecked
- AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams();
+ AbsListView.LayoutParams p = (AbsListView.LayoutParams)child.getLayoutParams();
if (p == null) {
p = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
@@ -1672,7 +1675,7 @@ public class ListView extends AbsListView {
if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
if (child instanceof Checkable) {
- ((Checkable) child).setChecked(mCheckStates.get(position));
+ ((Checkable)child).setChecked(mCheckStates.get(position));
}
}
diff --git a/core/java/android/widget/MultiAutoCompleteTextView.java b/core/java/android/widget/MultiAutoCompleteTextView.java
index 05abc26..59a9310 100644
--- a/core/java/android/widget/MultiAutoCompleteTextView.java
+++ b/core/java/android/widget/MultiAutoCompleteTextView.java
@@ -126,7 +126,7 @@ public class MultiAutoCompleteTextView extends AutoCompleteTextView {
Editable text = getText();
int end = getSelectionEnd();
- if (end < 0 || mTokenizer == null) {
+ if (end < 0) {
return false;
}
@@ -147,7 +147,7 @@ public class MultiAutoCompleteTextView extends AutoCompleteTextView {
public void performValidation() {
Validator v = getValidator();
- if (v == null || mTokenizer == null) {
+ if (v == null) {
return;
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 53db77e..4a5cea1 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -30,7 +30,6 @@ import android.view.View.OnTouchListener;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
import android.os.IBinder;
import android.content.Context;
import android.content.res.TypedArray;
@@ -103,8 +102,6 @@ public class PopupWindow {
private Rect mTempRect = new Rect();
private Drawable mBackground;
- private Drawable mAboveAnchorBackgroundDrawable;
- private Drawable mBelowAnchorBackgroundDrawable;
private boolean mAboveAnchor;
@@ -167,43 +164,6 @@ public class PopupWindow {
mBackground = a.getDrawable(R.styleable.PopupWindow_popupBackground);
- // If this is a StateListDrawable, try to find and store the drawable to be
- // used when the drop-down is placed above its anchor view, and the one to be
- // used when the drop-down is placed below its anchor view. We extract
- // the drawables ourselves to work around a problem with using refreshDrawableState
- // that it will take into account the padding of all drawables specified in a
- // StateListDrawable, thus adding superfluous padding to drop-down views.
- //
- // We assume a StateListDrawable will have a drawable for ABOVE_ANCHOR_STATE_SET and
- // at least one other drawable, intended for the 'below-anchor state'.
- if (mBackground instanceof StateListDrawable) {
- StateListDrawable background = (StateListDrawable) mBackground;
-
- // Find the above-anchor view - this one's easy, it should be labeled as such.
- int aboveAnchorStateIndex = background.getStateDrawableIndex(ABOVE_ANCHOR_STATE_SET);
-
- // Now, for the below-anchor view, look for any other drawable specified in the
- // StateListDrawable which is not for the above-anchor state and use that.
- int count = background.getStateCount();
- int belowAnchorStateIndex = -1;
- for (int i = 0; i < count; i++) {
- if (i != aboveAnchorStateIndex) {
- belowAnchorStateIndex = i;
- break;
- }
- }
-
- // Store the drawables we found, if we found them. Otherwise, set them both
- // to null so that we'll just use refreshDrawableState.
- if (aboveAnchorStateIndex != -1 && belowAnchorStateIndex != -1) {
- mAboveAnchorBackgroundDrawable = background.getStateDrawable(aboveAnchorStateIndex);
- mBelowAnchorBackgroundDrawable = background.getStateDrawable(belowAnchorStateIndex);
- } else {
- mBelowAnchorBackgroundDrawable = null;
- mAboveAnchorBackgroundDrawable = null;
- }
- }
-
a.recycle();
}
@@ -701,18 +661,7 @@ public class PopupWindow {
mAboveAnchor = findDropDownPosition(anchor, p, xoff, yoff);
if (mBackground != null) {
- // If the background drawable provided was a StateListDrawable with above-anchor
- // and below-anchor states, use those. Otherwise rely on refreshDrawableState to
- // do the job.
- if (mAboveAnchorBackgroundDrawable != null) {
- if (mAboveAnchor) {
- mPopupView.setBackgroundDrawable(mAboveAnchorBackgroundDrawable);
- } else {
- mPopupView.setBackgroundDrawable(mBelowAnchorBackgroundDrawable);
- }
- } else {
- mPopupView.refreshDrawableState();
- }
+ mPopupView.refreshDrawableState();
}
if (mHeightMode < 0) p.height = mLastHeight = mHeightMode;
@@ -748,18 +697,12 @@ public class PopupWindow {
*/
private void preparePopup(WindowManager.LayoutParams p) {
if (mBackground != null) {
- final ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams();
- int height = ViewGroup.LayoutParams.FILL_PARENT;
- if (layoutParams != null &&
- layoutParams.height == ViewGroup.LayoutParams.WRAP_CONTENT) {
- height = ViewGroup.LayoutParams.WRAP_CONTENT;
- }
-
// when a background is available, we embed the content view
// within another view that owns the background drawable
PopupViewContainer popupViewContainer = new PopupViewContainer(mContext);
PopupViewContainer.LayoutParams listParams = new PopupViewContainer.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, height
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT
);
popupViewContainer.setBackgroundDrawable(mBackground);
popupViewContainer.addView(mContentView, listParams);
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index f646ab5..dd2570a 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -526,7 +526,6 @@ public class ProgressBar extends View {
* @see #getProgress()
* @see #incrementProgressBy(int)
*/
- @android.view.RemotableViewMethod
public synchronized void setProgress(int progress) {
setProgress(progress, false);
}
diff --git a/core/java/android/widget/ResourceCursorAdapter.java b/core/java/android/widget/ResourceCursorAdapter.java
index a5dbd98..9052ae3 100644
--- a/core/java/android/widget/ResourceCursorAdapter.java
+++ b/core/java/android/widget/ResourceCursorAdapter.java
@@ -46,30 +46,10 @@ public abstract class ResourceCursorAdapter extends CursorAdapter {
public ResourceCursorAdapter(Context context, int layout, Cursor c) {
super(context, c);
mLayout = mDropDownLayout = layout;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
- * Constructor.
- *
- * @param context The context where the ListView associated with this
- * SimpleListItemFactory is running
- * @param layout resource identifier of a layout file that defines the views
- * for this list item. Unless you override them later, this will
- * define both the item views and the drop down views.
- * @param c The cursor from which to get the data.
- * @param autoRequery If true the adapter will call requery() on the
- * cursor whenever it changes so the most recent
- * data is always displayed.
- * @hide Pending API Council approval
- */
- public ResourceCursorAdapter(Context context, int layout, Cursor c, boolean autoRequery) {
- super(context, c, autoRequery);
- mLayout = mDropDownLayout = layout;
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- }
-
- /**
* Inflates view(s) from the specified XML file.
*
* @see android.widget.CursorAdapter#newView(android.content.Context,
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 88b2a01..c852be5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -84,7 +84,6 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
-import android.view.ViewRoot;
import android.view.ViewTreeObserver;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AnimationUtils;
@@ -216,7 +215,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int mDrawableSizeTop, mDrawableSizeBottom, mDrawableSizeLeft, mDrawableSizeRight;
int mDrawableWidthTop, mDrawableWidthBottom, mDrawableHeightLeft, mDrawableHeightRight;
int mDrawablePadding;
- }
+ };
private Drawables mDrawables;
private CharSequence mError;
@@ -240,13 +239,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private int mMarqueeRepeatLimit = 3;
class InputContentType {
- int imeOptions = EditorInfo.IME_UNDEFINED;
- String privateImeOptions;
- CharSequence imeActionLabel;
- int imeActionId;
+ String privateContentType;
Bundle extras;
- OnEditorActionListener onEditorActionListener;
- boolean enterDown;
}
InputContentType mInputContentType;
@@ -274,26 +268,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
p.measureText("H");
}
- /**
- * Interface definition for a callback to be invoked when an action is
- * performed on the editor.
- */
- public interface OnEditorActionListener {
- /**
- * Called when an action is being performed.
- *
- * @param v The view that was clicked.
- * @param actionId Identifier of the action. This will be either the
- * identifier you supplied, or {@link EditorInfo#IME_UNDEFINED
- * EditorInfo.IME_UNDEFINED} if being called due to the enter key
- * being pressed.
- * @param event If triggered by an enter key, this is the event;
- * otherwise, this is null.
- * @return Return true if you have consumed the action, else false.
- */
- boolean onEditorAction(TextView v, int actionId, KeyEvent event);
- }
-
public TextView(Context context) {
this(context, null);
}
@@ -402,7 +376,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
int shadowcolor = 0;
float dx = 0, dy = 0, r = 0;
boolean password = false;
- int inputType = EditorInfo.TYPE_NULL;
+ int contentType = EditorInfo.TYPE_NULL;
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
@@ -636,34 +610,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case com.android.internal.R.styleable.TextView_inputType:
- inputType = a.getInt(attr, mInputType);
+ contentType = a.getInt(attr, mInputType);
break;
- case com.android.internal.R.styleable.TextView_imeOptions:
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
- }
- mInputContentType.imeOptions = a.getInt(attr,
- mInputContentType.imeOptions);
- break;
-
- case com.android.internal.R.styleable.TextView_imeActionLabel:
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
- }
- mInputContentType.imeActionLabel = a.getText(attr);
- break;
-
- case com.android.internal.R.styleable.TextView_imeActionId:
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
- }
- mInputContentType.imeActionId = a.getInt(attr,
- mInputContentType.imeActionId);
- break;
-
- case com.android.internal.R.styleable.TextView_privateImeOptions:
- setPrivateImeOptions(a.getString(attr));
+ case com.android.internal.R.styleable.TextView_editorPrivateContentType:
+ setPrivateContentType(a.getString(attr));
break;
case com.android.internal.R.styleable.TextView_editorExtras:
@@ -681,7 +632,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
BufferType bufferType = BufferType.EDITABLE;
- if ((inputType&(EditorInfo.TYPE_MASK_CLASS
+ if ((contentType&(EditorInfo.TYPE_MASK_CLASS
|EditorInfo.TYPE_MASK_VARIATION))
== (EditorInfo.TYPE_CLASS_TEXT
|EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {
@@ -705,57 +656,57 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
throw new RuntimeException(ex);
}
try {
- mInputType = inputType != EditorInfo.TYPE_NULL
- ? inputType
+ mInputType = contentType != EditorInfo.TYPE_NULL
+ ? contentType
: mInput.getInputType();
} catch (IncompatibleClassChangeError e) {
mInputType = EditorInfo.TYPE_CLASS_TEXT;
}
} else if (digits != null) {
mInput = DigitsKeyListener.getInstance(digits.toString());
- mInputType = inputType;
- } else if (inputType != EditorInfo.TYPE_NULL) {
- setInputType(inputType, true);
- singleLine = (inputType&(EditorInfo.TYPE_MASK_CLASS
+ mInputType = contentType;
+ } else if (contentType != EditorInfo.TYPE_NULL) {
+ setInputType(contentType, true);
+ singleLine = (contentType&(EditorInfo.TYPE_MASK_CLASS
| EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE)) !=
(EditorInfo.TYPE_CLASS_TEXT
| EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE);
} else if (phone) {
mInput = DialerKeyListener.getInstance();
- inputType = EditorInfo.TYPE_CLASS_PHONE;
+ contentType = EditorInfo.TYPE_CLASS_PHONE;
} else if (numeric != 0) {
mInput = DigitsKeyListener.getInstance((numeric & SIGNED) != 0,
(numeric & DECIMAL) != 0);
- inputType = EditorInfo.TYPE_CLASS_NUMBER;
+ contentType = EditorInfo.TYPE_CLASS_NUMBER;
if ((numeric & SIGNED) != 0) {
- inputType |= EditorInfo.TYPE_NUMBER_FLAG_SIGNED;
+ contentType |= EditorInfo.TYPE_NUMBER_FLAG_SIGNED;
}
if ((numeric & DECIMAL) != 0) {
- inputType |= EditorInfo.TYPE_NUMBER_FLAG_DECIMAL;
+ contentType |= EditorInfo.TYPE_NUMBER_FLAG_DECIMAL;
}
- mInputType = inputType;
+ mInputType = contentType;
} else if (autotext || autocap != -1) {
TextKeyListener.Capitalize cap;
- inputType = EditorInfo.TYPE_CLASS_TEXT;
+ contentType = EditorInfo.TYPE_CLASS_TEXT;
if (!singleLine) {
- inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+ contentType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
}
switch (autocap) {
case 1:
cap = TextKeyListener.Capitalize.SENTENCES;
- inputType |= EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES;
+ contentType |= EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES;
break;
case 2:
cap = TextKeyListener.Capitalize.WORDS;
- inputType |= EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS;
+ contentType |= EditorInfo.TYPE_TEXT_FLAG_CAP_WORDS;
break;
case 3:
cap = TextKeyListener.Capitalize.CHARACTERS;
- inputType |= EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS;
+ contentType |= EditorInfo.TYPE_TEXT_FLAG_CAP_CHARACTERS;
break;
default:
@@ -764,7 +715,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
mInput = TextKeyListener.getInstance(autotext, cap);
- mInputType = inputType;
+ mInputType = contentType;
} else if (editable) {
mInput = TextKeyListener.getInstance();
mInputType = EditorInfo.TYPE_CLASS_TEXT;
@@ -1124,11 +1075,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_singleLine
*/
public final void setTransformationMethod(TransformationMethod method) {
- if (method == mTransformation) {
- // Avoid the setText() below if the transformation is
- // the same.
- return;
- }
if (mTransformation != null) {
if (mText instanceof Spannable) {
((Spannable) mText).removeSpan(mTransformation);
@@ -2832,7 +2778,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/**
* Directly change the content type integer of the text view, without
* modifying any other state.
- * @see #setInputType(int)
+ * @see #setContentType
* @see android.text.InputType
* @attr ref android.R.styleable#TextView_inputType
*/
@@ -2896,159 +2842,28 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
- * Change the editor type integer associated with the text view, which
- * will be reported to an IME with {@link EditorInfo#imeOptions} when it
- * has focus.
- * @see #getImeOptions
- * @see android.view.inputmethod.EditorInfo
- * @attr ref android.R.styleable#TextView_imeOptions
- */
- public void setImeOptions(int imeOptions) {
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
- }
- mInputContentType.imeOptions = imeOptions;
- }
-
- /**
- * Get the type of the IME editor.
- *
- * @see #setImeOptions(int)
- * @see android.view.inputmethod.EditorInfo
- */
- public int getImeOptions() {
- return mInputContentType != null
- ? mInputContentType.imeOptions : EditorInfo.IME_UNDEFINED;
- }
-
- /**
- * Change the custom IME action associated with the text view, which
- * will be reported to an IME with {@link EditorInfo#actionLabel}
- * and {@link EditorInfo#actionId} when it has focus.
- * @see #getImeActionLabel
- * @see #getImeActionId
- * @see android.view.inputmethod.EditorInfo
- * @attr ref android.R.styleable#TextView_imeActionLabel
- * @attr ref android.R.styleable#TextView_imeActionId
- */
- public void setImeActionLabel(CharSequence label, int actionId) {
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
- }
- mInputContentType.imeActionLabel = label;
- mInputContentType.imeActionId = actionId;
- }
-
- /**
- * Get the IME action label previous set with {@link #setImeActionLabel}.
- *
- * @see #setImeActionLabel
- * @see android.view.inputmethod.EditorInfo
- */
- public CharSequence getImeActionLabel() {
- return mInputContentType != null
- ? mInputContentType.imeActionLabel : null;
- }
-
- /**
- * Get the IME action ID previous set with {@link #setImeActionLabel}.
- *
- * @see #setImeActionLabel
- * @see android.view.inputmethod.EditorInfo
- */
- public int getImeActionId() {
- return mInputContentType != null
- ? mInputContentType.imeActionId : 0;
- }
-
- /**
- * Set a special OnClickListener to be called when an action is performed
- * on the text view. This will be called when the enter key is pressed,
- * or when an action supplied to the IME is selected by the user.
- */
- public void setOnEditorActionListener(OnEditorActionListener l) {
- if (mInputContentType == null) {
- mInputContentType = new InputContentType();
- }
- mInputContentType.onEditorActionListener = l;
- }
-
- /**
- * Called when an attached input method calls
- * {@link InputConnection#performEditorAction(int)
- * InputConnection.performEditorAction()}
- * for this text view. The default implementation will call your click
- * listener supplied to {@link #setOnEditorActionListener},
- * or generate an enter key down/up pair to invoke the action if not.
- *
- * @param actionCode The code of the action being performed.
- *
- * @see #setOnEditorActionListener
- */
- public void onEditorAction(int actionCode) {
- final InputContentType ict = mInputContentType;
- if (ict != null) {
- if (ict.onEditorActionListener != null) {
- if (ict.onEditorActionListener.onEditorAction(this,
- actionCode, null)) {
- return;
- }
- }
- }
-
- if (actionCode == EditorInfo.IME_ACTION_NEXT &&
- (ict != null || !shouldAdvanceFocusOnEnter())) {
- // This is the default handling for the NEXT action, to advance
- // focus. Note that for backwards compatibility we don't do this
- // default handling if explicit ime options have not been given,
- // and we do not advance by default on an enter key -- in that
- // case, we want to turn this into the normal enter key codes that
- // an app may be expecting.
- View v = focusSearch(FOCUS_DOWN);
- if (v != null) {
- if (!v.requestFocus(FOCUS_DOWN)) {
- throw new IllegalStateException("focus search returned a view " +
- "that wasn't able to take focus!");
- }
- }
- return;
- }
-
- Handler h = getHandler();
- long eventTime = SystemClock.uptimeMillis();
- h.sendMessage(h.obtainMessage(ViewRoot.DISPATCH_KEY_FROM_IME,
- new KeyEvent(eventTime, eventTime,
- KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 0, 0, 0, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
- h.sendMessage(h.obtainMessage(ViewRoot.DISPATCH_KEY_FROM_IME,
- new KeyEvent(SystemClock.uptimeMillis(), eventTime,
- KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0, 0, 0, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
- }
-
- /**
* Set the private content type of the text, which is the
- * {@link EditorInfo#privateImeOptions EditorInfo.privateImeOptions}
+ * {@link EditorInfo#privateContentType TextBoxAttribute.privateContentType}
* field that will be filled in when creating an input connection.
*
- * @see #getPrivateImeOptions()
- * @see EditorInfo#privateImeOptions
- * @attr ref android.R.styleable#TextView_privateImeOptions
+ * @see #getPrivateContentType()
+ * @see EditorInfo#privateContentType
+ * @attr ref android.R.styleable#TextView_editorPrivateContentType
*/
- public void setPrivateImeOptions(String type) {
+ public void setPrivateContentType(String type) {
if (mInputContentType == null) mInputContentType = new InputContentType();
- mInputContentType.privateImeOptions = type;
+ mInputContentType.privateContentType = type;
}
/**
* Get the private type of the content.
*
- * @see #setPrivateImeOptions(String)
- * @see EditorInfo#privateImeOptions
+ * @see #setPrivateContentType(String)
+ * @see EditorInfo#privateContentType
*/
- public String getPrivateImeOptions() {
+ public String getPrivateContentType() {
return mInputContentType != null
- ? mInputContentType.privateImeOptions : null;
+ ? mInputContentType.privateContentType : null;
}
/**
@@ -3992,7 +3807,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* but also in mail addresses and subjects which will display on multiple
* lines but where it doesn't make sense to insert newlines.
*/
- protected boolean shouldAdvanceFocusOnEnter() {
+ private boolean advanceFocusOnEnter() {
if (mInput == null) {
return false;
}
@@ -4013,37 +3828,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return false;
}
- private boolean isInterestingEnter(KeyEvent event) {
- if ((event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 &&
- mInputContentType != null &&
- (mInputContentType.imeOptions &
- EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
- // If this enter key came from a soft keyboard, and the
- // text editor has been configured to not do a default
- // action for software enter keys, then we aren't interested.
- return false;
- }
- return true;
- }
-
private int doKeyDown(int keyCode, KeyEvent event, KeyEvent otherEvent) {
if (!isEnabled()) {
return 0;
}
switch (keyCode) {
- case KeyEvent.KEYCODE_ENTER:
- if (!isInterestingEnter(event)) {
- // Ignore enter key we aren't interested in.
- return -1;
- }
- if (mInputContentType != null
- && mInputContentType.onEditorActionListener != null) {
- mInputContentType.enterDown = true;
- }
- // fall through...
case KeyEvent.KEYCODE_DPAD_CENTER:
- if (shouldAdvanceFocusOnEnter()) {
+ case KeyEvent.KEYCODE_ENTER:
+ if (advanceFocusOnEnter()) {
return 0;
}
}
@@ -4146,17 +3939,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return super.onKeyUp(keyCode, event);
case KeyEvent.KEYCODE_ENTER:
- if (mInputContentType != null
- && mInputContentType.onEditorActionListener != null
- && mInputContentType.enterDown) {
- mInputContentType.enterDown = false;
- if (mInputContentType.onEditorActionListener.onEditorAction(
- this, EditorInfo.IME_UNDEFINED, event)) {
- return true;
- }
- }
-
- if (shouldAdvanceFocusOnEnter()) {
+ if (advanceFocusOnEnter()) {
/*
* If there is a click listener, just call through to
* super, which will invoke it.
@@ -4211,26 +3994,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mInputMethodState = new InputMethodState();
}
outAttrs.inputType = mInputType;
+ outAttrs.hintText = mHint;
if (mInputContentType != null) {
- outAttrs.imeOptions = mInputContentType.imeOptions;
- outAttrs.privateImeOptions = mInputContentType.privateImeOptions;
- outAttrs.actionLabel = mInputContentType.imeActionLabel;
- outAttrs.actionId = mInputContentType.imeActionId;
+ outAttrs.privateContentType = mInputContentType.privateContentType;
outAttrs.extras = mInputContentType.extras;
- } else {
- outAttrs.imeOptions = EditorInfo.IME_UNDEFINED;
- }
- if (outAttrs.imeOptions == EditorInfo.IME_UNDEFINED) {
- if (focusSearch(FOCUS_DOWN) != null) {
- // An action has not been set, but the enter key will move to
- // the next focus, so set the action to that.
- outAttrs.imeOptions = EditorInfo.IME_ACTION_NEXT;
- if (!shouldAdvanceFocusOnEnter()) {
- outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_ENTER_ACTION;
- }
- }
}
- outAttrs.hintText = mHint;
if (mText instanceof Editable) {
InputConnection ic = new EditableInputConnection(this);
outAttrs.initialSelStart = Selection.getSelectionStart(mText);
@@ -6019,9 +5787,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
// Don't leave us in the middle of a batch edit.
onEndBatchEdit();
- if (mInputContentType != null) {
- mInputContentType.enterDown = false;
- }
}
startStopMarquee(hasWindowFocus);
@@ -6115,7 +5880,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mScroller = s;
}
- private static class Blink extends Handler implements Runnable {
+ private static class Blink extends Handler
+ implements Runnable {
private WeakReference<TextView> mView;
private boolean mCancelled;
@@ -6373,44 +6139,23 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
int start = end;
+ char c;
int len = mText.length();
- for (; start > 0; start--) {
- char c = mTransformed.charAt(start - 1);
- int type = Character.getType(c);
-
- if (c != '\'' &&
- type != Character.UPPERCASE_LETTER &&
- type != Character.LOWERCASE_LETTER &&
- type != Character.TITLECASE_LETTER &&
- type != Character.MODIFIER_LETTER &&
- type != Character.DECIMAL_DIGIT_NUMBER) {
- break;
- }
+ while (start > 0 && (((c = mTransformed.charAt(start - 1)) == '\'') ||
+ (Character.isLetterOrDigit(c)))) {
+ start--;
}
- for (; end < len; end++) {
- char c = mTransformed.charAt(end);
- int type = Character.getType(c);
-
- if (c != '\'' &&
- type != Character.UPPERCASE_LETTER &&
- type != Character.LOWERCASE_LETTER &&
- type != Character.TITLECASE_LETTER &&
- type != Character.MODIFIER_LETTER &&
- type != Character.DECIMAL_DIGIT_NUMBER) {
- break;
- }
+ while (end < len && (((c = mTransformed.charAt(end)) == '\'') ||
+ (Character.isLetterOrDigit(c)))) {
+ end++;
}
if (start == end) {
return null;
}
- if (end - start > 48) {
- return null;
- }
-
return TextUtils.substring(mTransformed, start, end);
}
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
deleted file mode 100644
index ec45e23..0000000
--- a/core/java/android/widget/ZoomButtonsController.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.widget;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.WindowManager;
-import android.view.View.OnClickListener;
-import android.view.WindowManager.LayoutParams;
-
-// TODO: make sure no px values exist, only dip (scale if necessary from Viewconfiguration)
-
-/**
- * TODO: Docs
- *
- * If you are using this with a custom View, please call
- * {@link #setVisible(boolean) setVisible(false)} from the
- * {@link View#onDetachedFromWindow}.
- *
- * @hide
- */
-public class ZoomButtonsController implements View.OnTouchListener {
-
- private static final String TAG = "ZoomButtonsController";
-
- private static final int ZOOM_CONTROLS_TIMEOUT =
- (int) ViewConfiguration.getZoomControlsTimeout();
-
- // TODO: scaled to density
- private static final int ZOOM_CONTROLS_TOUCH_PADDING = 20;
-
- private Context mContext;
- private WindowManager mWindowManager;
-
- /**
- * The view that is being zoomed by this zoom ring.
- */
- private View mOwnerView;
-
- /**
- * The bounds of the owner view in global coordinates. This is recalculated
- * each time the zoom ring is shown.
- */
- private Rect mOwnerViewBounds = new Rect();
-
- /**
- * The container that is added as a window.
- */
- private FrameLayout mContainer;
- private LayoutParams mContainerLayoutParams;
- private int[] mContainerLocation = new int[2];
-
- private ZoomControls mControls;
-
- /**
- * The view (or null) that should receive touch events. This will get set if
- * the touch down hits the container. It will be reset on the touch up.
- */
- private View mTouchTargetView;
- /**
- * The {@link #mTouchTargetView}'s location in window, set on touch down.
- */
- private int[] mTouchTargetLocationInWindow = new int[2];
- /**
- * If the zoom ring is dismissed but the user is still in a touch
- * interaction, we set this to true. This will ignore all touch events until
- * up/cancel, and then set the owner's touch listener to null.
- */
- private boolean mReleaseTouchListenerOnUp;
-
- private boolean mIsVisible;
-
- private Rect mTempRect = new Rect();
-
- private OnZoomListener mCallback;
-
- /**
- * When showing the zoom, we add the view as a new window. However, there is
- * logic that needs to know the size of the zoom which is determined after
- * it's laid out. Therefore, we must post this logic onto the UI thread so
- * it will be exceuted AFTER the layout. This is the logic.
- */
- private Runnable mPostedVisibleInitializer;
-
- private IntentFilter mConfigurationChangedFilter =
- new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
-
- private BroadcastReceiver mConfigurationChangedReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!mIsVisible) return;
-
- mHandler.removeMessages(MSG_POST_CONFIGURATION_CHANGED);
- mHandler.sendEmptyMessage(MSG_POST_CONFIGURATION_CHANGED);
- }
- };
-
- /** When configuration changes, this is called after the UI thread is idle. */
- private static final int MSG_POST_CONFIGURATION_CHANGED = 2;
- /** Used to delay the zoom ring dismissal. */
- private static final int MSG_DISMISS_ZOOM_RING = 3;
- /**
- * If setVisible(true) is called and the owner view's window token is null,
- * we delay the setVisible(true) call until it is not null.
- */
- private static final int MSG_POST_SET_VISIBLE = 4;
-
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_POST_CONFIGURATION_CHANGED:
- onPostConfigurationChanged();
- break;
-
- case MSG_DISMISS_ZOOM_RING:
- setVisible(false);
- break;
-
- case MSG_POST_SET_VISIBLE:
- if (mOwnerView.getWindowToken() == null) {
- // Doh, it is still null, throw an exception
- throw new IllegalArgumentException(
- "Cannot make the zoom ring visible if the owner view is " +
- "not attached to a window.");
- }
- setVisible(true);
- break;
- }
-
- }
- };
-
- public ZoomButtonsController(Context context, View ownerView) {
- mContext = context;
- mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- mOwnerView = ownerView;
-
- mContainer = createContainer();
- }
-
- private FrameLayout createContainer() {
- LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
- lp.gravity = Gravity.BOTTOM | Gravity.CENTER;
- lp.flags = LayoutParams.FLAG_NOT_TOUCHABLE |
- LayoutParams.FLAG_LAYOUT_NO_LIMITS;
- lp.height = LayoutParams.WRAP_CONTENT;
- lp.width = LayoutParams.FILL_PARENT;
- lp.type = LayoutParams.TYPE_APPLICATION_PANEL;
- lp.format = PixelFormat.TRANSPARENT;
- // TODO: make a new animation for this
- lp.windowAnimations = com.android.internal.R.style.Animation_InputMethodFancy;
- mContainerLayoutParams = lp;
-
- FrameLayout container = new FrameLayout(mContext);
- container.setLayoutParams(lp);
- container.setMeasureAllChildren(true);
-
- LayoutInflater inflater = (LayoutInflater) mContext
- .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(com.android.internal.R.layout.zoom_magnify, container);
-
- mControls = (ZoomControls) container.findViewById(com.android.internal.R.id.zoomControls);
- mControls.setOnZoomInClickListener(new OnClickListener() {
- public void onClick(View v) {
- dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
- if (mCallback != null) mCallback.onZoom(true);
- }
- });
- mControls.setOnZoomOutClickListener(new OnClickListener() {
- public void onClick(View v) {
- dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
- if (mCallback != null) mCallback.onZoom(false);
- }
- });
-
- View overview = container.findViewById(com.android.internal.R.id.zoomMagnify);
- overview.setVisibility(View.GONE);
- overview.setOnClickListener(new OnClickListener() {
- public void onClick(View v) {
- dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
- if (mCallback != null) mCallback.onOverview();
- }
- });
-
- return container;
- }
-
- public void setCallback(OnZoomListener callback) {
- mCallback = callback;
- }
-
- public void setFocusable(boolean focusable) {
- if (focusable) {
- mContainerLayoutParams.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
- } else {
- mContainerLayoutParams.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
- }
-
- if (mIsVisible) {
- mWindowManager.updateViewLayout(mContainer, mContainerLayoutParams);
- }
- }
-
- public void setOverviewVisible(boolean visible) {
- mContainer.findViewById(com.android.internal.R.id.zoomMagnify)
- .setVisibility(visible ? View.VISIBLE : View.GONE);
- }
-
- public boolean isVisible() {
- return mIsVisible;
- }
-
- public void setVisible(boolean visible) {
-
- if (!useThisZoom(mContext)) return;
-
- if (visible) {
- if (mOwnerView.getWindowToken() == null) {
- /*
- * We need a window token to show ourselves, maybe the owner's
- * window hasn't been created yet but it will have been by the
- * time the looper is idle, so post the setVisible(true) call.
- */
- if (!mHandler.hasMessages(MSG_POST_SET_VISIBLE)) {
- mHandler.sendEmptyMessage(MSG_POST_SET_VISIBLE);
- }
- return;
- }
-
- dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
- }
-
- if (mIsVisible == visible) {
- return;
- }
- mIsVisible = visible;
-
- if (visible) {
- if (mContainerLayoutParams.token == null) {
- mContainerLayoutParams.token = mOwnerView.getWindowToken();
- }
-
- mWindowManager.addView(mContainer, mContainerLayoutParams);
-
- if (mPostedVisibleInitializer == null) {
- mPostedVisibleInitializer = new Runnable() {
- public void run() {
- refreshPositioningVariables();
-
- if (mCallback != null) {
- mCallback.onVisibilityChanged(true);
- }
- }
- };
- }
-
- mHandler.post(mPostedVisibleInitializer);
-
- // Handle configuration changes when visible
- mContext.registerReceiver(mConfigurationChangedReceiver, mConfigurationChangedFilter);
-
- // Steal touches events from the owner
- mOwnerView.setOnTouchListener(this);
- mReleaseTouchListenerOnUp = false;
-
- } else {
- // Don't want to steal any more touches
- if (mTouchTargetView != null) {
- // We are still stealing the touch events for this touch
- // sequence, so release the touch listener later
- mReleaseTouchListenerOnUp = true;
- } else {
- mOwnerView.setOnTouchListener(null);
- }
-
- // No longer care about configuration changes
- mContext.unregisterReceiver(mConfigurationChangedReceiver);
-
- mWindowManager.removeView(mContainer);
- mHandler.removeCallbacks(mPostedVisibleInitializer);
-
- if (mCallback != null) {
- mCallback.onVisibilityChanged(false);
- }
- }
-
- }
-
- /**
- * TODO: docs
- *
- * Notes:
- * - Please ensure you set your View to INVISIBLE not GONE when hiding it.
- *
- * @return TODO
- */
- public FrameLayout getContainer() {
- return mContainer;
- }
-
- public int getZoomRingId() {
- return mControls.getId();
- }
-
- private void dismissControlsDelayed(int delay) {
- mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
- mHandler.sendEmptyMessageDelayed(MSG_DISMISS_ZOOM_RING, delay);
- }
-
- /**
- * Should be called by the client for each event belonging to the second tap
- * (the down, move, up, and cancel events).
- *
- * @param event The event belonging to the second tap.
- * @return Whether the event was consumed.
- */
- public boolean handleDoubleTapEvent(MotionEvent event) {
- if (!useThisZoom(mContext)) return false;
-
- int action = event.getAction();
-
- if (action == MotionEvent.ACTION_DOWN) {
- int x = (int) event.getX();
- int y = (int) event.getY();
-
- setVisible(true);
- centerPoint(x, y);
- }
-
- return true;
- }
-
- private void refreshPositioningVariables() {
- // Calculate the owner view's bounds
- mOwnerView.getGlobalVisibleRect(mOwnerViewBounds);
- mContainer.getLocationOnScreen(mContainerLocation);
- }
-
- /**
- * Centers the point (in owner view's coordinates).
- */
- private void centerPoint(int x, int y) {
- if (mCallback != null) {
- mCallback.onCenter(x, y);
- }
- }
-
- public boolean onTouch(View v, MotionEvent event) {
- int action = event.getAction();
-
- if (mReleaseTouchListenerOnUp) {
- // The ring was dismissed but we need to throw away all events until the up
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- mOwnerView.setOnTouchListener(null);
- setTouchTargetView(null);
- mReleaseTouchListenerOnUp = false;
- }
-
- // Eat this event
- return true;
- }
-
- // TODO: optimize this (it ends up removing message and queuing another)
- dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
-
- View targetView = mTouchTargetView;
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- targetView = getViewForTouch((int) event.getRawX(), (int) event.getRawY());
- setTouchTargetView(targetView);
- break;
-
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- setTouchTargetView(null);
- break;
- }
-
- if (targetView != null) {
- // The upperleft corner of the target view in raw coordinates
- int targetViewRawX = mContainerLocation[0] + mTouchTargetLocationInWindow[0];
- int targetViewRawY = mContainerLocation[1] + mTouchTargetLocationInWindow[1];
-
- MotionEvent containerEvent = MotionEvent.obtain(event);
- // Convert the motion event into the target view's coordinates (from
- // owner view's coordinates)
- containerEvent.offsetLocation(mOwnerViewBounds.left - targetViewRawX,
- mOwnerViewBounds.top - targetViewRawY);
- boolean retValue = targetView.dispatchTouchEvent(containerEvent);
- containerEvent.recycle();
- return retValue;
-
- } else {
- return false;
- }
- }
-
- private void setTouchTargetView(View view) {
- mTouchTargetView = view;
- if (view != null) {
- view.getLocationInWindow(mTouchTargetLocationInWindow);
- }
- }
-
- /**
- * Returns the View that should receive a touch at the given coordinates.
- *
- * @param rawX The raw X.
- * @param rawY The raw Y.
- * @return The view that should receive the touches, or null if there is not one.
- */
- private View getViewForTouch(int rawX, int rawY) {
- // Reverse order so the child drawn on top gets first dibs.
- int containerCoordsX = rawX - mContainerLocation[0];
- int containerCoordsY = rawY - mContainerLocation[1];
- Rect frame = mTempRect;
- for (int i = mContainer.getChildCount() - 1; i >= 0; i--) {
- View child = mContainer.getChildAt(i);
- if (child.getVisibility() != View.VISIBLE) {
- continue;
- }
-
- child.getHitRect(frame);
- // Expand the touch region
- frame.top -= ZOOM_CONTROLS_TOUCH_PADDING;
- if (frame.contains(containerCoordsX, containerCoordsY)) {
- return child;
- }
- }
-
- return null;
- }
-
- private void onPostConfigurationChanged() {
- dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
- refreshPositioningVariables();
- }
-
- public static boolean useThisZoom(Context context) {
- return ZoomRingController.getZoomType(context) == 2;
- }
-
- public interface OnZoomListener {
- void onCenter(int x, int y);
- void onVisibilityChanged(boolean visible);
- void onZoom(boolean zoomIn);
- void onOverview();
- }
-}
diff --git a/core/java/android/widget/ZoomRing.java b/core/java/android/widget/ZoomRing.java
index a5a867b..a29e1a0 100644
--- a/core/java/android/widget/ZoomRing.java
+++ b/core/java/android/widget/ZoomRing.java
@@ -77,7 +77,7 @@ public class ZoomRing extends View {
private int mPreviousWidgetDragX;
private int mPreviousWidgetDragY;
- private boolean mThumbVisible = true;
+ private boolean mDrawThumb = true;
private Drawable mThumbDrawable;
/** Shown beneath the thumb if we can still zoom in. */
@@ -91,13 +91,6 @@ public class ZoomRing extends View {
private static final int THUMB_ARROWS_FADE_DURATION = 300;
private long mThumbArrowsFadeStartTime;
private int mThumbArrowsAlpha = 255;
-
- private static final int THUMB_PLUS_MINUS_DISTANCE = 69;
- private static final int THUMB_PLUS_MINUS_OFFSET_ANGLE = TWO_PI_INT_MULTIPLIED / 11;
- /** Drawn (without rotation) on top of the arrow. */
- private Drawable mThumbPlusDrawable;
- /** Drawn (without rotation) on top of the arrow. */
- private Drawable mThumbMinusDrawable;
private static final int MODE_IDLE = 0;
@@ -106,7 +99,7 @@ public class ZoomRing extends View {
* are waiting for him to move the slop amount before considering him in the
* drag thumb state.
*/
- private static final int MODE_WAITING_FOR_DRAG_THUMB_AFTER_JUMP = 5;
+ private static final int MODE_WAITING_FOR_DRAG_THUMB = 5;
private static final int MODE_DRAG_THUMB = 1;
/**
* User has his finger down, but we are waiting for him to pass the touch
@@ -116,14 +109,11 @@ public class ZoomRing extends View {
private static final int MODE_WAITING_FOR_MOVE_ZOOM_RING = 4;
private static final int MODE_MOVE_ZOOM_RING = 2;
private static final int MODE_TAP_DRAG = 3;
- /** Ignore the touch interaction until the user touches the thumb again. */
- private static final int MODE_IGNORE_UNTIL_TOUCHES_THUMB = 6;
+ /** Ignore the touch interaction. Reset to MODE_IDLE after up/cancel. */
+ private static final int MODE_IGNORE_UNTIL_UP = 6;
private int mMode;
-
- /** Records the last mode the user was in. */
- private int mPreviousMode;
-
- private long mPreviousCenterUpTime;
+
+ private long mPreviousUpTime;
private int mPreviousDownX;
private int mPreviousDownY;
@@ -132,9 +122,7 @@ public class ZoomRing extends View {
private OnZoomRingCallback mCallback;
private int mPreviousCallbackAngle;
private int mCallbackThreshold = Integer.MAX_VALUE;
- /** If the user drags to within __% of a tick, snap to that tick. */
- private int mFuzzyCallbackThreshold = Integer.MAX_VALUE;
-
+
private boolean mResetThumbAutomatically = true;
private int mThumbDragStartAngle;
@@ -145,8 +133,6 @@ public class ZoomRing extends View {
private Scroller mThumbScroller;
- private boolean mVibration = true;
-
private static final int MSG_THUMB_SCROLLER_TICK = 1;
private static final int MSG_THUMB_ARROWS_FADE_TICK = 2;
private Handler mHandler = new Handler() {
@@ -177,8 +163,6 @@ public class ZoomRing extends View {
mutate();
mThumbMinusArrowDrawable = res.getDrawable(R.drawable.zoom_ring_thumb_minus_arrow_rotatable).
mutate();
- mThumbPlusDrawable = res.getDrawable(R.drawable.zoom_ring_thumb_plus);
- mThumbMinusDrawable = res.getDrawable(R.drawable.zoom_ring_thumb_minus);
if (DRAW_TRAIL) {
mTrail = res.getDrawable(R.drawable.zoom_ring_trail).mutate();
}
@@ -191,7 +175,7 @@ public class ZoomRing extends View {
mThumbHalfHeight = mThumbDrawable.getIntrinsicHeight() / 2;
mThumbHalfWidth = mThumbDrawable.getIntrinsicWidth() / 2;
- setCallbackThreshold(PI_INT_MULTIPLIED / 6);
+ mCallbackThreshold = PI_INT_MULTIPLIED / 6;
}
public ZoomRing(Context context, AttributeSet attrs) {
@@ -209,20 +193,8 @@ public class ZoomRing extends View {
// TODO: rename
public void setCallbackThreshold(int callbackThreshold) {
mCallbackThreshold = callbackThreshold;
- mFuzzyCallbackThreshold = (int) (callbackThreshold * 0.65f);
}
- public void setVibration(boolean vibrate) {
- mVibration = vibrate;
- }
-
- public void setThumbVisible(boolean thumbVisible) {
- if (mThumbVisible != thumbVisible) {
- mThumbVisible = thumbVisible;
- invalidate();
- }
- }
-
// TODO: from XML too
public void setRingBounds(int innerRadius, int outerRadius) {
mBoundInnerRadiusSquared = innerRadius * innerRadius;
@@ -334,7 +306,15 @@ public class ZoomRing extends View {
public void setThumbAngleAnimated(int angle, int duration) {
// The angle when going from the current angle to the new angle
int deltaAngle = getDelta(mThumbAngle, angle);
- setThumbAngleAnimated(angle, duration, deltaAngle > 0);
+ // Counter clockwise if the new angle is more the current angle
+ boolean counterClockwise = deltaAngle > 0;
+
+ if (deltaAngle > PI_INT_MULTIPLIED || deltaAngle < -PI_INT_MULTIPLIED) {
+ // It's quicker to go the other direction
+ counterClockwise = !counterClockwise;
+ }
+
+ setThumbAngleAnimated(angle, duration, counterClockwise);
}
public void setThumbAngleAnimated(int angle, int duration, boolean counterClockwise) {
@@ -374,10 +354,14 @@ public class ZoomRing extends View {
return mThumbScroller.getCurrX() % TWO_PI_INT_MULTIPLIED;
}
+ public void resetThumbAngle(int angle) {
+ mPreviousCallbackAngle = angle;
+ setThumbAngleInt(angle);
+ }
+
public void resetThumbAngle() {
if (mResetThumbAutomatically) {
- mPreviousCallbackAngle = 0;
- setThumbAngleInt(0);
+ resetThumbAngle(0);
}
}
@@ -410,119 +394,101 @@ public class ZoomRing extends View {
mTrail.setBounds(0, 0, right - left, bottom - top);
}
- // These drawables are the same size as the track
mThumbPlusArrowDrawable.setBounds(0, 0, right - left, bottom - top);
mThumbMinusArrowDrawable.setBounds(0, 0, right - left, bottom - top);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
-// Log.d(TAG, "History size: " + event.getHistorySize());
-
return handleTouch(event.getAction(), event.getEventTime(),
(int) event.getX(), (int) event.getY(), (int) event.getRawX(),
(int) event.getRawY());
}
- private void resetToIdle() {
- setMode(MODE_IDLE);
+ private void resetState() {
+ mMode = MODE_IDLE;
mPreviousWidgetDragX = mPreviousWidgetDragY = Integer.MIN_VALUE;
mAcculumalatedTrailAngle = 0.0;
}
public void setTapDragMode(boolean tapDragMode, int x, int y) {
- resetToIdle();
+ resetState();
+ mMode = tapDragMode ? MODE_TAP_DRAG : MODE_IDLE;
+
if (tapDragMode) {
- setMode(MODE_TAP_DRAG);
- mCallback.onUserInteractionStarted();
onThumbDragStarted(getAngle(x - mCenterX, y - mCenterY));
- } else {
- onTouchUp(SystemClock.elapsedRealtime(), true);
}
}
public boolean handleTouch(int action, long time, int x, int y, int rawX, int rawY) {
- // local{X,Y} will be where the center of the widget is (0,0)
- int localX = x - mCenterX;
- int localY = y - mCenterY;
-
- /*
- * If we are not drawing the thumb, there is no way for the user to be
- * touching the thumb. Also, if this is the case, assume they are not
- * touching the ring (so the user cannot absolute set the thumb, and
- * there will be a larger touch region for going into the move-ring
- * mode).
- */
- boolean isTouchingThumb = mThumbVisible;
- boolean isTouchingRing = mThumbVisible;
-
- int touchAngle = getAngle(localX, localY);
-// printAngle("touchAngle", touchAngle);
-// printAngle("mThumbAngle", mThumbAngle);
-// printAngle("mPreviousCallbackAngle", mPreviousCallbackAngle);
-// Log.d(TAG, "");
-
-
- int radiusSquared = localX * localX + localY * localY;
- if (radiusSquared < mBoundInnerRadiusSquared ||
- radiusSquared > mBoundOuterRadiusSquared) {
- // Out-of-bounds
- isTouchingThumb = false;
- isTouchingRing = false;
- }
-
- if (isTouchingThumb) {
- int deltaThumbAndTouch = getDelta(mThumbAngle, touchAngle);
- int absoluteDeltaThumbAndTouch = deltaThumbAndTouch >= 0 ?
- deltaThumbAndTouch : -deltaThumbAndTouch;
- if (absoluteDeltaThumbAndTouch > THUMB_GRAB_SLOP) {
- // Didn't grab close enough to the thumb
- isTouchingThumb = false;
- }
- }
-
switch (action) {
+
case MotionEvent.ACTION_DOWN:
- if (!isTouchingRing &&
- (time - mPreviousCenterUpTime <= DOUBLE_TAP_DISMISS_TIMEOUT)) {
- // Make sure the double-tap is in the center of the widget (and not on the ring)
+ if (time - mPreviousUpTime <= DOUBLE_TAP_DISMISS_TIMEOUT) {
mCallback.onZoomRingDismissed(true);
- onTouchUp(time, isTouchingRing);
+ onTouchUp(time);
// Dismissing, so halt here
return true;
}
- resetToIdle();
mCallback.onUserInteractionStarted();
mPreviousDownX = x;
mPreviousDownY = y;
+ resetState();
// Fall through to code below switch (since the down is used for
// jumping to the touched tick)
break;
case MotionEvent.ACTION_MOVE:
+ if (mMode == MODE_IGNORE_UNTIL_UP) return true;
+
// Fall through to code below switch
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
- onTouchUp(time, isTouchingRing);
+ onTouchUp(time);
return true;
default:
return false;
}
+ // local{X,Y} will be where the center of the widget is (0,0)
+ int localX = x - mCenterX;
+ int localY = y - mCenterY;
+ boolean isTouchingThumb = true;
+ boolean isInRingBounds = true;
+
+ int touchAngle = getAngle(localX, localY);
+ int radiusSquared = localX * localX + localY * localY;
+ if (radiusSquared < mBoundInnerRadiusSquared ||
+ radiusSquared > mBoundOuterRadiusSquared) {
+ // Out-of-bounds
+ isTouchingThumb = false;
+ isInRingBounds = false;
+ }
+
+ int deltaThumbAndTouch = getDelta(mThumbAngle, touchAngle);
+ int absoluteDeltaThumbAndTouch = deltaThumbAndTouch >= 0 ?
+ deltaThumbAndTouch : -deltaThumbAndTouch;
+ if (isTouchingThumb &&
+ absoluteDeltaThumbAndTouch > THUMB_GRAB_SLOP) {
+ // Didn't grab close enough to the thumb
+ isTouchingThumb = false;
+ }
+
if (mMode == MODE_IDLE) {
if (isTouchingThumb) {
// They grabbed the thumb
- setMode(MODE_DRAG_THUMB);
+ mMode = MODE_DRAG_THUMB;
onThumbDragStarted(touchAngle);
- } else if (isTouchingRing) {
+ } else if (isInRingBounds) {
// They tapped somewhere else on the ring
int tickAngle = getClosestTickAngle(touchAngle);
+
int deltaThumbAndTick = getDelta(mThumbAngle, tickAngle);
int boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick);
@@ -531,12 +497,12 @@ public class ZoomRing extends View {
if (deltaThumbAndTick > MAX_ABS_JUMP_DELTA_ANGLE ||
deltaThumbAndTick < -MAX_ABS_JUMP_DELTA_ANGLE) {
// Trying to jump too far, ignore this touch interaction
- setMode(MODE_IGNORE_UNTIL_TOUCHES_THUMB);
+ mMode = MODE_IGNORE_UNTIL_UP;
return true;
}
+ // Make sure we only let them jump within bounds
if (boundAngle != Integer.MIN_VALUE) {
- // Cap the user's jump to the bound
tickAngle = boundAngle;
}
} else {
@@ -549,59 +515,47 @@ public class ZoomRing extends View {
deltaThumbAndTick = getDelta(mThumbAngle, tickAngle, !oldDirectionIsCcw);
boundAngle = getBoundIfExceeds(mThumbAngle, deltaThumbAndTick);
if (boundAngle != Integer.MIN_VALUE) {
- // Cannot get to the tapped location because it is out-of-bounds
- setMode(MODE_IGNORE_UNTIL_TOUCHES_THUMB);
+ // Not allowed to be here, it is between two bounds
+ mMode = MODE_IGNORE_UNTIL_UP;
return true;
}
}
}
- setMode(MODE_WAITING_FOR_DRAG_THUMB_AFTER_JUMP);
+ mMode = MODE_WAITING_FOR_DRAG_THUMB;
mWaitingForDragThumbDownAngle = touchAngle;
boolean ccw = deltaThumbAndTick > 0;
setThumbAngleAnimated(tickAngle, 0, ccw);
- /*
- * Our thumb scrolling animation takes us from mThumbAngle to
- * tickAngle, so manifest that as the user dragging the thumb
- * there.
- */
+ // Our thumb scrolling animation takes us from mThumbAngle to tickAngle
onThumbDragStarted(mThumbAngle);
- // We know which direction we want to go
onThumbDragged(tickAngle, true, ccw);
} else {
- // They tapped somewhere else on the widget
- setMode(MODE_WAITING_FOR_MOVE_ZOOM_RING);
+ // They tapped somewhere else
+ mMode = MODE_WAITING_FOR_MOVE_ZOOM_RING;
mCallback.onZoomRingSetMovableHintVisible(true);
}
- } else if (mMode == MODE_WAITING_FOR_DRAG_THUMB_AFTER_JUMP) {
+ } else if (mMode == MODE_WAITING_FOR_DRAG_THUMB) {
int deltaDownAngle = getDelta(mWaitingForDragThumbDownAngle, touchAngle);
if ((deltaDownAngle < -THUMB_DRAG_SLOP || deltaDownAngle > THUMB_DRAG_SLOP) &&
isDeltaInBounds(mWaitingForDragThumbDownAngle, deltaDownAngle)) {
- setMode(MODE_DRAG_THUMB);
-
- // No need to call onThumbDragStarted, since that was done when they tapped-to-jump
+ mMode = MODE_DRAG_THUMB;
}
} else if (mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
if (Math.abs(x - mPreviousDownX) > mTouchSlop ||
Math.abs(y - mPreviousDownY) > mTouchSlop) {
/* Make sure the user has moved the slop amount before going into that mode. */
- setMode(MODE_MOVE_ZOOM_RING);
+ mMode = MODE_MOVE_ZOOM_RING;
mCallback.onZoomRingMovingStarted();
}
- } else if (mMode == MODE_IGNORE_UNTIL_TOUCHES_THUMB) {
- if (isTouchingThumb) {
- // The user is back on the thumb, let's go back to the previous mode
- setMode(mPreviousMode);
- }
}
// Purposefully not an "else if"
if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) {
- if (isTouchingRing) {
+ if (isInRingBounds) {
onThumbDragged(touchAngle, false, false);
}
} else if (mMode == MODE_MOVE_ZOOM_RING) {
@@ -611,39 +565,24 @@ public class ZoomRing extends View {
return true;
}
- private void onTouchUp(long time, boolean isTouchingRing) {
- int mode = mMode;
- if (mode == MODE_IGNORE_UNTIL_TOUCHES_THUMB) {
- // For cleaning up, pretend like the user was still in the previous mode
- mode = mPreviousMode;
- }
-
- if (mode == MODE_MOVE_ZOOM_RING || mode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
+ private void onTouchUp(long time) {
+ if (mMode == MODE_MOVE_ZOOM_RING || mMode == MODE_WAITING_FOR_MOVE_ZOOM_RING) {
mCallback.onZoomRingSetMovableHintVisible(false);
- if (mode == MODE_MOVE_ZOOM_RING) {
+ if (mMode == MODE_MOVE_ZOOM_RING) {
mCallback.onZoomRingMovingStopped();
}
- } else if (mode == MODE_DRAG_THUMB || mode == MODE_TAP_DRAG ||
- mode == MODE_WAITING_FOR_DRAG_THUMB_AFTER_JUMP) {
+ } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG ||
+ mMode == MODE_WAITING_FOR_DRAG_THUMB) {
onThumbDragStopped();
- if (mode == MODE_DRAG_THUMB || mode == MODE_TAP_DRAG) {
+ if (mMode == MODE_DRAG_THUMB) {
// Animate back to a tick
setThumbAngleAnimated(mPreviousCallbackAngle, 0);
}
}
+
+ mPreviousUpTime = time;
mCallback.onUserInteractionStopped();
-
- if (!isTouchingRing) {
- mPreviousCenterUpTime = time;
- }
- }
-
- private void setMode(int mode) {
- if (mode != mMode) {
- mPreviousMode = mMode;
- mMode = mode;
- }
}
private boolean isDeltaInBounds(int startAngle, int deltaAngle) {
@@ -742,8 +681,9 @@ public class ZoomRing extends View {
int totalDeltaAngle;
totalDeltaAngle = getDelta(mPreviousCallbackAngle, touchAngle, useDirection, ccw);
- if (totalDeltaAngle >= mFuzzyCallbackThreshold
- || totalDeltaAngle <= -mFuzzyCallbackThreshold) {
+ int fuzzyCallbackThreshold = (int) (mCallbackThreshold * 0.65f);
+ if (totalDeltaAngle >= fuzzyCallbackThreshold
+ || totalDeltaAngle <= -fuzzyCallbackThreshold) {
if (!useDirection) {
// Set ccw to match the direction found by getDelta
@@ -797,7 +737,7 @@ public class ZoomRing extends View {
// We bounded the touch angle
totalDeltaAngle = getDelta(mPreviousCallbackAngle, touchAngle, useDirection, ccw);
animateThumbToNewAngle = true;
- setMode(MODE_IGNORE_UNTIL_TOUCHES_THUMB);
+ mMode = MODE_IGNORE_UNTIL_UP;
}
@@ -824,13 +764,11 @@ public class ZoomRing extends View {
boolean canStillZoom = mCallback.onZoomRingThumbDragged(
deltaLevels, mThumbDragStartAngle, touchAngle);
- if (mVibration) {
- // TODO: we're trying the haptics to see how it goes with
- // users, so we're ignoring the settings (for now)
- performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK,
- HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING |
- HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
- }
+ // TODO: we're trying the haptics to see how it goes with
+ // users, so we're ignoring the settings (for now)
+ performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK,
+ HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING |
+ HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
// Set the callback angle to the actual angle based on how many delta levels we gave
mPreviousCallbackAngle = getValidAngle(
@@ -853,134 +791,6 @@ public class ZoomRing extends View {
setThumbAngleAuto(touchAngle, useDirection, ccw);
}
}
-// private void onThumbDragged(int touchAngle, boolean useDirection, boolean ccw) {
-// int deltaPrevCbAndTouch = getDelta(mPreviousCallbackAngle, touchAngle, useDirection, ccw);
-//
-// if (!useDirection) {
-// // Set ccw to match the direction found by getDelta
-// ccw = deltaPrevCbAndTouch > 0;
-// useDirection = true;
-// }
-//
-// boolean animateThumbToNewAngle = false;
-// boolean animationCcw = ccw;
-//
-// if (deltaPrevCbAndTouch >= mFuzzyCallbackThreshold
-// || deltaPrevCbAndTouch <= -mFuzzyCallbackThreshold) {
-//
-// /*
-// * When the user slides the thumb through the tick that corresponds
-// * to a zoom bound, we don't want to abruptly stop there. Instead,
-// * let the user slide it to the next tick, and then animate it back
-// * to the original zoom bound tick. Because of this, we make sure
-// * the delta from the bound is more than halfway to the next tick.
-// * We make sure the bound is between the touch and the previous
-// * callback to ensure we JUST passed the bound.
-// */
-// int oldTouchAngle = touchAngle;
-// if (ccw && mThumbCcwBound != Integer.MIN_VALUE) {
-// int deltaCcwBoundAndTouch =
-// getDelta(mThumbCcwBound, touchAngle, true, ccw);
-// if (deltaCcwBoundAndTouch >= mCallbackThreshold / 2) {
-// // The touch has past far enough from the bound
-// int deltaPreviousCbAndTouch = getDelta(mPreviousCallbackAngle,
-// touchAngle, true, ccw);
-// if (deltaPreviousCbAndTouch >= deltaCcwBoundAndTouch) {
-// // The bound is between the previous callback angle and the touch
-// // Cap to the bound
-// touchAngle = mThumbCcwBound;
-// /*
-// * We're moving the touch BACK to the bound, so animate
-// * back in the opposite direction that passed the bound.
-// */
-// animationCcw = false;
-// }
-// }
-// } else if (!ccw && mThumbCwBound != Integer.MIN_VALUE) {
-// // See block above for general comments
-// int deltaCwBoundAndTouch =
-// getDelta(mThumbCwBound, touchAngle, true, ccw);
-// if (deltaCwBoundAndTouch <= -mCallbackThreshold / 2) {
-// int deltaPreviousCbAndTouch = getDelta(mPreviousCallbackAngle,
-// touchAngle, true, ccw);
-// /*
-// * Both of these will be negative since we got delta in
-// * clockwise direction, and we want the magnitude of
-// * deltaPreviousCbAndTouch to be greater than the magnitude
-// * of deltaCwBoundAndTouch
-// */
-// if (deltaPreviousCbAndTouch <= deltaCwBoundAndTouch) {
-// touchAngle = mThumbCwBound;
-// animationCcw = true;
-// }
-// }
-// }
-// if (touchAngle != oldTouchAngle) {
-// // We bounded the touch angle
-// deltaPrevCbAndTouch = getDelta(mPreviousCallbackAngle, touchAngle, true, ccw);
-// // Animate back to the bound
-// animateThumbToNewAngle = true;
-// // Disallow movement now
-// setMode(MODE_IGNORE_UNTIL_UP);
-// }
-//
-//
-// /*
-// * Prevent it from jumping too far (this could happen if the user
-// * goes through the center)
-// */
-//
-// if (mEnforceMaxAbsJump) {
-// if (deltaPrevCbAndTouch <= -MAX_ABS_JUMP_DELTA_ANGLE) {
-// deltaPrevCbAndTouch = -MAX_ABS_JUMP_DELTA_ANGLE;
-// animateThumbToNewAngle = true;
-// } else if (deltaPrevCbAndTouch >= MAX_ABS_JUMP_DELTA_ANGLE) {
-// deltaPrevCbAndTouch = MAX_ABS_JUMP_DELTA_ANGLE;
-// animateThumbToNewAngle = true;
-// }
-// }
-//
-// /*
-// * We need to cover the edge case of a user grabbing the thumb,
-// * going into the center of the widget, and then coming out from the
-// * center to an angle that's slightly below the angle he's trying to
-// * hit. If we do int division, we'll end up with one level lower
-// * than the one he was going for.
-// */
-// int deltaLevels = Math.round((float) deltaPrevCbAndTouch / mCallbackThreshold);
-// if (deltaLevels != 0) {
-// boolean canStillZoom = mCallback.onZoomRingThumbDragged(
-// deltaLevels, mThumbDragStartAngle, touchAngle);
-//
-// if (mVibration) {
-// // TODO: we're trying the haptics to see how it goes with
-// // users, so we're ignoring the settings (for now)
-// performHapticFeedback(HapticFeedbackConstants.ZOOM_RING_TICK,
-// HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING |
-// HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
-//
-// }
-// // Set the callback angle to the actual angle based on how many delta levels we gave
-// mPreviousCallbackAngle = getValidAngle(
-// mPreviousCallbackAngle + (deltaLevels * mCallbackThreshold));
-// }
-// }
-//
-// if (DRAW_TRAIL) {
-// int deltaAngle = getDelta(mThumbAngle, touchAngle, true, ccw);
-// mAcculumalatedTrailAngle += Math.toDegrees(deltaAngle / (double) RADIAN_INT_MULTIPLIER);
-// }
-//
-// if (animateThumbToNewAngle) {
-// setThumbAngleAnimated(touchAngle, 0, animationCcw);
-// } else {
-// /*
-// * Use regular ccw here because animationCcw will never have been
-// * changed if animateThumbToNewAngle is false
-// */
-// setThumbAngleAuto(touchAngle, true, ccw);
-// }
-// }
private int getValidAngle(int invalidAngle) {
if (invalidAngle < 0) {
@@ -1008,16 +818,16 @@ public class ZoomRing extends View {
mCallback.onZoomRingThumbDraggingStopped();
}
- private void onZoomRingMoved(int rawX, int rawY) {
+ private void onZoomRingMoved(int x, int y) {
if (mPreviousWidgetDragX != Integer.MIN_VALUE) {
- int deltaX = rawX - mPreviousWidgetDragX;
- int deltaY = rawY - mPreviousWidgetDragY;
+ int deltaX = x - mPreviousWidgetDragX;
+ int deltaY = y - mPreviousWidgetDragY;
- mCallback.onZoomRingMoved(deltaX, deltaY, rawX, rawY);
+ mCallback.onZoomRingMoved(deltaX, deltaY);
}
- mPreviousWidgetDragX = rawX;
- mPreviousWidgetDragY = rawY;
+ mPreviousWidgetDragX = x;
+ mPreviousWidgetDragY = y;
}
@Override
@@ -1049,17 +859,15 @@ public class ZoomRing extends View {
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
- if (mThumbVisible) {
+ if (mDrawThumb) {
if (DRAW_TRAIL) {
mTrail.draw(canvas);
}
if ((mThumbArrowsToDraw & THUMB_ARROW_PLUS) != 0) {
mThumbPlusArrowDrawable.draw(canvas);
- mThumbPlusDrawable.draw(canvas);
}
if ((mThumbArrowsToDraw & THUMB_ARROW_MINUS) != 0) {
mThumbMinusArrowDrawable.draw(canvas);
- mThumbMinusDrawable.draw(canvas);
}
mThumbDrawable.draw(canvas);
}
@@ -1069,28 +877,6 @@ public class ZoomRing extends View {
int level = -angle * 10000 / ZoomRing.TWO_PI_INT_MULTIPLIED;
mThumbPlusArrowDrawable.setLevel(level);
mThumbMinusArrowDrawable.setLevel(level);
-
- // Assume it is a square
- int halfSideLength = mThumbPlusDrawable.getIntrinsicHeight() / 2;
- int unoffsetAngle = angle + mZeroAngle;
-
- int plusCenterX = (int) (Math.cos(1f * (unoffsetAngle - THUMB_PLUS_MINUS_OFFSET_ANGLE)
- / RADIAN_INT_MULTIPLIER) * THUMB_PLUS_MINUS_DISTANCE) + mCenterX;
- int plusCenterY = (int) (Math.sin(1f * (unoffsetAngle - THUMB_PLUS_MINUS_OFFSET_ANGLE)
- / RADIAN_INT_MULTIPLIER) * THUMB_PLUS_MINUS_DISTANCE) * -1 + mCenterY;
- mThumbPlusDrawable.setBounds(plusCenterX - halfSideLength,
- plusCenterY - halfSideLength,
- plusCenterX + halfSideLength,
- plusCenterY + halfSideLength);
-
- int minusCenterX = (int) (Math.cos(1f * (unoffsetAngle + THUMB_PLUS_MINUS_OFFSET_ANGLE)
- / RADIAN_INT_MULTIPLIER) * THUMB_PLUS_MINUS_DISTANCE) + mCenterX;
- int minusCenterY = (int) (Math.sin(1f * (unoffsetAngle + THUMB_PLUS_MINUS_OFFSET_ANGLE)
- / RADIAN_INT_MULTIPLIER) * THUMB_PLUS_MINUS_DISTANCE) * -1 + mCenterY;
- mThumbMinusDrawable.setBounds(minusCenterX - halfSideLength,
- minusCenterY - halfSideLength,
- minusCenterX + halfSideLength,
- minusCenterY + halfSideLength);
}
public void setThumbArrowsVisible(boolean visible) {
@@ -1100,7 +886,6 @@ public class ZoomRing extends View {
if (callbackAngle < mThumbCwBound - RADIAN_INT_ERROR ||
callbackAngle > mThumbCwBound + RADIAN_INT_ERROR) {
mThumbPlusArrowDrawable.setAlpha(255);
- mThumbPlusDrawable.setAlpha(255);
mThumbArrowsToDraw |= THUMB_ARROW_PLUS;
} else {
mThumbArrowsToDraw &= ~THUMB_ARROW_PLUS;
@@ -1108,7 +893,6 @@ public class ZoomRing extends View {
if (callbackAngle < mThumbCcwBound - RADIAN_INT_ERROR ||
callbackAngle > mThumbCcwBound + RADIAN_INT_ERROR) {
mThumbMinusArrowDrawable.setAlpha(255);
- mThumbMinusDrawable.setAlpha(255);
mThumbArrowsToDraw |= THUMB_ARROW_MINUS;
} else {
mThumbArrowsToDraw &= ~THUMB_ARROW_MINUS;
@@ -1133,14 +917,10 @@ public class ZoomRing extends View {
if (mThumbArrowsAlpha < 0) mThumbArrowsAlpha = 0;
if ((mThumbArrowsToDraw & THUMB_ARROW_PLUS) != 0) {
mThumbPlusArrowDrawable.setAlpha(mThumbArrowsAlpha);
- mThumbPlusDrawable.setAlpha(mThumbArrowsAlpha);
- invalidateDrawable(mThumbPlusDrawable);
invalidateDrawable(mThumbPlusArrowDrawable);
}
if ((mThumbArrowsToDraw & THUMB_ARROW_MINUS) != 0) {
mThumbMinusArrowDrawable.setAlpha(mThumbArrowsAlpha);
- mThumbMinusDrawable.setAlpha(mThumbArrowsAlpha);
- invalidateDrawable(mThumbMinusDrawable);
invalidateDrawable(mThumbMinusArrowDrawable);
}
@@ -1161,7 +941,7 @@ public class ZoomRing extends View {
void onZoomRingSetMovableHintVisible(boolean visible);
void onZoomRingMovingStarted();
- boolean onZoomRingMoved(int deltaX, int deltaY, int rawX, int rawY);
+ boolean onZoomRingMoved(int deltaX, int deltaY);
void onZoomRingMovingStopped();
void onZoomRingThumbDraggingStarted();
diff --git a/core/java/android/widget/ZoomRingController.java b/core/java/android/widget/ZoomRingController.java
index 19f66a0..2e97fda 100644
--- a/core/java/android/widget/ZoomRingController.java
+++ b/core/java/android/widget/ZoomRingController.java
@@ -33,7 +33,6 @@ import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
-import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -48,36 +47,30 @@ import android.view.animation.DecelerateInterpolator;
/**
* TODO: Docs
- *
+ *
* If you are using this with a custom View, please call
* {@link #setVisible(boolean) setVisible(false)} from the
* {@link View#onDetachedFromWindow}.
- *
+ *
* @hide
*/
public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
View.OnTouchListener, View.OnKeyListener {
-
+
private static final int ZOOM_RING_RADIUS_INSET = 24;
private static final int ZOOM_RING_RECENTERING_DURATION = 500;
private static final String TAG = "ZoomRing";
- public static final boolean USE_OLD_ZOOM = false;
- static int getZoomType(Context context) {
- return Settings.System.getInt(context.getContentResolver(), "zoom", 1);
- }
+ public static final boolean USE_OLD_ZOOM = false;
public static boolean useOldZoom(Context context) {
- return getZoomType(context) == 0;
+ return Settings.System.getInt(context.getContentResolver(), "zoom", 1) == 0;
}
- private static boolean useThisZoom(Context context) {
- return getZoomType(context) == 1;
- }
-
+
private static final int ZOOM_CONTROLS_TIMEOUT =
(int) ViewConfiguration.getZoomControlsTimeout();
-
+
// TODO: move these to ViewConfiguration or re-use existing ones
// TODO: scale px values based on latest from ViewConfiguration
private static final int SECOND_TAP_TIMEOUT = 500;
@@ -87,12 +80,12 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private static final int MAX_INITIATE_PAN_GAP = 10;
// TODO view config
private static final int INITIATE_PAN_DELAY = 300;
-
+
private static final String SETTING_NAME_SHOWN_TOAST = "shown_zoom_ring_toast";
-
+
private Context mContext;
private WindowManager mWindowManager;
-
+
/**
* The view that is being zoomed by this zoom ring.
*/
@@ -118,15 +111,15 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
/**
* The {@link #mTouchTargetView}'s location in window, set on touch down.
*/
- private int[] mTouchTargetLocationInWindow = new int[2];
+ private int[] mTouchTargetLocationInWindow = new int[2];
/**
* If the zoom ring is dismissed but the user is still in a touch
* interaction, we set this to true. This will ignore all touch events until
* up/cancel, and then set the owner's touch listener to null.
*/
private boolean mReleaseTouchListenerOnUp;
-
-
+
+
/*
* Tap-drag is an interaction where the user first taps and then (quickly)
* does the clockwise or counter-clockwise drag. In reality, this is: (down,
@@ -139,40 +132,30 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
*/
private int mTapDragStartX;
private int mTapDragStartY;
-
+
private static final int TOUCH_MODE_IDLE = 0;
private static final int TOUCH_MODE_WAITING_FOR_SECOND_TAP = 1;
private static final int TOUCH_MODE_WAITING_FOR_TAP_DRAG_MOVEMENT = 2;
private static final int TOUCH_MODE_FORWARDING_FOR_TAP_DRAG = 3;
private int mTouchMode;
-
+
private boolean mIsZoomRingVisible;
-
+
private ZoomRing mZoomRing;
private int mZoomRingWidth;
private int mZoomRingHeight;
-
+
/** Invokes panning of owner view if the zoom ring is touching an edge. */
private Panner mPanner;
private long mTouchingEdgeStartTime;
private boolean mPanningEnabledForThisInteraction;
-
- /**
- * When the finger moves the zoom ring to an edge, this is the horizontal
- * accumulator for how much the finger has moved off of its original touch
- * point on the zoom ring (OOB = out-of-bounds). If < 0, the finger has
- * moved that many px to the left of its original touch point on the ring.
- */
- private int mMovingZoomRingOobX;
- /** Vertical accumulator, see {@link #mMovingZoomRingOobX} */
- private int mMovingZoomRingOobY;
-
+
private ImageView mPanningArrows;
private Animation mPanningArrowsEnterAnimation;
private Animation mPanningArrowsExitAnimation;
-
+
private Rect mTempRect = new Rect();
-
+
private OnZoomListener mCallback;
private ViewConfiguration mViewConfig;
@@ -188,7 +171,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
* for the container's layout params.
*/
private int mCenteredContainerY = Integer.MIN_VALUE;
-
+
/**
* Scroller used to re-center the zoom ring if the user had dragged it to a
* corner and then double-taps any point on the owner view (the owner view
@@ -198,7 +181,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
* The (x,y) of the scroller is the (x,y) of the container's layout params.
*/
private Scroller mScroller;
-
+
/**
* When showing the zoom ring, we add the view as a new window. However,
* there is logic that needs to know the size of the zoom ring which is
@@ -206,7 +189,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
* the UI thread so it will be exceuted AFTER the layout. This is the logic.
*/
private Runnable mPostedVisibleInitializer;
-
+
/**
* Only touch from the main thread.
*/
@@ -216,29 +199,23 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private IntentFilter mConfigurationChangedFilter =
new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
-
+
private BroadcastReceiver mConfigurationChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!mIsZoomRingVisible) return;
-
+
mHandler.removeMessages(MSG_POST_CONFIGURATION_CHANGED);
mHandler.sendEmptyMessage(MSG_POST_CONFIGURATION_CHANGED);
}
};
-
+
/** Keeps the scroller going (or starts it). */
private static final int MSG_SCROLLER_TICK = 1;
/** When configuration changes, this is called after the UI thread is idle. */
private static final int MSG_POST_CONFIGURATION_CHANGED = 2;
/** Used to delay the zoom ring dismissal. */
private static final int MSG_DISMISS_ZOOM_RING = 3;
-
- /**
- * If setVisible(true) is called and the owner view's window token is null,
- * we delay the setVisible(true) call until it is not null.
- */
- private static final int MSG_POST_SET_VISIBLE = 4;
private Handler mHandler = new Handler() {
@Override
@@ -247,36 +224,26 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
case MSG_SCROLLER_TICK:
onScrollerTick();
break;
-
+
case MSG_POST_CONFIGURATION_CHANGED:
onPostConfigurationChanged();
break;
-
+
case MSG_DISMISS_ZOOM_RING:
setVisible(false);
break;
-
- case MSG_POST_SET_VISIBLE:
- if (mOwnerView.getWindowToken() == null) {
- // Doh, it is still null, throw an exception
- throw new IllegalArgumentException(
- "Cannot make the zoom ring visible if the owner view is " +
- "not attached to a window.");
- }
- setVisible(true);
- break;
}
-
- }
+
+ }
};
-
+
public ZoomRingController(Context context, View ownerView) {
mContext = context;
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mPanner = new Panner();
mOwnerView = ownerView;
-
+
mZoomRing = new ZoomRing(context);
mZoomRing.setId(com.android.internal.R.id.zoomControls);
mZoomRing.setLayoutParams(new FrameLayout.LayoutParams(
@@ -284,7 +251,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER));
mZoomRing.setCallback(this);
-
+
createPanningArrows();
mContainerLayoutParams = new LayoutParams();
@@ -302,12 +269,12 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mContainer = new FrameLayout(context);
mContainer.setLayoutParams(mContainerLayoutParams);
mContainer.setMeasureAllChildren(true);
-
+
mContainer.addView(mZoomRing);
mContainer.addView(mPanningArrows);
-
+
mScroller = new Scroller(context, new DecelerateInterpolator());
-
+
mViewConfig = ViewConfiguration.get(context);
}
@@ -320,7 +287,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER));
mPanningArrows.setVisibility(View.INVISIBLE);
-
+
mPanningArrowsEnterAnimation = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.fade_in);
mPanningArrowsExitAnimation = AnimationUtils.loadAnimation(mContext,
@@ -332,7 +299,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
* get a callback. Once there is a callback, the accumulator resets. For
* example, if you set this to PI/6, it will give a callback every time the
* user moves PI/6 amount on the ring.
- *
+ *
* @param callbackThreshold The angle for the callback threshold, in radians
*/
public void setZoomCallbackThreshold(float callbackThreshold) {
@@ -341,7 +308,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
/**
* Sets a drawable for the zoom ring track.
- *
+ *
* @param drawable The drawable to use for the track.
* @hide Need a better way of doing this, but this one-off for browser so it
* can have its final look for the usability study
@@ -349,11 +316,11 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void setZoomRingTrack(int drawable) {
mZoomRing.setBackgroundResource(drawable);
}
-
+
public void setCallback(OnZoomListener callback) {
mCallback = callback;
}
-
+
public void setThumbAngle(float angle) {
mZoomRing.setThumbAngle((int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER));
}
@@ -361,21 +328,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void setThumbAngleAnimated(float angle) {
mZoomRing.setThumbAngleAnimated((int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER), 0);
}
-
+
public void setResetThumbAutomatically(boolean resetThumbAutomatically) {
mZoomRing.setResetThumbAutomatically(resetThumbAutomatically);
}
-
- public void setVibration(boolean vibrate) {
- mZoomRing.setVibration(vibrate);
- }
-
- public void setThumbVisible(boolean thumbVisible) {
- mZoomRing.setThumbVisible(thumbVisible);
- }
public void setThumbClockwiseBound(float angle) {
- mZoomRing.setThumbClockwiseBound(angle >= 0 ?
+ mZoomRing.setThumbClockwiseBound(angle >= 0 ?
(int) (angle * ZoomRing.RADIAN_INT_MULTIPLIER) :
Integer.MIN_VALUE);
}
@@ -392,26 +351,14 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void setVisible(boolean visible) {
- if (!useThisZoom(mContext)) return;
+ if (useOldZoom(mContext)) return;
if (visible) {
- if (mOwnerView.getWindowToken() == null) {
- /*
- * We need a window token to show ourselves, maybe the owner's
- * window hasn't been created yet but it will have been by the
- * time the looper is idle, so post the setVisible(true) call.
- */
- if (!mHandler.hasMessages(MSG_POST_SET_VISIBLE)) {
- mHandler.sendEmptyMessage(MSG_POST_SET_VISIBLE);
- }
- return;
- }
-
dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT);
} else {
mPanner.stop();
}
-
+
if (mIsZoomRingVisible == visible) {
return;
}
@@ -421,40 +368,40 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
if (mContainerLayoutParams.token == null) {
mContainerLayoutParams.token = mOwnerView.getWindowToken();
}
-
+
mWindowManager.addView(mContainer, mContainerLayoutParams);
-
+
if (mPostedVisibleInitializer == null) {
mPostedVisibleInitializer = new Runnable() {
public void run() {
refreshPositioningVariables();
resetZoomRing();
-
+
// TODO: remove this 'update' and just center zoom ring before the
// 'add', but need to make sure we have the width and height (which
// probably can only be retrieved after it's measured, which happens
// after it's added).
mWindowManager.updateViewLayout(mContainer, mContainerLayoutParams);
-
+
if (mCallback != null) {
mCallback.onVisibilityChanged(true);
}
}
- };
+ };
}
-
+
mPanningArrows.setAnimation(null);
-
+
mHandler.post(mPostedVisibleInitializer);
-
+
// Handle configuration changes when visible
mContext.registerReceiver(mConfigurationChangedReceiver, mConfigurationChangedFilter);
-
+
// Steal key/touches events from the owner
mOwnerView.setOnKeyListener(this);
mOwnerView.setOnTouchListener(this);
mReleaseTouchListenerOnUp = false;
-
+
} else {
// Don't want to steal any more keys/touches
mOwnerView.setOnKeyListener(null);
@@ -468,45 +415,45 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
// No longer care about configuration changes
mContext.unregisterReceiver(mConfigurationChangedReceiver);
-
+
mWindowManager.removeView(mContainer);
mHandler.removeCallbacks(mPostedVisibleInitializer);
-
+
if (mCallback != null) {
mCallback.onVisibilityChanged(false);
}
}
-
+
}
-
+
/**
* TODO: docs
- *
+ *
* Notes:
* - Touch dispatching is different. Only direct children who are clickable are eligble for touch events.
* - Please ensure you set your View to INVISIBLE not GONE when hiding it.
- *
+ *
* @return
*/
public FrameLayout getContainer() {
return mContainer;
}
-
+
public int getZoomRingId() {
return mZoomRing.getId();
}
-
+
private void dismissZoomRingDelayed(int delay) {
mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
mHandler.sendEmptyMessageDelayed(MSG_DISMISS_ZOOM_RING, delay);
}
-
+
private void resetZoomRing() {
mScroller.abortAnimation();
-
+
mContainerLayoutParams.x = mCenteredContainerX;
mContainerLayoutParams.y = mCenteredContainerY;
-
+
// Reset the thumb
mZoomRing.resetThumbAngle();
}
@@ -514,15 +461,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
/**
* Should be called by the client for each event belonging to the second tap
* (the down, move, up, and cancel events).
- *
+ *
* @param event The event belonging to the second tap.
* @return Whether the event was consumed.
*/
public boolean handleDoubleTapEvent(MotionEvent event) {
- if (!useThisZoom(mContext)) return false;
-
int action = event.getAction();
-
+
// TODO: make sure this works well with the
// ownerView.setOnTouchListener(this) instead of window receiving
// touches
@@ -530,19 +475,19 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mTouchMode = TOUCH_MODE_WAITING_FOR_TAP_DRAG_MOVEMENT;
int x = (int) event.getX();
int y = (int) event.getY();
-
+
refreshPositioningVariables();
setVisible(true);
centerPoint(x, y);
- ensureZoomRingIsCentered();
-
+ ensureZoomRingIsCentered();
+
// Tap drag mode stuff
mTapDragStartX = x;
mTapDragStartY = y;
} else if (action == MotionEvent.ACTION_CANCEL) {
mTouchMode = TOUCH_MODE_IDLE;
-
+
} else { // action is move or up
switch (mTouchMode) {
case TOUCH_MODE_WAITING_FOR_TAP_DRAG_MOVEMENT: {
@@ -558,29 +503,29 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
setTouchTargetView(mZoomRing);
}
return true;
-
+
case MotionEvent.ACTION_UP:
mTouchMode = TOUCH_MODE_IDLE;
break;
}
break;
}
-
+
case TOUCH_MODE_FORWARDING_FOR_TAP_DRAG: {
switch (action) {
case MotionEvent.ACTION_MOVE:
giveTouchToZoomRing(event);
return true;
-
+
case MotionEvent.ACTION_UP:
mTouchMode = TOUCH_MODE_IDLE;
-
+
/*
* This is a power-user feature that only shows the
* zoom while the user is performing the tap-drag.
* That means once it is released, the zoom ring
* should disappear.
- */
+ */
mZoomRing.setTapDragMode(false, (int) event.getX(), (int) event.getY());
dismissZoomRingDelayed(0);
break;
@@ -589,13 +534,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
}
}
-
+
return true;
}
-
+
private void ensureZoomRingIsCentered() {
LayoutParams lp = mContainerLayoutParams;
-
+
if (lp.x != mCenteredContainerX || lp.y != mCenteredContainerY) {
int width = mContainer.getWidth();
int height = mContainer.getHeight();
@@ -604,21 +549,21 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mHandler.sendEmptyMessage(MSG_SCROLLER_TICK);
}
}
-
+
private void refreshPositioningVariables() {
mZoomRingWidth = mZoomRing.getWidth();
mZoomRingHeight = mZoomRing.getHeight();
-
+
// Calculate the owner view's bounds
mOwnerView.getGlobalVisibleRect(mOwnerViewBounds);
-
+
// Get the center
Gravity.apply(Gravity.CENTER, mContainer.getWidth(), mContainer.getHeight(),
mOwnerViewBounds, mTempRect);
mCenteredContainerX = mTempRect.left;
mCenteredContainerY = mTempRect.top;
}
-
+
/**
* Centers the point (in owner view's coordinates).
*/
@@ -627,7 +572,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mCallback.onCenter(x, y);
}
}
-
+
private void giveTouchToZoomRing(MotionEvent event) {
int rawX = (int) event.getRawX();
int rawY = (int) event.getRawY();
@@ -635,11 +580,11 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
int y = rawY - mContainerLayoutParams.y - mZoomRing.getTop();
mZoomRing.handleTouch(event.getAction(), event.getEventTime(), x, y, rawX, rawY);
}
-
+
public void onZoomRingSetMovableHintVisible(boolean visible) {
- setPanningArrowsVisible(visible);
+ setPanningArrowsVisible(visible);
}
-
+
public void onUserInteractionStarted() {
mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
}
@@ -651,62 +596,24 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void onZoomRingMovingStarted() {
mScroller.abortAnimation();
mTouchingEdgeStartTime = 0;
- mMovingZoomRingOobX = 0;
- mMovingZoomRingOobY = 0;
if (mCallback != null) {
mCallback.onBeginPan();
}
}
-
+
private void setPanningArrowsVisible(boolean visible) {
mPanningArrows.startAnimation(visible ? mPanningArrowsEnterAnimation
: mPanningArrowsExitAnimation);
mPanningArrows.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
}
-
- public boolean onZoomRingMoved(int deltaX, int deltaY, int rawX, int rawY) {
-
- if (mMovingZoomRingOobX != 0) {
- /*
- * The finger has moved off the point where it originally touched
- * the zidget.
- */
- boolean wasOobLeft = mMovingZoomRingOobX < 0;
- mMovingZoomRingOobX += deltaX;
- if ((wasOobLeft && mMovingZoomRingOobX > 0) ||
- (!wasOobLeft && mMovingZoomRingOobX < 0)) {
- /*
- * Woot, the finger is back on the original point. Infact, it
- * went PAST its original point, so take the amount it passed
- * and use that as the delta to move the zoom ring.
- */
- deltaX = mMovingZoomRingOobX;
- // No longer out-of-bounds, reset
- mMovingZoomRingOobX = 0;
- } else {
- // The finger is still not back, eat this movement
- deltaX = 0;
- }
- }
-
- if (mMovingZoomRingOobY != 0) {
- // See above for comments
- boolean wasOobUp = mMovingZoomRingOobY < 0;
- mMovingZoomRingOobY += deltaY;
- if ((wasOobUp && mMovingZoomRingOobY > 0) || (!wasOobUp && mMovingZoomRingOobY < 0)) {
- deltaY = mMovingZoomRingOobY;
- mMovingZoomRingOobY = 0;
- } else {
- deltaY = 0;
- }
- }
-
+
+ public boolean onZoomRingMoved(int deltaX, int deltaY) {
WindowManager.LayoutParams lp = mContainerLayoutParams;
Rect ownerBounds = mOwnerViewBounds;
-
+
int zoomRingLeft = mZoomRing.getLeft();
int zoomRingTop = mZoomRing.getTop();
-
+
int newX = lp.x + deltaX;
int newZoomRingX = newX + zoomRingLeft;
newZoomRingX = (newZoomRingX <= ownerBounds.left) ? ownerBounds.left :
@@ -720,26 +627,19 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
(newZoomRingY + mZoomRingHeight > ownerBounds.bottom) ?
ownerBounds.bottom - mZoomRingHeight : newZoomRingY;
lp.y = newZoomRingY - zoomRingTop;
-
+
mWindowManager.updateViewLayout(mContainer, lp);
-
+
// Check for pan
boolean horizontalPanning = true;
int leftGap = newZoomRingX - ownerBounds.left;
if (leftGap < MAX_PAN_GAP) {
- if (leftGap == 0 && deltaX != 0 && mMovingZoomRingOobX == 0) {
- // Future moves in this direction should be accumulated in mMovingZoomRingOobX
- mMovingZoomRingOobX = deltaX / Math.abs(deltaX);
- }
if (shouldPan(leftGap)) {
mPanner.setHorizontalStrength(-getStrengthFromGap(leftGap));
}
} else {
int rightGap = ownerBounds.right - (lp.x + mZoomRingWidth + zoomRingLeft);
if (rightGap < MAX_PAN_GAP) {
- if (rightGap == 0 && deltaX != 0 && mMovingZoomRingOobX == 0) {
- mMovingZoomRingOobX = deltaX / Math.abs(deltaX);
- }
if (shouldPan(rightGap)) {
mPanner.setHorizontalStrength(getStrengthFromGap(rightGap));
}
@@ -748,21 +648,15 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
horizontalPanning = false;
}
}
-
+
int topGap = newZoomRingY - ownerBounds.top;
if (topGap < MAX_PAN_GAP) {
- if (topGap == 0 && deltaY != 0 && mMovingZoomRingOobY == 0) {
- mMovingZoomRingOobY = deltaY / Math.abs(deltaY);
- }
if (shouldPan(topGap)) {
mPanner.setVerticalStrength(-getStrengthFromGap(topGap));
}
} else {
int bottomGap = ownerBounds.bottom - (lp.y + mZoomRingHeight + zoomRingTop);
if (bottomGap < MAX_PAN_GAP) {
- if (bottomGap == 0 && deltaY != 0 && mMovingZoomRingOobY == 0) {
- mMovingZoomRingOobY = deltaY / Math.abs(deltaY);
- }
if (shouldPan(bottomGap)) {
mPanner.setVerticalStrength(getStrengthFromGap(bottomGap));
}
@@ -776,13 +670,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
}
}
-
+
return true;
}
-
+
private boolean shouldPan(int gap) {
if (mPanningEnabledForThisInteraction) return true;
-
+
if (gap < MAX_INITIATE_PAN_GAP) {
long time = SystemClock.elapsedRealtime();
if (mTouchingEdgeStartTime != 0 &&
@@ -799,7 +693,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
}
return false;
}
-
+
public void onZoomRingMovingStopped() {
mPanner.stop();
setPanningArrowsVisible(false);
@@ -807,18 +701,18 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mCallback.onEndPan();
}
}
-
+
private int getStrengthFromGap(int gap) {
return gap > MAX_PAN_GAP ? 0 :
(MAX_PAN_GAP - gap) * 100 / MAX_PAN_GAP;
}
-
+
public void onZoomRingThumbDraggingStarted() {
if (mCallback != null) {
mCallback.onBeginDrag();
}
}
-
+
public boolean onZoomRingThumbDragged(int numLevels, int startAngle, int curAngle) {
if (mCallback != null) {
int deltaZoomLevel = -numLevels;
@@ -826,17 +720,17 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mZoomRingWidth / 2;
int globalZoomCenterY = mContainerLayoutParams.y + mZoomRing.getTop() +
mZoomRingHeight / 2;
-
+
return mCallback.onDragZoom(deltaZoomLevel,
globalZoomCenterX - mOwnerViewBounds.left,
globalZoomCenterY - mOwnerViewBounds.top,
(float) startAngle / ZoomRing.RADIAN_INT_MULTIPLIER,
(float) curAngle / ZoomRing.RADIAN_INT_MULTIPLIER);
}
-
+
return false;
}
-
+
public void onZoomRingThumbDraggingStopped() {
if (mCallback != null) {
mCallback.onEndDrag();
@@ -846,35 +740,35 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void onZoomRingDismissed(boolean dismissImmediately) {
if (dismissImmediately) {
mHandler.removeMessages(MSG_DISMISS_ZOOM_RING);
- setVisible(false);
+ setVisible(false);
} else {
dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY);
}
}
-
+
public void onRingDown(int tickAngle, int touchAngle) {
}
-
+
public boolean onTouch(View v, MotionEvent event) {
if (sTutorialDialog != null && sTutorialDialog.isShowing() &&
SystemClock.elapsedRealtime() - sTutorialShowTime >= TUTORIAL_MIN_DISPLAY_TIME) {
finishZoomTutorial();
}
-
+
int action = event.getAction();
if (mReleaseTouchListenerOnUp) {
- // The ring was dismissed but we need to throw away all events until the up
+ // The ring was dismissed but we need to throw away all events until the up
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
mOwnerView.setOnTouchListener(null);
setTouchTargetView(null);
mReleaseTouchListenerOnUp = false;
}
-
+
// Eat this event
return true;
}
-
+
View targetView = mTouchTargetView;
switch (action) {
@@ -882,7 +776,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
targetView = getViewForTouch((int) event.getRawX(), (int) event.getRawY());
setTouchTargetView(targetView);
break;
-
+
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
setTouchTargetView(null);
@@ -893,7 +787,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
// The upperleft corner of the target view in raw coordinates
int targetViewRawX = mContainerLayoutParams.x + mTouchTargetLocationInWindow[0];
int targetViewRawY = mContainerLayoutParams.y + mTouchTargetLocationInWindow[1];
-
+
MotionEvent containerEvent = MotionEvent.obtain(event);
// Convert the motion event into the target view's coordinates (from
// owner view's coordinates)
@@ -902,32 +796,32 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
boolean retValue = targetView.dispatchTouchEvent(containerEvent);
containerEvent.recycle();
return retValue;
-
+
} else {
if (action == MotionEvent.ACTION_DOWN) {
dismissZoomRingDelayed(ZOOM_RING_DISMISS_DELAY);
}
-
+
return false;
}
}
-
+
private void setTouchTargetView(View view) {
mTouchTargetView = view;
if (view != null) {
view.getLocationInWindow(mTouchTargetLocationInWindow);
}
}
-
+
/**
* Returns the View that should receive a touch at the given coordinates.
- *
+ *
* @param rawX The raw X.
* @param rawY The raw Y.
* @return The view that should receive the touches, or null if there is not one.
*/
private View getViewForTouch(int rawX, int rawY) {
- // Check to see if it is touching the ring
+ // Check to see if it is touching the ring
int containerCenterX = mContainerLayoutParams.x + mContainer.getWidth() / 2;
int containerCenterY = mContainerLayoutParams.y + mContainer.getHeight() / 2;
int distanceFromCenterX = rawX - containerCenterX;
@@ -938,7 +832,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
zoomRingRadius * zoomRingRadius) {
return mZoomRing;
}
-
+
// Check to see if it is touching any other clickable View.
// Reverse order so the child drawn on top gets first dibs.
int containerCoordsX = rawX - mContainerLayoutParams.x;
@@ -950,13 +844,13 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
!child.isClickable()) {
continue;
}
-
+
child.getHitRect(frame);
if (frame.contains(containerCoordsX, containerCoordsY)) {
return child;
}
}
-
+
return null;
}
@@ -967,34 +861,34 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
case KeyEvent.KEYCODE_DPAD_RIGHT:
// Eat these
return true;
-
+
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
// Keep the zoom alive a little longer
dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT);
// They started zooming, hide the thumb arrows
mZoomRing.setThumbArrowsVisible(false);
-
+
if (mCallback != null && event.getAction() == KeyEvent.ACTION_DOWN) {
mCallback.onSimpleZoom(keyCode == KeyEvent.KEYCODE_DPAD_UP);
}
-
+
return true;
}
-
+
return false;
}
private void onScrollerTick() {
if (!mScroller.computeScrollOffset() || !mIsZoomRingVisible) return;
-
+
mContainerLayoutParams.x = mScroller.getCurrX();
mContainerLayoutParams.y = mScroller.getCurrY();
mWindowManager.updateViewLayout(mContainer, mContainerLayoutParams);
mHandler.sendEmptyMessage(MSG_SCROLLER_TICK);
}
-
+
private void onPostConfigurationChanged() {
dismissZoomRingDelayed(ZOOM_CONTROLS_TIMEOUT);
refreshPositioningVariables();
@@ -1014,7 +908,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
* before. Furthermore, if the application does not have privilege to write
* to the system settings, it will store this bit locally in a shared
* preference.
- *
+ *
* @hide This should only be used by our main apps--browser, maps, and
* gallery
*/
@@ -1023,65 +917,53 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
if (Settings.System.getInt(cr, SETTING_NAME_SHOWN_TOAST, 0) == 1) {
return;
}
-
+
SharedPreferences sp = context.getSharedPreferences("_zoom", Context.MODE_PRIVATE);
if (sp.getInt(SETTING_NAME_SHOWN_TOAST, 0) == 1) {
return;
}
-
+
if (sTutorialDialog != null && sTutorialDialog.isShowing()) {
sTutorialDialog.dismiss();
}
-
- LayoutInflater layoutInflater =
- (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- TextView textView = (TextView) layoutInflater.inflate(
- com.android.internal.R.layout.alert_dialog_simple_text, null)
- .findViewById(android.R.id.text1);
- textView.setText(com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short);
sTutorialDialog = new AlertDialog.Builder(context)
- .setView(textView)
+ .setMessage(
+ com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short)
.setIcon(0)
.create();
-
+
Window window = sTutorialDialog.getWindow();
window.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
- window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND |
+ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND |
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
-
+
sTutorialDialog.show();
sTutorialShowTime = SystemClock.elapsedRealtime();
}
-
- public static void finishZoomTutorial(Context context, boolean userNotified) {
+
+ public void finishZoomTutorial() {
if (sTutorialDialog == null) return;
-
+
sTutorialDialog.dismiss();
sTutorialDialog = null;
-
+
// Record that they have seen the tutorial
- if (userNotified) {
- try {
- Settings.System.putInt(context.getContentResolver(), SETTING_NAME_SHOWN_TOAST, 1);
- } catch (SecurityException e) {
- /*
- * The app does not have permission to clear this global flag, make
- * sure the user does not see the message when he comes back to this
- * same app at least.
- */
- SharedPreferences sp = context.getSharedPreferences("_zoom", Context.MODE_PRIVATE);
- sp.edit().putInt(SETTING_NAME_SHOWN_TOAST, 1).commit();
- }
+ try {
+ Settings.System.putInt(mContext.getContentResolver(), SETTING_NAME_SHOWN_TOAST, 1);
+ } catch (SecurityException e) {
+ /*
+ * The app does not have permission to clear this global flag, make
+ * sure the user does not see the message when he comes back to this
+ * same app at least.
+ */
+ SharedPreferences sp = mContext.getSharedPreferences("_zoom", Context.MODE_PRIVATE);
+ sp.edit().putInt(SETTING_NAME_SHOWN_TOAST, 1).commit();
}
}
-
- public void finishZoomTutorial() {
- finishZoomTutorial(mContext, true);
- }
-
+
public void setPannerStartVelocity(float startVelocity) {
mPanner.mStartVelocity = startVelocity;
}
@@ -1101,27 +983,27 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
private class Panner implements Runnable {
private static final int RUN_DELAY = 15;
private static final float STOP_SLOWDOWN = 0.8f;
-
+
private final Handler mUiHandler = new Handler();
-
+
private int mVerticalStrength;
private int mHorizontalStrength;
private boolean mStopping;
-
+
/** The time this current pan started. */
private long mStartTime;
-
+
/** The time of the last callback to pan the map/browser/etc. */
private long mPreviousCallbackTime;
-
+
// TODO Adjust to be DPI safe
private float mStartVelocity = 135;
private float mAcceleration = 160;
private float mMaxVelocity = 1000;
private int mStartAcceleratingDuration = 700;
private float mVelocity;
-
+
/** -100 (full left) to 0 (none) to 100 (full right) */
public void setHorizontalStrength(int horizontalStrength) {
if (mHorizontalStrength == 0 && mVerticalStrength == 0 && horizontalStrength != 0) {
@@ -1129,7 +1011,7 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
} else if (mVerticalStrength == 0 && horizontalStrength == 0) {
stop();
}
-
+
mHorizontalStrength = horizontalStrength;
mStopping = false;
}
@@ -1141,11 +1023,11 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
} else if (mHorizontalStrength == 0 && verticalStrength == 0) {
stop();
}
-
- mVerticalStrength = verticalStrength;
+
+ mVerticalStrength = verticalStrength;
mStopping = false;
}
-
+
private void start() {
mUiHandler.post(this);
mPreviousCallbackTime = 0;
@@ -1155,37 +1037,37 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
public void stop() {
mStopping = true;
}
-
+
public void run() {
if (mStopping) {
mHorizontalStrength *= STOP_SLOWDOWN;
mVerticalStrength *= STOP_SLOWDOWN;
}
-
+
if (mHorizontalStrength == 0 && mVerticalStrength == 0) {
return;
}
-
+
boolean firstRun = mPreviousCallbackTime == 0;
long curTime = SystemClock.elapsedRealtime();
int panAmount = getPanAmount(mPreviousCallbackTime, curTime);
mPreviousCallbackTime = curTime;
-
+
if (firstRun) {
mStartTime = curTime;
mVelocity = mStartVelocity;
} else {
int panX = panAmount * mHorizontalStrength / 100;
int panY = panAmount * mVerticalStrength / 100;
-
+
if (mCallback != null) {
mCallback.onPan(panX, panY);
}
}
-
+
mUiHandler.postDelayed(this, RUN_DELAY);
}
-
+
private int getPanAmount(long previousTime, long currentTime) {
if (mVelocity > mMaxVelocity) {
mVelocity = mMaxVelocity;
@@ -1195,12 +1077,14 @@ public class ZoomRingController implements ZoomRing.OnZoomRingCallback,
mVelocity += (currentTime - previousTime) * mAcceleration / 1000;
}
}
-
+
return (int) ((currentTime - previousTime) * mVelocity) / 1000;
}
}
+
+
public interface OnZoomListener {
void onBeginDrag();
boolean onDragZoom(int deltaZoomLevel, int centerX, int centerY, float startAngle,
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index edda1d9..b502a6c 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -28,8 +28,6 @@ interface IBatteryStats {
void noteStopGps(int uid);
void noteScreenOn();
void noteScreenOff();
- void notePhoneOn();
- void notePhoneOff();
void setOnBattery(boolean onBattery);
long getAwakeTimeBattery();
long getAwakeTimePlugged();
diff --git a/core/java/com/android/internal/gadget/IGadgetService.aidl b/core/java/com/android/internal/gadget/IGadgetService.aidl
index 9c66b95..a22f3f3 100644
--- a/core/java/com/android/internal/gadget/IGadgetService.aidl
+++ b/core/java/com/android/internal/gadget/IGadgetService.aidl
@@ -44,7 +44,6 @@ interface IGadgetService {
List<GadgetProviderInfo> getInstalledProviders();
GadgetProviderInfo getGadgetInfo(int gadgetId);
void bindGadgetId(int gadgetId, in ComponentName provider);
- int[] getGadgetIds(in ComponentName provider);
}
diff --git a/core/java/com/android/internal/logging/AndroidConfig.java b/core/java/com/android/internal/logging/AndroidConfig.java
index f8002c6..d8be889 100644
--- a/core/java/com/android/internal/logging/AndroidConfig.java
+++ b/core/java/com/android/internal/logging/AndroidConfig.java
@@ -34,14 +34,11 @@ public class AndroidConfig {
super();
try {
- Logger rootLogger = Logger.getLogger("");
- rootLogger.addHandler(new AndroidHandler());
- rootLogger.setLevel(Level.INFO);
-
- // Turn down logging in Apache libraries.
- Logger.getLogger("org.apache").setLevel(Level.WARNING);
+ Logger.global.addHandler(new AndroidHandler());
+ Logger.global.setLevel(Level.ALL);
} catch (Exception ex) {
ex.printStackTrace();
}
- }
+ }
+
}
diff --git a/core/java/com/android/internal/logging/AndroidHandler.java b/core/java/com/android/internal/logging/AndroidHandler.java
index d9fcf60..a6a4c64 100644
--- a/core/java/com/android/internal/logging/AndroidHandler.java
+++ b/core/java/com/android/internal/logging/AndroidHandler.java
@@ -18,14 +18,14 @@ package com.android.internal.logging;
import android.util.Log;
-import java.util.logging.*;
-import java.util.Date;
-import java.text.MessageFormat;
-import java.io.PrintWriter;
-import java.io.StringWriter;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.SimpleFormatter;
/**
- * Implements a {@link java.util.logging.Logger} handler that writes to the Android log. The
+ * Implements a {@link java.util.Logger} handler that writes to the Android log. The
* implementation is rather straightforward. The name of the logger serves as
* the log tag. Only the log levels need to be converted appropriately. For
* this purpose, the following mapping is being used:
@@ -81,24 +81,8 @@ public class AndroidHandler extends Handler {
/**
* Holds the formatter for all Android log handlers.
*/
- private static final Formatter THE_FORMATTER = new Formatter() {
- @Override
- public String format(LogRecord r) {
- Throwable thrown = r.getThrown();
- if (thrown != null) {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- sw.write(r.getMessage());
- sw.write("\n");
- thrown.printStackTrace(pw);
- pw.flush();
- return sw.toString();
- } else {
- return r.getMessage();
- }
- }
- };
-
+ private static final Formatter THE_FORMATTER = new SimpleFormatter();
+
/**
* Constructs a new instance of the Android log handler.
*/
@@ -122,40 +106,27 @@ public class AndroidHandler extends Handler {
int level = getAndroidLevel(record.getLevel());
String tag = record.getLoggerName();
- if (tag == null) {
- // Anonymous logger.
- tag = "null";
- } else {
- // Tags must be <= 23 characters.
- int length = tag.length();
- if (length > 23) {
- // Most loggers use the full class name. Try dropping the
- // package.
- int lastPeriod = tag.lastIndexOf(".");
- if (length - lastPeriod - 1 <= 23) {
- tag = tag.substring(lastPeriod + 1);
- } else {
- // Use last 23 chars.
- tag = tag.substring(tag.length() - 23);
- }
- }
- }
-
if (!Log.isLoggable(tag, level)) {
return;
}
-
- String message = getFormatter().format(record);
- Log.println(level, tag, message);
+
+ String msg;
+ try {
+ msg = getFormatter().format(record);
+ } catch (RuntimeException e) {
+ Log.e("AndroidHandler", "Error formatting log record", e);
+ msg = record.getMessage();
+ }
+ Log.println(level, tag, msg);
} catch (RuntimeException e) {
- Log.e("AndroidHandler", "Error logging message.", e);
+ Log.e("AndroidHandler", "Error publishing log record", e);
}
}
/**
- * Converts a {@link java.util.logging.Logger} logging level into an Android one.
+ * Converts a {@link java.util.Logger} logging level into an Android one.
*
- * @param level The {@link java.util.logging.Logger} logging level.
+ * @param level The {@link java.util.Logger} logging level.
*
* @return The resulting Android logging level.
*/
diff --git a/core/java/com/android/internal/net/DbSSLSessionCache.java b/core/java/com/android/internal/net/DbSSLSessionCache.java
deleted file mode 100644
index 06e4ca8..0000000
--- a/core/java/com/android/internal/net/DbSSLSessionCache.java
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2009 The Android Open Source Project
-
-package com.android.internal.net;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.SQLException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.util.Log;
-
-import org.apache.commons.codec.binary.Base64;
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.net.ssl.SSLSession;
-
-/**
- * Hook into harmony SSL cache to persist the SSL sessions.
- *
- * Current implementation is suitable for saving a small number of hosts -
- * like google services. It can be extended with expiration and more features
- * to support more hosts.
- *
- * {@hide}
- */
-public class DbSSLSessionCache implements SSLClientSessionCache {
- private static final String TAG = "DbSSLSessionCache";
-
- /**
- * Table where sessions are stored.
- */
- public static final String SSL_CACHE_TABLE = "ssl_sessions";
-
- private static final String SSL_CACHE_ID = "_id";
-
- /**
- * Key is host:port - port is not optional.
- */
- private static final String SSL_CACHE_HOSTPORT = "hostport";
-
- /**
- * Base64-encoded DER value of the session.
- */
- private static final String SSL_CACHE_SESSION = "session";
-
- /**
- * Time when the record was added - should be close to the time
- * of the initial session negotiation.
- */
- private static final String SSL_CACHE_TIME_SEC = "time_sec";
-
- public static final String DATABASE_NAME = "ssl_sessions.db";
-
- public static final int DATABASE_VERSION = 2;
-
- /** public for testing
- */
- public static final int SSL_CACHE_ID_COL = 0;
- public static final int SSL_CACHE_HOSTPORT_COL = 1;
- public static final int SSL_CACHE_SESSION_COL = 2;
- public static final int SSL_CACHE_TIME_SEC_COL = 3;
-
- public static final int MAX_CACHE_SIZE = 256;
-
- private final Map<String, byte[]> mExternalCache =
- new HashMap<String, byte[]>();
-
-
- private DatabaseHelper mDatabaseHelper;
-
- private boolean mNeedsCacheLoad = true;
-
- public static final String[] PROJECTION = new String[] {
- SSL_CACHE_ID,
- SSL_CACHE_HOSTPORT,
- SSL_CACHE_SESSION,
- SSL_CACHE_TIME_SEC
- };
-
- /**
- * Create a SslSessionCache instance, using the specified context to
- * initialize the database.
- *
- * This constructor will use the default database - created for the application
- * context.
- *
- * @param activityContext
- */
- public DbSSLSessionCache(Context activityContext) {
- Context appContext = activityContext.getApplicationContext();
- mDatabaseHelper = new DatabaseHelper(appContext);
- }
-
- /**
- * Create a SslSessionCache that uses a specific database.
- *
- *
- * @param database
- */
- public DbSSLSessionCache(DatabaseHelper database) {
- this.mDatabaseHelper = database;
- }
-
- public void putSessionData(SSLSession session, byte[] der) {
- if (mDatabaseHelper == null) {
- return;
- }
- synchronized (this.getClass()) {
- SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
- if (mExternalCache.size() == MAX_CACHE_SIZE) {
- // remove oldest.
- // TODO: check if the new one is in cached already ( i.e. update ).
- Cursor byTime = mDatabaseHelper.getReadableDatabase().query(SSL_CACHE_TABLE,
- PROJECTION, null, null, null, null, SSL_CACHE_TIME_SEC);
- if (byTime.moveToFirst()) {
- // TODO: can I do byTime.deleteRow() ?
- String hostPort = byTime.getString(SSL_CACHE_HOSTPORT_COL);
- db.delete(SSL_CACHE_TABLE,
- SSL_CACHE_HOSTPORT + "= ?" , new String[] { hostPort });
- mExternalCache.remove(hostPort);
- } else {
- Log.w(TAG, "No rows found");
- // something is wrong, clear it
- clear();
- }
- }
- // Serialize native session to standard DER encoding
- long t0 = System.currentTimeMillis();
-
- String b64 = new String(Base64.encodeBase64(der));
- String key = session.getPeerHost() + ":" + session.getPeerPort();
-
- ContentValues values = new ContentValues();
- values.put(SSL_CACHE_HOSTPORT, key);
- values.put(SSL_CACHE_SESSION, b64);
- values.put(SSL_CACHE_TIME_SEC, System.currentTimeMillis() / 1000);
-
- mExternalCache.put(key, der);
-
- try {
- db.insert(SSL_CACHE_TABLE, null /*nullColumnHack */ , values);
- } catch(SQLException ex) {
- // Ignore - nothing we can do to recover, and caller shouldn't
- // be affected.
- Log.w(TAG, "Ignoring SQL exception when caching session", ex);
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- long t1 = System.currentTimeMillis();
- Log.d(TAG, "New SSL session " + session.getPeerHost() +
- " DER len: " + der.length + " " + (t1 - t0));
- }
- }
-
- }
-
- public byte[] getSessionData(String host, int port) {
- // Current (simple) implementation does a single lookup to DB, then saves
- // all entries to the cache.
-
- // This works for google services - i.e. small number of certs.
- // If we extend this to all processes - we should hold a separate cache
- // or do lookups to DB each time.
- if (mDatabaseHelper == null) {
- return null;
- }
- synchronized(this.getClass()) {
- if (mNeedsCacheLoad) {
- // Don't try to load again, if something is wrong on the first
- // request it'll likely be wrong each time.
- mNeedsCacheLoad = false;
- long t0 = System.currentTimeMillis();
-
- Cursor cur = null;
- try {
- cur = mDatabaseHelper.getReadableDatabase().query(SSL_CACHE_TABLE,
- PROJECTION, null, null, null, null, null);
- if (cur.moveToFirst()) {
- do {
- String hostPort = cur.getString(SSL_CACHE_HOSTPORT_COL);
- String value = cur.getString(SSL_CACHE_SESSION_COL);
-
- if (hostPort == null || value == null) {
- continue;
- }
- // TODO: blob support ?
- byte[] der = Base64.decodeBase64(value.getBytes());
- mExternalCache.put(hostPort, der);
- } while (cur.moveToNext());
-
- }
- } catch (SQLException ex) {
- Log.d(TAG, "Error loading SSL cached entries ", ex);
- } finally {
- if (cur != null) {
- cur.close();
- }
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- long t1 = System.currentTimeMillis();
- Log.d(TAG, "LOADED CACHED SSL " + (t1 - t0) + " ms");
- }
- }
- }
-
- String key = host + ":" + port;
-
- return mExternalCache.get(key);
- }
- }
-
- /**
- * Reset the database and internal state.
- * Used for testing or to free space.
- */
- public void clear() {
- synchronized(this) {
- try {
- mExternalCache.clear();
- mNeedsCacheLoad = true;
- mDatabaseHelper.getWritableDatabase().delete(SSL_CACHE_TABLE,
- null, null);
- } catch (SQLException ex) {
- Log.d(TAG, "Error removing SSL cached entries ", ex);
- // ignore - nothing we can do about it
- }
- }
- }
-
- public byte[] getSessionData(byte[] id) {
- // We support client side only - the cache will do nothing for
- // server-side sessions.
- return null;
- }
-
- /** Visible for testing.
- */
- public static class DatabaseHelper extends SQLiteOpenHelper {
-
- public DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null /* factory */, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE " + SSL_CACHE_TABLE + " (" +
- SSL_CACHE_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
- SSL_CACHE_HOSTPORT + " TEXT UNIQUE ON CONFLICT REPLACE," +
- SSL_CACHE_SESSION + " TEXT," +
- SSL_CACHE_TIME_SEC + " INTEGER" +
- ");");
-
- // No index - we load on startup, index would slow down inserts.
- // If we want to scale this to lots of rows - we could use
- // index, but then we'll hit DB a bit too often ( including
- // negative hits )
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.execSQL("DROP TABLE IF EXISTS " + SSL_CACHE_TABLE );
- onCreate(db);
- }
-
- }
-
-}
diff --git a/core/java/com/android/internal/net/SSLSessionCache.java b/core/java/com/android/internal/net/SSLSessionCache.java
deleted file mode 100644
index ec02fe5..0000000
--- a/core/java/com/android/internal/net/SSLSessionCache.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2009 The Android Open Source Project
-package com.android.internal.net;
-
-import org.apache.harmony.xnet.provider.jsse.SSLClientSessionCache;
-import org.apache.harmony.xnet.provider.jsse.SSLContextImpl;
-
-import java.security.KeyManagementException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManager;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-import android.util.Log;
-
-/**
- * Utility class to configure SSL session caching.
- *
- *
- *
- * {@hide}
- */
-public class SSLSessionCache {
- private static final String TAG = "SSLSessionCache";
-
- private static final String CACHE_TYPE_DB = "db";
-
- private static boolean sInitializationDone = false;
-
- // One per process
- private static DbSSLSessionCache sDbCache;
-
- /**
- * Check settings for ssl session caching.
- *
- * @return false if disabled.
- */
- public static boolean isEnabled(ContentResolver resolver) {
- String sslCache = Settings.Gservices.getString(resolver,
- Settings.Gservices.SSL_SESSION_CACHE);
-
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "enabled " + sslCache);
- }
-
- return CACHE_TYPE_DB.equals(sslCache);
- }
-
- /**
- * Return the configured session cache, or null if not enabled.
- */
- public static SSLClientSessionCache getSessionCache(Context context) {
- if (context == null) {
- return null;
- }
- if (!sInitializationDone) {
- if (isEnabled(context.getContentResolver())) {
- sDbCache = new DbSSLSessionCache(context);
- return sDbCache;
- }
- // Don't check again.
- sInitializationDone = true;
- }
- return sDbCache;
- }
-
- /**
- * Construct the factory, using default constructor if caching is disabled.
- * Refactored here to avoid duplication, used in tests.
- */
- public static SSLSocketFactory getSocketFactory(Context androidContext,
- TrustManager[] trustManager) {
- try {
- if (androidContext != null) {
- SSLClientSessionCache sessionCache = getSessionCache(androidContext);
-
- if (sessionCache != null) {
- SSLContextImpl sslContext = new SSLContextImpl();
- sslContext.engineInit(null /* kms */,
- trustManager, new java.security.SecureRandom(),
- sessionCache, null /* serverCache */);
- return sslContext.engineGetSocketFactory();
- }
- }
- // default
- SSLContext context = SSLContext.getInstance("TLS");
- context.init(null, trustManager, new java.security.SecureRandom());
- return context.getSocketFactory();
-
- } catch (NoSuchAlgorithmException e) {
- throw new AssertionError(e);
- } catch (KeyManagementException e) {
- throw new AssertionError(e);
- }
- }
-
-
-}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 7eea8b7..558a122 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -23,7 +23,6 @@ import android.os.ParcelFormatException;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.Log;
-import android.util.Printer;
import android.util.SparseArray;
import java.io.File;
@@ -40,14 +39,14 @@ import java.util.Map;
* otherwise.
*/
public final class BatteryStatsImpl extends BatteryStats {
+
private static final String TAG = "BatteryStatsImpl";
- private static final boolean DEBUG = false;
// In-memory Parcel magic number, used to detect attempts to unmarshall bad data
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 25;
+ private static final int VERSION = 23;
private final File mFile;
private final File mBackupFile;
@@ -87,11 +86,9 @@ public final class BatteryStatsImpl extends BatteryStats {
long mLastRealtime;
boolean mScreenOn;
- Timer mScreenOnTimer;
-
- boolean mPhoneOn;
- Timer mPhoneOnTimer;
-
+ long mLastScreenOnTimeMillis;
+ long mBatteryScreenOnTimeMillis;
+ long mPluggedScreenOnTimeMillis;
/**
* These provide time bases that discount the time the device is plugged
* in to power.
@@ -135,45 +132,16 @@ public final class BatteryStatsImpl extends BatteryStats {
// Times are in microseconds for better accuracy when dividing by the
// lock count, and are in "battery realtime" units.
- /**
- * The total time we have accumulated since the start of the original
- * boot, to the last time something interesting happened in the
- * current run.
- */
long mTotalTime;
-
- /**
- * The total time we loaded for the previous runs. Subtract this from
- * mTotalTime to find the time for the current run of the system.
- */
- long mLoadedTime;
-
- /**
- * The run time of the last run of the system, as loaded from the
- * saved data.
- */
- long mLastTime;
-
- /**
- * The value of mTotalTime when unplug() was last called. Subtract
- * this from mTotalTime to find the time since the last unplug from
- * power.
- */
- long mUnpluggedTime;
-
- /**
- * The last time at which we updated the timer. If mNesting is > 0,
- * subtract this from the current battery time to find the amount of
- * time we have been running since we last computed an update.
- */
+ long mLoadedTotalTime;
+ long mLastTotalTime;
long mUpdateTime;
/**
- * The total time at which the timer was acquired, to determine if
- * was actually held for an interesting duration.
+ * The value of mTotalTime when unplug() was last called, initially 0.
*/
- long mAcquireTime;
-
+ long mUnpluggedTotalTime;
+
Timer(int type, ArrayList<Timer> timerPool,
ArrayList<Unpluggable> unpluggables, Parcel in) {
mType = type;
@@ -183,10 +151,10 @@ public final class BatteryStatsImpl extends BatteryStats {
mLastCount = in.readInt();
mUnpluggedCount = in.readInt();
mTotalTime = in.readLong();
- mLoadedTime = in.readLong();
- mLastTime = in.readLong();
+ mLoadedTotalTime = in.readLong();
+ mLastTotalTime = in.readLong();
mUpdateTime = in.readLong();
- mUnpluggedTime = in.readLong();
+ mUnpluggedTotalTime = in.readLong();
unpluggables.add(this);
}
@@ -203,41 +171,21 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(mLastCount);
out.writeInt(mUnpluggedCount);
out.writeLong(computeRunTimeLocked(batteryRealtime));
- out.writeLong(mLoadedTime);
- out.writeLong(mLastTime);
+ out.writeLong(mLoadedTotalTime);
+ out.writeLong(mLastTotalTime);
out.writeLong(mUpdateTime);
- out.writeLong(mUnpluggedTime);
+ out.writeLong(mUnpluggedTotalTime);
}
public void unplug(long batteryUptime, long batteryRealtime) {
- if (DEBUG && mType < 0) {
- Log.v(TAG, "unplug #" + mType + ": realtime=" + batteryRealtime
- + " old mUnpluggedTime=" + mUnpluggedTime
- + " old mUnpluggedCount=" + mUnpluggedCount);
- }
- mUnpluggedTime = computeRunTimeLocked(batteryRealtime);
+ mUnpluggedTotalTime = computeRunTimeLocked(batteryRealtime);
mUnpluggedCount = mCount;
- if (DEBUG && mType < 0) {
- Log.v(TAG, "unplug #" + mType
- + ": new mUnpluggedTime=" + mUnpluggedTime
- + " new mUnpluggedCount=" + mUnpluggedCount);
- }
}
public void plug(long batteryUptime, long batteryRealtime) {
if (mNesting > 0) {
- if (DEBUG && mType < 0) {
- Log.v(TAG, "plug #" + mType + ": realtime=" + batteryRealtime
- + " old mTotalTime=" + mTotalTime
- + " old mUpdateTime=" + mUpdateTime);
- }
mTotalTime = computeRunTimeLocked(batteryRealtime);
mUpdateTime = batteryRealtime;
- if (DEBUG && mType < 0) {
- Log.v(TAG, "plug #" + mType
- + ": new mTotalTime=" + mTotalTime
- + " old mUpdateTime=" + mUpdateTime);
- }
}
}
@@ -259,16 +207,16 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
- public long getTotalTime(long batteryRealtime, int which) {
+ public long getTotalTime(long now, int which) {
long val;
if (which == STATS_LAST) {
- val = mLastTime;
+ val = mLastTotalTime;
} else {
- val = computeRunTimeLocked(batteryRealtime);
+ val = computeRunTimeLocked(now);
if (which == STATS_UNPLUGGED) {
- val -= mUnpluggedTime;
+ val -= mUnpluggedTotalTime;
} else if (which != STATS_TOTAL) {
- val -= mLoadedTime;
+ val -= mLoadedTotalTime;
}
}
@@ -297,32 +245,22 @@ public final class BatteryStatsImpl extends BatteryStats {
+ " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
+ " mUnpluggedCount=" + mUnpluggedCount);
Log.i("foo", "mTotalTime=" + mTotalTime
- + " mLoadedTime=" + mLoadedTime);
- Log.i("foo", "mLastTime=" + mLastTime
- + " mUnpluggedTime=" + mUnpluggedTime);
- Log.i("foo", "mUpdateTime=" + mUpdateTime
- + " mAcquireTime=" + mAcquireTime);
+ + " mLoadedTotalTime=" + mLoadedTotalTime);
+ Log.i("foo", "mLastTotalTime=" + mLastTotalTime
+ + " mUpdateTime=" + mUpdateTime);
}
void startRunningLocked(BatteryStatsImpl stats) {
if (mNesting++ == 0) {
mUpdateTime = stats.getBatteryRealtimeLocked(
SystemClock.elapsedRealtime() * 1000);
- if (mTimerPool != null) {
- // Accumulate time to all currently active timers before adding
- // this new one to the pool.
- refreshTimersLocked(stats, mTimerPool);
- // Add this timer to the active pool
- mTimerPool.add(this);
- }
+ // Accumulate time to all currently active timers before adding
+ // this new one to the pool.
+ refreshTimersLocked(stats, mTimerPool);
+ // Add this timer to the active pool
+ mTimerPool.add(this);
// Increment the count
mCount++;
- mAcquireTime = mTotalTime;
- if (DEBUG && mType < 0) {
- Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
- + " mTotalTime=" + mTotalTime + " mCount=" + mCount
- + " mAcquireTime=" + mAcquireTime);
- }
}
}
@@ -332,31 +270,11 @@ public final class BatteryStatsImpl extends BatteryStats {
return;
}
if (--mNesting == 0) {
- if (mTimerPool != null) {
- // Accumulate time to all active counters, scaled by the total
- // active in the pool, before taking this one out of the pool.
- refreshTimersLocked(stats, mTimerPool);
- // Remove this timer from the active pool
- mTimerPool.remove(this);
- } else {
- final long realtime = SystemClock.elapsedRealtime() * 1000;
- final long batteryRealtime = stats.getBatteryRealtimeLocked(realtime);
- mNesting = 1;
- mTotalTime = computeRunTimeLocked(batteryRealtime);
- mNesting = 0;
- }
-
- if (DEBUG && mType < 0) {
- Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
- + " mTotalTime=" + mTotalTime + " mCount=" + mCount
- + " mAcquireTime=" + mAcquireTime);
- }
-
- if (mTotalTime == mAcquireTime) {
- // If there was no change in the time, then discard this
- // count. A somewhat cheezy strategy, but hey.
- mCount--;
- }
+ // Accumulate time to all active counters, scaled by the total
+ // active in the pool, before taking this one out of the pool.
+ refreshTimersLocked(stats, mTimerPool);
+ // Remove this timer from the active pool
+ mTimerPool.remove(this);
}
}
@@ -379,28 +297,24 @@ public final class BatteryStatsImpl extends BatteryStats {
private long computeRunTimeLocked(long curBatteryRealtime) {
return mTotalTime + (mNesting > 0
- ? (curBatteryRealtime - mUpdateTime)
- / (mTimerPool != null ? mTimerPool.size() : 1)
- : 0);
+ ? (curBatteryRealtime - mUpdateTime) / mTimerPool.size() : 0);
}
- void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
- long runTime = computeRunTimeLocked(batteryRealtime);
+ void writeSummaryFromParcelLocked(Parcel out, long curBatteryUptime) {
+ long runTime = computeRunTimeLocked(curBatteryUptime);
// Divide by 1000 for backwards compatibility
out.writeLong((runTime + 500) / 1000);
- out.writeLong(((runTime - mLoadedTime) + 500) / 1000);
+ out.writeLong(((runTime - mLoadedTotalTime) + 500) / 1000);
out.writeInt(mCount);
out.writeInt(mCount - mLoadedCount);
}
void readSummaryFromParcelLocked(Parcel in) {
// Multiply by 1000 for backwards compatibility
- mTotalTime = mLoadedTime = in.readLong() * 1000;
- mLastTime = in.readLong() * 1000;
- mUnpluggedTime = mTotalTime;
+ mTotalTime = mLoadedTotalTime = in.readLong() * 1000;
+ mLastTotalTime = in.readLong();
mCount = mLoadedCount = in.readInt();
mLastCount = in.readInt();
- mUnpluggedCount = mCount;
mNesting = 0;
}
}
@@ -443,40 +357,47 @@ public final class BatteryStatsImpl extends BatteryStats {
mUidStats.get(uid).noteStopGps();
}
- public void noteScreenOnLocked() {
+ /**
+ * When the device screen or battery state changes, update the appropriate "screen on time"
+ * counter.
+ */
+ private void updateScreenOnTimeLocked(boolean screenOn) {
if (!mScreenOn) {
- mScreenOn = true;
- mScreenOnTimer.startRunningLocked(this);
+ Log.w(TAG, "updateScreenOnTime without mScreenOn, ignored");
+ return;
}
- }
-
- public void noteScreenOffLocked() {
- if (mScreenOn) {
- mScreenOn = false;
- mScreenOnTimer.stopRunningLocked(this);
+ long now = SystemClock.elapsedRealtime();
+ long elapsed = now - mLastScreenOnTimeMillis;
+ if (mOnBattery) {
+ mBatteryScreenOnTimeMillis += elapsed;
+ } else {
+ mPluggedScreenOnTimeMillis += elapsed;
+ }
+ if (screenOn) {
+ mLastScreenOnTimeMillis = now;
}
}
- public void notePhoneOnLocked() {
- if (!mPhoneOn) {
- mPhoneOn = true;
- mPhoneOnTimer.startRunningLocked(this);
- }
+ public void noteScreenOnLocked() {
+ mScreenOn = true;
+ mLastScreenOnTimeMillis = SystemClock.elapsedRealtime();
}
- public void notePhoneOffLocked() {
- if (mPhoneOn) {
- mPhoneOn = false;
- mPhoneOnTimer.stopRunningLocked(this);
+ public void noteScreenOffLocked() {
+ if (!mScreenOn) {
+ Log.w(TAG, "noteScreenOff without mScreenOn, ignored");
+ return;
}
+ updateScreenOnTimeLocked(false);
+ mScreenOn = false;
}
- @Override public long getScreenOnTime(long batteryRealtime, int which) {
- return mScreenOnTimer.getTotalTime(batteryRealtime, which);
+ @Override public long getBatteryScreenOnTime() {
+ return mBatteryScreenOnTimeMillis;
}
- @Override public long getPhoneOnTime(long batteryRealtime, int which) {
- return mPhoneOnTimer.getTotalTime(batteryRealtime, which);
+ @Override public long getPluggedScreenOnTime() {
+ return mPluggedScreenOnTimeMillis;
}
@Override public boolean getIsOnBattery() {
@@ -1460,8 +1381,6 @@ public final class BatteryStatsImpl extends BatteryStats {
mFile = new File(filename);
mBackupFile = new File(filename + ".bak");
mStartCount++;
- mScreenOnTimer = new Timer(-1, null, mUnpluggables);
- mPhoneOnTimer = new Timer(-2, null, mUnpluggables);
mOnBattery = mOnBatteryInternal = false;
mTrackBatteryPastUptime = 0;
mTrackBatteryPastRealtime = 0;
@@ -1488,6 +1407,10 @@ public final class BatteryStatsImpl extends BatteryStats {
public void setOnBattery(boolean onBattery) {
synchronized(this) {
if (mOnBattery != onBattery) {
+ if (mScreenOn) {
+ updateScreenOnTimeLocked(true);
+ }
+
mOnBattery = mOnBatteryInternal = onBattery;
long uptime = SystemClock.uptimeMillis() * 1000;
@@ -1502,7 +1425,7 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart;
mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart;
- doPlug(getBatteryUptimeLocked(uptime), getBatteryRealtimeLocked(realtime));
+ doPlug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime);
}
if ((mLastWriteTime + (60 * 1000)) < mSecRealtime) {
if (mFile != null) {
@@ -1524,10 +1447,10 @@ public final class BatteryStatsImpl extends BatteryStats {
@Override
public long computeUptime(long curTime, int which) {
switch (which) {
- case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
- case STATS_LAST: return mLastUptime;
- case STATS_CURRENT: return (curTime-mUptimeStart);
- case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
+ case STATS_TOTAL: return mUptime + (curTime-mUptimeStart);
+ case STATS_LAST: return mLastUptime;
+ case STATS_CURRENT: return (curTime-mUptimeStart);
+ case STATS_UNPLUGGED: return (curTime-mTrackBatteryUptimeStart);
}
return 0;
}
@@ -1535,25 +1458,26 @@ public final class BatteryStatsImpl extends BatteryStats {
@Override
public long computeRealtime(long curTime, int which) {
switch (which) {
- case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
- case STATS_LAST: return mLastRealtime;
- case STATS_CURRENT: return (curTime-mRealtimeStart);
- case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
+ case STATS_TOTAL: return mRealtime + (curTime-mRealtimeStart);
+ case STATS_LAST: return mLastRealtime;
+ case STATS_CURRENT: return (curTime-mRealtimeStart);
+ case STATS_UNPLUGGED: return (curTime-mTrackBatteryRealtimeStart);
}
return 0;
}
@Override
public long computeBatteryUptime(long curTime, int which) {
+ long uptime = getBatteryUptime(curTime);
switch (which) {
- case STATS_TOTAL:
- return mBatteryUptime + getBatteryUptime(curTime);
- case STATS_LAST:
- return mBatteryLastUptime;
- case STATS_CURRENT:
- return getBatteryUptime(curTime);
- case STATS_UNPLUGGED:
- return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
+ case STATS_TOTAL:
+ return mBatteryUptime + uptime;
+ case STATS_LAST:
+ return mBatteryLastUptime;
+ case STATS_CURRENT:
+ return uptime;
+ case STATS_UNPLUGGED:
+ return getBatteryUptimeLocked(curTime) - mUnpluggedBatteryUptime;
}
return 0;
}
@@ -1561,14 +1485,14 @@ public final class BatteryStatsImpl extends BatteryStats {
@Override
public long computeBatteryRealtime(long curTime, int which) {
switch (which) {
- case STATS_TOTAL:
- return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
- case STATS_LAST:
- return mBatteryLastRealtime;
- case STATS_CURRENT:
- return getBatteryRealtimeLocked(curTime);
- case STATS_UNPLUGGED:
- return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
+ case STATS_TOTAL:
+ return mBatteryRealtime + getBatteryRealtimeLocked(curTime);
+ case STATS_LAST:
+ return mBatteryLastRealtime;
+ case STATS_CURRENT:
+ return getBatteryRealtimeLocked(curTime);
+ case STATS_UNPLUGGED:
+ return getBatteryRealtimeLocked(curTime) - mUnpluggedBatteryRealtime;
}
return 0;
}
@@ -1764,10 +1688,9 @@ public final class BatteryStatsImpl extends BatteryStats {
mLastRealtime = in.readLong();
mStartCount++;
+ mBatteryScreenOnTimeMillis = in.readLong();
+ mPluggedScreenOnTimeMillis = in.readLong();
mScreenOn = false;
- mScreenOnTimer.readSummaryFromParcelLocked(in);
- mPhoneOn = false;
- mPhoneOnTimer.readSummaryFromParcelLocked(in);
final int NU = in.readInt();
for (int iu = 0; iu < NU; iu++) {
@@ -1841,10 +1764,9 @@ public final class BatteryStatsImpl extends BatteryStats {
* @param out the Parcel to be written to.
*/
public void writeSummaryToParcel(Parcel out) {
+ final long NOW = getBatteryUptimeLocked();
final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
- final long NOW = getBatteryUptimeLocked(NOW_SYS);
- final long NOWREAL = getBatteryRealtimeLocked(NOWREAL_SYS);
out.writeInt(VERSION);
@@ -1858,8 +1780,8 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeLong(computeRealtime(NOWREAL_SYS, STATS_TOTAL));
out.writeLong(computeRealtime(NOWREAL_SYS, STATS_CURRENT));
- mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
- mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+ out.writeLong(mBatteryScreenOnTimeMillis);
+ out.writeLong(mPluggedScreenOnTimeMillis);
final int NU = mUidStats.size();
out.writeInt(NU);
@@ -1876,19 +1798,19 @@ public final class BatteryStatsImpl extends BatteryStats {
Uid.Wakelock wl = ent.getValue();
if (wl.mTimerFull != null) {
out.writeInt(1);
- wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL);
+ wl.mTimerFull.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
if (wl.mTimerPartial != null) {
out.writeInt(1);
- wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL);
+ wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
if (wl.mTimerWindow != null) {
out.writeInt(1);
- wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL);
+ wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
@@ -1904,7 +1826,7 @@ public final class BatteryStatsImpl extends BatteryStats {
Uid.Sensor se = ent.getValue();
if (se.mTimer != null) {
out.writeInt(1);
- se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL);
+ se.mTimer.writeSummaryFromParcelLocked(out, NOW);
} else {
out.writeInt(0);
}
@@ -1975,10 +1897,9 @@ public final class BatteryStatsImpl extends BatteryStats {
mBatteryLastUptime = in.readLong();
mBatteryRealtime = in.readLong();
mBatteryLastRealtime = in.readLong();
+ mBatteryScreenOnTimeMillis = in.readLong();
+ mPluggedScreenOnTimeMillis = in.readLong();
mScreenOn = false;
- mScreenOnTimer = new Timer(-1, null, mUnpluggables, in);
- mPhoneOn = false;
- mPhoneOnTimer = new Timer(-2, null, mUnpluggables, in);
mUptime = in.readLong();
mUptimeStart = in.readLong();
mLastUptime = in.readLong();
@@ -1991,8 +1912,6 @@ public final class BatteryStatsImpl extends BatteryStats {
mTrackBatteryUptimeStart = in.readLong();
mTrackBatteryPastRealtime = in.readLong();
mTrackBatteryRealtimeStart = in.readLong();
- mUnpluggedBatteryUptime = in.readLong();
- mUnpluggedBatteryRealtime = in.readLong();
mLastWriteTime = in.readLong();
mPartialTimers.clear();
@@ -2026,8 +1945,8 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeLong(mBatteryLastUptime);
out.writeLong(mBatteryRealtime);
out.writeLong(mBatteryLastRealtime);
- mScreenOnTimer.writeToParcel(out, batteryRealtime);
- mPhoneOnTimer.writeToParcel(out, batteryRealtime);
+ out.writeLong(mBatteryScreenOnTimeMillis);
+ out.writeLong(mPluggedScreenOnTimeMillis);
out.writeLong(mUptime);
out.writeLong(mUptimeStart);
out.writeLong(mLastUptime);
@@ -2035,12 +1954,10 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeLong(mRealtimeStart);
out.writeLong(mLastRealtime);
out.writeInt(mOnBattery ? 1 : 0);
- out.writeLong(batteryUptime);
+ out.writeLong(mTrackBatteryPastUptime);
out.writeLong(mTrackBatteryUptimeStart);
- out.writeLong(batteryRealtime);
+ out.writeLong(mTrackBatteryPastRealtime);
out.writeLong(mTrackBatteryRealtimeStart);
- out.writeLong(mUnpluggedBatteryUptime);
- out.writeLong(mUnpluggedBatteryRealtime);
out.writeLong(mLastWriteTime);
int size = mUidStats.size();
@@ -2063,14 +1980,4 @@ public final class BatteryStatsImpl extends BatteryStats {
return new BatteryStatsImpl[size];
}
};
-
- public void dumpLocked(Printer pw) {
- if (DEBUG) {
- Log.i(TAG, "*** Screen timer:");
- mScreenOnTimer.logState();
- Log.i(TAG, "*** Phone timer:");
- mPhoneOnTimer.logState();
- }
- super.dumpLocked(pw);
- }
}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index ac8b589..f21b62f 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -19,7 +19,6 @@ package com.android.internal.os;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.net.LocalServerSocket;
import android.os.Debug;
@@ -336,18 +335,32 @@ public class ZygoteInit {
mResources.startPreloading();
if (PRELOAD_RESOURCES) {
Log.i(TAG, "Preloading resources...");
-
long startTime = SystemClock.uptimeMillis();
TypedArray ar = mResources.obtainTypedArray(
com.android.internal.R.array.preloaded_drawables);
- int N = preloadDrawables(runtime, ar);
- Log.i(TAG, "...preloaded " + N + " resources in "
- + (SystemClock.uptimeMillis()-startTime) + "ms.");
-
- startTime = SystemClock.uptimeMillis();
- ar = mResources.obtainTypedArray(
- com.android.internal.R.array.preloaded_color_state_lists);
- N = preloadColorStateLists(runtime, ar);
+ int N = ar.length();
+ for (int i=0; i<N; i++) {
+ if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
+ if (Config.LOGV) {
+ Log.v(TAG, " GC at " + Debug.getGlobalAllocSize());
+ }
+ runtime.gcSoftReferences();
+ runtime.runFinalizationSync();
+ Debug.resetGlobalAllocSize();
+ }
+ int id = ar.getResourceId(i, 0);
+ if (Config.LOGV) {
+ Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
+ }
+ if (id != 0) {
+ Drawable dr = mResources.getDrawable(id);
+ if ((dr.getChangingConfigurations()&~ActivityInfo.CONFIG_FONT_SCALE) != 0) {
+ Log.w(TAG, "Preloaded drawable resource #0x"
+ + Integer.toHexString(id)
+ + " that varies with configuration!!");
+ }
+ }
+ }
Log.i(TAG, "...preloaded " + N + " resources in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
}
@@ -359,56 +372,6 @@ public class ZygoteInit {
}
}
- private static int preloadColorStateLists(VMRuntime runtime, TypedArray ar) {
- int N = ar.length();
- for (int i=0; i<N; i++) {
- if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
- if (Config.LOGV) {
- Log.v(TAG, " GC at " + Debug.getGlobalAllocSize());
- }
- runtime.gcSoftReferences();
- runtime.runFinalizationSync();
- Debug.resetGlobalAllocSize();
- }
- int id = ar.getResourceId(i, 0);
- if (Config.LOGV) {
- Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
- }
- if (id != 0) {
- mResources.getColorStateList(id);
- }
- }
- return N;
- }
-
-
- private static int preloadDrawables(VMRuntime runtime, TypedArray ar) {
- int N = ar.length();
- for (int i=0; i<N; i++) {
- if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
- if (Config.LOGV) {
- Log.v(TAG, " GC at " + Debug.getGlobalAllocSize());
- }
- runtime.gcSoftReferences();
- runtime.runFinalizationSync();
- Debug.resetGlobalAllocSize();
- }
- int id = ar.getResourceId(i, 0);
- if (Config.LOGV) {
- Log.v(TAG, "Preloading resource #" + Integer.toHexString(id));
- }
- if (id != 0) {
- Drawable dr = mResources.getDrawable(id);
- if ((dr.getChangingConfigurations()&~ActivityInfo.CONFIG_FONT_SCALE) != 0) {
- Log.w(TAG, "Preloaded drawable resource #0x"
- + Integer.toHexString(id)
- + " (" + ar.getString(i) + ") that varies with configuration!!");
- }
- }
- }
- return N;
- }
-
/**
* Runs several special GCs to try to clean up a few generations of
* softly- and final-reachable objects, along with any other garbage.
diff --git a/core/java/com/android/internal/view/IInputConnectionWrapper.java b/core/java/com/android/internal/view/IInputConnectionWrapper.java
index 8e65177..4f98cee 100644
--- a/core/java/com/android/internal/view/IInputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/IInputConnectionWrapper.java
@@ -23,8 +23,7 @@ public class IInputConnectionWrapper extends IInputContext.Stub {
private static final int DO_COMMIT_TEXT = 50;
private static final int DO_COMMIT_COMPLETION = 55;
private static final int DO_SET_SELECTION = 57;
- private static final int DO_PERFORM_EDITOR_ACTION = 58;
- private static final int DO_PERFORM_CONTEXT_MENU_ACTION = 59;
+ private static final int DO_PERFORM_CONTEXT_MENU_ACTION = 58;
private static final int DO_SET_COMPOSING_TEXT = 60;
private static final int DO_FINISH_COMPOSING_TEXT = 65;
private static final int DO_SEND_KEY_EVENT = 70;
@@ -98,10 +97,6 @@ public class IInputConnectionWrapper extends IInputContext.Stub {
dispatchMessage(obtainMessageII(DO_SET_SELECTION, start, end));
}
- public void performEditorAction(int id) {
- dispatchMessage(obtainMessageII(DO_PERFORM_EDITOR_ACTION, id, 0));
- }
-
public void performContextMenuAction(int id) {
dispatchMessage(obtainMessageII(DO_PERFORM_CONTEXT_MENU_ACTION, id, 0));
}
@@ -240,15 +235,6 @@ public class IInputConnectionWrapper extends IInputContext.Stub {
ic.setSelection(msg.arg1, msg.arg2);
return;
}
- case DO_PERFORM_EDITOR_ACTION: {
- InputConnection ic = mInputConnection.get();
- if (ic == null || !isActive()) {
- Log.w(TAG, "performEditorAction on inactive InputConnection");
- return;
- }
- ic.performEditorAction(msg.arg1);
- return;
- }
case DO_PERFORM_CONTEXT_MENU_ACTION: {
InputConnection ic = mInputConnection.get();
if (ic == null || !isActive()) {
diff --git a/core/java/com/android/internal/view/IInputContext.aidl b/core/java/com/android/internal/view/IInputContext.aidl
index 02cb9e4..02b6044 100644
--- a/core/java/com/android/internal/view/IInputContext.aidl
+++ b/core/java/com/android/internal/view/IInputContext.aidl
@@ -50,8 +50,6 @@ import com.android.internal.view.IInputContextCallback;
void setSelection(int start, int end);
- void performEditorAction(int actionCode);
-
void performContextMenuAction(int id);
void beginBatchEdit();
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index b92cb45..32d9f3d 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -250,15 +250,6 @@ public class InputConnectionWrapper implements InputConnection {
}
}
- public boolean performEditorAction(int actionCode) {
- try {
- mIInputContext.performEditorAction(actionCode);
- return true;
- } catch (RemoteException e) {
- return false;
- }
- }
-
public boolean performContextMenuAction(int id) {
try {
mIInputContext.performContextMenuAction(id);
diff --git a/core/java/com/android/internal/view/menu/ExpandedMenuView.java b/core/java/com/android/internal/view/menu/ExpandedMenuView.java
index 9e4b4ce..c16c165 100644
--- a/core/java/com/android/internal/view/menu/ExpandedMenuView.java
+++ b/core/java/com/android/internal/view/menu/ExpandedMenuView.java
@@ -80,11 +80,6 @@ public final class ExpandedMenuView extends ListView implements ItemInvoker, Men
setChildrenDrawingCacheEnabled(false);
}
- @Override
- protected boolean recycleOnMeasure() {
- return false;
- }
-
public boolean invokeItem(MenuItemImpl item) {
return mMenu.performItemAction(item, 0);
}
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index f2ec064..44cf0ed 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -59,14 +59,7 @@ public class EditableInputConnection extends BaseInputConnection {
final Editable content = getEditable();
if (content == null) return false;
KeyListener kl = mTextView.getKeyListener();
- if (kl != null) {
- try {
- kl.clearMetaKeyState(mTextView, content, states);
- } catch (AbstractMethodError e) {
- // This is an old listener that doesn't implement the
- // new method.
- }
- }
+ if (kl != null) kl.clearMetaKeyState(mTextView, content, states);
return true;
}
@@ -78,12 +71,6 @@ public class EditableInputConnection extends BaseInputConnection {
return true;
}
- public boolean performEditorAction(int actionCode) {
- if (DEBUG) Log.v(TAG, "performEditorAction " + actionCode);
- mTextView.onEditorAction(actionCode);
- return true;
- }
-
public boolean performContextMenuAction(int id) {
if (DEBUG) Log.v(TAG, "performContextMenuAction " + id);
mTextView.beginBatchEdit();
diff --git a/core/java/com/android/internal/widget/TextProgressBar.java b/core/java/com/android/internal/widget/TextProgressBar.java
index aee7b76..5bf4601 100644
--- a/core/java/com/android/internal/widget/TextProgressBar.java
+++ b/core/java/com/android/internal/widget/TextProgressBar.java
@@ -115,10 +115,8 @@ public class TextProgressBar extends RelativeLayout implements OnChronometerTick
// Update the ProgressBar maximum relative to Chronometer base
mDuration = (int) (durationBase - mChronometer.getBase());
- if (mDuration <= 0) {
- mDuration = 1;
- }
mProgressBar.setMax(mDuration);
+
}
/**
diff --git a/core/java/com/google/android/gdata/client/AndroidGDataClient.java b/core/java/com/google/android/gdata/client/AndroidGDataClient.java
index fe7d860..1d8e9c5 100644
--- a/core/java/com/google/android/gdata/client/AndroidGDataClient.java
+++ b/core/java/com/google/android/gdata/client/AndroidGDataClient.java
@@ -21,7 +21,6 @@ import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.AbstractHttpEntity;
import android.content.ContentResolver;
-import android.content.Context;
import android.net.http.AndroidHttpClient;
import android.text.TextUtils;
import android.util.Config;
@@ -118,28 +117,16 @@ public class AndroidGDataClient implements GDataClient {
}
/**
- * @deprecated Use AndroidGDAtaClient(Context) instead.
- */
- public AndroidGDataClient(ContentResolver resolver) {
- mHttpClient = new GoogleHttpClient(resolver, USER_AGENT_APP_VERSION,
- true /* gzip capable */);
- mHttpClient.enableCurlLogging(TAG, Log.VERBOSE);
- mResolver = resolver;
- }
-
- /**
* Creates a new AndroidGDataClient.
*
- * @param context The ContentResolver to get URL rewriting rules from
+ * @param resolver The ContentResolver to get URL rewriting rules from
* through the Android proxy server, using null to indicate not using proxy.
- * The context will also be used by GoogleHttpClient for configuration of
- * SSL session persistence.
*/
- public AndroidGDataClient(Context context) {
- mHttpClient = new GoogleHttpClient(context, USER_AGENT_APP_VERSION,
+ public AndroidGDataClient(ContentResolver resolver) {
+ mHttpClient = new GoogleHttpClient(resolver, USER_AGENT_APP_VERSION,
true /* gzip capable */);
mHttpClient.enableCurlLogging(TAG, Log.VERBOSE);
- mResolver = context.getContentResolver();
+ mResolver = resolver;
}
public void close() {
diff --git a/core/java/com/google/android/net/GoogleHttpClient.java b/core/java/com/google/android/net/GoogleHttpClient.java
index ae78ba8..2fcb0c3 100644
--- a/core/java/com/google/android/net/GoogleHttpClient.java
+++ b/core/java/com/google/android/net/GoogleHttpClient.java
@@ -16,12 +16,8 @@
package com.google.android.net;
-import com.android.internal.net.DbSSLSessionCache;
-import com.android.internal.net.SSLSessionCache;
-
import android.content.ContentResolver;
import android.content.ContentValues;
-import android.content.Context;
import android.net.http.AndroidHttpClient;
import android.os.Build;
import android.os.NetStat;
@@ -83,24 +79,6 @@ public class GoogleHttpClient implements HttpClient {
}
/**
- * GoogleHttpClient(Context, String, boolean) - without SSL session
- * persistence.
- *
- * @deprecated use Context instead of ContentResolver.
- */
- public GoogleHttpClient(ContentResolver resolver, String appAndVersion,
- boolean gzipCapable) {
- String userAgent = appAndVersion
- + " (" + Build.DEVICE + " " + Build.ID + ")";
- if (gzipCapable) {
- userAgent = userAgent + "; gzip";
- }
- mClient = AndroidHttpClient.newInstance(userAgent);
- mResolver = resolver;
- mUserAgent = userAgent;
- }
-
- /**
* Create an HTTP client. Normaly this client is shared throughout an app.
* The HTTP client will construct its User-Agent as follows:
*
@@ -109,10 +87,7 @@ public class GoogleHttpClient implements HttpClient {
* <appAndVersion> (<build device> <build id>); gzip
* (if gzip capable)
*
- * The context has settings for URL rewriting rules and is used to enable
- * SSL session persistence.
- *
- * @param context application context.
+ * @param resolver to use for acccessing URL rewriting rules.
* @param appAndVersion Base app and version to use in the User-Agent.
* e.g., "MyApp/1.0"
* @param gzipCapable Whether or not this client is able to consume gzip'd
@@ -120,18 +95,15 @@ public class GoogleHttpClient implements HttpClient {
* headers. Needed because Google servers require gzip in the User-Agent
* in order to return gzip'd content.
*/
- public GoogleHttpClient(Context context, String appAndVersion,
- boolean gzipCapable) {
-
+ public GoogleHttpClient(ContentResolver resolver, String appAndVersion,
+ boolean gzipCapable) {
String userAgent = appAndVersion
+ " (" + Build.DEVICE + " " + Build.ID + ")";
if (gzipCapable) {
userAgent = userAgent + "; gzip";
}
- mClient = AndroidHttpClient.newInstance(userAgent,
- SSLSessionCache.getSessionCache(context));
-
- mResolver = context.getContentResolver();
+ mClient = AndroidHttpClient.newInstance(userAgent);
+ mResolver = resolver;
mUserAgent = userAgent;
}