Merge "Fix 6583164: Make navbar slippery when shade is open" into jb-dev
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index cb53422..54b5836 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -1301,7 +1301,6 @@
" am display-size [reset|MxN]\n" +
" am to-uri [INTENT]\n" +
" am to-intent-uri [INTENT]\n" +
- " am switch-user <USER_ID>\n" +
"\n" +
"am start: start an Activity. Options are:\n" +
" -D: enable debugging\n" +
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index f9ff861..88a025e 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -1360,22 +1360,19 @@
System.err.println(" pm list instrumentation [-f] [TARGET-PACKAGE]");
System.err.println(" pm list features");
System.err.println(" pm list libraries");
- System.err.println(" pm list users");
System.err.println(" pm path PACKAGE");
System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
System.err.println(" pm clear PACKAGE");
- System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
- System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
- System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm enable PACKAGE_OR_COMPONENT");
+ System.err.println(" pm disable PACKAGE_OR_COMPONENT");
+ System.err.println(" pm disable-user PACKAGE_OR_COMPONENT");
System.err.println(" pm grant PACKAGE PERMISSION");
System.err.println(" pm revoke PACKAGE PERMISSION");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
System.err.println(" pm get-install-location");
System.err.println(" pm set-permission-enforced PERMISSION [true|false]");
- System.err.println(" pm create-user USER_NAME");
- System.err.println(" pm remove-user USER_ID");
System.err.println("");
System.err.println("pm list packages: prints all packages, optionally only");
System.err.println(" those whose package name contains the text in FILTER. Options:");
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index ad4b58f..079b9bd 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -163,7 +163,8 @@
new HashMap<Account, Integer>();
private final Object cacheLock = new Object();
/** protected by the {@link #cacheLock} */
- private final HashMap<String, Account[]> accountCache = new HashMap<String, Account[]>();
+ private final HashMap<String, Account[]> accountCache =
+ new LinkedHashMap<String, Account[]>();
/** protected by the {@link #cacheLock} */
private HashMap<Account, HashMap<String, String>> userDataCache =
new HashMap<Account, HashMap<String, String>>();
@@ -296,7 +297,7 @@
try {
accounts.accountCache.clear();
final HashMap<String, ArrayList<String>> accountNamesByType =
- new HashMap<String, ArrayList<String>>();
+ new LinkedHashMap<String, ArrayList<String>>();
while (cursor.moveToNext()) {
final long accountId = cursor.getLong(0);
final String accountType = cursor.getString(1);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 6058bdc..03ee419 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1568,8 +1568,17 @@
for (int i=0; i<N; i++) {
Fragment f = mActive.get(i);
if (f != null) {
+ if (f.mIndex < 0) {
+ String msg = "Failure saving state: active " + f
+ + " has cleared index: " + f.mIndex;
+ Slog.e(TAG, msg);
+ dump(" ", null, new PrintWriter(new LogWriter(
+ Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
+ throw new IllegalStateException(msg);
+ }
+
haveFragments = true;
-
+
FragmentState fs = new FragmentState(f);
active[i] = fs;
@@ -1621,6 +1630,14 @@
added = new int[N];
for (int i=0; i<N; i++) {
added[i] = mAdded.get(i).mIndex;
+ if (added[i] < 0) {
+ String msg = "Failure saving state: active " + mAdded.get(i)
+ + " has cleared index: " + added[i];
+ Slog.e(TAG, msg);
+ dump(" ", null, new PrintWriter(new LogWriter(
+ Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
+ throw new IllegalStateException(msg);
+ }
if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
+ ": " + mAdded.get(i));
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3ced82b..036008b 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1379,7 +1379,7 @@
}
}
- private RemoteViews applyStandardTemplate(int resId) {
+ private RemoteViews applyStandardTemplate(int resId, boolean fitIn1U) {
RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
boolean showLine3 = false;
boolean showLine2 = false;
@@ -1432,7 +1432,6 @@
contentView.setTextViewText(R.id.text, mSubText);
if (mContentText != null) {
contentView.setTextViewText(R.id.text2, mContentText);
- // need to shrink all the type to make sure everything fits
contentView.setViewVisibility(R.id.text2, View.VISIBLE);
showLine2 = true;
} else {
@@ -1450,10 +1449,13 @@
}
}
if (showLine2) {
- final Resources res = mContext.getResources();
- final float subTextSize = res.getDimensionPixelSize(
- R.dimen.notification_subtext_size);
- contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
+ if (fitIn1U) {
+ // need to shrink all the type to make sure everything fits
+ final Resources res = mContext.getResources();
+ final float subTextSize = res.getDimensionPixelSize(
+ R.dimen.notification_subtext_size);
+ contentView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_PX, subTextSize);
+ }
// vertical centering
contentView.setViewPadding(R.id.line1, 0, 0, 0, 0);
}
@@ -1470,16 +1472,18 @@
}
}
contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
+ contentView.setViewVisibility(R.id.overflow_divider, showLine3 ? View.VISIBLE : View.GONE);
return contentView;
}
private RemoteViews applyStandardTemplateWithActions(int layoutId) {
- RemoteViews big = applyStandardTemplate(layoutId);
+ RemoteViews big = applyStandardTemplate(layoutId, false);
int N = mActions.size();
if (N > 0) {
// Log.d("Notification", "has actions: " + mContentText);
big.setViewVisibility(R.id.actions, View.VISIBLE);
+ big.setViewVisibility(R.id.action_divider, View.VISIBLE);
if (N>MAX_ACTION_BUTTONS) N=MAX_ACTION_BUTTONS;
big.removeAllViews(R.id.actions);
for (int i=0; i<N; i++) {
@@ -1495,7 +1499,7 @@
if (mContentView != null) {
return mContentView;
} else {
- return applyStandardTemplate(R.layout.notification_template_base); // no more special large_icon flavor
+ return applyStandardTemplate(R.layout.notification_template_base, true); // no more special large_icon flavor
}
}
@@ -1506,7 +1510,7 @@
if (mContentView == null) {
return applyStandardTemplate(mLargeIcon == null
? R.layout.status_bar_latest_event_ticker
- : R.layout.status_bar_latest_event_ticker_large_icon);
+ : R.layout.status_bar_latest_event_ticker_large_icon, true);
} else {
return null;
}
@@ -1655,12 +1659,9 @@
contentView.setViewVisibility(R.id.line1, View.VISIBLE);
}
+ // The last line defaults to the content text or subtext, but can be replaced by mSummaryText
if (mSummaryText != null && !mSummaryText.equals("")) {
- contentView.setViewVisibility(R.id.overflow_title, View.VISIBLE);
- contentView.setTextViewText(R.id.overflow_title, mSummaryText);
- contentView.setViewVisibility(R.id.line3, View.GONE);
- } else {
- contentView.setViewVisibility(R.id.overflow_title, View.GONE);
+ contentView.setTextViewText(R.id.text, mSummaryText);
contentView.setViewVisibility(R.id.line3, View.VISIBLE);
}
@@ -1801,6 +1802,8 @@
}
private RemoteViews makeBigContentView() {
+ // Remove the content text so line3 disappears entirely
+ mBuilder.mContentText = null;
RemoteViews contentView = getStandardView(R.layout.notification_template_big_text);
contentView.setTextViewText(R.id.big_text, mBigText);
contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ad52e13..e180df4 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -935,7 +935,17 @@
com.android.internal.R.styleable.AndroidManifest_installLocation,
PARSE_DEFAULT_INSTALL_LOCATION);
pkg.applicationInfo.installLocation = pkg.installLocation;
-
+
+ /* Set the global "forward lock" flag */
+ if ((flags & PARSE_FORWARD_LOCK) != 0) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FORWARD_LOCK;
+ }
+
+ /* Set the global "on SD card" flag */
+ if ((flags & PARSE_ON_SDCARD) != 0) {
+ pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+ }
+
// Resource boolean are -1, so 1 means we don't know the value.
int supportsSmallScreens = 1;
int supportsNormalScreens = 1;
@@ -1726,14 +1736,6 @@
}
}
- if ((flags & PARSE_FORWARD_LOCK) != 0) {
- ai.flags |= ApplicationInfo.FLAG_FORWARD_LOCK;
- }
-
- if ((flags & PARSE_ON_SDCARD) != 0) {
- ai.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
- }
-
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_debuggable,
false)) {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 035a7c6..4d9077f 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -736,8 +736,8 @@
return;
case CAMERA_MSG_PREVIEW_FRAME:
- if (mPreviewCallback != null) {
- PreviewCallback cb = mPreviewCallback;
+ PreviewCallback pCb = mPreviewCallback;
+ if (pCb != null) {
if (mOneShot) {
// Clear the callback variable before the callback
// in case the app calls setPreviewCallback from
@@ -749,7 +749,7 @@
// Set to oneshot mode again.
setHasPreviewCallback(true, false);
}
- cb.onPreviewFrame((byte[])msg.obj, mCamera);
+ pCb.onPreviewFrame((byte[])msg.obj, mCamera);
}
return;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 2782dca..e8f87bb 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -24,6 +24,7 @@
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
+import android.content.ContextWrapper;
import android.content.CursorEntityIterator;
import android.content.Entity;
import android.content.EntityIterator;
@@ -7711,9 +7712,19 @@
*/
public static void showQuickContact(Context context, Rect target, Uri lookupUri, int mode,
String[] excludeMimes) {
+ // When launching from an Activiy, we don't want to start a new task, but otherwise
+ // we *must* start a new task. (Otherwise startActivity() would crash.)
+ Context actualContext = context;
+ while ((actualContext instanceof ContextWrapper)
+ && !(actualContext instanceof Activity)) {
+ actualContext = ((ContextWrapper) actualContext).getBaseContext();
+ }
+ final int intentFlags = (actualContext instanceof Activity)
+ ? Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
+ : Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK;
+
// Launch pivot dialog through intent for now
- final Intent intent = new Intent(ACTION_QUICK_CONTACT)
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ final Intent intent = new Intent(ACTION_QUICK_CONTACT).addFlags(intentFlags);
intent.setData(lookupUri);
intent.setSourceBounds(target);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 8b7ee0e..8630204 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2886,6 +2886,15 @@
"enabled_accessibility_services";
/**
+ * List of the accessibility services to which the user has graned
+ * permission to put the device into touch exploration mode.
+ *
+ * @hide
+ */
+ public static final String TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES =
+ "touch_exploration_granted_accessibility_services";
+
+ /**
* Whether to speak passwords while in accessibility mode.
*/
public static final String ACCESSIBILITY_SPEAK_PASSWORD = "speak_password";
@@ -4292,6 +4301,7 @@
ACCESSIBILITY_SCRIPT_INJECTION,
BACKUP_AUTO_RESTORE,
ENABLED_ACCESSIBILITY_SERVICES,
+ TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
TOUCH_EXPLORATION_ENABLED,
ACCESSIBILITY_ENABLED,
ACCESSIBILITY_SPEAK_PASSWORD,
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index 300bc68..08a99d2 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -33,7 +33,11 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
+import android.os.Handler;
+import android.os.Message;
import android.os.ParcelUuid;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
import android.provider.Settings;
import android.util.Log;
@@ -65,6 +69,10 @@
private final BluetoothAdapter mAdapter;
private int mTargetA2dpState;
private BluetoothDevice mPlayingA2dpDevice;
+ private IntentBroadcastHandler mIntentBroadcastHandler;
+ private final WakeLock mWakeLock;
+
+ private static final int MSG_CONNECTION_STATE_CHANGED = 0;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -131,6 +139,11 @@
public BluetoothA2dpService(Context context, BluetoothService bluetoothService) {
mContext = context;
+ PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BluetoothA2dpService");
+
+ mIntentBroadcastHandler = new IntentBroadcastHandler();
+
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mBluetoothService = bluetoothService;
@@ -514,17 +527,15 @@
adjustOtherSinkPriorities(device);
}
- Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
- intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+ int delay = mAudioManager.setBluetoothA2dpDeviceConnectionState(device, state);
- if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
-
- mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
- prevState);
+ mWakeLock.acquire();
+ mIntentBroadcastHandler.sendMessageDelayed(mIntentBroadcastHandler.obtainMessage(
+ MSG_CONNECTION_STATE_CHANGED,
+ prevState,
+ state,
+ device),
+ delay);
}
}
@@ -586,6 +597,34 @@
}
}
+ /** Handles A2DP connection state change intent broadcasts. */
+ private class IntentBroadcastHandler extends Handler {
+
+ private void onConnectionStateChanged(BluetoothDevice device, int prevState, int state) {
+ Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
+ intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ mContext.sendBroadcast(intent, BLUETOOTH_PERM);
+
+ if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
+
+ mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
+ prevState);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_CONNECTION_STATE_CHANGED:
+ onConnectionStateChanged((BluetoothDevice) msg.obj, msg.arg1, msg.arg2);
+ mWakeLock.release();
+ break;
+ }
+ }
+ }
+
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 2ea0360..3bb9c01 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -459,6 +459,18 @@
}
/**
+ * Returns true if the device is a full keyboard.
+ *
+ * @return True if the device is a full keyboard.
+ *
+ * @hide
+ */
+ public boolean isFullKeyboard() {
+ return (mSources & SOURCE_KEYBOARD) == SOURCE_KEYBOARD
+ && mKeyboardType == KEYBOARD_TYPE_ALPHABETIC;
+ }
+
+ /**
* Gets the name of this input device.
* @return The input device name.
*/
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index 78984e0..5ffc2c3 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -437,8 +437,10 @@
public void postVolumeChanged(int streamType, int flags) {
if (hasMessages(MSG_VOLUME_CHANGED)) return;
- if (mStreamControls == null) {
- createSliders();
+ synchronized (this) {
+ if (mStreamControls == null) {
+ createSliders();
+ }
}
removeMessages(MSG_FREE_RESOURCES);
obtainMessage(MSG_VOLUME_CHANGED, streamType, flags).sendToTarget();
@@ -450,8 +452,10 @@
public void postMuteChanged(int streamType, int flags) {
if (hasMessages(MSG_VOLUME_CHANGED)) return;
- if (mStreamControls == null) {
- createSliders();
+ synchronized (this) {
+ if (mStreamControls == null) {
+ createSliders();
+ }
}
removeMessages(MSG_FREE_RESOURCES);
obtainMessage(MSG_MUTE_CHANGED, streamType, flags).sendToTarget();
@@ -471,10 +475,12 @@
if (LOGD) Log.d(TAG, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")");
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
- if (mActiveStreamType != streamType) {
- reorderSliders(streamType);
+ synchronized (this) {
+ if (mActiveStreamType != streamType) {
+ reorderSliders(streamType);
+ }
+ onShowVolumeChanged(streamType, flags);
}
- onShowVolumeChanged(streamType, flags);
}
if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && ! mRingIsSilent) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 9abe72b..dae9c6a 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2283,14 +2283,10 @@
final ListAdapter adapter = getAdapter();
if ((position == INVALID_POSITION) || (adapter == null)) {
- // Cannot perform actions on invalid items.
- info.setEnabled(false);
return;
}
if (!isEnabled() || !adapter.isEnabled(position)) {
- // Cannot perform actions on invalid items.
- info.setEnabled(false);
return;
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 16490e8..c29dd58 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1416,6 +1416,7 @@
}
Layout layout = mTextView.getLayout();
+ Layout hintLayout = mTextView.getHintLayout();
final int offset = mTextView.getSelectionStart();
final int line = layout.getLineForOffset(offset);
final int top = layout.getLineTop(line);
@@ -1429,13 +1430,23 @@
middle = (top + bottom) >> 1;
}
- updateCursorPosition(0, top, middle, layout.getPrimaryHorizontal(offset));
+ updateCursorPosition(0, top, middle, getPrimaryHorizontal(layout, hintLayout, offset));
if (mCursorCount == 2) {
updateCursorPosition(1, middle, bottom, layout.getSecondaryHorizontal(offset));
}
}
+ private float getPrimaryHorizontal(Layout layout, Layout hintLayout, int offset) {
+ if (TextUtils.isEmpty(layout.getText()) &&
+ hintLayout != null &&
+ !TextUtils.isEmpty(hintLayout.getText())) {
+ return hintLayout.getPrimaryHorizontal(offset);
+ } else {
+ return layout.getPrimaryHorizontal(offset);
+ }
+ }
+
/**
* @return true if the selection mode was actually started.
*/
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 3e2d43a..131b075 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1312,6 +1312,14 @@
}
/**
+ * @return the Layout that is currently being used to display the hint text.
+ * This can be null.
+ */
+ final Layout getHintLayout() {
+ return mHintLayout;
+ }
+
+ /**
* @return the current key listener for this TextView.
* This will frequently be null for non-EditText TextViews.
*
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 234cb71..46478ca 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -673,26 +673,29 @@
if (mCurWindowVisibility == View.VISIBLE && (mShowHideAnimationEnabled
|| fromSystem)) {
- mTopVisibilityView.setAlpha(0);
- mTopVisibilityView.setTranslationY(-mTopVisibilityView.getHeight());
+ mTopVisibilityView.setTranslationY(0); // because we're about to ask its window loc
+ float startingY = -mTopVisibilityView.getHeight();
+ if (fromSystem) {
+ int topLeft[] = {0, 0};
+ mTopVisibilityView.getLocationInWindow(topLeft);
+ startingY -= topLeft[1];
+ }
+ mTopVisibilityView.setTranslationY(startingY);
AnimatorSet anim = new AnimatorSet();
- AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView, "alpha", 1));
- b.with(ObjectAnimator.ofFloat(mTopVisibilityView, "translationY", 0));
+ AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
+ "translationY", 0));
if (mContentView != null) {
b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
- -mTopVisibilityView.getHeight(), 0));
+ startingY, 0));
}
if (mSplitView != null && mContextDisplayMode == CONTEXT_DISPLAY_SPLIT) {
- mSplitView.setAlpha(0);
mSplitView.setTranslationY(mSplitView.getHeight());
mSplitView.setVisibility(View.VISIBLE);
- b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 1));
b.with(ObjectAnimator.ofFloat(mSplitView, "translationY", 0));
}
anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.decelerate_quad));
- anim.setDuration(mContext.getResources().getInteger(
- com.android.internal.R.integer.config_mediumAnimTime));
+ com.android.internal.R.interpolator.decelerate_cubic));
+ anim.setDuration(250);
// If this is being shown from the system, add a small delay.
// This is because we will also be animating in the status bar,
// and these two elements can't be done in lock-step. So we give
@@ -700,9 +703,6 @@
// the action bar animates. (This corresponds to the corresponding
// case when hiding, where the status bar has a small delay before
// starting.)
- if (fromSystem) {
- anim.setStartDelay(100);
- }
anim.addListener(mShowListener);
mCurrentShowAnim = anim;
anim.start();
@@ -734,23 +734,26 @@
mTopVisibilityView.setAlpha(1);
mContainerView.setTransitioning(true);
AnimatorSet anim = new AnimatorSet();
- AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView, "alpha", 0));
- b.with(ObjectAnimator.ofFloat(mTopVisibilityView, "translationY",
- -mTopVisibilityView.getHeight()));
+ float endingY = -mTopVisibilityView.getHeight();
+ if (fromSystem) {
+ int topLeft[] = {0, 0};
+ mTopVisibilityView.getLocationInWindow(topLeft);
+ endingY -= topLeft[1];
+ }
+ AnimatorSet.Builder b = anim.play(ObjectAnimator.ofFloat(mTopVisibilityView,
+ "translationY", endingY));
if (mContentView != null) {
b.with(ObjectAnimator.ofFloat(mContentView, "translationY",
- 0, -mTopVisibilityView.getHeight()));
+ 0, endingY));
}
if (mSplitView != null && mSplitView.getVisibility() == View.VISIBLE) {
mSplitView.setAlpha(1);
- b.with(ObjectAnimator.ofFloat(mSplitView, "alpha", 0));
b.with(ObjectAnimator.ofFloat(mSplitView, "translationY",
mSplitView.getHeight()));
}
anim.setInterpolator(AnimationUtils.loadInterpolator(mContext,
- com.android.internal.R.interpolator.accelerate_quad));
- anim.setDuration(mContext.getResources().getInteger(
- com.android.internal.R.integer.config_mediumAnimTime));
+ com.android.internal.R.interpolator.accelerate_cubic));
+ anim.setDuration(250);
anim.addListener(mHideListener);
mCurrentShowAnim = anim;
anim.start();
diff --git a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
index a22395b..b2c3091 100644
--- a/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
+++ b/core/java/com/android/internal/widget/multiwaveview/MultiWaveView.java
@@ -419,6 +419,7 @@
"y", 0,
"onUpdate", mUpdateListener,
"onComplete", finishListener));
+ mHandleAnimations.start();
}
/**
@@ -528,7 +529,6 @@
deactivateHandle(HIDE_ANIMATION_DURATION, HIDE_ANIMATION_DELAY, 1.0f,
mResetListenerWithPing);
hideTargets(true, false);
- mHandleAnimations.start();
}
setGrabbedState(OnTriggerListener.NO_HANDLE);
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
index 0777ea2..3bbb8bf 100644
--- a/core/jni/android_database_SQLiteConnection.cpp
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -41,6 +41,20 @@
namespace android {
+/* Busy timeout in milliseconds.
+ * If another connection (possibly in another process) has the database locked for
+ * longer than this amount of time then SQLite will generate a SQLITE_BUSY error.
+ * The SQLITE_BUSY error is then raised as a SQLiteDatabaseLockedException.
+ *
+ * In ordinary usage, busy timeouts are quite rare. Most databases only ever
+ * have a single open connection at a time unless they are using WAL. When using
+ * WAL, a timeout could occur if one connection is busy performing an auto-checkpoint
+ * operation. The busy timeout needs to be long enough to tolerate slow I/O write
+ * operations but not so long as to cause the application to hang indefinitely if
+ * there is a problem acquiring a database lock.
+ */
+static const int BUSY_TIMEOUT_MS = 2500;
+
static struct {
jfieldID name;
jfieldID numArgs;
@@ -127,8 +141,8 @@
return 0;
}
- // Set the default busy handler to retry for 1000ms and then return SQLITE_BUSY
- err = sqlite3_busy_timeout(db, 1000 /* ms */);
+ // Set the default busy handler to retry automatically before returning SQLITE_BUSY.
+ err = sqlite3_busy_timeout(db, BUSY_TIMEOUT_MS);
if (err != SQLITE_OK) {
throw_sqlite3_exception(env, db, "Could not set busy timeout");
sqlite3_close(db);
diff --git a/core/res/res/anim/dock_bottom_enter.xml b/core/res/res/anim/dock_bottom_enter.xml
index 74a021b..4f2f753 100644
--- a/core/res/res/anim/dock_bottom_enter.xml
+++ b/core/res/res/anim/dock_bottom_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the bottom of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromYDelta="100%" android:toYDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_bottom_exit.xml b/core/res/res/anim/dock_bottom_exit.xml
index 213b3d9..afbe24b 100644
--- a/core/res/res/anim/dock_bottom_exit.xml
+++ b/core/res/res/anim/dock_bottom_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the bottom of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromYDelta="0" android:toYDelta="100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_left_enter.xml b/core/res/res/anim/dock_left_enter.xml
index 4fce35a..7f5dfd5 100644
--- a/core/res/res/anim/dock_left_enter.xml
+++ b/core/res/res/anim/dock_left_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the left of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromXDelta="-100%" android:toXDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_left_exit.xml b/core/res/res/anim/dock_left_exit.xml
index bce203d..11cbc0b3 100644
--- a/core/res/res/anim/dock_left_exit.xml
+++ b/core/res/res/anim/dock_left_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the right of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromXDelta="0" android:toXDelta="-100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_right_enter.xml b/core/res/res/anim/dock_right_enter.xml
index 26b8ad6..a92c7d2 100644
--- a/core/res/res/anim/dock_right_enter.xml
+++ b/core/res/res/anim/dock_right_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the right of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromXDelta="100%" android:toXDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_right_exit.xml b/core/res/res/anim/dock_right_exit.xml
index 6beda59..80e4dc3 100644
--- a/core/res/res/anim/dock_right_exit.xml
+++ b/core/res/res/anim/dock_right_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the right of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromXDelta="0" android:toXDelta="100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_top_enter.xml b/core/res/res/anim/dock_top_enter.xml
index 594b479..1f74e48 100644
--- a/core/res/res/anim/dock_top_enter.xml
+++ b/core/res/res/anim/dock_top_enter.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the top of the screen is entering. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/decelerate_quad">
+ android:interpolator="@android:interpolator/decelerate_cubic">
<translate android:fromYDelta="-100%" android:toYDelta="0"
- android:duration="@android:integer/config_mediumAnimTime"/>
+ android:duration="250"/>
</set>
diff --git a/core/res/res/anim/dock_top_exit.xml b/core/res/res/anim/dock_top_exit.xml
index b9691f6..4d2fea94 100644
--- a/core/res/res/anim/dock_top_exit.xml
+++ b/core/res/res/anim/dock_top_exit.xml
@@ -18,7 +18,7 @@
<!-- Animation for when a dock window at the top of the screen is exiting. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:interpolator/accelerate_quad">
+ android:interpolator="@android:interpolator/accelerate_cubic">
<translate android:fromYDelta="0" android:toYDelta="-100%"
- android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
+ android:startOffset="100" android:duration="250"/>
</set>
diff --git a/core/res/res/layout/notification_action_list.xml b/core/res/res/layout/notification_action_list.xml
index fa0a8c8..591c9ea 100644
--- a/core/res/res/layout/notification_action_list.xml
+++ b/core/res/res/layout/notification_action_list.xml
@@ -23,6 +23,7 @@
android:visibility="gone"
android:showDividers="middle"
android:divider="?android:attr/listDivider"
+ android:dividerPadding="12dp"
>
<!-- actions will be added here -->
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_base.xml b/core/res/res/layout/notification_template_base.xml
index ed680a9..47bbbde 100644
--- a/core/res/res/layout/notification_template_base.xml
+++ b/core/res/res/layout/notification_template_base.xml
@@ -36,8 +36,7 @@
android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
+ android:paddingRight="8dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:gravity="top"
@@ -47,6 +46,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
+ android:layout_marginLeft="8dp"
android:orientation="horizontal"
>
<TextView android:id="@+id/title"
@@ -81,6 +81,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginLeft="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -90,24 +91,17 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginLeft="8dp"
android:visibility="gone"
style="?android:attr/progressBarStyleHorizontal"
/>
- <TextView android:id="@+id/overflow_title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:visibility="gone"
- android:layout_weight="1"
- />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginLeft="8dp"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -130,14 +124,14 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_big_base.xml b/core/res/res/layout/notification_template_big_base.xml
index f2c204f..69f0a24 100644
--- a/core/res/res/layout/notification_template_big_base.xml
+++ b/core/res/res/layout/notification_template_big_base.xml
@@ -33,19 +33,16 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
- android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
- android:paddingTop="2dp"
- android:paddingBottom="2dp"
android:gravity="top"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
+ android:paddingTop="2dp"
android:orientation="vertical"
>
<LinearLayout
@@ -53,6 +50,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
+ android:layout_marginRight="8dp"
+ android:layout_marginLeft="8dp"
android:orientation="horizontal"
>
<TextView android:id="@+id/title"
@@ -87,6 +86,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -96,6 +97,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="false"
android:visibility="gone"
/>
@@ -103,7 +106,10 @@
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
+ android:gravity="center_vertical"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -126,29 +132,38 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
<ProgressBar
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:visibility="gone"
style="?android:attr/progressBarStyleHorizontal"
/>
</LinearLayout>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:id="@+id/action_divider"
+ android:visibility="gone"
+ android:background="?android:attr/dividerHorizontal" />
<include
layout="@layout/notification_action_list"
- android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/notification_large_icon_width"
/>
</LinearLayout>
</FrameLayout>
diff --git a/core/res/res/layout/notification_template_big_picture.xml b/core/res/res/layout/notification_template_big_picture.xml
index 077616e..ecb3616 100644
--- a/core/res/res/layout/notification_template_big_picture.xml
+++ b/core/res/res/layout/notification_template_big_picture.xml
@@ -53,7 +53,6 @@
<include
layout="@layout/notification_action_list"
android:id="@+id/actions"
- android:layout_marginLeft="8dp"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/notification_template_big_text.xml b/core/res/res/layout/notification_template_big_text.xml
index 304f2b5..b86177e 100644
--- a/core/res/res/layout/notification_template_big_text.xml
+++ b/core/res/res/layout/notification_template_big_text.xml
@@ -34,8 +34,6 @@
android:layout_gravity="fill_vertical"
android:layout_marginLeft="@dimen/notification_large_icon_width"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:gravity="top"
@@ -44,6 +42,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:layout_weight="1"
>
<LinearLayout
@@ -87,6 +87,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -97,6 +98,8 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:visibility="gone"
android:layout_weight="0"
style="?android:attr/progressBarStyleHorizontal"
@@ -105,7 +108,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:layout_marginBottom="2dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="false"
android:visibility="gone"
android:maxLines="8"
@@ -113,6 +117,13 @@
android:layout_weight="1"
/>
</LinearLayout>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:layout_marginTop="-1px"
+ android:id="@+id/action_divider"
+ android:visibility="gone"
+ android:background="?android:attr/dividerHorizontal" />
<include
layout="@layout/notification_action_list"
android:layout_width="match_parent"
@@ -120,22 +131,23 @@
android:visibility="gone"
android:layout_weight="1"
/>
- <TextView android:id="@+id/overflow_title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ <ImageView
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
- android:visibility="gone"
- android:layout_weight="0"
- />
+ android:layout_height="1px"
+ android:id="@+id/overflow_divider"
+ android:layout_marginBottom="8dp"
+ android:visibility="visible"
+ android:background="?android:attr/dividerHorizontal" />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
android:layout_weight="0"
+ android:gravity="center_vertical"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -158,14 +170,14 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_inbox.xml b/core/res/res/layout/notification_template_inbox.xml
index 121a81c..e9a3686 100644
--- a/core/res/res/layout/notification_template_inbox.xml
+++ b/core/res/res/layout/notification_template_inbox.xml
@@ -36,8 +36,6 @@
android:layout_marginLeft="@dimen/notification_large_icon_width"
android:minHeight="@dimen/notification_large_icon_height"
android:orientation="vertical"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:gravity="top"
@@ -46,6 +44,8 @@
android:id="@+id/line1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:paddingTop="6dp"
android:orientation="horizontal"
android:layout_weight="0"
@@ -82,6 +82,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="-2dp"
android:layout_marginBottom="-2dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:fadingEdge="horizontal"
android:ellipsize="marquee"
@@ -92,6 +94,8 @@
android:id="@android:id/progress"
android:layout_width="match_parent"
android:layout_height="12dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:visibility="gone"
android:layout_weight="0"
style="?android:attr/progressBarStyleHorizontal"
@@ -100,6 +104,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -109,6 +115,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -118,6 +126,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -127,6 +137,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -136,6 +148,7 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -145,6 +158,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -154,6 +169,8 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
@@ -163,35 +180,44 @@
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
android:layout_width="match_parent"
android:layout_height="0dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginRight="8dp"
android:singleLine="true"
android:ellipsize="end"
android:visibility="gone"
android:layout_weight="1"
android:text="@android:string/ellipsis"
/>
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:id="@+id/overflow_divider"
+ android:layout_marginTop="8dp"
+ android:visibility="visible"
+ android:background="?android:attr/dividerHorizontal" />
<include
layout="@layout/notification_action_list"
- android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
/>
- <TextView android:id="@+id/overflow_title"
- android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ <ImageView
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:singleLine="true"
- android:ellipsize="marquee"
- android:fadingEdge="horizontal"
+ android:layout_height="1px"
+ android:id="@+id/action_divider"
android:visibility="gone"
- android:layout_weight="0"
- />
+ android:background="?android:attr/dividerHorizontal" /><!-- note: divider below actions -->
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginLeft="8dp"
+ android:layout_marginBottom="8dp"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
android:layout_weight="0"
+ android:gravity="center_vertical"
>
<TextView android:id="@+id/text"
android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
@@ -214,14 +240,14 @@
android:paddingLeft="8dp"
/>
<ImageView android:id="@+id/right_icon"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_width="16dp"
+ android:layout_height="16dp"
android:layout_gravity="center"
android:layout_weight="0"
+ android:layout_marginLeft="8dp"
android:scaleType="centerInside"
- android:paddingLeft="8dp"
android:visibility="gone"
- android:drawableAlpha="180"
+ android:drawableAlpha="153"
/>
</LinearLayout>
</LinearLayout>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index a70394f..bf9fe42 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -120,7 +120,6 @@
<java-symbol type="id" name="old_app_action" />
<java-symbol type="id" name="old_app_description" />
<java-symbol type="id" name="old_app_icon" />
- <java-symbol type="id" name="overflow_title" />
<java-symbol type="id" name="package_label" />
<java-symbol type="id" name="packages_list" />
<java-symbol type="id" name="pause" />
@@ -210,6 +209,8 @@
<java-symbol type="id" name="inbox_text6" />
<java-symbol type="id" name="inbox_more" />
<java-symbol type="id" name="status_bar_latest_event_content" />
+ <java-symbol type="id" name="action_divider" />
+ <java-symbol type="id" name="overflow_divider" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a54cdf1..223d17a 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -239,7 +239,7 @@
</style>
<!-- Notification content styles -->
<style name="TextAppearance.StatusBar.EventContent">
- <item name="android:textColor">#808080</item>
+ <item name="android:textColor">#999999</item>
<item name="android:textSize">@dimen/notification_text_size</item>
</style>
<style name="TextAppearance.StatusBar.EventContent.Title">
@@ -253,11 +253,14 @@
</style>
<style name="TextAppearance.StatusBar.EventContent.Info">
<item name="android:textSize">@dimen/notification_subtext_size</item>
- <item name="android:textColor">#666666</item>
+ <item name="android:textColor">#999999</item>
</style>
<style name="TextAppearance.StatusBar.EventContent.Time">
<item name="android:textSize">@dimen/notification_subtext_size</item>
- <item name="android:textColor">#666666</item>
+ <item name="android:textColor">#999999</item>
+ </style>
+ <style name="TextAppearance.StatusBar.EventContent.Emphasis">
+ <item name="android:textColor">#CCCCCC</item>
</style>
<style name="TextAppearance.Small.CalendarViewWeekDayView">
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 6c7c160..6b9522b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -19,6 +19,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -2376,6 +2377,42 @@
}
}
+ /**
+ * Indicate wired accessory connection state change.
+ * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
+ * @param state new connection state: 1 connected, 0 disconnected
+ * @param name device name
+ * {@hide}
+ */
+ public void setWiredDeviceConnectionState(int device, int state, String name) {
+ IAudioService service = getService();
+ try {
+ service.setWiredDeviceConnectionState(device, state, name);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in setWiredDeviceConnectionState "+e);
+ }
+ }
+
+ /**
+ * Indicate A2DP sink connection state change.
+ * @param device Bluetooth device connected/disconnected
+ * @param state new connection state (BluetoothProfile.STATE_xxx)
+ * @return a delay in ms that the caller should wait before broadcasting
+ * BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED intent.
+ * {@hide}
+ */
+ public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state) {
+ IAudioService service = getService();
+ int delay = 0;
+ try {
+ delay = service.setBluetoothA2dpDeviceConnectionState(device, state);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Dead object in setBluetoothA2dpDeviceConnectionState "+e);
+ } finally {
+ return delay;
+ }
+ }
+
/** {@hide} */
public IRingtonePlayer getRingtonePlayer() {
try {
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 5e338ab..84856bf 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -135,6 +135,8 @@
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;
+ private static final int MSG_SET_WIRED_DEVICE_CONNECTION_STATE = 16;
+ private static final int MSG_SET_A2DP_CONNECTION_STATE = 17;
// flags for MSG_PERSIST_VOLUME indicating if current and/or last audible volume should be
@@ -442,15 +444,9 @@
// Register for device connection intent broadcasts.
IntentFilter intentFilter =
- new IntentFilter(Intent.ACTION_HEADSET_PLUG);
-
- intentFilter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- intentFilter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
+ new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
intentFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
intentFilter.addAction(Intent.ACTION_DOCK_EVENT);
- intentFilter.addAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
- intentFilter.addAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
- intentFilter.addAction(Intent.ACTION_HDMI_AUDIO_PLUG);
intentFilter.addAction(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG);
intentFilter.addAction(Intent.ACTION_USB_AUDIO_DEVICE_PLUG);
intentFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
@@ -1961,7 +1957,19 @@
deviceList = a2dp.getConnectedDevices();
if (deviceList.size() > 0) {
btDevice = deviceList.get(0);
- handleA2dpConnectionStateChange(btDevice, a2dp.getConnectionState(btDevice));
+ synchronized (mConnectedDevices) {
+ int state = a2dp.getConnectionState(btDevice);
+ int delay = checkSendBecomingNoisyIntent(
+ AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ sendMsg(mAudioHandler,
+ MSG_SET_A2DP_CONNECTION_STATE,
+ SENDMSG_QUEUE,
+ state,
+ 0,
+ btDevice,
+ delay);
+ }
}
break;
@@ -2262,6 +2270,36 @@
return device;
}
+ public void setWiredDeviceConnectionState(int device, int state, String name) {
+ synchronized (mConnectedDevices) {
+ int delay = checkSendBecomingNoisyIntent(device, state);
+ sendMsg(mAudioHandler,
+ MSG_SET_WIRED_DEVICE_CONNECTION_STATE,
+ SENDMSG_QUEUE,
+ device,
+ state,
+ name,
+ delay);
+ }
+ }
+
+ public int setBluetoothA2dpDeviceConnectionState(BluetoothDevice device, int state)
+ {
+ int delay;
+ synchronized (mConnectedDevices) {
+ delay = checkSendBecomingNoisyIntent(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ (state == BluetoothA2dp.STATE_CONNECTED) ? 1 : 0);
+ sendMsg(mAudioHandler,
+ MSG_SET_A2DP_CONNECTION_STATE,
+ SENDMSG_QUEUE,
+ state,
+ 0,
+ device,
+ delay);
+ }
+ return delay;
+ }
+
///////////////////////////////////////////////////////////////////////////
// Inner classes
///////////////////////////////////////////////////////////////////////////
@@ -2959,6 +2997,14 @@
case MSG_BT_HEADSET_CNCT_FAILED:
resetBluetoothSco();
break;
+
+ case MSG_SET_WIRED_DEVICE_CONNECTION_STATE:
+ onSetWiredDeviceConnectionState(msg.arg1, msg.arg2, (String)msg.obj);
+ break;
+
+ case MSG_SET_A2DP_CONNECTION_STATE:
+ onSetA2dpConnectionState((BluetoothDevice)msg.obj, msg.arg1);
+ break;
}
}
}
@@ -3020,7 +3066,6 @@
// must be called synchronized on mConnectedDevices
private void makeA2dpDeviceUnavailableNow(String address) {
- sendBecomingNoisyIntent();
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
AudioSystem.DEVICE_STATE_UNAVAILABLE,
address);
@@ -3050,7 +3095,7 @@
return mAudioHandler.hasMessages(MSG_BTA2DP_DOCK_TIMEOUT);
}
- private void handleA2dpConnectionStateChange(BluetoothDevice btDevice, int state)
+ private void onSetA2dpConnectionState(BluetoothDevice btDevice, int state)
{
if (btDevice == null) {
return;
@@ -3116,6 +3161,76 @@
return false;
}
+ // Devices which removal triggers intent ACTION_AUDIO_BECOMING_NOISY. The intent is only
+ // sent if none of these devices is connected.
+ int mBecomingNoisyIntentDevices =
+ AudioSystem.DEVICE_OUT_WIRED_HEADSET | AudioSystem.DEVICE_OUT_WIRED_HEADPHONE |
+ AudioSystem.DEVICE_OUT_ALL_A2DP;
+
+ // must be called before removing the device from mConnectedDevices
+ private int checkSendBecomingNoisyIntent(int device, int state) {
+ int delay = 0;
+ if ((state == 0) && ((device & mBecomingNoisyIntentDevices) != 0)) {
+ int devices = 0;
+ for (int dev : mConnectedDevices.keySet()) {
+ if ((dev & mBecomingNoisyIntentDevices) != 0) {
+ devices |= dev;
+ }
+ }
+ if (devices == device) {
+ delay = 1000;
+ sendBecomingNoisyIntent();
+ }
+ }
+
+ if (mAudioHandler.hasMessages(MSG_SET_A2DP_CONNECTION_STATE) ||
+ mAudioHandler.hasMessages(MSG_SET_WIRED_DEVICE_CONNECTION_STATE)) {
+ delay = 1000;
+ }
+ return delay;
+ }
+
+ private void sendDeviceConnectionIntent(int device, int state, String name)
+ {
+ Intent intent = new Intent();
+
+ intent.putExtra("state", state);
+ intent.putExtra("name", name);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+
+ if (device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) {
+ intent.setAction(Intent.ACTION_HEADSET_PLUG);
+ intent.putExtra("microphone", 1);
+ } else if (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE) {
+ intent.setAction(Intent.ACTION_HEADSET_PLUG);
+ intent.putExtra("microphone", 0);
+ } else if (device == AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET) {
+ intent.setAction(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
+ } else if (device == AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET) {
+ intent.setAction(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
+ } else if (device == AudioSystem.DEVICE_OUT_AUX_DIGITAL) {
+ intent.setAction(Intent.ACTION_HDMI_AUDIO_PLUG);
+ }
+
+ ActivityManagerNative.broadcastStickyIntent(intent, null);
+ }
+
+ private void onSetWiredDeviceConnectionState(int device, int state, String name)
+ {
+ synchronized (mConnectedDevices) {
+ if ((state == 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
+ (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
+ setBluetoothA2dpOnInt(true);
+ }
+ handleDeviceConnection((state == 1), device, "");
+ if ((state != 0) && ((device == AudioSystem.DEVICE_OUT_WIRED_HEADSET) ||
+ (device == AudioSystem.DEVICE_OUT_WIRED_HEADPHONE))) {
+ setBluetoothA2dpOnInt(false);
+ }
+ sendDeviceConnectionIntent(device, state, name);
+ }
+ }
+
/* cache of the address of the last dock the device was connected to */
private String mDockAddress;
@@ -3151,12 +3266,6 @@
config = AudioSystem.FORCE_NONE;
}
AudioSystem.setForceUse(AudioSystem.FOR_DOCK, config);
- } else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
- state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
- BluetoothProfile.STATE_DISCONNECTED);
- BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
-
- handleA2dpConnectionStateChange(btDevice, state);
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,
BluetoothProfile.STATE_DISCONNECTED);
@@ -3197,43 +3306,9 @@
}
}
}
- } else if (action.equals(Intent.ACTION_HEADSET_PLUG)) {
- state = intent.getIntExtra("state", 0);
- int microphone = intent.getIntExtra("microphone", 0);
-
- if (microphone != 0) {
- device = AudioSystem.DEVICE_OUT_WIRED_HEADSET;
- } else {
- device = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
- }
- // enable A2DP before notifying headset disconnection to avoid glitches
- if (state == 0) {
- setBluetoothA2dpOnInt(true);
- }
- handleDeviceConnection((state == 1), device, "");
- // disable A2DP after notifying headset connection to avoid glitches
- if (state != 0) {
- setBluetoothA2dpOnInt(false);
- }
- } else if (action.equals(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG)) {
- state = intent.getIntExtra("state", 0);
- Log.v(TAG, "Broadcast Receiver: Got ACTION_ANALOG_AUDIO_DOCK_PLUG, state = "+state);
- handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, "");
- } else if (action.equals(Intent.ACTION_HDMI_AUDIO_PLUG)) {
- state = intent.getIntExtra("state", 0);
- Log.v(TAG, "Broadcast Receiver: Got ACTION_HDMI_AUDIO_PLUG, state = "+state);
- handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_AUX_DIGITAL, "");
- } else if (action.equals(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG)) {
- state = intent.getIntExtra("state", 0);
- Log.v(TAG,
- "Broadcast Receiver Got ACTION_DIGITAL_AUDIO_DOCK_PLUG, state = " + state);
- handleDeviceConnection((state == 1), AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, "");
} else if (action.equals(Intent.ACTION_USB_AUDIO_ACCESSORY_PLUG) ||
action.equals(Intent.ACTION_USB_AUDIO_DEVICE_PLUG)) {
state = intent.getIntExtra("state", 0);
- if (state == 0) {
- sendBecomingNoisyIntent();
- }
int alsaCard = intent.getIntExtra("card", -1);
int alsaDevice = intent.getIntExtra("device", -1);
String params = (alsaCard == -1 && alsaDevice == -1 ? ""
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 7fbe28c..133f30b 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -17,6 +17,7 @@
package android.media;
import android.app.PendingIntent;
+import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
import android.media.IAudioFocusDispatcher;
import android.media.IRemoteControlClient;
@@ -133,4 +134,7 @@
void setRingtonePlayer(IRingtonePlayer player);
IRingtonePlayer getRingtonePlayer();
int getMasterStreamType();
+
+ void setWiredDeviceConnectionState(int device, int state, String name);
+ int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state);
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
index 62462bd..6995c60 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -415,59 +415,61 @@
output.write("Total number of loops: " + NUMBER_OF_TIME_LAPSE_LOOPS + "\n");
try {
- output.write("No of loop: ");
- for (int i = 0; i < NUMBER_OF_TIME_LAPSE_LOOPS; i++) {
- filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
- Log.v(TAG, filename);
- runOnLooper(new Runnable() {
- @Override
- public void run() {
- mRecorder = new MediaRecorder();
+ for (int j = 0, n = Camera.getNumberOfCameras(); j < n; j++) {
+ output.write("No of loop: camera " + j);
+ for (int i = 0; i < NUMBER_OF_TIME_LAPSE_LOOPS; i++) {
+ filename = OUTPUT_FILE + j + "_" + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ runOnLooper(new Runnable() {
+ @Override
+ public void run() {
+ mRecorder = new MediaRecorder();
+ }
+ });
+
+ // Set callback
+ mRecorder.setOnErrorListener(mRecorderErrorCallback);
+
+ // Set video source
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+
+ // Set camcorder profile for time lapse
+ CamcorderProfile profile =
+ CamcorderProfile.get(j, CamcorderProfile.QUALITY_TIME_LAPSE_HIGH);
+ mRecorder.setProfile(profile);
+
+ // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc.
+ // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video
+ mRecorder.setCaptureRate(captureRate);
+
+ // Set output file
+ mRecorder.setOutputFile(filename);
+
+ // Set the preview display
+ Log.v(TAG, "mediaRecorder setPreviewDisplay");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+
+ mRecorder.prepare();
+ mRecorder.start();
+ Thread.sleep(record_duration);
+ Log.v(TAG, "Before stop");
+ mRecorder.stop();
+ mRecorder.release();
+
+ // Start the playback
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filename);
+ mp.setDisplay(mSurfaceHolder);
+ mp.prepare();
+ mp.start();
+ Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME);
+ mp.release();
+ validateRecordedVideo(filename);
+ if (remove_video) {
+ removeRecordedVideo(filename);
}
- });
-
- // Set callback
- mRecorder.setOnErrorListener(mRecorderErrorCallback);
-
- // Set video source
- mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-
- // Set camcorder profile for time lapse
- CamcorderProfile profile =
- CamcorderProfile.get(CamcorderProfile.QUALITY_TIME_LAPSE_HIGH);
- mRecorder.setProfile(profile);
-
- // Set the timelapse setting; 0.1 = 10 sec timelapse, 0.5 = 2 sec timelapse, etc.
- // http://developer.android.com/guide/topics/media/camera.html#time-lapse-video
- mRecorder.setCaptureRate(captureRate);
-
- // Set output file
- mRecorder.setOutputFile(filename);
-
- // Set the preview display
- Log.v(TAG, "mediaRecorder setPreviewDisplay");
- mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
-
- mRecorder.prepare();
- mRecorder.start();
- Thread.sleep(record_duration);
- Log.v(TAG, "Before stop");
- mRecorder.stop();
- mRecorder.release();
-
- // Start the playback
- MediaPlayer mp = new MediaPlayer();
- mp.setDataSource(filename);
- mp.setDisplay(mSurfaceHolder);
- mp.prepare();
- mp.start();
- Thread.sleep(TIME_LAPSE_PLAYBACK_WAIT_TIME);
- mp.release();
- validateRecordedVideo(filename);
- if(remove_video) {
- removeRecordedVideo(filename);
+ output.write(", " + i);
}
- output.write(", " + i);
}
}
catch (IllegalStateException e) {
diff --git a/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
index 8a0a30f..ff0bd4c 100644
--- a/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/notification_panel_bg.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
index 25f15e6..2bbb2c6 100644
--- a/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-mdpi/notification_panel_bg.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
index 2ff93d3..e7caeda 100644
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/notification_panel_bg.9.png
+++ 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
index 430f913..ae07083 100644
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/notification_panel_bg.9.png
+++ 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
index 807241a..8423ef9 100644
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/notification_panel_bg.9.png
+++ 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
index 2ff93d3..0c20ba2 100644
--- a/packages/SystemUI/res/drawable-sw720dp-hdpi/notification_panel_bg.9.png
+++ 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
index 430f913..56cd238 100644
--- a/packages/SystemUI/res/drawable-sw720dp-mdpi/notification_panel_bg.9.png
+++ 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
index 807241a..3f05767 100644
--- a/packages/SystemUI/res/drawable-sw720dp-xhdpi/notification_panel_bg.9.png
+++ 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
index 60e7418..932e0ef 100644
--- a/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
+++ b/packages/SystemUI/res/drawable-xhdpi/notification_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 6433cd3..ca29738 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -145,6 +145,6 @@
<string name="notifications_off_title" msgid="8936620513608443224">"通知功能已停用"</string>
<string name="notifications_off_text" msgid="2529001315769385273">"点按此处可重新启用通知功能。"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
- <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"屏幕锁定为横向浏览模式。"</string>
- <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"屏幕已锁定为纵向浏览模式。"</string>
+ <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"屏幕锁定为横向模式。"</string>
+ <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"屏幕锁定为纵向模式。"</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
index 1db2a7f..73249b4 100644
--- a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
+++ b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
@@ -58,8 +58,8 @@
@Override
public void onReceive(Context context, Intent intent) {
final boolean activateOnDock = 0 != Settings.Secure.getInt(
- context.getContentResolver(),
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 1);
+ context.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, 0);
if (!activateOnDock) return;
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 89bf3b6..587bfe8 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -309,7 +309,7 @@
// if there are no apps, either bring up a "No recent apps" message, or just
// quit early
- boolean noApps = (mRecentTaskDescriptions.size() == 0);
+ boolean noApps = !mFirstScreenful && (mRecentTaskDescriptions.size() == 0);
if (mRecentsNoApps != null) {
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 3c71784..f682203 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -101,6 +101,9 @@
}
final View view = mAdapter.getView(i, old, mLinearLayout);
+ if (view.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
if (mPerformanceHelper != null) {
mPerformanceHelper.addViewCallback(view);
@@ -139,6 +142,9 @@
thumbnailView.setClickable(true);
thumbnailView.setOnClickListener(launchAppListener);
thumbnailView.setOnLongClickListener(longClickListener);
+ if (view.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
// We don't want to dismiss recents if a user clicks on the app title
// (we also don't want to launch the app either, though, because the
@@ -148,6 +154,9 @@
appTitle.setOnTouchListener(noOpListener);
final View calloutLine = view.findViewById(R.id.recents_callout_line);
calloutLine.setOnTouchListener(noOpListener);
+ if (view.getParent() != null) {
+ throw new RuntimeException("Recycled child has parent");
+ }
mLinearLayout.addView(view);
}
diff --git a/policy/src/com/android/internal/policy/impl/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
index 737ea47..22b854e 100644
--- a/policy/src/com/android/internal/policy/impl/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/FaceUnlock.java
@@ -468,7 +468,8 @@
if (!mServiceRunning) {
Log.d(TAG, "Starting Face Unlock");
try {
- mService.startUi(windowToken, x, y, w, h, false);
+ mService.startUi(windowToken, x, y, w, h,
+ mLockPatternUtils.isBiometricWeakLivelinessEnabled());
} catch (RemoteException e) {
Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
return;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index cce55d5..1033296 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2278,7 +2278,12 @@
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
int top = displayHeight - mNavigationBarHeightForRotation[displayRotation];
if (mHdmiPlugged) {
- if (top > mExternalDisplayHeight) {
+ // Move the nav bar up if the external display is the same aspect ratio
+ // but shorter. This avoids clipping on the external display.
+ boolean sameAspect = mExternalDisplayHeight > 0 && displayHeight > 0
+ && ((float) mExternalDisplayWidth / mExternalDisplayHeight > 1)
+ == ((float) displayWidth / displayHeight > 1);
+ if (sameAspect && top > mExternalDisplayHeight) {
top = mExternalDisplayHeight;
}
}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 38e08ae..469b4f1 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -2242,7 +2242,9 @@
} else {
newValue = endValue;
mHighestLightSensorValue = endSensorValue;
- mInitialAnimation = false;
+ if (endValue > 0) {
+ mInitialAnimation = false;
+ }
}
if (mDebugLightAnimation) {
@@ -2290,7 +2292,7 @@
currentMask = mask;
duration = (int) (mWindowScaleAnimation * animationDuration);
startTimeMillis = SystemClock.elapsedRealtime();
- mInitialAnimation = currentValue == 0 && target > 0;
+ mInitialAnimation = mInitialAnimation && target > 0;
if (mDebugLightAnimation) {
Slog.v(TAG, "animateTo(target=" + target
@@ -2608,7 +2610,8 @@
}
};
- private boolean mInitialAnimation; // used to prevent lightsensor changes while turning on
+ /** used to prevent lightsensor changes while turning on. */
+ private boolean mInitialAnimation = true;
private void dockStateChanged(int state) {
synchronized (mLocks) {
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index c936ef9..d1f92a7 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -65,7 +65,7 @@
// Enable launching of applications when entering the dock.
private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
- private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = false;
+ private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = true;
private static final int MSG_UPDATE_TWILIGHT = 0;
private static final int MSG_ENABLE_LOCATION_UPDATES = 1;
@@ -120,7 +120,7 @@
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
return intent;
}
-
+
// The broadcast receiver which receives the result of the ordered broadcast sent when
// the dock state changes. The original ordered broadcast is sent with an initial result
// code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
@@ -130,7 +130,7 @@
public void onReceive(Context context, Intent intent) {
if (getResultCode() != Activity.RESULT_OK) {
if (LOG) {
- Slog.v(TAG, "Handling broadcast result for action " + intent.getAction()
+ Slog.v(TAG, "Handling broadcast result for action " + intent.getAction()
+ ": canceled: " + getResultCode());
}
return;
@@ -138,7 +138,7 @@
final int enableFlags = intent.getIntExtra("enableFlags", 0);
final int disableFlags = intent.getIntExtra("disableFlags", 0);
-
+
synchronized (mLock) {
// Launch a dock activity
String category = null;
@@ -166,15 +166,15 @@
if (LOG) {
Slog.v(TAG, String.format(
- "Handling broadcast result for action %s: enable=0x%08x disable=0x%08x category=%s",
+ "Handling broadcast result for action %s: enable=0x%08x disable=0x%08x category=%s",
intent.getAction(), enableFlags, disableFlags, category));
}
-
+
if (category != null) {
// This is the new activity that will serve as home while
// we are in care mode.
Intent homeIntent = buildHomeIntent(category);
-
+
// Now we are going to be careful about switching the
// configuration and starting the activity -- we need to
// do this in a specific order under control of the
@@ -479,8 +479,8 @@
}
if (LOG) {
- Slog.d(TAG,
- "updateConfigurationLocked: mDockState=" + mDockState
+ Slog.d(TAG,
+ "updateConfigurationLocked: mDockState=" + mDockState
+ "; mCarMode=" + mCarModeEnabled
+ "; mNightMode=" + mNightMode
+ "; uiMode=" + uiMode);
@@ -657,7 +657,7 @@
boolean mNetworkListenerEnabled;
boolean mDidFirstInit;
long mLastNetworkRegisterTime = -MIN_LOCATION_UPDATE_MS;
-
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -682,12 +682,12 @@
// since we last requested an update.
return;
}
-
+
// Unregister the current location monitor, so we can
// register a new one for it to get an immediate update.
mNetworkListenerEnabled = false;
mLocationManager.removeUpdates(mEmptyLocationListener);
-
+
// Fall through to re-register listener.
case MSG_ENABLE_LOCATION_UPDATES:
// enable network provider to receive at least location updates for a given
diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java
index 53d1f0e..96ac493 100644
--- a/services/java/com/android/server/WiredAccessoryObserver.java
+++ b/services/java/com/android/server/WiredAccessoryObserver.java
@@ -139,11 +139,14 @@
private final Context mContext;
private final WakeLock mWakeLock; // held while there is a pending route change
+ private final AudioManager mAudioManager;
+
public WiredAccessoryObserver(Context context) {
mContext = context;
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryObserver");
mWakeLock.setReferenceCounted(false);
+ mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
context.registerReceiver(new BootCompletedReceiver(),
new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
@@ -250,106 +253,65 @@
mPrevHeadsetState = mHeadsetState;
mHeadsetState = headsetState;
- if (headsetState == 0) {
- if (mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_sendAudioBecomingNoisy)) {
- Intent intent = new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
- mContext.sendBroadcast(intent);
- }
-
- // It can take hundreds of ms flush the audio pipeline after
- // apps pause audio playback, but audio route changes are
- // immediate, so delay the route change by 1000ms.
- // This could be improved once the audio sub-system provides an
- // interface to clear the audio pipeline.
- delay = 1000;
- } else {
- // Insert the same delay for headset connection so that the connection event is not
- // broadcast before the disconnection event in case of fast removal/insertion
- if (mHandler.hasMessages(0)) {
- delay = 1000;
- }
- }
mWakeLock.acquire();
- mHandler.sendMessageDelayed(mHandler.obtainMessage(0,
- mHeadsetState,
- mPrevHeadsetState,
- mHeadsetName),
- delay);
+ mHandler.sendMessage(mHandler.obtainMessage(0,
+ mHeadsetState,
+ mPrevHeadsetState,
+ mHeadsetName));
}
- private synchronized final void sendIntents(int headsetState, int prevHeadsetState, String headsetName) {
+ private synchronized final void setDevicesState(int headsetState,
+ int prevHeadsetState,
+ String headsetName) {
int allHeadsets = SUPPORTED_HEADSETS;
for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
if ((curHeadset & allHeadsets) != 0) {
- sendIntent(curHeadset, headsetState, prevHeadsetState, headsetName);
+ setDeviceState(curHeadset, headsetState, prevHeadsetState, headsetName);
allHeadsets &= ~curHeadset;
}
}
}
- private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) {
+ private final void setDeviceState(int headset,
+ int headsetState,
+ int prevHeadsetState,
+ String headsetName) {
if ((headsetState & headset) != (prevHeadsetState & headset)) {
+ int device;
+ int state;
- int state = 0;
if ((headsetState & headset) != 0) {
state = 1;
+ } else {
+ state = 0;
}
- if((headset == BIT_USB_HEADSET_ANLG) || (headset == BIT_USB_HEADSET_DGTL) ||
- (headset == BIT_HDMI_AUDIO)) {
- Intent intent;
- // Pack up the values and broadcast them to everyone
- if (headset == BIT_USB_HEADSET_ANLG) {
- intent = new Intent(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- } else if (headset == BIT_USB_HEADSET_DGTL) {
- intent = new Intent(Intent.ACTION_DIGITAL_AUDIO_DOCK_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- } else if (headset == BIT_HDMI_AUDIO) {
- intent = new Intent(Intent.ACTION_HDMI_AUDIO_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- }
-
- if (LOG) Slog.v(TAG, "Intent.ACTION_USB_HEADSET_PLUG: state: "+state+" name: "+headsetName);
- // TODO: Should we require a permission?
+ if (headset == BIT_HEADSET) {
+ device = AudioManager.DEVICE_OUT_WIRED_HEADSET;
+ } else if (headset == BIT_HEADSET_NO_MIC){
+ device = AudioManager.DEVICE_OUT_WIRED_HEADPHONE;
+ } else if (headset == BIT_USB_HEADSET_ANLG) {
+ device = AudioManager.DEVICE_OUT_ANLG_DOCK_HEADSET;
+ } else if (headset == BIT_USB_HEADSET_DGTL) {
+ device = AudioManager.DEVICE_OUT_DGTL_DOCK_HEADSET;
+ } else if (headset == BIT_HDMI_AUDIO) {
+ device = AudioManager.DEVICE_OUT_AUX_DIGITAL;
+ } else {
+ Slog.e(TAG, "setDeviceState() invalid headset type: "+headset);
+ return;
}
- if((headset == BIT_HEADSET) || (headset == BIT_HEADSET_NO_MIC)) {
- // Pack up the values and broadcast them to everyone
- Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- //int state = 0;
- int microphone = 0;
+ if (LOG)
+ Slog.v(TAG, "device "+headsetName+((state == 1) ? " connected" : " disconnected"));
- if ((headset & HEADSETS_WITH_MIC) != 0) {
- microphone = 1;
- }
-
- intent.putExtra("state", state);
- intent.putExtra("name", headsetName);
- intent.putExtra("microphone", microphone);
-
- if (LOG) Slog.v(TAG, "Intent.ACTION_HEADSET_PLUG: state: "+state+" name: "+headsetName+" mic: "+microphone);
- // TODO: Should we require a permission?
- ActivityManagerNative.broadcastStickyIntent(intent, null);
- }
+ mAudioManager.setWiredDeviceConnectionState(device, state, headsetName);
}
}
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- sendIntents(msg.arg1, msg.arg2, (String)msg.obj);
+ setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
mWakeLock.release();
}
};
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 039efbd..3e8f512 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -104,10 +104,14 @@
private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
"registerUiTestAutomationService";
+ private static final char COMPONENT_NAME_SEPARATOR = ':';
+
private static final int OWN_PROCESS_ID = android.os.Process.myPid();
private static final int MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG = 1;
+ private static final int MSG_TOGGLE_TOUCH_EXPLORATION = 2;
+
private static int sIdCounter = 0;
private static int sNextWindowId;
@@ -127,12 +131,14 @@
private final Set<ComponentName> mEnabledServices = new HashSet<ComponentName>();
+ private final Set<ComponentName> mTouchExplorationGrantedServices = new HashSet<ComponentName>();
+
private final SparseArray<AccessibilityConnectionWrapper> mWindowIdToInteractionConnectionWrapperMap =
new SparseArray<AccessibilityConnectionWrapper>();
private final SparseArray<IBinder> mWindowIdToWindowTokenMap = new SparseArray<IBinder>();
- private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(':');
+ private final SimpleStringSplitter mStringColonSplitter = new SimpleStringSplitter(COMPONENT_NAME_SEPARATOR);
private final Rect mTempRect = new Rect();
@@ -164,6 +170,8 @@
private boolean mTouchExplorationGestureStarted;
+ private AlertDialog mEnableTouchExplorationDialog;
+
/**
* Creates a new instance.
*
@@ -208,7 +216,16 @@
String compPkg = comp.getPackageName();
if (compPkg.equals(packageName)) {
it.remove();
- updateEnabledAccessibilitySerivcesSettingLocked(mEnabledServices);
+ // Update the enabled services setting.
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
+ // Update the touch exploration granted services setting.
+ mTouchExplorationGrantedServices.remove(comp);
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.
+ TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
return;
}
}
@@ -219,7 +236,6 @@
public boolean onHandleForceStop(Intent intent, String[] packages,
int uid, boolean doit) {
synchronized (mLock) {
- boolean changed = false;
Iterator<ComponentName> it = mEnabledServices.iterator();
while (it.hasNext()) {
ComponentName comp = it.next();
@@ -230,13 +246,12 @@
return true;
}
it.remove();
- changed = true;
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
}
}
}
- if (changed) {
- updateEnabledAccessibilitySerivcesSettingLocked(mEnabledServices);
- }
return false;
}
}
@@ -248,33 +263,19 @@
// We will update when the automation service dies.
if (mUiAutomationService == null) {
populateAccessibilityServiceListLocked();
+ populateEnabledAccessibilityServicesLocked();
+ populateTouchExplorationGrantedAccessibilityServicesLocked();
handleAccessibilityEnabledSettingChangedLocked();
handleTouchExplorationEnabledSettingChangedLocked();
updateInputFilterLocked();
sendStateToClientsLocked();
}
}
-
return;
}
super.onReceive(context, intent);
}
-
- private void updateEnabledAccessibilitySerivcesSettingLocked(
- Set<ComponentName> enabledServices) {
- Iterator<ComponentName> it = enabledServices.iterator();
- StringBuilder str = new StringBuilder();
- while (it.hasNext()) {
- if (str.length() > 0) {
- str.append(':');
- }
- str.append(it.next().flattenToShortString());
- }
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- str.toString());
- }
};
// package changes
@@ -338,6 +339,25 @@
synchronized (mLock) {
// We will update when the automation service dies.
if (mUiAutomationService == null) {
+ populateEnabledAccessibilityServicesLocked();
+ manageServicesLocked();
+ }
+ }
+ }
+ });
+
+ Uri touchExplorationGrantedServicesUri = Settings.Secure.getUriFor(
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
+ contentResolver.registerContentObserver(touchExplorationGrantedServicesUri, false,
+ new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+ synchronized (mLock) {
+ // We will update when the automation service dies.
+ if (mUiAutomationService == null) {
+ populateTouchExplorationGrantedAccessibilityServicesLocked();
+ unbindAllServicesLocked();
manageServicesLocked();
}
}
@@ -647,6 +667,18 @@
}
}
+ private void populateEnabledAccessibilityServicesLocked() {
+ populateComponentNamesFromSettingLocked(
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mEnabledServices);
+ }
+
+ private void populateTouchExplorationGrantedAccessibilityServicesLocked() {
+ populateComponentNamesFromSettingLocked(
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ mTouchExplorationGrantedServices);
+ }
+
/**
* Performs {@link AccessibilityService}s delayed notification. The delay is configurable
* and denotes the period after the last event before notifying the service.
@@ -689,7 +721,7 @@
mServices.add(service);
mComponentNameToServiceMap.put(service.mComponentName, service);
updateInputFilterLocked();
- tryEnableTouchExploration(service);
+ tryEnableTouchExplorationLocked(service);
} catch (RemoteException e) {
/* do nothing */
}
@@ -710,7 +742,7 @@
service.unlinkToOwnDeath();
service.dispose();
updateInputFilterLocked();
- tryDisableTouchExploration(service);
+ tryDisableTouchExplorationLocked(service);
return removed;
}
@@ -762,7 +794,6 @@
* Manages services by starting enabled ones and stopping disabled ones.
*/
private void manageServicesLocked() {
- populateEnabledServicesLocked(mEnabledServices);
final int enabledInstalledServicesCount = updateServicesStateLocked(mInstalledServices,
mEnabledServices);
// No enabled installed services => disable accessibility to avoid
@@ -789,20 +820,21 @@
}
/**
- * Populates a list with the {@link ComponentName}s of all enabled
- * {@link AccessibilityService}s.
+ * Populates a set with the {@link ComponentName}s stored in a colon
+ * separated value setting.
*
- * @param enabledServices The list.
+ * @param settingName The setting to parse.
+ * @param outComponentNames The output component names.
*/
- private void populateEnabledServicesLocked(Set<ComponentName> enabledServices) {
- enabledServices.clear();
+ private void populateComponentNamesFromSettingLocked(String settingName,
+ Set<ComponentName> outComponentNames) {
+ outComponentNames.clear();
- String servicesValue = Settings.Secure.getString(mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
+ String settingValue = Settings.Secure.getString(mContext.getContentResolver(), settingName);
- if (servicesValue != null) {
+ if (settingValue != null) {
TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
- splitter.setString(servicesValue);
+ splitter.setString(settingValue);
while (splitter.hasNext()) {
String str = splitter.next();
if (str == null || str.length() <= 0) {
@@ -810,13 +842,32 @@
}
ComponentName enabledService = ComponentName.unflattenFromString(str);
if (enabledService != null) {
- enabledServices.add(enabledService);
+ outComponentNames.add(enabledService);
}
}
}
}
/**
+ * Persists the component names in the specified setting in a
+ * colon separated fashion.
+ *
+ * @param settingName The setting name.
+ * @param componentNames The component names.
+ */
+ private void persistComponentNamesToSettingLocked(String settingName,
+ Set<ComponentName> componentNames) {
+ StringBuilder builder = new StringBuilder();
+ for (ComponentName componentName : componentNames) {
+ if (builder.length() > 0) {
+ builder.append(COMPONENT_NAME_SEPARATOR);
+ }
+ builder.append(componentName.flattenToShortString());
+ }
+ Settings.Secure.putString(mContext.getContentResolver(), settingName, builder.toString());
+ }
+
+ /**
* Updates the state of each service by starting (or keeping running) enabled ones and
* stopping the rest.
*
@@ -935,20 +986,21 @@
Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
}
- private void tryEnableTouchExploration(final Service service) {
+ private void tryEnableTouchExplorationLocked(final Service service) {
if (!mIsTouchExplorationEnabled && service.mRequestTouchExplorationMode) {
- if (!service.mIsAutomation) {
+ final boolean canToggleTouchExploration = mTouchExplorationGrantedServices.contains(
+ service.mComponentName);
+ if (!service.mIsAutomation && !canToggleTouchExploration) {
mMainHandler.obtainMessage(MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG,
service).sendToTarget();
} else {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
+ mMainHandler.obtainMessage(MSG_TOGGLE_TOUCH_EXPLORATION, 1, 0).sendToTarget();
}
}
}
- private void tryDisableTouchExploration(Service service) {
- if (mIsTouchExplorationEnabled && service.mReqeustTouchExplorationMode) {
+ private void tryDisableTouchExplorationLocked(Service service) {
+ if (mIsTouchExplorationEnabled) {
synchronized (mLock) {
final int serviceCount = mServices.size();
for (int i = 0; i < serviceCount; i++) {
@@ -957,8 +1009,7 @@
return;
}
}
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0);
+ mMainHandler.obtainMessage(MSG_TOGGLE_TOUCH_EXPLORATION, 0, 0).sendToTarget();
}
}
}
@@ -995,32 +1046,54 @@
public void handleMessage(Message msg) {
final int type = msg.what;
switch (type) {
+ case MSG_TOGGLE_TOUCH_EXPLORATION: {
+ final int value = msg.arg1;
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED, value);
+ } break;
case MSG_SHOW_ENABLE_TOUCH_EXPLORATION_DIALOG: {
- Service service = (Service) msg.obj;
+ final Service service = (Service) msg.obj;
String label = service.mResolveInfo.loadLabel(
mContext.getPackageManager()).toString();
- final AlertDialog dialog = new AlertDialog.Builder(mContext)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setPositiveButton(android.R.string.ok, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
- }
- })
- .setNegativeButton(android.R.string.cancel, new OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- })
- .setTitle(R.string.enable_explore_by_touch_warning_title)
- .setMessage(mContext.getString(
- R.string.enable_explore_by_touch_warning_message, label))
- .create();
- dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
- dialog.setCanceledOnTouchOutside(true);
- dialog.show();
+ synchronized (mLock) {
+ if (mIsTouchExplorationEnabled) {
+ return;
+ }
+ if (mEnableTouchExplorationDialog != null
+ && mEnableTouchExplorationDialog.isShowing()) {
+ return;
+ }
+ mEnableTouchExplorationDialog = new AlertDialog.Builder(mContext)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .setPositiveButton(android.R.string.ok, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // The user allowed the service to toggle touch exploration.
+ mTouchExplorationGrantedServices.add(service.mComponentName);
+ persistComponentNamesToSettingLocked(
+ Settings.Secure.
+ TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ mTouchExplorationGrantedServices);
+ // Enable touch exploration.
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
+ }
+ })
+ .setNegativeButton(android.R.string.cancel, new OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
+ }
+ })
+ .setTitle(R.string.enable_explore_by_touch_warning_title)
+ .setMessage(mContext.getString(
+ R.string.enable_explore_by_touch_warning_message, label))
+ .create();
+ mEnableTouchExplorationDialog.getWindow().setType(
+ WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
+ mEnableTouchExplorationDialog.setCanceledOnTouchOutside(true);
+ mEnableTouchExplorationDialog.show();
+ }
}
}
}
@@ -1143,8 +1216,16 @@
mRequestTouchExplorationMode = (info.flags
& AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE) != 0;
+ // If this service is up and running we may have to enable touch
+ // exploration, otherwise this will happen when the service connects.
synchronized (mLock) {
- tryAddServiceLocked(this);
+ if (isConfigured()) {
+ if (mRequestTouchExplorationMode) {
+ tryEnableTouchExplorationLocked(this);
+ } else {
+ tryDisableTouchExplorationLocked(this);
+ }
+ }
}
}
@@ -1496,6 +1577,9 @@
if (mIsAutomation) {
mUiAutomationService = null;
+ populateEnabledAccessibilityServicesLocked();
+ populateTouchExplorationGrantedAccessibilityServicesLocked();
+
handleAccessibilityEnabledSettingChangedLocked();
sendStateToClientsLocked();
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index b0b2b8d..4c38ab9 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -1532,7 +1532,7 @@
*/
public ReceivedPointerTracker(Context context) {
mThresholdActivePointer =
- ViewConfiguration.get(context).getScaledTouchSlop() * COEFFICIENT_ACTIVE_POINTER;
+ ViewConfiguration.get(context).getScaledTouchSlop() * COEFFICIENT_ACTIVE_POINTER;//Heie govna
}
/**
diff --git a/services/java/com/android/server/am/ContentProviderConnection.java b/services/java/com/android/server/am/ContentProviderConnection.java
index 84f8f02..7f69b24 100644
--- a/services/java/com/android/server/am/ContentProviderConnection.java
+++ b/services/java/com/android/server/am/ContentProviderConnection.java
@@ -17,6 +17,8 @@
package com.android.server.am;
import android.os.Binder;
+import android.os.SystemClock;
+import android.util.TimeUtils;
/**
* Represents a link between a content provider and client.
@@ -24,6 +26,7 @@
public class ContentProviderConnection extends Binder {
public final ContentProviderRecord provider;
public final ProcessRecord client;
+ public final long createTime;
public int stableCount;
public int unstableCount;
// The client of this connection is currently waiting for the provider to appear.
@@ -39,6 +42,7 @@
public ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client) {
provider = _provider;
client = _client;
+ createTime = SystemClock.elapsedRealtime();
}
public String toString() {
@@ -83,5 +87,8 @@
if (dead) {
sb.append(" DEAD");
}
+ long nowReal = SystemClock.elapsedRealtime();
+ sb.append(" ");
+ TimeUtils.formatDuration(nowReal-createTime, sb);
}
}
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index d85facc..bdd0aa4 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -592,7 +592,7 @@
deviceIdAndGeneration[i * 2] = inputDevice.getId();
deviceIdAndGeneration[i * 2 + 1] = inputDevice.getGeneration();
- if (isFullKeyboard(inputDevice)) {
+ if (!inputDevice.isVirtual() && inputDevice.isFullKeyboard()) {
if (!containsInputDeviceWithDescriptor(oldInputDevices,
inputDevice.getDescriptor())) {
mTempFullKeyboards.add(numFullKeyboardsAdded++, inputDevice);
@@ -695,12 +695,6 @@
reloadKeyboardLayouts();
}
- private static boolean isFullKeyboard(InputDevice inputDevice) {
- return !inputDevice.isVirtual()
- && (inputDevice.getSources() & InputDevice.SOURCE_KEYBOARD) != 0
- && inputDevice.getKeyboardType() == InputDevice.KEYBOARD_TYPE_ALPHABETIC;
- }
-
private static boolean containsInputDeviceWithDescriptor(InputDevice[] inputDevices,
String descriptor) {
final int numDevices = inputDevices.length;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 4ce8c97..10919f2 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -6466,17 +6466,18 @@
WindowManagerPolicy.PRESENCE_INTERNAL;
if (mIsTouchDevice) {
- if ((sources & InputDevice.SOURCE_TOUCHSCREEN) != 0) {
+ if ((sources & InputDevice.SOURCE_TOUCHSCREEN) ==
+ InputDevice.SOURCE_TOUCHSCREEN) {
config.touchscreen = Configuration.TOUCHSCREEN_FINGER;
}
} else {
config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
}
- if ((sources & InputDevice.SOURCE_TRACKBALL) != 0) {
+ if ((sources & InputDevice.SOURCE_TRACKBALL) == InputDevice.SOURCE_TRACKBALL) {
config.navigation = Configuration.NAVIGATION_TRACKBALL;
navigationPresence |= presenceFlag;
- } else if ((sources & InputDevice.SOURCE_DPAD) != 0
+ } else if ((sources & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD
&& config.navigation == Configuration.NAVIGATION_NONAV) {
config.navigation = Configuration.NAVIGATION_DPAD;
navigationPresence |= presenceFlag;
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 04ec820..9e5e84b 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -226,7 +226,7 @@
ALOGD("nuSensorService thread starting...");
const size_t numEventMax = 16;
- const size_t minBufferSize = numEventMax * mVirtualSensorList.size();
+ const size_t minBufferSize = numEventMax + numEventMax * mVirtualSensorList.size();
sensors_event_t buffer[minBufferSize];
sensors_event_t scratch[minBufferSize];
SensorDevice& device(SensorDevice::getInstance());
diff --git a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
index 5220d04..1a42f93 100644
--- a/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiWatchdogStateMachine.java
@@ -263,12 +263,19 @@
Context.CONNECTIVITY_SERVICE);
sWifiOnly = (cm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false);
- // Disable for wifi only devices.
- if (Settings.Secure.getString(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON) == null
- && sWifiOnly) {
- log("Disabling watchog for wi-fi only device");
- putSettingsBoolean(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON, false);
+ // Watchdog is always enabled. Poor network detection & walled garden detection
+ // can individually be turned on/off
+ // TODO: Remove this setting & clean up state machine since we always have
+ // watchdog in an enabled state
+ putSettingsBoolean(contentResolver, Settings.Secure.WIFI_WATCHDOG_ON, true);
+
+ // Disable poor network avoidance, but keep watchdog active for walled garden detection
+ if (sWifiOnly) {
+ log("Disabling poor network avoidance for wi-fi only device");
+ putSettingsBoolean(contentResolver,
+ Settings.Secure.WIFI_WATCHDOG_POOR_NETWORK_TEST_ENABLED, false);
}
+
WifiWatchdogStateMachine wwsm = new WifiWatchdogStateMachine(context);
wwsm.start();
return wwsm;