Merge "Update path in MediaStore when moving/renaming a file/folder."
diff --git a/api/system-current.txt b/api/system-current.txt
index dea8f68..883eba4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -26618,11 +26618,15 @@
method public int describeContents();
method public java.lang.String getAudioAddress();
method public int getAudioType();
+ method public int getCableConnectionStatus();
method public int getDeviceId();
method public int getHdmiPortId();
method public int getType();
method public void readFromParcel(android.os.Parcel);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CABLE_CONNECTION_STATUS_CONNECTED = 1; // 0x1
+ field public static final int CABLE_CONNECTION_STATUS_DISCONNECTED = 2; // 0x2
+ field public static final int CABLE_CONNECTION_STATUS_UNKNOWN = 0; // 0x0
field public static final android.os.Parcelable.Creator<android.media.tv.TvInputHardwareInfo> CREATOR;
field public static final int TV_INPUT_TYPE_COMPONENT = 6; // 0x6
field public static final int TV_INPUT_TYPE_COMPOSITE = 3; // 0x3
@@ -26641,6 +26645,7 @@
method public android.media.tv.TvInputHardwareInfo.Builder audioAddress(java.lang.String);
method public android.media.tv.TvInputHardwareInfo.Builder audioType(int);
method public android.media.tv.TvInputHardwareInfo build();
+ method public android.media.tv.TvInputHardwareInfo.Builder cableConnectionStatus(int);
method public android.media.tv.TvInputHardwareInfo.Builder deviceId(int);
method public android.media.tv.TvInputHardwareInfo.Builder hdmiPortId(int);
method public android.media.tv.TvInputHardwareInfo.Builder type(int);
diff --git a/core/java/android/view/LayoutInflater.java b/core/java/android/view/LayoutInflater.java
index e3ac40c..0e06cd3 100644
--- a/core/java/android/view/LayoutInflater.java
+++ b/core/java/android/view/LayoutInflater.java
@@ -833,6 +833,7 @@
final int depth = parser.getDepth();
int type;
+ boolean pendingRequestFocus = false;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
@@ -844,7 +845,8 @@
final String name = parser.getName();
if (TAG_REQUEST_FOCUS.equals(name)) {
- parseRequestFocus(parser, parent);
+ pendingRequestFocus = true;
+ consumeChildElements(parser);
} else if (TAG_TAG.equals(name)) {
parseViewTag(parser, parent, attrs);
} else if (TAG_INCLUDE.equals(name)) {
@@ -863,23 +865,16 @@
}
}
+ if (pendingRequestFocus) {
+ parent.restoreDefaultFocus();
+ }
+
if (finishInflate) {
parent.onFinishInflate();
}
}
/**
- * Parses a <code><request-focus></code> element and requests focus on
- * the containing View.
- */
- private void parseRequestFocus(XmlPullParser parser, View view)
- throws XmlPullParserException, IOException {
- view.requestFocus();
-
- consumeChildElements(parser);
- }
-
- /**
* Parses a <code><tag></code> element and sets a keyed tag on the
* containing View.
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 580888c..ed42385 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -164,6 +164,17 @@
static final ArrayList<ComponentCallbacks> sConfigCallbacks = new ArrayList();
/**
+ * Signals that compatibility booleans have been initialized according to
+ * target SDK versions.
+ */
+ private static boolean sCompatibilityDone = false;
+
+ /**
+ * Always assign focus if a focusable View is available.
+ */
+ private static boolean sAlwaysAssignFocus;
+
+ /**
* This list must only be modified by the main thread, so a lock is only needed when changing
* the list or when accessing the list from a non-main thread.
*/
@@ -451,6 +462,13 @@
mFallbackEventHandler = new PhoneFallbackEventHandler(context);
mChoreographer = Choreographer.getInstance();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
+
+ if (!sCompatibilityDone) {
+ sAlwaysAssignFocus = mTargetSdkVersion < Build.VERSION_CODES.O;
+
+ sCompatibilityDone = true;
+ }
+
loadSystemProperties();
}
@@ -2180,7 +2198,7 @@
}
}
- if (mFirst) {
+ if (mFirst && sAlwaysAssignFocus) {
// handle first focus request
if (DEBUG_INPUT_RESIZE) Log.v(mTag, "First: mView.hasFocus()="
+ mView.hasFocus());
@@ -3290,7 +3308,9 @@
checkThread();
if (mView != null) {
if (!mView.hasFocus()) {
- v.requestFocus();
+ if (sAlwaysAssignFocus) {
+ v.requestFocus();
+ }
} else {
// the one case where will transfer focus away from the current one
// is if the current view is a view group that prefers to give focus
@@ -4463,9 +4483,7 @@
return true;
}
} else {
- // find the best view to give focus to in this non-touch-mode with no-focus
- View v = focusSearch(null, direction);
- if (v != null && v.requestFocus(direction)) {
+ if (mView.restoreDefaultFocus()) {
return true;
}
}
@@ -4475,9 +4493,10 @@
private boolean performKeyboardGroupNavigation(int direction) {
final View focused = mView.findFocus();
- View cluster = focused != null
- ? focused.keyboardNavigationClusterSearch(null, direction)
- : keyboardNavigationClusterSearch(null, direction);
+ if (focused == null && mView.restoreDefaultFocus()) {
+ return true;
+ }
+ View cluster = focused.keyboardNavigationClusterSearch(null, direction);
// Since requestFocus only takes "real" focus directions (and therefore also
// restoreFocusInCluster), convert forward/backward focus into FOCUS_DOWN.
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index d1871ff..415eef7 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -58,8 +58,9 @@
size_t bufSize) {
minikin::MinikinPaint minikinPaint;
minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface);
- minikin::Layout layout(Typeface::resolveDefault(typeface)->fFontCollection);
- layout.doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint);
+ minikin::Layout layout;
+ layout.doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint,
+ Typeface::resolveDefault(typeface)->fFontCollection);
return layout;
}
diff --git a/media/java/android/media/tv/TvInputHardwareInfo.java b/media/java/android/media/tv/TvInputHardwareInfo.java
index 51fa036..957c582 100644
--- a/media/java/android/media/tv/TvInputHardwareInfo.java
+++ b/media/java/android/media/tv/TvInputHardwareInfo.java
@@ -16,11 +16,15 @@
package android.media.tv;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.media.AudioManager;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
+import java.lang.annotation.Retention;
/**
* Simple container for information about TV input hardware.
@@ -44,6 +48,28 @@
public static final int TV_INPUT_TYPE_HDMI = 9;
public static final int TV_INPUT_TYPE_DISPLAY_PORT = 10;
+ /** @hide */
+ @Retention(SOURCE)
+ @IntDef({CABLE_CONNECTION_STATUS_UNKNOWN, CABLE_CONNECTION_STATUS_CONNECTED,
+ CABLE_CONNECTION_STATUS_DISCONNECTED})
+ public @interface CableConnectionStatus {}
+
+ // Match hardware/interfaces/tv/input/1.0/types.hal
+ /**
+ * The hardware is unsure about the connection status or does not support cable detection.
+ */
+ public static final int CABLE_CONNECTION_STATUS_UNKNOWN = 0;
+
+ /**
+ * Cable is connected to the hardware.
+ */
+ public static final int CABLE_CONNECTION_STATUS_CONNECTED = 1;
+
+ /**
+ * Cable is disconnected to the hardware.
+ */
+ public static final int CABLE_CONNECTION_STATUS_DISCONNECTED = 2;
+
public static final Parcelable.Creator<TvInputHardwareInfo> CREATOR =
new Parcelable.Creator<TvInputHardwareInfo>() {
@Override
@@ -69,6 +95,8 @@
private int mAudioType;
private String mAudioAddress;
private int mHdmiPortId;
+ @CableConnectionStatus
+ private int mCableConnectionStatus;
private TvInputHardwareInfo() {
}
@@ -96,6 +124,19 @@
return mHdmiPortId;
}
+ /**
+ * Gets the cable connection status of the hardware.
+ *
+ * @return {@code CABLE_CONNECTION_STATUS_CONNECTED} if cable is connected.
+ * {@code CABLE_CONNECTION_STATUS_DISCONNECTED} if cable is disconnected.
+ * {@code CABLE_CONNECTION_STATUS_UNKNOWN} if the hardware is unsure about the
+ * connection status or does not support cable detection.
+ */
+ @CableConnectionStatus
+ public int getCableConnectionStatus() {
+ return mCableConnectionStatus;
+ }
+
@Override
public String toString() {
StringBuilder b = new StringBuilder(128);
@@ -106,6 +147,7 @@
if (mType == TV_INPUT_TYPE_HDMI) {
b.append(", hdmi_port=").append(mHdmiPortId);
}
+ b.append(", cable_connection_status=").append(mCableConnectionStatus);
b.append("}");
return b.toString();
}
@@ -125,6 +167,7 @@
if (mType == TV_INPUT_TYPE_HDMI) {
dest.writeInt(mHdmiPortId);
}
+ dest.writeInt(mCableConnectionStatus);
}
public void readFromParcel(Parcel source) {
@@ -135,6 +178,7 @@
if (mType == TV_INPUT_TYPE_HDMI) {
mHdmiPortId = source.readInt();
}
+ mCableConnectionStatus = source.readInt();
}
public static final class Builder {
@@ -143,6 +187,7 @@
private int mAudioType = AudioManager.DEVICE_NONE;
private String mAudioAddress = "";
private Integer mHdmiPortId = null;
+ private Integer mCableConnectionStatus = CABLE_CONNECTION_STATUS_UNKNOWN;
public Builder() {
}
@@ -172,6 +217,14 @@
return this;
}
+ /**
+ * Sets cable connection status.
+ */
+ public Builder cableConnectionStatus(@CableConnectionStatus int cableConnectionStatus) {
+ mCableConnectionStatus = cableConnectionStatus;
+ return this;
+ }
+
public TvInputHardwareInfo build() {
if (mDeviceId == null || mType == null) {
throw new UnsupportedOperationException();
@@ -191,6 +244,7 @@
if (mHdmiPortId != null) {
info.mHdmiPortId = mHdmiPortId;
}
+ info.mCableConnectionStatus = mCableConnectionStatus;
return info;
}
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 1eae8db..09b2050 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -224,9 +224,8 @@
* {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is connected.
*
* <p>This state indicates that a source device is connected to the input port and is in the
- * normal operation mode. It is mostly relevant to hardware inputs such as HDMI input. This is
- * the default state for any hardware inputs where their states are unknown. Non-hardware inputs
- * are considered connected all the time.
+ * normal operation mode. It is mostly relevant to hardware inputs such as HDMI input.
+ * Non-hardware inputs are considered connected all the time.
*/
public static final int INPUT_STATE_CONNECTED = 0;
@@ -236,7 +235,8 @@
* in standby mode.
*
* <p>This state indicates that a source device is connected to the input port but is in standby
- * mode. It is mostly relevant to hardware inputs such as HDMI input.
+ * or low power mode. It is mostly relevant to hardware inputs such as HDMI input and Component
+ * inputs.
*/
public static final int INPUT_STATE_CONNECTED_STANDBY = 1;
diff --git a/packages/SettingsProvider/AndroidManifest.xml b/packages/SettingsProvider/AndroidManifest.xml
index 6c06d05..9374d52 100644
--- a/packages/SettingsProvider/AndroidManifest.xml
+++ b/packages/SettingsProvider/AndroidManifest.xml
@@ -17,6 +17,7 @@
android:multiprocess="false"
android:exported="true"
android:singleUser="true"
- android:initOrder="100" />
+ android:initOrder="100"
+ android:visibleToInstantApps="true" />
</application>
</manifest>
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index c0c433e..99fe418 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -2013,10 +2013,6 @@
final Configuration parentConfig = getParent().getConfiguration();
final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
- // TODO: Orientation?
- config.orientation = (config.screenWidthDp <= config.screenHeightDp)
- ? Configuration.ORIENTATION_PORTRAIT
- : Configuration.ORIENTATION_LANDSCAPE;
if (mStack != null) {
final StackWindowController stackController = mStack.getWindowContainerController();
stackController.adjustConfigurationForBounds(bounds, insetBounds,
@@ -2030,6 +2026,10 @@
Slog.wtf(TAG, "Expected stack when caclulating override config");
}
+ config.orientation = (config.screenWidthDp <= config.screenHeightDp)
+ ? Configuration.ORIENTATION_PORTRAIT
+ : Configuration.ORIENTATION_LANDSCAPE;
+
// For calculating screen layout, we need to use the non-decor inset screen area for the
// calculation for compatibility reasons, i.e. screen area without system bars that could
// never go away in Honeycomb.
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 8043c65..08eca73 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -17,6 +17,7 @@
package com.android.server.tv;
import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED;
+import static android.media.tv.TvInputManager.INPUT_STATE_CONNECTED_STANDBY;
import static android.media.tv.TvInputManager.INPUT_STATE_DISCONNECTED;
import android.content.BroadcastReceiver;
@@ -109,7 +110,6 @@
private int mCurrentIndex = 0;
private int mCurrentMaxIndex = 0;
- // TODO: Should handle STANDBY case.
private final SparseBooleanArray mHdmiStateMap = new SparseBooleanArray();
private final List<Message> mPendingHdmiDeviceEvents = new LinkedList<>();
@@ -209,11 +209,13 @@
+ deviceId);
return;
}
+ int previousConfigsLength = connection.getConfigsLengthLocked();
connection.updateConfigsLocked(configs);
String inputId = mHardwareInputIdMap.get(deviceId);
- if (inputId != null) {
+ if (inputId != null
+ && (previousConfigsLength == 0) != (connection.getConfigsLengthLocked() == 0)) {
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
- convertConnectedToState(configs.length > 0), 0, inputId).sendToTarget();
+ connection.getInputStateLocked(), 0, inputId).sendToTarget();
}
ITvInputHardwareCallback callback = connection.getCallbackLocked();
if (callback != null) {
@@ -263,14 +265,6 @@
|| connectionCallingUid != callingUid || connectionResolvedUserId != resolvedUserId;
}
- private int convertConnectedToState(boolean connected) {
- if (connected) {
- return INPUT_STATE_CONNECTED;
- } else {
- return INPUT_STATE_DISCONNECTED;
- }
- }
-
public void addHardwareInput(int deviceId, TvInputInfo info) {
synchronized (mLock) {
String oldInputId = mHardwareInputIdMap.get(deviceId);
@@ -293,18 +287,22 @@
}
String inputId = mHardwareInputIdMap.get(hardwareInfo.getDeviceId());
if (inputId != null && inputId.equals(info.getId())) {
- mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
- convertConnectedToState(mHdmiStateMap.valueAt(i)), 0,
- inputId).sendToTarget();
+ // No HDMI hotplug does not necessarily mean disconnected, as old devices may
+ // not report hotplug state correctly. Using INPUT_STATE_CONNECTED_STANDBY to
+ // denote unknown state.
+ int state = mHdmiStateMap.valueAt(i)
+ ? INPUT_STATE_CONNECTED
+ : INPUT_STATE_CONNECTED_STANDBY;
+ mHandler.obtainMessage(
+ ListenerHandler.STATE_CHANGED, state, 0, inputId).sendToTarget();
return;
}
}
- // For the rest of the devices, we can tell by the number of available streams.
+ // For the rest of the devices, we can tell by the cable connection status.
Connection connection = mConnections.get(deviceId);
if (connection != null) {
mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
- convertConnectedToState(connection.getConfigsLocked().length > 0), 0,
- info.getId()).sendToTarget();
+ connection.getInputStateLocked(), 0, info.getId()).sendToTarget();
}
}
}
@@ -716,6 +714,26 @@
+ ", mResolvedUserId: " + mResolvedUserId
+ " }";
}
+
+ private int getConfigsLengthLocked() {
+ return mConfigs == null ? 0 : mConfigs.length;
+ }
+
+ private int getInputStateLocked() {
+ int configsLength = getConfigsLengthLocked();
+ if (configsLength > 0) {
+ return INPUT_STATE_CONNECTED;
+ }
+ switch (mHardwareInfo.getCableConnectionStatus()) {
+ case TvInputHardwareInfo.CABLE_CONNECTION_STATUS_CONNECTED:
+ return INPUT_STATE_CONNECTED;
+ case TvInputHardwareInfo.CABLE_CONNECTION_STATUS_DISCONNECTED:
+ return INPUT_STATE_DISCONNECTED;
+ case TvInputHardwareInfo.CABLE_CONNECTION_STATUS_UNKNOWN:
+ default:
+ return INPUT_STATE_CONNECTED_STANDBY;
+ }
+ }
}
private class TvInputHardwareImpl extends ITvInputHardware.Stub {
@@ -1199,8 +1217,14 @@
if (inputId == null) {
return;
}
- mHandler.obtainMessage(ListenerHandler.STATE_CHANGED,
- convertConnectedToState(event.isConnected()), 0, inputId).sendToTarget();
+ // No HDMI hotplug does not necessarily mean disconnected, as old devices may
+ // not report hotplug state correctly. Using INPUT_STATE_CONNECTED_STANDBY to
+ // denote unknown state.
+ int state = event.isConnected()
+ ? INPUT_STATE_CONNECTED
+ : INPUT_STATE_CONNECTED_STANDBY;
+ mHandler.obtainMessage(
+ ListenerHandler.STATE_CHANGED, state, 0, inputId).sendToTarget();
}
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index e026130..52763a1 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -288,7 +288,7 @@
userState.serviceStateMap.put(component, serviceState);
updateServiceConnectionLocked(component, userId);
} else {
- inputList.addAll(serviceState.hardwareInputList);
+ inputList.addAll(serviceState.hardwareInputMap.values());
}
} else {
try {
@@ -2105,7 +2105,7 @@
private final ServiceConnection connection;
private final ComponentName component;
private final boolean isHardware;
- private final List<TvInputInfo> hardwareInputList = new ArrayList<>();
+ private final Map<String, TvInputInfo> hardwareInputMap = new HashMap<>();
private ITvInputService service;
private ServiceCallback callback;
@@ -2216,7 +2216,7 @@
}
if (serviceState.isHardware) {
- serviceState.hardwareInputList.clear();
+ serviceState.hardwareInputMap.clear();
for (TvInputHardwareInfo hardware : mTvInputHardwareManager.getHardwareList()) {
try {
serviceState.service.notifyHardwareAdded(hardware);
@@ -2283,7 +2283,7 @@
private void addHardwareInputLocked(TvInputInfo inputInfo) {
ServiceState serviceState = getServiceStateLocked(mComponent, mUserId);
- serviceState.hardwareInputList.add(inputInfo);
+ serviceState.hardwareInputMap.put(inputInfo.getId(), inputInfo);
buildTvInputListLocked(mUserId, null);
}
@@ -2309,15 +2309,7 @@
ensureHardwarePermission();
synchronized (mLock) {
ServiceState serviceState = getServiceStateLocked(mComponent, mUserId);
- boolean removed = false;
- for (Iterator<TvInputInfo> it = serviceState.hardwareInputList.iterator();
- it.hasNext(); ) {
- if (it.next().getId().equals(inputId)) {
- it.remove();
- removed = true;
- break;
- }
- }
+ boolean removed = serviceState.hardwareInputMap.remove(inputId) != null;
if (removed) {
buildTvInputListLocked(mUserId, null);
mTvInputHardwareManager.removeHardwareInput(inputId);
diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp
index 9f528b1..b433350 100644
--- a/services/core/jni/com_android_server_tv_TvInputHal.cpp
+++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp
@@ -81,6 +81,7 @@
jmethodID deviceId;
jmethodID type;
jmethodID hdmiPortId;
+ jmethodID cableConnectionStatus;
jmethodID audioType;
jmethodID audioAddress;
jmethodID build;
@@ -469,6 +470,9 @@
builder, gTvInputHardwareInfoBuilderClassInfo.hdmiPortId, info.portId);
}
env->CallObjectMethod(
+ builder, gTvInputHardwareInfoBuilderClassInfo.cableConnectionStatus,
+ info.cableConnectionStatus);
+ env->CallObjectMethod(
builder, gTvInputHardwareInfoBuilderClassInfo.audioType, info.audioType);
if (info.audioType != AudioDevice::NONE) {
uint8_t buffer[info.audioAddress.size() + 1];
@@ -743,6 +747,10 @@
gTvInputHardwareInfoBuilderClassInfo.clazz,
"hdmiPortId", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
GET_METHOD_ID(
+ gTvInputHardwareInfoBuilderClassInfo.cableConnectionStatus,
+ gTvInputHardwareInfoBuilderClassInfo.clazz,
+ "cableConnectionStatus", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");
+ GET_METHOD_ID(
gTvInputHardwareInfoBuilderClassInfo.audioType,
gTvInputHardwareInfoBuilderClassInfo.clazz,
"audioType", "(I)Landroid/media/tv/TvInputHardwareInfo$Builder;");