Merge "Invalid active window if temporary disabling accessibility for test tools." into lmp-dev
diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
index e19f587..fcf172c 100644
--- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
+++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java
@@ -336,8 +336,16 @@
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(cameraId, info);
+ Camera.Parameters legacyParameters = null;
+ try {
+ legacyParameters = legacyCamera.getParameters();
+ } catch (RuntimeException e) {
+ throw new CameraRuntimeException(CameraAccessException.CAMERA_ERROR,
+ "Unable to get initial parameters", e);
+ }
+
CameraCharacteristics characteristics =
- LegacyMetadataMapper.createCharacteristics(legacyCamera.getParameters(), info);
+ LegacyMetadataMapper.createCharacteristics(legacyParameters, info);
LegacyCameraDevice device = new LegacyCameraDevice(
cameraId, legacyCamera, characteristics, threadCallbacks);
return new CameraDeviceUserShim(cameraId, device, characteristics, init, threadCallbacks);
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index d27ca14..a7ea89c 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -328,6 +328,7 @@
resetJpegSurfaceFormats(mCallbackOutputs);
mPreviewOutputs.clear();
mCallbackOutputs.clear();
+ mJpegSurfaceIds.clear();
mPreviewTexture = null;
int facing = mCharacteristics.get(CameraCharacteristics.LENS_FACING);
@@ -356,7 +357,14 @@
}
}
}
- mParams = mCamera.getParameters();
+ try {
+ mParams = mCamera.getParameters();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Received device exception: ", e);
+ mDeviceState.setError(
+ CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
+ return;
+ }
List<int[]> supportedFpsRanges = mParams.getSupportedPreviewFpsRange();
int[] bestRange = getPhotoPreviewFpsRange(supportedFpsRanges);
@@ -780,7 +788,14 @@
if (DEBUG) {
Log.d(TAG, "Params changed -- getting new Parameters from HAL.");
}
- mParams = mCamera.getParameters();
+ try {
+ mParams = mCamera.getParameters();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Received device exception: ", e);
+ mDeviceState.setError(
+ CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
+ break;
+ }
// Update parameters to the latest that we think the camera is using
mLastRequest.setParameters(mParams);
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index ba71605..362afba 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -17,6 +17,7 @@
package android.os;
import android.util.Log;
+import android.util.Slog;
import com.android.internal.util.FastPrintWriter;
import java.io.FileDescriptor;
@@ -48,7 +49,7 @@
* of classes can potentially create leaks.
*/
private static final boolean FIND_POTENTIAL_LEAKS = false;
- private static final String TAG = "Binder";
+ static final String TAG = "Binder";
/**
* Control whether dump() calls are allowed.
@@ -385,7 +386,14 @@
super.finalize();
}
}
-
+
+ static void checkParcel(Parcel parcel, String msg) {
+ if (parcel.dataSize() >= 800*1024) {
+ // Trying to send > 800k, this is way too much
+ Slog.wtfStack(TAG, msg + parcel.dataSize());
+ }
+ }
+
private native final void init();
private native final void destroy();
@@ -424,6 +432,7 @@
reply.writeException(re);
res = true;
}
+ checkParcel(reply, "Unreasonably large binder reply buffer: ");
reply.recycle();
data.recycle();
return res;
@@ -433,13 +442,18 @@
final class BinderProxy implements IBinder {
public native boolean pingBinder();
public native boolean isBinderAlive();
-
+
public IInterface queryLocalInterface(String descriptor) {
return null;
}
-
+
+ public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
+ Binder.checkParcel(data, "Unreasonably large binder buffer: ");
+ return transactNative(code, data, reply, flags);
+ }
+
public native String getInterfaceDescriptor() throws RemoteException;
- public native boolean transact(int code, Parcel data, Parcel reply,
+ public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
public native void linkToDeath(DeathRecipient recipient, int flags)
throws RemoteException;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 440b1ec..ec4a53e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -978,6 +978,19 @@
public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
/**
+ * Activity Extra: The device identifier to act upon.
+ * <p>
+ * This can be passed as an extra field in an Activity Intent with a single
+ * InputDeviceIdentifier. This field is used by some activities to jump straight into the
+ * settings for the given device.
+ * <p>
+ * Example: The {@link #INPUT_METHOD_SETTINGS} intent opens the keyboard layout dialog for the
+ * given device.
+ * @hide
+ */
+ public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier";
+
+ /**
* @hide
* Activity Extra: Enable or disable Airplane Mode.
* <p>
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 2b8b4dc..0439168 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1493,11 +1493,11 @@
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(AbsListView.class.getName());
if (isEnabled()) {
- if (getFirstVisiblePosition() > 0) {
+ if (canScrollUp()) {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
info.setScrollable(true);
}
- if (getLastVisiblePosition() < getCount() - 1) {
+ if (canScrollDown()) {
info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
info.setScrollable(true);
}
@@ -2203,38 +2203,46 @@
void updateScrollIndicators() {
if (mScrollUp != null) {
- boolean canScrollUp;
- // 0th element is not visible
- canScrollUp = mFirstPosition > 0;
-
- // ... Or top of 0th element is not visible
- if (!canScrollUp) {
- if (getChildCount() > 0) {
- View child = getChildAt(0);
- canScrollUp = child.getTop() < mListPadding.top;
- }
- }
-
- mScrollUp.setVisibility(canScrollUp ? View.VISIBLE : View.INVISIBLE);
+ mScrollUp.setVisibility(canScrollUp() ? View.VISIBLE : View.INVISIBLE);
}
if (mScrollDown != null) {
- boolean canScrollDown;
- int count = getChildCount();
-
- // Last item is not visible
- canScrollDown = (mFirstPosition + count) < mItemCount;
-
- // ... Or bottom of the last element is not visible
- if (!canScrollDown && count > 0) {
- View child = getChildAt(count - 1);
- canScrollDown = child.getBottom() > mBottom - mListPadding.bottom;
- }
-
- mScrollDown.setVisibility(canScrollDown ? View.VISIBLE : View.INVISIBLE);
+ mScrollDown.setVisibility(canScrollDown() ? View.VISIBLE : View.INVISIBLE);
}
}
+ private boolean canScrollUp() {
+ boolean canScrollUp;
+ // 0th element is not visible
+ canScrollUp = mFirstPosition > 0;
+
+ // ... Or top of 0th element is not visible
+ if (!canScrollUp) {
+ if (getChildCount() > 0) {
+ View child = getChildAt(0);
+ canScrollUp = child.getTop() < mListPadding.top;
+ }
+ }
+
+ return canScrollUp;
+ }
+
+ private boolean canScrollDown() {
+ boolean canScrollDown;
+ int count = getChildCount();
+
+ // Last item is not visible
+ canScrollDown = (mFirstPosition + count) < mItemCount;
+
+ // ... Or bottom of the last element is not visible
+ if (!canScrollDown && count > 0) {
+ View child = getChildAt(count - 1);
+ canScrollDown = child.getBottom() > mBottom - mListPadding.bottom;
+ }
+
+ return canScrollDown;
+ }
+
@Override
@ViewDebug.ExportedProperty
public View getSelectedView() {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 22600de..5685ad7 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -128,7 +128,10 @@
com.android.internal.R.string.whichSendApplicationNamed),
DEFAULT(null,
com.android.internal.R.string.whichApplication,
- com.android.internal.R.string.whichApplicationNamed);
+ com.android.internal.R.string.whichApplicationNamed),
+ HOME(Intent.ACTION_MAIN,
+ com.android.internal.R.string.whichHomeApplication,
+ com.android.internal.R.string.whichHomeApplicationNamed);
public final String action;
public final int titleRes;
@@ -142,7 +145,7 @@
public static ActionTitle forAction(String action) {
for (ActionTitle title : values()) {
- if (action != null && action.equals(title.action)) {
+ if (title != HOME && action != null && action.equals(title.action)) {
return title;
}
}
@@ -165,26 +168,19 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
// Use a specialized prompt when we're handling the 'Home' app startActivity()
- final int titleResource;
final Intent intent = makeMyIntent();
final Set<String> categories = intent.getCategories();
if (Intent.ACTION_MAIN.equals(intent.getAction())
&& categories != null
&& categories.size() == 1
&& categories.contains(Intent.CATEGORY_HOME)) {
- titleResource = com.android.internal.R.string.whichHomeApplication;
-
// Note: this field is not set to true in the compatibility version.
mResolvingHome = true;
- } else {
- titleResource = 0;
}
setSafeForwardingMode(true);
- onCreate(savedInstanceState, intent,
- titleResource != 0 ? getResources().getText(titleResource) : null, titleResource,
- null, null, true);
+ onCreate(savedInstanceState, intent, null, 0, null, null, true);
}
/**
@@ -336,7 +332,7 @@
}
protected CharSequence getTitleForAction(String action, int defaultTitleRes) {
- final ActionTitle title = ActionTitle.forAction(action);
+ final ActionTitle title = mResolvingHome ? ActionTitle.HOME : ActionTitle.forAction(action);
final boolean named = mAdapter.hasFilteredItem();
if (title == ActionTitle.DEFAULT && defaultTitleRes != 0) {
return getString(defaultTitleRes);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1a2d6ce..85b58aa 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -780,9 +780,9 @@
*/
public void saveLockPassword(String password, int quality, boolean isFallback, int userHandle) {
try {
- getLockSettings().setLockPassword(password, userHandle);
DevicePolicyManager dpm = getDevicePolicyManager();
if (!TextUtils.isEmpty(password)) {
+ getLockSettings().setLockPassword(password, userHandle);
int computedQuality = computePasswordQuality(password);
if (userHandle == UserHandle.USER_OWNER) {
@@ -860,6 +860,7 @@
setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
} else {
// Empty password
+ getLockSettings().setLockPassword(null, userHandle);
if (userHandle == UserHandle.USER_OWNER) {
// Set the encryption password to default.
updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 81e887d..2dbd382 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -1239,7 +1239,7 @@
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
- {"transact", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
+ {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fd4b40f..9fc7801 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3440,7 +3440,10 @@
and a previously used application is known. -->
<string name="whichSendApplicationNamed">Share with %1$s</string>
<!-- Title of intent resolver dialog when selecting a HOME application to run. -->
- <string name="whichHomeApplication">Select a home app</string>
+ <string name="whichHomeApplication">Select a Home app</string>
+ <!-- Title of intent resolver dialog when selecting a HOME application to run
+ and a previously used application is known. -->
+ <string name="whichHomeApplicationNamed">Use %1$s as Home</string>
<!-- Option to always use the selected application resolution in the future. See the "Complete action using" dialog title-->
<string name="alwaysUse">Use by default for this action.</string>
<!-- Title of the list of alternate options to complete an action shown when the
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2620c27..72f756a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2067,4 +2067,5 @@
<java-symbol type="bool" name="config_restart_radio_on_pdp_fail_regular_deactivation" />
<java-symbol type="array" name="networks_not_clear_data" />
<java-symbol type="bool" name="config_switch_phone_on_voice_reg_state_change" />
+ <java-symbol type="string" name="whichHomeApplicationNamed" />
</resources>
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index 4e709b5..faa89bf 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -106,7 +106,7 @@
public void setup(int maxRadius, int color, float density) {
mColorOpaque = color | 0xFF000000;
- mColorAlpha = Color.alpha(color);
+ mColorAlpha = Color.alpha(color) / 2;
if (maxRadius != RippleDrawable.RADIUS_AUTO) {
mHasMaxRadius = true;
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index f0a2072..e9e475c 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -289,7 +289,7 @@
+ " mPopupImmediately: " + mPopupImmediately
+ " mInEmergency: " + getInEmergency());
- if (getLocationEnabled() && !getInEmergency()) {
+ if (!getLocationEnabled() && !getInEmergency()) {
// Location is currently disabled, ignore all NI requests.
try {
mNetInitiatedListener.sendNiResponse(notif.notificationId,
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 00026dc..42ee666 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -274,6 +274,8 @@
private long mBackgroundFadeDurationMillis = -1;
private Boolean mSharedElementsUseOverlay;
+ private Rect mTempRect;
+
static class WindowManagerHolder {
static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
@@ -2892,37 +2894,53 @@
// Show the status guard when the non-overlay contextual action bar is showing
if (mActionModeView != null) {
if (mActionModeView.getLayoutParams() instanceof MarginLayoutParams) {
- MarginLayoutParams mlp = (MarginLayoutParams) mActionModeView.getLayoutParams();
+ // Insets are magic!
+ final MarginLayoutParams mlp = (MarginLayoutParams)
+ mActionModeView.getLayoutParams();
boolean mlpChanged = false;
if (mActionModeView.isShown()) {
- final boolean nonOverlay = (getLocalFeatures()
- & (1 << FEATURE_ACTION_MODE_OVERLAY)) == 0;
- if (mlp.topMargin != insets.getSystemWindowInsetTop()) {
+ if (mTempRect == null) {
+ mTempRect = new Rect();
+ }
+ final Rect rect = mTempRect;
+
+ // If the parent doesn't consume the insets, manually
+ // apply the default system window insets.
+ mContentParent.computeSystemWindowInsets(insets, rect);
+ final int newMargin = rect.top == 0 ? insets.getSystemWindowInsetTop() : 0;
+ if (mlp.topMargin != newMargin) {
mlpChanged = true;
mlp.topMargin = insets.getSystemWindowInsetTop();
- // Only show status guard for non-overlay modes.
- if (nonOverlay) {
- if (mStatusGuard == null) {
- mStatusGuard = new View(mContext);
- mStatusGuard.setBackgroundColor(mContext.getResources()
- .getColor(R.color.input_method_navigation_guard));
- addView(mStatusGuard, indexOfChild(mStatusColorView),
- new LayoutParams(LayoutParams.MATCH_PARENT,
- mlp.topMargin,
- Gravity.START | Gravity.TOP));
- } else {
- LayoutParams lp = (LayoutParams) mStatusGuard.getLayoutParams();
- if (lp.height != mlp.topMargin) {
- lp.height = mlp.topMargin;
- mStatusGuard.setLayoutParams(lp);
- }
+ if (mStatusGuard == null) {
+ mStatusGuard = new View(mContext);
+ mStatusGuard.setBackgroundColor(mContext.getResources()
+ .getColor(R.color.input_method_navigation_guard));
+ addView(mStatusGuard, indexOfChild(mStatusColorView),
+ new LayoutParams(LayoutParams.MATCH_PARENT,
+ mlp.topMargin, Gravity.START | Gravity.TOP));
+ } else {
+ final LayoutParams lp = (LayoutParams)
+ mStatusGuard.getLayoutParams();
+ if (lp.height != mlp.topMargin) {
+ lp.height = mlp.topMargin;
+ mStatusGuard.setLayoutParams(lp);
}
}
}
+
+ // We only need to consume the insets if the action
+ // mode is overlaid on the app content (e.g. it's
+ // sitting in a FrameLayout, see
+ // screen_simple_overlay_action_mode.xml).
+ final boolean nonOverlay = (getLocalFeatures()
+ & (1 << FEATURE_ACTION_MODE_OVERLAY)) == 0;
insets = insets.consumeSystemWindowInsets(
false, nonOverlay /* top */, false, false);
- showStatusGuard = nonOverlay;
+
+ // The action mode's theme may differ from the app, so
+ // always show the status guard above it.
+ showStatusGuard = true;
} else {
// reset top margin
if (mlp.topMargin != 0) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 4c00b7e..be3fc47 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1169,7 +1169,8 @@
// No enabled installed services => disable accessibility to avoid
// sending accessibility events with no recipient across processes.
- if (isEnabled && userState.mEnabledServices.isEmpty()) {
+ if (isEnabled && userState.mBoundServices.isEmpty()
+ && userState.mBindingServices.isEmpty()) {
userState.mIsAccessibilityEnabled = false;
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_ENABLED, 0, userState.mUserId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d2e3d25..4d2fd4c 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4690,8 +4690,8 @@
private final void handleAppDiedLocked(ProcessRecord app,
boolean restarting, boolean allowRestart) {
int pid = app.pid;
- cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
- if (!restarting) {
+ boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
+ if (!kept && !restarting) {
removeLruProcessLocked(app);
if (pid > 0) {
ProcessList.remove(pid);
@@ -4816,6 +4816,14 @@
}
final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
+ // First check if this ProcessRecord is actually active for the pid.
+ synchronized (mPidsSelfLocked) {
+ ProcessRecord curProc = mPidsSelfLocked.get(pid);
+ if (curProc != app) {
+ Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
+ return;
+ }
+ }
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
@@ -4833,7 +4841,7 @@
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
Slog.i(TAG, "Process " + app.processName + " (pid " + pid
- + ") has died.");
+ + ") has died");
mAllowLowerMemLevel = true;
} else {
// Note that we always want to do oom adj to update our state with the
@@ -14310,8 +14318,11 @@
* Main code for cleaning up a process when it has gone away. This is
* called both as a result of the process dying, or directly when stopping
* a process when running in single process mode.
+ *
+ * @return Returns true if the given process has been restarted, so the
+ * app that was passed in must remain on the process lists.
*/
- private final void cleanUpApplicationRecordLocked(ProcessRecord app,
+ private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
boolean restarting, boolean allowRestart, int index) {
if (index >= 0) {
removeLruProcessLocked(app);
@@ -14434,7 +14445,7 @@
// If the caller is restarting this app, then leave it in its
// current lists and let the caller take care of it.
if (restarting) {
- return;
+ return false;
}
if (!app.persistent || app.isolated) {
@@ -14470,8 +14481,12 @@
if (restart && !app.isolated) {
// We have components that still need to be running in the
// process, so re-launch it.
+ if (index < 0) {
+ ProcessList.remove(app.pid);
+ }
mProcessNames.put(app.processName, app.uid, app);
startProcessLocked(app, "restart", app.processName);
+ return true;
} else if (app.pid > 0 && app.pid != MY_PID) {
// Goodbye!
boolean removed;
@@ -14485,6 +14500,7 @@
}
app.setPid(0);
}
+ return false;
}
boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 7f89947..15dcd44 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -695,6 +695,8 @@
final int numFullKeyboards = mTempFullKeyboards.size();
boolean missingLayoutForExternalKeyboard = false;
boolean missingLayoutForExternalKeyboardAdded = false;
+ boolean multipleMissingLayoutsForExternalKeyboardsAdded = false;
+ InputDevice keyboardMissingLayout = null;
synchronized (mDataStore) {
for (int i = 0; i < numFullKeyboards; i++) {
final InputDevice inputDevice = mTempFullKeyboards.get(i);
@@ -704,13 +706,25 @@
missingLayoutForExternalKeyboard = true;
if (i < numFullKeyboardsAdded) {
missingLayoutForExternalKeyboardAdded = true;
+ if (keyboardMissingLayout == null) {
+ keyboardMissingLayout = inputDevice;
+ } else {
+ multipleMissingLayoutsForExternalKeyboardsAdded = true;
+ }
}
}
}
}
if (missingLayoutForExternalKeyboard) {
if (missingLayoutForExternalKeyboardAdded) {
- showMissingKeyboardLayoutNotification();
+ if (multipleMissingLayoutsForExternalKeyboardsAdded) {
+ // We have more than one keyboard missing a layout, so drop the
+ // user at the generic input methods page so they can pick which
+ // one to set.
+ showMissingKeyboardLayoutNotification(null);
+ } else {
+ showMissingKeyboardLayoutNotification(keyboardMissingLayout);
+ }
}
} else if (mKeyboardLayoutNotificationShown) {
hideMissingKeyboardLayoutNotification();
@@ -761,16 +775,17 @@
}
// Must be called on handler.
- private void showMissingKeyboardLayoutNotification() {
+ private void showMissingKeyboardLayoutNotification(InputDevice device) {
if (!mKeyboardLayoutNotificationShown) {
- if (mKeyboardLayoutIntent == null) {
- final Intent intent = new Intent("android.settings.INPUT_METHOD_SETTINGS");
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- mKeyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
- intent, 0, null, UserHandle.CURRENT);
+ final Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS);
+ if (device != null) {
+ intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, device.getIdentifier());
}
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
+ intent, 0, null, UserHandle.CURRENT);
Resources r = mContext.getResources();
Notification notification = new Notification.Builder(mContext)
@@ -778,7 +793,7 @@
R.string.select_keyboard_layout_notification_title))
.setContentText(r.getString(
R.string.select_keyboard_layout_notification_message))
- .setContentIntent(mKeyboardLayoutIntent)
+ .setContentIntent(keyboardLayoutIntent)
.setSmallIcon(R.drawable.ic_settings_language)
.setPriority(Notification.PRIORITY_LOW)
.setColor(mContext.getResources().getColor(
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index 796725b..b18cb96 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -166,6 +166,20 @@
}
}
+ public void merge() {
+ try {
+ mConnectionService.mergeConference(mId);
+ } catch (RemoteException e) {
+ }
+ }
+
+ public void swap() {
+ try {
+ mConnectionService.swapConference(mId);
+ } catch (RemoteException e) {
+ }
+ }
+
public void hold() {
try {
mConnectionService.hold(mId);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index b8c3454..77d3beb 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -3310,6 +3310,19 @@
, mParentId(entry.mParentId)
, mPos(entry.mPos) {}
+ResourceTable::Entry& ResourceTable::Entry::operator=(const Entry& entry) {
+ mName = entry.mName;
+ mParent = entry.mParent;
+ mType = entry.mType;
+ mItem = entry.mItem;
+ mItemFormat = entry.mItemFormat;
+ mBag = entry.mBag;
+ mNameIndex = entry.mNameIndex;
+ mParentId = entry.mParentId;
+ mPos = entry.mPos;
+ return *this;
+}
+
status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
{
if (mType == TYPE_BAG) {
@@ -4352,7 +4365,11 @@
String8(entriesToAdd[i].value->getName()).string(),
entriesToAdd[i].key.toString().string());
- c->addEntry(entriesToAdd[i].key, entriesToAdd[i].value);
+ sp<Entry> newEntry = t->getEntry(c->getName(),
+ entriesToAdd[i].value->getPos(),
+ &entriesToAdd[i].key);
+
+ *newEntry = *entriesToAdd[i].value;
}
}
}
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index c548a85..eac5dd3 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -316,6 +316,7 @@
{ }
Entry(const Entry& entry);
+ Entry& operator=(const Entry& entry);
virtual ~Entry() { }