summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt93
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java12
-rw-r--r--core/java/android/app/ContextImpl.java2
-rw-r--r--core/java/android/app/TaskStackBuilder.java12
-rw-r--r--core/java/android/appwidget/AppWidgetHostView.java24
-rw-r--r--core/java/android/content/SyncStorageEngine.java26
-rw-r--r--core/java/android/content/res/AssetFileDescriptor.java3
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java16
-rw-r--r--core/java/android/net/nsd/NsdManager.java677
-rw-r--r--core/java/android/net/nsd/NsdServiceInfo.java (renamed from core/java/android/net/nsd/DnsSdServiceInfo.java)22
-rw-r--r--core/java/android/os/IBinder.java3
-rw-r--r--core/java/android/os/ServiceManagerNative.java36
-rw-r--r--core/java/android/os/SystemProperties.java29
-rw-r--r--core/java/android/os/Trace.java18
-rw-r--r--core/java/android/preference/MultiCheckPreference.java16
-rw-r--r--core/java/android/provider/Settings.java20
-rw-r--r--core/java/android/view/View.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java26
-rw-r--r--core/java/android/view/WindowManagerImpl.java19
-rw-r--r--core/java/android/view/WindowManagerPolicy.java2
-rw-r--r--core/java/android/webkit/WebViewClassic.java80
-rw-r--r--core/java/android/widget/AbsListView.java136
-rw-r--r--core/java/android/widget/SpellChecker.java23
-rw-r--r--core/java/android/widget/TextView.java69
-rw-r--r--core/java/com/android/internal/content/PackageHelper.java12
-rw-r--r--core/java/com/android/internal/util/FileRotator.java63
-rw-r--r--core/java/com/android/internal/view/menu/ListMenuPresenter.java8
-rw-r--r--core/java/com/android/internal/view/menu/MenuPopupHelper.java8
-rw-r--r--core/jni/android_os_SystemProperties.cpp50
-rw-r--r--core/jni/android_util_Binder.cpp6
-rw-r--r--core/res/res/values-sw600dp/dimens.xml4
-rw-r--r--core/res/res/values/dimens.xml4
-rw-r--r--core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java7
-rw-r--r--core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java4
-rw-r--r--data/fonts/Android.mk2
-rw-r--r--data/fonts/Roboto-Light.ttfbin0 -> 173776 bytes
-rw-r--r--data/fonts/Roboto-LightItalic.ttfbin0 -> 177000 bytes
-rw-r--r--data/fonts/fonts.mk2
-rw-r--r--data/fonts/system_fonts.xml10
-rw-r--r--media/java/android/media/AudioService.java236
-rw-r--r--media/java/android/media/AudioSystem.java6
-rw-r--r--media/java/android/media/MediaExtractor.java5
-rw-r--r--media/java/android/media/MediaPlayer.java58
-rw-r--r--media/jni/android_media_MediaExtractor.cpp2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java128
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java15
-rw-r--r--packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.pngbin0 -> 232 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.pngbin0 -> 716 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.pngbin3026 -> 712 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.pngbin0 -> 211 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.pngbin0 -> 414 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.pngbin1565 -> 532 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.pngbin0 -> 2641 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.pngbin0 -> 1496 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.pngbin0 -> 4014 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.pngbin0 -> 2641 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.pngbin0 -> 1496 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.pngbin0 -> 4014 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.pngbin0 -> 249 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.pngbin0 -> 822 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.pngbin5166 -> 1001 bytes
-rw-r--r--packages/SystemUI/res/drawable/ic_notify_rotation.xml27
-rw-r--r--packages/SystemUI/res/drawable/status_bar_close.xml23
-rw-r--r--packages/SystemUI/res/layout-land/status_bar_recent_panel.xml2
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml86
-rw-r--r--packages/SystemUI/res/layout/status_bar_tracking.xml60
-rw-r--r--packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml (renamed from core/java/android/net/nsd/NetworkServiceInfo.java)31
-rw-r--r--packages/SystemUI/res/values-sw600dp-port/dimens.xml21
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml10
-rw-r--r--packages/SystemUI/res/values/colors.xml2
-rw-r--r--packages/SystemUI/res/values/dimens.xml14
-rw-r--r--packages/SystemUI/src/com/android/systemui/SearchPanelView.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java2
-rw-r--r--policy/src/com/android/internal/policy/impl/FaceUnlock.java18
-rw-r--r--policy/src/com/android/internal/policy/impl/LockScreen.java11
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java2
-rw-r--r--services/input/EventHub.cpp23
-rw-r--r--services/input/InputDispatcher.cpp2
-rw-r--r--services/java/com/android/server/InputMethodManagerService.java138
-rwxr-xr-xservices/java/com/android/server/NotificationManagerService.java2
-rw-r--r--services/java/com/android/server/NsdService.java497
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java41
-rwxr-xr-xservices/java/com/android/server/am/ActivityStack.java4
-rw-r--r--services/java/com/android/server/net/NetworkStatsRecorder.java37
-rw-r--r--services/java/com/android/server/net/NetworkStatsService.java4
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java111
-rw-r--r--services/java/com/android/server/wm/InputMonitor.java4
-rw-r--r--services/java/com/android/server/wm/WindowAnimator.java9
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java39
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java50
-rw-r--r--telephony/java/android/telephony/PhoneNumberUtils.java21
-rw-r--r--tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java5
96 files changed, 2110 insertions, 1328 deletions
diff --git a/api/current.txt b/api/current.txt
index 8e8c750..a8bf949 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2017,6 +2017,7 @@ package android.accessibilityservice {
method protected void onServiceConnected();
method public final boolean performGlobalAction(int);
method public final void setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo);
+ field public static final int GESTURE_DOUBLE_TAP = 17; // 0x11
field public static final int GESTURE_SWIPE_DOWN = 2; // 0x2
field public static final int GESTURE_SWIPE_DOWN_AND_LEFT = 15; // 0xf
field public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16; // 0x10
@@ -2033,8 +2034,7 @@ package android.accessibilityservice {
field public static final int GESTURE_SWIPE_UP_AND_DOWN = 7; // 0x7
field public static final int GESTURE_SWIPE_UP_AND_LEFT = 13; // 0xd
field public static final int GESTURE_SWIPE_UP_AND_RIGHT = 14; // 0xe
- field public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18; // 0x12
- field public static final int GESTURE_TWO_FINGER_TAP = 17; // 0x11
+ field public static final int GESTURE_TAP_AND_HOLD = 18; // 0x12
field public static final int GLOBAL_ACTION_BACK = 1; // 0x1
field public static final int GLOBAL_ACTION_HOME = 2; // 0x2
field public static final int GLOBAL_ACTION_NOTIFICATIONS = 4; // 0x4
@@ -11236,7 +11236,6 @@ package android.media {
method public void unselectTrack(int);
field public static final int SAMPLE_FLAG_ENCRYPTED = 2; // 0x2
field public static final int SAMPLE_FLAG_SYNC = 1; // 0x1
- field public static final int SEEK_TO_CLOSEST = 3; // 0x3
field public static final int SEEK_TO_CLOSEST_SYNC = 2; // 0x2
field public static final int SEEK_TO_NEXT_SYNC = 1; // 0x1
field public static final int SEEK_TO_PREVIOUS_SYNC = 0; // 0x0
@@ -12709,21 +12708,6 @@ package android.net.http {
package android.net.nsd {
- public class DnsSdServiceInfo implements android.os.Parcelable {
- ctor public DnsSdServiceInfo();
- method public int describeContents();
- method public java.net.InetAddress getHost();
- method public int getPort();
- method public java.lang.String getServiceName();
- method public java.lang.String getServiceType();
- method public void setHost(java.net.InetAddress);
- method public void setPort(int);
- method public void setServiceName(java.lang.String);
- method public void setServiceType(java.lang.String);
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator CREATOR;
- }
-
public class DnsSdTxtRecord implements android.os.Parcelable {
ctor public DnsSdTxtRecord();
ctor public DnsSdTxtRecord(byte[]);
@@ -12740,53 +12724,56 @@ package android.net.nsd {
field public static final android.os.Parcelable.Creator CREATOR;
}
- public class NsdManager {
- method public void deinitialize(android.net.nsd.NsdManager.Channel);
- method public void discoverServices(android.net.nsd.NsdManager.Channel, java.lang.String, android.net.nsd.NsdManager.DnsSdDiscoveryListener);
- method public void initialize(android.content.Context, android.os.Looper, android.net.nsd.NsdManager.ChannelListener);
- method public void registerService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, int, android.net.nsd.NsdManager.DnsSdRegisterListener);
- method public void resolveService(android.net.nsd.NsdManager.Channel, java.lang.String, java.lang.String, android.net.nsd.NsdManager.DnsSdResolveListener);
- method public void stopServiceDiscovery(android.net.nsd.NsdManager.Channel, android.net.nsd.NsdManager.ActionListener);
- method public void unregisterService(android.net.nsd.NsdManager.Channel, int, android.net.nsd.NsdManager.ActionListener);
+ public final class NsdManager {
+ method public void discoverServices(java.lang.String, int, android.net.nsd.NsdManager.DiscoveryListener);
+ method public void registerService(android.net.nsd.NsdServiceInfo, int, android.net.nsd.NsdManager.RegistrationListener);
+ method public void resolveService(android.net.nsd.NsdServiceInfo, android.net.nsd.NsdManager.ResolveListener);
+ method public void stopServiceDiscovery(android.net.nsd.NsdManager.DiscoveryListener);
+ method public void unregisterService(android.net.nsd.NsdManager.RegistrationListener);
field public static final java.lang.String ACTION_NSD_STATE_CHANGED = "android.net.nsd.STATE_CHANGED";
- field public static final int ALREADY_ACTIVE = 3; // 0x3
- field public static final int BUSY = 2; // 0x2
- field public static final int ERROR = 0; // 0x0
field public static final java.lang.String EXTRA_NSD_STATE = "nsd_state";
- field public static final int MAX_REGS_REACHED = 4; // 0x4
+ field public static final int FAILURE_ALREADY_ACTIVE = 3; // 0x3
+ field public static final int FAILURE_INTERNAL_ERROR = 0; // 0x0
+ field public static final int FAILURE_MAX_LIMIT = 4; // 0x4
field public static final int NSD_STATE_DISABLED = 1; // 0x1
field public static final int NSD_STATE_ENABLED = 2; // 0x2
- field public static final int UNSUPPORTED = 1; // 0x1
- }
-
- public static abstract interface NsdManager.ActionListener {
- method public abstract void onFailure(int);
- method public abstract void onSuccess();
+ field public static final int PROTOCOL_DNS_SD = 1; // 0x1
}
- public static class NsdManager.Channel {
+ public static abstract interface NsdManager.DiscoveryListener {
+ method public abstract void onDiscoveryStarted(java.lang.String);
+ method public abstract void onDiscoveryStopped(java.lang.String);
+ method public abstract void onServiceFound(android.net.nsd.NsdServiceInfo);
+ method public abstract void onServiceLost(android.net.nsd.NsdServiceInfo);
+ method public abstract void onStartDiscoveryFailed(java.lang.String, int);
+ method public abstract void onStopDiscoveryFailed(java.lang.String, int);
}
- public static abstract interface NsdManager.ChannelListener {
- method public abstract void onChannelConnected(android.net.nsd.NsdManager.Channel);
- method public abstract void onChannelDisconnected();
+ public static abstract interface NsdManager.RegistrationListener {
+ method public abstract void onRegistrationFailed(android.net.nsd.NsdServiceInfo, int);
+ method public abstract void onServiceRegistered(android.net.nsd.NsdServiceInfo);
+ method public abstract void onServiceUnregistered(android.net.nsd.NsdServiceInfo);
+ method public abstract void onUnregistrationFailed(android.net.nsd.NsdServiceInfo, int);
}
- public static abstract interface NsdManager.DnsSdDiscoveryListener {
- method public abstract void onFailure(int);
- method public abstract void onServiceFound(android.net.nsd.DnsSdServiceInfo);
- method public abstract void onServiceLost(android.net.nsd.DnsSdServiceInfo);
- method public abstract void onStarted(java.lang.String);
+ public static abstract interface NsdManager.ResolveListener {
+ method public abstract void onResolveFailed(android.net.nsd.NsdServiceInfo, int);
+ method public abstract void onServiceResolved(android.net.nsd.NsdServiceInfo);
}
- public static abstract interface NsdManager.DnsSdRegisterListener {
- method public abstract void onFailure(int);
- method public abstract void onServiceRegistered(int, android.net.nsd.DnsSdServiceInfo);
- }
-
- public static abstract interface NsdManager.DnsSdResolveListener {
- method public abstract void onFailure(int);
- method public abstract void onServiceResolved(android.net.nsd.DnsSdServiceInfo);
+ public final class NsdServiceInfo implements android.os.Parcelable {
+ ctor public NsdServiceInfo();
+ method public int describeContents();
+ method public java.net.InetAddress getHost();
+ method public int getPort();
+ method public java.lang.String getServiceName();
+ method public java.lang.String getServiceType();
+ method public void setHost(java.net.InetAddress);
+ method public void setPort(int);
+ method public void setServiceName(java.lang.String);
+ method public void setServiceType(java.lang.String);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
}
}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index b644dd1..c559e54 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -284,14 +284,14 @@ public abstract class AccessibilityService extends Service {
public static final int GESTURE_SWIPE_DOWN_AND_RIGHT = 16;
/**
- * The user has performed a two finger tap gesture on the touch screen.
+ * The user has performed a double tap gesture on the touch screen.
*/
- public static final int GESTURE_TWO_FINGER_TAP = 17;
+ public static final int GESTURE_DOUBLE_TAP = 17;
/**
- * The user has performed a two finger long press gesture on the touch screen.
+ * The user has performed a tap and hold gesture on the touch screen.
*/
- public static final int GESTURE_TWO_FINGER_LONG_PRESS = 18;
+ public static final int GESTURE_TAP_AND_HOLD = 18;
/**
* The {@link Intent} that must be declared as handled by the service.
@@ -408,8 +408,8 @@ public abstract class AccessibilityService extends Service {
* @see #GESTURE_SWIPE_RIGHT_AND_DOWN
* @see #GESTURE_CLOCKWISE_CIRCLE
* @see #GESTURE_COUNTER_CLOCKWISE_CIRCLE
- * @see #GESTURE_TWO_FINGER_TAP
- * @see #GESTURE_TWO_FINGER_LONG_PRESS
+ * @see #GESTURE_DOUBLE_TAP
+ * @see #GESTURE_TAP_AND_HOLD
*/
protected boolean onGesture(int gestureId) {
// TODO: Describe the default gesture processing in the javaDoc once it is finalized.
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 64a05a8..4943c9a 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -387,7 +387,7 @@ class ContextImpl extends Context {
public Object createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(NSD_SERVICE);
INsdManager service = INsdManager.Stub.asInterface(b);
- return new NsdManager(service);
+ return new NsdManager(ctx.getOuterContext(), service);
}});
// Note: this was previously cached in a static variable, but
diff --git a/core/java/android/app/TaskStackBuilder.java b/core/java/android/app/TaskStackBuilder.java
index e546f6c..14c5736 100644
--- a/core/java/android/app/TaskStackBuilder.java
+++ b/core/java/android/app/TaskStackBuilder.java
@@ -196,18 +196,12 @@ public class TaskStackBuilder {
try {
ActivityInfo info = pm.getActivityInfo(sourceActivityName, 0);
String parentActivity = info.parentActivityName;
- Intent parent = new Intent().setComponent(
- new ComponentName(info.packageName, parentActivity));
- while (parent != null) {
+ while (parentActivity != null) {
+ Intent parent = new Intent().setComponent(
+ new ComponentName(info.packageName, parentActivity));
mIntents.add(insertAt, parent);
info = pm.getActivityInfo(parent.getComponent(), 0);
parentActivity = info.parentActivityName;
- if (parentActivity != null) {
- parent = new Intent().setComponent(
- new ComponentName(info.packageName, parentActivity));
- } else {
- parent = null;
- }
}
} catch (NameNotFoundException e) {
Log.e(TAG, "Bad ComponentName while traversing activity parent metadata");
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index c9bacba..01b68d4 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -208,8 +208,10 @@ public class AppWidgetHostView extends FrameLayout {
}
/**
- * Provide guidance about the size of this widget to the AppWidgetManager. This information
- * gets embedded into the AppWidgetExtras and causes a callback to the AppWidgetProvider.
+ * Provide guidance about the size of this widget to the AppWidgetManager. The widths and
+ * heights should correspond to the full area the AppWidgetHostView is given. Padding added by
+ * the framework will be accounted for automatically. This information gets embedded into the
+ * AppWidget options and causes a callback to the AppWidgetProvider.
* @see AppWidgetProvider#onAppWidgetOptionsChanged(Context, AppWidgetManager, int, Bundle)
*
* @param options The bundle of options, in addition to the size information,
@@ -225,10 +227,20 @@ public class AppWidgetHostView extends FrameLayout {
if (options == null) {
options = new Bundle();
}
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth);
- options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight);
+
+ Rect padding = new Rect();
+ if (mInfo != null) {
+ padding = getDefaultPaddingForWidget(mContext, mInfo.provider, padding);
+ }
+ float density = getResources().getDisplayMetrics().density;
+
+ int xPaddingDips = (int) ((padding.left + padding.right) / density);
+ int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
+
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, minWidth - xPaddingDips);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, minHeight - yPaddingDips);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, maxWidth - xPaddingDips);
+ options.putInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, maxHeight - yPaddingDips);
updateAppWidgetOptions(options);
}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 6c7e940..226e107 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -197,6 +197,29 @@ public class SyncStorageEngine extends Handler {
long delayUntil;
final ArrayList<Pair<Bundle, Long>> periodicSyncs;
+ /**
+ * Copy constructor for making deep-ish copies. Only the bundles stored
+ * in periodic syncs can make unexpected changes.
+ *
+ * @param toCopy AuthorityInfo to be copied.
+ */
+ AuthorityInfo(AuthorityInfo toCopy) {
+ account = toCopy.account;
+ userId = toCopy.userId;
+ authority = toCopy.authority;
+ ident = toCopy.ident;
+ enabled = toCopy.enabled;
+ syncable = toCopy.syncable;
+ backoffTime = toCopy.backoffTime;
+ backoffDelay = toCopy.backoffDelay;
+ delayUntil = toCopy.delayUntil;
+ periodicSyncs = new ArrayList<Pair<Bundle, Long>>();
+ for (Pair<Bundle, Long> sync : toCopy.periodicSyncs) {
+ // Still not a perfect copy, because we are just copying the mappings.
+ periodicSyncs.add(Pair.create(new Bundle(sync.first), sync.second));
+ }
+ }
+
AuthorityInfo(Account account, int userId, String authority, int ident) {
this.account = account;
this.userId = userId;
@@ -1212,7 +1235,8 @@ public class SyncStorageEngine extends Handler {
final int N = mAuthorities.size();
ArrayList<AuthorityInfo> infos = new ArrayList<AuthorityInfo>(N);
for (int i=0; i<N; i++) {
- infos.add(mAuthorities.valueAt(i));
+ // Make deep copy because AuthorityInfo syncs are liable to change.
+ infos.add(new AuthorityInfo(mAuthorities.valueAt(i)));
}
return infos;
}
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
index 9893133..7d46710 100644
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ b/core/java/android/content/res/AssetFileDescriptor.java
@@ -52,6 +52,9 @@ public class AssetFileDescriptor implements Parcelable {
*/
public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset,
long length) {
+ if (fd == null) {
+ throw new IllegalArgumentException("fd must not be null");
+ }
if (length < 0 && startOffset != 0) {
throw new IllegalArgumentException(
"startOffset must be 0 when using UNKNOWN_LENGTH");
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 332f40a..33dea6c 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -402,7 +402,7 @@ public class InputMethodService extends AbstractInputMethodService {
mShowInputFlags = 0;
mShowInputRequested = false;
mShowInputForced = false;
- hideWindow();
+ doHideWindow();
if (resultReceiver != null) {
resultReceiver.send(wasVis != isInputViewShown()
? InputMethodManager.RESULT_HIDDEN
@@ -737,7 +737,7 @@ public class InputMethodService extends AbstractInputMethodService {
onDisplayCompletions(completions);
}
} else {
- hideWindow();
+ doHideWindow();
}
} else if (mCandidatesVisibility == View.VISIBLE) {
// If the candidates are currently visible, make sure the
@@ -745,7 +745,7 @@ public class InputMethodService extends AbstractInputMethodService {
showWindow(false);
} else {
// Otherwise hide the window.
- hideWindow();
+ doHideWindow();
}
// If user uses hard keyboard, IME button should always be shown.
boolean showing = onEvaluateInputViewShown();
@@ -1096,7 +1096,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (shown) {
showWindow(false);
} else {
- hideWindow();
+ doHideWindow();
}
}
}
@@ -1449,9 +1449,13 @@ public class InputMethodService extends AbstractInputMethodService {
mCandidatesViewStarted = false;
}
+ private void doHideWindow() {
+ mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
+ hideWindow();
+ }
+
public void hideWindow() {
finishViews();
- mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
if (mWindowVisible) {
mWindow.hide();
mWindowVisible = false;
@@ -1703,7 +1707,7 @@ public class InputMethodService extends AbstractInputMethodService {
// If we have the window visible for some other reason --
// most likely to show candidates -- then just get rid
// of it. This really shouldn't happen, but just in case...
- if (doIt) hideWindow();
+ if (doIt) doHideWindow();
}
return true;
}
diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java
index 77e97e1..08ba728 100644
--- a/core/java/android/net/nsd/NsdManager.java
+++ b/core/java/android/net/nsd/NsdManager.java
@@ -22,12 +22,16 @@ import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.Messenger;
import android.text.TextUtils;
import android.util.Log;
+import android.util.SparseArray;
+
+import java.util.concurrent.CountDownLatch;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
@@ -39,88 +43,73 @@ import com.android.internal.util.Protocol;
* B. Another example use case is an application discovering printers on the network.
*
* <p> The API currently supports DNS based service discovery and discovery is currently
- * limited to a local network over Multicast DNS. In future, it will be extended to
- * support wide area discovery and other service discovery mechanisms.
- * DNS service discovery is described at http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
+ * limited to a local network over Multicast DNS. DNS service discovery is described at
+ * http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
*
* <p> The API is asynchronous and responses to requests from an application are on listener
- * callbacks provided by the application. The application must invoke {@link #initialize} before
- * doing any other operation.
+ * callbacks on a seperate thread.
*
* <p> There are three main operations the API supports - registration, discovery and resolution.
* <pre>
* Application start
* |
- * | <----------------------------------------------
- * initialize() |
- * | |
- * | Wait until channel connects |
- * | before doing any operation |
- * | |
- * onChannelConnected() __________ |
- * | | |
- * | | |
- * | onServiceRegistered() | |
- * Register any local services / | |
- * to be advertised with \ | | If application needs to
- * registerService() onFailure() | | do any further operations
- * | | | again, it needs to
- * | | | initialize() connection
- * discoverServices() | | to framework again
- * | | |
- * Maintain a list to track | |
- * discovered services | |
- * | | |
- * |---------> |-> onChannelDisconnected()
- * | | |
- * | onServiceFound() |
- * | | |
- * | add service to list |
- * | | |
- * |<---------- |
- * | |
- * |---------> |
- * | | |
- * | onServiceLost() |
- * | | |
- * | remove service from list |
- * | | |
- * |<---------- |
- * | |
- * | |
- * | Connect to a service |
- * | from list ? |
- * | |
- * resolveService() |
- * | |
- * onServiceResolved() |
- * | |
- * Establish connection to service |
- * with the host and port information |
- * | |
- * | ___________|
- * deinitialize()
- * when done with all operations
- * or before quit
+ * |
+ * | onServiceRegistered()
+ * Register any local services /
+ * to be advertised with \
+ * registerService() onRegistrationFailed()
+ * |
+ * |
+ * discoverServices()
+ * |
+ * Maintain a list to track
+ * discovered services
+ * |
+ * |--------->
+ * | |
+ * | onServiceFound()
+ * | |
+ * | add service to list
+ * | |
+ * |<----------
+ * |
+ * |--------->
+ * | |
+ * | onServiceLost()
+ * | |
+ * | remove service from list
+ * | |
+ * |<----------
+ * |
+ * |
+ * | Connect to a service
+ * | from list ?
+ * |
+ * resolveService()
+ * |
+ * onServiceResolved()
+ * |
+ * Establish connection to service
+ * with the host and port information
*
* </pre>
* An application that needs to advertise itself over a network for other applications to
* discover it can do so with a call to {@link #registerService}. If Example is a http based
* application that can provide HTML data to peer services, it can register a name "Example"
* with service type "_http._tcp". A successful registration is notified with a callback to
- * {@link DnsSdRegisterListener#onServiceRegistered} and a failure to register is notified
- * over {@link DnsSdRegisterListener#onFailure}
+ * {@link RegistrationListener#onServiceRegistered} and a failure to register is notified
+ * over {@link RegistrationListener#onRegistrationFailed}
*
* <p> A peer application looking for http services can initiate a discovery for "_http._tcp"
* with a call to {@link #discoverServices}. A service found is notified with a callback
- * to {@link DnsSdDiscoveryListener#onServiceFound} and a service lost is notified on
- * {@link DnsSdDiscoveryListener#onServiceLost}.
+ * to {@link DiscoveryListener#onServiceFound} and a service lost is notified on
+ * {@link DiscoveryListener#onServiceLost}.
*
* <p> Once the peer application discovers the "Example" http srevice, and needs to receive data
* from the "Example" application, it can initiate a resolve with {@link #resolveService} to
* resolve the host and port details for the purpose of establishing a connection. A successful
- * resolve is notified on {@link DnsSdResolveListener#onServiceResolved} and a failure is notified
- * on {@link DnsSdResolveListener#onFailure}.
+ * resolve is notified on {@link ResolveListener#onServiceResolved} and a failure is notified
+ * on {@link ResolveListener#onResolveFailed}.
*
* Applications can reserve for a service type at
* http://www.iana.org/form/ports-service. Existing services can be found at
@@ -129,9 +118,9 @@ import com.android.internal.util.Protocol;
* Get an instance of this class by calling {@link android.content.Context#getSystemService(String)
* Context.getSystemService(Context.NSD_SERVICE)}.
*
- * {@see DnsSdServiceInfo}
+ * {@see NsdServiceInfo}
*/
-public class NsdManager {
+public final class NsdManager {
private static final String TAG = "NsdManager";
INsdManager mService;
@@ -204,13 +193,6 @@ public class NsdManager {
public static final int UNREGISTER_SERVICE_SUCCEEDED = BASE + 14;
/** @hide */
- public static final int UPDATE_SERVICE = BASE + 15;
- /** @hide */
- public static final int UPDATE_SERVICE_FAILED = BASE + 16;
- /** @hide */
- public static final int UPDATE_SERVICE_SUCCEEDED = BASE + 17;
-
- /** @hide */
public static final int RESOLVE_SERVICE = BASE + 18;
/** @hide */
public static final int RESOLVE_SERVICE_FAILED = BASE + 19;
@@ -218,17 +200,27 @@ public class NsdManager {
public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 20;
/** @hide */
- public static final int STOP_RESOLVE = BASE + 21;
- /** @hide */
- public static final int STOP_RESOLVE_FAILED = BASE + 22;
- /** @hide */
- public static final int STOP_RESOLVE_SUCCEEDED = BASE + 23;
-
- /** @hide */
public static final int ENABLE = BASE + 24;
/** @hide */
public static final int DISABLE = BASE + 25;
+ /** @hide */
+ public static final int NATIVE_DAEMON_EVENT = BASE + 26;
+
+ /** Dns based service discovery protocol */
+ public static final int PROTOCOL_DNS_SD = 0x0001;
+
+ private Context mContext;
+
+ private static final int INVALID_LISTENER_KEY = 0;
+ private int mListenerKey = 1;
+ private final SparseArray mListenerMap = new SparseArray();
+ private final SparseArray<NsdServiceInfo> mServiceMap = new SparseArray<NsdServiceInfo>();
+ private final Object mMapLock = new Object();
+
+ private final AsyncChannel mAsyncChannel = new AsyncChannel();
+ private ServiceHandler mHandler;
+ private final CountDownLatch mConnected = new CountDownLatch(1);
/**
* Create a new Nsd instance. Applications use
@@ -238,271 +230,213 @@ public class NsdManager {
* @hide - hide this because it takes in a parameter of type INsdManager, which
* is a system private class.
*/
- public NsdManager(INsdManager service) {
+ public NsdManager(Context context, INsdManager service) {
mService = service;
+ mContext = context;
+ init();
}
/**
- * Passed with onFailure() calls.
+ * Failures are passed with {@link RegistrationListener#onRegistrationFailed},
+ * {@link RegistrationListener#onUnregistrationFailed},
+ * {@link DiscoveryListener#onStartDiscoveryFailed},
+ * {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
+ *
* Indicates that the operation failed due to an internal error.
*/
- public static final int ERROR = 0;
+ public static final int FAILURE_INTERNAL_ERROR = 0;
/**
- * Passed with onFailure() calls.
- * Indicates that the operation failed because service discovery
- * is unsupported on the device.
- */
- public static final int UNSUPPORTED = 1;
-
- /**
- * Passed with onFailure() calls.
- * Indicates that the operation failed because the framework is
- * busy and unable to service the request.
- */
- public static final int BUSY = 2;
-
- /**
- * Passed with onFailure() calls.
* Indicates that the operation failed because it is already active.
*/
- public static final int ALREADY_ACTIVE = 3;
+ public static final int FAILURE_ALREADY_ACTIVE = 3;
/**
- * Passed with onFailure() calls.
- * Indicates that the operation failed because maximum limit on
- * service registrations has reached.
+ * Indicates that the operation failed because the maximum outstanding
+ * requests from the applications have reached.
*/
- public static final int MAX_REGS_REACHED = 4;
-
- /** Interface for callback invocation when framework channel is connected or lost */
- public interface ChannelListener {
- /**
- * The channel to the framework is connected.
- * Application can initiate calls into the framework using the channel instance passed.
- */
- public void onChannelConnected(Channel c);
- /**
- * The channel to the framework has been disconnected.
- * Application could try re-initializing using {@link #initialize}
- */
- public void onChannelDisconnected();
- }
+ public static final int FAILURE_MAX_LIMIT = 4;
- /** Generic interface for callback invocation for a success or failure */
- public interface ActionListener {
+ /** Interface for callback invocation for service discovery */
+ public interface DiscoveryListener {
- public void onFailure(int errorCode);
+ public void onStartDiscoveryFailed(String serviceType, int errorCode);
- public void onSuccess();
- }
+ public void onStopDiscoveryFailed(String serviceType, int errorCode);
- /** Interface for callback invocation for service discovery */
- public interface DnsSdDiscoveryListener {
+ public void onDiscoveryStarted(String serviceType);
- public void onFailure(int errorCode);
+ public void onDiscoveryStopped(String serviceType);
- public void onStarted(String serviceType);
+ public void onServiceFound(NsdServiceInfo serviceInfo);
- public void onServiceFound(DnsSdServiceInfo serviceInfo);
-
- public void onServiceLost(DnsSdServiceInfo serviceInfo);
+ public void onServiceLost(NsdServiceInfo serviceInfo);
}
/** Interface for callback invocation for service registration */
- public interface DnsSdRegisterListener {
-
- public void onFailure(int errorCode);
+ public interface RegistrationListener {
- public void onServiceRegistered(int registeredId, DnsSdServiceInfo serviceInfo);
- }
+ public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
- /** @hide */
- public interface DnsSdUpdateRegistrationListener {
+ public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode);
- public void onFailure(int errorCode);
+ public void onServiceRegistered(NsdServiceInfo serviceInfo);
- public void onServiceUpdated(int registeredId, DnsSdTxtRecord txtRecord);
+ public void onServiceUnregistered(NsdServiceInfo serviceInfo);
}
/** Interface for callback invocation for service resolution */
- public interface DnsSdResolveListener {
+ public interface ResolveListener {
- public void onFailure(int errorCode);
+ public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode);
- public void onServiceResolved(DnsSdServiceInfo serviceInfo);
+ public void onServiceResolved(NsdServiceInfo serviceInfo);
}
- /**
- * A channel that connects the application to the NetworkService framework.
- * Most service operations require a Channel as an argument. An instance of Channel is obtained
- * by doing a call on {@link #initialize}
- */
- public static class Channel {
- Channel(Looper looper, ChannelListener l) {
- mAsyncChannel = new AsyncChannel();
- mHandler = new ServiceHandler(looper);
- mChannelListener = l;
+ private class ServiceHandler extends Handler {
+ ServiceHandler(Looper looper) {
+ super(looper);
}
- private ChannelListener mChannelListener;
- private DnsSdDiscoveryListener mDnsSdDiscoveryListener;
- private ActionListener mDnsSdStopDiscoveryListener;
- private DnsSdRegisterListener mDnsSdRegisterListener;
- private ActionListener mDnsSdUnregisterListener;
- private DnsSdUpdateRegistrationListener mDnsSdUpdateListener;
- private DnsSdResolveListener mDnsSdResolveListener;
- private ActionListener mDnsSdStopResolveListener;
-
- private AsyncChannel mAsyncChannel;
- private ServiceHandler mHandler;
- class ServiceHandler extends Handler {
- ServiceHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
- mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
- break;
- case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
- if (mChannelListener != null) {
- mChannelListener.onChannelConnected(Channel.this);
- }
- break;
- case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
- if (mChannelListener != null) {
- mChannelListener.onChannelDisconnected();
- mChannelListener = null;
- }
- break;
- case DISCOVER_SERVICES_STARTED:
- if (mDnsSdDiscoveryListener != null) {
- mDnsSdDiscoveryListener.onStarted((String) message.obj);
- }
- break;
- case DISCOVER_SERVICES_FAILED:
- if (mDnsSdDiscoveryListener != null) {
- mDnsSdDiscoveryListener.onFailure(message.arg1);
- }
- break;
- case SERVICE_FOUND:
- if (mDnsSdDiscoveryListener != null) {
- mDnsSdDiscoveryListener.onServiceFound(
- (DnsSdServiceInfo) message.obj);
- }
- break;
- case SERVICE_LOST:
- if (mDnsSdDiscoveryListener != null) {
- mDnsSdDiscoveryListener.onServiceLost(
- (DnsSdServiceInfo) message.obj);
- }
- break;
- case STOP_DISCOVERY_FAILED:
- if (mDnsSdStopDiscoveryListener != null) {
- mDnsSdStopDiscoveryListener.onFailure(message.arg1);
- }
- break;
- case STOP_DISCOVERY_SUCCEEDED:
- if (mDnsSdStopDiscoveryListener != null) {
- mDnsSdStopDiscoveryListener.onSuccess();
- }
- break;
- case REGISTER_SERVICE_FAILED:
- if (mDnsSdRegisterListener != null) {
- mDnsSdRegisterListener.onFailure(message.arg1);
- }
- break;
- case REGISTER_SERVICE_SUCCEEDED:
- if (mDnsSdRegisterListener != null) {
- mDnsSdRegisterListener.onServiceRegistered(message.arg1,
- (DnsSdServiceInfo) message.obj);
- }
- break;
- case UNREGISTER_SERVICE_FAILED:
- if (mDnsSdUnregisterListener != null) {
- mDnsSdUnregisterListener.onFailure(message.arg1);
- }
- break;
- case UNREGISTER_SERVICE_SUCCEEDED:
- if (mDnsSdUnregisterListener != null) {
- mDnsSdUnregisterListener.onSuccess();
- }
- break;
- case UPDATE_SERVICE_FAILED:
- if (mDnsSdUpdateListener != null) {
- mDnsSdUpdateListener.onFailure(message.arg1);
- }
- break;
- case UPDATE_SERVICE_SUCCEEDED:
- if (mDnsSdUpdateListener != null) {
- mDnsSdUpdateListener.onServiceUpdated(message.arg1,
- (DnsSdTxtRecord) message.obj);
- }
- break;
- case RESOLVE_SERVICE_FAILED:
- if (mDnsSdResolveListener != null) {
- mDnsSdResolveListener.onFailure(message.arg1);
- }
- break;
- case RESOLVE_SERVICE_SUCCEEDED:
- if (mDnsSdResolveListener != null) {
- mDnsSdResolveListener.onServiceResolved(
- (DnsSdServiceInfo) message.obj);
- }
- break;
- case STOP_RESOLVE_FAILED:
- if (mDnsSdStopResolveListener!= null) {
- mDnsSdStopResolveListener.onFailure(message.arg1);
- }
- break;
- case STOP_RESOLVE_SUCCEEDED:
- if (mDnsSdStopResolveListener != null) {
- mDnsSdStopResolveListener.onSuccess();
- }
- break;
- default:
- Log.d(TAG, "Ignored " + message);
- break;
- }
+ @Override
+ public void handleMessage(Message message) {
+ Object listener = getListener(message.arg2);
+ boolean listenerRemove = true;
+ switch (message.what) {
+ case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
+ mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION);
+ mConnected.countDown();
+ break;
+ case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED:
+ // Ignore
+ break;
+ case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
+ Log.e(TAG, "Channel lost");
+ break;
+ case DISCOVER_SERVICES_STARTED:
+ String s = ((NsdServiceInfo) message.obj).getServiceType();
+ ((DiscoveryListener) listener).onDiscoveryStarted(s);
+ // Keep listener until stop discovery
+ listenerRemove = false;
+ break;
+ case DISCOVER_SERVICES_FAILED:
+ ((DiscoveryListener) listener).onStartDiscoveryFailed(
+ getNsdService(message.arg2).getServiceType(), message.arg1);
+ break;
+ case SERVICE_FOUND:
+ ((DiscoveryListener) listener).onServiceFound((NsdServiceInfo) message.obj);
+ // Keep listener until stop discovery
+ listenerRemove = false;
+ break;
+ case SERVICE_LOST:
+ ((DiscoveryListener) listener).onServiceLost((NsdServiceInfo) message.obj);
+ // Keep listener until stop discovery
+ listenerRemove = false;
+ break;
+ case STOP_DISCOVERY_FAILED:
+ ((DiscoveryListener) listener).onStopDiscoveryFailed(
+ getNsdService(message.arg2).getServiceType(), message.arg1);
+ break;
+ case STOP_DISCOVERY_SUCCEEDED:
+ ((DiscoveryListener) listener).onDiscoveryStopped(
+ getNsdService(message.arg2).getServiceType());
+ break;
+ case REGISTER_SERVICE_FAILED:
+ ((RegistrationListener) listener).onRegistrationFailed(
+ getNsdService(message.arg2), message.arg1);
+ break;
+ case REGISTER_SERVICE_SUCCEEDED:
+ ((RegistrationListener) listener).onServiceRegistered(
+ (NsdServiceInfo) message.obj);
+ // Keep listener until unregister
+ listenerRemove = false;
+ break;
+ case UNREGISTER_SERVICE_FAILED:
+ ((RegistrationListener) listener).onUnregistrationFailed(
+ getNsdService(message.arg2), message.arg1);
+ break;
+ case UNREGISTER_SERVICE_SUCCEEDED:
+ ((RegistrationListener) listener).onServiceUnregistered(
+ getNsdService(message.arg2));
+ break;
+ case RESOLVE_SERVICE_FAILED:
+ ((ResolveListener) listener).onResolveFailed(
+ getNsdService(message.arg2), message.arg1);
+ break;
+ case RESOLVE_SERVICE_SUCCEEDED:
+ ((ResolveListener) listener).onServiceResolved((NsdServiceInfo) message.obj);
+ break;
+ default:
+ Log.d(TAG, "Ignored " + message);
+ break;
+ }
+ if (listenerRemove) {
+ removeListener(message.arg2);
}
}
- }
+ }
- private static void checkChannel(Channel c) {
- if (c == null) throw new IllegalArgumentException("Channel needs to be initialized");
+ private int putListener(Object listener, NsdServiceInfo s) {
+ if (listener == null) return INVALID_LISTENER_KEY;
+ int key;
+ synchronized (mMapLock) {
+ do {
+ key = mListenerKey++;
+ } while (key == INVALID_LISTENER_KEY);
+ mListenerMap.put(key, listener);
+ mServiceMap.put(key, s);
+ }
+ return key;
}
- /**
- * Registers the application with the service discovery framework. This function
- * must be the first to be called before any other operations are performed. No service
- * discovery operations must be performed until the ChannelListener callback notifies
- * that the channel is connected
- *
- * @param srcContext is the context of the source
- * @param srcLooper is the Looper on which the callbacks are receivied
- * @param listener for callback at loss of framework communication. Cannot be null.
- */
- public void initialize(Context srcContext, Looper srcLooper, ChannelListener listener) {
- Messenger messenger = getMessenger();
- if (messenger == null) throw new RuntimeException("Failed to initialize");
- if (listener == null) throw new IllegalArgumentException("ChannelListener cannot be null");
+ private Object getListener(int key) {
+ if (key == INVALID_LISTENER_KEY) return null;
+ synchronized (mMapLock) {
+ return mListenerMap.get(key);
+ }
+ }
+
+ private NsdServiceInfo getNsdService(int key) {
+ synchronized (mMapLock) {
+ return mServiceMap.get(key);
+ }
+ }
+
+ private void removeListener(int key) {
+ if (key == INVALID_LISTENER_KEY) return;
+ synchronized (mMapLock) {
+ mListenerMap.remove(key);
+ mServiceMap.remove(key);
+ }
+ }
- Channel c = new Channel(srcLooper, listener);
- c.mAsyncChannel.connect(srcContext, c.mHandler, messenger);
+ private int getListenerKey(Object listener) {
+ synchronized (mMapLock) {
+ int valueIndex = mListenerMap.indexOfValue(listener);
+ if (valueIndex != -1) {
+ return mListenerMap.keyAt(valueIndex);
+ }
+ }
+ return INVALID_LISTENER_KEY;
}
+
/**
- * Disconnects application from service discovery framework. No further operations
- * will succeed until a {@link #initialize} is called again.
- *
- * @param c channel initialized with {@link #initialize}
+ * Initialize AsyncChannel
*/
- public void deinitialize(Channel c) {
- checkChannel(c);
- c.mAsyncChannel.disconnect();
+ private void init() {
+ final Messenger messenger = getMessenger();
+ if (messenger == null) throw new RuntimeException("Failed to initialize");
+ HandlerThread t = new HandlerThread("NsdManager");
+ t.start();
+ mHandler = new ServiceHandler(t.getLooper());
+ mAsyncChannel.connect(mContext, mHandler, messenger);
+ try {
+ mConnected.await();
+ } catch (InterruptedException e) {
+ Log.e(TAG, "interrupted wait at init");
+ }
}
/**
@@ -510,45 +444,51 @@ public class NsdManager {
*
* <p> The function call immediately returns after sending a request to register service
* to the framework. The application is notified of a success to initiate
- * discovery through the callback {@link DnsSdRegisterListener#onServiceRegistered} or a failure
- * through {@link DnsSdRegisterListener#onFailure}.
+ * discovery through the callback {@link RegistrationListener#onServiceRegistered} or a failure
+ * through {@link RegistrationListener#onRegistrationFailed}.
*
- * @param c is the channel created at {@link #initialize}
- * @param serviceType The service type being advertised.
- * @param port on which the service is listenering for incoming connections
- * @param listener for success or failure callback. Can be null.
+ * @param serviceInfo The service being registered
+ * @param protocolType The service discovery protocol
+ * @param listener The listener notifies of a successful registration and is used to
+ * unregister this service through a call on {@link #unregisterService}. Cannot be null.
*/
- public void registerService(Channel c, String serviceName, String serviceType, int port,
- DnsSdRegisterListener listener) {
- checkChannel(c);
- if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+ public void registerService(NsdServiceInfo serviceInfo, int protocolType,
+ RegistrationListener listener) {
+ if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+ TextUtils.isEmpty(serviceInfo.getServiceType())) {
throw new IllegalArgumentException("Service name or type cannot be empty");
}
- if (port <= 0) {
+ if (serviceInfo.getPort() <= 0) {
throw new IllegalArgumentException("Invalid port number");
}
- DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
- serviceInfo.setPort(port);
- c.mDnsSdRegisterListener = listener;
- c.mAsyncChannel.sendMessage(REGISTER_SERVICE, serviceInfo);
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ if (protocolType != PROTOCOL_DNS_SD) {
+ throw new IllegalArgumentException("Unsupported protocol");
+ }
+ mAsyncChannel.sendMessage(REGISTER_SERVICE, 0, putListener(listener, serviceInfo),
+ serviceInfo);
}
/**
- * Unregister a service registered through {@link #registerService}
- * @param c is the channel created at {@link #initialize}
- * @param registeredId is obtained at {@link DnsSdRegisterListener#onServiceRegistered}
- * @param listener provides callbacks for success or failure. Can be null.
+ * Unregister a service registered through {@link #registerService}. A successful
+ * unregister is notified to the application with a call to
+ * {@link RegistrationListener#onServiceUnregistered}.
+ *
+ * @param listener This should be the listener object that was passed to
+ * {@link #registerService}. It identifies the service that should be unregistered
+ * and notifies of a successful unregistration.
*/
- public void unregisterService(Channel c, int registeredId, ActionListener listener) {
- checkChannel(c);
- c.mDnsSdUnregisterListener = listener;
- c.mAsyncChannel.sendMessage(UNREGISTER_SERVICE, registeredId);
- }
-
- /** @hide */
- public void updateService(Channel c, int registeredId, DnsSdTxtRecord txtRecord) {
- checkChannel(c);
- c.mAsyncChannel.sendMessage(UPDATE_SERVICE, registeredId, 0, txtRecord);
+ public void unregisterService(RegistrationListener listener) {
+ int id = getListenerKey(listener);
+ if (id == INVALID_LISTENER_KEY) {
+ throw new IllegalArgumentException("listener not registered");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mAsyncChannel.sendMessage(UNREGISTER_SERVICE, 0, id);
}
/**
@@ -558,51 +498,61 @@ public class NsdManager {
*
* <p> The function call immediately returns after sending a request to start service
* discovery to the framework. The application is notified of a success to initiate
- * discovery through the callback {@link DnsSdDiscoveryListener#onStarted} or a failure
- * through {@link DnsSdDiscoveryListener#onFailure}.
+ * discovery through the callback {@link DiscoveryListener#onDiscoveryStarted} or a failure
+ * through {@link DiscoveryListener#onStartDiscoveryFailed}.
*
* <p> Upon successful start, application is notified when a service is found with
- * {@link DnsSdDiscoveryListener#onServiceFound} or when a service is lost with
- * {@link DnsSdDiscoveryListener#onServiceLost}.
+ * {@link DiscoveryListener#onServiceFound} or when a service is lost with
+ * {@link DiscoveryListener#onServiceLost}.
*
* <p> Upon failure to start, service discovery is not active and application does
* not need to invoke {@link #stopServiceDiscovery}
*
- * @param c is the channel created at {@link #initialize}
* @param serviceType The service type being discovered. Examples include "_http._tcp" for
* http services or "_ipp._tcp" for printers
- * @param listener provides callbacks when service is found or lost. Cannot be null.
+ * @param protocolType The service discovery protocol
+ * @param listener The listener notifies of a successful discovery and is used
+ * to stop discovery on this serviceType through a call on {@link #stopServiceDiscovery}.
+ * Cannot be null.
*/
- public void discoverServices(Channel c, String serviceType, DnsSdDiscoveryListener listener) {
- checkChannel(c);
+ public void discoverServices(String serviceType, int protocolType, DiscoveryListener listener) {
if (listener == null) {
- throw new IllegalStateException("Discovery listener needs to be set first");
+ throw new IllegalArgumentException("listener cannot be null");
}
if (TextUtils.isEmpty(serviceType)) {
- throw new IllegalStateException("Service type cannot be empty");
+ throw new IllegalArgumentException("Service type cannot be empty");
}
- DnsSdServiceInfo s = new DnsSdServiceInfo();
+
+ if (protocolType != PROTOCOL_DNS_SD) {
+ throw new IllegalArgumentException("Unsupported protocol");
+ }
+
+ NsdServiceInfo s = new NsdServiceInfo();
s.setServiceType(serviceType);
- c.mDnsSdDiscoveryListener = listener;
- c.mAsyncChannel.sendMessage(DISCOVER_SERVICES, s);
+ mAsyncChannel.sendMessage(DISCOVER_SERVICES, 0, putListener(listener, s), s);
}
/**
* Stop service discovery initiated with {@link #discoverServices}. An active service
- * discovery is notified to the application with {@link DnsSdDiscoveryListener#onStarted}
- * and it stays active until the application invokes a stop service discovery.
+ * discovery is notified to the application with {@link DiscoveryListener#onDiscoveryStarted}
+ * and it stays active until the application invokes a stop service discovery. A successful
+ * stop is notified to with a call to {@link DiscoveryListener#onDiscoveryStopped}.
*
- * <p> Upon failure to start service discovery notified through
- * {@link DnsSdDiscoveryListener#onFailure} service discovery is not active and
- * application does not need to stop it.
+ * <p> Upon failure to stop service discovery, application is notified through
+ * {@link DiscoveryListener#onStopDiscoveryFailed}.
*
- * @param c is the channel created at {@link #initialize}
- * @param listener notifies success or failure. Can be null.
+ * @param listener This should be the listener object that was passed to {@link #discoverServices}.
+ * It identifies the discovery that should be stopped and notifies of a successful stop.
*/
- public void stopServiceDiscovery(Channel c, ActionListener listener) {
- checkChannel(c);
- c.mDnsSdStopDiscoveryListener = listener;
- c.mAsyncChannel.sendMessage(STOP_DISCOVERY);
+ public void stopServiceDiscovery(DiscoveryListener listener) {
+ int id = getListenerKey(listener);
+ if (id == INVALID_LISTENER_KEY) {
+ throw new IllegalArgumentException("service discovery not active on listener");
+ }
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, id);
}
/**
@@ -610,30 +560,19 @@ public class NsdManager {
* establishing a connection to fetch the IP and port details on which to setup
* the connection.
*
- * @param c is the channel created at {@link #initialize}
- * @param serviceName of the the service
- * @param serviceType of the service
+ * @param serviceInfo service to be resolved
* @param listener to receive callback upon success or failure. Cannot be null.
*/
- public void resolveService(Channel c, String serviceName, String serviceType,
- DnsSdResolveListener listener) {
- checkChannel(c);
- if (TextUtils.isEmpty(serviceName) || TextUtils.isEmpty(serviceType)) {
+ public void resolveService(NsdServiceInfo serviceInfo, ResolveListener listener) {
+ if (TextUtils.isEmpty(serviceInfo.getServiceName()) ||
+ TextUtils.isEmpty(serviceInfo.getServiceType())) {
throw new IllegalArgumentException("Service name or type cannot be empty");
}
- if (listener == null) throw new
- IllegalStateException("Resolve listener cannot be null");
- c.mDnsSdResolveListener = listener;
- DnsSdServiceInfo serviceInfo = new DnsSdServiceInfo(serviceName, serviceType, null);
- c.mAsyncChannel.sendMessage(RESOLVE_SERVICE, serviceInfo);
- }
-
- /** @hide */
- public void stopServiceResolve(Channel c) {
- checkChannel(c);
- if (c.mDnsSdResolveListener == null) throw new
- IllegalStateException("Resolve listener needs to be set first");
- c.mAsyncChannel.sendMessage(STOP_RESOLVE);
+ if (listener == null) {
+ throw new IllegalArgumentException("listener cannot be null");
+ }
+ mAsyncChannel.sendMessage(RESOLVE_SERVICE, 0, putListener(listener, serviceInfo),
+ serviceInfo);
}
/** Internal use only @hide */
diff --git a/core/java/android/net/nsd/DnsSdServiceInfo.java b/core/java/android/net/nsd/NsdServiceInfo.java
index 66abd3a..205a21d 100644
--- a/core/java/android/net/nsd/DnsSdServiceInfo.java
+++ b/core/java/android/net/nsd/NsdServiceInfo.java
@@ -25,7 +25,7 @@ import java.net.InetAddress;
* A class representing service information for network service discovery
* {@see NsdManager}
*/
-public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
+public final class NsdServiceInfo implements Parcelable {
private String mServiceName;
@@ -37,36 +37,32 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
private int mPort;
- public DnsSdServiceInfo() {
+ public NsdServiceInfo() {
}
/** @hide */
- public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
+ public NsdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) {
mServiceName = sn;
mServiceType = rt;
mTxtRecord = tr;
}
/** Get the service name */
- @Override
public String getServiceName() {
return mServiceName;
}
/** Set the service name */
- @Override
public void setServiceName(String s) {
mServiceName = s;
}
/** Get the service type */
- @Override
public String getServiceType() {
return mServiceType;
}
/** Set the service type */
- @Override
public void setServiceType(String s) {
mServiceType = s;
}
@@ -132,10 +128,10 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
}
/** Implement the Parcelable interface */
- public static final Creator<DnsSdServiceInfo> CREATOR =
- new Creator<DnsSdServiceInfo>() {
- public DnsSdServiceInfo createFromParcel(Parcel in) {
- DnsSdServiceInfo info = new DnsSdServiceInfo();
+ public static final Creator<NsdServiceInfo> CREATOR =
+ new Creator<NsdServiceInfo>() {
+ public NsdServiceInfo createFromParcel(Parcel in) {
+ NsdServiceInfo info = new NsdServiceInfo();
info.mServiceName = in.readString();
info.mServiceType = in.readString();
info.mTxtRecord = in.readParcelable(null);
@@ -150,8 +146,8 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable {
return info;
}
- public DnsSdServiceInfo[] newArray(int size) {
- return new DnsSdServiceInfo[size];
+ public NsdServiceInfo[] newArray(int size) {
+ return new NsdServiceInfo[size];
}
};
}
diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java
index 0586d9e..b7bc45f 100644
--- a/core/java/android/os/IBinder.java
+++ b/core/java/android/os/IBinder.java
@@ -140,6 +140,9 @@ public interface IBinder {
*/
int LIKE_TRANSACTION = ('_'<<24)|('L'<<16)|('I'<<8)|'K';
+ /** @hide */
+ int SYSPROPS_TRANSACTION = ('_'<<24)|('S'<<16)|('P'<<8)|'R';
+
/**
* Flag to {@link #transact}: this is a one-way call, meaning that the
* caller returns immediately, without waiting for a result from the
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 43b5128..be24426 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -16,6 +16,8 @@
package android.os;
+import java.util.ArrayList;
+
/**
* Native implementation of the service manager. Most clients will only
@@ -151,14 +153,32 @@ class ServiceManagerProxy implements IServiceManager {
}
public String[] listServices() throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken(IServiceManager.descriptor);
- mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
- String[] list = reply.readStringArray();
- reply.recycle();
- data.recycle();
- return list;
+ ArrayList<String> services = new ArrayList<String>();
+ int n = 0;
+ while (true) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IServiceManager.descriptor);
+ data.writeInt(n);
+ n++;
+ try {
+ boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
+ if (!res) {
+ break;
+ }
+ } catch (RuntimeException e) {
+ // The result code that is returned by the C++ code can
+ // cause the call to throw an exception back instead of
+ // returning a nice result... so eat it here and go on.
+ break;
+ }
+ services.add(reply.readString());
+ reply.recycle();
+ data.recycle();
+ }
+ String[] array = new String[services.size()];
+ services.toArray(array);
+ return array;
}
public void setPermissionController(IPermissionController controller)
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 619bf8d..156600e 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -16,6 +16,10 @@
package android.os;
+import java.util.ArrayList;
+
+import android.util.Log;
+
/**
* Gives access to the system properties store. The system properties
@@ -28,12 +32,15 @@ public class SystemProperties
public static final int PROP_NAME_MAX = 31;
public static final int PROP_VALUE_MAX = 91;
+ private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
+
private static native String native_get(String key);
private static native String native_get(String key, String def);
private static native int native_get_int(String key, int def);
private static native long native_get_long(String key, long def);
private static native boolean native_get_boolean(String key, boolean def);
private static native void native_set(String key, String def);
+ private static native void native_add_change_callback();
/**
* Get the value for the given key.
@@ -124,4 +131,26 @@ public class SystemProperties
}
native_set(key, val);
}
+
+ public static void addChangeCallback(Runnable callback) {
+ synchronized (sChangeCallbacks) {
+ if (sChangeCallbacks.size() == 0) {
+ native_add_change_callback();
+ }
+ sChangeCallbacks.add(callback);
+ }
+ }
+
+ static void callChangeCallbacks() {
+ synchronized (sChangeCallbacks) {
+ //Log.i("foo", "Calling " + sChangeCallbacks.size() + " change callbacks!");
+ if (sChangeCallbacks.size() == 0) {
+ return;
+ }
+ ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
+ for (int i=0; i<callbacks.size(); i++) {
+ callbacks.get(i).run();
+ }
+ }
+ }
}
diff --git a/core/java/android/os/Trace.java b/core/java/android/os/Trace.java
index ac9ee26..911183d 100644
--- a/core/java/android/os/Trace.java
+++ b/core/java/android/os/Trace.java
@@ -39,13 +39,29 @@ public final class Trace {
public static final long TRACE_TAG_SYNC_MANAGER = 1L << 7;
public static final long TRACE_TAG_AUDIO = 1L << 8;
- private static final long sEnabledTags = nativeGetEnabledTags();
+ public static final int TRACE_FLAGS_START_BIT = 1;
+ public static final String[] TRACE_TAGS = {
+ "Graphics", "Input", "View", "WebView", "Window Manager",
+ "Activity Manager", "Sync Manager", "Audio"
+ };
+
+ public static final String PROPERTY_TRACE_TAG_ENABLEFLAGS = "debug.atrace.tags.enableflags";
+
+ private static long sEnabledTags = nativeGetEnabledTags();
private static native long nativeGetEnabledTags();
private static native void nativeTraceCounter(long tag, String name, int value);
private static native void nativeTraceBegin(long tag, String name);
private static native void nativeTraceEnd(long tag);
+ static {
+ SystemProperties.addChangeCallback(new Runnable() {
+ @Override public void run() {
+ sEnabledTags = nativeGetEnabledTags();
+ }
+ });
+ }
+
private Trace() {
}
diff --git a/core/java/android/preference/MultiCheckPreference.java b/core/java/android/preference/MultiCheckPreference.java
index 735f66a..6953075 100644
--- a/core/java/android/preference/MultiCheckPreference.java
+++ b/core/java/android/preference/MultiCheckPreference.java
@@ -136,11 +136,25 @@ public class MultiCheckPreference extends DialogPreference {
*
* @return The array of values.
*/
- public CharSequence[] getEntryValues() {
+ public String[] getEntryValues() {
return mEntryValues;
}
/**
+ * Get the boolean state of a given value.
+ */
+ public boolean getValue(int index) {
+ return mSetValues[index];
+ }
+
+ /**
+ * Set the boolean state of a given value.
+ */
+ public void setValue(int index, boolean state) {
+ mSetValues[index] = state;
+ }
+
+ /**
* Sets the current values.
*/
public void setValues(boolean[] values) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2c49bd2..ba8c4c9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1557,6 +1557,9 @@ public final class Settings {
* will likely be removed in a future release with support for
* audio/vibe feedback profiles.
*
+ * Not used anymore. On devices with vibrator, the user explicitly selects
+ * silent or vibrate mode.
+ * Kept for use by legacy database upgrade code in DatabaseHelper.
* @hide
*/
public static final String VIBRATE_IN_SILENT = "vibrate_in_silent";
@@ -1746,6 +1749,20 @@ public final class Settings {
public static final String USER_ROTATION = "user_rotation";
/**
+ * Whether the phone vibrates when it is ringing due to an incoming call. This will
+ * be used by Phone and Setting apps; it shouldn't affect other apps.
+ * The value is boolean (1 or 0).
+ *
+ * Note: this is not same as "vibrate on ring", which had been available until ICS.
+ * It was about AudioManager's setting and thus affected all the applications which
+ * relied on the setting, while this is purely about the vibration setting for incoming
+ * calls.
+ *
+ * @hide
+ */
+ public static final String VIBRATE_WHEN_RINGING = "vibrate_when_ringing";
+
+ /**
* Whether the audible DTMF tones are played by the dialer when dialing. The value is
* boolean (1 or 0).
*/
@@ -1983,7 +2000,6 @@ public final class Settings {
SCREEN_BRIGHTNESS,
SCREEN_BRIGHTNESS_MODE,
SCREEN_AUTO_BRIGHTNESS_ADJ,
- VIBRATE_ON,
VIBRATE_INPUT_DEVICES,
MODE_RINGER,
MODE_RINGER_STREAMS_AFFECTED,
@@ -2002,7 +2018,6 @@ public final class Settings {
VOLUME_ALARM + APPEND_FOR_LAST_AUDIBLE,
VOLUME_NOTIFICATION + APPEND_FOR_LAST_AUDIBLE,
VOLUME_BLUETOOTH_SCO + APPEND_FOR_LAST_AUDIBLE,
- VIBRATE_IN_SILENT,
TEXT_AUTO_REPLACE,
TEXT_AUTO_CAPS,
TEXT_AUTO_PUNCTUATE,
@@ -2029,6 +2044,7 @@ public final class Settings {
SIP_CALL_OPTIONS,
SIP_RECEIVE_CALLS,
POINTER_SPEED,
+ VIBRATE_WHEN_RINGING
};
// Settings moved to Settings.Secure
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2befcce..aad6756 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4676,13 +4676,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
RectF position = mAttachInfo.mTmpTransformRect;
- position.setEmpty();
+ position.set(0, 0, mRight - mLeft, mBottom - mTop);
if (!hasIdentityMatrix()) {
getMatrix().mapRect(position);
}
- position.offset(mLeft, mRight);
+ position.offset(mLeft, mTop);
ViewParent parent = mParent;
while (parent instanceof View) {
@@ -17250,7 +17250,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
/**
* Show where the margins, bounds and layout bounds are for each view.
*/
- final boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
+ boolean mDebugLayout = SystemProperties.getBoolean(DEBUG_LAYOUT_PROPERTY, false);
/**
* Point used to compute visible regions.
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5f295cb..6e6fab2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -408,6 +408,7 @@ public final class ViewRootImpl implements ViewParent,
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
mAttachInfo.mScreenOn = powerManager.isScreenOn();
+ loadSystemProperties();
}
/**
@@ -846,6 +847,16 @@ public final class ViewRootImpl implements ViewParent,
scheduleTraversals();
}
+ void invalidateWorld(View view) {
+ view.invalidate();
+ if (view instanceof ViewGroup) {
+ ViewGroup parent = (ViewGroup)view;
+ for (int i=0; i<parent.getChildCount(); i++) {
+ invalidateWorld(parent.getChildAt(i));
+ }
+ }
+ }
+
public void invalidateChild(View child, Rect dirty) {
invalidateChildInParent(null, dirty);
}
@@ -2730,6 +2741,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_INVALIDATE_DISPLAY_LIST = 21;
private final static int MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST = 22;
private final static int MSG_DISPATCH_DONE_ANIMATING = 23;
+ private final static int MSG_INVALIDATE_WORLD = 24;
final class ViewRootHandler extends Handler {
@Override
@@ -2997,6 +3009,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_DISPATCH_DONE_ANIMATING: {
handleDispatchDoneAnimating();
} break;
+ case MSG_INVALIDATE_WORLD: {
+ invalidateWorld(mView);
+ } break;
}
}
}
@@ -4016,6 +4031,17 @@ public final class ViewRootImpl implements ViewParent,
mHandler.sendMessage(msg);
}
+ public void loadSystemProperties() {
+ boolean layout = SystemProperties.getBoolean(
+ View.DEBUG_LAYOUT_PROPERTY, false);
+ if (layout != mAttachInfo.mDebugLayout) {
+ mAttachInfo.mDebugLayout = layout;
+ if (!mHandler.hasMessages(MSG_INVALIDATE_WORLD)) {
+ mHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_WORLD, 200);
+ }
+ }
+ }
+
private void destroyHardwareRenderer() {
AttachInfo attachInfo = mAttachInfo;
HardwareRenderer hardwareRenderer = attachInfo.mHardwareRenderer;
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index b5690e9..5d33cec 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -23,6 +23,7 @@ import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.opengl.ManagedEGLContext;
import android.os.IBinder;
+import android.os.SystemProperties;
import android.util.AndroidRuntimeException;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
@@ -112,6 +113,8 @@ public class WindowManagerImpl implements WindowManager {
private WindowManager.LayoutParams[] mParams;
private boolean mNeedsEglTerminate;
+ private Runnable mSystemPropertyUpdater = null;
+
private final static Object sLock = new Object();
private final static WindowManagerImpl sWindowManager = new WindowManagerImpl();
private final static HashMap<CompatibilityInfo, WindowManager> sCompatWindowManagers
@@ -237,6 +240,22 @@ public class WindowManagerImpl implements WindowManager {
View panelParentView = null;
synchronized (this) {
+ // Start watching for system property changes.
+ if (mSystemPropertyUpdater == null) {
+ mSystemPropertyUpdater = new Runnable() {
+ @Override public void run() {
+ synchronized (this) {
+ synchronized (this) {
+ for (ViewRootImpl root : mRoots) {
+ root.loadSystemProperties();
+ }
+ }
+ }
+ }
+ };
+ SystemProperties.addChangeCallback(mSystemPropertyUpdater);
+ }
+
// Here's an odd/questionable case: if someone tries to add a
// view multiple times, then we simply bump up a nesting count
// and they need to remove the view the corresponding number of
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index e725e75..388cfb3 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1017,7 +1017,7 @@ public interface WindowManagerPolicy {
/**
* Called when we have finished booting and can now display the home
- * screen to the user. This wilWl happen after systemReady(), and at
+ * screen to the user. This will happen after systemReady(), and at
* this point the display is active.
*/
public void enableScreenAfterBoot();
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 17e4efb..057c3d1 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -609,6 +609,10 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// The presumed scroll rate for the first scroll of edit text
static private final long TEXT_SCROLL_FIRST_SCROLL_MS = 16;
+ // Buffer pixels of the caret rectangle when moving edit text into view
+ // after resize.
+ static private final int EDIT_RECT_BUFFER = 10;
+
// true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
private boolean mAutoRedraw;
@@ -3294,7 +3298,8 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
}
public int getPageBackgroundColor() {
- return nativeGetBackgroundColor();
+ if (mNativeClass == 0) return Color.WHITE;
+ return nativeGetBackgroundColor(mNativeClass);
}
/**
@@ -4451,7 +4456,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
if (mNativeClass == 0) {
return 0;
}
- return nativeGetBaseLayer();
+ return nativeGetBaseLayer(mNativeClass);
}
private void onZoomAnimationStart() {
@@ -5574,9 +5579,76 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// However, do not update the base layer as that hasn't changed
setNewPicture(mLoadedPicture, false);
}
+ if (mIsEditingText) {
+ scrollEditIntoView();
+ }
relocateAutoCompletePopup();
}
+ /**
+ * Scrolls the edit field into view using the minimum scrolling necessary.
+ * If the edit field is too large to fit in the visible window, the caret
+ * dimensions are used so that at least the caret is visible.
+ * A buffer of EDIT_RECT_BUFFER in view pixels is used to offset the
+ * edit rectangle to ensure a margin with the edge of the screen.
+ */
+ private void scrollEditIntoView() {
+ Rect visibleRect = new Rect(viewToContentX(getScrollX()),
+ viewToContentY(getScrollY()),
+ viewToContentX(getScrollX() + getWidth()),
+ viewToContentY(getScrollY() + getViewHeightWithTitle()));
+ if (visibleRect.contains(mEditTextContentBounds)) {
+ return; // no need to scroll
+ }
+ syncSelectionCursors();
+ final int buffer = Math.max(1, viewToContentDimension(EDIT_RECT_BUFFER));
+ Rect showRect = new Rect(
+ Math.max(0, mEditTextContentBounds.left - buffer),
+ Math.max(0, mEditTextContentBounds.top - buffer),
+ mEditTextContentBounds.right + buffer,
+ mEditTextContentBounds.bottom + buffer);
+ Point caretTop = calculateCaretTop();
+ if (visibleRect.width() < mEditTextContentBounds.width()) {
+ // The whole edit won't fit in the width, so use the caret rect
+ if (mSelectCursorBase.x < caretTop.x) {
+ showRect.left = Math.max(0, mSelectCursorBase.x - buffer);
+ showRect.right = caretTop.x + buffer;
+ } else {
+ showRect.left = Math.max(0, caretTop.x - buffer);
+ showRect.right = mSelectCursorBase.x + buffer;
+ }
+ }
+ if (visibleRect.height() < mEditTextContentBounds.height()) {
+ // The whole edit won't fit in the height, so use the caret rect
+ if (mSelectCursorBase.y > caretTop.y) {
+ showRect.top = Math.max(0, caretTop.y - buffer);
+ showRect.bottom = mSelectCursorBase.y + buffer;
+ } else {
+ showRect.top = Math.max(0, mSelectCursorBase.y - buffer);
+ showRect.bottom = caretTop.y + buffer;
+ }
+ }
+
+ if (visibleRect.contains(showRect)) {
+ return; // no need to scroll
+ }
+
+ int scrollX = visibleRect.left;
+ if (visibleRect.left > showRect.left) {
+ scrollX = showRect.left;
+ } else if (visibleRect.right < showRect.right) {
+ scrollX = Math.max(0, showRect.right - visibleRect.width());
+ }
+ int scrollY = visibleRect.top;
+ if (visibleRect.top > showRect.top) {
+ scrollY = showRect.top;
+ } else if (visibleRect.bottom < showRect.bottom) {
+ scrollY = Math.max(0, showRect.bottom - visibleRect.height());
+ }
+
+ contentScrollTo(scrollX, scrollY, false);
+ }
+
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
if (!mInOverScrollMode) {
@@ -8586,7 +8658,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
private native void nativeSetHeightCanMeasure(boolean measure);
private native boolean nativeSetBaseLayer(int nativeInstance,
int layer, boolean showVisualIndicator, boolean isPictureAfterFirstLayout);
- private native int nativeGetBaseLayer();
+ private native int nativeGetBaseLayer(int nativeInstance);
private native void nativeCopyBaseContentToPicture(Picture pict);
private native boolean nativeHasContent();
private native void nativeStopGL();
@@ -8614,7 +8686,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
*/
private native boolean nativeScrollLayer(int nativeInstance, int layer, int newX, int newY);
private native void nativeSetIsScrolling(boolean isScrolling);
- private native int nativeGetBackgroundColor();
+ private native int nativeGetBackgroundColor(int nativeInstance);
native boolean nativeSetProperty(String key, String value);
native String nativeGetProperty(String key);
/**
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a3b613b..3aafba5 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -25,6 +25,7 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
+import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Parcel;
@@ -57,6 +58,7 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
@@ -648,6 +650,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mGlowPaddingLeft;
private int mGlowPaddingRight;
+ /**
+ * Used for interacting with list items from an accessibility service.
+ */
+ private ListItemAccessibilityDelegate mAccessibilityDelegate;
+
private int mLastAccessibilityScrollEventFromIndex;
private int mLastAccessibilityScrollEventToIndex;
@@ -2121,9 +2128,77 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
child.setLayoutParams(lp);
}
+ if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+ if (mAccessibilityDelegate == null) {
+ mAccessibilityDelegate = new ListItemAccessibilityDelegate();
+ }
+ child.setAccessibilityDelegate(mAccessibilityDelegate);
+ }
+
return child;
}
+ class ListItemAccessibilityDelegate extends AccessibilityDelegate {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+
+ final int position = getPositionForView(host);
+
+ if (position == INVALID_POSITION) {
+ return;
+ }
+
+ if (isClickable()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
+ info.setClickable(true);
+ }
+
+ if (isLongClickable()) {
+ info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
+ info.setLongClickable(true);
+ }
+
+ info.addAction(AccessibilityNodeInfo.ACTION_SELECT);
+
+ if (position == getSelectedItemPosition()) {
+ info.setSelected(true);
+ }
+ }
+
+ @Override
+ public boolean performAccessibilityAction(View host, int action, Bundle arguments) {
+ final int position = getPositionForView(host);
+
+ if (position == INVALID_POSITION) {
+ return false;
+ }
+
+ final long id = getItemIdAtPosition(position);
+
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_SELECT:
+ setSelection(position);
+ return true;
+ case AccessibilityNodeInfo.ACTION_CLICK:
+ if (!super.performAccessibilityAction(host, action, arguments)) {
+ return performItemClick(host, position, id);
+ }
+ return true;
+ case AccessibilityNodeInfo.ACTION_LONG_CLICK:
+ if (!super.performAccessibilityAction(host, action, arguments)) {
+ return performLongPress(host, position, id);
+ }
+ return true;
+ case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
+ smoothScrollToPosition(position);
+ break;
+ }
+
+ return super.performAccessibilityAction(host, action, arguments);
+ }
+ }
+
void positionSelector(int position, View sel) {
if (position != INVALID_POSITION) {
mSelectorPosition = position;
@@ -4009,17 +4084,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
void start(final int position) {
stop();
+ if (mDataChanged) {
+ // Wait until we're back in a stable state to try this.
+ post(new Runnable() {
+ @Override public void run() {
+ start(position);
+ }
+ });
+ return;
+ }
+
final int childCount = getChildCount();
if (childCount == 0) {
// Can't scroll without children.
- if (mDataChanged) {
- // But we might have something in a minute.
- post(new Runnable() {
- @Override public void run() {
- start(position);
- }
- });
- }
return;
}
@@ -4058,17 +4135,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
return;
}
+ if (mDataChanged) {
+ // Wait until we're back in a stable state to try this.
+ post(new Runnable() {
+ @Override public void run() {
+ start(position, boundPosition);
+ }
+ });
+ return;
+ }
+
final int childCount = getChildCount();
if (childCount == 0) {
// Can't scroll without children.
- if (mDataChanged) {
- // But we might have something in a minute.
- post(new Runnable() {
- @Override public void run() {
- start(position, boundPosition);
- }
- });
- }
return;
}
@@ -4129,9 +4208,26 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
startWithOffset(position, offset, SCROLL_DURATION);
}
- void startWithOffset(int position, int offset, int duration) {
+ void startWithOffset(final int position, int offset, final int duration) {
stop();
+ if (mDataChanged) {
+ // Wait until we're back in a stable state to try this.
+ final int postOffset = offset;
+ post(new Runnable() {
+ @Override public void run() {
+ startWithOffset(position, postOffset, duration);
+ }
+ });
+ return;
+ }
+
+ final int childCount = getChildCount();
+ if (childCount == 0) {
+ // Can't scroll without children.
+ return;
+ }
+
offset += getPaddingTop();
mTargetPos = position;
@@ -4141,7 +4237,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mMode = MOVE_OFFSET;
final int firstPos = mFirstPosition;
- final int childCount = getChildCount();
final int lastPos = firstPos + childCount - 1;
int viewTravelCount;
@@ -4514,7 +4609,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
if (distance == 0 || mItemCount == 0 || childCount == 0 ||
(firstPos == 0 && getChildAt(0).getTop() == topLimit && distance < 0) ||
- (lastPos == mItemCount - 1 &&
+ (lastPos == mItemCount &&
getChildAt(childCount - 1).getBottom() == bottomLimit && distance > 0)) {
mFlingRunnable.endFling();
if (mPositionScroller != null) {
@@ -5651,6 +5746,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Don't reclaim header or footer views, or views that should be ignored
if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
views.add(child);
+ child.setAccessibilityDelegate(null);
if (listener != null) {
// Pretend they went through the scrap heap
listener.onMovedToScrapHeap(child);
@@ -6206,6 +6302,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mScrapViews[viewType].add(scrap);
}
+ scrap.setAccessibilityDelegate(null);
if (mRecyclerListener != null) {
mRecyclerListener.onMovedToScrapHeap(scrap);
}
@@ -6267,6 +6364,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
lp.scrappedFromPosition = mFirstActivePosition + i;
scrapViews.add(victim);
+ victim.setAccessibilityDelegate(null);
if (hasListener) {
mRecyclerListener.onMovedToScrapHeap(victim);
}
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index e1103dd..ebf8a4a 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -427,12 +427,6 @@ public class SpellChecker implements SpellCheckerSessionListener {
if (spellCheckSpanStart < 0 || spellCheckSpanEnd <= spellCheckSpanStart)
return; // span was removed in the meantime
- final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
- if (suggestionsCount <= 0) {
- // A negative suggestion count is possible
- return;
- }
-
final int start;
final int end;
if (offset != USE_SPAN_RANGE && length != USE_SPAN_RANGE) {
@@ -443,9 +437,15 @@ public class SpellChecker implements SpellCheckerSessionListener {
end = spellCheckSpanEnd;
}
- String[] suggestions = new String[suggestionsCount];
- for (int i = 0; i < suggestionsCount; i++) {
- suggestions[i] = suggestionsInfo.getSuggestionAt(i);
+ final int suggestionsCount = suggestionsInfo.getSuggestionsCount();
+ String[] suggestions;
+ if (suggestionsCount > 0) {
+ suggestions = new String[suggestionsCount];
+ for (int i = 0; i < suggestionsCount; i++) {
+ suggestions[i] = suggestionsInfo.getSuggestionAt(i);
+ }
+ } else {
+ suggestions = ArrayUtils.emptyArray(String.class);
}
SuggestionSpan suggestionSpan = new SuggestionSpan(mTextView.getContext(), suggestions,
@@ -453,7 +453,7 @@ public class SpellChecker implements SpellCheckerSessionListener {
// TODO: Remove mIsSentenceSpellCheckSupported by extracting an interface
// to share the logic of word level spell checker and sentence level spell checker
if (mIsSentenceSpellCheckSupported) {
- final long key = TextUtils.packRangeInLong(start, end);
+ final Long key = Long.valueOf(TextUtils.packRangeInLong(start, end));
final SuggestionSpan tempSuggestionSpan = mSuggestionSpanCache.get(key);
if (tempSuggestionSpan != null) {
if (DBG) {
@@ -611,6 +611,9 @@ public class SpellChecker implements SpellCheckerSessionListener {
if (spellCheckEnd < start) {
break;
}
+ if (spellCheckEnd <= spellCheckStart) {
+ break;
+ }
if (createSpellCheckSpan) {
addSpellCheckSpan(editable, spellCheckStart, spellCheckEnd);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f2334ae..555c974 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -397,7 +397,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/**
* EditText specific data, created on demand when one of the Editor fields is used.
- * See {@link #createEditorIfNeeded(String)}.
+ * See {@link #createEditorIfNeeded()}.
*/
private Editor mEditor;
@@ -798,20 +798,20 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
case com.android.internal.R.styleable.TextView_imeOptions:
- createEditorIfNeeded("IME options specified in constructor");
+ createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.imeOptions = a.getInt(attr,
mEditor.mInputContentType.imeOptions);
break;
case com.android.internal.R.styleable.TextView_imeActionLabel:
- createEditorIfNeeded("IME action label specified in constructor");
+ createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.imeActionLabel = a.getText(attr);
break;
case com.android.internal.R.styleable.TextView_imeActionId:
- createEditorIfNeeded("IME action id specified in constructor");
+ createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.imeActionId = a.getInt(attr,
mEditor.mInputContentType.imeActionId);
@@ -883,7 +883,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
try {
- createEditorIfNeeded("inputMethod in ctor");
+ createEditorIfNeeded();
mEditor.mKeyListener = (KeyListener) c.newInstance();
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
@@ -898,7 +898,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
mEditor.mInputType = EditorInfo.TYPE_CLASS_TEXT;
}
} else if (digits != null) {
- createEditorIfNeeded("digits in ctor");
+ createEditorIfNeeded();
mEditor.mKeyListener = DigitsKeyListener.getInstance(digits.toString());
// If no input type was specified, we will default to generic
// text, since we can't tell the IME about the set of digits
@@ -910,11 +910,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// If set, the input type overrides what was set using the deprecated singleLine flag.
singleLine = !isMultilineInputType(inputType);
} else if (phone) {
- createEditorIfNeeded("dialer in ctor");
+ createEditorIfNeeded();
mEditor.mKeyListener = DialerKeyListener.getInstance();
mEditor.mInputType = inputType = EditorInfo.TYPE_CLASS_PHONE;
} else if (numeric != 0) {
- createEditorIfNeeded("numeric in ctor");
+ createEditorIfNeeded();
mEditor.mKeyListener = DigitsKeyListener.getInstance((numeric & SIGNED) != 0,
(numeric & DECIMAL) != 0);
inputType = EditorInfo.TYPE_CLASS_NUMBER;
@@ -951,7 +951,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
break;
}
- createEditorIfNeeded("text input in ctor");
+ createEditorIfNeeded();
mEditor.mKeyListener = TextKeyListener.getInstance(autotext, cap);
mEditor.mInputType = inputType;
} else if (isTextSelectable()) {
@@ -964,7 +964,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
// So that selection can be changed using arrow keys and touch is handled.
setMovementMethod(ArrowKeyMovementMethod.getInstance());
} else if (editable) {
- createEditorIfNeeded("editable input in ctor");
+ createEditorIfNeeded();
mEditor.mKeyListener = TextKeyListener.getInstance();
mEditor.mInputType = EditorInfo.TYPE_CLASS_TEXT;
} else {
@@ -987,7 +987,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
webPasswordInputType, numberPasswordInputType);
if (selectallonfocus) {
- createEditorIfNeeded("selectallonfocus in constructor");
+ createEditorIfNeeded();
mEditor.mSelectAllOnFocus = true;
if (bufferType == BufferType.NORMAL)
@@ -1335,7 +1335,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
fixFocusableAndClickableSettings();
if (input != null) {
- createEditorIfNeeded("input is not null");
+ createEditorIfNeeded();
try {
mEditor.mInputType = mEditor.mKeyListener.getInputType();
} catch (IncompatibleClassChangeError e) {
@@ -1355,7 +1355,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private void setKeyListenerOnly(KeyListener input) {
if (mEditor == null && input == null) return; // null is the default value
- createEditorIfNeeded("setKeyListenerOnly");
+ createEditorIfNeeded();
if (mEditor.mKeyListener != input) {
mEditor.mKeyListener = input;
if (input != null && !(mText instanceof Editable)) {
@@ -2383,7 +2383,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
@android.view.RemotableViewMethod
public final void setShowSoftInputOnFocus(boolean show) {
- createEditorIfNeeded("setShowSoftInputOnFocus");
+ createEditorIfNeeded();
mEditor.mShowSoftInputOnFocus = show;
}
@@ -3263,7 +3263,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
Selection.setSelection((Spannable) mText, ss.selStart, ss.selEnd);
if (ss.frozenWithFocus) {
- createEditorIfNeeded("restore instance with focus");
+ createEditorIfNeeded();
mEditor.mFrozenWithFocus = true;
}
}
@@ -3424,7 +3424,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (type == BufferType.EDITABLE || getKeyListener() != null ||
needEditableForNotification) {
- createEditorIfNeeded("setText with BufferType.EDITABLE or non null mInput");
+ createEditorIfNeeded();
Editable t = mEditableFactory.newEditable(text);
text = t;
setFilters(t, mFilters);
@@ -3768,7 +3768,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
public void setRawInputType(int type) {
if (type == InputType.TYPE_NULL && mEditor == null) return; //TYPE_NULL is the default value
- createEditorIfNeeded("non null input type");
+ createEditorIfNeeded();
mEditor.mInputType = type;
}
@@ -3811,7 +3811,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
setRawInputType(type);
if (direct) {
- createEditorIfNeeded("setInputType");
+ createEditorIfNeeded();
mEditor.mKeyListener = input;
} else {
setKeyListenerOnly(input);
@@ -3837,7 +3837,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_imeOptions
*/
public void setImeOptions(int imeOptions) {
- createEditorIfNeeded("IME options specified");
+ createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.imeOptions = imeOptions;
}
@@ -3864,7 +3864,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_imeActionId
*/
public void setImeActionLabel(CharSequence label, int actionId) {
- createEditorIfNeeded("IME action label specified");
+ createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.imeActionLabel = label;
mEditor.mInputContentType.imeActionId = actionId;
@@ -3901,7 +3901,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* modifier will, however, allow the user to insert a newline character.
*/
public void setOnEditorActionListener(OnEditorActionListener l) {
- createEditorIfNeeded("Editor action listener set");
+ createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.onEditorActionListener = l;
}
@@ -3998,7 +3998,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_privateImeOptions
*/
public void setPrivateImeOptions(String type) {
- createEditorIfNeeded("Private IME option set");
+ createEditorIfNeeded();
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.privateImeOptions = type;
}
@@ -4026,7 +4026,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @attr ref android.R.styleable#TextView_editorExtras
*/
public void setInputExtras(int xmlResId) throws XmlPullParserException, IOException {
- createEditorIfNeeded("Input extra set");
+ createEditorIfNeeded();
XmlResourceParser parser = getResources().getXml(xmlResId);
mEditor.createInputContentTypeIfNeeded();
mEditor.mInputContentType.extras = new Bundle();
@@ -4045,7 +4045,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
public Bundle getInputExtras(boolean create) {
if (mEditor == null && !create) return null;
- createEditorIfNeeded("get Input extra");
+ createEditorIfNeeded();
if (mEditor.mInputContentType == null) {
if (!create) return null;
mEditor.createInputContentTypeIfNeeded();
@@ -4097,7 +4097,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* be cleared (and you should provide a <code>null</code> icon as well).
*/
public void setError(CharSequence error, Drawable icon) {
- createEditorIfNeeded("setError");
+ createEditorIfNeeded();
mEditor.setError(error, icon);
}
@@ -4609,7 +4609,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
public void setTextIsSelectable(boolean selectable) {
if (!selectable && mEditor == null) return; // false is default value with no edit data
- createEditorIfNeeded("setTextIsSelectable");
+ createEditorIfNeeded();
if (mEditor.mTextIsSelectable == selectable) return;
mEditor.mTextIsSelectable = selectable;
@@ -5422,7 +5422,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @return Returns true if the text was successfully extracted, else false.
*/
public boolean extractText(ExtractedTextRequest request, ExtractedText outText) {
- createEditorIfNeeded("extractText");
+ createEditorIfNeeded();
return mEditor.extractText(request, outText);
}
@@ -6836,7 +6836,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
@android.view.RemotableViewMethod
public void setSelectAllOnFocus(boolean selectAllOnFocus) {
- createEditorIfNeeded("setSelectAllOnFocus");
+ createEditorIfNeeded();
mEditor.mSelectAllOnFocus = selectAllOnFocus;
if (selectAllOnFocus && !(mText instanceof Spannable)) {
@@ -6855,7 +6855,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
@android.view.RemotableViewMethod
public void setCursorVisible(boolean visible) {
if (visible && mEditor == null) return; // visible is the default value with no edit data
- createEditorIfNeeded("setCursorVisible");
+ createEditorIfNeeded();
if (mEditor.mCursorVisible != visible) {
mEditor.mCursorVisible = visible;
invalidate();
@@ -7914,7 +7914,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* that case, to allow for quick replacement.
*/
public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
- createEditorIfNeeded("custom selection action mode set");
+ createEditorIfNeeded();
mEditor.mCustomSelectionActionModeCallback = actionModeCallback;
}
@@ -8285,16 +8285,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* Also note that for performance reasons, the mEditor is created when needed, but not
* reset when no more edit-specific fields are needed.
*/
- private void createEditorIfNeeded(String reason) {
+ private void createEditorIfNeeded() {
if (mEditor == null) {
- if (!(this instanceof EditText)) {
- Log.e(LOG_TAG + " EDITOR", "Creating an Editor on a regular TextView. " + reason);
- }
mEditor = new Editor(this);
- } else {
- if (!(this instanceof EditText)) {
- Log.d(LOG_TAG + " EDITOR", "Redundant Editor creation. " + reason);
- }
}
}
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index 48ed561..246b0c9 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -57,25 +57,25 @@ public class PackageHelper {
public static final int APP_INSTALL_INTERNAL = 1;
public static final int APP_INSTALL_EXTERNAL = 2;
- public static IMountService getMountService() {
+ public static IMountService getMountService() throws RemoteException {
IBinder service = ServiceManager.getService("mount");
if (service != null) {
return IMountService.Stub.asInterface(service);
} else {
Log.e(TAG, "Can't get mount service");
+ throw new RemoteException("Could not contact mount service");
}
- return null;
}
public static String createSdDir(int sizeMb, String cid, String sdEncKey, int uid,
boolean isExternal) {
// Create mount point via MountService
- IMountService mountService = getMountService();
+ try {
+ IMountService mountService = getMountService();
- if (localLOGV)
- Log.i(TAG, "Size of container " + sizeMb + " MB");
+ if (localLOGV)
+ Log.i(TAG, "Size of container " + sizeMb + " MB");
- try {
int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid,
isExternal);
if (rc != StorageResultCode.OperationSucceeded) {
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 6cfb97d..26235f1 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -19,8 +19,6 @@ package com.android.internal.util;
import android.os.FileUtils;
import android.util.Slog;
-import com.android.internal.util.FileRotator.Rewriter;
-
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -29,8 +27,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
import libcore.io.IoUtils;
+import libcore.io.Streams;
/**
* Utility that rotates files over time, similar to {@code logrotate}. There is
@@ -137,10 +138,38 @@ public class FileRotator {
public void deleteAll() {
final FileInfo info = new FileInfo(mPrefix);
for (String name : mBasePath.list()) {
- if (!info.parse(name)) continue;
+ if (info.parse(name)) {
+ // delete each file that matches parser
+ new File(mBasePath, name).delete();
+ }
+ }
+ }
+
+ /**
+ * Dump all files managed by this rotator for debugging purposes.
+ */
+ public void dumpAll(OutputStream os) throws IOException {
+ final ZipOutputStream zos = new ZipOutputStream(os);
+ try {
+ final FileInfo info = new FileInfo(mPrefix);
+ for (String name : mBasePath.list()) {
+ if (info.parse(name)) {
+ final ZipEntry entry = new ZipEntry(name);
+ zos.putNextEntry(entry);
- // delete each file that matches parser
- new File(mBasePath, name).delete();
+ final File file = new File(mBasePath, name);
+ final FileInputStream is = new FileInputStream(file);
+ try {
+ Streams.copy(is, zos);
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+
+ zos.closeEntry();
+ }
+ }
+ } finally {
+ IoUtils.closeQuietly(zos);
}
}
@@ -159,22 +188,22 @@ public class FileRotator {
public void combineActive(final Reader reader, final Writer writer, long currentTimeMillis)
throws IOException {
rewriteActive(new Rewriter() {
- /** {@inheritDoc} */
+ @Override
public void reset() {
// ignored
}
- /** {@inheritDoc} */
+ @Override
public void read(InputStream in) throws IOException {
reader.read(in);
}
- /** {@inheritDoc} */
+ @Override
public boolean shouldWrite() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public void write(OutputStream out) throws IOException {
writer.write(out);
}
@@ -224,11 +253,11 @@ public class FileRotator {
// write success, delete backup
backupFile.delete();
- } catch (IOException e) {
+ } catch (Throwable t) {
// write failed, delete file and restore backup
file.delete();
backupFile.renameTo(file);
- throw e;
+ throw rethrowAsIoException(t);
}
} else {
@@ -241,11 +270,11 @@ public class FileRotator {
// write success, delete empty backup
backupFile.delete();
- } catch (IOException e) {
+ } catch (Throwable t) {
// write failed, delete file and empty backup
file.delete();
backupFile.delete();
- throw e;
+ throw rethrowAsIoException(t);
}
}
}
@@ -353,6 +382,14 @@ public class FileRotator {
}
}
+ private static IOException rethrowAsIoException(Throwable t) throws IOException {
+ if (t instanceof IOException) {
+ throw (IOException) t;
+ } else {
+ throw new IOException(t.getMessage(), t);
+ }
+ }
+
/**
* Details for a rotated file, either parsed from an existing filename, or
* ready to be built into a new filename.
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index a331bec..b3e2d27 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -220,7 +220,6 @@ public class ListMenuPresenter implements MenuPresenter, AdapterView.OnItemClick
private int mExpandedIndex = -1;
public MenuAdapter() {
- registerDataSetObserver(new ExpandedIndexObserver());
findExpandedIndex();
}
@@ -273,12 +272,11 @@ public class ListMenuPresenter implements MenuPresenter, AdapterView.OnItemClick
}
mExpandedIndex = -1;
}
- }
- private class ExpandedIndexObserver extends DataSetObserver {
@Override
- public void onChanged() {
- mAdapter.findExpandedIndex();
+ public void notifyDataSetChanged() {
+ findExpandedIndex();
+ super.notifyDataSetChanged();
}
}
}
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 329b457..cacc86b 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -307,7 +307,6 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
public MenuAdapter(MenuBuilder menu) {
mAdapterMenu = menu;
- registerDataSetObserver(new ExpandedIndexObserver());
findExpandedIndex();
}
@@ -363,12 +362,11 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
}
mExpandedIndex = -1;
}
- }
- private class ExpandedIndexObserver extends DataSetObserver {
@Override
- public void onChanged() {
- mAdapter.findExpandedIndex();
+ public void notifyDataSetChanged() {
+ findExpandedIndex();
+ super.notifyDataSetChanged();
}
}
}
diff --git a/core/jni/android_os_SystemProperties.cpp b/core/jni/android_os_SystemProperties.cpp
index 66af965..677396d1 100644
--- a/core/jni/android_os_SystemProperties.cpp
+++ b/core/jni/android_os_SystemProperties.cpp
@@ -15,7 +15,11 @@
** limitations under the License.
*/
+#define LOG_TAG "SysPropJNI"
+
#include "cutils/properties.h"
+#include "utils/misc.h"
+#include <utils/Log.h>
#include "jni.h"
#include "android_runtime/AndroidRuntime.h"
#include <nativehelper/JNIHelp.h>
@@ -65,6 +69,7 @@ static jint SystemProperties_get_int(JNIEnv *env, jobject clazz,
int len;
const char* key;
char buf[PROPERTY_VALUE_MAX];
+ char* end;
jint result = defJ;
if (keyJ == NULL) {
@@ -76,9 +81,10 @@ static jint SystemProperties_get_int(JNIEnv *env, jobject clazz,
len = property_get(key, buf, "");
if (len > 0) {
- jint temp;
- if (sscanf(buf, "%d", &temp) == 1)
- result = temp;
+ result = strtol(buf, &end, 0);
+ if (end == buf) {
+ result = defJ;
+ }
}
env->ReleaseStringUTFChars(keyJ, key);
@@ -93,6 +99,7 @@ static jlong SystemProperties_get_long(JNIEnv *env, jobject clazz,
int len;
const char* key;
char buf[PROPERTY_VALUE_MAX];
+ char* end;
jlong result = defJ;
if (keyJ == NULL) {
@@ -104,9 +111,10 @@ static jlong SystemProperties_get_long(JNIEnv *env, jobject clazz,
len = property_get(key, buf, "");
if (len > 0) {
- jlong temp;
- if (sscanf(buf, "%lld", &temp) == 1)
- result = temp;
+ result = strtoll(buf, &end, 0);
+ if (end == buf) {
+ result = defJ;
+ }
}
env->ReleaseStringUTFChars(keyJ, key);
@@ -184,6 +192,34 @@ static void SystemProperties_set(JNIEnv *env, jobject clazz,
}
}
+static JavaVM* sVM = NULL;
+static jclass sClazz = NULL;
+static jmethodID sCallChangeCallbacks;
+
+static void do_report_sysprop_change() {
+ //ALOGI("Java SystemProperties: VM=%p, Clazz=%p", sVM, sClazz);
+ if (sVM != NULL && sClazz != NULL) {
+ JNIEnv* env;
+ if (sVM->GetEnv((void **)&env, JNI_VERSION_1_4) >= 0) {
+ //ALOGI("Java SystemProperties: calling %p", sCallChangeCallbacks);
+ env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks);
+ }
+ }
+}
+
+static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
+{
+ // This is called with the Java lock held.
+ if (sVM == NULL) {
+ env->GetJavaVM(&sVM);
+ }
+ if (sClazz == NULL) {
+ sClazz = (jclass) env->NewGlobalRef(clazz);
+ sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V");
+ add_sysprop_change_callback(do_report_sysprop_change, -10000);
+ }
+}
+
static JNINativeMethod method_table[] = {
{ "native_get", "(Ljava/lang/String;)Ljava/lang/String;",
(void*) SystemProperties_getS },
@@ -197,6 +233,8 @@ static JNINativeMethod method_table[] = {
(void*) SystemProperties_get_boolean },
{ "native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) SystemProperties_set },
+ { "native_add_change_callback", "()V",
+ (void*) SystemProperties_add_change_callback },
};
int register_android_os_SystemProperties(JNIEnv *env)
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 0f99fb2..04dc49f 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -308,6 +308,12 @@ protected:
env->DeleteLocalRef(excep2);
}
+ // Need to always call through the native implementation of
+ // SYSPROPS_TRANSACTION.
+ if (code == SYSPROPS_TRANSACTION) {
+ BBinder::onTransact(code, data, reply, flags);
+ }
+
//aout << "onTransact to Java code; result=" << res << endl
// << "Transact from " << this << " to Java code returning "
// << reply << ": " << *reply << endl;
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 61136e3..c5727ea 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -18,6 +18,10 @@
*/
-->
<resources>
+ <!-- The width that is used when creating thumbnails of applications. -->
+ <dimen name="thumbnail_width">200dp</dimen>
+ <!-- The height that is used when creating thumbnails of applications. -->
+ <dimen name="thumbnail_height">177dp</dimen>
<!-- The maximum number of action buttons that should be permitted within
an action bar/action mode. This will be used to determine how many
showAsAction="ifRoom" items can fit. "always" items can override this. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index f812822..734151b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -19,9 +19,9 @@
-->
<resources>
<!-- The width that is used when creating thumbnails of applications. -->
- <dimen name="thumbnail_width">120dp</dimen>
+ <dimen name="thumbnail_width">164dp</dimen>
<!-- The height that is used when creating thumbnails of applications. -->
- <dimen name="thumbnail_height">120dp</dimen>
+ <dimen name="thumbnail_height">145dp</dimen>
<!-- The standard size (both width and height) of an application icon that
will be displayed in the app launcher and elsewhere. -->
<dimen name="app_icon_size">48dip</dimen>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 19aa77b..f7b0cd0 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -246,9 +246,7 @@ public class ConnectivityManagerTestActivity extends Activity {
initializeNetworkStates();
- mWifiManager.setWifiEnabled(true);
log("Clear Wifi before we start the test.");
- sleep(SHORT_TIMEOUT);
removeConfiguredNetworksAndDisableWifi();
mWifiRegexs = mCM.getTetherableWifiRegexs();
}
@@ -645,6 +643,11 @@ public class ConnectivityManagerTestActivity extends Activity {
*/
public boolean disconnectAP() {
// remove saved networks
+ if (!mWifiManager.isWifiEnabled()) {
+ log("Enabled wifi before remove configured networks");
+ mWifiManager.setWifiEnabled(true);
+ sleep(SHORT_TIMEOUT);
+ }
List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
log("size of wifiConfigList: " + wifiConfigList.size());
for (WifiConfiguration wifiConfig: wifiConfigList) {
diff --git a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
index 94d1cb6..95f0e67 100644
--- a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
@@ -187,12 +187,12 @@ public class FileRotatorTest extends AndroidTestCase {
rotate.combineActive(reader, new Writer() {
public void write(OutputStream out) throws IOException {
new DataOutputStream(out).writeUTF("bar");
- throw new ProtocolException("yikes");
+ throw new NullPointerException("yikes");
}
}, currentTime);
fail("woah, somehow able to write exception");
- } catch (ProtocolException e) {
+ } catch (IOException e) {
// expected from above
}
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 13f2480..16a98d3 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -142,6 +142,8 @@ font_src_files := \
Roboto-Bold.ttf \
Roboto-Italic.ttf \
Roboto-BoldItalic.ttf \
+ Roboto-Light.ttf \
+ Roboto-LightItalic.ttf \
DroidNaskh-Regular.ttf \
DroidNaskh-Regular-SystemUI.ttf \
DroidSansDevanagari-Regular.ttf \
diff --git a/data/fonts/Roboto-Light.ttf b/data/fonts/Roboto-Light.ttf
new file mode 100644
index 0000000..b50399e
--- /dev/null
+++ b/data/fonts/Roboto-Light.ttf
Binary files differ
diff --git a/data/fonts/Roboto-LightItalic.ttf b/data/fonts/Roboto-LightItalic.ttf
new file mode 100644
index 0000000..a1fdc8d
--- /dev/null
+++ b/data/fonts/Roboto-LightItalic.ttf
Binary files differ
diff --git a/data/fonts/fonts.mk b/data/fonts/fonts.mk
index 7a84df6..397ccda 100644
--- a/data/fonts/fonts.mk
+++ b/data/fonts/fonts.mk
@@ -24,6 +24,8 @@ PRODUCT_PACKAGES := \
Roboto-Bold.ttf \
Roboto-Italic.ttf \
Roboto-BoldItalic.ttf \
+ Roboto-Light.ttf \
+ Roboto-LightItalic.ttf \
DroidNaskh-Regular.ttf \
DroidNaskh-Regular-SystemUI.ttf \
DroidSansDevanagari-Regular.ttf \
diff --git a/data/fonts/system_fonts.xml b/data/fonts/system_fonts.xml
index d2fe546..95c4f70 100644
--- a/data/fonts/system_fonts.xml
+++ b/data/fonts/system_fonts.xml
@@ -36,6 +36,16 @@
<family>
<nameset>
+ <name>sans-serif-light</name>
+ </nameset>
+ <fileset>
+ <file>Roboto-Light.ttf</file>
+ <file>Roboto-LightItalic.ttf</file>
+ </fileset>
+ </family>
+
+ <family>
+ <nameset>
<name>serif</name>
<name>times</name>
<name>times new roman</name>
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 2174d06..1892fce 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -55,6 +55,7 @@ import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.Vibrator;
import android.provider.Settings;
import android.provider.Settings.System;
import android.telephony.PhoneStateListener;
@@ -119,19 +120,18 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private static final int MSG_PERSIST_VOLUME = 1;
private static final int MSG_PERSIST_MASTER_VOLUME = 2;
private static final int MSG_PERSIST_RINGER_MODE = 3;
- private static final int MSG_PERSIST_VIBRATE_SETTING = 4;
- private static final int MSG_MEDIA_SERVER_DIED = 5;
- private static final int MSG_MEDIA_SERVER_STARTED = 6;
- private static final int MSG_PLAY_SOUND_EFFECT = 7;
- private static final int MSG_BTA2DP_DOCK_TIMEOUT = 8;
- private static final int MSG_LOAD_SOUND_EFFECTS = 9;
- private static final int MSG_SET_FORCE_USE = 10;
- private static final int MSG_PERSIST_MEDIABUTTONRECEIVER = 11;
- private static final int MSG_BT_HEADSET_CNCT_FAILED = 12;
- private static final int MSG_RCDISPLAY_CLEAR = 13;
- private static final int MSG_RCDISPLAY_UPDATE = 14;
- private static final int MSG_SET_ALL_VOLUMES = 15;
- private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 16;
+ private static final int MSG_MEDIA_SERVER_DIED = 4;
+ private static final int MSG_MEDIA_SERVER_STARTED = 5;
+ private static final int MSG_PLAY_SOUND_EFFECT = 6;
+ private static final int MSG_BTA2DP_DOCK_TIMEOUT = 7;
+ private static final int MSG_LOAD_SOUND_EFFECTS = 8;
+ private static final int MSG_SET_FORCE_USE = 9;
+ private static final int MSG_PERSIST_MEDIABUTTONRECEIVER = 10;
+ private static final int MSG_BT_HEADSET_CNCT_FAILED = 11;
+ private static final int MSG_RCDISPLAY_CLEAR = 12;
+ private static final int MSG_RCDISPLAY_UPDATE = 13;
+ private static final int MSG_SET_ALL_VOLUMES = 14;
+ private static final int MSG_PERSIST_MASTER_VOLUME_MUTE = 15;
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -241,6 +241,20 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
};
private int[] mStreamVolumeAlias;
+ // stream names used by dumpStreamStates()
+ private final String[] STREAM_NAMES = new String[] {
+ "STREAM_VOICE_CALL",
+ "STREAM_SYSTEM",
+ "STREAM_RING",
+ "STREAM_MUSIC",
+ "STREAM_ALARM",
+ "STREAM_NOTIFICATION",
+ "STREAM_BLUETOOTH_SCO",
+ "STREAM_SYSTEM_ENFORCED",
+ "STREAM_DTMF",
+ "STREAM_TTS"
+ };
+
private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
@@ -282,14 +296,15 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private int mMuteAffectedStreams;
/**
- * Has multiple bits per vibrate type to indicate the type's vibrate
- * setting. See {@link #setVibrateSetting(int, int)}.
- * <p>
- * NOTE: This is not the final decision of whether vibrate is on/off for the
- * type since it depends on the ringer mode. See {@link #shouldVibrate(int)}.
+ * NOTE: setVibrateSetting(), getVibrateSetting(), shouldVibrate() are deprecated.
+ * mVibrateSetting is just maintained during deprecation period but vibration policy is
+ * now only controlled by mHasVibrator and mRingerMode
*/
private int mVibrateSetting;
+ // Is there a vibrator
+ private final boolean mHasVibrator;
+
// Broadcast receiver for device connections intent broadcasts
private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
@@ -388,6 +403,9 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mMediaEventWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "mediaKeyEvent");
+ Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
+
// Intialized volume
MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = SystemProperties.getInt(
"ro.config.vc_call_vol_steps",
@@ -507,6 +525,16 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
}
+ private void dumpStreamStates(PrintWriter pw) {
+ pw.println("\nStream volumes (device: index)");
+ int numStreamTypes = AudioSystem.getNumStreamTypes();
+ for (int i = 0; i < numStreamTypes; i++) {
+ pw.println("- "+STREAM_NAMES[i]+":");
+ mStreamStates[i].dump(pw);
+ pw.println("");
+ }
+ }
+
private void updateStreamVolumeAlias(boolean updateVolumes) {
int dtmfStreamAlias;
@@ -538,18 +566,34 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
private void readPersistedSettings() {
final ContentResolver cr = mContentResolver;
- int ringerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
+ int ringerModeFromSettings =
+ System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
+ int ringerMode = ringerModeFromSettings;
// sanity check in case the settings are restored from a device with incompatible
// ringer modes
if (!AudioManager.isValidRingerMode(ringerMode)) {
ringerMode = AudioManager.RINGER_MODE_NORMAL;
+ }
+ if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) {
+ ringerMode = AudioManager.RINGER_MODE_SILENT;
+ }
+ if (ringerMode != ringerModeFromSettings) {
System.putInt(cr, System.MODE_RINGER, ringerMode);
}
synchronized(mSettingsLock) {
mRingerMode = ringerMode;
}
- mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
+ // System.VIBRATE_ON is not used any more but defaults for mVibrateSetting
+ // are still needed while setVibrateSetting() and getVibrateSetting() are being deprecated.
+ mVibrateSetting = getValueForVibrateSetting(0,
+ AudioManager.VIBRATE_TYPE_NOTIFICATION,
+ mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
+ : AudioManager.VIBRATE_SETTING_OFF);
+ mVibrateSetting = getValueForVibrateSetting(mVibrateSetting,
+ AudioManager.VIBRATE_TYPE_RINGER,
+ mHasVibrator ? AudioManager.VIBRATE_SETTING_ONLY_SILENT
+ : AudioManager.VIBRATE_SETTING_OFF);
// make sure settings for ringer mode are consistent with device type: non voice capable
// devices (tablets) include media stream in silent mode whereas phones don't.
@@ -639,8 +683,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// If either the client forces allowing ringer modes for this adjustment,
// or the stream type is one that is affected by ringer modes
if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||
- streamTypeAlias == AudioSystem.STREAM_RING ||
- (!mVoiceCapable && streamTypeAlias == AudioSystem.STREAM_MUSIC)) {
+ (streamTypeAlias == getMasterStreamType())) {
int ringerMode = getRingerMode();
// do not vibrate if already in vibrate mode
if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
@@ -648,7 +691,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
// Check if the ringer mode changes with this volume adjustment. If
// it does, it will handle adjusting the volume, so we won't below
- adjustVolume = checkForRingerModeChange(oldIndex, direction, streamTypeAlias);
+ adjustVolume = checkForRingerModeChange(oldIndex, direction);
}
// If stream is muted, adjust last audible index only
@@ -724,9 +767,8 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
(mStreamVolumeAlias[streamType] == getMasterStreamType())) {
int newRingerMode;
if (index == 0) {
- newRingerMode = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1
- ? AudioManager.RINGER_MODE_VIBRATE
- : AudioManager.RINGER_MODE_SILENT;
+ newRingerMode = mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
+ : AudioManager.RINGER_MODE_SILENT;
setStreamVolumeInt(mStreamVolumeAlias[streamType],
index,
device,
@@ -1070,7 +1112,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// on voice capable devices
if (mVoiceCapable &&
mStreamVolumeAlias[streamType] == AudioSystem.STREAM_RING) {
-
Set set = mStreamStates[streamType].mLastAudibleIndex.entrySet();
Iterator i = set.iterator();
while (i.hasNext()) {
@@ -1111,6 +1152,7 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
/** @see AudioManager#shouldVibrate(int) */
public boolean shouldVibrate(int vibrateType) {
+ if (!mHasVibrator) return false;
switch (getVibrateSetting(vibrateType)) {
@@ -1131,21 +1173,20 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
/** @see AudioManager#getVibrateSetting(int) */
public int getVibrateSetting(int vibrateType) {
+ if (!mHasVibrator) return AudioManager.VIBRATE_SETTING_OFF;
return (mVibrateSetting >> (vibrateType * 2)) & 3;
}
/** @see AudioManager#setVibrateSetting(int, int) */
public void setVibrateSetting(int vibrateType, int vibrateSetting) {
+ if (!mHasVibrator) return;
+
mVibrateSetting = getValueForVibrateSetting(mVibrateSetting, vibrateType, vibrateSetting);
// Broadcast change
broadcastVibrateSetting(vibrateType);
- // Post message to set ringer mode (it in turn will post a message
- // to persist)
- sendMsg(mAudioHandler, MSG_PERSIST_VIBRATE_SETTING, SENDMSG_NOOP, 0, 0,
- null, 0);
}
/**
@@ -1967,48 +2008,56 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
* adjusting volume. If so, this will set the proper ringer mode and volume
* indices on the stream states.
*/
- private boolean checkForRingerModeChange(int oldIndex, int direction, int streamType) {
+ private boolean checkForRingerModeChange(int oldIndex, int direction) {
boolean adjustVolumeIndex = true;
int ringerMode = getRingerMode();
- int newRingerMode = ringerMode;
int uiIndex = (oldIndex + 5) / 10;
- boolean vibeInSilent = System.getInt(mContentResolver, System.VIBRATE_IN_SILENT, 1) == 1;
-
- if (ringerMode == RINGER_MODE_NORMAL) {
- if ((direction == AudioManager.ADJUST_LOWER) && (uiIndex <= 1)) {
- // enter silent mode if current index is the last audible one and not repeating a
- // volume key down
- if (vibeInSilent || mPrevVolDirection != AudioManager.ADJUST_LOWER) {
- // "silent mode", but which one?
- newRingerMode = vibeInSilent ? RINGER_MODE_VIBRATE : RINGER_MODE_SILENT;
- }
- if (uiIndex == 0 ||
- (!vibeInSilent &&
- mPrevVolDirection == AudioManager.ADJUST_LOWER &&
- mVoiceCapable && streamType == AudioSystem.STREAM_RING)) {
- adjustVolumeIndex = false;
+
+ switch (ringerMode) {
+ case RINGER_MODE_NORMAL:
+ if (direction == AudioManager.ADJUST_LOWER) {
+ if (mHasVibrator) {
+ if (uiIndex == 1) {
+ ringerMode = RINGER_MODE_VIBRATE;
+ }
+ } else {
+ if (uiIndex == 0 && mPrevVolDirection != AudioManager.ADJUST_LOWER) {
+ ringerMode = RINGER_MODE_SILENT;
+ }
}
}
- } else if (ringerMode == RINGER_MODE_VIBRATE) {
+ break;
+ case RINGER_MODE_VIBRATE:
+ if (!mHasVibrator) {
+ Log.e(TAG, "checkForRingerModeChange() current ringer mode is vibrate" +
+ "but no vibrator is present");
+ break;
+ }
if ((direction == AudioManager.ADJUST_LOWER)) {
- // Set it to silent, if it wasn't a long-press
if (mPrevVolDirection != AudioManager.ADJUST_LOWER) {
- newRingerMode = RINGER_MODE_SILENT;
+ ringerMode = RINGER_MODE_SILENT;
}
} else if (direction == AudioManager.ADJUST_RAISE) {
- newRingerMode = RINGER_MODE_NORMAL;
+ ringerMode = RINGER_MODE_NORMAL;
}
adjustVolumeIndex = false;
- } else {
+ break;
+ case RINGER_MODE_SILENT:
if (direction == AudioManager.ADJUST_RAISE) {
- // exiting silent mode
- // If VIBRATE_IN_SILENT, then go into vibrate mode
- newRingerMode = vibeInSilent ? RINGER_MODE_VIBRATE : RINGER_MODE_NORMAL;
+ if (mHasVibrator) {
+ ringerMode = RINGER_MODE_VIBRATE;
+ } else {
+ ringerMode = RINGER_MODE_NORMAL;
+ }
}
adjustVolumeIndex = false;
+ break;
+ default:
+ Log.e(TAG, "checkForRingerModeChange() wrong ringer mode: "+ringerMode);
+ break;
}
- setRingerMode(newRingerMode);
+ setRingerMode(ringerMode);
mPrevVolDirection = direction;
@@ -2217,9 +2266,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
}
public void readSettings() {
- boolean checkSilentVolume = (mRingerMode == AudioManager.RINGER_MODE_NORMAL) &&
- isStreamAffectedByRingerMode(mStreamType);
-
int remainingDevices = AudioSystem.DEVICE_OUT_ALL;
for (int i = 0; remainingDevices != 0; i++) {
@@ -2248,12 +2294,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
index : AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
int lastAudibleIndex = Settings.System.getInt(mContentResolver, name, defaultIndex);
- // a last audible index of 0 is never stored, except on non-voice capable devices
- // (e.g. tablets) for the music stream type, where the music stream volume can reach
- // 0 without the device being in silent mode
+ // a last audible index of 0 should never be stored for ring and notification
+ // streams on phones (voice capable devices).
+ // same for system stream on phones and tablets
if ((lastAudibleIndex == 0) &&
- (mVoiceCapable ||
- (mStreamVolumeAlias[mStreamType] != AudioSystem.STREAM_MUSIC))) {
+ ((mVoiceCapable &&
+ (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_RING)) ||
+ (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_SYSTEM))) {
lastAudibleIndex = AudioManager.DEFAULT_STREAM_VOLUME[mStreamType];
// Correct the data base
sendMsg(mAudioHandler,
@@ -2265,12 +2312,13 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
PERSIST_DELAY);
}
mLastAudibleIndex.put(device, getValidIndex(10 * lastAudibleIndex));
- // the initial index should never be 0 for a stream affected by ringer mode if not
- // in silent or vibrate mode.
- // this is permitted on tablets for music stream type.
- if (checkSilentVolume && (index == 0) &&
- (mVoiceCapable ||
- (mStreamVolumeAlias[mStreamType] != AudioSystem.STREAM_MUSIC))) {
+ // the initial index should never be 0 for ring and notification streams on phones
+ // (voice capable devices) if not in silent or vibrate mode.
+ // same for system stream on phones and tablets
+ if ((index == 0) && (mRingerMode == AudioManager.RINGER_MODE_NORMAL) &&
+ ((mVoiceCapable &&
+ (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_RING)) ||
+ (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_SYSTEM))) {
index = lastAudibleIndex;
// Correct the data base
sendMsg(mAudioHandler,
@@ -2328,14 +2376,22 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
mLastAudibleIndex.put(device, index);
}
// Apply change to all streams using this one as alias
+ // if changing volume of current device, also change volume of current
+ // device on aliased stream
+ boolean currentDevice = (device == getDeviceForStream(mStreamType));
int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
- if (streamType != mStreamType && mStreamVolumeAlias[streamType] == mStreamType) {
- mStreamStates[streamType].setIndex(rescaleIndex(index,
- mStreamType,
- streamType),
- getDeviceForStream(streamType),
+ if (streamType != mStreamType &&
+ mStreamVolumeAlias[streamType] == mStreamType) {
+ int scaledIndex = rescaleIndex(index, mStreamType, streamType);
+ mStreamStates[streamType].setIndex(scaledIndex,
+ device,
lastAudible);
+ if (currentDevice) {
+ mStreamStates[streamType].setIndex(scaledIndex,
+ getDeviceForStream(streamType),
+ lastAudible);
+ }
}
}
return true;
@@ -2544,6 +2600,25 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
return handler;
}
}
+
+ private void dump(PrintWriter pw) {
+ pw.print(" Current: ");
+ Set set = mIndex.entrySet();
+ Iterator i = set.iterator();
+ while (i.hasNext()) {
+ Map.Entry entry = (Map.Entry)i.next();
+ pw.print(Integer.toHexString(((Integer)entry.getKey()).intValue())
+ + ": " + ((((Integer)entry.getValue()).intValue() + 5) / 10)+", ");
+ }
+ pw.print("\n Last audible: ");
+ set = mLastAudibleIndex.entrySet();
+ i = set.iterator();
+ while (i.hasNext()) {
+ Map.Entry entry = (Map.Entry)i.next();
+ pw.print(Integer.toHexString(((Integer)entry.getKey()).intValue())
+ + ": " + ((((Integer)entry.getValue()).intValue() + 5) / 10)+", ");
+ }
+ }
}
/** Thread that handles native AudioSystem control. */
@@ -2631,10 +2706,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
System.putInt(mContentResolver, System.MODE_RINGER, ringerMode);
}
- private void persistVibrateSetting() {
- System.putInt(mContentResolver, System.VIBRATE_ON, mVibrateSetting);
- }
-
private void playSoundEffect(int effectType, int volume) {
synchronized (mSoundEffectsLock) {
if (mSoundPool == null) {
@@ -2734,10 +2805,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
persistRingerMode(getRingerMode());
break;
- case MSG_PERSIST_VIBRATE_SETTING:
- persistVibrateSetting();
- break;
-
case MSG_MEDIA_SERVER_DIED:
if (!mMediaServerOk) {
Log.e(TAG, "Media server died.");
@@ -4366,5 +4433,6 @@ public class AudioService extends IAudioService.Stub implements OnFinished {
// TODO probably a lot more to do here than just the audio focus and remote control stacks
dumpFocusStack(pw);
dumpRCStack(pw);
+ dumpStreamStates(pw);
}
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 9bafa5c..55071ec 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -260,6 +260,8 @@ public class AudioSystem
public static final String DEVICE_OUT_AUX_DIGITAL_NAME = "aux_digital";
public static final String DEVICE_OUT_ANLG_DOCK_HEADSET_NAME = "analog_dock";
public static final String DEVICE_OUT_DGTL_DOCK_HEADSET_NAME = "digital_dock";
+ public static final String DEVICE_OUT_USB_ACCESSORY_NAME = "usb_accessory";
+ public static final String DEVICE_OUT_USB_DEVICE_NAME = "usb_device";
public static String getDeviceName(int device)
{
@@ -290,6 +292,10 @@ public class AudioSystem
return DEVICE_OUT_ANLG_DOCK_HEADSET_NAME;
case DEVICE_OUT_DGTL_DOCK_HEADSET:
return DEVICE_OUT_DGTL_DOCK_HEADSET_NAME;
+ case DEVICE_OUT_USB_ACCESSORY:
+ return DEVICE_OUT_USB_ACCESSORY_NAME;
+ case DEVICE_OUT_USB_DEVICE:
+ return DEVICE_OUT_USB_DEVICE_NAME;
case DEVICE_IN_DEFAULT:
default:
return "";
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 58b30db..d3a00c2 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -225,11 +225,6 @@ final public class MediaExtractor {
* If possible, seek to the sync sample closest to the specified time
*/
public static final int SEEK_TO_CLOSEST_SYNC = 2;
- /**
- * If possible, seek to a sample closest to the specified time, which may
- * NOT be a sync sample!
- */
- public static final int SEEK_TO_CLOSEST = 3;
/**
* All selected tracks seek near the requested time according to the
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 7540c6f..9f0fd48 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -743,9 +743,14 @@ public class MediaPlayer
}
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
- request.writeInterfaceToken(IMEDIA_PLAYER);
- request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
- invoke(request, reply);
+ try {
+ request.writeInterfaceToken(IMEDIA_PLAYER);
+ request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
+ invoke(request, reply);
+ } finally {
+ request.recycle();
+ reply.recycle();
+ }
}
/**
@@ -1642,11 +1647,16 @@ public class MediaPlayer
public TrackInfo[] getTrackInfo() throws IllegalStateException {
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
- request.writeInterfaceToken(IMEDIA_PLAYER);
- request.writeInt(INVOKE_ID_GET_TRACK_INFO);
- invoke(request, reply);
- TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
- return trackInfo;
+ try {
+ request.writeInterfaceToken(IMEDIA_PLAYER);
+ request.writeInt(INVOKE_ID_GET_TRACK_INFO);
+ invoke(request, reply);
+ TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
+ return trackInfo;
+ } finally {
+ request.recycle();
+ reply.recycle();
+ }
}
/* Do not change these values without updating their counterparts
@@ -1791,13 +1801,18 @@ public class MediaPlayer
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
- request.writeInterfaceToken(IMEDIA_PLAYER);
- request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE_FD);
- request.writeFileDescriptor(fd);
- request.writeLong(offset);
- request.writeLong(length);
- request.writeString(mimeType);
- invoke(request, reply);
+ try {
+ request.writeInterfaceToken(IMEDIA_PLAYER);
+ request.writeInt(INVOKE_ID_ADD_EXTERNAL_SOURCE_FD);
+ request.writeFileDescriptor(fd);
+ request.writeLong(offset);
+ request.writeLong(length);
+ request.writeString(mimeType);
+ invoke(request, reply);
+ } finally {
+ request.recycle();
+ reply.recycle();
+ }
}
/**
@@ -1854,10 +1869,15 @@ public class MediaPlayer
throws IllegalStateException {
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
- request.writeInterfaceToken(IMEDIA_PLAYER);
- request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
- request.writeInt(index);
- invoke(request, reply);
+ try {
+ request.writeInterfaceToken(IMEDIA_PLAYER);
+ request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
+ request.writeInt(index);
+ invoke(request, reply);
+ } finally {
+ request.recycle();
+ reply.recycle();
+ }
}
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index c93baf1..351ff04 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -313,7 +313,7 @@ static void android_media_MediaExtractor_seekTo(
}
if (mode < MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC
- || mode > MediaSource::ReadOptions::SEEK_CLOSEST) {
+ || mode >= MediaSource::ReadOptions::SEEK_CLOSEST) {
jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
return;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index abf713b..b0939de 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -63,7 +63,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 76;
+ private static final int DATABASE_VERSION = 78;
private Context mContext;
@@ -657,7 +657,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
upgradeVersion = 53;
}
-
+
if (upgradeVersion == 53) {
/*
* New settings for set install location UI no longer initiated here.
@@ -1031,6 +1031,29 @@ public class DatabaseHelper extends SQLiteOpenHelper {
upgradeVersion = 76;
}
+ /************* The following are Jelly Bean changes ************/
+
+ if (upgradeVersion == 76) {
+ // Removed VIBRATE_IN_SILENT setting
+ db.beginTransaction();
+ try {
+ db.execSQL("DELETE FROM system WHERE name='"
+ + Settings.System.VIBRATE_IN_SILENT + "'");
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+
+ upgradeVersion = 77;
+ }
+
+ if (upgradeVersion == 77) {
+ // Introduce "vibrate when ringing" setting
+ loadVibrateWhenRingingSetting(db);
+
+ upgradeVersion = 78;
+ }
+
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
@@ -1124,7 +1147,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
try {
stmt = db.compileStatement("INSERT OR REPLACE INTO system(name,value)"
+ " VALUES(?,?);");
-
+
// Set the timeout to 30 minutes in milliseconds
loadSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
Integer.toString(30 * 60 * 1000));
@@ -1286,7 +1309,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+ " VALUES(?,?);");
-
+
loadSetting(stmt, Settings.System.VOLUME_MUSIC,
AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
loadSetting(stmt, Settings.System.VOLUME_RING,
@@ -1307,12 +1330,10 @@ public class DatabaseHelper extends SQLiteOpenHelper {
stmt,
Settings.System.VOLUME_BLUETOOTH_SCO,
AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
-
+
loadSetting(stmt, Settings.System.MODE_RINGER,
AudioManager.RINGER_MODE_NORMAL);
-
- loadVibrateSetting(db, false);
-
+
// By default:
// - ringtones, notification, system and music streams are affected by ringer mode
// on non voice capable devices (tablets)
@@ -1337,6 +1358,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
} finally {
if (stmt != null) stmt.close();
}
+
+ loadVibrateWhenRingingSetting(db);
}
private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
@@ -1348,7 +1371,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+ " VALUES(?,?);");
-
+
// Vibrate on by default for ringer, on for notification
int vibrate = 0;
vibrate = AudioService.getValueForVibrateSetting(vibrate,
@@ -1362,6 +1385,24 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
}
+ private void loadVibrateWhenRingingSetting(SQLiteDatabase db) {
+ // The default should be off. VIBRATE_SETTING_ONLY_SILENT should also be ignored here.
+ // Phone app should separately check whether AudioManager#getRingerMode() returns
+ // RINGER_MODE_VIBRATE, with which the device should vibrate anyway.
+ int vibrateSetting = getIntValueFromSystem(db, Settings.System.VIBRATE_ON,
+ AudioManager.VIBRATE_SETTING_OFF);
+ boolean vibrateWhenRinging = ((vibrateSetting & 3) == AudioManager.VIBRATE_SETTING_ON);
+
+ SQLiteStatement stmt = null;
+ try {
+ stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadSetting(stmt, Settings.System.VIBRATE_WHEN_RINGING, vibrateWhenRinging ? 1 : 0);
+ } finally {
+ if (stmt != null) stmt.close();
+ }
+ }
+
private void loadSettings(SQLiteDatabase db) {
loadSystemSettings(db);
loadSecureSettings(db);
@@ -1372,7 +1413,7 @@ public class DatabaseHelper extends SQLiteOpenHelper {
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+ " VALUES(?,?);");
-
+
loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
R.bool.def_dim_screen);
loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
@@ -1381,31 +1422,31 @@ public class DatabaseHelper extends SQLiteOpenHelper {
? 1 : 0);
loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
R.integer.def_screen_off_timeout);
-
+
// Set default cdma emergency tone
loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
-
+
// Set default cdma call auto retry
loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
-
+
// Set default cdma DTMF type
loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
-
+
// Set default hearing aid
loadSetting(stmt, Settings.System.HEARING_AID, 0);
-
+
// Set default tty mode
loadSetting(stmt, Settings.System.TTY_MODE, 0);
-
+
loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
R.bool.def_airplane_mode_on);
-
+
loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
R.string.def_airplane_mode_radios);
-
+
loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
R.string.airplane_mode_toggleable_radios);
-
+
loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
R.bool.def_auto_time); // Sync time to NITZ
@@ -1414,17 +1455,17 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
R.integer.def_screen_brightness);
-
+
loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
R.bool.def_screen_brightness_automatic_mode);
-
+
loadDefaultAnimationSettings(stmt);
-
+
loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
R.bool.def_accelerometer_rotation);
-
+
loadDefaultHapticSettings(stmt);
-
+
loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
R.bool.def_notification_pulse);
loadSetting(stmt, Settings.Secure.SET_INSTALL_LOCATION, 0);
@@ -1433,9 +1474,6 @@ public class DatabaseHelper extends SQLiteOpenHelper {
loadUISoundEffectsSettings(stmt);
- loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
- R.bool.def_vibrate_in_silent);
-
loadIntegerSetting(stmt, Settings.System.POINTER_SPEED,
R.integer.def_pointer_speed);
@@ -1492,41 +1530,41 @@ public class DatabaseHelper extends SQLiteOpenHelper {
try {
stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+ " VALUES(?,?);");
-
+
loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
R.bool.def_bluetooth_on);
-
+
// Data roaming default, based on build
loadSetting(stmt, Settings.Secure.DATA_ROAMING,
"true".equalsIgnoreCase(
SystemProperties.get("ro.com.android.dataroaming",
"false")) ? 1 : 0);
-
+
loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
R.bool.def_install_non_market_apps);
-
+
loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
R.string.def_location_providers_allowed);
-
+
loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
R.bool.assisted_gps_enabled);
-
+
loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
R.integer.def_network_preference);
-
+
loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
R.bool.def_usb_mass_storage_enabled);
-
+
loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
R.bool.def_wifi_on);
loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
R.bool.def_networks_available_notification_on);
-
+
String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
if (!TextUtils.isEmpty(wifiWatchList)) {
loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
}
-
+
// Set the preferred network mode to 0 = Global, CDMA default
int type;
if (BaseCommands.getLteOnCdmaModeStatic() == Phone.LTE_ON_CDMA_TRUE) {
@@ -1536,30 +1574,30 @@ public class DatabaseHelper extends SQLiteOpenHelper {
RILConstants.PREFERRED_NETWORK_MODE);
}
loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
-
+
// Enable or disable Cell Broadcast SMS
loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
-
+
// Don't do this. The SystemServer will initialize ADB_ENABLED from a
// persistent system property instead.
//loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
-
+
// Allow mock locations default, based on build
loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
"1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
-
+
loadSecure35Settings(stmt);
-
+
loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
R.bool.def_mount_play_notification_snd);
-
+
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
R.bool.def_mount_ums_autostart);
-
+
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
R.bool.def_mount_ums_prompt);
-
+
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
R.bool.def_mount_ums_notify_enabled);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 3e7d86a..18e7faa 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -43,9 +43,6 @@ public class SettingsHelper {
private IContentService mContentService;
private IPowerManager mPowerManager;
- private boolean mSilent;
- private boolean mVibrate;
-
public SettingsHelper(Context context) {
mContext = context;
mAudioManager = (AudioManager) context
@@ -119,18 +116,6 @@ public class SettingsHelper {
}
}
- private void setRingerMode() {
- if (mSilent) {
- mAudioManager.setRingerMode(mVibrate ? AudioManager.RINGER_MODE_VIBRATE :
- AudioManager.RINGER_MODE_SILENT);
- } else {
- mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
- mAudioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
- mVibrate ? AudioManager.VIBRATE_SETTING_ON
- : AudioManager.VIBRATE_SETTING_OFF);
- }
- }
-
byte[] getLocaleData() {
Configuration conf = mContext.getResources().getConfiguration();
final Locale loc = conf.locale;
diff --git a/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..8a0a30f
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..bc6462b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
index 69f3543..f4e28ae 100644
--- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..25f15e6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..4f5bba5
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
index fb30982..ef7afb8 100644
--- a/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..2ff93d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..430f913
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..807241a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..2ff93d3
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..430f913
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..807241a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
new file mode 100644
index 0000000..60e7418
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
new file mode 100644
index 0000000..e243e50
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_off.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
index fe2c642..cdad949 100644
--- a/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/status_bar_close_on.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_notify_rotation.xml b/packages/SystemUI/res/drawable/ic_notify_rotation.xml
index 213af80..11bc22c 100644
--- a/packages/SystemUI/res/drawable/ic_notify_rotation.xml
+++ b/packages/SystemUI/res/drawable/ic_notify_rotation.xml
@@ -14,14 +14,23 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true"
- android:drawable="@drawable/ic_notify_rotation_on_normal" />
- <item android:state_checked="true" android:state_pressed="true"
- android:drawable="@drawable/ic_notify_rotation_on_pressed" />
- <item android:state_pressed="true"
- android:drawable="@drawable/ic_notify_rotation_off_pressed" />
- <item
- android:drawable="@drawable/ic_notify_rotation_off_normal" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:constantSize="true">
+ <item android:state_checked="true" android:state_pressed="true">
+ <bitmap android:src="@drawable/ic_notify_rotation_on_pressed"
+ android:gravity="center" />
+ </item>
+ <item android:state_checked="true">
+ <bitmap android:src="@drawable/ic_notify_rotation_on_normal"
+ android:gravity="center" />
+ </item>
+ <item android:state_pressed="true">
+ <bitmap android:src="@drawable/ic_notify_rotation_off_pressed"
+ android:gravity="center" />
+ </item>
+ <item>
+ <bitmap android:src="@drawable/ic_notify_rotation_off_normal"
+ android:gravity="center" />
+ </item>
</selector>
diff --git a/packages/SystemUI/res/drawable/status_bar_close.xml b/packages/SystemUI/res/drawable/status_bar_close.xml
new file mode 100644
index 0000000..2efc3c3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/status_bar_close.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/status_bar_close_on" />
+ <item
+ android:drawable="@drawable/status_bar_close_off" />
+</selector>
+
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index fcdd56c..ec2abe0 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -45,7 +45,7 @@
android:fadingEdge="horizontal"
android:scrollbars="none"
android:fadingEdgeLength="@dimen/status_bar_recents_scroll_fading_edge_length"
- android:layout_gravity="bottom|left"
+ android:layout_gravity="bottom|right"
android:orientation="horizontal"
android:clipToPadding="false"
android:clipChildren="false">
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 8715a99..f69aac8 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -25,25 +25,24 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:background="@drawable/notification_tracking_bg"
- android:paddingTop="@*android:dimen/status_bar_height"
+ android:background="@drawable/notification_panel_bg"
+ android:paddingTop="@dimen/notification_panel_padding_top"
android:layout_marginLeft="@dimen/notification_panel_margin_left"
>
- <RelativeLayout
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="52dp"
- android:paddingTop="3dp"
- android:paddingBottom="5dp"
- android:paddingRight="3dp"
+ android:layout_height="wrap_content"
+ android:paddingTop="@dimen/notification_panel_header_padding_top"
android:background="@drawable/notification_header_bg"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:baselineAligned="false"
>
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
android:layout_marginLeft="8dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
@@ -52,64 +51,41 @@
<com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@id/clock"
android:layout_marginLeft="8dp"
- android:paddingLeft="8dp"
+ android:layout_marginRight="8dp"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
/>
- <!--
- <com.android.systemui.statusbar.phone.CarrierLabel
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:layout_marginTop="1dp"
- android:layout_marginLeft="5dp"
- android:layout_gravity="center_vertical"
- android:paddingBottom="1dp"
- android:paddingLeft="4dp"
- android:textAppearance="?android:attr/textAppearanceLarge"
- android:textColor="?android:attr/textColorSecondary"
- />
- -->
<com.android.systemui.statusbar.RotationToggle android:id="@+id/rotation_lock_button"
android:layout_width="32dp"
android:layout_height="32dp"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@id/date"
- android:layout_marginLeft="12dp"
+ android:layout_margin="8dp"
android:button="@drawable/ic_notify_rotation"
android:contentDescription="@string/accessibility_rotation_lock_off"
/>
<ImageView android:id="@+id/settings_button"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_marginLeft="8dp"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@id/rotation_lock_button"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:scaleType="center"
android:src="@drawable/ic_notify_quicksettings"
android:contentDescription="@string/accessibility_settings_button"
/>
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ />
+
<ImageView android:id="@+id/clear_all_button"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:layout_marginLeft="8dp"
- android:layout_centerVertical="true"
- android:layout_alignParentRight="true"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:scaleType="center"
android:src="@drawable/ic_notify_clear"
android:contentDescription="@string/accessibility_clear_all"
/>
- </RelativeLayout>
-
- <View
- android:layout_width="match_parent"
- android:layout_height="2dp"
- android:layout_marginTop="52dp"
- android:background="@drawable/status_bar_hr"
- />
+ </LinearLayout>
<ScrollView
android:id="@+id/scroll"
@@ -117,8 +93,8 @@
android:layout_height="match_parent"
android:fadingEdge="none"
android:overScrollMode="ifContentScrolls"
- android:layout_marginTop="54dp"
- android:layout_marginBottom="34dp"
+ android:layout_marginTop="@dimen/notification_panel_header_height"
+ android:layout_marginBottom="@dimen/close_handle_underlap"
>
<com.android.systemui.statusbar.policy.NotificationRowLayout
android:id="@+id/latestItems"
@@ -128,14 +104,6 @@
/>
</ScrollView>
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:src="@drawable/title_bar_shadow"
- android:layout_marginTop="54dp"
- android:scaleType="fitXY"
- />
-
<com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
android:layout_width="match_parent"
android:layout_height="@dimen/close_handle_height"
@@ -144,10 +112,10 @@
>
<ImageView
android:layout_width="match_parent"
- android:layout_height="34dp"
+ android:layout_height="@dimen/close_handle_height"
android:layout_gravity="bottom"
android:scaleType="fitXY"
- android:src="@drawable/status_bar_close_on"
+ android:src="@drawable/status_bar_close"
/>
</com.android.systemui.statusbar.phone.CloseDragHandle>
diff --git a/packages/SystemUI/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml
deleted file mode 100644
index c1b0066..0000000
--- a/packages/SystemUI/res/layout/status_bar_tracking.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<com.android.systemui.statusbar.phone.TrackingView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:visibility="gone"
- android:focusable="true"
- android:descendantFocusability="afterDescendants"
- android:paddingBottom="0px"
- android:paddingLeft="0px"
- android:paddingRight="0px"
- >
-
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:background="@drawable/notification_tracking_bg"
- >
- <com.android.systemui.statusbar.phone.CarrierLabel
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_gravity="bottom"
- android:gravity="center"
- android:paddingBottom="20dp"
- />
- </FrameLayout>
-
- <com.android.systemui.statusbar.phone.CloseDragHandle android:id="@+id/close"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- >
- <ImageView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:scaleType="fitXY"
- android:src="@drawable/status_bar_close_on"
- />
-
- </com.android.systemui.statusbar.phone.CloseDragHandle>
-
-</com.android.systemui.statusbar.phone.TrackingView>
diff --git a/core/java/android/net/nsd/NetworkServiceInfo.java b/packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml
index 34d83d1..e440de1 100644
--- a/core/java/android/net/nsd/NetworkServiceInfo.java
+++ b/packages/SystemUI/res/values-sw600dp-land/values-land-sw600dp/dimens.xml
@@ -1,32 +1,21 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2012, 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
+ * 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.net.nsd;
-
-/**
- * Interface for a network service.
- *
- * {@hide}
- */
-public interface NetworkServiceInfo {
-
- String getServiceName();
- void setServiceName(String s);
-
- String getServiceType();
- void setServiceType(String s);
-
-}
+*/
+-->
+<resources>
+ <!-- Recent Applications parameters -->
+ <dimen name="status_bar_recents_app_label_width">190dip</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp-port/dimens.xml b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
new file mode 100644
index 0000000..7dc91d1
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp-port/dimens.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+-->
+<resources>
+ <!-- Recent Applications parameters -->
+ <dimen name="status_bar_recents_app_label_width">140dip</dimen>
+</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 50a61b1..2cb99ff 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -16,8 +16,8 @@
*/
-->
<resources>
- <!-- The width of the notification panel window -->
- <dimen name="notification_panel_width">446dp</dimen>
+ <!-- The width of the notification panel window: 446 + 16 + 16 (padding in the bg drawable) -->
+ <dimen name="notification_panel_width">478dp</dimen>
<!-- Layout parameters for the notification panel -->
<dimen name="notification_panel_margin_bottom">192dp</dimen>
@@ -36,4 +36,10 @@
<!-- Height of search panel including navigation bar height -->
<dimen name="navbar_search_panel_height">300dip</dimen>
+ <!-- Extra space above the clock in the panel; on this device, zero -->
+ <dimen name="notification_panel_header_padding_top">0dp</dimen>
+
+ <!-- Size of application thumbnail -->
+ <dimen name="status_bar_recents_thumbnail_width">200dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_height">177dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 9257195..ac2779f 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -20,11 +20,11 @@
<drawable name="notification_number_text_color">#ffffffff</drawable>
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
<drawable name="status_bar_background">#ff000000</drawable>
+ <color name="notification_panel_solid_background">#ff000000</color>
<drawable name="status_bar_recents_app_thumbnail_background">#88000000</drawable>
<color name="status_bar_recents_app_label_color">#ffffffff</color>
<drawable name="status_bar_notification_row_background_color">#ff090909</drawable>
<drawable name="notification_header_bg">#FF000000</drawable>
- <drawable name="notification_tracking_bg">#66000000</drawable>
<color name="notification_list_shadow_top">#80000000</color>
<drawable name="recents_callout_line">#99ffffff</drawable>
<drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 276d74b..b908188 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -125,7 +125,19 @@
<dimen name="navbar_search_panel_height">230dip</dimen>
<!-- Height of the draggable handle at the bottom of the phone notification panel -->
- <dimen name="close_handle_height">34dp</dimen>
+ <dimen name="close_handle_height">32dp</dimen>
+
+ <!-- Amount of close_handle that will not overlap the notification list -->
+ <dimen name="close_handle_underlap">18dp</dimen>
+
+ <!-- Height of the notification panel header bar -->
+ <dimen name="notification_panel_header_height">48dp</dimen>
+
+ <!-- Height of the notification panel header bar -->
+ <dimen name="notification_panel_padding_top">@*android:dimen/status_bar_height</dimen>
+
+ <!-- Extra space above the clock in the panel; half of (notification_panel_header_height - 32) -->
+ <dimen name="notification_panel_header_padding_top">0dp</dimen>
<!-- Layout parameters for the notification panel -->
<dimen name="notification_panel_margin_bottom">0dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index 185ca5b..57f15a8 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -146,7 +146,7 @@ public class SearchPanelView extends FrameLayout implements
}
}
- public void show(boolean show, boolean animate) {
+ public void show(final boolean show, boolean animate) {
if (animate) {
if (mShowing != show) {
mShowing = show;
@@ -156,21 +156,24 @@ public class SearchPanelView extends FrameLayout implements
mShowing = show;
onAnimationEnd(null);
}
- setVisibility(show ? View.VISIBLE : View.GONE);
- if (show) {
- setFocusable(true);
- setFocusableInTouchMode(true);
- requestFocus();
- }
+ postDelayed(new Runnable() {
+ public void run() {
+ setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+ if (show) {
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+ requestFocus();
+ }
+ }
+ }, show ? 0 : 100);
}
public void hide(boolean animate) {
- if (!animate) {
- setVisibility(View.GONE);
- }
if (mBar != null) {
// This will indirectly cause show(false, ...) to get called
mBar.animateCollapse();
+ } else {
+ setVisibility(View.INVISIBLE);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index e865b9c..995ee43 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -91,6 +91,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
private int mThumbnailWidth;
private boolean mFitThumbnailToXY;
private int mRecentItemLayoutId;
+ private boolean mFirstScreenful = true;
public static interface OnRecentsPanelVisibilityChangedListener {
public void onRecentsPanelVisibilityChanged(boolean visible);
@@ -206,6 +207,22 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
}
}
+ public RecentsPanelView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mContext = context;
+ updateValuesFromResources();
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView,
+ defStyle, 0);
+
+ mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
+ a.recycle();
+ }
+
public int numItemsInOneScreenful() {
if (mRecentsContainer instanceof RecentsScrollView){
RecentsScrollView scrollView
@@ -297,6 +314,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
mRecentTasksDirty = true;
mWaitingToShow = false;
mReadyToShow = false;
+ mRecentsNoApps.setVisibility(View.INVISIBLE);
}
if (animate) {
if (mShowing != show) {
@@ -415,21 +433,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
super.setVisibility(visibility);
}
- public RecentsPanelView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public RecentsPanelView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mContext = context;
- updateValuesFromResources();
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecentsPanelView,
- defStyle, 0);
-
- mRecentItemLayoutId = a.getResourceId(R.styleable.RecentsPanelView_recentItemLayout, 0);
- }
-
public void updateValuesFromResources() {
final Resources res = mContext.getResources();
mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
@@ -572,7 +575,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
showIfReady();
}
- // additional optimization when we have sofware system buttons - start loading the recent
+ // additional optimization when we have software system buttons - start loading the recent
// tasks on touch down
@Override
public boolean onTouch(View v, MotionEvent ev) {
@@ -631,7 +634,6 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
}
}
- boolean mFirstScreenful;
public void onTasksLoaded(ArrayList<TaskDescription> tasks) {
if (!mFirstScreenful && tasks.size() == 0) {
return;
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 f6f41b8..f5f2e28 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -106,6 +106,7 @@ public class PhoneStatusBar extends BaseStatusBar {
= "com.android.internal.policy.statusbar.START";
private static final boolean ENABLE_INTRUDERS = false;
+ private static final boolean DIM_BEHIND_EXPANDED_PANEL = false;
static final int EXPANDED_LEAVE_ALONE = -10000;
static final int EXPANDED_FULL_OPEN = -10001;
@@ -212,6 +213,7 @@ public class PhoneStatusBar extends BaseStatusBar {
Choreographer mChoreographer;
boolean mAnimating;
+ boolean mClosing; // only valid when mAnimating; indicates the initial acceleration
float mAnimY;
float mAnimVel;
float mAnimAccel;
@@ -311,6 +313,12 @@ public class PhoneStatusBar extends BaseStatusBar {
}
});
+ if (!ActivityManager.isHighEndGfx(mDisplay)) {
+ mStatusBarWindow.setBackground(null);
+ mNotificationPanel.setBackgroundColor(context.getResources().getColor(
+ R.color.notification_panel_solid_background));
+ }
+
if (ENABLE_INTRUDERS) {
mIntruderAlertView = (IntruderAlertView) View.inflate(context, R.layout.intruder_alert, null);
mIntruderAlertView.setVisibility(View.GONE);
@@ -459,6 +467,9 @@ public class PhoneStatusBar extends BaseStatusBar {
// .03, the item disappears entirely (as if alpha = 0) and that discontinuity looks
// a bit jarring
mRecentsPanel.setMinSwipeAlpha(0.03f);
+ if (mNavigationBarView != null) {
+ mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPanel);
+ }
}
@Override
@@ -474,7 +485,6 @@ public class PhoneStatusBar extends BaseStatusBar {
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
}
@@ -484,7 +494,6 @@ public class PhoneStatusBar extends BaseStatusBar {
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
}
@@ -565,8 +574,7 @@ public class PhoneStatusBar extends BaseStatusBar {
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
- | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
- | WindowManager.LayoutParams.FLAG_SLIPPERY,
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.OPAQUE);
// this will allow the navbar to run in an overlay on devices that support this
if (ActivityManager.isHighEndGfx(mDisplay)) {
@@ -1270,14 +1278,26 @@ public class PhoneStatusBar extends BaseStatusBar {
}
}
+ void resetLastAnimTime() {
+ mAnimLastTimeNanos = System.nanoTime();
+ if (SPEW) {
+ Throwable t = new Throwable();
+ t.fillInStackTrace();
+ Slog.d(TAG, "resetting last anim time=" + mAnimLastTimeNanos, t);
+ }
+ }
+
void doAnimation(long frameTimeNanos) {
if (mAnimating) {
- if (SPEW) Slog.d(TAG, "doAnimation");
+ if (SPEW) Slog.d(TAG, "doAnimation dt=" + (frameTimeNanos - mAnimLastTimeNanos));
if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY);
incrementAnim(frameTimeNanos);
- if (SPEW) Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY);
+ if (SPEW) {
+ Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY);
+ Slog.d(TAG, "doAnimation expandedViewMax=" + getExpandedViewMaxHeight());
+ }
- if (mAnimY >= getExpandedViewMaxHeight()-1) {
+ if (mAnimY >= getExpandedViewMaxHeight()-1 && !mClosing) {
if (SPEW) Slog.d(TAG, "Animation completed to expanded state.");
mAnimating = false;
updateExpandedViewPos(EXPANDED_FULL_OPEN);
@@ -1285,14 +1305,14 @@ public class PhoneStatusBar extends BaseStatusBar {
return;
}
- if (mAnimY == 0 && mAnimAccel == 0 && mAnimVel == 0) {
+ if (mAnimY == 0 && mAnimAccel == 0 && mClosing) {
if (SPEW) Slog.d(TAG, "Animation completed to collapsed state.");
mAnimating = false;
performCollapse();
return;
}
- if (mAnimY < getStatusBarHeight()) {
+ if (mAnimY < getStatusBarHeight() && mClosing) {
// Draw one more frame with the bar positioned at the top of the screen
// before ending the animation so that the user sees the bar in
// its final position. The call to performCollapse() causes a window
@@ -1314,6 +1334,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mPile.setLayerType(View.LAYER_TYPE_NONE, null);
mVelocityTracker.recycle();
mVelocityTracker = null;
+ mCloseView.setPressed(false);
}
void incrementAnim(long frameTimeNanos) {
@@ -1330,6 +1351,9 @@ public class PhoneStatusBar extends BaseStatusBar {
}
void doRevealAnimation(long frameTimeNanos) {
+ if (SPEW) {
+ Slog.d(TAG, "doRevealAnimation: dt=" + (frameTimeNanos - mAnimLastTimeNanos));
+ }
final int h = getCloseViewHeight() + getStatusBarHeight();
if (mAnimatingReveal && mAnimating && mAnimY < h) {
incrementAnim(frameTimeNanos);
@@ -1349,6 +1373,8 @@ public class PhoneStatusBar extends BaseStatusBar {
Slog.d(TAG, "panel: beginning to track the user's touch, y=" + y + " opening=" + opening);
}
+ mCloseView.setPressed(true);
+
mTracking = true;
mPile.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mVelocityTracker = VelocityTracker.obtain();
@@ -1359,7 +1385,7 @@ public class PhoneStatusBar extends BaseStatusBar {
updateExpandedViewPos((int)mAnimY);
mAnimating = true;
mAnimatingReveal = true;
- mAnimLastTimeNanos = System.nanoTime();
+ resetLastAnimTime();
mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
mAnimationCallback, null);
mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
@@ -1433,8 +1459,9 @@ public class PhoneStatusBar extends BaseStatusBar {
//Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel
// + " mAnimAccel=" + mAnimAccel);
- mAnimLastTimeNanos = System.nanoTime();
+ resetLastAnimTime();
mAnimating = true;
+ mClosing = mAnimAccel < 0;
mChoreographer.removeCallbacks(Choreographer.CALLBACK_ANIMATION,
mAnimationCallback, null);
@@ -1474,8 +1501,8 @@ public class PhoneStatusBar extends BaseStatusBar {
if (!mExpanded) {
mViewDelta = statusBarSize - y;
} else {
-// mCloseView.getLocationOnScreen(mAbsPos)...?
-// mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y;
+ mCloseView.getLocationOnScreen(mAbsPos);
+ mViewDelta = mAbsPos[1] + statusBarSize + getCloseViewHeight() - y; // XXX: not closeViewHeight, but paddingBottom from the 9patch
}
if ((!mExpanded && y < hitSize) ||
// @@ add taps outside the panel if it's not full-screen
@@ -1987,11 +2014,14 @@ public class PhoneStatusBar extends BaseStatusBar {
Slog.v(TAG, "updated cropView height=" + panelh + " grav=" + lp.gravity);
}
mNotificationPanel.setLayoutParams(lp);
- // woo, special effects
- final int barh = getCloseViewHeight() + getStatusBarHeight();
- final float frac = saturate((float)(panelh - barh) / (disph - barh));
- final int color = ((int)(0xB0 * Math.sin(frac * 1.57f))) << 24;
- mStatusBarWindow.setBackgroundColor(color);
+
+ if (DIM_BEHIND_EXPANDED_PANEL && ActivityManager.isHighEndGfx(mDisplay)) {
+ // woo, special effects
+ final int barh = getCloseViewHeight() + getStatusBarHeight();
+ final float frac = saturate((float)(panelh - barh) / (disph - barh));
+ final int color = ((int)(0xB0 * Math.sin(frac * 1.57f))) << 24;
+ mStatusBarWindow.setBackgroundColor(color);
+ }
}
void updateDisplaySize() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 5f18b5d..374226d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -122,8 +122,7 @@ public class PhoneStatusBarPolicy {
action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) {
updateBluetooth(intent);
}
- else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION) ||
- action.equals(AudioManager.VIBRATE_SETTING_CHANGED_ACTION)) {
+ else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
updateVolume();
}
else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
@@ -144,7 +143,6 @@ public class PhoneStatusBarPolicy {
filter.addAction(Intent.ACTION_ALARM_CHANGED);
filter.addAction(Intent.ACTION_SYNC_STATE_CHANGED);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
- filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
@@ -238,7 +236,7 @@ public class PhoneStatusBarPolicy {
final int iconId;
String contentDescription = null;
- if (audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER)) {
+ if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
iconId = R.drawable.stat_sys_ringer_vibrate;
contentDescription = mContext.getString(R.string.accessibility_ringer_vibrate);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
index c9da01a..43cb85e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/VolumeController.java
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.Vibrator;
import android.media.AudioManager;
import android.provider.Settings;
import android.util.Slog;
@@ -36,10 +37,16 @@ public class VolumeController implements ToggleSlider.Listener {
private boolean mMute;
private int mVolume;
+ // Is there a vibrator
+ private final boolean mHasVibrator;
public VolumeController(Context context, ToggleSlider control) {
mContext = context;
mControl = control;
+
+ Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
+
mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mMute = mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
@@ -54,10 +61,8 @@ public class VolumeController implements ToggleSlider.Listener {
public void onChanged(ToggleSlider view, boolean tracking, boolean mute, int level) {
if (!tracking) {
if (mute) {
- boolean vibeInSilent = (1 == Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.VIBRATE_IN_SILENT, 1));
mAudioManager.setRingerMode(
- vibeInSilent ? AudioManager.RINGER_MODE_VIBRATE
+ mHasVibrator ? AudioManager.RINGER_MODE_VIBRATE
: AudioManager.RINGER_MODE_SILENT);
} else {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index a394596..b0830ee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -704,7 +704,6 @@ public class TabletStatusBar extends BaseStatusBar implements
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
}
@@ -714,7 +713,6 @@ public class TabletStatusBar extends BaseStatusBar implements
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
}
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 6e09b7f..6590fb3 100644
--- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
@@ -28,6 +28,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
@@ -112,10 +113,14 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
/**
* Sets the Face Unlock view to visible, hiding it after the specified amount of time. If
- * timeoutMillis is 0, no hide is performed.
+ * timeoutMillis is 0, no hide is performed. Called on the UI thread.
*/
public void show(long timeoutMillis) {
if (DEBUG) Log.d(TAG, "show()");
+ if (mHandler.getLooper() != Looper.myLooper()) {
+ Log.e(TAG, "show() called off of the UI thread");
+ }
+
removeDisplayMessages();
if (mFaceUnlockView != null) {
mFaceUnlockView.setVisibility(View.VISIBLE);
@@ -138,9 +143,14 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
/**
* Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The
* Face Unlock view is displayed to hide the backup lock while the service is starting up.
+ * Called on the UI thread.
*/
public boolean start() {
if (DEBUG) Log.d(TAG, "start()");
+ if (mHandler.getLooper() != Looper.myLooper()) {
+ Log.e(TAG, "start() called off of the UI thread");
+ }
+
if (mIsRunning) {
Log.w(TAG, "start() called when already running");
}
@@ -170,10 +180,14 @@ public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
}
/**
- * Stops Face Unlock and unbinds from the service.
+ * Stops Face Unlock and unbinds from the service. Called on the UI thread.
*/
public boolean stop() {
if (DEBUG) Log.d(TAG, "stop()");
+ if (mHandler.getLooper() != Looper.myLooper()) {
+ Log.e(TAG, "stop() called off of the UI thread");
+ }
+
boolean mWasRunning = mIsRunning;
stopUi();
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 8b0d858..c7a30e2 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -34,6 +34,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.os.Vibrator;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -82,6 +83,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
private boolean mCameraDisabled;
private boolean mSearchDisabled;
private SearchManager mSearchManager;
+ // Is there a vibrator
+ private final boolean mHasVibrator;
InfoCallbackImpl mInfoCallback = new InfoCallbackImpl() {
@@ -385,11 +388,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
// toggle silent mode
mSilentMode = !mSilentMode;
if (mSilentMode) {
- final boolean vibe = (Settings.System.getInt(
- mContext.getContentResolver(),
- Settings.System.VIBRATE_IN_SILENT, 1) == 1);
-
- mAudioManager.setRingerMode(vibe
+ mAudioManager.setRingerMode(mHasVibrator
? AudioManager.RINGER_MODE_VIBRATE
: AudioManager.RINGER_MODE_SILENT);
} else {
@@ -451,6 +450,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
+ mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mSilentMode = isSilentMode();
mUnlockWidget = findViewById(R.id.unlock_widget);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 4b91422..cc7050a 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -2098,7 +2098,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (widthMode == AT_MOST) {
final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
- fixedWidth = true;
final int w;
if (tvw.type == TypedValue.TYPE_DIMENSION) {
w = (int) tvw.getDimension(metrics);
@@ -2112,6 +2111,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
widthMeasureSpec = MeasureSpec.makeMeasureSpec(
Math.min(w, widthSize), EXACTLY);
+ fixedWidth = true;
}
}
}
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index f80ac18..50bfee6 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "EventHub"
-// #define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
#include "EventHub.h"
@@ -767,11 +767,7 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
size_t count = size_t(readSize) / sizeof(struct input_event);
for (size_t i = 0; i < count; i++) {
const struct input_event& iev = readBuffer[i];
- ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
- device->path.string(),
- (int) iev.time.tv_sec, (int) iev.time.tv_usec,
- iev.type, iev.code, iev.value);
-
+ nsecs_t delta = 0;
#ifdef HAVE_POSIX_CLOCKS
// Use the time specified in the event instead of the current time
// so that downstream code can get more accurate estimates of
@@ -786,10 +782,23 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
// system call that also queries ktime_get_ts().
event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL
+ nsecs_t(iev.time.tv_usec) * 1000LL;
- ALOGV("event time %lld, now %lld", event->when, now);
+ delta = now - event->when;
+
+ // Only log verbose if events are older that 1ms
+ if (delta > 1 * 1000000LL) {
+ ALOGV("event time %lld, now %lld, delta %lldus", event->when, now, delta / 1000LL);
+ }
#else
event->when = now;
#endif
+ if (delta > 1 * 1000000LL) {
+ ALOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, value=%d",
+ device->path.string(),
+ (int) iev.time.tv_sec, (int) iev.time.tv_usec,
+ iev.type, iev.code, iev.value);
+ }
+
+
event->deviceId = deviceId;
event->type = iev.type;
event->code = iev.code;
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index dad4ef4..ada9d9e 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -185,7 +185,7 @@ InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& polic
mPolicy(policy),
mPendingEvent(NULL), mAppSwitchSawKeyDown(false), mAppSwitchDueTime(LONG_LONG_MAX),
mNextUnblockedEvent(NULL),
- mDispatchEnabled(true), mDispatchFrozen(false), mInputFilterEnabled(false),
+ mDispatchEnabled(false), mDispatchFrozen(false), mInputFilterEnabled(false),
mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
mLooper = new Looper(false);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 8e3b825..a49ccf7 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -1142,6 +1142,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
if (mCurToken != null) {
try {
if (DEBUG) Slog.v(TAG, "Removing window token: " + mCurToken);
+ if ((mImeWindowVis & InputMethodService.IME_ACTIVE) != 0) {
+ // The current IME is shown. Hence an IME switch (transition) is happening.
+ mWindowManagerService.saveLastInputMethodWindowForTransition();
+ }
mIWindowManager.removeWindowToken(mCurToken);
} catch (RemoteException e) {
}
@@ -2410,17 +2414,63 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
- private static class ImeSubtypeListItem {
+ private static class ImeSubtypeListItem implements Comparable<ImeSubtypeListItem> {
public final CharSequence mImeName;
public final CharSequence mSubtypeName;
public final InputMethodInfo mImi;
public final int mSubtypeId;
+ private final boolean mIsSystemLocale;
+ private final boolean mIsSystemLanguage;
+
public ImeSubtypeListItem(CharSequence imeName, CharSequence subtypeName,
- InputMethodInfo imi, int subtypeId) {
+ InputMethodInfo imi, int subtypeId, String subtypeLocale, String systemLocale) {
mImeName = imeName;
mSubtypeName = subtypeName;
mImi = imi;
mSubtypeId = subtypeId;
+ if (TextUtils.isEmpty(subtypeLocale)) {
+ mIsSystemLocale = false;
+ mIsSystemLanguage = false;
+ } else {
+ mIsSystemLocale = subtypeLocale.equals(systemLocale);
+ mIsSystemLanguage = mIsSystemLocale
+ || subtypeLocale.startsWith(systemLocale.substring(0, 2));
+ }
+ }
+
+ @Override
+ public int compareTo(ImeSubtypeListItem other) {
+ if (TextUtils.isEmpty(mImeName)) {
+ return 1;
+ }
+ if (TextUtils.isEmpty(other.mImeName)) {
+ return -1;
+ }
+ if (!TextUtils.equals(mImeName, other.mImeName)) {
+ return mImeName.toString().compareTo(other.mImeName.toString());
+ }
+ if (TextUtils.equals(mSubtypeName, other.mSubtypeName)) {
+ return 0;
+ }
+ if (mIsSystemLocale) {
+ return -1;
+ }
+ if (other.mIsSystemLocale) {
+ return 1;
+ }
+ if (mIsSystemLanguage) {
+ return -1;
+ }
+ if (other.mIsSystemLanguage) {
+ return 1;
+ }
+ if (TextUtils.isEmpty(mSubtypeName)) {
+ return 1;
+ }
+ if (TextUtils.isEmpty(other.mSubtypeName)) {
+ return -1;
+ }
+ return mSubtypeName.toString().compareTo(other.mSubtypeName.toString());
}
}
@@ -2619,7 +2669,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
return getSubtypeIdFromHashCode(imi, subtypeId);
}
- private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
+ private static boolean isValidSubtypeId(InputMethodInfo imi, int subtypeHashCode) {
+ return getSubtypeIdFromHashCode(imi, subtypeHashCode) != NOT_A_SUBTYPE_ID;
+ }
+
+ private static int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
if (imi != null) {
final int subtypeCount = imi.getSubtypeCount();
for (int i = 0; i < subtypeCount; ++i) {
@@ -2844,6 +2898,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
*/
@Override
public InputMethodSubtype getCurrentInputMethodSubtype() {
+ if (mCurMethodId == null) {
+ return null;
+ }
boolean subtypeIsSelected = false;
try {
subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(),
@@ -2851,36 +2908,35 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
} catch (SettingNotFoundException e) {
}
synchronized (mMethodMap) {
- if (!subtypeIsSelected || mCurrentSubtype == null) {
- String lastInputMethodId = Settings.Secure.getString(
- mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
- int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId);
+ final InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+ if (imi == null || imi.getSubtypeCount() == 0) {
+ return null;
+ }
+ if (!subtypeIsSelected || mCurrentSubtype == null
+ || !isValidSubtypeId(imi, mCurrentSubtype.hashCode())) {
+ int subtypeId = getSelectedInputMethodSubtypeId(mCurMethodId);
if (subtypeId == NOT_A_SUBTYPE_ID) {
- InputMethodInfo imi = mMethodMap.get(lastInputMethodId);
- if (imi != null) {
- // If there are no selected subtypes, the framework will try to find
- // the most applicable subtype from explicitly or implicitly enabled
- // subtypes.
- List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
- getEnabledInputMethodSubtypeList(imi, true);
- // If there is only one explicitly or implicitly enabled subtype,
- // just returns it.
- if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
- mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
- } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
+ // If there are no selected subtypes, the framework will try to find
+ // the most applicable subtype from explicitly or implicitly enabled
+ // subtypes.
+ List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes =
+ getEnabledInputMethodSubtypeList(imi, true);
+ // If there is only one explicitly or implicitly enabled subtype,
+ // just returns it.
+ if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) {
+ mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0);
+ } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) {
+ mCurrentSubtype = findLastResortApplicableSubtypeLocked(
+ mRes, explicitlyOrImplicitlyEnabledSubtypes,
+ SUBTYPE_MODE_KEYBOARD, null, true);
+ if (mCurrentSubtype == null) {
mCurrentSubtype = findLastResortApplicableSubtypeLocked(
- mRes, explicitlyOrImplicitlyEnabledSubtypes,
- SUBTYPE_MODE_KEYBOARD, null, true);
- if (mCurrentSubtype == null) {
- mCurrentSubtype = findLastResortApplicableSubtypeLocked(
- mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null,
- true);
- }
+ mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null,
+ true);
}
}
} else {
- mCurrentSubtype =
- getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId);
+ mCurrentSubtype = getSubtypes(imi).get(subtypeId);
}
}
return mCurrentSubtype;
@@ -2946,10 +3002,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
private final Context mContext;
private final PackageManager mPm;
private final InputMethodManagerService mImms;
+ private final String mSystemLocaleStr;
public InputMethodAndSubtypeListManager(Context context, InputMethodManagerService imms) {
mContext = context;
mPm = context.getPackageManager();
mImms = imms;
+ mSystemLocaleStr =
+ imms.mLastSystemLocale != null ? imms.mLastSystemLocale.toString() : "";
}
private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
@@ -2979,7 +3038,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
final int N = imList.size();
final int currentSubtypeId = subtype != null
- ? mImms.getSubtypeIdFromHashCode(imi, subtype.hashCode())
+ ? getSubtypeIdFromHashCode(imi, subtype.hashCode())
: NOT_A_SUBTYPE_ID;
for (int i = 0; i < N; ++i) {
final ImeSubtypeListItem isli = imList.get(i);
@@ -3037,7 +3096,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
subtype.overridesImplicitlyEnabledSubtype() ? null
: subtype.getDisplayName(mContext, imi.getPackageName(),
imi.getServiceInfo().applicationInfo);
- imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j));
+ imList.add(new ImeSubtypeListItem(imeLabel, subtypeLabel, imi, j,
+ subtype.getLocale(), mSystemLocaleStr));
// Removing this subtype from enabledSubtypeSet because we no longer
// need to add an entry of this subtype to imList to avoid duplicated
@@ -3046,9 +3106,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
}
}
} else {
- imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID));
+ imList.add(new ImeSubtypeListItem(imeLabel, null, imi, NOT_A_SUBTYPE_ID,
+ null, mSystemLocaleStr));
}
}
+ Collections.sort(imList);
return imList;
}
}
@@ -3356,10 +3418,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
for (Pair<String, ArrayList<String>> enabledIme: enabledImes) {
if (enabledIme.first.equals(imeId)) {
final ArrayList<String> explicitlyEnabledSubtypes = enabledIme.second;
+ final InputMethodInfo imi = mMethodMap.get(imeId);
if (explicitlyEnabledSubtypes.size() == 0) {
// If there are no explicitly enabled subtypes, applicable subtypes are
// enabled implicitly.
- InputMethodInfo imi = mMethodMap.get(imeId);
// If IME is enabled and no subtypes are enabled, applicable subtypes
// are enabled implicitly, so needs to treat them to be enabled.
if (imi != null && imi.getSubtypeCount() > 0) {
@@ -3379,7 +3441,17 @@ public class InputMethodManagerService extends IInputMethodManager.Stub
for (String s: explicitlyEnabledSubtypes) {
if (s.equals(subtypeHashCode)) {
// If both imeId and subtypeId are enabled, return subtypeId.
- return s;
+ try {
+ final int hashCode = Integer.valueOf(subtypeHashCode);
+ // Check whether the subtype id is valid or not
+ if (isValidSubtypeId(imi, hashCode)) {
+ return s;
+ } else {
+ return NOT_A_SUBTYPE_ID_STR;
+ }
+ } catch (NumberFormatException e) {
+ return NOT_A_SUBTYPE_ID_STR;
+ }
}
}
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 663a031..52ba665 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -1046,7 +1046,7 @@ public class NotificationManagerService extends INotificationManager.Stub
final boolean useDefaultVibrate =
(notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
if ((useDefaultVibrate || notification.vibrate != null)
- && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION)) {
+ && !(audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT)) {
mVibrateNotification = r;
mVibrator.vibrate(useDefaultVibrate ? DEFAULT_VIBRATE_PATTERN
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index f33bf8b..cc8e6a4 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -20,7 +20,7 @@ import android.content.Context;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.net.nsd.DnsSdServiceInfo;
+import android.net.nsd.NsdServiceInfo;
import android.net.nsd.DnsSdTxtRecord;
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
@@ -32,6 +32,7 @@ import android.os.Messenger;
import android.os.IBinder;
import android.provider.Settings;
import android.util.Slog;
+import android.util.SparseArray;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -72,13 +73,16 @@ public class NsdService extends INsdManager.Stub {
*/
private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>();
+ /* A map from unique id to client info */
+ private SparseArray<ClientInfo> mIdToClientInfoMap= new SparseArray<ClientInfo>();
+
private AsyncChannel mReplyChannel = new AsyncChannel();
private int INVALID_ID = 0;
private int mUniqueId = 1;
private static final int BASE = Protocol.BASE_NSD_MANAGER;
- private static final int CMD_TO_STRING_COUNT = NsdManager.STOP_RESOLVE - BASE + 1;
+ private static final int CMD_TO_STRING_COUNT = NsdManager.RESOLVE_SERVICE - BASE + 1;
private static String[] sCmdToString = new String[CMD_TO_STRING_COUNT];
static {
@@ -87,7 +91,6 @@ public class NsdService extends INsdManager.Stub {
sCmdToString[NsdManager.REGISTER_SERVICE - BASE] = "REGISTER";
sCmdToString[NsdManager.UNREGISTER_SERVICE - BASE] = "UNREGISTER";
sCmdToString[NsdManager.RESOLVE_SERVICE - BASE] = "RESOLVE";
- sCmdToString[NsdManager.STOP_RESOLVE - BASE] = "STOP-RESOLVE";
}
private static String cmdToString(int cmd) {
@@ -101,9 +104,9 @@ public class NsdService extends INsdManager.Stub {
private class NsdStateMachine extends StateMachine {
- private DefaultState mDefaultState = new DefaultState();
- private DisabledState mDisabledState = new DisabledState();
- private EnabledState mEnabledState = new EnabledState();
+ private final DefaultState mDefaultState = new DefaultState();
+ private final DisabledState mDisabledState = new DisabledState();
+ private final EnabledState mEnabledState = new EnabledState();
@Override
protected String getMessageInfo(Message msg) {
@@ -151,29 +154,26 @@ public class NsdService extends INsdManager.Stub {
ac.connect(mContext, getHandler(), msg.replyTo);
break;
case NsdManager.DISCOVER_SERVICES:
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.BUSY);
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.STOP_DISCOVERY:
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.REGISTER_SERVICE:
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.UNREGISTER_SERVICE:
- mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
case NsdManager.RESOLVE_SERVICE:
- mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- break;
- case NsdManager.STOP_RESOLVE:
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
+ case NsdManager.NATIVE_DAEMON_EVENT:
default:
Slog.e(TAG, "Unhandled " + msg);
return NOT_HANDLED;
@@ -217,11 +217,30 @@ public class NsdService extends INsdManager.Stub {
}
}
+ private boolean requestLimitReached(ClientInfo clientInfo) {
+ if (clientInfo.mClientIds.size() >= ClientInfo.MAX_LIMIT) {
+ if (DBG) Slog.d(TAG, "Exceeded max outstanding requests " + clientInfo);
+ return true;
+ }
+ return false;
+ }
+
+ private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+ clientInfo.mClientIds.put(clientId, globalId);
+ mIdToClientInfoMap.put(globalId, clientInfo);
+ }
+
+ private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+ clientInfo.mClientIds.remove(clientId);
+ mIdToClientInfoMap.remove(globalId);
+ }
+
@Override
public boolean processMessage(Message msg) {
ClientInfo clientInfo;
- DnsSdServiceInfo servInfo;
+ NsdServiceInfo servInfo;
boolean result = HANDLED;
+ int id;
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
//First client
@@ -244,111 +263,112 @@ public class NsdService extends INsdManager.Stub {
break;
case NsdManager.DISCOVER_SERVICES:
if (DBG) Slog.d(TAG, "Discover services");
- servInfo = (DnsSdServiceInfo) msg.obj;
+ servInfo = (NsdServiceInfo) msg.obj;
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mDiscoveryId != INVALID_ID) {
- //discovery already in progress
- if (DBG) Slog.d(TAG, "discovery in progress");
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ALREADY_ACTIVE);
+
+ if (requestLimitReached(clientInfo)) {
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_MAX_LIMIT);
break;
}
- clientInfo.mDiscoveryId = getUniqueId();
- if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) {
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED);
+
+ id = getUniqueId();
+ if (discoverServices(id, servInfo.getServiceType())) {
+ if (DBG) {
+ Slog.d(TAG, "Discover " + msg.arg2 + " " + id +
+ servInfo.getServiceType());
+ }
+ storeRequestMap(msg.arg2, id, clientInfo);
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ERROR);
- clientInfo.mDiscoveryId = INVALID_ID;
+ stopServiceDiscovery(id);
+ replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
case NsdManager.STOP_DISCOVERY:
if (DBG) Slog.d(TAG, "Stop service discovery");
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mDiscoveryId == INVALID_ID) {
- //already stopped
- if (DBG) Slog.d(TAG, "discovery already stopped");
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ALREADY_ACTIVE);
+
+ try {
+ id = clientInfo.mClientIds.get(msg.arg2).intValue();
+ } catch (NullPointerException e) {
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
break;
}
- if (stopServiceDiscovery(clientInfo.mDiscoveryId)) {
- clientInfo.mDiscoveryId = INVALID_ID;
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
+ removeRequestMap(msg.arg2, id, clientInfo);
+ if (stopServiceDiscovery(id)) {
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
case NsdManager.REGISTER_SERVICE:
if (DBG) Slog.d(TAG, "Register service");
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) {
- if (DBG) Slog.d(TAG, "register service exceeds limit");
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.MAX_REGS_REACHED);
+ if (requestLimitReached(clientInfo)) {
+ replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_MAX_LIMIT);
+ break;
}
- int id = getUniqueId();
- if (registerService(id, (DnsSdServiceInfo) msg.obj)) {
- clientInfo.mRegisteredIds.add(id);
+ id = getUniqueId();
+ if (registerService(id, (NsdServiceInfo) msg.obj)) {
+ if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
+ storeRequestMap(msg.arg2, id, clientInfo);
+ // Return success after mDns reports success
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ unregisterService(id);
+ replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
case NsdManager.UNREGISTER_SERVICE:
if (DBG) Slog.d(TAG, "unregister service");
clientInfo = mClients.get(msg.replyTo);
- int regId = msg.arg1;
- if (clientInfo.mRegisteredIds.remove(new Integer(regId)) &&
- unregisterService(regId)) {
- mReplyChannel.replyToMessage(msg,
- NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
+ try {
+ id = clientInfo.mClientIds.get(msg.arg2).intValue();
+ } catch (NullPointerException e) {
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
+ break;
+ }
+ removeRequestMap(msg.arg2, id, clientInfo);
+ if (unregisterService(id)) {
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_SUCCEEDED);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.UNREGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
- case NsdManager.UPDATE_SERVICE:
- if (DBG) Slog.d(TAG, "Update service");
- //TODO: implement
- mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED);
- break;
case NsdManager.RESOLVE_SERVICE:
if (DBG) Slog.d(TAG, "Resolve service");
- servInfo = (DnsSdServiceInfo) msg.obj;
+ servInfo = (NsdServiceInfo) msg.obj;
clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mResolveId != INVALID_ID) {
- //first cancel existing resolve
- stopResolveService(clientInfo.mResolveId);
- }
- clientInfo.mResolveId = getUniqueId();
- if (!resolveService(clientInfo.mResolveId, servInfo)) {
- mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- clientInfo.mResolveId = INVALID_ID;
- }
- break;
- case NsdManager.STOP_RESOLVE:
- if (DBG) Slog.d(TAG, "Stop resolve");
- clientInfo = mClients.get(msg.replyTo);
- if (clientInfo.mResolveId == INVALID_ID) {
- //already stopped
- if (DBG) Slog.d(TAG, "resolve already stopped");
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ALREADY_ACTIVE);
+
+ if (clientInfo.mResolvedService != null) {
+ replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_ALREADY_ACTIVE);
break;
}
- if (stopResolveService(clientInfo.mResolveId)) {
- clientInfo.mResolveId = INVALID_ID;
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED);
+
+ id = getUniqueId();
+ if (resolveService(id, servInfo)) {
+ clientInfo.mResolvedService = new NsdServiceInfo();
+ storeRequestMap(msg.arg2, id, clientInfo);
} else {
- mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED,
- NsdManager.ERROR);
+ replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR);
}
break;
+ case NsdManager.NATIVE_DAEMON_EVENT:
+ NativeEvent event = (NativeEvent) msg.obj;
+ handleNativeEvent(event.code, event.raw,
+ NativeDaemonEvent.unescapeArgs(event.raw));
+ break;
default:
result = NOT_HANDLED;
break;
@@ -439,121 +459,144 @@ public class NsdService extends INsdManager.Stub {
public static final int SERVICE_GET_ADDR_SUCCESS = 612;
}
+ private class NativeEvent {
+ int code;
+ String raw;
+
+ NativeEvent(int code, String raw) {
+ this.code = code;
+ this.raw = raw;
+ }
+ }
+
class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
public void onDaemonConnected() {
mNativeDaemonConnected.countDown();
}
public boolean onEvent(int code, String raw, String[] cooked) {
- ClientInfo clientInfo;
- DnsSdServiceInfo servInfo;
- int id = Integer.parseInt(cooked[1]);
- switch (code) {
- case NativeResponseCode.SERVICE_FOUND:
- /* NNN uniqueId serviceName regType domain */
- if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
- clientInfo = getClientByDiscovery(id);
- if (clientInfo == null) break;
-
- servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
- clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo);
- break;
- case NativeResponseCode.SERVICE_LOST:
- /* NNN uniqueId serviceName regType domain */
- if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
- clientInfo = getClientByDiscovery(id);
- if (clientInfo == null) break;
-
- servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null);
- clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo);
- break;
- case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
- /* NNN uniqueId errorCode */
- if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
- clientInfo = getClientByDiscovery(id);
- if (clientInfo == null) break;
-
- clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
- NsdManager.ERROR);
- break;
- case NativeResponseCode.SERVICE_REGISTERED:
- /* NNN regId serviceName regType */
- if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
- clientInfo = getClientByRegistration(id);
- if (clientInfo == null) break;
-
- servInfo = new DnsSdServiceInfo(cooked[2], null, null);
- clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
- id, 0, servInfo);
- break;
- case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
- /* NNN regId errorCode */
- if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
- clientInfo = getClientByRegistration(id);
- if (clientInfo == null) break;
-
- clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
- NsdManager.ERROR);
- break;
- case NativeResponseCode.SERVICE_UPDATED:
- /* NNN regId */
- break;
- case NativeResponseCode.SERVICE_UPDATE_FAILED:
- /* NNN regId errorCode */
- break;
- case NativeResponseCode.SERVICE_RESOLVED:
- /* NNN resolveId fullName hostName port txtlen txtdata */
- if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
- clientInfo = getClientByResolve(id);
- if (clientInfo == null) break;
-
- int index = cooked[2].indexOf(".");
- if (index == -1) {
- Slog.e(TAG, "Invalid service found " + raw);
- break;
- }
- String name = cooked[2].substring(0, index);
- String rest = cooked[2].substring(index);
- String type = rest.replace(".local.", "");
+ // TODO: NDC translates a message to a callback, we could enhance NDC to
+ // directly interact with a state machine through messages
+ NativeEvent event = new NativeEvent(code, raw);
+ mNsdStateMachine.sendMessage(NsdManager.NATIVE_DAEMON_EVENT, event);
+ return true;
+ }
+ }
- clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null);
- clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
+ private void handleNativeEvent(int code, String raw, String[] cooked) {
+ NsdServiceInfo servInfo;
+ int id = Integer.parseInt(cooked[1]);
+ ClientInfo clientInfo = mIdToClientInfoMap.get(id);
+ if (clientInfo == null) {
+ Slog.e(TAG, "Unique id with no client mapping: " + id);
+ return;
+ }
- stopResolveService(id);
- getAddrInfo(id, cooked[3]);
+ /* This goes in response as msg.arg2 */
+ int clientId = -1;
+ int keyId = clientInfo.mClientIds.indexOfValue(id);
+ if (keyId != -1) {
+ clientId = clientInfo.mClientIds.keyAt(keyId);
+ }
+ switch (code) {
+ case NativeResponseCode.SERVICE_FOUND:
+ /* NNN uniqueId serviceName regType domain */
+ if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw);
+ servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+ clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, 0,
+ clientId, servInfo);
+ break;
+ case NativeResponseCode.SERVICE_LOST:
+ /* NNN uniqueId serviceName regType domain */
+ if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw);
+ servInfo = new NsdServiceInfo(cooked[2], cooked[3], null);
+ clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, 0,
+ clientId, servInfo);
+ break;
+ case NativeResponseCode.SERVICE_DISCOVERY_FAILED:
+ /* NNN uniqueId errorCode */
+ if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw);
+ clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ break;
+ case NativeResponseCode.SERVICE_REGISTERED:
+ /* NNN regId serviceName regType */
+ if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw);
+ servInfo = new NsdServiceInfo(cooked[2], null, null);
+ clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED,
+ id, clientId, servInfo);
+ break;
+ case NativeResponseCode.SERVICE_REGISTRATION_FAILED:
+ /* NNN regId errorCode */
+ if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw);
+ clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ break;
+ case NativeResponseCode.SERVICE_UPDATED:
+ /* NNN regId */
+ break;
+ case NativeResponseCode.SERVICE_UPDATE_FAILED:
+ /* NNN regId errorCode */
+ break;
+ case NativeResponseCode.SERVICE_RESOLVED:
+ /* NNN resolveId fullName hostName port txtlen txtdata */
+ if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw);
+ int index = cooked[2].indexOf(".");
+ if (index == -1) {
+ Slog.e(TAG, "Invalid service found " + raw);
break;
- case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
- case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
- /* NNN resolveId errorCode */
- if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
- clientInfo = getClientByResolve(id);
- if (clientInfo == null) break;
+ }
+ String name = cooked[2].substring(0, index);
+ String rest = cooked[2].substring(index);
+ String type = rest.replace(".local.", "");
+
+ clientInfo.mResolvedService.setServiceName(name);
+ clientInfo.mResolvedService.setServiceType(type);
+ clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4]));
+ stopResolveService(id);
+ if (!getAddrInfo(id, cooked[3])) {
clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- break;
- case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
- /* NNN resolveId hostname ttl addr */
- if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
- clientInfo = getClientByResolve(id);
- if (clientInfo == null || clientInfo.mResolvedService == null) break;
-
- try {
- clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
- clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
- clientInfo.mResolvedService);
- clientInfo.mResolvedService = null;
- clientInfo.mResolveId = INVALID_ID;
- } catch (java.net.UnknownHostException e) {
- clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
- NsdManager.ERROR);
- }
- stopGetAddrInfo(id);
- break;
- default:
- break;
- }
- return false;
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ }
+ break;
+ case NativeResponseCode.SERVICE_RESOLUTION_FAILED:
+ /* NNN resolveId errorCode */
+ if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+ stopResolveService(id);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ break;
+ case NativeResponseCode.SERVICE_GET_ADDR_FAILED:
+ /* NNN resolveId errorCode */
+ stopGetAddrInfo(id);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw);
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ break;
+ case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS:
+ /* NNN resolveId hostname ttl addr */
+ if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw);
+ try {
+ clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4]));
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED,
+ 0, clientId, clientInfo.mResolvedService);
+ } catch (java.net.UnknownHostException e) {
+ clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
+ NsdManager.FAILURE_INTERNAL_ERROR, clientId);
+ }
+ stopGetAddrInfo(id);
+ mIdToClientInfoMap.remove(id);
+ clientInfo.mResolvedService = null;
+ break;
+ default:
+ break;
}
}
@@ -579,7 +622,7 @@ public class NsdService extends INsdManager.Stub {
return true;
}
- private boolean registerService(int regId, DnsSdServiceInfo service) {
+ private boolean registerService(int regId, NsdServiceInfo service) {
if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
try {
//Add txtlen and txtdata
@@ -637,7 +680,7 @@ public class NsdService extends INsdManager.Stub {
return true;
}
- private boolean resolveService(int resolveId, DnsSdServiceInfo service) {
+ private boolean resolveService(int resolveId, NsdServiceInfo service) {
if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
try {
mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
@@ -700,49 +743,52 @@ public class NsdService extends INsdManager.Stub {
mNsdStateMachine.dump(fd, pw, args);
}
- private ClientInfo getClientByDiscovery(int discoveryId) {
- for (ClientInfo c: mClients.values()) {
- if (c.mDiscoveryId == discoveryId) {
- return c;
- }
- }
- return null;
+ /* arg2 on the source message has an id that needs to be retained in replies
+ * see NsdManager for details */
+ private Message obtainMessage(Message srcMsg) {
+ Message msg = Message.obtain();
+ msg.arg2 = srcMsg.arg2;
+ return msg;
}
- private ClientInfo getClientByResolve(int resolveId) {
- for (ClientInfo c: mClients.values()) {
- if (c.mResolveId == resolveId) {
- return c;
- }
- }
- return null;
+ private void replyToMessage(Message msg, int what) {
+ if (msg.replyTo == null) return;
+ Message dstMsg = obtainMessage(msg);
+ dstMsg.what = what;
+ mReplyChannel.replyToMessage(msg, dstMsg);
}
- private ClientInfo getClientByRegistration(int regId) {
- for (ClientInfo c: mClients.values()) {
- if (c.mRegisteredIds.contains(regId)) {
- return c;
- }
- }
- return null;
+ private void replyToMessage(Message msg, int what, int arg1) {
+ if (msg.replyTo == null) return;
+ Message dstMsg = obtainMessage(msg);
+ dstMsg.what = what;
+ dstMsg.arg1 = arg1;
+ mReplyChannel.replyToMessage(msg, dstMsg);
+ }
+
+ private void replyToMessage(Message msg, int what, Object obj) {
+ if (msg.replyTo == null) return;
+ Message dstMsg = obtainMessage(msg);
+ dstMsg.what = what;
+ dstMsg.obj = obj;
+ mReplyChannel.replyToMessage(msg, dstMsg);
}
/* Information tracked per client */
private class ClientInfo {
- private static final int MAX_REG = 5;
+ private static final int MAX_LIMIT = 10;
private AsyncChannel mChannel;
private Messenger mMessenger;
- private int mDiscoveryId;
- private int mResolveId;
/* Remembers a resolved service until getaddrinfo completes */
- private DnsSdServiceInfo mResolvedService;
- private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>();
+ private NsdServiceInfo mResolvedService;
+
+ /* A map from client id to unique id sent to mDns */
+ private SparseArray<Integer> mClientIds = new SparseArray<Integer>();
private ClientInfo(AsyncChannel c, Messenger m) {
mChannel = c;
mMessenger = m;
- mDiscoveryId = mResolveId = INVALID_ID;
if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m);
}
@@ -751,11 +797,10 @@ public class NsdService extends INsdManager.Stub {
StringBuffer sb = new StringBuffer();
sb.append("mChannel ").append(mChannel).append("\n");
sb.append("mMessenger ").append(mMessenger).append("\n");
- sb.append("mDiscoveryId ").append(mDiscoveryId).append("\n");
- sb.append("mResolveId ").append(mResolveId).append("\n");
sb.append("mResolvedService ").append(mResolvedService).append("\n");
- for(int regId : mRegisteredIds) {
- sb.append("regId ").append(regId).append("\n");
+ for(int i = 0; i< mClientIds.size(); i++) {
+ sb.append("clientId ").append(mClientIds.keyAt(i));
+ sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n");
}
return sb.toString();
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 0f8d151..aa7de82 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1567,6 +1567,31 @@ public final class ActivityManagerService extends ActivityManagerNative
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
+ if (code == SYSPROPS_TRANSACTION) {
+ // We need to tell all apps about the system property change.
+ ArrayList<IBinder> procs = new ArrayList<IBinder>();
+ synchronized(this) {
+ for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
+ final int NA = apps.size();
+ for (int ia=0; ia<NA; ia++) {
+ ProcessRecord app = apps.valueAt(ia);
+ if (app.thread != null) {
+ procs.add(app.thread.asBinder());
+ }
+ }
+ }
+ }
+
+ int N = procs.size();
+ for (int i=0; i<N; i++) {
+ Parcel data2 = Parcel.obtain();
+ try {
+ procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
+ } catch (RemoteException e) {
+ }
+ data2.recycle();
+ }
+ }
try {
return super.onTransact(code, data, reply, flags);
} catch (RuntimeException e) {
@@ -4098,6 +4123,10 @@ public final class ActivityManagerService extends ActivityManagerNative
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
SystemClock.uptimeMillis());
mWindowManager.enableScreenAfterBoot();
+
+ synchronized (this) {
+ updateEventDispatchingLocked();
+ }
}
public void showBootMessage(final CharSequence msg, final boolean always) {
@@ -6686,7 +6715,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized(this) {
mWentToSleep = true;
- mWindowManager.setEventDispatching(false);
+ updateEventDispatchingLocked();
if (!mSleeping) {
mSleeping = true;
@@ -6712,7 +6741,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized(this) {
mShuttingDown = true;
- mWindowManager.setEventDispatching(false);
+ updateEventDispatchingLocked();
if (mMainStack.mResumedActivity != null) {
mMainStack.stopIfSleepingLocked();
@@ -6776,11 +6805,15 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized(this) {
mWentToSleep = false;
- mWindowManager.setEventDispatching(true);
+ updateEventDispatchingLocked();
comeOutOfSleepIfNeededLocked();
}
}
+ private void updateEventDispatchingLocked() {
+ mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
+ }
+
public void setLockScreenShown(boolean shown) {
if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
@@ -11049,7 +11082,7 @@ public final class ActivityManagerService extends ActivityManagerNative
updateOomAdjLocked(r.app);
}
int flags = 0;
- if (si.deliveryCount > 0) {
+ if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
}
if (si.doneExecutingCount > 0) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 1e14f5b..c300411 100755
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1794,10 +1794,6 @@ final class ActivityStack {
mService.mWindowManager.prepareAppTransition(
WindowManagerPolicy.TRANSIT_NONE, keepCurTransition);
mNoAnimActivities.add(r);
- } else if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
- mService.mWindowManager.prepareAppTransition(
- WindowManagerPolicy.TRANSIT_TASK_OPEN, keepCurTransition);
- mNoAnimActivities.remove(r);
} else {
mService.mWindowManager.prepareAppTransition(newTask
? WindowManagerPolicy.TRANSIT_TASK_OPEN
diff --git a/services/java/com/android/server/net/NetworkStatsRecorder.java b/services/java/com/android/server/net/NetworkStatsRecorder.java
index 2ce7771..c3ecf54 100644
--- a/services/java/com/android/server/net/NetworkStatsRecorder.java
+++ b/services/java/com/android/server/net/NetworkStatsRecorder.java
@@ -26,6 +26,7 @@ import android.net.NetworkStats.NonMonotonicObserver;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
import android.net.TrafficStats;
+import android.os.DropBoxManager;
import android.util.Log;
import android.util.MathUtils;
import android.util.Slog;
@@ -34,6 +35,7 @@ import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
import com.google.android.collect.Sets;
+import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
@@ -43,6 +45,8 @@ import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Map;
+import libcore.io.IoUtils;
+
/**
* Logic to record deltas between periodic {@link NetworkStats} snapshots into
* {@link NetworkStatsHistory} that belong to {@link NetworkStatsCollection}.
@@ -56,8 +60,14 @@ public class NetworkStatsRecorder {
private static final boolean LOGD = false;
private static final boolean LOGV = false;
+ private static final String TAG_NETSTATS_DUMP = "netstats_dump";
+
+ /** Dump before deleting in {@link #recoverFromWtf()}. */
+ private static final boolean DUMP_BEFORE_DELETE = true;
+
private final FileRotator mRotator;
private final NonMonotonicObserver<String> mObserver;
+ private final DropBoxManager mDropBox;
private final String mCookie;
private final long mBucketDuration;
@@ -74,9 +84,10 @@ public class NetworkStatsRecorder {
private WeakReference<NetworkStatsCollection> mComplete;
public NetworkStatsRecorder(FileRotator rotator, NonMonotonicObserver<String> observer,
- String cookie, long bucketDuration, boolean onlyTags) {
+ DropBoxManager dropBox, String cookie, long bucketDuration, boolean onlyTags) {
mRotator = checkNotNull(rotator, "missing FileRotator");
mObserver = checkNotNull(observer, "missing NonMonotonicObserver");
+ mDropBox = checkNotNull(dropBox, "missing DropBoxManager");
mCookie = cookie;
mBucketDuration = bucketDuration;
@@ -122,6 +133,7 @@ public class NetworkStatsRecorder {
mComplete = new WeakReference<NetworkStatsCollection>(complete);
} catch (IOException e) {
Log.wtf(TAG, "problem completely reading network stats", e);
+ recoverFromWtf();
}
}
return complete;
@@ -212,6 +224,7 @@ public class NetworkStatsRecorder {
mPending.reset();
} catch (IOException e) {
Log.wtf(TAG, "problem persisting pending stats", e);
+ recoverFromWtf();
}
}
}
@@ -226,6 +239,7 @@ public class NetworkStatsRecorder {
mRotator.rewriteAll(new RemoveUidRewriter(mBucketDuration, uid));
} catch (IOException e) {
Log.wtf(TAG, "problem removing UID " + uid, e);
+ recoverFromWtf();
}
// clear UID from current stats snapshot
@@ -355,4 +369,25 @@ public class NetworkStatsRecorder {
mSinceBoot.dump(pw);
}
}
+
+ /**
+ * Recover from {@link FileRotator} failure by dumping state to
+ * {@link DropBoxManager} and deleting contents.
+ */
+ private void recoverFromWtf() {
+ if (DUMP_BEFORE_DELETE) {
+ final ByteArrayOutputStream os = new ByteArrayOutputStream();
+ try {
+ mRotator.dumpAll(os);
+ } catch (IOException e) {
+ // ignore partial contents
+ os.reset();
+ } finally {
+ IoUtils.closeQuietly(os);
+ }
+ mDropBox.addData(TAG_NETSTATS_DUMP, os.toByteArray(), 0);
+ }
+
+ mRotator.deleteAll();
+ }
}
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 1a56b80..e710b33 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -338,9 +338,11 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private NetworkStatsRecorder buildRecorder(
String prefix, NetworkStatsSettings.Config config, boolean includeTags) {
+ final DropBoxManager dropBox = (DropBoxManager) mContext.getSystemService(
+ Context.DROPBOX_SERVICE);
return new NetworkStatsRecorder(new FileRotator(
mBaseDir, prefix, config.rotateAgeMillis, config.deleteAgeMillis),
- mNonMonotonicObserver, prefix, config.bucketDuration, includeTags);
+ mNonMonotonicObserver, dropBox, prefix, config.bucketDuration, includeTags);
}
private void shutdownLocked() {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 4ae3c57..7c14d49 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1050,7 +1050,7 @@ public class PackageManagerService extends IPackageManager.Stub {
mSystemInstallObserver.startWatching();
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
-
+
// Collect all vendor packages.
mVendorAppDir = new File("/vendor/app");
mVendorInstallObserver = new AppDirObserver(
@@ -1068,8 +1068,30 @@ public class PackageManagerService extends IPackageManager.Stub {
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
- if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
- || mPackages.containsKey(ps.name)) {
+
+ /*
+ * If this is not a system app, it can't be a
+ * disable system app.
+ */
+ if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+ continue;
+ }
+
+ /*
+ * If the package is scanned, it's not erased.
+ */
+ if (mPackages.containsKey(ps.name)) {
+ /*
+ * If the system app is both scanned and in the
+ * disabled packages list, then it must have been
+ * added via OTA. Remove it from the currently
+ * scanned package so the previously user-installed
+ * application can be scanned.
+ */
+ if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
+ mPackages.remove(ps.name);
+ }
+
continue;
}
@@ -3096,15 +3118,21 @@ public class PackageManagerService extends IPackageManager.Stub {
+ "reverting from " + ps.codePathString
+ ": new version " + pkg.mVersionCode
+ " better than installed " + ps.versionCode);
- InstallArgs args = new FileInstallArgs(ps.codePathString,
+ InstallArgs args = createInstallArgs(ps.pkgFlags, ps.codePathString,
ps.resourcePathString, ps.nativeLibraryPathString);
- args.cleanUpResourcesLI();
- mSettings.enableSystemPackageLPw(ps.name);
+ synchronized (mInstaller) {
+ args.cleanUpResourcesLI();
+ }
+ synchronized (mPackages) {
+ mSettings.enableSystemPackageLPw(ps.name);
+ }
}
}
}
+
if (updatedPkg != null) {
- // An updated system app will not have the PARSE_IS_SYSTEM flag set initially
+ // An updated system app will not have the PARSE_IS_SYSTEM flag set
+ // initially
parseFlags |= PackageParser.PARSE_IS_SYSTEM;
}
// Verify certificates against what was last scanned
@@ -3112,6 +3140,49 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.w(TAG, "Failed verifying certificates for package:" + pkg.packageName);
return null;
}
+
+ /*
+ * A new system app appeared, but we already had a non-system one of the
+ * same name installed earlier.
+ */
+ boolean shouldHideSystemApp = false;
+ if (updatedPkg == null && ps != null
+ && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
+ /*
+ * Check to make sure the signatures match first. If they don't,
+ * wipe the installed application and its data.
+ */
+ if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
+ != PackageManager.SIGNATURE_MATCH) {
+ deletePackageLI(pkg.packageName, true, 0, null, false);
+ ps = null;
+ } else {
+ /*
+ * If the newly-added system app is an older version than the
+ * already installed version, hide it. It will be scanned later
+ * and re-added like an update.
+ */
+ if (pkg.mVersionCode < ps.versionCode) {
+ shouldHideSystemApp = true;
+ } else {
+ /*
+ * The newly found system app is a newer version that the
+ * one previously installed. Simply remove the
+ * already-installed application and replace it with our own
+ * while keeping the application data.
+ */
+ Slog.w(TAG, "Package " + ps.name + " at " + scanFile + "reverting from "
+ + ps.codePathString + ": new version " + pkg.mVersionCode
+ + " better than installed " + ps.versionCode);
+ InstallArgs args = createInstallArgs(ps.pkgFlags, ps.codePathString,
+ ps.resourcePathString, ps.nativeLibraryPathString);
+ synchronized (mInstaller) {
+ args.cleanUpResourcesLI();
+ }
+ }
+ }
+ }
+
// The apk is forward locked (not public) if its code and resources
// are kept in different files.
// TODO grab this value from PackageSettings
@@ -3135,7 +3206,27 @@ public class PackageManagerService extends IPackageManager.Stub {
// Set application objects path explicitly.
setApplicationInfoPaths(pkg, codePath, resPath);
// Note that we invoke the following method only if we are about to unpack an application
- return scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime);
+ PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
+ | SCAN_UPDATE_SIGNATURE, currentTime);
+
+ /*
+ * If the system app should be overridden by a previously installed
+ * data, hide the system app now and let the /data/app scan pick it up
+ * again.
+ */
+ if (shouldHideSystemApp) {
+ synchronized (mPackages) {
+ /*
+ * We have to grant systems permissions before we hide, because
+ * grantPermissions will assume the package update is trying to
+ * expand its permissions.
+ */
+ grantPermissionsLPw(pkg, true);
+ mSettings.disableSystemPackageLPw(pkg.packageName);
+ }
+ }
+
+ return scannedPkg;
}
private static void setApplicationInfoPaths(PackageParser.Package pkg, String destCodePath,
@@ -7177,6 +7268,10 @@ public class PackageManagerService extends IPackageManager.Stub {
return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
+ private static boolean isSystemApp(PackageSetting ps) {
+ return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ }
+
private static boolean isUpdatedSystemApp(PackageParser.Package pkg) {
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
}
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index c28cfa2..c4bb519 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -41,7 +41,9 @@ final class InputMonitor implements InputManagerService.Callbacks {
private boolean mInputDispatchFrozen;
// When true, input dispatch proceeds normally. Otherwise all events are dropped.
- private boolean mInputDispatchEnabled = true;
+ // Initially false, so that input does not get dispatched until boot is finished at
+ // which point the ActivityManager will enable dispatching.
+ private boolean mInputDispatchEnabled;
// When true, need to call updateInputWindowsLw().
private boolean mUpdateInputWindowsNeeded = true;
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 2e817ca..5536559 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -85,6 +85,15 @@ public class WindowAnimator {
mPolicy = policy;
}
+ void hideWallpapersLocked() {
+ for (final WindowToken token : mService.mWallpaperTokens) {
+ for (final WindowState wallpaper : token.windows) {
+ wallpaper.mWinAnimator.hide();
+ }
+ token.hidden = true;
+ }
+ }
+
private void testWallpaperAndBackgroundLocked() {
if (mWindowDetachedWallpaper != mDetachedWallpaper) {
if (WindowManagerService.DEBUG_WALLPAPER) Slog.v(TAG,
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 8eda9ca..8957edf 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -3430,9 +3430,6 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized(mWindowMap) {
WindowToken wtoken = mTokenMap.remove(token);
if (wtoken != null) {
- if (wtoken.windowType == TYPE_INPUT_METHOD && mInputMethodWindow != null) {
- mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
- }
boolean delayed = false;
if (!wtoken.hidden) {
wtoken.hidden = true;
@@ -3825,7 +3822,8 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Slog.v(
TAG, "Prepare app transition: transit=" + transit
- + " mNextAppTransition=" + mNextAppTransition);
+ + " mNextAppTransition=" + mNextAppTransition
+ + "\nCallers=" + Debug.getCallers(3));
if (okToDisplay()) {
if (mNextAppTransition == WindowManagerPolicy.TRANSIT_UNSET
|| mNextAppTransition == WindowManagerPolicy.TRANSIT_NONE) {
@@ -4237,7 +4235,7 @@ public class WindowManagerService extends IWindowManager.Stub
e = new RuntimeException();
e.fillInStackTrace();
}
- Slog.v(TAG, "setAppVisibility(" + token + ", " + visible
+ Slog.v(TAG, "setAppVisibility(" + token + ", visible=" + visible
+ "): mNextAppTransition=" + mNextAppTransition
+ " hidden=" + wtoken.hidden
+ " hiddenRequested=" + wtoken.hiddenRequested, e);
@@ -5149,7 +5147,7 @@ public class WindowManagerService extends IWindowManager.Stub
//Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
- surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION,
+ surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
data, null, 0);
data.recycle();
}
@@ -6673,8 +6671,7 @@ public class WindowManagerService extends IWindowManager.Stub
public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1;
public static final int SET_WALLPAPER_OFFSET = ANIMATOR_WHAT_OFFSET + 2;
public static final int SET_DIM_PARAMETERS = ANIMATOR_WHAT_OFFSET + 3;
- public static final int SET_MOVE_ANIMATION = ANIMATOR_WHAT_OFFSET + 4;
- public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 5;
+ public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 4;
private Session mLastReportedHold;
@@ -7158,18 +7155,6 @@ public class WindowManagerService extends IWindowManager.Stub
break;
}
- case SET_MOVE_ANIMATION: {
- WindowAnimator.SetAnimationParams params =
- (WindowAnimator.SetAnimationParams) msg.obj;
- WindowStateAnimator winAnimator = params.mWinAnimator;
- winAnimator.setAnimation(params.mAnimation);
- winAnimator.mAnimDw = params.mAnimDw;
- winAnimator.mAnimDh = params.mAnimDh;
-
- scheduleAnimationLocked();
- break;
- }
-
case CLEAR_PENDING_ACTIONS: {
mAnimator.clearPendingActions();
break;
@@ -7866,8 +7851,10 @@ public class WindowManagerService extends IWindowManager.Stub
mToTopApps.clear();
}
+ // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
WindowState oldWallpaper =
mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+ && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
? null : mWallpaperTarget;
adjustWallpaperWindowsLocked();
@@ -8415,9 +8402,6 @@ public class WindowManagerService extends IWindowManager.Stub
winAnimator.setAnimation(a);
winAnimator.mAnimDw = w.mLastFrame.left - w.mFrame.left;
winAnimator.mAnimDh = w.mLastFrame.top - w.mFrame.top;
- } else {
- winAnimator.mAnimDw = innerDw;
- winAnimator.mAnimDh = innerDh;
}
//Slog.i(TAG, "Window " + this + " clearing mContentChanged - done placing");
@@ -9266,6 +9250,15 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ // It is assumed that this method is called only by InputMethodManagerService.
+ public void saveLastInputMethodWindowForTransition() {
+ synchronized (mWindowMap) {
+ if (mInputMethodWindow != null) {
+ mPolicy.setLastInputMethodWindowLw(mInputMethodWindow, mInputMethodTarget);
+ }
+ }
+ }
+
@Override
public boolean hasNavigationBar() {
return mPolicy.hasNavigationBar();
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index 4f08d92..642de73 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -177,6 +177,13 @@ class WindowStateAnimator {
|| atoken.inPendingTransaction));
}
+ /** Is the window animating the DummyAnimation? */
+ boolean isDummyAnimation() {
+ final AppWindowToken atoken = mWin.mAppToken;
+ return atoken != null
+ && atoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
+ }
+
/** Is this window currently animating? */
boolean isWindowAnimating() {
return mAnimation != null;
@@ -363,19 +370,33 @@ class WindowStateAnimator {
mWin.mDestroying = true;
if (WindowState.SHOW_TRANSACTIONS) WindowManagerService.logSurface(
mWin, "HIDE (finishExit)", null);
- mSurfaceShown = false;
- try {
- mSurface.hide();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error hiding surface in " + this, e);
- }
- mLastHidden = true;
+ hide();
}
mWin.mExiting = false;
if (mWin.mRemoveOnExit) {
mService.mPendingRemove.add(mWin);
mWin.mRemoveOnExit = false;
}
+ if (mService.mWallpaperTarget == mWin) {
+ mAnimator.hideWallpapersLocked();
+ }
+ }
+
+ void hide() {
+ if (!mLastHidden) {
+ //dump();
+ mLastHidden = true;
+ if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
+ "HIDE (performLayout)", null);
+ if (mSurface != null) {
+ mSurfaceShown = false;
+ try {
+ mSurface.hide();
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Exception hiding surface in " + mWin);
+ }
+ }
+ }
}
boolean finishDrawingLocked() {
@@ -987,20 +1008,7 @@ class WindowStateAnimator {
setSurfaceBoundaries(recoveringMemory);
if (w.mAttachedHidden || !w.isReadyForDisplay()) {
- if (!mLastHidden) {
- //dump();
- mLastHidden = true;
- if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
- "HIDE (performLayout)", null);
- if (mSurface != null) {
- mSurfaceShown = false;
- try {
- mSurface.hide();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Exception hiding surface in " + w);
- }
- }
- }
+ hide();
// If we are waiting for this window to handle an
// orientation change, well, it is hidden, so
// doesn't really matter. Note that this does
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 5afe56c..f740718 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1711,12 +1711,8 @@ public class PhoneNumberUtils
return false;
}
- // STOPSHIP: remove this after figuring out issue 5914560, 6383850.
Log.d(LOG_TAG, "System property doesn't provide any emergency numbers."
- + " Use embedded logic for determining emergency numbers."
- + " number: " + toLogSafePhoneNumber(number)
- + ", Iso: " + defaultCountryIso
- + ", useExactMatch: " + useExactMatch);
+ + " Use embedded logic for determining ones.");
// No ecclist system property, so use our own list.
if (defaultCountryIso != null) {
@@ -1735,21 +1731,6 @@ public class PhoneNumberUtils
}
}
- private static String toLogSafePhoneNumber(String number) {
- // Do exactly same thing as Uri#toSafeString() does, which will enable us to compare
- // sanitized phone numbers.
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < number.length(); i++) {
- char c = number.charAt(i);
- if (c == '-' || c == '@' || c == '.') {
- builder.append(c);
- } else {
- builder.append('x');
- }
- }
- return builder.toString();
- }
-
/**
* Checks if a given number is an emergency number for the country that the user is in. The
* current country is determined using the CountryDetector.
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 16f1575..9aed8c8 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -307,6 +307,11 @@ public final class Canvas_Delegate {
}
@LayoutlibDelegate
+ /*package*/ static void freeTextLayoutCaches() {
+ // nothing to be done here yet.
+ }
+
+ @LayoutlibDelegate
/*package*/ static int initRaster(int nativeBitmapOrZero) {
if (nativeBitmapOrZero > 0) {
// get the Bitmap from the int