summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml19
-rw-r--r--cmds/stagefright/Android.mk24
-rw-r--r--cmds/stagefright/stream.cpp168
-rw-r--r--core/java/android/app/ActivityManagerNative.java51
-rw-r--r--core/java/android/app/DownloadManager.java6
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java15
-rw-r--r--core/java/android/bluetooth/BluetoothDeviceProfileState.java8
-rw-r--r--core/java/android/bluetooth/IBluetooth.aidl1
-rw-r--r--core/java/android/os/Looper.java69
-rw-r--r--core/java/android/os/StrictMode.java83
-rw-r--r--core/java/android/os/SystemProperties.java2
-rw-r--r--core/java/android/preference/PreferenceFrameLayout.java14
-rw-r--r--core/java/android/provider/Downloads.java21
-rw-r--r--core/java/android/server/BluetoothService.java38
-rw-r--r--core/java/android/util/PrefixPrinter.java50
-rw-r--r--core/java/android/util/TimeUtils.java5
-rw-r--r--core/java/android/view/IWindowManager.aidl6
-rw-r--r--core/java/android/view/Surface.java13
-rw-r--r--core/java/android/view/WindowManager.java10
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java25
-rw-r--r--core/java/android/webkit/OverScrollGlow.java12
-rw-r--r--core/java/android/webkit/WebView.java25
-rw-r--r--core/java/android/widget/AbsListView.java111
-rw-r--r--core/java/android/widget/EdgeGlow.java40
-rw-r--r--core/java/android/widget/HorizontalScrollView.java53
-rw-r--r--core/java/android/widget/ScrollView.java51
-rw-r--r--core/java/android/widget/TextView.java218
-rw-r--r--core/java/com/android/internal/view/IInputMethodManager.aidl1
-rw-r--r--core/jni/android_view_Surface.cpp62
-rw-r--r--core/res/res/values/colors.xml4
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/tests/coretests/src/android/content/SyncOperationTest.java93
-rw-r--r--core/tests/coretests/src/android/util/TimeUtilsTest.java18
-rw-r--r--drm/libdrmframework/plugins/widevine/Android.mk27
-rw-r--r--include/media/IMediaPlayerService.h6
-rw-r--r--include/media/IStreamSource.h66
-rw-r--r--include/media/MediaPlayerInterface.h5
-rw-r--r--include/ui/InputDispatcher.h4
-rw-r--r--libs/rs/java/Balls/src/com/android/balls/BallsRS.java2
-rw-r--r--libs/rs/java/Balls/src/com/android/balls/ball_physics.rs15
-rwxr-xr-xmedia/java/android/media/videoeditor/MediaProperties.java3
-rw-r--r--media/libmedia/Android.mk1
-rw-r--r--media/libmedia/IMediaPlayerService.cpp38
-rw-r--r--media/libmedia/IStreamSource.cpp168
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp44
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h8
-rw-r--r--media/libmediaplayerservice/StagefrightPlayer.cpp4
-rw-r--r--media/libmediaplayerservice/StagefrightPlayer.h3
-rw-r--r--media/libstagefright/AwesomePlayer.cpp227
-rw-r--r--media/libstagefright/include/AwesomePlayer.h2
-rw-r--r--media/libwvm/Android.mk10
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_notification_open.pngbin0 -> 508 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_notification_veto.pngbin0 -> 602 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd.pngbin0 -> 1224 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd_off.pngbin0 -> 1238 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_quicksettings.pngbin0 -> 1414 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_lanscape.pngbin0 -> 911 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_portrait.pngbin0 -> 871 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_shadow.9.pngbin0 -> 300 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/recent_overlay.pngbin0 -> 302563 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/recent_rez_border.pngbin0 -> 28494 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/sysbar_signalmini_100.pngbin0 -> 2472 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_notification_veto.pngbin0 -> 551 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd.pngbin0 -> 853 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd_off.pngbin0 -> 850 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.pngbin0 -> 700 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.pngbin0 -> 697 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/recent_overlay.png (renamed from packages/SystemUI/res/drawable/recent_overlay.png)bin162325 -> 162325 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/recent_rez_border.png (renamed from packages/SystemUI/res/drawable/recent_rez_border.png)bin21739 -> 21739 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.pngbin0 -> 2585 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.pngbin0 -> 5134 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.pngbin0 -> 10128 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.pngbin0 -> 5958 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.pngbin0 -> 6780 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.pngbin0 -> 7537 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.pngbin0 -> 8164 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.pngbin0 -> 8703 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.pngbin0 -> 9377 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.pngbin0 -> 9827 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.pngbin0 -> 10446 bytes
-rw-r--r--packages/SystemUI/res/drawable-xlarge-hdpi/app_icon.pngbin0 -> 7310 bytes
-rw-r--r--packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml18
-rw-r--r--packages/SystemUI/res/values-xlarge/dimens.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java1
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java121
-rw-r--r--services/audioflinger/A2dpAudioInterface.cpp89
-rw-r--r--services/audioflinger/A2dpAudioInterface.h1
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java29
-rw-r--r--services/java/com/android/server/ScreenRotationAnimation.java152
-rw-r--r--services/java/com/android/server/WindowManagerService.java43
-rw-r--r--telephony/java/com/android/internal/telephony/ApnSetting.java (renamed from telephony/java/com/android/internal/telephony/gsm/ApnSetting.java)27
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnection.java1
-rw-r--r--telephony/java/com/android/internal/telephony/DataConnectionTracker.java45
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java1
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java27
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java1
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java31
-rw-r--r--tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java1
-rw-r--r--tools/validatekeymaps/Main.cpp2
100 files changed, 1998 insertions, 553 deletions
diff --git a/api/current.xml b/api/current.xml
index 04d7a1d..7624086 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -221393,6 +221393,23 @@
<parameter name="id" type="java.lang.String">
</parameter>
</method>
+<method name="setInputMethodAndSubtype"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="token" type="android.os.IBinder">
+</parameter>
+<parameter name="id" type="java.lang.String">
+</parameter>
+<parameter name="subtype" type="android.view.inputmethod.InputMethodSubtype">
+</parameter>
+</method>
<method name="showInputMethodAndSubtypeEnabler"
return="void"
abstract="false"
@@ -249195,7 +249212,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 93baefd..f8650eb 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -98,3 +98,27 @@ LOCAL_MODULE_TAGS := debug
LOCAL_MODULE:= audioloop
include $(BUILD_EXECUTABLE)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ stream.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+ libstagefright liblog libutils libbinder libsurfaceflinger_client \
+ libstagefright_foundation libmedia
+
+LOCAL_C_INCLUDES:= \
+ $(JNI_H_INCLUDE) \
+ frameworks/base/media/libstagefright \
+ $(TOP)/frameworks/base/include/media/stagefright/openmax
+
+LOCAL_CFLAGS += -Wno-multichar
+
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_MODULE:= stream
+
+include $(BUILD_EXECUTABLE)
diff --git a/cmds/stagefright/stream.cpp b/cmds/stagefright/stream.cpp
new file mode 100644
index 0000000..f2b5638
--- /dev/null
+++ b/cmds/stagefright/stream.cpp
@@ -0,0 +1,168 @@
+#include <binder/ProcessState.h>
+
+#include <media/IStreamSource.h>
+#include <media/mediaplayer.h>
+#include <media/stagefright/foundation/ADebug.h>
+
+#include <binder/IServiceManager.h>
+#include <media/IMediaPlayerService.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <fcntl.h>
+
+using namespace android;
+
+struct MyStreamSource : public BnStreamSource {
+ // Caller retains ownership of fd.
+ MyStreamSource(int fd);
+
+ virtual void setListener(const sp<IStreamListener> &listener);
+ virtual void setBuffers(const Vector<sp<IMemory> > &buffers);
+
+ virtual void onBufferAvailable(size_t index);
+
+protected:
+ virtual ~MyStreamSource();
+
+private:
+ int mFd;
+
+ sp<IStreamListener> mListener;
+ Vector<sp<IMemory> > mBuffers;
+
+ DISALLOW_EVIL_CONSTRUCTORS(MyStreamSource);
+};
+
+MyStreamSource::MyStreamSource(int fd)
+ : mFd(fd) {
+ CHECK_GE(fd, 0);
+}
+
+MyStreamSource::~MyStreamSource() {
+}
+
+void MyStreamSource::setListener(const sp<IStreamListener> &listener) {
+ mListener = listener;
+}
+
+void MyStreamSource::setBuffers(const Vector<sp<IMemory> > &buffers) {
+ mBuffers = buffers;
+}
+
+void MyStreamSource::onBufferAvailable(size_t index) {
+ CHECK_LT(index, mBuffers.size());
+ sp<IMemory> mem = mBuffers.itemAt(index);
+
+ ssize_t n = read(mFd, mem->pointer(), mem->size());
+ if (n <= 0) {
+ mListener->queueCommand(IStreamListener::EOS);
+ } else {
+ mListener->queueBuffer(index, n);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct MyClient : public BnMediaPlayerClient {
+ MyClient()
+ : mEOS(false) {
+ }
+
+ virtual void notify(int msg, int ext1, int ext2) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (msg == MEDIA_ERROR || msg == MEDIA_PLAYBACK_COMPLETE) {
+ mEOS = true;
+ mCondition.signal();
+ }
+ }
+
+ void waitForEOS() {
+ Mutex::Autolock autoLock(mLock);
+ while (!mEOS) {
+ mCondition.wait(mLock);
+ }
+ }
+
+protected:
+ virtual ~MyClient() {
+ }
+
+private:
+ Mutex mLock;
+ Condition mCondition;
+
+ bool mEOS;
+
+ DISALLOW_EVIL_CONSTRUCTORS(MyClient);
+};
+
+int main(int argc, char **argv) {
+ android::ProcessState::self()->startThreadPool();
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s filename\n", argv[0]);
+ return 1;
+ }
+
+ sp<SurfaceComposerClient> composerClient = new SurfaceComposerClient;
+ CHECK_EQ(composerClient->initCheck(), (status_t)OK);
+
+ sp<SurfaceControl> control =
+ composerClient->createSurface(
+ getpid(),
+ String8("A Surface"),
+ 0,
+ 1280,
+ 800,
+ PIXEL_FORMAT_RGB_565,
+ 0);
+
+ CHECK(control != NULL);
+ CHECK(control->isValid());
+
+ CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
+ CHECK_EQ(control->setLayer(30000), (status_t)OK);
+ CHECK_EQ(control->show(), (status_t)OK);
+ CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
+
+ sp<Surface> surface = control->getSurface();
+ CHECK(surface != NULL);
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("media.player"));
+ sp<IMediaPlayerService> service = interface_cast<IMediaPlayerService>(binder);
+
+ CHECK(service.get() != NULL);
+
+ int fd = open(argv[1], O_RDONLY);
+
+ if (fd < 0) {
+ fprintf(stderr, "Failed to open file '%s'.", argv[1]);
+ return 1;
+ }
+
+ sp<MyClient> client = new MyClient;
+
+ sp<IMediaPlayer> player =
+ service->create(getpid(), client, new MyStreamSource(fd), 0);
+
+ if (player != NULL) {
+ player->setVideoSurface(surface);
+ player->start();
+
+ client->waitForEOS();
+
+ player->stop();
+ } else {
+ fprintf(stderr, "failed to instantiate player.\n");
+ }
+
+ close(fd);
+ fd = -1;
+
+ composerClient->dispose();
+
+ return 0;
+}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 273e3c6..f3cc4ee 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -41,6 +41,7 @@ import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Config;
import android.util.Log;
+import android.util.Singleton;
import java.util.ArrayList;
import java.util.List;
@@ -52,8 +53,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
* Cast a Binder object into an activity manager interface, generating
* a proxy if needed.
*/
- static public IActivityManager asInterface(IBinder obj)
- {
+ static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
@@ -62,27 +62,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
if (in != null) {
return in;
}
-
+
return new ActivityManagerProxy(obj);
}
-
+
/**
* Retrieve the system's default/global activity manager.
*/
- static public IActivityManager getDefault()
- {
- if (gDefault != null) {
- //if (Config.LOGV) Log.v(
- // "ActivityManager", "returning cur default = " + gDefault);
- return gDefault;
- }
- IBinder b = ServiceManager.getService("activity");
- if (Config.LOGV) Log.v(
- "ActivityManager", "default service binder = " + b);
- gDefault = asInterface(b);
- if (Config.LOGV) Log.v(
- "ActivityManager", "default service = " + gDefault);
- return gDefault;
+ static public IActivityManager getDefault() {
+ return gDefault.get();
}
/**
@@ -95,13 +83,12 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return sSystemReady;
}
static boolean sSystemReady = false;
-
+
/**
* Convenience for sending a sticky broadcast. For internal use only.
* If you don't care about permission, use null.
*/
- static public void broadcastStickyIntent(Intent intent, String permission)
- {
+ static public void broadcastStickyIntent(Intent intent, String permission) {
try {
getDefault().broadcastIntent(
null, intent, null, null, Activity.RESULT_OK, null, null,
@@ -117,8 +104,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
}
}
- public ActivityManagerNative()
- {
+ public ActivityManagerNative() {
attachInterface(this, descriptor);
}
@@ -1390,16 +1376,27 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
}
}
-
+
return super.onTransact(code, data, reply, flags);
}
- public IBinder asBinder()
- {
+ public IBinder asBinder() {
return this;
}
- private static IActivityManager gDefault;
+ private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
+ protected IActivityManager create() {
+ IBinder b = ServiceManager.getService("activity");
+ if (Config.LOGV) {
+ Log.v("ActivityManager", "default service binder = " + b);
+ }
+ IActivityManager am = asInterface(b);
+ if (Config.LOGV) {
+ Log.v("ActivityManager", "default service = " + am);
+ }
+ return am;
+ }
+ };
}
class ActivityManagerProxy implements IActivityManager
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 09a21f8..4aa4d77 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -841,6 +841,12 @@ public class DownloadManager {
}
ContentValues values = new ContentValues();
values.put(Downloads.Impl.COLUMN_DELETED, 1);
+ // if only one id is passed in, then include it in the uri itself.
+ // this will eliminate a full database scan in the download service.
+ if (ids.length == 1) {
+ return mResolver.update(ContentUris.withAppendedId(mBaseUri, ids[0]), values,
+ null, null);
+ }
return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),
getWhereArgsForIds(ids));
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 556fb10..32df4e8 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -521,6 +521,21 @@ public final class BluetoothAdapter {
}
/**
+ * Get the UUIDs supported by the local Bluetooth adapter.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+ *
+ * @return the UUIDs supported by the local Bluetooth Adapter.
+ * @hide
+ */
+ public ParcelUuid[] getUuids() {
+ try {
+ return mService.getUuids();
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return null;
+ }
+
+ /**
* Set the friendly Bluetooth name of the local Bluetooth adapter.
* <p>This name is visible to remote Bluetooth devices.
* <p>Valid Bluetooth names are a maximum of 248 bytes using UTF-8
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 138e7f2..3eadff9 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -301,10 +301,9 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
if (isPhoneDocked(mDevice)) {
// Don't auto connect to docks.
break;
- } else if (mHeadsetService == null) {
- deferMessage(message);
} else {
- if (mHeadsetService.getPriority(mDevice) ==
+ if (mHeadsetService != null &&
+ mHeadsetService.getPriority(mDevice) ==
BluetoothHeadset.PRIORITY_AUTO_CONNECT &&
mHeadsetService.getDevicesMatchingConnectionStates(
new int[] {BluetoothProfile.STATE_CONNECTED,
@@ -1027,7 +1026,8 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
// This is again against spec. HFP incoming connections should be made
// before A2DP, so we should not hit this case. But many devices
// don't follow this.
- if (mHeadsetService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON) {
+ if (mHeadsetService != null &&
+ mHeadsetService.getPriority(mDevice) == BluetoothProfile.PRIORITY_ON) {
Message msg = new Message();
msg.what = CONNECT_OTHER_PROFILES;
msg.arg1 = CONNECT_HFP_OUTGOING;
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index aefb3f2..f3e73cf 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -35,6 +35,7 @@ interface IBluetooth
String getAddress();
String getName();
boolean setName(in String name);
+ ParcelUuid[] getUuids();
int getScanMode();
boolean setScanMode(int mode, int duration);
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index d360140..898c642 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -17,7 +17,9 @@
package android.os;
import android.util.Config;
+import android.util.Log;
import android.util.Printer;
+import android.util.PrefixPrinter;
/**
* Class used to run a message loop for a thread. Threads by default do
@@ -31,37 +33,38 @@ import android.util.Printer;
* <p>This is a typical example of the implementation of a Looper thread,
* using the separation of {@link #prepare} and {@link #loop} to create an
* initial Handler to communicate with the Looper.
- *
+ *
* <pre>
* class LooperThread extends Thread {
* public Handler mHandler;
- *
+ *
* public void run() {
* Looper.prepare();
- *
+ *
* mHandler = new Handler() {
* public void handleMessage(Message msg) {
* // process incoming messages here
* }
* };
- *
+ *
* Looper.loop();
* }
* }</pre>
*/
public class Looper {
- private static final boolean DEBUG = false;
- private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
+ private static final String TAG = "Looper";
+ private static final boolean LOG_V = Log.isLoggable(TAG, Log.VERBOSE);
// sThreadLocal.get() will return null unless you've called prepare().
- private static final ThreadLocal sThreadLocal = new ThreadLocal();
+ private static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
final MessageQueue mQueue;
+ final Thread mThread;
volatile boolean mRun;
- Thread mThread;
+
private Printer mLogging = null;
- private static Looper mMainLooper = null;
-
+ private static Looper mMainLooper = null; // guarded by Looper.class
+
/** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
* this looper, before actually starting the loop. Be sure to call
@@ -74,13 +77,13 @@ public class Looper {
}
sThreadLocal.set(new Looper());
}
-
- /** Initialize the current thread as a looper, marking it as an application's main
- * looper. The main looper for your application is created by the Android environment,
- * so you should never need to call this function yourself.
- * {@link #prepare()}
+
+ /**
+ * Initialize the current thread as a looper, marking it as an
+ * application's main looper. The main looper for your application
+ * is created by the Android environment, so you should never need
+ * to call this function yourself. See also: {@link #prepare()}
*/
-
public static final void prepareMainLooper() {
prepare();
setMainLooper(myLooper());
@@ -92,7 +95,7 @@ public class Looper {
private synchronized static void setMainLooper(Looper looper) {
mMainLooper = looper;
}
-
+
/** Returns the application's main looper, which lives in the main thread of the application.
*/
public synchronized static final Looper getMainLooper() {
@@ -100,28 +103,28 @@ public class Looper {
}
/**
- * Run the message queue in this thread. Be sure to call
+ * Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static final void loop() {
Looper me = myLooper();
+ if (me == null) {
+ throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
+ }
MessageQueue queue = me.mQueue;
while (true) {
Message msg = queue.next(); // might block
- //if (!me.mRun) {
- // break;
- //}
if (msg != null) {
if (msg.target == null) {
// No target is a magic identifier for the quit message.
return;
}
- if (me.mLogging!= null) me.mLogging.println(
+ if (me.mLogging != null) me.mLogging.println(
">>>>> Dispatching to " + msg.target + " "
+ msg.callback + ": " + msg.what
);
msg.target.dispatchMessage(msg);
- if (me.mLogging!= null) me.mLogging.println(
+ if (me.mLogging != null) me.mLogging.println(
"<<<<< Finished to " + msg.target + " "
+ msg.callback);
msg.recycle();
@@ -134,7 +137,7 @@ public class Looper {
* null if the calling thread is not associated with a Looper.
*/
public static final Looper myLooper() {
- return (Looper)sThreadLocal.get();
+ return sThreadLocal.get();
}
/**
@@ -179,28 +182,29 @@ public class Looper {
public Thread getThread() {
return mThread;
}
-
+
/** @hide */
public MessageQueue getQueue() {
return mQueue;
}
-
+
public void dump(Printer pw, String prefix) {
- pw.println(prefix + this);
- pw.println(prefix + "mRun=" + mRun);
- pw.println(prefix + "mThread=" + mThread);
- pw.println(prefix + "mQueue=" + ((mQueue != null) ? mQueue : "(null"));
+ pw = PrefixPrinter.create(pw, prefix);
+ pw.println(this.toString());
+ pw.println("mRun=" + mRun);
+ pw.println("mThread=" + mThread);
+ pw.println("mQueue=" + ((mQueue != null) ? mQueue : "(null"));
if (mQueue != null) {
synchronized (mQueue) {
long now = SystemClock.uptimeMillis();
Message msg = mQueue.mMessages;
int n = 0;
while (msg != null) {
- pw.println(prefix + " Message " + n + ": " + msg.toString(now));
+ pw.println(" Message " + n + ": " + msg.toString(now));
n++;
msg = msg.next;
}
- pw.println(prefix + "(Total messages: " + n + ")");
+ pw.println("(Total messages: " + n + ")");
}
}
}
@@ -226,4 +230,3 @@ public class Looper {
}
}
}
-
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index b69e0b1..754d073 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -19,6 +19,7 @@ import android.animation.ValueAnimator;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
import android.app.ApplicationErrorReport;
+import android.app.IActivityManager;
import android.content.Intent;
import android.util.Log;
import android.util.Printer;
@@ -112,6 +113,13 @@ public final class StrictMode {
private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
private static final boolean IS_ENG_BUILD = "eng".equals(Build.TYPE);
+ /**
+ * The boolean system property to control screen flashes on violations.
+ *
+ * @hide
+ */
+ public static final String VISUAL_PROPERTY = "persist.sys.strictmode.visual";
+
// Only log a duplicate stack trace to the logs every second.
private static final long MIN_LOG_INTERVAL_MS = 1000;
@@ -711,29 +719,66 @@ public final class StrictMode {
return new ThreadPolicy(oldPolicyMask);
}
+ // We don't want to flash the screen red in the system server
+ // process, nor do we want to modify all the call sites of
+ // conditionallyEnableDebugLogging() in the system server,
+ // so instead we use this to determine if we are the system server.
+ private static boolean amTheSystemServerProcess() {
+ // Fast path. Most apps don't have the system server's UID.
+ if (Process.myUid() != Process.SYSTEM_UID) {
+ return false;
+ }
+
+ // The settings app, though, has the system server's UID so
+ // look up our stack to see if we came from the system server.
+ Throwable stack = new Throwable();
+ stack.fillInStackTrace();
+ for (StackTraceElement ste : stack.getStackTrace()) {
+ String clsName = ste.getClassName();
+ if (clsName != null && clsName.startsWith("com.android.server.")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Enable DropBox logging for debug phone builds.
*
* @hide
*/
public static boolean conditionallyEnableDebugLogging() {
+ boolean doFlashes = !amTheSystemServerProcess() &&
+ SystemProperties.getBoolean(VISUAL_PROPERTY, IS_ENG_BUILD);
+
// For debug builds, log event loop stalls to dropbox for analysis.
// Similar logic also appears in ActivityThread.java for system apps.
- if (IS_USER_BUILD) {
+ if (IS_USER_BUILD && !doFlashes) {
setCloseGuardEnabled(false);
return false;
}
- StrictMode.setThreadPolicyMask(
- StrictMode.DETECT_DISK_WRITE |
- StrictMode.DETECT_DISK_READ |
- StrictMode.DETECT_NETWORK |
- StrictMode.PENALTY_DROPBOX |
- (IS_ENG_BUILD ? StrictMode.PENALTY_FLASH : 0)
- );
- sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS |
- StrictMode.DETECT_VM_CLOSABLE_LEAKS |
- StrictMode.PENALTY_DROPBOX;
- setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
+
+ int threadPolicyMask = StrictMode.DETECT_DISK_WRITE |
+ StrictMode.DETECT_DISK_READ |
+ StrictMode.DETECT_NETWORK;
+
+ if (!IS_USER_BUILD) {
+ threadPolicyMask |= StrictMode.PENALTY_DROPBOX;
+ }
+ if (doFlashes) {
+ threadPolicyMask |= StrictMode.PENALTY_FLASH;
+ }
+
+ StrictMode.setThreadPolicyMask(threadPolicyMask);
+
+ if (IS_USER_BUILD) {
+ setCloseGuardEnabled(false);
+ } else {
+ sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS |
+ StrictMode.DETECT_VM_CLOSABLE_LEAKS |
+ StrictMode.PENALTY_DROPBOX;
+ setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
+ }
return true;
}
@@ -1091,11 +1136,15 @@ public final class StrictMode {
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
try {
- ActivityManagerNative.getDefault().
- handleApplicationStrictModeViolation(
- RuntimeInit.getApplicationObject(),
- violationMaskSubset,
- info);
+ IActivityManager am = ActivityManagerNative.getDefault();
+ if (am == null) {
+ Log.d(TAG, "No activity manager; failed to Dropbox violation.");
+ } else {
+ am.handleApplicationStrictModeViolation(
+ RuntimeInit.getApplicationObject(),
+ violationMaskSubset,
+ info);
+ }
} catch (RemoteException e) {
Log.e(TAG, "RemoteException handling StrictMode violation", e);
}
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 4a036ec..619bf8d 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -93,7 +93,7 @@ public class SystemProperties
* Get the value for the given key, returned as a boolean.
* Values 'n', 'no', '0', 'false' or 'off' are considered false.
* Values 'y', 'yes', '1', 'true' or 'on' are considered true.
- * (case insensitive).
+ * (case sensitive).
* If the key does not exist, or has any other value, then the default
* result is returned.
* @param key the key to lookup
diff --git a/core/java/android/preference/PreferenceFrameLayout.java b/core/java/android/preference/PreferenceFrameLayout.java
index 426abf0..481859e 100644
--- a/core/java/android/preference/PreferenceFrameLayout.java
+++ b/core/java/android/preference/PreferenceFrameLayout.java
@@ -45,12 +45,18 @@ public class PreferenceFrameLayout extends FrameLayout {
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.PreferenceFrameLayout, defStyle, 0);
- mTopPadding = (int) a.getDimension(
+ float density = context.getResources().getDisplayMetrics().density;
+ int defaultTopPadding = (int) (density * DEFAULT_TOP_PADDING + 0.5f);
+ int defaultBottomPadding = (int) (density * DEFAULT_BOTTOM_PADDING + 0.5f);
+
+ mTopPadding = a.getDimensionPixelSize(
com.android.internal.R.styleable.PreferenceFrameLayout_topPadding,
- DEFAULT_TOP_PADDING);
- mBottomPadding = (int) a.getDimension(
+ defaultTopPadding);
+ mBottomPadding = a.getDimensionPixelSize(
com.android.internal.R.styleable.PreferenceFrameLayout_bottomPadding,
- DEFAULT_BOTTOM_PADDING);
+ defaultBottomPadding);
+
+
a.recycle();
}
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index ff769ad..683e603 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -382,6 +382,27 @@ public final class Downloads {
*/
public static final String COLUMN_ERROR_MSG = "errorMsg";
+ /**
+ * This column stores the source of the last update to this row.
+ * This column is only for internal use.
+ * Valid values are indicated by LAST_UPDATESRC_* constants.
+ * <P>Type: INT</P>
+ */
+ public static final String COLUMN_LAST_UPDATESRC = "lastUpdateSrc";
+
+ /**
+ * default value for {@link #COLUMN_LAST_UPDATESRC}.
+ * This value is used when this column's value is not relevant.
+ */
+ public static final int LAST_UPDATESRC_NOT_RELEVANT = 0;
+
+ /**
+ * One of the values taken by {@link #COLUMN_LAST_UPDATESRC}.
+ * This value is used when the update is NOT to be relayed to the DownloadService
+ * (and thus spare DownloadService from scanning the database when this change occurs)
+ */
+ public static final int LAST_UPDATESRC_DONT_NOTIFY_DOWNLOADSVC = 1;
+
/*
* Lists the destinations that an application can specify for a download.
*/
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 01a6b94..398b5ae 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -541,14 +541,15 @@ public class BluetoothService extends IBluetooth.Stub {
mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 3, -1), 500);
break;
case 3:
- Log.d(TAG, "Registering opush record");
- SystemService.start("opush");
+ Log.d(TAG, "Registering pbap record");
+ SystemService.start("pbap");
mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 500);
+ mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 500);
+
break;
case 4:
- Log.d(TAG, "Registering pbap record");
- SystemService.start("pbap");
+ Log.d(TAG, "Registering opush record");
+ SystemService.start("opush");
break;
}
break;
@@ -630,8 +631,15 @@ public class BluetoothService extends IBluetooth.Stub {
initProfileState();
//Register SDP records.
- mHandler.sendMessageDelayed(
+ if (mContext.getResources().
+ getBoolean(com.android.internal.R.bool.config_voice_capable)) {
+ mHandler.sendMessageDelayed(
mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 1, -1), 3000);
+ } else {
+ // Register only OPP.
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(MESSAGE_REGISTER_SDP_RECORDS, 4, -1), 3000);
+ }
setBluetoothTetheringNative(true, BluetoothPan.NAP_ROLE, BluetoothPan.NAP_BRIDGE);
@@ -1196,6 +1204,24 @@ public class BluetoothService extends IBluetooth.Stub {
return getProperty("Name");
}
+ public synchronized ParcelUuid[] getUuids() {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ String value = getProperty("UUIDs");
+ if (value == null) return null;
+
+ String[] uuidStrings = null;
+ // The UUIDs are stored as a "," separated string.
+ uuidStrings = value.split(",");
+ ParcelUuid[] uuids = new ParcelUuid[uuidStrings.length];
+
+ for (int i = 0; i < uuidStrings.length; i++) {
+ uuids[i] = ParcelUuid.fromString(uuidStrings[i]);
+ }
+ return uuids;
+
+ }
+
+
/**
* Returns the user-friendly name of a remote device. This value is
* returned from our local cache, which is updated when onPropertyChange
diff --git a/core/java/android/util/PrefixPrinter.java b/core/java/android/util/PrefixPrinter.java
new file mode 100644
index 0000000..62f7da1
--- /dev/null
+++ b/core/java/android/util/PrefixPrinter.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 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.util;
+
+/**
+ * PrefixPrinter is a Printer which prefixes all lines with a given
+ * prefix.
+ *
+ * @hide
+ */
+public class PrefixPrinter implements Printer {
+ private final Printer mPrinter;
+ private final String mPrefix;
+
+ /**
+ * Creates a new PrefixPrinter.
+ *
+ * <p>If prefix is null or empty, the provided printer is returned, rather
+ * than making a prefixing printer.
+ */
+ public static Printer create(Printer printer, String prefix) {
+ if (prefix == null || prefix.equals("")) {
+ return printer;
+ }
+ return new PrefixPrinter(printer, prefix);
+ }
+
+ private PrefixPrinter(Printer printer, String prefix) {
+ mPrinter = printer;
+ mPrefix = prefix;
+ }
+
+ public void println(String str) {
+ mPrinter.println(mPrefix + str);
+ }
+}
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index 60ca384..85ce5e1 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -158,18 +158,17 @@ public class TimeUtils {
static private int printField(char[] formatStr, int amt, char suffix, int pos,
boolean always, int zeropad) {
if (always || amt > 0) {
+ final int startPos = pos;
if ((always && zeropad >= 3) || amt > 99) {
int dig = amt/100;
formatStr[pos] = (char)(dig + '0');
pos++;
- always = true;
amt -= (dig*100);
}
- if ((always && zeropad >= 2) || amt > 9) {
+ if ((always && zeropad >= 2) || amt > 9 || startPos != pos) {
int dig = amt/10;
formatStr[pos] = (char)(dig + '0');
pos++;
- always = true;
amt -= (dig*10);
}
formatStr[pos] = (char)(amt + '0');
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index d964e2f..beda099 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -140,6 +140,12 @@ interface IWindowManager
// on screen)
void showStrictModeViolation(boolean on);
+ // Proxy to set the system property for whether the flashing
+ // should be enabled. The 'enabled' value is null or blank for
+ // the system default (differs per build variant) or any valid
+ // boolean string as parsed by SystemProperties.getBoolean().
+ void setStrictModeVisualIndicatorPreference(String enabled);
+
// These can only be called with the SET_ORIENTATION permission.
/**
* Change the current screen rotation, constants as per
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index d596a7f..e967522 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -374,6 +374,19 @@ public class Surface implements Parcelable {
}
/**
+ * Copy the current screen contents into a bitmap and return it.
+ *
+ * @param width The desired width of the returned bitmap; the raw
+ * screen will be scaled down to this size.
+ * @param height The desired height of the returned bitmap; the raw
+ * screen will be scaled down to this size.
+ * @return Returns a Bitmap containing the screen contents.
+ *
+ * @hide
+ */
+ public static native Bitmap screenshot(int width, int height);
+
+ /**
* set surface parameters.
* needs to be inside open/closeTransaction block
*/
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 784951f..51016f5 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -171,6 +171,7 @@ public interface WindowManager extends ViewManager {
@ViewDebug.IntToString(from = TYPE_SYSTEM_OVERLAY, to = "TYPE_SYSTEM_OVERLAY"),
@ViewDebug.IntToString(from = TYPE_PRIORITY_PHONE, to = "TYPE_PRIORITY_PHONE"),
@ViewDebug.IntToString(from = TYPE_STATUS_BAR_PANEL, to = "TYPE_STATUS_BAR_PANEL"),
+ @ViewDebug.IntToString(from = TYPE_STATUS_BAR_SUB_PANEL, to = "TYPE_STATUS_BAR_SUB_PANEL"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_DIALOG, to = "TYPE_SYSTEM_DIALOG"),
@ViewDebug.IntToString(from = TYPE_KEYGUARD_DIALOG, to = "TYPE_KEYGUARD_DIALOG"),
@ViewDebug.IntToString(from = TYPE_SYSTEM_ERROR, to = "TYPE_SYSTEM_ERROR"),
@@ -351,7 +352,7 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13;
/**
- * Window type: panel that slides out from the status bar
+ * Window type: panel that slides out from over the status bar
*/
public static final int TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14;
@@ -375,6 +376,13 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_DRAG = FIRST_SYSTEM_WINDOW+16;
/**
+ * Window type: panel that slides out from under the status bar
+ * @hide
+ */
+ public static final int TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17;
+
+
+ /**
* End of types of system windows.
*/
public static final int LAST_SYSTEM_WINDOW = 2999;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 621a908..9bc1c22 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1278,10 +1278,10 @@ public final class InputMethodManager {
}
}
}
-
+
/**
- * Force switch to a new input method component. This can only be called
- * from the currently active input method, as validated by the given token.
+ * Force switch to a new input method component. This can only be called
+ * from an application or a service which has a token of the currently active input method.
* @param token Supplies the identifying token given to an input method
* when it was started, which allows it to perform this operation on
* itself.
@@ -1294,7 +1294,24 @@ public final class InputMethodManager {
throw new RuntimeException(e);
}
}
-
+
+ /**
+ * Force switch to a new input method and subtype. This can only be called
+ * from an application or a service which has a token of the currently active input method.
+ * @param token Supplies the identifying token given to an input method
+ * when it was started, which allows it to perform this operation on
+ * itself.
+ * @param id The unique identifier for the new input method to be switched to.
+ * @param subtype The new subtype of the new input method to be switched to.
+ */
+ public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) {
+ try {
+ mService.setInputMethodAndSubtype(token, id, subtype);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
/**
* Close/hide the input method's soft input area, so the user no longer
* sees it or can interact with it. This can only be called
diff --git a/core/java/android/webkit/OverScrollGlow.java b/core/java/android/webkit/OverScrollGlow.java
index 53600f6..af56a2f 100644
--- a/core/java/android/webkit/OverScrollGlow.java
+++ b/core/java/android/webkit/OverScrollGlow.java
@@ -17,6 +17,7 @@ package android.webkit;
import com.android.internal.R;
+import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
@@ -40,13 +41,14 @@ public class OverScrollGlow {
public OverScrollGlow(WebView host) {
mHostView = host;
- final Resources res = host.getContext().getResources();
+ Context context = host.getContext();
+ final Resources res = context.getResources();
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
- mEdgeGlowTop = new EdgeGlow(edge, glow);
- mEdgeGlowBottom = new EdgeGlow(edge, glow);
- mEdgeGlowLeft = new EdgeGlow(edge, glow);
- mEdgeGlowRight = new EdgeGlow(edge, glow);
+ mEdgeGlowTop = new EdgeGlow(context, edge, glow);
+ mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
+ mEdgeGlowLeft = new EdgeGlow(context, edge, glow);
+ mEdgeGlowRight = new EdgeGlow(context, edge, glow);
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9b519c2..56325f6 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3050,10 +3050,10 @@ public class WebView extends AbsoluteLayout
} else {
mScrollX = x;
mScrollY = y;
- if (mScroller.getStartX() != mScrollX || mScroller.getStartY() != mScrollY) {
- abortAnimation();
- mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
- WebViewCore.resumePriority();
+ abortAnimation();
+ mPrivateHandler.removeMessages(RESUME_WEBCORE_PRIORITY);
+ WebViewCore.resumePriority();
+ if (!mSelectingText) {
WebViewCore.resumeUpdatePicture(mWebViewCore);
}
}
@@ -3820,7 +3820,9 @@ public class WebView extends AbsoluteLayout
}
void onFixedLengthZoomAnimationEnd() {
- WebViewCore.resumeUpdatePicture(mWebViewCore);
+ if (!mSelectingText) {
+ WebViewCore.resumeUpdatePicture(mWebViewCore);
+ }
onZoomAnimationEnd();
}
@@ -4649,6 +4651,7 @@ public class WebView extends AbsoluteLayout
// called by mSelectCallback.onDestroyActionMode
mSelectCallback.finish();
mSelectCallback = null;
+ WebViewCore.resumePriority();
WebViewCore.resumeUpdatePicture(mWebViewCore);
invalidate(); // redraw without selection
}
@@ -5554,7 +5557,9 @@ public class WebView extends AbsoluteLayout
// is possible on emulator.
mLastVelocity = 0;
WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
+ if (!mSelectingText) {
+ WebViewCore.resumeUpdatePicture(mWebViewCore);
+ }
break;
}
stopTouch();
@@ -5683,8 +5688,8 @@ public class WebView extends AbsoluteLayout
mVelocityTracker = null;
}
- if (mTouchMode == TOUCH_DRAG_MODE ||
- mTouchMode == TOUCH_DRAG_LAYER_MODE) {
+ if ((mTouchMode == TOUCH_DRAG_MODE
+ || mTouchMode == TOUCH_DRAG_LAYER_MODE) && !mSelectingText) {
WebViewCore.resumePriority();
WebViewCore.resumeUpdatePicture(mWebViewCore);
}
@@ -6055,7 +6060,9 @@ public class WebView extends AbsoluteLayout
}
if ((maxX == 0 && vy == 0) || (maxY == 0 && vx == 0)) {
WebViewCore.resumePriority();
- WebViewCore.resumeUpdatePicture(mWebViewCore);
+ if (!mSelectingText) {
+ WebViewCore.resumeUpdatePicture(mWebViewCore);
+ }
if (mScroller.springBack(mScrollX, mScrollY, 0, computeMaxScrollX(),
0, computeMaxScrollY())) {
invalidate();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 423a788..4ff7ee8 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -132,7 +132,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* Indicates the touch gesture is a scroll
*/
static final int TOUCH_MODE_SCROLL = 3;
-
+
/**
* Indicates the view is in the process of being flung
*/
@@ -385,7 +385,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* Handles one frame of a fling
*/
private FlingRunnable mFlingRunnable;
-
+
/**
* Handles scrolling between positions within the list.
*/
@@ -456,7 +456,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
int mResurrectToPosition = INVALID_POSITION;
private ContextMenuInfo mContextMenuInfo = null;
-
+
/**
* Maximum distance to record overscroll
*/
@@ -550,19 +550,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mMinimumVelocity;
private int mMaximumVelocity;
private float mVelocityScale = 1.0f;
-
+
final boolean[] mIsScrap = new boolean[1];
-
+
// True when the popup should be hidden because of a call to
// dispatchDisplayHint()
private boolean mPopupHidden;
-
+
/**
* ID of the active pointer. This is used to retain consistency during
* drags/flings if multiple pointers are used.
*/
private int mActivePointerId = INVALID_POINTER;
-
+
/**
* Sentinel value for no current active pointer.
* Used by {@link #mActivePointerId}.
@@ -726,7 +726,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
boolean smoothScrollbar = a.getBoolean(R.styleable.AbsListView_smoothScrollbar, true);
setSmoothScrollbarEnabled(smoothScrollbar);
-
+
final int adapterId = a.getResourceId(R.styleable.AbsListView_adapter, 0);
if (adapterId != 0) {
final Context c = context;
@@ -764,11 +764,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
public void setOverScrollMode(int mode) {
if (mode != OVER_SCROLL_NEVER) {
if (mEdgeGlowTop == null) {
- final Resources res = getContext().getResources();
+ Context context = getContext();
+ final Resources res = context.getResources();
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
- mEdgeGlowTop = new EdgeGlow(edge, glow);
- mEdgeGlowBottom = new EdgeGlow(edge, glow);
+ mEdgeGlowTop = new EdgeGlow(context, edge, glow);
+ mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
}
} else {
mEdgeGlowTop = null;
@@ -1843,7 +1844,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* @param position The position to display
* @param isScrap Array of at least 1 boolean, the first entry will become true if
* the returned view was taken from the scrap heap, false if otherwise.
- *
+ *
* @return A view displaying the data associated with the specified position
*/
View obtainView(int position, boolean[] isScrap) {
@@ -2166,7 +2167,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
treeObserver.addOnGlobalLayoutListener(this);
}
}
-
+
if (mAdapter != null && mDataSetObserver == null) {
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
@@ -2962,7 +2963,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mFlingRunnable = new FlingRunnable();
}
reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
-
+
mFlingRunnable.start(-initialVelocity);
} else {
mTouchMode = TOUCH_MODE_REST;
@@ -3015,7 +3016,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mVelocityTracker.recycle();
mVelocityTracker = null;
}
-
+
mActivePointerId = INVALID_POINTER;
if (PROFILE_SCROLLING) {
@@ -3064,7 +3065,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mVelocityTracker = null;
}
}
-
+
if (mEdgeGlowTop != null) {
mEdgeGlowTop.onRelease();
mEdgeGlowBottom.onRelease();
@@ -3072,7 +3073,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mActivePointerId = INVALID_POINTER;
break;
}
-
+
case MotionEvent.ACTION_POINTER_UP: {
onSecondaryPointerUp(ev);
final int x = mMotionX;
@@ -3170,11 +3171,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mMotionCorrection = 0;
return true;
}
-
+
final int x = (int) ev.getX();
final int y = (int) ev.getY();
mActivePointerId = ev.getPointerId(0);
-
+
int motionPosition = findMotionRow(y);
if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) {
// User clicked on an actual view (and was not stopping a fling).
@@ -3213,7 +3214,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
break;
}
-
+
case MotionEvent.ACTION_POINTER_UP: {
onSecondaryPointerUp(ev);
break;
@@ -3222,7 +3223,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return false;
}
-
+
private void onSecondaryPointerUp(MotionEvent ev) {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
@@ -3418,7 +3419,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
default:
endFling();
return;
-
+
case TOUCH_MODE_SCROLL:
if (mScroller.isFinished()) {
return;
@@ -3521,17 +3522,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
-
-
+
+
class PositionScroller implements Runnable {
private static final int SCROLL_DURATION = 400;
-
+
private static final int MOVE_DOWN_POS = 1;
private static final int MOVE_UP_POS = 2;
private static final int MOVE_DOWN_BOUND = 3;
private static final int MOVE_UP_BOUND = 4;
private static final int MOVE_OFFSET = 5;
-
+
private int mMode;
private int mTargetPos;
private int mBoundPos;
@@ -3540,17 +3541,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private final int mExtraScroll;
private int mOffsetFromTop;
-
+
PositionScroller() {
mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
}
-
+
void start(int position) {
final int firstPos = mFirstPosition;
final int lastPos = firstPos + getChildCount() - 1;
-
+
int viewTravelCount;
- if (position <= firstPos) {
+ if (position <= firstPos) {
viewTravelCount = firstPos - position + 1;
mMode = MOVE_UP_POS;
} else if (position >= lastPos) {
@@ -3560,7 +3561,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Already on screen, nothing to do
return;
}
-
+
if (viewTravelCount > 0) {
mScrollDuration = SCROLL_DURATION / viewTravelCount;
} else {
@@ -3569,19 +3570,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mTargetPos = position;
mBoundPos = INVALID_POSITION;
mLastSeenPos = INVALID_POSITION;
-
+
post(this);
}
-
+
void start(int position, int boundPosition) {
if (boundPosition == INVALID_POSITION) {
start(position);
return;
}
-
+
final int firstPos = mFirstPosition;
final int lastPos = firstPos + getChildCount() - 1;
-
+
int viewTravelCount;
if (position <= firstPos) {
final int boundPosFromLast = lastPos - boundPosition;
@@ -3589,7 +3590,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Moving would shift our bound position off the screen. Abort.
return;
}
-
+
final int posTravel = firstPos - position + 1;
final int boundTravel = boundPosFromLast - 1;
if (boundTravel < posTravel) {
@@ -3619,7 +3620,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Already on screen, nothing to do
return;
}
-
+
if (viewTravelCount > 0) {
mScrollDuration = SCROLL_DURATION / viewTravelCount;
} else {
@@ -3628,7 +3629,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mTargetPos = position;
mBoundPos = boundPosition;
mLastSeenPos = INVALID_POSITION;
-
+
post(this);
}
@@ -3679,12 +3680,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int listHeight = getHeight();
final int firstPos = mFirstPosition;
-
+
switch (mMode) {
case MOVE_DOWN_POS: {
final int lastViewIndex = getChildCount() - 1;
final int lastPos = firstPos + lastViewIndex;
-
+
if (lastViewIndex < 0) {
return;
}
@@ -3710,11 +3711,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
break;
}
-
+
case MOVE_DOWN_BOUND: {
final int nextViewIndex = 1;
final int childCount = getChildCount();
-
+
if (firstPos == mBoundPos || childCount <= nextViewIndex
|| firstPos + childCount >= mItemCount) {
return;
@@ -3739,13 +3740,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
post(this);
} else {
- if (nextViewTop > extraScroll) {
+ if (nextViewTop > extraScroll) {
smoothScrollBy(nextViewTop - extraScroll, mScrollDuration);
}
}
break;
}
-
+
case MOVE_UP_POS: {
if (firstPos == mLastSeenPos) {
// No new views, let things keep going.
@@ -3769,7 +3770,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
break;
}
-
+
case MOVE_UP_BOUND: {
final int lastViewIndex = getChildCount() - 2;
if (lastViewIndex < 0) {
@@ -3835,11 +3836,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
-
+
/**
* The amount of friction applied to flings. The default value
* is {@link ViewConfiguration#getScrollFriction}.
- *
+ *
* @return A scalar dimensionless value representing the coefficient of
* friction.
*/
@@ -3847,19 +3848,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (mFlingRunnable == null) {
mFlingRunnable = new FlingRunnable();
}
- mFlingRunnable.mScroller.setFriction(friction);
+ mFlingRunnable.mScroller.setFriction(friction);
}
/**
* Sets a scale factor for the fling velocity. The initial scale
* factor is 1.0.
- *
+ *
* @param scale The scale factor to multiply the velocity by.
*/
public void setVelocityScale(float scale) {
mVelocityScale = scale;
}
-
+
/**
* Smoothly scroll to the specified adapter position. The view will
* scroll such that the indicated position is displayed.
@@ -3913,7 +3914,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
* Smoothly scroll to the specified adapter position. The view will
* scroll such that the indicated position is displayed, but it will
* stop early if scrolling further would scroll boundPosition out of
- * view.
+ * view.
* @param position Scroll to this adapter position.
* @param boundPosition Do not scroll if it would move this adapter
* position out of view.
@@ -3924,7 +3925,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
mPositionScroller.start(position, boundPosition);
}
-
+
/**
* Smoothly scroll by distance pixels over duration milliseconds.
* @param distance Distance to scroll in pixels.
@@ -4145,7 +4146,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (down) {
mFirstPosition += count;
}
-
+
invalidate();
final int absIncrementalDeltaY = Math.abs(incrementalDeltaY);
@@ -4171,7 +4172,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
invokeOnItemScrollListener();
awakenScrollBars();
-
+
return false;
}
@@ -5289,7 +5290,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mCurrentScrap = scrapViews[0];
mScrapViews = scrapViews;
}
-
+
public void markChildrenDirty() {
if (mViewTypeCount == 1) {
final ArrayList<View> scrap = mCurrentScrap;
diff --git a/core/java/android/widget/EdgeGlow.java b/core/java/android/widget/EdgeGlow.java
index 9b3a6e6..2a0e849 100644
--- a/core/java/android/widget/EdgeGlow.java
+++ b/core/java/android/widget/EdgeGlow.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.animation.AnimationUtils;
@@ -44,7 +45,7 @@ public class EdgeGlow {
private static final float HELD_GLOW_ALPHA = 0.5f;
private static final float HELD_GLOW_SCALE_Y = 0.5f;
- private static final float MAX_GLOW_HEIGHT = 3.f;
+ private static final float MAX_GLOW_HEIGHT = 4.f;
private static final float PULL_GLOW_BEGIN = 1.f;
private static final float PULL_EDGE_BEGIN = 0.6f;
@@ -58,6 +59,8 @@ public class EdgeGlow {
private final Drawable mGlow;
private int mWidth;
private int mHeight;
+ private final int MIN_WIDTH = 300;
+ private final int mMinWidth;
private float mEdgeAlpha;
private float mEdgeScaleY;
@@ -86,12 +89,12 @@ public class EdgeGlow {
// How much dragging should effect the height of the edge image.
// Number determined by user testing.
- private static final int PULL_DISTANCE_EDGE_FACTOR = 5;
+ private static final int PULL_DISTANCE_EDGE_FACTOR = 7;
// How much dragging should effect the height of the glow image.
// Number determined by user testing.
- private static final int PULL_DISTANCE_GLOW_FACTOR = 5;
- private static final float PULL_DISTANCE_ALPHA_GLOW_FACTOR = 0.8f;
+ private static final int PULL_DISTANCE_GLOW_FACTOR = 7;
+ private static final float PULL_DISTANCE_ALPHA_GLOW_FACTOR = 1.1f;
private static final int VELOCITY_EDGE_FACTOR = 8;
private static final int VELOCITY_GLOW_FACTOR = 16;
@@ -100,10 +103,11 @@ public class EdgeGlow {
private float mPullDistance;
- public EdgeGlow(Drawable edge, Drawable glow) {
+ public EdgeGlow(Context context, Drawable edge, Drawable glow) {
mEdge = edge;
mGlow = glow;
+ mMinWidth = (int) (context.getResources().getDisplayMetrics().density * MIN_WIDTH + 0.5f);
mInterpolator = new DecelerateInterpolator();
}
@@ -251,17 +255,31 @@ public class EdgeGlow {
mGlow.setAlpha((int) (Math.max(0, Math.min(mGlowAlpha, 1)) * 255));
- // Center the glow inside the width of the container.
- int glowLeft = (mWidth - glowWidth)/2;
- mGlow.setBounds(glowLeft, 0, mWidth - glowLeft, (int) Math.min(
+ int glowBottom = (int) Math.min(
glowHeight * mGlowScaleY * glowHeight/ glowWidth * 0.6f,
- glowHeight * MAX_GLOW_HEIGHT));
+ glowHeight * MAX_GLOW_HEIGHT);
+ if (mWidth < mMinWidth) {
+ // Center the glow and clip it.
+ int glowLeft = (mWidth - glowWidth)/2;
+ mGlow.setBounds(glowLeft, 0, mWidth - glowLeft, glowBottom);
+ } else {
+ // Stretch the glow to fit.
+ mGlow.setBounds(0, 0, mWidth, glowBottom);
+ }
+
mGlow.draw(canvas);
mEdge.setAlpha((int) (Math.max(0, Math.min(mEdgeAlpha, 1)) * 255));
- int edgeLeft = (mWidth - edgeWidth)/2;
- mEdge.setBounds(edgeLeft, 0, mWidth - edgeLeft, (int) (edgeHeight * mEdgeScaleY));
+ int edgeBottom = (int) (edgeHeight * mEdgeScaleY);
+ if (mWidth < mMinWidth) {
+ // Center the edge and clip it.
+ int edgeLeft = (mWidth - edgeWidth)/2;
+ mEdge.setBounds(edgeLeft, 0, mWidth - edgeLeft, edgeBottom);
+ } else {
+ // Stretch the edge to fit.
+ mEdge.setBounds(0, 0, mWidth, edgeBottom);
+ }
mEdge.draw(canvas);
return mState != STATE_IDLE;
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 9fc91da..c05e3ad 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -58,8 +58,8 @@ import java.util.List;
* within a larger container.
*
* <p>HorizontalScrollView only supports horizontal scrolling.
- *
- * @attr ref android.R.styleable#HorizontalScrollView_fillViewport
+ *
+ * @attr ref android.R.styleable#HorizontalScrollView_fillViewport
*/
public class HorizontalScrollView extends FrameLayout {
private static final int ANIMATED_SCROLL_GAP = ScrollView.ANIMATED_SCROLL_GAP;
@@ -125,7 +125,7 @@ public class HorizontalScrollView extends FrameLayout {
private int mTouchSlop;
private int mMinimumVelocity;
private int mMaximumVelocity;
-
+
private int mOverscrollDistance;
private int mOverflingDistance;
@@ -134,13 +134,13 @@ public class HorizontalScrollView extends FrameLayout {
* drags/flings if multiple pointers are used.
*/
private int mActivePointerId = INVALID_POINTER;
-
+
/**
* Sentinel value for no current active pointer.
* Used by {@link #mActivePointerId}.
*/
private static final int INVALID_POINTER = -1;
-
+
public HorizontalScrollView(Context context) {
this(context, null);
}
@@ -279,7 +279,7 @@ public class HorizontalScrollView extends FrameLayout {
*
* @param fillViewport True to stretch the content's width to the viewport's
* boundaries, false otherwise.
- *
+ *
* @attr ref android.R.styleable#HorizontalScrollView_fillViewport
*/
public void setFillViewport(boolean fillViewport) {
@@ -322,13 +322,13 @@ public class HorizontalScrollView extends FrameLayout {
int width = getMeasuredWidth();
if (child.getMeasuredWidth() < width) {
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
+
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, mPaddingTop
+ mPaddingBottom, lp.height);
width -= mPaddingLeft;
width -= mPaddingRight;
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
-
+
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
@@ -400,7 +400,7 @@ public class HorizontalScrollView extends FrameLayout {
}
return false;
}
-
+
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
/*
@@ -453,7 +453,7 @@ public class HorizontalScrollView extends FrameLayout {
mIsBeingDragged = false;
break;
}
-
+
/*
* Remember location of down touch.
* ACTION_DOWN always refers to pointer index 0.
@@ -581,7 +581,7 @@ public class HorizontalScrollView extends FrameLayout {
}
}
}
-
+
mActivePointerId = INVALID_POINTER;
mIsBeingDragged = false;
@@ -618,7 +618,7 @@ public class HorizontalScrollView extends FrameLayout {
}
return true;
}
-
+
private void onSecondaryPointerUp(MotionEvent ev) {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
@@ -635,7 +635,7 @@ public class HorizontalScrollView extends FrameLayout {
}
}
}
-
+
@Override
protected void onOverScrolled(int scrollX, int scrollY,
boolean clampedX, boolean clampedY) {
@@ -917,7 +917,7 @@ public class HorizontalScrollView extends FrameLayout {
if (direction == View.FOCUS_LEFT && getScrollX() < scrollDelta) {
scrollDelta = getScrollX();
} else if (direction == View.FOCUS_RIGHT && getChildCount() > 0) {
-
+
int daRight = getChildAt(0).getRight();
int screenRight = getScrollX() + getWidth();
@@ -1033,7 +1033,7 @@ public class HorizontalScrollView extends FrameLayout {
if (count == 0) {
return contentWidth;
}
-
+
int scrollRange = getChildAt(0).getRight();
final int scrollX = mScrollX;
final int overscrollRight = Math.max(0, scrollRange - contentWidth);
@@ -1045,7 +1045,7 @@ public class HorizontalScrollView extends FrameLayout {
return scrollRange;
}
-
+
@Override
protected int computeHorizontalScrollOffset() {
return Math.max(0, super.computeHorizontalScrollOffset());
@@ -1352,25 +1352,25 @@ public class HorizontalScrollView extends FrameLayout {
if (getChildCount() > 0) {
int width = getWidth() - mPaddingRight - mPaddingLeft;
int right = getChildAt(0).getWidth();
-
- mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
+
+ mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
Math.max(0, right - width), 0, 0, width/2, 0);
-
+
final boolean movingRight = velocityX > 0;
-
+
View newFocused = findFocusableViewInMyBounds(movingRight,
mScroller.getFinalX(), findFocus());
-
+
if (newFocused == null) {
newFocused = this;
}
-
+
if (newFocused != findFocus()
&& newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT)) {
mScrollViewMovedFocus = true;
mScrollViewMovedFocus = false;
}
-
+
invalidate();
}
}
@@ -1396,11 +1396,12 @@ public class HorizontalScrollView extends FrameLayout {
public void setOverScrollMode(int mode) {
if (mode != OVER_SCROLL_NEVER) {
if (mEdgeGlowLeft == null) {
- final Resources res = getContext().getResources();
+ Context context = getContext();
+ final Resources res = context.getResources();
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
- mEdgeGlowLeft = new EdgeGlow(edge, glow);
- mEdgeGlowRight = new EdgeGlow(edge, glow);
+ mEdgeGlowLeft = new EdgeGlow(context, edge, glow);
+ mEdgeGlowRight = new EdgeGlow(context, edge, glow);
}
} else {
mEdgeGlowLeft = null;
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 900c9ec..9fa90dc 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -51,7 +51,7 @@ import java.util.List;
* takes care of its own scrolling, so does not require a ScrollView, but
* using the two together is possible to achieve the effect of a text view
* within a larger container.
- *
+ *
* <p>ScrollView only supports vertical scrolling.
*
* @attr ref android.R.styleable#ScrollView_fillViewport
@@ -120,7 +120,7 @@ public class ScrollView extends FrameLayout {
private int mTouchSlop;
private int mMinimumVelocity;
private int mMaximumVelocity;
-
+
private int mOverscrollDistance;
private int mOverflingDistance;
@@ -269,7 +269,7 @@ public class ScrollView extends FrameLayout {
* Indicates whether this ScrollView's content is stretched to fill the viewport.
*
* @return True if the content fills the viewport, false otherwise.
- *
+ *
* @attr ref android.R.styleable#ScrollView_fillViewport
*/
public boolean isFillViewport() {
@@ -282,7 +282,7 @@ public class ScrollView extends FrameLayout {
*
* @param fillViewport True to stretch the content's height to the viewport's
* boundaries, false otherwise.
- *
+ *
* @attr ref android.R.styleable#ScrollView_fillViewport
*/
public void setFillViewport(boolean fillViewport) {
@@ -325,14 +325,14 @@ public class ScrollView extends FrameLayout {
int height = getMeasuredHeight();
if (child.getMeasuredHeight() < height) {
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
+
int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, mPaddingLeft
+ mPaddingRight, lp.width);
height -= mPaddingTop;
height -= mPaddingBottom;
int childHeightMeasureSpec =
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
-
+
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
}
@@ -521,7 +521,7 @@ public class ScrollView extends FrameLayout {
case MotionEvent.ACTION_DOWN: {
final float y = ev.getY();
mIsBeingDragged = true;
-
+
/*
* If being flinged and user touches, stop the fling. isFinished
* will be false if being flinged.
@@ -579,7 +579,7 @@ public class ScrollView extends FrameLayout {
}
}
break;
- case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_UP:
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
@@ -615,7 +615,7 @@ public class ScrollView extends FrameLayout {
}
return true;
}
-
+
private void onSecondaryPointerUp(MotionEvent ev) {
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
@@ -632,7 +632,7 @@ public class ScrollView extends FrameLayout {
}
}
}
-
+
@Override
protected void onOverScrolled(int scrollX, int scrollY,
boolean clampedX, boolean clampedY) {
@@ -919,9 +919,9 @@ public class ScrollView extends FrameLayout {
} else if (direction == View.FOCUS_DOWN) {
if (getChildCount() > 0) {
int daBottom = getChildAt(0).getBottom();
-
+
int screenBottom = getScrollY() + getHeight();
-
+
if (daBottom - screenBottom < maxJump) {
scrollDelta = daBottom - screenBottom;
}
@@ -1038,7 +1038,7 @@ public class ScrollView extends FrameLayout {
if (count == 0) {
return contentHeight;
}
-
+
int scrollRange = getChildAt(0).getBottom();
final int scrollY = mScrollY;
final int overscrollBottom = Math.max(0, scrollRange - contentHeight);
@@ -1289,7 +1289,7 @@ public class ScrollView extends FrameLayout {
}
return nextFocus.requestFocus(direction, previouslyFocusedRect);
- }
+ }
@Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
@@ -1325,7 +1325,7 @@ public class ScrollView extends FrameLayout {
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mIsLayoutDirty = false;
- // Give a child focus if it needs it
+ // Give a child focus if it needs it
if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
scrollToChild(mChildToScrollTo);
}
@@ -1352,7 +1352,7 @@ public class ScrollView extends FrameLayout {
int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
doScrollY(scrollDelta);
}
- }
+ }
/**
* Return true if child is an descendant of parent, (or equal to the parent).
@@ -1364,7 +1364,7 @@ public class ScrollView extends FrameLayout {
final ViewParent theParent = child.getParent();
return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
- }
+ }
/**
* Fling the scroll view
@@ -1377,18 +1377,18 @@ public class ScrollView extends FrameLayout {
if (getChildCount() > 0) {
int height = getHeight() - mPaddingBottom - mPaddingTop;
int bottom = getChildAt(0).getHeight();
-
- mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
+
+ mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
Math.max(0, bottom - height), 0, height/2);
-
+
final boolean movingDown = velocityY > 0;
-
+
View newFocused =
findFocusableViewInMyBounds(movingDown, mScroller.getFinalY(), findFocus());
if (newFocused == null) {
newFocused = this;
}
-
+
if (newFocused != findFocus()
&& newFocused.requestFocus(movingDown ? View.FOCUS_DOWN : View.FOCUS_UP)) {
mScrollViewMovedFocus = true;
@@ -1444,11 +1444,12 @@ public class ScrollView extends FrameLayout {
public void setOverScrollMode(int mode) {
if (mode != OVER_SCROLL_NEVER) {
if (mEdgeGlowTop == null) {
- final Resources res = getContext().getResources();
+ Context context = getContext();
+ final Resources res = context.getResources();
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
- mEdgeGlowTop = new EdgeGlow(edge, glow);
- mEdgeGlowBottom = new EdgeGlow(edge, glow);
+ mEdgeGlowTop = new EdgeGlow(context, edge, glow);
+ mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
}
} else {
mEdgeGlowTop = null;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 78f3cd9..5e4a514 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -313,6 +313,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Drawable mSelectHandleRight;
Drawable mSelectHandleCenter;
+ private int mLastDownPositionX, mLastDownPositionY;
+
/*
* Kick-start the font cache for the zygote process (to pay the cost of
* initializing freetype for our default font only once).
@@ -3839,20 +3841,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
boolean changed = false;
- SelectionModifierCursorController selectionController = null;
- if (mSelectionModifierCursorController != null) {
- selectionController = (SelectionModifierCursorController)
- mSelectionModifierCursorController;
- }
-
-
if (mMovement != null) {
/* This code also provides auto-scrolling when a cursor is moved using a
* CursorController (insertion point or selection limits).
* For selection, ensure start or end is visible depending on controller's state.
*/
int curs = getSelectionEnd();
- if (selectionController != null && selectionController.isSelectionStartDragged()) {
+ // Do not create the controller if it is not already created.
+ if (mSelectionModifierCursorController != null &&
+ mSelectionModifierCursorController.isSelectionStartDragged()) {
curs = getSelectionStart();
}
@@ -3879,7 +3876,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// - ExtractEditText does not call onFocus when it is displayed. Fixing this issue would
// allow to test for hasSelection in onFocusChanged, which would trigger a
// startTextSelectionMode here. TODO
- if (this instanceof ExtractEditText && selectionController != null && hasSelection()) {
+ if (this instanceof ExtractEditText && hasSelection() && hasSelectionController()) {
startSelectionActionMode();
}
@@ -3900,6 +3897,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final ViewTreeObserver observer = getViewTreeObserver();
if (observer != null) {
+ // No need to create the controller.
+ // The get method will add the listener on controller creation.
if (mInsertionPointCursorController != null) {
observer.addOnTouchModeChangeListener(mInsertionPointCursorController);
}
@@ -3919,6 +3918,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
observer.removeOnPreDrawListener(this);
mPreDrawState = PREDRAW_NOT_REGISTERED;
}
+ // No need to create the controller, as getXXController would.
if (mInsertionPointCursorController != null) {
observer.removeOnTouchModeChangeListener(mInsertionPointCursorController);
}
@@ -4396,6 +4396,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
protected void updateCursorControllerPositions() {
+ // No need to create the controllers if they were not already
if (mInsertionPointCursorController != null &&
mInsertionPointCursorController.isShowing()) {
mInsertionPointCursorController.updatePosition();
@@ -6906,8 +6907,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
terminateSelectionActionMode();
}
+ // No need to create the controller
if (mSelectionModifierCursorController != null) {
- ((SelectionModifierCursorController) mSelectionModifierCursorController).resetTouchOffsets();
+ mSelectionModifierCursorController.resetTouchOffsets();
}
}
@@ -6921,9 +6923,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private int getLastTapPosition() {
+ // No need to create the controller at that point, no last tap position saved
if (mSelectionModifierCursorController != null) {
- int lastTapPosition = ((SelectionModifierCursorController)
- mSelectionModifierCursorController).getMinTouchOffset();
+ int lastTapPosition = mSelectionModifierCursorController.getMinTouchOffset();
if (lastTapPosition >= 0) {
// Safety check, should not be possible.
if (lastTapPosition > mText.length()) {
@@ -7009,8 +7011,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Restore previous selection
Selection.setSelection((Spannable)mText, prevStart, prevEnd);
- if (hasSelectionController() && !getSelectionController().isShowing()) {
- // If the anchors aren't showing, revive them.
+ if (hasSelectionController()) {
+ // Revive the anchors.
getSelectionController().show();
}
return;
@@ -7065,6 +7067,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (action == MotionEvent.ACTION_DOWN) {
+ mLastDownPositionX = (int) event.getX();
+ mLastDownPositionY = (int) event.getY();
+
// Reset this state; it will be re-set if super.onTouchEvent
// causes focus to move to the view.
mTouchFocusSelected = false;
@@ -7102,6 +7107,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mScrollX != oldScrollX || mScrollY != oldScrollY) {
// Hide insertion anchor while scrolling. Leave selection.
hideInsertionPointCursorController();
+ // No need to create the controller, since there is nothing to update.
if (mSelectionModifierCursorController != null &&
mSelectionModifierCursorController.isShowing()) {
mSelectionModifierCursorController.updatePosition();
@@ -7146,7 +7152,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|| windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
}
- // TODO Add an extra android:cursorController flag to disable the controller?
mInsertionControllerEnabled = windowSupportsHandles && isTextEditable() && mCursorVisible &&
mLayout != null && !mTextIsSelectable;
mSelectionControllerEnabled = windowSupportsHandles && textCanBeSelected() &&
@@ -7157,10 +7162,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (!mSelectionControllerEnabled) {
- // Stop selection mode if the controller becomes unavailable.
- if (mSelectionModifierCursorController != null) {
- stopSelectionActionMode();
- }
+ stopSelectionActionMode();
mSelectionModifierCursorController = null;
}
}
@@ -7565,9 +7567,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void selectCurrentWord() {
- // In case selection mode is started after an orientation change or after a select all,
- // use the current selection instead of creating one
- if (hasSelection()) {
+ if (hasPasswordTransformationMethod()) {
+ // selectCurrentWord is not available on a password field and would return an
+ // arbitrary 10-charater selection around pressed position. Select all instead.
+ // Note that cut/copy menu entries are not available for passwords.
+ // This is however useful to delete or paste to replace the entire content.
+ Selection.setSelection((Spannable) mText, 0, mText.length());
return;
}
@@ -7577,11 +7582,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
minOffset = getSelectionStart();
maxOffset = getSelectionEnd();
} else {
- // selectionModifierCursorController is not null at that point
- SelectionModifierCursorController selectionModifierCursorController =
- ((SelectionModifierCursorController) mSelectionModifierCursorController);
- minOffset = selectionModifierCursorController.getMinTouchOffset();
- maxOffset = selectionModifierCursorController.getMaxTouchOffset();
+ // selectionModifierCursorController is guaranteed to exist at that point
+ SelectionModifierCursorController selectionController = getSelectionController();
+ minOffset = selectionController.getMinTouchOffset();
+ maxOffset = selectionController.getMaxTouchOffset();
}
int selectionStart, selectionEnd;
@@ -7768,7 +7772,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// Two spaces at beginning of paste: remove one
final int originalLength = mText.length();
((Editable) mText).replace(min - 1, min, "");
- // Due to filters, there is no garantee that exactly one character was
+ // Due to filters, there is no guarantee that exactly one character was
// removed. Count instead.
final int delta = mText.length() - originalLength;
min += delta;
@@ -7835,6 +7839,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return true;
}
+ if (!isPositionOnText(mLastDownPositionX, mLastDownPositionY) && mInsertionControllerEnabled) {
+ final int offset = getOffset(mLastDownPositionX, mLastDownPositionY);
+ Selection.setSelection((Spannable)mText, offset);
+ if (canPaste()) {
+ getInsertionController().showWithPaste();
+ performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ } else {
+ getInsertionController().show();
+ }
+ mEatTouchRelease = true;
+ return true;
+ }
+
if (mSelectionActionMode != null && touchPositionIsInSelection()) {
final int start = getSelectionStart();
final int end = getSelectionEnd();
@@ -7871,10 +7888,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Selection.setSelection((Spannable) mText, selectionStart, selectionEnd);
}
- SelectionModifierCursorController selectionModifierCursorController =
- ((SelectionModifierCursorController) mSelectionModifierCursorController);
- int minOffset = selectionModifierCursorController.getMinTouchOffset();
- int maxOffset = selectionModifierCursorController.getMaxTouchOffset();
+ SelectionModifierCursorController selectionController = getSelectionController();
+ int minOffset = selectionController.getMinTouchOffset();
+ int maxOffset = selectionController.getMaxTouchOffset();
return ((minOffset >= selectionStart) && (maxOffset < selectionEnd));
}
@@ -7886,9 +7902,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* mode is not available.
*/
private ActionMode.Callback getActionModeCallback() {
- // Long press in the current selection.
- // Should initiate a drag. Return false, to rely on context menu for now.
- if (canSelectText() && !touchPositionIsInSelection()) {
+ if (canSelectText()) {
return new SelectionActionModeCallback();
}
return null;
@@ -7921,10 +7935,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
private void terminateSelectionActionMode() {
stopSelectionActionMode();
+
+ // No need to create the controller, nothing to cancel in that case.
if (mSelectionModifierCursorController != null) {
- SelectionModifierCursorController selectionModifierCursorController =
- (SelectionModifierCursorController) mSelectionModifierCursorController;
- selectionModifierCursorController.cancelFadeOutAnimation();
+ mSelectionModifierCursorController.cancelFadeOutAnimation();
}
}
@@ -7966,7 +7980,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
- if (mSelectionModifierCursorController == null) {
+ if (!hasSelectionController()) {
Log.w(LOG_TAG, "TextView has no selection controller. Action mode cancelled.");
return false;
}
@@ -7983,15 +7997,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
boolean atLeastOne = false;
if (canSelectText()) {
- if (hasPasswordTransformationMethod()) {
- // selectCurrentWord is not available on a password field and would return an
- // arbitrary 10-charater selection around pressed position. Select all instead.
- // Note that cut/copy menu entries are not available for passwords.
- // This is however useful to delete or paste to replace the entire content.
- Selection.setSelection((Spannable) mText, 0, mText.length());
- } else {
- selectCurrentWord();
- }
+ selectCurrentWord();
menu.add(0, ID_SELECT_ALL, 0, com.android.internal.R.string.selectAll).
setAlphabeticShortcut('a').
@@ -8030,7 +8036,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
styledAttributes.recycle();
if (atLeastOne) {
- mSelectionModifierCursorController.show();
+ getSelectionController().show();
return true;
} else {
return false;
@@ -8049,8 +8055,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (itemId == ID_SELECT_ALL) {
Selection.setSelection((Spannable) mText, 0, mText.length());
// Update controller positions after selection change.
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.show();
+ if (hasSelectionController()) {
+ getSelectionController().show();
}
return true;
}
@@ -8094,9 +8100,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@Override
public void onDestroyActionMode(ActionMode mode) {
Selection.setSelection((Spannable) mText, getSelectionStart());
- if (mSelectionModifierCursorController != null) {
- mSelectionModifierCursorController.hide();
- }
+ hideSelectionModifierCursorController();
mSelectionActionMode = null;
}
}
@@ -8254,6 +8258,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private int mLastParentY;
private int mContainerPositionX, mContainerPositionY;
private long mTouchTimer;
+ private boolean mHasPastePopupWindow = false;
private PastePopupMenu mPastePopupWindow;
public static final int LEFT = 0;
@@ -8306,7 +8311,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mDrawable = mSelectHandleCenter;
handleWidth = mDrawable.getIntrinsicWidth();
mHotspotX = handleWidth / 2;
- mPastePopupWindow = new PastePopupMenu();
+ mHasPastePopupWindow = true;
break;
}
}
@@ -8474,9 +8479,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mLastParentX = coords[0];
mLastParentY = coords[1];
mIsDragging = true;
- if (mPastePopupWindow != null) {
+ if (mHasPastePopupWindow) {
mTouchTimer = SystemClock.uptimeMillis();
- if (mPastePopupWindow.isShowing()) {
+ if (mPastePopupWindow != null && mPastePopupWindow.isShowing()) {
// Tapping on the handle again dismisses the displayed paste view,
mPastePopupWindow.hide();
// and makes sure the action up does not display the paste view.
@@ -8508,7 +8513,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final int doubleTapSlop = viewConfiguration.getScaledDoubleTapSlop();
final int slopSquared = doubleTapSlop * doubleTapSlop;
if (distanceSquared < slopSquared) {
- mPastePopupWindow.show();
+ showPastePopupWindow();
}
}
}
@@ -8542,6 +8547,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
convertFromViewportToContentCoordinates(bounds);
moveTo(bounds.left, bounds.top);
}
+
+ void showPastePopupWindow() {
+ if (mHasPastePopupWindow) {
+ if (mPastePopupWindow == null) {
+ // Lazy initialisation: create when actually shown only.
+ mPastePopupWindow = new PastePopupMenu();
+ }
+ mPastePopupWindow.show();
+ }
+ }
}
private class InsertionPointCursorController implements CursorController {
@@ -8566,6 +8581,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
hideDelayed(DELAY_BEFORE_FADE_OUT);
}
+ void showWithPaste() {
+ show();
+ mHandle.showPastePopupWindow();
+ }
+
public void hide() {
mHandle.hide();
TextView.this.removeCallbacks(mHider);
@@ -8822,12 +8842,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
private void hideInsertionPointCursorController() {
+ // No need to create the controller to hide it.
if (mInsertionPointCursorController != null) {
mInsertionPointCursorController.hide();
}
}
private void hideSelectionModifierCursorController() {
+ // No need to create the controller to hide it.
if (mSelectionModifierCursorController != null) {
mSelectionModifierCursorController.hide();
}
@@ -8838,15 +8860,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
hideSelectionModifierCursorController();
}
- private int getOffsetForHorizontal(int line, int x) {
- x -= getTotalPaddingLeft();
- // Clamp the position to inside of the view.
- x = Math.max(0, x);
- x = Math.min(getWidth() - getTotalPaddingRight() - 1, x);
- x += getScrollX();
- return getLayout().getOffsetForHorizontal(line, x);
- }
-
/**
* Get the offset character closest to the specified absolute position.
*
@@ -8859,15 +8872,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
public int getOffset(int x, int y) {
if (getLayout() == null) return -1;
-
- y -= getTotalPaddingTop();
- // Clamp the position to inside of the view.
- y = Math.max(0, y);
- y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
- y += getScrollY();
-
- final int line = getLayout().getLineForVertical(y);
- final int offset = getOffsetForHorizontal(line, x);
+ final int line = getLineAtCoordinate(y);
+ final int offset = getOffsetAtCoordinate(line, x);
return offset;
}
@@ -8875,14 +8881,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final Layout layout = getLayout();
if (layout == null) return -1;
- y -= getTotalPaddingTop();
- // Clamp the position to inside of the view.
- y = Math.max(0, y);
- y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
- y += getScrollY();
-
- int line = getLayout().getLineForVertical(y);
-
+ int line = getLineAtCoordinate(y);
final int previousLine = layout.getLineForOffset(previousOffset);
final int previousLineTop = layout.getLineTop(previousLine);
final int previousLineBottom = layout.getLineBottom(previousLine);
@@ -8895,21 +8894,58 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
line = previousLine;
}
- return getOffsetForHorizontal(line, x);
+ return getOffsetAtCoordinate(line, x);
+ }
+
+ private int convertToLocalHorizontalCoordinate(int x) {
+ x -= getTotalPaddingLeft();
+ // Clamp the position to inside of the view.
+ x = Math.max(0, x);
+ x = Math.min(getWidth() - getTotalPaddingRight() - 1, x);
+ x += getScrollX();
+ return x;
+ }
+
+ private int getLineAtCoordinate(int y) {
+ y -= getTotalPaddingTop();
+ // Clamp the position to inside of the view.
+ y = Math.max(0, y);
+ y = Math.min(getHeight() - getTotalPaddingBottom() - 1, y);
+ y += getScrollY();
+ return getLayout().getLineForVertical(y);
+ }
+
+ private int getOffsetAtCoordinate(int line, int x) {
+ x = convertToLocalHorizontalCoordinate(x);
+ return getLayout().getOffsetForHorizontal(line, x);
+ }
+
+ /** Returns true if the screen coordinates position (x,y) corresponds to a character displayed
+ * in the view. Returns false when the position is in the empty space of left/right of text.
+ */
+ private boolean isPositionOnText(int x, int y) {
+ if (getLayout() == null) return false;
+
+ final int line = getLineAtCoordinate(y);
+ x = convertToLocalHorizontalCoordinate(x);
+
+ if (x < getLayout().getLineLeft(line)) return false;
+ if (x > getLayout().getLineRight(line)) return false;
+ return true;
}
@Override
public boolean onDragEvent(DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
- return mInsertionPointCursorController != null;
+ return hasInsertionController();
case DragEvent.ACTION_DRAG_ENTERED:
TextView.this.requestFocus();
return true;
case DragEvent.ACTION_DRAG_LOCATION: {
- final int offset = getOffset((int)event.getX(), (int)event.getY());
+ final int offset = getOffset((int) event.getX(), (int) event.getY());
Selection.setSelection((Spannable)mText, offset);
return true;
}
@@ -8952,7 +8988,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return mSelectionControllerEnabled;
}
- CursorController getInsertionController() {
+ InsertionPointCursorController getInsertionController() {
if (!mInsertionControllerEnabled) {
return null;
}
@@ -8969,7 +9005,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return mInsertionPointCursorController;
}
- CursorController getSelectionController() {
+ SelectionModifierCursorController getSelectionController() {
if (!mSelectionControllerEnabled) {
return null;
}
@@ -9028,8 +9064,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private boolean mCursorVisible = true;
// Cursor Controllers.
- private CursorController mInsertionPointCursorController;
- private CursorController mSelectionModifierCursorController;
+ private InsertionPointCursorController mInsertionPointCursorController;
+ private SelectionModifierCursorController mSelectionModifierCursorController;
private ActionMode mSelectionActionMode;
private boolean mInsertionControllerEnabled;
private boolean mSelectionControllerEnabled;
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 125b210..a2e9486 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -55,6 +55,7 @@ interface IInputMethodManager {
void showInputMethodSubtypePickerFromClient(in IInputMethodClient client);
void showInputMethodAndSubtypeEnablerFromClient(in IInputMethodClient client, String topId);
void setInputMethod(in IBinder token, String id);
+ void setInputMethodAndSubtype(in IBinder token, String id, in InputMethodSubtype subtype);
void hideMySoftInput(in IBinder token, int flags);
void showMySoftInput(in IBinder token, int flags);
void updateStatusIcon(in IBinder token, String packageName, int iconId);
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index c4d6d1b..9a85edc 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -19,7 +19,9 @@
#include <stdio.h>
#include "android_util_Binder.h"
+#include "android/graphics/GraphicsJNI.h"
+#include <binder/IMemory.h>
#include <surfaceflinger/SurfaceComposerClient.h>
#include <surfaceflinger/Surface.h>
#include <ui/Region.h>
@@ -91,15 +93,6 @@ struct no_t {
static no_t no;
-static __attribute__((noinline))
-void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
-{
- if (!env->ExceptionOccurred()) {
- jclass npeClazz = env->FindClass(exc);
- env->ThrowNew(npeClazz, msg);
- }
-}
-
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
@@ -444,6 +437,56 @@ static void Surface_unfreezeDisplay(
}
}
+class ScreenshotBitmap : public SkBitmap {
+public:
+ ScreenshotBitmap() {
+ }
+
+ status_t update(int width, int height) {
+ status_t res = (width > 0 && height > 0)
+ ? mScreenshot.update(width, height)
+ : mScreenshot.update();
+ if (res != NO_ERROR) {
+ return res;
+ }
+
+ void const* base = mScreenshot.getPixels();
+ uint32_t w = mScreenshot.getWidth();
+ uint32_t h = mScreenshot.getHeight();
+ uint32_t s = mScreenshot.getStride();
+ uint32_t f = mScreenshot.getFormat();
+
+ ssize_t bpr = s * android::bytesPerPixel(f);
+ setConfig(convertPixelFormat(f), w, h, bpr);
+ if (f == PIXEL_FORMAT_RGBX_8888) {
+ setIsOpaque(true);
+ }
+ if (w > 0 && h > 0) {
+ setPixels((void*)base);
+ } else {
+ // be safe with an empty bitmap.
+ setPixels(NULL);
+ }
+
+ return NO_ERROR;
+ }
+
+private:
+ ScreenshotClient mScreenshot;
+};
+
+static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height)
+{
+ ScreenshotBitmap* bitmap = new ScreenshotBitmap();
+
+ if (bitmap->update(width, height) != NO_ERROR) {
+ delete bitmap;
+ return 0;
+ }
+
+ return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
+}
+
static void Surface_setLayer(
JNIEnv* env, jobject clazz, jint zorder)
{
@@ -669,6 +712,7 @@ static JNINativeMethod gSurfaceMethods[] = {
{"setOrientation", "(III)V", (void*)Surface_setOrientation },
{"freezeDisplay", "(I)V", (void*)Surface_freezeDisplay },
{"unfreezeDisplay", "(I)V", (void*)Surface_unfreezeDisplay },
+ {"screenshot", "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
{"setLayer", "(I)V", (void*)Surface_setLayer },
{"setPosition", "(II)V",(void*)Surface_setPosition },
{"setSize", "(II)V",(void*)Surface_setSize },
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 21b810e..d64fb74 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -110,8 +110,8 @@
<color name="background_holo_light">#fff3f3f3</color>
<color name="bright_foreground_holo_dark">@android:color/background_holo_light</color>
<color name="bright_foreground_holo_light">@android:color/background_holo_dark</color>
- <color name="bright_foreground_disabled_holo_dark">#80ffffff</color>
- <color name="bright_foreground_disabled_holo_light">#80000000</color>
+ <color name="bright_foreground_disabled_holo_dark">#ff4c4c4c</color>
+ <color name="bright_foreground_disabled_holo_light">#ffb2b2b2</color>
<color name="bright_foreground_inverse_holo_dark">@android:color/bright_foreground_holo_light</color>
<color name="bright_foreground_inverse_holo_light">@android:color/bright_foreground_holo_dark</color>
<color name="dim_foreground_holo_dark">#bebebe</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 15b5db4..61223b3 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -195,6 +195,10 @@
<!-- XXXXXX END OF RESOURCES USING WRONG NAMING CONVENTION -->
+ <!-- If true, the screen can be rotated via the accelerometer in all 4
+ rotations as the default behavior. -->
+ <bool name="config_allowAllRotations">true</bool>
+
<!-- The number of degrees to rotate the display when the keyboard is open. -->
<integer name="config_lidOpenRotation">90</integer>
diff --git a/core/tests/coretests/src/android/content/SyncOperationTest.java b/core/tests/coretests/src/android/content/SyncOperationTest.java
new file mode 100644
index 0000000..57435e5
--- /dev/null
+++ b/core/tests/coretests/src/android/content/SyncOperationTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 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.content;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * You can run those tests with:
+ *
+ * adb shell am instrument
+ * -e debug false
+ * -w
+ * -e class android.content.SyncOperationTest com.android.frameworks.coretests/android.test.InstrumentationTestRunner
+ */
+
+public class SyncOperationTest extends AndroidTestCase {
+
+ @SmallTest
+ public void testToKey() {
+ Account account1 = new Account("account1", "type1");
+ Account account2 = new Account("account2", "type2");
+
+ Bundle b1 = new Bundle();
+ Bundle b2 = new Bundle();
+ b2.putBoolean("b2", true);
+
+ SyncOperation op1 = new SyncOperation(account1,
+ 1,
+ "authority1",
+ b1,
+ 100,
+ 1000,
+ 10000);
+
+ // Same as op1 but different time infos
+ SyncOperation op2 = new SyncOperation(account1,
+ 1,
+ "authority1",
+ b1,
+ 200,
+ 2000,
+ 20000);
+
+ // Same as op1 but different authority
+ SyncOperation op3 = new SyncOperation(account1,
+ 1,
+ "authority2",
+ b1,
+ 100,
+ 1000,
+ 10000);
+
+ // Same as op1 but different account
+ SyncOperation op4 = new SyncOperation(account2,
+ 1,
+ "authority1",
+ b1,
+ 100,
+ 1000,
+ 10000);
+
+ // Same as op1 but different bundle
+ SyncOperation op5 = new SyncOperation(account1,
+ 1,
+ "authority1",
+ b2,
+ 100,
+ 1000,
+ 10000);
+
+ assertEquals(op1.key, op2.key);
+ assertNotSame(op1.key, op3.key);
+ assertNotSame(op1.key, op4.key);
+ assertNotSame(op1.key, op5.key);
+ }
+}
diff --git a/core/tests/coretests/src/android/util/TimeUtilsTest.java b/core/tests/coretests/src/android/util/TimeUtilsTest.java
index 65a6078..8d9f8e5 100644
--- a/core/tests/coretests/src/android/util/TimeUtilsTest.java
+++ b/core/tests/coretests/src/android/util/TimeUtilsTest.java
@@ -429,4 +429,22 @@ public class TimeUtilsTest extends TestCase {
c.getTimeInMillis(),
country);
}
+
+ public void testFormatDuration() {
+ assertFormatDuration("0", 0);
+ assertFormatDuration("-1ms", -1);
+ assertFormatDuration("+1ms", 1);
+ assertFormatDuration("+10ms", 10);
+ assertFormatDuration("+100ms", 100);
+ assertFormatDuration("+101ms", 101);
+ assertFormatDuration("+330ms", 330);
+ assertFormatDuration("+1s330ms", 1330);
+ assertFormatDuration("+10s24ms", 10024);
+ }
+
+ private void assertFormatDuration(String expected, long duration) {
+ StringBuilder sb = new StringBuilder();
+ TimeUtils.formatDuration(duration, sb);
+ assertEquals("formatDuration(" + duration + ")", expected, sb.toString());
+ }
}
diff --git a/drm/libdrmframework/plugins/widevine/Android.mk b/drm/libdrmframework/plugins/widevine/Android.mk
deleted file mode 100644
index 2c388da..0000000
--- a/drm/libdrmframework/plugins/widevine/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (C) 2010 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.
-#
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libdrmwvmplugin
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/drm/plugins/native
-
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 9416ca1..0bfb166 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -32,6 +32,7 @@ namespace android {
class IMediaRecorder;
class IOMX;
+struct IStreamSource;
class IMediaPlayerService: public IInterface
{
@@ -45,6 +46,11 @@ public:
int audioSessionId = 0) = 0;
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client,
int fd, int64_t offset, int64_t length, int audioSessionId) = 0;
+
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient> &client,
+ const sp<IStreamSource> &source, int audioSessionId) = 0;
+
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IOMX> getOMX() = 0;
diff --git a/include/media/IStreamSource.h b/include/media/IStreamSource.h
new file mode 100644
index 0000000..6291124
--- /dev/null
+++ b/include/media/IStreamSource.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_ISTREAMSOURCE_H_
+
+#define ANDROID_ISTREAMSOURCE_H_
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+struct IMemory;
+struct IStreamListener;
+
+struct IStreamSource : public IInterface {
+ DECLARE_META_INTERFACE(StreamSource);
+
+ virtual void setListener(const sp<IStreamListener> &listener) = 0;
+ virtual void setBuffers(const Vector<sp<IMemory> > &buffers) = 0;
+
+ virtual void onBufferAvailable(size_t index) = 0;
+};
+
+struct IStreamListener : public IInterface {
+ DECLARE_META_INTERFACE(StreamListener);
+
+ enum Command {
+ FLUSH,
+ DISCONTINUITY,
+ EOS
+ };
+
+ virtual void queueBuffer(size_t index, size_t size) = 0;
+ virtual void queueCommand(Command cmd) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct BnStreamSource : public BnInterface<IStreamSource> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+struct BnStreamListener : public BnInterface<IStreamListener> {
+ virtual status_t onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply,
+ uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif // ANDROID_ISTREAMSOURCE_H_
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 672931e..e7f1d6d 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -106,6 +106,11 @@ public:
const KeyedVector<String8, String8> *headers = NULL) = 0;
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
+
+ virtual status_t setDataSource(const sp<IStreamSource> &source) {
+ return INVALID_OPERATION;
+ }
+
virtual status_t setVideoSurface(const sp<Surface>& surface) = 0;
virtual status_t prepare() = 0;
virtual status_t prepareAsync() = 0;
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index 15a3925..d0812de 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -179,8 +179,10 @@ struct InputWindow {
TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11,
TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13,
- TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14,
+ TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+14,
TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15,
+ TYPE_DRAG = FIRST_SYSTEM_WINDOW+16,
+ TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+17,
LAST_SYSTEM_WINDOW = 2999,
};
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
index 76c23b7..42eaede 100644
--- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
+++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
@@ -21,7 +21,7 @@ import android.renderscript.*;
import android.util.Log;
public class BallsRS {
- public static final int PART_COUNT = 800;
+ public static final int PART_COUNT = 1000;
public BallsRS() {
}
diff --git a/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs b/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs
index 96c39b1..47eaf1b 100644
--- a/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs
+++ b/libs/rs/java/Balls/src/com/android/balls/ball_physics.rs
@@ -41,7 +41,20 @@ void root(const Ball_t *ballIn, Ball_t *ballOut, const BallControl_t *ctl, uint3
fv -= (vec / (len * len * len)) * 20000.f;
} else {
if (len2 < 0.1) {
- continue;
+ if (xin == x) {
+ continue;
+ }
+ ballOut->delta = 0.f;
+ ballOut->position = ballIn->position;
+ if (xin > x) {
+ ballOut->position.x += 1.f;
+ } else {
+ ballOut->position.x -= 1.f;
+ }
+ ballOut->color.rgb = 1.f;
+ ballOut->arcID = -1;
+ ballOut->arcStr = 0;
+ return;
}
// Collision
float2 axis = normalize(vec);
diff --git a/media/java/android/media/videoeditor/MediaProperties.java b/media/java/android/media/videoeditor/MediaProperties.java
index 34088fc..0bb83eb 100755
--- a/media/java/android/media/videoeditor/MediaProperties.java
+++ b/media/java/android/media/videoeditor/MediaProperties.java
@@ -95,6 +95,9 @@ public class MediaProperties {
public static final int BITRATE_384K = 384000;
public static final int BITRATE_512K = 512000;
public static final int BITRATE_800K = 800000;
+ public static final int BITRATE_2M = 2000000;
+ public static final int BITRATE_5M = 5000000;
+ public static final int BITRATE_8M = 8000000;
// The array of supported bitrates
private static final int[] SUPPORTED_BITRATES = new int[] {
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 2e5cbe3..731c09d 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -15,6 +15,7 @@ LOCAL_SRC_FILES:= \
IMediaRecorderClient.cpp \
IMediaPlayer.cpp \
IMediaRecorder.cpp \
+ IStreamSource.cpp \
Metadata.cpp \
mediarecorder.cpp \
IMediaMetadataRetriever.cpp \
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 4abfa75..77199e1 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -23,6 +23,7 @@
#include <media/IMediaPlayerService.h>
#include <media/IMediaRecorder.h>
#include <media/IOMX.h>
+#include <media/IStreamSource.h>
#include <utils/Errors.h> // for status_t
@@ -31,6 +32,7 @@ namespace android {
enum {
CREATE_URL = IBinder::FIRST_CALL_TRANSACTION,
CREATE_FD,
+ CREATE_STREAM,
DECODE_URL,
DECODE_FD,
CREATE_MEDIA_RECORDER,
@@ -107,6 +109,21 @@ public:
return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
}
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient> &client,
+ const sp<IStreamSource> &source, int audioSessionId) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(pid));
+ data.writeStrongBinder(client->asBinder());
+ data.writeStrongBinder(source->asBinder());
+ data.writeInt32(static_cast<int32_t>(audioSessionId));
+
+ remote()->transact(CREATE_STREAM, data, &reply);
+
+ return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
+ }
+
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
{
Parcel data, reply;
@@ -184,6 +201,27 @@ status_t BnMediaPlayerService::onTransact(
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
} break;
+ case CREATE_STREAM:
+ {
+ CHECK_INTERFACE(IMediaPlayerService, data, reply);
+
+ pid_t pid = static_cast<pid_t>(data.readInt32());
+
+ sp<IMediaPlayerClient> client =
+ interface_cast<IMediaPlayerClient>(data.readStrongBinder());
+
+ sp<IStreamSource> source =
+ interface_cast<IStreamSource>(data.readStrongBinder());
+
+ int audioSessionId = static_cast<int>(data.readInt32());
+
+ sp<IMediaPlayer> player =
+ create(pid, client, source, audioSessionId);
+
+ reply->writeStrongBinder(player->asBinder());
+ return OK;
+ break;
+ }
case DECODE_URL: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const char* url = data.readCString();
diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp
new file mode 100644
index 0000000..89f2b44
--- /dev/null
+++ b/media/libmedia/IStreamSource.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "IStreamSource"
+#include <utils/Log.h>
+
+#include <media/IStreamSource.h>
+
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+enum {
+ // IStreamSource
+ SET_LISTENER = IBinder::FIRST_CALL_TRANSACTION,
+ SET_BUFFERS,
+ ON_BUFFER_AVAILABLE,
+
+ // IStreamListener
+ QUEUE_BUFFER,
+ QUEUE_COMMAND,
+};
+
+struct BpStreamSource : public BpInterface<IStreamSource> {
+ BpStreamSource(const sp<IBinder> &impl)
+ : BpInterface<IStreamSource>(impl) {
+ }
+
+ virtual void setListener(const sp<IStreamListener> &listener) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
+ data.writeStrongBinder(listener->asBinder());
+ remote()->transact(SET_LISTENER, data, &reply);
+ }
+
+ virtual void setBuffers(const Vector<sp<IMemory> > &buffers) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(buffers.size()));
+ for (size_t i = 0; i < buffers.size(); ++i) {
+ data.writeStrongBinder(buffers.itemAt(i)->asBinder());
+ }
+ remote()->transact(SET_BUFFERS, data, &reply);
+ }
+
+ virtual void onBufferAvailable(size_t index) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(index));
+ remote()->transact(
+ ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(StreamSource, "android.hardware.IStreamSource");
+
+status_t BnStreamSource::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case SET_LISTENER:
+ {
+ CHECK_INTERFACE(IStreamSource, data, reply);
+ setListener(
+ interface_cast<IStreamListener>(data.readStrongBinder()));
+ break;
+ }
+
+ case SET_BUFFERS:
+ {
+ CHECK_INTERFACE(IStreamSource, data, reply);
+ size_t n = static_cast<size_t>(data.readInt32());
+ Vector<sp<IMemory> > buffers;
+ for (size_t i = 0; i < n; ++i) {
+ sp<IMemory> mem =
+ interface_cast<IMemory>(data.readStrongBinder());
+
+ buffers.push(mem);
+ }
+ setBuffers(buffers);
+ break;
+ }
+
+ case ON_BUFFER_AVAILABLE:
+ {
+ CHECK_INTERFACE(IStreamSource, data, reply);
+ onBufferAvailable(static_cast<size_t>(data.readInt32()));
+ break;
+ }
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+
+ return OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct BpStreamListener : public BpInterface<IStreamListener> {
+ BpStreamListener(const sp<IBinder> &impl)
+ : BpInterface<IStreamListener>(impl) {
+ }
+
+ virtual void queueBuffer(size_t index, size_t size) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(index));
+ data.writeInt32(static_cast<int32_t>(size));
+
+ remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+
+ virtual void queueCommand(Command cmd) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(cmd));
+
+ remote()->transact(QUEUE_COMMAND, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(StreamListener, "android.hardware.IStreamListener");
+
+status_t BnStreamListener::onTransact(
+ uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
+ switch (code) {
+ case QUEUE_BUFFER:
+ {
+ CHECK_INTERFACE(IStreamListener, data, reply);
+ size_t index = static_cast<size_t>(data.readInt32());
+ size_t size = static_cast<size_t>(data.readInt32());
+
+ queueBuffer(index, size);
+ break;
+ }
+
+ case QUEUE_COMMAND:
+ {
+ CHECK_INTERFACE(IStreamListener, data, reply);
+ Command cmd = static_cast<Command>(data.readInt32());
+
+ queueCommand(cmd);
+ break;
+ }
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 00e510b..63d09d6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -278,6 +278,26 @@ sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClie
return c;
}
+sp<IMediaPlayer> MediaPlayerService::create(
+ pid_t pid, const sp<IMediaPlayerClient> &client,
+ const sp<IStreamSource> &source, int audioSessionId) {
+ int32_t connId = android_atomic_inc(&mNextConnId);
+ sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+
+ LOGV("Create new client(%d) from pid %d, audioSessionId=%d",
+ connId, pid, audioSessionId);
+
+ if (OK != c->setDataSource(source)) {
+ c.clear();
+ } else {
+ wp<Client> w = c;
+ Mutex::Autolock lock(mLock);
+ mClients.add(w);
+ }
+
+ return c;
+}
+
sp<IOMX> MediaPlayerService::getOMX() {
Mutex::Autolock autoLock(mLock);
@@ -864,6 +884,30 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64
return mStatus;
}
+status_t MediaPlayerService::Client::setDataSource(
+ const sp<IStreamSource> &source) {
+ // create the right type of player
+ sp<MediaPlayerBase> p = createPlayer(STAGEFRIGHT_PLAYER);
+
+ if (p == NULL) {
+ return NO_INIT;
+ }
+
+ if (!p->hardwareOutput()) {
+ mAudioOutput = new AudioOutput(mAudioSessionId);
+ static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
+ }
+
+ // now set data source
+ mStatus = p->setDataSource(source);
+
+ if (mStatus == OK) {
+ mPlayer = p;
+ }
+
+ return mStatus;
+}
+
status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface)
{
LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get());
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 184324c..62f8ed6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -191,6 +191,11 @@ public:
const KeyedVector<String8, String8> *headers, int audioSessionId);
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length, int audioSessionId);
+
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient> &client,
+ const sp<IStreamSource> &source, int audioSessionId);
+
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IOMX> getOMX();
@@ -234,6 +239,9 @@ private:
const KeyedVector<String8, String8> *headers);
status_t setDataSource(int fd, int64_t offset, int64_t length);
+
+ status_t setDataSource(const sp<IStreamSource> &source);
+
static void notify(void* cookie, int msg, int ext1, int ext2);
pid_t pid() const { return mPid; }
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 58ef99b..da564dc 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -44,6 +44,10 @@ status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length
return mPlayer->setDataSource(dup(fd), offset, length);
}
+status_t StagefrightPlayer::setDataSource(const sp<IStreamSource> &source) {
+ return mPlayer->setDataSource(source);
+}
+
status_t StagefrightPlayer::setVideoSurface(const sp<Surface> &surface) {
LOGV("setVideoSurface");
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index c4a2588..fc72bfb 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -35,6 +35,9 @@ public:
const char *url, const KeyedVector<String8, String8> *headers);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
+
+ virtual status_t setDataSource(const sp<IStreamSource> &source);
+
virtual status_t setVideoSurface(const sp<Surface> &surface);
virtual status_t prepare();
virtual status_t prepareAsync();
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index ec58919..a804866 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -34,13 +34,16 @@
#include "UDPPusher.h"
#include <binder/IPCThreadState.h>
+#include <binder/MemoryDealer.h>
+#include <media/IStreamSource.h>
+#include <media/stagefright/foundation/hexdump.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/AudioPlayer.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractor.h>
-#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/OMXCodec.h>
@@ -155,6 +158,201 @@ private:
const AwesomeNativeWindowRenderer &);
};
+////////////////////////////////////////////////////////////////////////////////
+
+struct QueueDataSource;
+
+struct QueueListener : public BnStreamListener {
+ QueueListener(QueueDataSource *owner)
+ : mOwner(owner) {
+ }
+
+ void clearOwner();
+
+ virtual void queueBuffer(size_t index, size_t size);
+ virtual void queueCommand(Command cmd);
+
+private:
+ Mutex mLock;
+
+ QueueDataSource *mOwner;
+
+ DISALLOW_EVIL_CONSTRUCTORS(QueueListener);
+};
+
+struct QueueDataSource : public DataSource {
+ QueueDataSource(const sp<IStreamSource> &source);
+
+ virtual status_t initCheck() const;
+
+ virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+
+ virtual void queueBuffer(size_t index, size_t size);
+ virtual void queueCommand(IStreamListener::Command cmd);
+
+protected:
+ virtual ~QueueDataSource();
+
+private:
+ enum {
+ kNumBuffers = 16
+ };
+
+ struct BufferInfo {
+ size_t mIndex;
+ size_t mOffset;
+ size_t mSize;
+ };
+
+ Mutex mLock;
+ Condition mCondition;
+
+ sp<IStreamSource> mSource;
+ sp<QueueListener> mListener;
+ sp<MemoryDealer> mDealer;
+ Vector<sp<IMemory> > mBuffers;
+
+ List<BufferInfo> mFilledBuffers;
+
+ off64_t mPosition;
+ bool mEOS;
+
+ DISALLOW_EVIL_CONSTRUCTORS(QueueDataSource);
+};
+
+QueueDataSource::QueueDataSource(const sp<IStreamSource> &source)
+ : mSource(source),
+ mPosition(0),
+ mEOS(false) {
+ mListener = new QueueListener(this);
+ mSource->setListener(mListener);
+
+ static const size_t kBufferSize = 8192;
+
+ mDealer = new MemoryDealer(kNumBuffers * kBufferSize);
+ for (size_t i = 0; i < kNumBuffers; ++i) {
+ sp<IMemory> mem = mDealer->allocate(kBufferSize);
+ CHECK(mem != NULL);
+
+ mBuffers.push(mem);
+ }
+ mSource->setBuffers(mBuffers);
+
+ for (size_t i = 0; i < kNumBuffers; ++i) {
+ mSource->onBufferAvailable(i);
+ }
+}
+
+QueueDataSource::~QueueDataSource() {
+ Mutex::Autolock autoLock(mLock);
+
+ while (mFilledBuffers.size() < kNumBuffers && !mEOS) {
+ mCondition.wait(mLock);
+ }
+
+ mListener->clearOwner();
+}
+
+status_t QueueDataSource::initCheck() const {
+ return OK;
+}
+
+ssize_t QueueDataSource::readAt(off64_t offset, void *data, size_t size) {
+ if (offset != mPosition) {
+ return -EPIPE;
+ }
+
+ Mutex::Autolock autoLock(mLock);
+
+ size_t sizeDone = 0;
+
+ while (sizeDone < size) {
+ while (mFilledBuffers.empty() && !mEOS) {
+ mCondition.wait(mLock);
+ }
+
+ if (mFilledBuffers.empty()) {
+ if (sizeDone > 0) {
+ mPosition += sizeDone;
+ return sizeDone;
+ }
+ return ERROR_END_OF_STREAM;
+ }
+
+ BufferInfo &info = *mFilledBuffers.begin();
+
+ size_t copy = size - sizeDone;
+ if (copy > info.mSize) {
+ copy = info.mSize;
+ }
+
+ memcpy((uint8_t *)data + sizeDone,
+ (const uint8_t *)mBuffers.itemAt(info.mIndex)->pointer()
+ + info.mOffset,
+ copy);
+
+ info.mSize -= copy;
+ info.mOffset += copy;
+ sizeDone += copy;
+
+ if (info.mSize == 0) {
+ mSource->onBufferAvailable(info.mIndex);
+ mFilledBuffers.erase(mFilledBuffers.begin());
+ }
+ }
+
+ mPosition += sizeDone;
+
+ return sizeDone;
+}
+
+void QueueDataSource::queueBuffer(size_t index, size_t size) {
+ Mutex::Autolock autoLock(mLock);
+
+ CHECK_LT(index, mBuffers.size());
+ CHECK_LE(size, mBuffers.itemAt(index)->size());
+
+ BufferInfo info;
+ info.mIndex = index;
+ info.mSize = size;
+ info.mOffset = 0;
+
+ mFilledBuffers.push_back(info);
+ mCondition.signal();
+}
+
+void QueueDataSource::queueCommand(IStreamListener::Command cmd) {
+ Mutex::Autolock autoLock(mLock);
+
+ if (cmd == IStreamListener::EOS) {
+ mEOS = true;
+ mCondition.signal();
+ }
+}
+
+void QueueListener::clearOwner() {
+ Mutex::Autolock autoLock(mLock);
+ mOwner = NULL;
+}
+
+void QueueListener::queueBuffer(size_t index, size_t size) {
+ Mutex::Autolock autoLock(mLock);
+ if (mOwner == NULL) {
+ return;
+ }
+ mOwner->queueBuffer(index, size);
+}
+
+void QueueListener::queueCommand(Command cmd) {
+ Mutex::Autolock autoLock(mLock);
+ if (mOwner == NULL) {
+ return;
+ }
+ mOwner->queueCommand(cmd);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
AwesomePlayer::AwesomePlayer()
: mQueueStarted(false),
mTimeSource(NULL),
@@ -164,7 +362,7 @@ AwesomePlayer::AwesomePlayer()
mExtractorFlags(0),
mVideoBuffer(NULL),
mDecryptHandle(NULL) {
- CHECK_EQ(mClient.connect(), OK);
+ CHECK_EQ(mClient.connect(), (status_t)OK);
DataSource::RegisterDefaultSniffers();
@@ -264,6 +462,26 @@ status_t AwesomePlayer::setDataSource(
return setDataSource_l(dataSource);
}
+status_t AwesomePlayer::setDataSource(const sp<IStreamSource> &source) {
+ Mutex::Autolock autoLock(mLock);
+
+ reset_l();
+
+ sp<DataSource> dataSource = new QueueDataSource(source);
+
+#if 0
+ sp<MediaExtractor> extractor =
+ MediaExtractor::Create(dataSource, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
+
+ return setDataSource_l(extractor);
+#else
+ sp<NuCachedSource2> cached = new NuCachedSource2(dataSource);
+ dataSource = cached;
+
+ return setDataSource_l(dataSource);
+#endif
+}
+
status_t AwesomePlayer::setDataSource_l(
const sp<DataSource> &dataSource) {
sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
@@ -619,7 +837,8 @@ void AwesomePlayer::partial_reset_l() {
IPCThreadState::self()->flushCommands();
}
- CHECK_EQ(OK, initVideoDecoder(OMXCodec::kIgnoreCodecSpecificData));
+ CHECK_EQ((status_t)OK,
+ initVideoDecoder(OMXCodec::kIgnoreCodecSpecificData));
}
void AwesomePlayer::onStreamDone() {
@@ -1171,7 +1390,7 @@ void AwesomePlayer::onVideoEvent() {
options.clearSeekTo();
if (err != OK) {
- CHECK_EQ(mVideoBuffer, NULL);
+ CHECK(mVideoBuffer == NULL);
if (err == INFO_FORMAT_CHANGED) {
LOGV("VideoSource signalled format change.");
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index e33f467..46f4a35 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -67,6 +67,8 @@ struct AwesomePlayer {
status_t setDataSource(int fd, int64_t offset, int64_t length);
+ status_t setDataSource(const sp<IStreamSource> &source);
+
void reset();
status_t prepare();
diff --git a/media/libwvm/Android.mk b/media/libwvm/Android.mk
deleted file mode 100644
index 7c75c0f..0000000
--- a/media/libwvm/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# create an empty mk for libwvm
-# for integration purpose
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libwvm
-
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_SHARED_LIBRARY)
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_open.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_open.png
new file mode 100644
index 0000000..d083396
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notification_open.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_veto.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_veto.png
new file mode 100644
index 0000000..395604f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notification_veto.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd.png
new file mode 100644
index 0000000..51b5809
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd_off.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd_off.png
new file mode 100644
index 0000000..37ef7e1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_notification_dnd_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_quicksettings.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_quicksettings.png
new file mode 100644
index 0000000..d9b4eca
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_quicksettings.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_lanscape.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_lanscape.png
new file mode 100644
index 0000000..c091489
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_lanscape.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_portrait.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_portrait.png
new file mode 100644
index 0000000..73a9897
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_rotate_off_portrait.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_shadow.9.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_shadow.9.png
new file mode 100644
index 0000000..7cb2643
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_shadow.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recent_overlay.png b/packages/SystemUI/res/drawable-hdpi/recent_overlay.png
new file mode 100644
index 0000000..fcf4417
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recent_overlay.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/recent_rez_border.png b/packages/SystemUI/res/drawable-hdpi/recent_rez_border.png
new file mode 100644
index 0000000..af36ac7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recent_rez_border.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/sysbar_signalmini_100.png b/packages/SystemUI/res/drawable-hdpi/sysbar_signalmini_100.png
new file mode 100644
index 0000000..d89f889
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/sysbar_signalmini_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_notification_veto.png b/packages/SystemUI/res/drawable-mdpi/ic_notification_veto.png
new file mode 100644
index 0000000..f6299e9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_notification_veto.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd.png
new file mode 100644
index 0000000..fe44063
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd_off.png
new file mode 100644
index 0000000..8088a2f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_notification_dnd_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png
new file mode 100644
index 0000000..96bf2ec
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png
new file mode 100644
index 0000000..cc56778
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/recent_overlay.png b/packages/SystemUI/res/drawable-mdpi/recent_overlay.png
index 4dfa3d9..4dfa3d9 100644
--- a/packages/SystemUI/res/drawable/recent_overlay.png
+++ b/packages/SystemUI/res/drawable-mdpi/recent_overlay.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/recent_rez_border.png b/packages/SystemUI/res/drawable-mdpi/recent_rez_border.png
index ad025f5..ad025f5 100644
--- a/packages/SystemUI/res/drawable/recent_rez_border.png
+++ b/packages/SystemUI/res/drawable-mdpi/recent_rez_border.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png
new file mode 100644
index 0000000..7371571
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png
new file mode 100644
index 0000000..5781e9a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png
new file mode 100644
index 0000000..c65728c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png
new file mode 100644
index 0000000..a249fa2
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png
new file mode 100644
index 0000000..289c088
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png
new file mode 100644
index 0000000..f49dbd6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png
new file mode 100644
index 0000000..2f83e68
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png
new file mode 100644
index 0000000..bedc021
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png
new file mode 100644
index 0000000..edd8c05
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png
new file mode 100644
index 0000000..148e20c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png
new file mode 100644
index 0000000..5a90ccb
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/app_icon.png b/packages/SystemUI/res/drawable-xlarge-hdpi/app_icon.png
new file mode 100644
index 0000000..aedf7e7
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/app_icon.png
Binary files differ
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
index 5fa8b3b..fb4cf3f 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
@@ -20,9 +20,8 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:animateLayoutChanges="true"
- android:background="@drawable/bg_scrim_notification"
android:paddingTop="32dp"
- android:paddingBottom="32dp"
+ android:paddingBottom="@dimen/status_bar_panel_bottom_offset"
android:orientation="vertical"
android:gravity="right"
>
@@ -66,6 +65,7 @@
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_below="@id/clock"
+ android:layout_marginTop="4dp"
android:layout_marginRight="48dp"
android:gravity="right"
/>
@@ -76,9 +76,10 @@
android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/date"
- android:layout_marginTop="16dp"
android:layout_marginLeft="48dp"
- android:baseline="17dp"
+ android:layout_marginTop="18dp"
+ android:layout_marginRight="8dp"
+ android:baseline="15dp"
/>
<TextView
@@ -97,7 +98,8 @@
android:layout_width="wrap_content"
android:layout_toRightOf="@id/battery_text"
android:layout_alignBaseline="@id/battery"
- android:baseline="21dp"
+ android:layout_marginRight="8dp"
+ android:baseline="15dp"
/>
<TextView
@@ -114,11 +116,11 @@
android:id="@+id/settings_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
android:layout_alignBaseline="@id/battery"
+ android:layout_alignParentRight="true"
android:paddingRight="16dp"
android:src="@drawable/ic_notification_open"
- android:baseline="17dp"
+ android:baseline="21dp"
/>
<ImageView
@@ -130,7 +132,7 @@
android:paddingRight="16dp"
android:visibility="invisible"
android:src="@drawable/status_bar_veto"
- android:baseline="17dp"
+ android:baseline="21dp"
/>
</com.android.systemui.statusbar.tablet.NotificationTitleArea>
diff --git a/packages/SystemUI/res/values-xlarge/dimens.xml b/packages/SystemUI/res/values-xlarge/dimens.xml
index 009b7a8..5ae3982 100644
--- a/packages/SystemUI/res/values-xlarge/dimens.xml
+++ b/packages/SystemUI/res/values-xlarge/dimens.xml
@@ -22,6 +22,8 @@
<dimen name="notification_large_icon_height">60dp</dimen>
<!-- The width of the ticker, including the icon -->
<dimen name="notification_ticker_width">360dp</dimen>
+ <!-- Status bar panel bottom offset (height of status bar - overlap) -->
+ <dimen name="status_bar_panel_bottom_offset">36dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 2dad81c..915fa2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -294,7 +294,7 @@ public class PhoneStatusBar extends StatusBar {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
- WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
+ WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
@@ -1254,7 +1254,7 @@ public class PhoneStatusBar extends StatusBar {
lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
- WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
+ WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
@@ -1282,7 +1282,7 @@ public class PhoneStatusBar extends StatusBar {
lp.height = getExpandedHeight();
lp.x = 0;
mTrackingPosition = lp.y = -disph; // sufficiently large negative
- lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+ lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 7f743b2..b05fe1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -163,6 +163,7 @@ public class TabletTicker extends Handler {
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 1c1a46e..f892e9e 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -103,6 +103,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
@@ -148,31 +149,32 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int APPLICATION_LAYER = 2;
static final int PHONE_LAYER = 3;
static final int SEARCH_BAR_LAYER = 4;
- static final int STATUS_BAR_PANEL_LAYER = 5;
+ static final int STATUS_BAR_SUB_PANEL_LAYER = 5;
static final int SYSTEM_DIALOG_LAYER = 6;
// toasts and the plugged-in battery thing
static final int TOAST_LAYER = 7;
static final int STATUS_BAR_LAYER = 8;
+ static final int STATUS_BAR_PANEL_LAYER = 9;
// SIM errors and unlock. Not sure if this really should be in a high layer.
- static final int PRIORITY_PHONE_LAYER = 9;
+ static final int PRIORITY_PHONE_LAYER = 10;
// like the ANR / app crashed dialogs
- static final int SYSTEM_ALERT_LAYER = 10;
+ static final int SYSTEM_ALERT_LAYER = 11;
// system-level error dialogs
- static final int SYSTEM_ERROR_LAYER = 11;
+ static final int SYSTEM_ERROR_LAYER = 12;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_LAYER = 12;
+ static final int INPUT_METHOD_LAYER = 13;
// on-screen keyboards and other such input method user interfaces go here.
- static final int INPUT_METHOD_DIALOG_LAYER = 13;
+ static final int INPUT_METHOD_DIALOG_LAYER = 14;
// the keyguard; nothing on top of these can take focus, since they are
// responsible for power management when displayed.
- static final int KEYGUARD_LAYER = 14;
- static final int KEYGUARD_DIALOG_LAYER = 15;
+ static final int KEYGUARD_LAYER = 15;
+ static final int KEYGUARD_DIALOG_LAYER = 16;
// the drag layer: input for drag-and-drop is associated with this window,
// which sits above all other focusable windows
- static final int DRAG_LAYER = 16;
+ static final int DRAG_LAYER = 17;
// things in here CAN NOT take focus, but are shown on top of everything else.
- static final int SYSTEM_OVERLAY_LAYER = 17;
- static final int SECURE_SYSTEM_OVERLAY_LAYER = 18;
+ static final int SYSTEM_OVERLAY_LAYER = 18;
+ static final int SECURE_SYSTEM_OVERLAY_LAYER = 19;
static final int APPLICATION_MEDIA_SUBLAYER = -2;
static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1;
@@ -239,6 +241,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
int mUserRotation = Surface.ROTATION_0;
+ boolean mAllowAllRotations;
boolean mCarDockEnablesAccelerometer;
boolean mDeskDockEnablesAccelerometer;
int mLidKeyboardAccessibility;
@@ -274,10 +277,15 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
};
+ // The current size of the screen; really; (ir)regardless of whether the status
+ // bar can be hidden or not
+ int mUnrestrictedScreenLeft, mUnrestrictedScreenTop;
+ int mUnrestrictedScreenWidth, mUnrestrictedScreenHeight;
// The current size of the screen; these may be different than (0,0)-(dw,dh)
// if the status bar can't be hidden; in that case it effectively carves out
// that area of the display from all other windows.
- int mScreenLeft, mScreenTop, mScreenWidth, mScreenHeight;
+ int mRestrictedScreenLeft, mRestrictedScreenTop;
+ int mRestrictedScreenWidth, mRestrictedScreenHeight;
// During layout, the current screen borders with all outer decoration
// (status bar, input method dock) accounted for.
int mCurLeft, mCurTop, mCurRight, mCurBottom;
@@ -650,6 +658,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
com.android.internal.R.integer.config_carDockRotation);
mDeskDockRotation = readRotation(
com.android.internal.R.integer.config_deskDockRotation);
+ mAllowAllRotations = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowAllRotations);
mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_carDockEnablesAccelerometer);
mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
@@ -906,6 +916,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return STATUS_BAR_LAYER;
case TYPE_STATUS_BAR_PANEL:
return STATUS_BAR_PANEL_LAYER;
+ case TYPE_STATUS_BAR_SUB_PANEL:
+ return STATUS_BAR_SUB_PANEL_LAYER;
case TYPE_SYSTEM_DIALOG:
return SYSTEM_DIALOG_LAYER;
case TYPE_SEARCH_BAR:
@@ -1126,6 +1138,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
"PhoneWindowManager");
mStatusBarPanels.add(win);
break;
+ case TYPE_STATUS_BAR_SUB_PANEL:
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.STATUS_BAR_SERVICE,
+ "PhoneWindowManager");
+ mStatusBarPanels.add(win);
+ break;
case TYPE_KEYGUARD:
if (mKeyguard != null) {
return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
@@ -1401,8 +1419,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if ((fl & (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR))
== (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) {
contentInset.set(mCurLeft, mCurTop,
- (mScreenLeft+mScreenWidth) - mCurRight,
- (mScreenTop+mScreenHeight) - mCurBottom);
+ (mRestrictedScreenLeft+mRestrictedScreenWidth) - mCurRight,
+ (mRestrictedScreenTop+mRestrictedScreenHeight) - mCurBottom);
} else {
contentInset.setEmpty();
}
@@ -1410,9 +1428,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/** {@inheritDoc} */
public void beginLayoutLw(int displayWidth, int displayHeight) {
- mScreenLeft = mScreenTop = 0;
- mScreenWidth = displayWidth;
- mScreenHeight = displayHeight;
+ mUnrestrictedScreenLeft = mUnrestrictedScreenTop = 0;
+ mUnrestrictedScreenWidth = displayWidth;
+ mUnrestrictedScreenHeight = displayHeight;
+ mRestrictedScreenLeft = mRestrictedScreenTop = 0;
+ mRestrictedScreenWidth = displayWidth;
+ mRestrictedScreenHeight = displayHeight;
mDockLeft = mContentLeft = mCurLeft = 0;
mDockTop = mContentTop = mCurTop = 0;
mDockRight = mContentRight = mCurRight = displayWidth;
@@ -1451,16 +1472,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} else {
// Status bar can't go away; the part of the screen it
// covers does not exist for anything behind it.
- if (mScreenTop == r.top) {
- mScreenTop = r.bottom;
- mScreenHeight -= (r.bottom-r.top);
- } else if ((mScreenHeight-mScreenTop) == r.bottom) {
- mScreenHeight -= (r.bottom-r.top);
+ if (mRestrictedScreenTop == r.top) {
+ mRestrictedScreenTop = r.bottom;
+ mRestrictedScreenHeight -= (r.bottom-r.top);
+ } else if ((mRestrictedScreenHeight-mRestrictedScreenTop) == r.bottom) {
+ mRestrictedScreenHeight -= (r.bottom-r.top);
}
- mContentTop = mCurTop = mDockTop = mScreenTop;
- mContentBottom = mCurBottom = mDockBottom = mScreenTop+mScreenHeight;
- if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mScreenTop=" + mScreenTop
- + " mScreenHeight=" + mScreenHeight);
+ mContentTop = mCurTop = mDockTop = mRestrictedScreenTop;
+ mContentBottom = mCurBottom = mDockBottom
+ = mRestrictedScreenTop + mRestrictedScreenHeight;
+ if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mRestrictedScreenTop="
+ + mRestrictedScreenTop
+ + " mRestrictedScreenHeight=" + mRestrictedScreenHeight);
}
}
}
@@ -1552,10 +1575,21 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// frame is the same as the one we are attached to.
setAttachedWindowFrames(win, fl, sim, attached, true, pf, df, cf, vf);
} else {
- pf.left = df.left = mScreenLeft;
- pf.top = df.top = mScreenTop;
- pf.right = df.right = mScreenLeft+mScreenWidth;
- pf.bottom = df.bottom = mScreenTop+mScreenHeight;
+ if (attrs.type == TYPE_STATUS_BAR_PANEL) {
+ // Status bar panels are the only windows who can go on top of
+ // the status bar. They are protected by the STATUS_BAR_SERVICE
+ // permission, so they have the same privileges as the status
+ // bar itself.
+ pf.left = df.left = mUnrestrictedScreenLeft;
+ pf.top = df.top = mUnrestrictedScreenTop;
+ pf.right = df.right = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
+ pf.bottom = df.bottom = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+ } else {
+ pf.left = df.left = mRestrictedScreenLeft;
+ pf.top = df.top = mRestrictedScreenTop;
+ pf.right = df.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
+ pf.bottom = df.bottom = mRestrictedScreenTop+mRestrictedScreenHeight;
+ }
if (adjust != SOFT_INPUT_ADJUST_RESIZE) {
cf.left = mDockLeft;
cf.top = mDockTop;
@@ -1579,10 +1613,20 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0) {
// A window that has requested to fill the entire screen just
// gets everything, period.
- pf.left = df.left = cf.left = mScreenLeft;
- pf.top = df.top = cf.top = mScreenTop;
- pf.right = df.right = cf.right = mScreenLeft+mScreenWidth;
- pf.bottom = df.bottom = cf.bottom = mScreenTop+mScreenHeight;
+ if (attrs.type == TYPE_STATUS_BAR_PANEL) {
+ pf.left = df.left = cf.left = mUnrestrictedScreenLeft;
+ pf.top = df.top = cf.top = mUnrestrictedScreenTop;
+ pf.right = df.right = cf.right
+ = mUnrestrictedScreenLeft+mUnrestrictedScreenWidth;
+ pf.bottom = df.bottom = cf.bottom
+ = mUnrestrictedScreenTop+mUnrestrictedScreenHeight;
+ } else {
+ pf.left = df.left = cf.left = mRestrictedScreenLeft;
+ pf.top = df.top = cf.top = mRestrictedScreenTop;
+ pf.right = df.right = cf.right = mRestrictedScreenLeft+mRestrictedScreenWidth;
+ pf.bottom = df.bottom = cf.bottom
+ = mRestrictedScreenTop+mRestrictedScreenHeight;
+ }
if (adjust != SOFT_INPUT_ADJUST_NOTHING) {
vf.left = mCurLeft;
vf.top = mCurTop;
@@ -1841,9 +1885,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
rect.union(w.getShownFrameLw());
}
}
- final int insetw = mScreenWidth/10;
- final int inseth = mScreenHeight/10;
- if (rect.contains(insetw, inseth, mScreenWidth-insetw, mScreenHeight-inseth)) {
+ final int insetw = mRestrictedScreenWidth/10;
+ final int inseth = mRestrictedScreenHeight/10;
+ if (rect.contains(insetw, inseth, mRestrictedScreenWidth-insetw,
+ mRestrictedScreenHeight-inseth)) {
// All of the status bar windows put together cover the
// screen, so the app can't be seen. (Note this test doesn't
// work if the rects of these windows are at off offsets or
@@ -2302,7 +2347,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return getCurrentPortraitRotation(lastRotation);
}
- mOrientationListener.setAllow180Rotation(
+ mOrientationListener.setAllow180Rotation(mAllowAllRotations ||
orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
// case for nosensor meaning ignore sensor and consider only lid
diff --git a/services/audioflinger/A2dpAudioInterface.cpp b/services/audioflinger/A2dpAudioInterface.cpp
index 995e31c..aee01ab 100644
--- a/services/audioflinger/A2dpAudioInterface.cpp
+++ b/services/audioflinger/A2dpAudioInterface.cpp
@@ -23,10 +23,13 @@
#include "A2dpAudioInterface.h"
#include "audio/liba2dp.h"
-
+#include <hardware_legacy/power.h>
namespace android {
+static const char *sA2dpWakeLock = "A2dpOutputStream";
+#define MAX_WRITE_RETRIES 5
+
// ----------------------------------------------------------------------------
//AudioHardwareInterface* A2dpAudioInterface::createA2dpInterface()
@@ -263,44 +266,55 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
{
LOGV("A2dpAudioStreamOut destructor");
- standby();
close();
LOGV("A2dpAudioStreamOut destructor returning from close()");
}
ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
{
- Mutex::Autolock lock(mLock);
-
- size_t remaining = bytes;
status_t status = -1;
+ {
+ Mutex::Autolock lock(mLock);
- if (!mBluetoothEnabled || mClosing || mSuspended) {
- LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
- mBluetoothEnabled %d, mClosing %d, mSuspended %d",
- mBluetoothEnabled, mClosing, mSuspended);
- goto Error;
- }
-
- status = init();
- if (status < 0)
- goto Error;
+ size_t remaining = bytes;
- while (remaining > 0) {
- status = a2dp_write(mData, buffer, remaining);
- if (status <= 0) {
- LOGE("a2dp_write failed err: %d\n", status);
+ if (!mBluetoothEnabled || mClosing || mSuspended) {
+ LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
+ mBluetoothEnabled %d, mClosing %d, mSuspended %d",
+ mBluetoothEnabled, mClosing, mSuspended);
goto Error;
}
- remaining -= status;
- buffer = ((char *)buffer) + status;
- }
- mStandby = false;
+ if (mStandby) {
+ acquire_wake_lock (PARTIAL_WAKE_LOCK, sA2dpWakeLock);
+ mStandby = false;
+ }
+
+ status = init();
+ if (status < 0)
+ goto Error;
+
+ int retries = MAX_WRITE_RETRIES;
+ while (remaining > 0 && retries) {
+ status = a2dp_write(mData, buffer, remaining);
+ if (status < 0) {
+ LOGE("a2dp_write failed err: %d\n", status);
+ goto Error;
+ }
+ if (status == 0) {
+ retries--;
+ }
+ remaining -= status;
+ buffer = (char *)buffer + status;
+ }
- return bytes;
+ return bytes;
+ }
Error:
+
+ standby();
+
// Simulate audio output timing in case of error
usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);
@@ -324,19 +338,22 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::init()
status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
{
- int result = 0;
-
- if (mClosing) {
- LOGV("Ignore standby, closing");
- return result;
- }
-
Mutex::Autolock lock(mLock);
+ return standby_l();
+}
+
+status_t A2dpAudioInterface::A2dpAudioStreamOut::standby_l()
+{
+ int result = NO_ERROR;
if (!mStandby) {
- result = a2dp_stop(mData);
- if (result == 0)
- mStandby = true;
+ LOGV_IF(mClosing || !mBluetoothEnabled, "Standby skip stop: closing %d enabled %d",
+ mClosing, mBluetoothEnabled);
+ if (!mClosing && mBluetoothEnabled) {
+ result = a2dp_stop(mData);
+ }
+ release_wake_lock(sA2dpWakeLock);
+ mStandby = true;
}
return result;
@@ -362,6 +379,9 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& ke
key = String8("closing");
if (param.get(key, value) == NO_ERROR) {
mClosing = (value == "true");
+ if (mClosing) {
+ standby();
+ }
param.remove(key);
}
key = AudioParameter::keyRouting;
@@ -444,6 +464,7 @@ status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
status_t A2dpAudioInterface::A2dpAudioStreamOut::close_l()
{
+ standby_l();
if (mData) {
LOGV("A2dpAudioStreamOut::close_l() calling a2dp_cleanup(mData)");
a2dp_cleanup(mData);
diff --git a/services/audioflinger/A2dpAudioInterface.h b/services/audioflinger/A2dpAudioInterface.h
index 48154f9..cef1926 100644
--- a/services/audioflinger/A2dpAudioInterface.h
+++ b/services/audioflinger/A2dpAudioInterface.h
@@ -103,6 +103,7 @@ private:
status_t setAddress(const char* address);
status_t setBluetoothEnabled(bool enabled);
status_t setSuspended(bool onOff);
+ status_t standby_l();
private:
int mFd;
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index eca37b7..723432d 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1300,7 +1300,18 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
public void setInputMethod(IBinder token, String id) {
- setInputMethodWithSubtype(token, id, NOT_A_SUBTYPE_ID);
+ setInputMethodWithSubtypeId(token, id, NOT_A_SUBTYPE_ID);
+ }
+
+ public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) {
+ synchronized (mMethodMap) {
+ if (subtype != null) {
+ setInputMethodWithSubtypeId(token, id, getSubtypeIdFromHashCode(
+ mMethodMap.get(id), subtype.hashCode()));
+ } else {
+ setInputMethod(token, id);
+ }
+ }
}
public boolean switchToLastInputMethod(IBinder token) {
@@ -1309,7 +1320,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (lastIme != null) {
InputMethodInfo imi = mMethodMap.get(lastIme.first);
if (imi != null) {
- setInputMethodWithSubtype(token, lastIme.first, getSubtypeIdFromHashCode(
+ setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode(
imi, Integer.valueOf(lastIme.second)));
return true;
}
@@ -1318,7 +1329,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- private void setInputMethodWithSubtype(IBinder token, String id, int subtypeId) {
+ private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) {
synchronized (mMethodMap) {
if (token == null) {
if (mContext.checkCallingOrSelfPermission(
@@ -1909,11 +1920,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
- ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
- for (int i = 0; i < subtypes.size(); ++i) {
- InputMethodSubtype ims = subtypes.get(i);
- if (subtypeHashCode == ims.hashCode()) {
- return i;
+ if (imi != null) {
+ ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
+ for (int i = 0; i < subtypes.size(); ++i) {
+ InputMethodSubtype ims = subtypes.get(i);
+ if (subtypeHashCode == ims.hashCode()) {
+ return i;
+ }
}
}
return NOT_A_SUBTYPE_ID;
diff --git a/services/java/com/android/server/ScreenRotationAnimation.java b/services/java/com/android/server/ScreenRotationAnimation.java
new file mode 100644
index 0000000..299567a
--- /dev/null
+++ b/services/java/com/android/server/ScreenRotationAnimation.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server; // TODO: use com.android.server.wm, once things move there
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.util.Slog;
+import android.view.Display;
+import android.view.Surface;
+import android.view.SurfaceSession;
+
+class ScreenRotationAnimation {
+ private static final String TAG = "ScreenRotationAnimation";
+
+ Surface mSurface;
+ int mWidth, mHeight;
+
+ int mBaseRotation;
+ int mCurRotation;
+ int mDeltaRotation;
+
+ final Matrix mMatrix = new Matrix();
+ final float[] mTmpFloats = new float[9];
+
+ public ScreenRotationAnimation(Display display, SurfaceSession session) {
+ final DisplayMetrics dm = new DisplayMetrics();
+ display.getMetrics(dm);
+
+ Bitmap screenshot = Surface.screenshot(0, 0);
+
+ if (screenshot != null) {
+ // Screenshot does NOT include rotation!
+ mBaseRotation = 0;
+ mWidth = screenshot.getWidth();
+ mHeight = screenshot.getHeight();
+ } else {
+ // Just in case.
+ mBaseRotation = display.getRotation();
+ mWidth = dm.widthPixels;
+ mHeight = dm.heightPixels;
+ }
+
+ Surface.openTransaction();
+ if (mSurface != null) {
+ mSurface.destroy();
+ mSurface = null;
+ }
+ try {
+ mSurface = new Surface(session, 0, "FreezeSurface",
+ -1, mWidth, mHeight, PixelFormat.OPAQUE, 0);
+ } catch (Surface.OutOfResourcesException e) {
+ Slog.w(TAG, "Unable to allocate freeze surface", e);
+ }
+ mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 200);
+ setRotation(display.getRotation());
+
+ Rect dirty = new Rect(0, 0, mWidth, mHeight);
+ Canvas c = null;
+ try {
+ c = mSurface.lockCanvas(dirty);
+ } catch (IllegalArgumentException e) {
+ Slog.w(TAG, "Unable to lock surface", e);
+ return;
+ } catch (Surface.OutOfResourcesException e) {
+ Slog.w(TAG, "Unable to lock surface", e);
+ return;
+ }
+ if (c == null) {
+ Slog.w(TAG, "Null surface");
+ return;
+ }
+
+ if (screenshot != null) {
+ c.drawBitmap(screenshot, 0, 0, new Paint(0));
+ } else {
+ c.drawColor(Color.GREEN);
+ }
+
+ mSurface.unlockCanvasAndPost(c);
+ Surface.closeTransaction();
+
+ screenshot.recycle();
+ }
+
+ // Must be called while in a transaction.
+ public void setRotation(int rotation) {
+ mCurRotation = rotation;
+ int delta = mCurRotation - mBaseRotation;
+ if (delta < 0) delta += 4;
+ mDeltaRotation = delta;
+
+ switch (delta) {
+ case Surface.ROTATION_0:
+ mMatrix.reset();
+ break;
+ case Surface.ROTATION_90:
+ mMatrix.setRotate(90, 0, 0);
+ mMatrix.postTranslate(0, mWidth);
+ break;
+ case Surface.ROTATION_180:
+ mMatrix.setRotate(180, 0, 0);
+ mMatrix.postTranslate(mWidth, mHeight);
+ break;
+ case Surface.ROTATION_270:
+ mMatrix.setRotate(270, 0, 0);
+ mMatrix.postTranslate(mHeight, 0);
+ break;
+ }
+
+ mMatrix.getValues(mTmpFloats);
+ mSurface.setPosition((int)mTmpFloats[Matrix.MTRANS_X],
+ (int)mTmpFloats[Matrix.MTRANS_Y]);
+ mSurface.setMatrix(
+ mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_X],
+ mTmpFloats[Matrix.MSKEW_Y], mTmpFloats[Matrix.MSCALE_Y]);
+
+ if (false) {
+ float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
+ float[] dstPnts = new float[8];
+ mMatrix.mapPoints(dstPnts, srcPnts);
+ Slog.i(TAG, "**** ROTATION: " + delta);
+ Slog.i(TAG, "Original : (" + srcPnts[0] + "," + srcPnts[1]
+ + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
+ Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
+ + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
+ }
+ }
+
+ public void dismiss() {
+ mSurface.destroy();
+ }
+}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index b3ea836..89512ae 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -201,6 +201,12 @@ public class WindowManagerService extends IWindowManager.Stub
*/
static final int DEFAULT_FADE_IN_OUT_DURATION = 400;
+ /**
+ * If true, the window manager will do its own custom freezing and general
+ * management of the screen during rotation.
+ */
+ static final boolean CUSTOM_SCREEN_ROTATION = true;
+
// Maximum number of milliseconds to wait for input event injection.
// FIXME is this value reasonable?
private static final int INJECTION_TIMEOUT_MILLIS = 30 * 1000;
@@ -374,6 +380,7 @@ public class WindowManagerService extends IWindowManager.Stub
boolean mBlurShown;
Watermark mWatermark;
StrictModeFlash mStrictModeFlash;
+ ScreenRotationAnimation mScreenRotationAnimation;
int mTransactionSequence = 0;
@@ -4911,6 +4918,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ public void setStrictModeVisualIndicatorPreference(String value) {
+ SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
+ }
+
public void freezeRotation() {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"setRotation()")) {
@@ -4998,7 +5009,18 @@ public class WindowManagerService extends IWindowManager.Stub
Slog.i(TAG, "Setting rotation to " + rotation + ", animFlags=" + animFlags);
mInputManager.setDisplayOrientation(0, rotation);
if (mDisplayEnabled) {
- Surface.setOrientation(0, rotation, animFlags);
+ if (CUSTOM_SCREEN_ROTATION) {
+ Surface.freezeDisplay(0);
+ Surface.openTransaction();
+ if (mScreenRotationAnimation != null) {
+ mScreenRotationAnimation.setRotation(rotation);
+ }
+ Surface.closeTransaction();
+ Surface.setOrientation(0, rotation, animFlags);
+ Surface.unfreezeDisplay(0);
+ } else {
+ Surface.setOrientation(0, rotation, animFlags);
+ }
}
for (int i=mWindows.size()-1; i>=0; i--) {
WindowState w = mWindows.get(i);
@@ -10817,7 +10839,14 @@ public class WindowManagerService extends IWindowManager.Stub
File file = new File("/data/system/frozen");
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
- Surface.freezeDisplay(0);
+
+ if (CUSTOM_SCREEN_ROTATION) {
+ if (mScreenRotationAnimation == null) {
+ mScreenRotationAnimation = new ScreenRotationAnimation(mDisplay, mFxSession);
+ }
+ } else {
+ Surface.freezeDisplay(0);
+ }
}
private void stopFreezingDisplayLocked() {
@@ -10834,7 +10863,15 @@ public class WindowManagerService extends IWindowManager.Stub
if (PROFILE_ORIENTATION) {
Debug.stopMethodTracing();
}
- Surface.unfreezeDisplay(0);
+
+ if (CUSTOM_SCREEN_ROTATION) {
+ if (mScreenRotationAnimation != null) {
+ mScreenRotationAnimation.dismiss();
+ mScreenRotationAnimation = null;
+ }
+ } else {
+ Surface.unfreezeDisplay(0);
+ }
mInputMonitor.thawInputDispatchingLw();
diff --git a/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java b/telephony/java/com/android/internal/telephony/ApnSetting.java
index 05527af..5af8e35 100644
--- a/telephony/java/com/android/internal/telephony/gsm/ApnSetting.java
+++ b/telephony/java/com/android/internal/telephony/ApnSetting.java
@@ -14,27 +14,26 @@
* limitations under the License.
*/
-package com.android.internal.telephony.gsm;
+package com.android.internal.telephony;
-import com.android.internal.telephony.*;
/**
* This class represents a apn setting for create PDP link
*/
public class ApnSetting {
- String carrier;
- String apn;
- String proxy;
- String port;
- String mmsc;
- String mmsProxy;
- String mmsPort;
- String user;
- String password;
- int authType;
+ public String carrier;
+ public String apn;
+ public String proxy;
+ public String port;
+ public String mmsc;
+ public String mmsProxy;
+ public String mmsPort;
+ public String user;
+ public String password;
+ public int authType;
public String[] types;
- int id;
- String numeric;
+ public int id;
+ public String numeric;
public ApnSetting(int id, String numeric, String carrier, String apn, String proxy, String port,
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index c3ad9e6..2536745 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -16,7 +16,6 @@
package com.android.internal.telephony;
-import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.util.HierarchicalState;
import com.android.internal.util.HierarchicalStateMachine;
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 9c738ec..8f3fa1b 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -16,8 +16,6 @@
package com.android.internal.telephony;
-import com.android.internal.telephony.cdma.CDMAPhone;
-
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -231,6 +229,9 @@ public abstract class DataConnectionTracker extends Handler {
protected HashMap<Integer, DataConnection> mDataConnections =
new HashMap<Integer, DataConnection>();
+ /* Currently active APN */
+ protected ApnSetting mActiveApn;
+
protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
{
@Override
@@ -343,6 +344,40 @@ public abstract class DataConnectionTracker extends Handler {
return new ArrayList<DataConnection>(mDataConnections.values());
}
+ protected boolean isApnTypeActive(String type) {
+ // TODO: support simultaneous with List instead
+ return mActiveApn != null && mActiveApn.canHandleType(type);
+ }
+
+ public String[] getActiveApnTypes() {
+ String[] result;
+ if (mActiveApn != null) {
+ result = mActiveApn.types;
+ } else {
+ result = new String[1];
+ result[0] = Phone.APN_TYPE_DEFAULT;
+ }
+ return result;
+ }
+
+ public String getActiveApnType() {
+ String result;
+ if (mActiveApn != null) {
+ result = apnIdToType(mActiveApn.id);
+ } else {
+ result = null;
+ }
+ return result;
+ }
+
+ protected String getActiveApnString() {
+ String result = null;
+ if (mActiveApn != null) {
+ result = mActiveApn.apn;
+ }
+ return result;
+ }
+
/**
* The data connection is expected to be setup while device
* 1. has Icc card
@@ -533,14 +568,8 @@ public abstract class DataConnectionTracker extends Handler {
}
}
- protected abstract boolean isApnTypeActive(String type);
-
protected abstract boolean isApnTypeAvailable(String type);
- protected abstract String[] getActiveApnTypes();
-
- protected abstract String getActiveApnString();
-
protected abstract void setState(State s);
protected LinkProperties getLinkProperties(String apnType) {
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 8072c44..c645da5 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -20,7 +20,6 @@ import android.os.Message;
import android.util.Log;
import com.android.internal.telephony.DataConnection;
-import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.RetryManager;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index d7ff0c5..024ef33 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -32,6 +32,7 @@ import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
+import com.android.internal.telephony.ApnSetting;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.DataConnection.FailCause;
@@ -39,7 +40,6 @@ import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.EventLogTags;
import com.android.internal.telephony.RetryManager;
-import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.telephony.Phone;
import java.util.ArrayList;
@@ -89,9 +89,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
Phone.APN_TYPE_MMS,
Phone.APN_TYPE_HIPRI };
- // if we have no active Apn this is null
- protected ApnSetting mActiveApn;
-
/* Constructor */
CdmaDataConnectionTracker(CDMAPhone p) {
@@ -158,11 +155,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
@Override
- protected boolean isApnTypeActive(String type) {
- return mActiveApn != null && mActiveApn.canHandleType(type);
- }
-
- @Override
protected boolean isApnTypeAvailable(String type) {
for (String s : mSupportedApnTypes) {
if (TextUtils.equals(type, s)) {
@@ -172,23 +164,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
return false;
}
- @Override
- protected String[] getActiveApnTypes() {
- String[] result;
- if (mActiveApn != null) {
- result = mActiveApn.types;
- } else {
- result = new String[1];
- result[0] = Phone.APN_TYPE_DEFAULT;
- }
- return result;
- }
-
- @Override
- protected String getActiveApnString() {
- return null;
- }
-
/**
* The data connection is expected to be setup while device
* 1. has ruim card or non-volatile data store
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index d428099..dfba8d6 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -20,6 +20,7 @@ import android.os.Message;
import android.util.Log;
import android.util.Patterns;
+import com.android.internal.telephony.ApnSetting;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index bbfdd31..b41402c 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -40,6 +40,7 @@ import android.util.EventLog;
import android.util.Log;
import com.android.internal.R;
+import com.android.internal.telephony.ApnSetting;
import com.android.internal.telephony.DataCallState;
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.DataConnectionTracker;
@@ -108,9 +109,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
private int mWaitingApnsPermanentFailureCountDown = 0;
private ApnSetting mPreferredApn = null;
- /* Currently active APN */
- protected ApnSetting mActiveApn;
-
/** The DataConnection being setup */
private GsmDataConnection mPendingDataConnection;
@@ -211,27 +209,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
}
- @Override
- public String[] getActiveApnTypes() {
- String[] result;
- if (mActiveApn != null) {
- result = mActiveApn.types;
- } else {
- result = new String[1];
- result[0] = Phone.APN_TYPE_DEFAULT;
- }
- return result;
- }
-
- @Override
- protected String getActiveApnString() {
- String result = null;
- if (mActiveApn != null) {
- result = mActiveApn.apn;
- }
- return result;
- }
-
/**
* The data connection is expected to be setup while device
* 1. has sim card
@@ -256,12 +233,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker {
}
@Override
- protected boolean isApnTypeActive(String type) {
- // TODO: support simultaneous with List instead
- return mActiveApn != null && mActiveApn.canHandleType(type);
- }
-
- @Override
protected boolean isApnTypeAvailable(String type) {
if (type.equals(Phone.APN_TYPE_DUN)) {
return (fetchDunApn() != null);
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index d545018..56beada 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -112,6 +112,7 @@ public class FileFilter {
ignoreResultList.add("fast/events/touch/touch-coords-in-zoom-and-scroll.html"); // Requires eventSender.zoomPageIn(),zoomPageOut()
ignoreResultList.add("fast/events/touch/touch-target.html"); // Requires multi-touch gestures not supported by Android system
ignoreResultList.add("fast/workers"); // workers not supported
+ ignoreResultList.add("http/tests/cookies/third-party-cookie-relaxing.html"); // We don't support conditional acceptance of third-party cookies
ignoreResultList.add("http/tests/eventsource/workers"); // workers not supported
ignoreResultList.add("http/tests/workers"); // workers not supported
ignoreResultList.add("http/tests/xmlhttprequest/workers"); // workers not supported
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index f0d2fee..6ec223b 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -42,7 +42,7 @@ static void usage() {
}
static FileType getFileType(const char* filename) {
- char *extension = strrchr(filename, '.');
+ const char *extension = strrchr(filename, '.');
if (extension) {
if (strcmp(extension, ".kl") == 0) {
return FILETYPE_KEYLAYOUT;