Merge "Read "gctype" flag from namespace "runtime_native_boot"."
diff --git a/api/current.txt b/api/current.txt
index 9dec22e..ad321c6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -44136,7 +44136,7 @@
}
public final class AvailableNetworkInfo implements android.os.Parcelable {
- ctor public AvailableNetworkInfo(int, int, java.util.ArrayList<java.lang.String>);
+ ctor public AvailableNetworkInfo(int, int, java.util.List<java.lang.String>);
method public int describeContents();
method public java.util.List<java.lang.String> getMccMncs();
method public int getPriority();
@@ -45098,7 +45098,7 @@
method public int getNetworkType();
method public int getPhoneCount();
method public int getPhoneType();
- method public int getPreferredOpportunisticDataSubscription();
+ method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telephony.ServiceState getServiceState();
method @Nullable public android.telephony.SignalStrength getSignalStrength();
method public int getSimCarrierId();
@@ -45134,6 +45134,7 @@
method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_NETWORK_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isDataRoamingEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
+ method public boolean isRttSupported();
method public boolean isSmsCapable();
method @Deprecated public boolean isTtyModeSupported();
method public boolean isVoiceCapable();
@@ -45666,9 +45667,9 @@
}
public interface GroupCallCallback {
- method public void onBroadcastSignalStrengthUpdated(@IntRange(from=0xffffffff, to=4) int);
- method public void onError(int, @Nullable String);
- method public void onGroupCallStateChanged(int, int);
+ method public default void onBroadcastSignalStrengthUpdated(@IntRange(from=0xffffffff, to=4) int);
+ method public default void onError(int, @Nullable String);
+ method public default void onGroupCallStateChanged(int, int);
field public static final int SIGNAL_STRENGTH_UNAVAILABLE = -1; // 0xffffffff
}
@@ -45726,10 +45727,10 @@
}
public interface MbmsGroupCallSessionCallback {
- method public void onAvailableSaisUpdated(@NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.util.List<java.lang.Integer>>);
- method public void onError(int, @Nullable String);
- method public void onMiddlewareReady();
- method public void onServiceInterfaceAvailable(@NonNull String, int);
+ method public default void onAvailableSaisUpdated(@NonNull java.util.List<java.lang.Integer>, @NonNull java.util.List<java.util.List<java.lang.Integer>>);
+ method public default void onError(int, @Nullable String);
+ method public default void onMiddlewareReady();
+ method public default void onServiceInterfaceAvailable(@NonNull String, int);
}
public class MbmsStreamingSessionCallback {
diff --git a/api/test-current.txt b/api/test-current.txt
index 2a9a149..ca1f0cc 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1761,6 +1761,7 @@
method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
method @NonNull public static java.io.File getVolumePath(@NonNull String) throws java.io.FileNotFoundException;
method @NonNull public static java.util.Collection<java.io.File> getVolumeScanPaths(@NonNull String) throws java.io.FileNotFoundException;
+ field public static final String EXTRA_ORIGINATED_FROM_SHELL = "android.intent.extra.originated_from_shell";
field public static final String SCAN_FILE_CALL = "scan_file";
field public static final String SCAN_VOLUME_CALL = "scan_volume";
}
@@ -2122,7 +2123,6 @@
public class TelephonyManager {
method public int checkCarrierPrivilegesForPackage(String);
method public int getCarrierIdListVersion();
- method public boolean isRttSupported();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void refreshUiccProfile();
method public void setCarrierTestOverride(String, String, String, String, String, String, String);
field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index eaba9be..40a4070 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -559,7 +559,7 @@
// Handles the oneof field in KeyValuePair atom.
if (isKeyValuePairAtom && depth == 2) {
- pos[depth] = 4;
+ pos[depth] = 5;
}
mValues.push_back(FieldValue(Field(mTagId, pos, depth), Value(elem.data.float32)));
@@ -575,7 +575,7 @@
// Handles the oneof field in KeyValuePair atom.
if (isKeyValuePairAtom && depth == 2) {
- pos[depth] = 3;
+ pos[depth] = 4;
}
mValues.push_back(FieldValue(Field(mTagId, pos, depth),
Value(string(elem.data.string, elem.len))));
@@ -593,7 +593,7 @@
}
// Handles the oneof field in KeyValuePair atom.
if (isKeyValuePairAtom && depth == 2) {
- pos[depth] = 2;
+ pos[depth] = 3;
}
mValues.push_back(
FieldValue(Field(mTagId, pos, depth), Value((int64_t)elem.data.int64)));
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 3a5be43..eec3c73 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -155,7 +155,7 @@
EXPECT_EQ(33, item5.mValue.int_value);
const FieldValue& item6 = event1.getValues()[6];
- EXPECT_EQ(0x2010482, item6.mField.getField());
+ EXPECT_EQ(0x2010483, item6.mField.getField());
EXPECT_EQ(Type::LONG, item6.mValue.getType());
EXPECT_EQ(678L, item6.mValue.int_value);
@@ -165,7 +165,7 @@
EXPECT_EQ(44, item7.mValue.int_value);
const FieldValue& item8 = event1.getValues()[8];
- EXPECT_EQ(0x2010582, item8.mField.getField());
+ EXPECT_EQ(0x2010583, item8.mField.getField());
EXPECT_EQ(Type::LONG, item8.mValue.getType());
EXPECT_EQ(890L, item8.mValue.int_value);
@@ -175,7 +175,7 @@
EXPECT_EQ(1, item9.mValue.int_value);
const FieldValue& item10 = event1.getValues()[10];
- EXPECT_EQ(0x2010683, item10.mField.getField());
+ EXPECT_EQ(0x2010684, item10.mField.getField());
EXPECT_EQ(Type::STRING, item10.mValue.getType());
EXPECT_EQ("test2", item10.mValue.str_value);
@@ -185,7 +185,7 @@
EXPECT_EQ(2, item11.mValue.int_value);
const FieldValue& item12 = event1.getValues()[12];
- EXPECT_EQ(0x2010783, item12.mField.getField());
+ EXPECT_EQ(0x2010784, item12.mField.getField());
EXPECT_EQ(Type::STRING, item12.mValue.getType());
EXPECT_EQ("test1", item12.mValue.str_value);
@@ -195,7 +195,7 @@
EXPECT_EQ(111, item13.mValue.int_value);
const FieldValue& item14 = event1.getValues()[14];
- EXPECT_EQ(0x2010884, item14.mField.getField());
+ EXPECT_EQ(0x2010885, item14.mField.getField());
EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
EXPECT_EQ(2.2f, item14.mValue.float_value);
@@ -205,7 +205,7 @@
EXPECT_EQ(222, item15.mValue.int_value);
const FieldValue& item16 = event1.getValues()[16];
- EXPECT_EQ(0x2018984, item16.mField.getField());
+ EXPECT_EQ(0x2018985, item16.mField.getField());
EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
EXPECT_EQ(1.1f, item16.mValue.float_value);
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 9ee2f03..ea145f0 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -4485,6 +4485,7 @@
* @hide
*/
public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+ logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
try {
return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
Binder.getCallingUid(), proxiedPackageName);
@@ -4500,7 +4501,7 @@
*/
@UnsupportedAppUsage
public int noteOpNoThrow(int op, int uid, String packageName) {
- logNoteOpIfNeeded(op, packageName);
+ logOperationIfNeeded(op, packageName, null);
try {
return mService.noteOperation(op, uid, packageName);
} catch (RemoteException e) {
@@ -4608,6 +4609,7 @@
* @hide
*/
public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
+ logOperationIfNeeded(op, packageName, null);
try {
return mService.startOperation(getToken(mService), op, uid, packageName,
startIfModeDefault);
@@ -4624,6 +4626,7 @@
* @hide
*/
public void finishOp(int op, int uid, String packageName) {
+ logOperationIfNeeded(op, packageName, null);
try {
mService.finishOperation(getToken(mService), op, uid, packageName);
} catch (RemoteException e) {
@@ -4870,7 +4873,7 @@
return AppOpsManager.MODE_DEFAULT;
}
- private static void logNoteOpIfNeeded(int op, String callingPackage) {
+ private static void logOperationIfNeeded(int op, String callingPackage, String proxiedPackage) {
// Check if debug logging propety is enabled.
if (!SystemProperties.getBoolean(DEBUG_LOGGING_ENABLE_PROP, false)) {
return;
@@ -4908,6 +4911,6 @@
// Log a stack trace
Exception here = new Exception("HERE!");
android.util.Log.i(DEBUG_LOGGING_TAG, "Note operation package= " + callingPackage
- + " op= " + opStr, here);
+ + " proxied= " + proxiedPackage + " op= " + opStr, here);
}
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index e2907e2..6e52b33 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -866,6 +866,14 @@
*/
public static final int INSTALL_ENABLE_ROLLBACK = 0x00040000;
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that package verification should be
+ * disabled for this package.
+ *
+ * @hide
+ */
+ public static final int INSTALL_DISABLE_VERIFICATION = 0x00080000;
+
/** @hide */
@IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
DONT_KILL_APP
diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java
index b2288fc..87568e8 100644
--- a/core/java/android/ddm/DdmHandleHello.java
+++ b/core/java/android/ddm/DdmHandleHello.java
@@ -16,13 +16,15 @@
package android.ddm;
+import android.os.Debug;
+import android.os.UserHandle;
+import android.util.Log;
+
+import dalvik.system.VMRuntime;
+
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
-import android.util.Log;
-import android.os.Debug;
-import android.os.UserHandle;
-import dalvik.system.VMRuntime;
import java.nio.ByteBuffer;
@@ -35,6 +37,8 @@
public static final int CHUNK_WAIT = type("WAIT");
public static final int CHUNK_FEAT = type("FEAT");
+ private static final int CLIENT_PROTOCOL_VERSION = 1;
+
private static DdmHandleHello mInstance = new DdmHandleHello();
private static final String[] FRAMEWORK_FEATURES = new String[] {
@@ -145,7 +149,7 @@
+ vmFlags.length() * 2
+ 1);
out.order(ChunkHandler.CHUNK_ORDER);
- out.putInt(DdmServer.CLIENT_PROTOCOL_VERSION);
+ out.putInt(CLIENT_PROTOCOL_VERSION);
out.putInt(android.os.Process.myPid());
out.putInt(vmIdent.length());
out.putInt(appName.length());
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 843db6d..ffae361e 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -51,6 +51,7 @@
private static final int DO_TOGGLE_SOFT_INPUT = 105;
private static final int DO_FINISH_SESSION = 110;
private static final int DO_VIEW_CLICKED = 115;
+ private static final int DO_NOTIFY_IME_HIDDEN = 120;
HandlerCaller mCaller;
InputMethodSession mInputMethodSession;
@@ -129,6 +130,10 @@
mInputMethodSession.viewClicked(msg.arg1 == 1);
return;
}
+ case DO_NOTIFY_IME_HIDDEN: {
+ mInputMethodSession.notifyImeHidden();
+ return;
+ }
}
Log.w(TAG, "Unhandled message code: " + msg.what);
}
@@ -172,6 +177,11 @@
}
@Override
+ public void notifyImeHidden() {
+ mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_NOTIFY_IME_HIDDEN));
+ }
+
+ @Override
public void updateCursor(Rect newCursor) {
mCaller.executeOrSendMessage(
mCaller.obtainMessageO(DO_UPDATE_CURSOR, newCursor));
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 333cfbd..ab630fd 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -592,7 +592,6 @@
final boolean wasVisible = mIsPreRendered
? mDecorViewVisible && mWindowVisible : isInputViewShown();
if (mIsPreRendered) {
- // TODO: notify visibility to insets consumer.
if (DEBUG) {
Log.v(TAG, "Making IME window invisible");
}
@@ -658,6 +657,11 @@
}
}
+ private void notifyImeHidden() {
+ setImeWindowStatus(IME_ACTIVE | IME_INVISIBLE, mBackDisposition);
+ onPreRenderedWindowVisibilityChanged(false /* setVisible */);
+ }
+
private void setImeWindowStatus(int visibilityFlags, int backDisposition) {
mPrivOps.setImeWindowStatus(visibilityFlags, backDisposition);
}
@@ -760,6 +764,14 @@
}
InputMethodService.this.onUpdateCursorAnchorInfo(info);
}
+
+ /**
+ * Notify IME that window is hidden.
+ * @hide
+ */
+ public final void notifyImeHidden() {
+ InputMethodService.this.notifyImeHidden();
+ }
}
/**
diff --git a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
index b4b541d..31c948a 100644
--- a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
+++ b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java
@@ -290,6 +290,12 @@
CallbackImpl::updateCursorAnchorInfo, mCallbackImpl, info));
}
}
+
+ @Override
+ public final void notifyImeHidden() {
+ // no-op for multi-session since IME is responsible controlling navigation bar buttons.
+ reportNotSupported();
+ }
}
private static final class MultiClientInputMethodSessionImpl
diff --git a/core/java/android/os/AsyncTask.java b/core/java/android/os/AsyncTask.java
index 141d33b..1f33693 100644
--- a/core/java/android/os/AsyncTask.java
+++ b/core/java/android/os/AsyncTask.java
@@ -19,6 +19,7 @@
import android.annotation.MainThread;
import android.annotation.Nullable;
import android.annotation.WorkerThread;
+
import java.util.ArrayDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
@@ -70,7 +71,7 @@
* protected Long doInBackground(URL... urls) {
* int count = urls.length;
* long totalSize = 0;
- * for (int i = 0; i < count; i++) {
+ * for (int i = 0; i < count; i++) {
* totalSize += Downloader.downloadFile(urls[i]);
* publishProgress((int) ((i / (float) count) * 100));
* // Escape early if cancel() is called
@@ -158,13 +159,22 @@
* </ul>
*
* <h2>Memory observability</h2>
- * <p>AsyncTask guarantees that all callback calls are synchronized in such a way that the following
- * operations are safe without explicit synchronizations.</p>
+ * <p>AsyncTask guarantees that all callback calls are synchronized to ensure the following
+ * without explicit synchronizations.</p>
* <ul>
- * <li>Set member fields in the constructor or {@link #onPreExecute}, and refer to them
- * in {@link #doInBackground}.
- * <li>Set member fields in {@link #doInBackground}, and refer to them in
- * {@link #onProgressUpdate} and {@link #onPostExecute}.
+ * <li>The memory effects of {@link #onPreExecute}, and anything else
+ * executed before the call to {@link #execute}, including the construction
+ * of the AsyncTask object, are visible to {@link #doInBackground}.
+ * <li>The memory effects of {@link #doInBackground} are visible to
+ * {@link #onPostExecute}.
+ * <li>Any memory effects of {@link #doInBackground} preceding a call
+ * to {@link #publishProgress} are visible to the corresponding
+ * {@link #onProgressUpdate} call. (But {@link #doInBackground} continues to
+ * run, and care needs to be taken that later updates in {@link #doInBackground}
+ * do not interfere with an in-progress {@link #onProgressUpdate} call.)
+ * <li>Any memory effects preceding a call to {@link #cancel} are visible
+ * after a call to {@link #isCancelled} that returns true as a result, or
+ * during and after a resulting call to {@link #onCancelled}.
* </ul>
*
* <h2>Order of execution</h2>
@@ -388,6 +398,10 @@
* specified parameters are the parameters passed to {@link #execute}
* by the caller of this task.
*
+ * This will normally run on a background thread. But to better
+ * support testing frameworks, it is recommended that this also tolerates
+ * direct execution on the foreground thread, as part of the {@link #execute} call.
+ *
* This method can call {@link #publishProgress} to publish updates
* on the UI thread.
*
@@ -404,6 +418,8 @@
/**
* Runs on the UI thread before {@link #doInBackground}.
+ * Invoked directly by {@link #execute} or {@link #executeOnExecutor}.
+ * The default version does nothing.
*
* @see #onPostExecute
* @see #doInBackground
@@ -414,7 +430,10 @@
/**
* <p>Runs on the UI thread after {@link #doInBackground}. The
- * specified result is the value returned by {@link #doInBackground}.</p>
+ * specified result is the value returned by {@link #doInBackground}.
+ * To better support testing frameworks, it is recommended that this be
+ * written to tolerate direct execution as part of the execute() call.
+ * The default version does nothing.</p>
*
* <p>This method won't be invoked if the task was cancelled.</p>
*
@@ -432,6 +451,7 @@
/**
* Runs on the UI thread after {@link #publishProgress} is invoked.
* The specified values are the values passed to {@link #publishProgress}.
+ * The default version does nothing.
*
* @param values The values indicating progress.
*
@@ -466,7 +486,8 @@
/**
* <p>Applications should preferably override {@link #onCancelled(Object)}.
* This method is invoked by the default implementation of
- * {@link #onCancelled(Object)}.</p>
+ * {@link #onCancelled(Object)}.
+ * The default version does nothing.</p>
*
* <p>Runs on the UI thread after {@link #cancel(boolean)} is invoked and
* {@link #doInBackground(Object[])} has finished.</p>
@@ -504,12 +525,16 @@
* an attempt to stop the task.</p>
*
* <p>Calling this method will result in {@link #onCancelled(Object)} being
- * invoked on the UI thread after {@link #doInBackground(Object[])}
- * returns. Calling this method guarantees that {@link #onPostExecute(Object)}
- * is never invoked. After invoking this method, you should check the
- * value returned by {@link #isCancelled()} periodically from
- * {@link #doInBackground(Object[])} to finish the task as early as
- * possible.</p>
+ * invoked on the UI thread after {@link #doInBackground(Object[])} returns.
+ * Calling this method guarantees that onPostExecute(Object) is never
+ * subsequently invoked, even if <tt>cancel</tt> returns false, but
+ * {@link #onPostExecute} has not yet run. To finish the
+ * task as early as possible, check {@link #isCancelled()} periodically from
+ * {@link #doInBackground(Object[])}.</p>
+ *
+ * <p>This only requests cancellation. It never waits for a running
+ * background task to terminate, even if <tt>mayInterruptIfRunning</tt> is
+ * true.</p>
*
* @param mayInterruptIfRunning <tt>true</tt> if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index ddec688..68f9288 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -103,7 +103,7 @@
* Return the debug layer app's on-disk and in-APK lib directories
*/
private static String getDebugLayerAppPaths(Context context, String app) {
- ApplicationInfo appInfo;
+ final ApplicationInfo appInfo;
try {
appInfo = context.getPackageManager().getApplicationInfo(
app, PackageManager.MATCH_ALL);
@@ -113,15 +113,15 @@
return null;
}
- String abi = chooseAbi(appInfo);
+ final String abi = chooseAbi(appInfo);
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append(appInfo.nativeLibraryDir)
.append(File.pathSeparator);
sb.append(appInfo.sourceDir)
.append("!/lib/")
.append(abi);
- String paths = sb.toString();
+ final String paths = sb.toString();
if (DEBUG) Log.v(TAG, "Debug layer app libs: " + paths);
@@ -143,13 +143,13 @@
if (isDebuggable(context) || (getCanLoadSystemLibraries() == 1)) {
- int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
+ final int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
if (enable != 0) {
- String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP);
+ final String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP);
- String packageName = context.getPackageName();
+ final String packageName = context.getPackageName();
if ((gpuDebugApp != null && packageName != null)
&& (!gpuDebugApp.isEmpty() && !packageName.isEmpty())
@@ -163,12 +163,12 @@
// If there is a debug layer app specified, add its path.
- String gpuDebugLayerApp =
+ final String gpuDebugLayerApp =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYER_APP);
if (gpuDebugLayerApp != null && !gpuDebugLayerApp.isEmpty()) {
Log.i(TAG, "GPU debug layer app: " + gpuDebugLayerApp);
- String paths = getDebugLayerAppPaths(context, gpuDebugLayerApp);
+ final String paths = getDebugLayerAppPaths(context, gpuDebugLayerApp);
if (paths != null) {
// Append the path so files placed in the app's base directory will
// override the external path
@@ -176,14 +176,14 @@
}
}
- String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);
+ final String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);
Log.i(TAG, "Vulkan debug layer list: " + layers);
if (layers != null && !layers.isEmpty()) {
setDebugLayers(layers);
}
- String layersGLES =
+ final String layersGLES =
coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS_GLES);
Log.i(TAG, "GLES debug layer list: " + layersGLES);
@@ -208,7 +208,7 @@
private static final Map<OpenGlDriverChoice, String> sDriverMap = buildMap();
private static Map<OpenGlDriverChoice, String> buildMap() {
- Map<OpenGlDriverChoice, String> map = new HashMap<>();
+ final Map<OpenGlDriverChoice, String> map = new HashMap<>();
map.put(OpenGlDriverChoice.DEFAULT, "default");
map.put(OpenGlDriverChoice.ANGLE, "angle");
map.put(OpenGlDriverChoice.NATIVE, "native");
@@ -219,7 +219,7 @@
private static List<String> getGlobalSettingsString(Bundle bundle, String globalSetting) {
List<String> valueList = null;
- String settingsValue = bundle.getString(globalSetting);
+ final String settingsValue = bundle.getString(globalSetting);
if (settingsValue != null) {
valueList = new ArrayList<>(Arrays.asList(settingsValue.split(",")));
@@ -242,18 +242,16 @@
}
private static String getDriverForPkg(Bundle bundle, String packageName) {
- String allUseAngle =
+ final String allUseAngle =
bundle.getString(Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_ALL_ANGLE);
if ((allUseAngle != null) && allUseAngle.equals("1")) {
return sDriverMap.get(OpenGlDriverChoice.ANGLE);
}
- List<String> globalSettingsDriverPkgs =
- getGlobalSettingsString(bundle,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS);
- List<String> globalSettingsDriverValues =
- getGlobalSettingsString(bundle,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES);
+ final List<String> globalSettingsDriverPkgs = getGlobalSettingsString(
+ bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS);
+ final List<String> globalSettingsDriverValues = getGlobalSettingsString(
+ bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES);
// Make sure we have a good package name
if ((packageName == null) || (packageName.isEmpty())) {
@@ -270,7 +268,7 @@
return sDriverMap.get(OpenGlDriverChoice.DEFAULT);
}
- int pkgIndex = getGlobalSettingsPkgIndex(packageName, globalSettingsDriverPkgs);
+ final int pkgIndex = getGlobalSettingsPkgIndex(packageName, globalSettingsDriverPkgs);
if (pkgIndex < 0) {
return sDriverMap.get(OpenGlDriverChoice.DEFAULT);
@@ -283,10 +281,10 @@
* Get the ANGLE package name.
*/
private String getAnglePackageName(Context context) {
- Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID);
+ final Intent intent = new Intent(ACTION_ANGLE_FOR_ANDROID);
- List<ResolveInfo> resolveInfos = context.getPackageManager()
- .queryIntentActivities(intent, PackageManager.MATCH_SYSTEM_ONLY);
+ final List<ResolveInfo> resolveInfos = context.getPackageManager().queryIntentActivities(
+ intent, PackageManager.MATCH_SYSTEM_ONLY);
if (resolveInfos.size() != 1) {
Log.e(TAG, "Invalid number of ANGLE packages. Required: 1, Found: "
+ resolveInfos.size());
@@ -315,8 +313,8 @@
* - devices that are running a userdebug build (ro.debuggable) or can inject libraries for
* debugging (PR_SET_DUMPABLE).
*/
- boolean appIsDebuggable = isDebuggable(context);
- boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1;
+ final boolean appIsDebuggable = isDebuggable(context);
+ final boolean deviceIsDebuggable = getCanLoadSystemLibraries() == 1;
if (!(appIsDebuggable || deviceIsDebuggable)) {
Log.v(TAG, "Skipping loading temporary rules file: "
+ "appIsDebuggable = " + appIsDebuggable + ", "
@@ -324,7 +322,7 @@
return false;
}
- String angleTempRules = SystemProperties.get(ANGLE_TEMP_RULES);
+ final String angleTempRules = SystemProperties.get(ANGLE_TEMP_RULES);
if ((angleTempRules == null) || angleTempRules.isEmpty()) {
Log.v(TAG, "System property '" + ANGLE_TEMP_RULES + "' is not set or is empty");
@@ -333,16 +331,16 @@
Log.i(TAG, "Detected system property " + ANGLE_TEMP_RULES + ": " + angleTempRules);
- File tempRulesFile = new File(angleTempRules);
+ final File tempRulesFile = new File(angleTempRules);
if (tempRulesFile.exists()) {
Log.i(TAG, angleTempRules + " exists, loading file.");
try {
- FileInputStream stream = new FileInputStream(angleTempRules);
+ final FileInputStream stream = new FileInputStream(angleTempRules);
try {
- FileDescriptor rulesFd = stream.getFD();
- long rulesOffset = 0;
- long rulesLength = stream.getChannel().size();
+ final FileDescriptor rulesFd = stream.getFD();
+ final long rulesOffset = 0;
+ final long rulesLength = stream.getChannel().size();
Log.i(TAG, "Loaded temporary ANGLE rules from " + angleTempRules);
setAngleInfo(paths, packageName, devOptIn, rulesFd, rulesOffset, rulesLength);
@@ -377,11 +375,11 @@
String devOptIn) {
// Pass the rules file to loader for ANGLE decisions
try {
- AssetManager angleAssets =
+ final AssetManager angleAssets =
context.getPackageManager().getResourcesForApplication(angleInfo).getAssets();
try {
- AssetFileDescriptor assetsFd = angleAssets.openFd(ANGLE_RULES_FILE);
+ final AssetFileDescriptor assetsFd = angleAssets.openFd(ANGLE_RULES_FILE);
setAngleInfo(paths, packageName, devOptIn, assetsFd.getFileDescriptor(),
assetsFd.getStartOffset(), assetsFd.getLength());
@@ -404,9 +402,8 @@
* Pull ANGLE whitelist from GlobalSettings and compare against current package
*/
private boolean checkAngleWhitelist(Bundle bundle, String packageName) {
- List<String> angleWhitelist =
- getGlobalSettingsString(bundle,
- Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);
+ final List<String> angleWhitelist =
+ getGlobalSettingsString(bundle, Settings.Global.GLOBAL_SETTINGS_ANGLE_WHITELIST);
return angleWhitelist.contains(packageName);
}
@@ -420,7 +417,7 @@
return;
}
- String devOptIn = getDriverForPkg(bundle, packageName);
+ final String devOptIn = getDriverForPkg(bundle, packageName);
if (DEBUG) {
Log.v(TAG, "ANGLE Developer option for '" + packageName + "' "
+ "set to: '" + devOptIn + "'");
@@ -438,9 +435,9 @@
// load a driver, GraphicsEnv::shouldUseAngle() has seen the package name before
// and can confidently answer yes/no based on the previously set developer
// option value.
- boolean whitelisted = checkAngleWhitelist(bundle, packageName);
- boolean defaulted = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.DEFAULT));
- boolean rulesCheck = (whitelisted || !defaulted);
+ final boolean whitelisted = checkAngleWhitelist(bundle, packageName);
+ final boolean defaulted = devOptIn.equals(sDriverMap.get(OpenGlDriverChoice.DEFAULT));
+ final boolean rulesCheck = (whitelisted || !defaulted);
if (!rulesCheck) {
return;
}
@@ -452,13 +449,13 @@
Log.v(TAG, "ANGLE developer option for " + packageName + ": " + devOptIn);
}
- String anglePkgName = getAnglePackageName(context);
+ final String anglePkgName = getAnglePackageName(context);
if (anglePkgName.isEmpty()) {
Log.e(TAG, "Failed to find ANGLE package.");
return;
}
- ApplicationInfo angleInfo;
+ final ApplicationInfo angleInfo;
try {
angleInfo = context.getPackageManager().getApplicationInfo(anglePkgName,
PackageManager.MATCH_SYSTEM_ONLY);
@@ -467,10 +464,10 @@
return;
}
- String abi = chooseAbi(angleInfo);
+ final String abi = chooseAbi(angleInfo);
// Build a path that includes installed native libs and APK
- String paths = angleInfo.nativeLibraryDir
+ final String paths = angleInfo.nativeLibraryDir
+ File.pathSeparator
+ angleInfo.sourceDir
+ "!/lib/"
@@ -493,12 +490,12 @@
* Choose whether the current process should use the builtin or an updated driver.
*/
private static void chooseDriver(Context context, Bundle coreSettings) {
- String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
+ final String driverPackageName = SystemProperties.get(PROPERTY_GFX_DRIVER);
if (driverPackageName == null || driverPackageName.isEmpty()) {
return;
}
- ApplicationInfo driverInfo;
+ final ApplicationInfo driverInfo;
try {
driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName,
PackageManager.MATCH_SYSTEM_ONLY);
@@ -519,7 +516,7 @@
// To minimize risk of driver updates crippling the device beyond user repair, never use an
// updated driver for privileged or non-updated system apps. Presumably pre-installed apps
// were tested thoroughly with the pre-installed driver.
- ApplicationInfo ai = context.getApplicationInfo();
+ final ApplicationInfo ai = context.getApplicationInfo();
if (ai.isPrivilegedApp() || (ai.isSystemApp() && !ai.isUpdatedSystemApp())) {
if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
return;
@@ -529,7 +526,7 @@
// 0: Default (Invalid values fallback to default as well)
// 1: All apps use Game Driver
// 2: All apps use system graphics driver
- int gameDriverAllApps = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
+ final int gameDriverAllApps = coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0);
if (gameDriverAllApps == 2) {
if (DEBUG) {
Log.w(TAG, "Game Driver is turned off on this device");
@@ -546,7 +543,7 @@
}
return;
}
- boolean isOptIn =
+ final boolean isOptIn =
getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
.contains(ai.packageName);
if (!isOptIn
@@ -563,13 +560,13 @@
// on the blacklist, terminate early when it's on the blacklist.
try {
// TODO(b/121350991) Switch to DeviceConfig with property listener.
- String base64String =
+ final String base64String =
coreSettings.getString(Settings.Global.GAME_DRIVER_BLACKLIST);
if (base64String != null && !base64String.isEmpty()) {
- Blacklists blacklistsProto = Blacklists.parseFrom(
- Base64.decode(base64String, BASE64_FLAGS));
- List<Blacklist> blacklists = blacklistsProto.getBlacklistsList();
- long driverVersionCode = driverInfo.longVersionCode;
+ final Blacklists blacklistsProto =
+ Blacklists.parseFrom(Base64.decode(base64String, BASE64_FLAGS));
+ final List<Blacklist> blacklists = blacklistsProto.getBlacklistsList();
+ final long driverVersionCode = driverInfo.longVersionCode;
for (Blacklist blacklist : blacklists) {
if (blacklist.getVersionCode() == driverVersionCode) {
for (String packageName : blacklist.getPackageNamesList()) {
@@ -589,7 +586,7 @@
}
}
- String abi = chooseAbi(driverInfo);
+ final String abi = chooseAbi(driverInfo);
if (abi == null) {
if (DEBUG) {
// This is the normal case for the pre-installed empty driver package, don't spam
@@ -600,13 +597,13 @@
return;
}
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append(driverInfo.nativeLibraryDir)
.append(File.pathSeparator);
sb.append(driverInfo.sourceDir)
.append("!/lib/")
.append(abi);
- String paths = sb.toString();
+ final String paths = sb.toString();
if (DEBUG) Log.v(TAG, "gfx driver package libs: " + paths);
setDriverPath(paths);
@@ -623,7 +620,7 @@
* Should only be called after chooseDriver().
*/
public static void earlyInitEGL() {
- Thread eglInitThread = new Thread(
+ final Thread eglInitThread = new Thread(
() -> {
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
},
@@ -632,7 +629,7 @@
}
private static String chooseAbi(ApplicationInfo ai) {
- String isa = VMRuntime.getCurrentInstructionSet();
+ final String isa = VMRuntime.getCurrentInstructionSet();
if (ai.primaryCpuAbi != null &&
isa.equals(VMRuntime.getInstructionSet(ai.primaryCpuAbi))) {
return ai.primaryCpuAbi;
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 0743c23..67c8400 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -110,6 +110,16 @@
public static final String SCAN_VOLUME_CALL = "scan_volume";
/**
+ * Extra used with {@link #SCAN_FILE_CALL} or {@link #SCAN_VOLUME_CALL} to indicate that
+ * the file path originated from shell.
+ *
+ * {@hide}
+ */
+ @TestApi
+ public static final String EXTRA_ORIGINATED_FROM_SHELL =
+ "android.intent.extra.originated_from_shell";
+
+ /**
* The method name used by the media scanner and mtp to tell the media provider to
* rescan and reclassify that have become unhidden because of renaming folders or
* removing nomedia files
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 7026d2b..2ba1e01 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -18,10 +18,10 @@
import static android.view.InsetsState.TYPE_IME;
+import android.inputmethodservice.InputMethodService;
import android.os.Parcel;
import android.text.TextUtils;
import android.view.SurfaceControl.Transaction;
-import android.view.WindowInsets.Type;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
@@ -73,11 +73,7 @@
return;
}
- if (setVisible) {
- mController.show(Type.IME);
- } else {
- mController.hide(Type.IME);
- }
+ mController.applyImeVisibility(setVisible);
}
@Override
@@ -91,6 +87,30 @@
mHasWindowFocus = false;
}
+ /**
+ * Request {@link InputMethodManager} to show the IME.
+ * @return @see {@link android.view.InsetsSourceConsumer.ShowResult}.
+ */
+ @Override
+ @ShowResult int requestShow(boolean fromIme) {
+ // TODO: ResultReceiver for IME.
+ // TODO: Set mShowOnNextImeRender to automatically show IME and guard it with a flag.
+ if (fromIme) {
+ return ShowResult.SHOW_IMMEDIATELY;
+ }
+
+ return getImm().requestImeShow(null /* resultReceiver */)
+ ? ShowResult.SHOW_DELAYED : ShowResult.SHOW_FAILED;
+ }
+
+ /**
+ * Notify {@link InputMethodService} that IME window is hidden.
+ */
+ @Override
+ void notifyHidden() {
+ getImm().notifyImeHidden();
+ }
+
private boolean isDummyOrEmptyEditor(EditorInfo info) {
// TODO(b/123044812): Handle dummy input gracefully in IME Insets API
return info == null || (info.fieldId <= 0 && info.inputType <= 0);
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index 625ddc2..583651d 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -180,9 +180,10 @@
for (int i = items.size() - 1; i >= 0; i--) {
final InsetsSourceConsumer consumer = items.valueAt(i);
final InsetsSource source = mInitialInsetsState.getSource(consumer.getType());
+ final InsetsSourceControl control = consumer.getControl();
final SurfaceControl leash = consumer.getControl().getLeash();
- mTmpMatrix.setTranslate(source.getFrame().left, source.getFrame().top);
+ mTmpMatrix.setTranslate(control.getSurfacePosition().x, control.getSurfacePosition().y);
mTmpFrame.set(source.getFrame());
addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 93a6741..7ad97a6 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -29,10 +29,13 @@
import android.os.RemoteException;
import android.util.ArraySet;
import android.util.Log;
+import android.util.Pair;
import android.util.Property;
import android.util.SparseArray;
+import android.view.InsetsSourceConsumer.ShowResult;
import android.view.InsetsState.InternalInsetType;
import android.view.SurfaceControl.Transaction;
+import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetType;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -54,6 +57,7 @@
private static final int DIRECTION_NONE = 0;
private static final int DIRECTION_SHOW = 1;
private static final int DIRECTION_HIDE = 2;
+
@IntDef ({DIRECTION_NONE, DIRECTION_SHOW, DIRECTION_HIDE})
private @interface AnimationDirection{}
@@ -106,6 +110,8 @@
private ObjectAnimator mAnimator;
private @AnimationDirection int mAnimationDirection;
+ private int mPendingTypesToShow;
+
public InsetsController(ViewRootImpl viewRoot) {
mViewRoot = viewRoot;
mAnimCallback = () -> {
@@ -196,6 +202,12 @@
@Override
public void show(@InsetType int types) {
+ show(types, false /* fromIme */);
+ }
+
+ private void show(@InsetType int types, boolean fromIme) {
+ // TODO: Support a ResultReceiver for IME.
+ // TODO(b/123718661): Make show() work for multi-session IME.
int typesReady = 0;
final ArraySet<Integer> internalTypes = InsetsState.toInternalType(types);
for (int i = internalTypes.size() - 1; i >= 0; i--) {
@@ -204,15 +216,18 @@
// Only one animator (with multiple InsetType) can run at a time.
// previous one should be cancelled for simplicity.
cancelExistingAnimation();
- } else if (consumer.isVisible() || mAnimationDirection == DIRECTION_SHOW) {
- // no-op: already shown or animating in.
+ } else if (consumer.isVisible()
+ && (mAnimationDirection == DIRECTION_NONE
+ || mAnimationDirection == DIRECTION_HIDE)) {
+ // no-op: already shown or animating in (because window visibility is
+ // applied before starting animation).
// TODO: When we have more than one types: handle specific case when
// show animation is going on, but the current type is not becoming visible.
continue;
}
typesReady |= InsetsState.toPublicType(consumer.getType());
}
- applyAnimation(typesReady, true /* show */);
+ applyAnimation(typesReady, true /* show */, fromIme);
}
@Override
@@ -223,35 +238,114 @@
InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
if (mAnimationDirection == DIRECTION_SHOW) {
cancelExistingAnimation();
- } else if (!consumer.isVisible() || mAnimationDirection == DIRECTION_HIDE) {
+ } else if (!consumer.isVisible()
+ && (mAnimationDirection == DIRECTION_NONE
+ || mAnimationDirection == DIRECTION_HIDE)) {
// no-op: already hidden or animating out.
continue;
}
typesReady |= InsetsState.toPublicType(consumer.getType());
}
- applyAnimation(typesReady, false /* show */);
+ applyAnimation(typesReady, false /* show */, false /* fromIme */);
}
@Override
public void controlWindowInsetsAnimation(@InsetType int types,
WindowInsetsAnimationControlListener listener) {
+ controlWindowInsetsAnimation(types, listener, false /* fromIme */);
+ }
+
+ private void controlWindowInsetsAnimation(@InsetType int types,
+ WindowInsetsAnimationControlListener listener, boolean fromIme) {
+ if (types == 0) {
+ // nothing to animate.
+ return;
+ }
// TODO: Check whether we already have a controller.
final ArraySet<Integer> internalTypes = mState.toInternalType(types);
final SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
+
+ Pair<Integer, Boolean> typesReadyPair = collectConsumers(fromIme, internalTypes, consumers);
+ int typesReady = typesReadyPair.first;
+ boolean isReady = typesReadyPair.second;
+ if (!isReady) {
+ // IME isn't ready, all requested types would be shown once IME is ready.
+ mPendingTypesToShow = typesReady;
+ // TODO: listener for pending types.
+ return;
+ }
+
+ // pending types from previous request.
+ typesReady = collectPendingConsumers(typesReady, consumers);
+
+ if (typesReady == 0) {
+ listener.onCancelled();
+ return;
+ }
+
+ final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers,
+ mFrame, mState, listener, typesReady,
+ () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this);
+ mAnimationControls.add(controller);
+ }
+
+ /**
+ * @return Pair of (types ready to animate, is ready to animate).
+ */
+ private Pair<Integer, Boolean> collectConsumers(boolean fromIme,
+ ArraySet<Integer> internalTypes, SparseArray<InsetsSourceConsumer> consumers) {
+ int typesReady = 0;
+ boolean isReady = true;
for (int i = internalTypes.size() - 1; i >= 0; i--) {
InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
if (consumer.getControl() != null) {
+ if (!consumer.isVisible()) {
+ // Show request
+ switch(consumer.requestShow(fromIme)) {
+ case ShowResult.SHOW_IMMEDIATELY:
+ typesReady |= InsetsState.toPublicType(TYPE_IME);
+ break;
+ case ShowResult.SHOW_DELAYED:
+ isReady = false;
+ break;
+ case ShowResult.SHOW_FAILED:
+ // IME cannot be shown (since it didn't have focus), proceed
+ // with animation of other types.
+ if (mPendingTypesToShow != 0) {
+ // remove IME from pending because view no longer has focus.
+ mPendingTypesToShow &= ~InsetsState.toPublicType(TYPE_IME);
+ }
+ break;
+ }
+ } else {
+ // Hide request
+ // TODO: Move notifyHidden() to beginning of the hide animation
+ // (when visibility actually changes using hideDirectly()).
+ consumer.notifyHidden();
+ typesReady |= InsetsState.toPublicType(consumer.getType());
+ }
consumers.put(consumer.getType(), consumer);
} else {
// TODO: Let calling app know it's not possible, or wait
// TODO: Remove it from types
}
}
- final InsetsAnimationControlImpl controller = new InsetsAnimationControlImpl(consumers,
- mFrame, mState, listener, types,
- () -> new SyncRtSurfaceTransactionApplier(mViewRoot.mView), this);
- mAnimationControls.add(controller);
+ return new Pair<>(typesReady, isReady);
+ }
+
+ private int collectPendingConsumers(@InsetType int typesReady,
+ SparseArray<InsetsSourceConsumer> consumers) {
+ if (mPendingTypesToShow != 0) {
+ typesReady |= mPendingTypesToShow;
+ final ArraySet<Integer> internalTypes = mState.toInternalType(mPendingTypesToShow);
+ for (int i = internalTypes.size() - 1; i >= 0; i--) {
+ InsetsSourceConsumer consumer = getSourceConsumer(internalTypes.valueAt(i));
+ consumers.put(consumer.getType(), consumer);
+ }
+ mPendingTypesToShow = 0;
+ }
+ return typesReady;
}
private void applyLocalVisibilityOverride() {
@@ -296,6 +390,19 @@
return mViewRoot;
}
+ /**
+ * Used by {@link ImeInsetsSourceConsumer} when IME decides to be shown/hidden.
+ * @hide
+ */
+ @VisibleForTesting
+ public void applyImeVisibility(boolean setVisible) {
+ if (setVisible) {
+ show(Type.IME, true /* fromIme */);
+ } else {
+ hide(Type.IME);
+ }
+ }
+
private InsetsSourceConsumer createConsumerOfType(int type) {
if (type == TYPE_IME) {
return new ImeInsetsSourceConsumer(mState, Transaction::new, this);
@@ -324,7 +431,7 @@
}
}
- private void applyAnimation(@InsetType final int types, boolean show) {
+ private void applyAnimation(@InsetType final int types, boolean show, boolean fromIme) {
if (types == 0) {
// nothing to animate.
return;
@@ -372,7 +479,7 @@
// TODO: Instead of clearing this here, properly wire up
// InsetsAnimationControlImpl.finish() to remove this from mAnimationControls.
mAnimationControls.clear();
- controlWindowInsetsAnimation(types, listener);
+ controlWindowInsetsAnimation(types, listener, fromIme);
}
private void hideDirectly(@InsetType int types) {
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index cccfd87..eab83ce 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -16,12 +16,15 @@
package android.view;
+import android.annotation.IntDef;
import android.annotation.Nullable;
import android.view.InsetsState.InternalInsetType;
import android.view.SurfaceControl.Transaction;
import com.android.internal.annotations.VisibleForTesting;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.function.Supplier;
/**
@@ -30,6 +33,25 @@
*/
public class InsetsSourceConsumer {
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {ShowResult.SHOW_IMMEDIATELY, ShowResult.SHOW_DELAYED, ShowResult.SHOW_FAILED})
+ @interface ShowResult {
+ /**
+ * Window type is ready to be shown, will be shown immidiately.
+ */
+ int SHOW_IMMEDIATELY = 0;
+ /**
+ * Result will be delayed. Window needs to be prepared or request is not from controller.
+ * Request will be delegated to controller and may or may not be shown.
+ */
+ int SHOW_DELAYED = 1;
+ /**
+ * Window will not be shown because one of the conditions couldn't be met.
+ * (e.g. in IME's case, when no editor is focused.)
+ */
+ int SHOW_FAILED = 2;
+ }
+
protected final InsetsController mController;
protected boolean mVisible;
private final Supplier<Transaction> mTransactionSupplier;
@@ -104,6 +126,25 @@
return mVisible;
}
+ /**
+ * Request to show current window type.
+ *
+ * @param fromController {@code true} if request is coming from controller.
+ * (e.g. in IME case, controller is
+ * {@link android.inputmethodservice.InputMethodService}).
+ * @return @see {@link ShowResult}.
+ */
+ @ShowResult int requestShow(boolean fromController) {
+ return ShowResult.SHOW_IMMEDIATELY;
+ }
+
+ /**
+ * Notify listeners that window is now hidden.
+ */
+ void notifyHidden() {
+ // no-op for types that always return ShowResult#SHOW_IMMEDIATELY.
+ }
+
private void setVisible(boolean visible) {
if (mVisible == visible) {
return;
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 9383e6c..9fb6bdb 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -29,10 +29,13 @@
private final @InternalInsetType int mType;
private final SurfaceControl mLeash;
+ private final Point mSurfacePosition;
- public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash) {
+ public InsetsSourceControl(@InternalInsetType int type, SurfaceControl leash,
+ Point surfacePosition) {
mType = type;
mLeash = leash;
+ mSurfacePosition = surfacePosition;
}
public int getType() {
@@ -46,6 +49,19 @@
public InsetsSourceControl(Parcel in) {
mType = in.readInt();
mLeash = in.readParcelable(null /* loader */);
+ mSurfacePosition = in.readParcelable(null /* loader */);
+ }
+
+ public boolean setSurfacePosition(int left, int top) {
+ if (mSurfacePosition.equals(left, top)) {
+ return false;
+ }
+ mSurfacePosition.set(left, top);
+ return true;
+ }
+
+ public Point getSurfacePosition() {
+ return mSurfacePosition;
}
@Override
@@ -57,6 +73,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeParcelable(mLeash, 0 /* flags*/);
+ dest.writeParcelable(mSurfacePosition, 0 /* flags*/);
}
public static final Creator<InsetsSourceControl> CREATOR
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9a317db..61fb38f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -180,7 +180,7 @@
* @see #USE_NEW_INSETS_PROPERTY
* @hide
*/
- public static final int sNewInsetsMode =
+ public static int sNewInsetsMode =
SystemProperties.getInt(USE_NEW_INSETS_PROPERTY, 0);
/**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 7fee3ef..ce94cb0 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1887,6 +1887,36 @@
}
/**
+ * Call showSoftInput with currently focused view.
+ * @return {@code true} if IME can be shown.
+ * @hide
+ */
+ public boolean requestImeShow(ResultReceiver resultReceiver) {
+ synchronized (mH) {
+ if (mServedView == null) {
+ return false;
+ }
+ showSoftInput(mServedView, 0 /* flags */, resultReceiver);
+ return true;
+ }
+ }
+
+ /**
+ * Notify IME directly that it is no longer visible.
+ * @hide
+ */
+ public void notifyImeHidden() {
+ synchronized (mH) {
+ try {
+ if (mCurMethod != null) {
+ mCurMethod.notifyImeHidden();
+ }
+ } catch (RemoteException re) {
+ }
+ }
+ }
+
+ /**
* Report the current selection range.
*
* <p><strong>Editor authors</strong>, you need to call this method whenever
diff --git a/core/java/android/view/inputmethod/InputMethodSession.java b/core/java/android/view/inputmethod/InputMethodSession.java
index de15f33..eb81628 100644
--- a/core/java/android/view/inputmethod/InputMethodSession.java
+++ b/core/java/android/view/inputmethod/InputMethodSession.java
@@ -184,4 +184,11 @@
* insertion point and composition string.
*/
public void updateCursorAnchorInfo(CursorAnchorInfo cursorAnchorInfo);
+
+ /**
+ * Notifies {@link android.inputmethodservice.InputMethodService} that IME has been
+ * hidden from user.
+ * @hide
+ */
+ public void notifyImeHidden();
}
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index 794238a..664643c 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -48,4 +48,6 @@
void finishSession();
void updateCursorAnchorInfo(in CursorAnchorInfo cursorAnchorInfo);
+
+ void notifyImeHidden();
}
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index b07cb99..da81d17 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.graphics.Insets;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
@@ -80,7 +81,7 @@
@Test
public void testImeVisibility() {
- final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash);
+ final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
mController.onControlsChanged(new InsetsSourceControl[] { ime });
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 7cd3c44..71ce02d 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -19,13 +19,23 @@
import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
import static android.view.InsetsState.TYPE_TOP_BAR;
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.WindowInsets.Type.sideBars;
+import static android.view.WindowInsets.Type.systemBars;
+import static android.view.WindowInsets.Type.topBar;
import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.graphics.Insets;
import android.graphics.Matrix;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.platform.test.annotations.Presubmit;
@@ -55,6 +65,7 @@
private SurfaceSession mSession = new SurfaceSession();
private SurfaceControl mTopLeash;
private SurfaceControl mNavLeash;
+ private InsetsState mInsetsState;
@Mock Transaction mMockTransaction;
@Mock InsetsController mMockController;
@@ -63,6 +74,7 @@
@Before
public void setup() {
+ ViewRootImpl.sNewInsetsMode = NEW_INSETS_MODE_FULL;
MockitoAnnotations.initMocks(this);
mTopLeash = new SurfaceControl.Builder(mSession)
.setName("testSurface")
@@ -70,24 +82,25 @@
mNavLeash = new SurfaceControl.Builder(mSession)
.setName("testSurface")
.build();
- InsetsState state = new InsetsState();
- state.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 500, 100));
- state.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
- InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, state,
+ mInsetsState = new InsetsState();
+ mInsetsState.getSource(TYPE_TOP_BAR).setFrame(new Rect(0, 0, 500, 100));
+ mInsetsState.getSource(TYPE_NAVIGATION_BAR).setFrame(new Rect(400, 0, 500, 500));
+ InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, mInsetsState,
() -> mMockTransaction, mMockController);
- topConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mTopLeash));
+ topConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mTopLeash, new Point(0, 0)));
- InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(TYPE_NAVIGATION_BAR, state,
- () -> mMockTransaction, mMockController);
+ InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(TYPE_NAVIGATION_BAR,
+ mInsetsState, () -> mMockTransaction, mMockController);
navConsumer.hide();
- navConsumer.setControl(new InsetsSourceControl(TYPE_NAVIGATION_BAR, mNavLeash));
+ navConsumer.setControl(new InsetsSourceControl(TYPE_NAVIGATION_BAR, mNavLeash,
+ new Point(400, 0)));
SparseArray<InsetsSourceConsumer> consumers = new SparseArray<>();
consumers.put(TYPE_TOP_BAR, topConsumer);
consumers.put(TYPE_NAVIGATION_BAR, navConsumer);
mController = new InsetsAnimationControlImpl(consumers,
- new Rect(0, 0, 500, 500), state, mMockListener, WindowInsets.Type.systemBars(),
- () -> mMockTransactionApplier, mock(InsetsController.class));
+ new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(),
+ () -> mMockTransactionApplier, mMockController);
}
@Test
@@ -95,7 +108,7 @@
assertEquals(Insets.of(0, 100, 100, 0), mController.getShownStateInsets());
assertEquals(Insets.of(0, 0, 0, 0), mController.getHiddenStateInsets());
assertEquals(Insets.of(0, 100, 0, 0), mController.getCurrentInsets());
- assertEquals(WindowInsets.Type.systemBars(), mController.getTypes());
+ assertEquals(systemBars(), mController.getTypes());
}
@Test
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index 8f21096..6dad6a2 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -27,6 +27,7 @@
import android.content.Context;
import android.graphics.Insets;
+import android.graphics.Point;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.WindowInsets.Type;
@@ -74,11 +75,12 @@
Insets.of(10, 10, 10, 10), rect, rect, rect, rect),
rect, rect);
});
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
}
@Test
public void testControlsChanged() {
- InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+ InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
mController.onControlsChanged(new InsetsSourceControl[] { control });
assertEquals(mLeash,
mController.getSourceConsumer(TYPE_TOP_BAR).getControl().getLeash());
@@ -86,7 +88,7 @@
@Test
public void testControlsRevoked() {
- InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
+ InsetsSourceControl control = new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point());
mController.onControlsChanged(new InsetsSourceControl[] { control });
mController.onControlsChanged(new InsetsSourceControl[0]);
assertNull(mController.getSourceConsumer(TYPE_TOP_BAR).getControl());
@@ -94,22 +96,19 @@
@Test
public void testAnimationEndState() {
- final InsetsSourceControl navBar = new InsetsSourceControl(TYPE_NAVIGATION_BAR, mLeash);
- final InsetsSourceControl topBar = new InsetsSourceControl(TYPE_TOP_BAR, mLeash);
- final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash);
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
- InsetsSourceControl[] controls = new InsetsSourceControl[3];
- controls[0] = navBar;
- controls[1] = topBar;
- controls[2] = ime;
- mController.onControlsChanged(controls);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mController.show(Type.all());
// quickly jump to final state by cancelling it.
mController.cancelExistingAnimation();
assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
- assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
+ // no focused view, no IME.
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
mController.hide(Type.all());
mController.cancelExistingAnimation();
@@ -119,11 +118,175 @@
mController.show(Type.ime());
mController.cancelExistingAnimation();
- assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
+ // no focused view, no IME.
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
- mController.hide(Type.ime());
+ @Test
+ public void testApplyImeVisibility() {
+ final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
+
+ InsetsSourceControl[] controls = new InsetsSourceControl[3];
+ controls[0] = ime;
+ mController.onControlsChanged(controls);
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ mController.applyImeVisibility(true);
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(ime.getType()).isVisible());
+ mController.applyImeVisibility(false);
mController.cancelExistingAnimation();
assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
});
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowHideSelectively() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ int types = Type.sideBars() | Type.systemBars();
+ // test show select types.
+ mController.show(types);
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test hide all
+ mController.hide(types);
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowHideSingle() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ int types = Type.sideBars() | Type.systemBars();
+ // test show select types.
+ mController.show(types);
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test hide all
+ mController.hide(Type.all());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test single show
+ mController.show(Type.sideBars());
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ // test single hide
+ mController.hide(Type.sideBars());
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowHideMultiple() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ // start two animations and see if previous is cancelled and final state is reached.
+ mController.show(Type.sideBars());
+ mController.show(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertTrue(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ mController.hide(Type.sideBars());
+ mController.hide(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ int types = Type.sideBars() | Type.systemBars();
+ // show two at a time and hide one by one.
+ mController.show(types);
+ mController.hide(Type.sideBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ mController.hide(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ @Test
+ public void testShowMultipleHideOneByOne() {
+ InsetsSourceControl[] controls = prepareControls();
+ InsetsSourceControl navBar = controls[0];
+ InsetsSourceControl topBar = controls[1];
+ InsetsSourceControl ime = controls[2];
+
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+ int types = Type.sideBars() | Type.systemBars();
+ // show two at a time and hide one by one.
+ mController.show(types);
+ mController.hide(Type.sideBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertTrue(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+
+ mController.hide(Type.systemBars());
+ mController.cancelExistingAnimation();
+ assertFalse(mController.getSourceConsumer(navBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(topBar.getType()).isVisible());
+ assertFalse(mController.getSourceConsumer(ime.getType()).isVisible());
+ });
+ InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ private InsetsSourceControl[] prepareControls() {
+ final InsetsSourceControl navBar = new InsetsSourceControl(TYPE_NAVIGATION_BAR, mLeash,
+ new Point());
+ final InsetsSourceControl topBar = new InsetsSourceControl(TYPE_TOP_BAR, mLeash,
+ new Point());
+ final InsetsSourceControl ime = new InsetsSourceControl(TYPE_IME, mLeash, new Point());
+
+ InsetsSourceControl[] controls = new InsetsSourceControl[3];
+ controls[0] = navBar;
+ controls[1] = topBar;
+ controls[2] = ime;
+ mController.onControlsChanged(controls);
+ return controls;
}
}
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 82cd213..66146c9 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
+import android.graphics.Point;
import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl.Transaction;
@@ -56,7 +57,7 @@
.build();
mConsumer = new InsetsSourceConsumer(TYPE_TOP_BAR, new InsetsState(),
() -> mMockTransaction, mMockController);
- mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+ mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point()));
}
@Test
@@ -78,7 +79,7 @@
reset(mMockTransaction);
mConsumer.hide();
verifyZeroInteractions(mMockTransaction);
- mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash));
+ mConsumer.setControl(new InsetsSourceControl(TYPE_TOP_BAR, mLeash, new Point()));
verify(mMockTransaction).hide(eq(mLeash));
}
}
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index 035ee10..bb47658 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -58,6 +58,14 @@
}
prebuilt_etc {
+ name: "privapp_whitelist_com.android.dialer",
+ product_specific: true,
+ sub_dir: "permissions",
+ src: "com.android.dialer.xml",
+ filename_from_src: true,
+}
+
+prebuilt_etc {
name: "privapp_whitelist_com.android.launcher3",
product_specific: true,
sub_dir: "permissions",
diff --git a/data/etc/com.android.dialer.xml b/data/etc/com.android.dialer.xml
new file mode 100644
index 0000000..ccdb21f
--- /dev/null
+++ b/data/etc/com.android.dialer.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<permissions>
+ <privapp-permissions package="com.android.dialer">
+ <permission name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"/>
+ <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+ <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
+ <permission name="android.permission.MODIFY_PHONE_STATE"/>
+ <permission name="android.permission.STATUS_BAR"/>
+ <permission name="android.permission.STOP_APP_SWITCHES"/>
+ <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
+ <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
+ </privapp-permissions>
+</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 2e7b998..4ef5adb 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -49,17 +49,6 @@
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
</privapp-permissions>
- <privapp-permissions package="com.android.dialer">
- <permission name="android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"/>
- <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
- <permission name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
- <permission name="android.permission.MODIFY_PHONE_STATE"/>
- <permission name="android.permission.STATUS_BAR"/>
- <permission name="android.permission.STOP_APP_SWITCHES"/>
- <permission name="com.android.voicemail.permission.READ_VOICEMAIL"/>
- <permission name="com.android.voicemail.permission.WRITE_VOICEMAIL"/>
- </privapp-permissions>
-
<privapp-permissions package="com.android.emergency">
<!-- Required to place emergency calls from emergency info screen. -->
<permission name="android.permission.CALL_PRIVILEGED"/>
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index b67aea2..d945635 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -142,10 +142,8 @@
void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
FunctorDrawable* functorDrawable;
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
- // TODO(cblume) use VkFunctorDrawable instead of VkInteropFunctorDrawable here when the
- // interop is disabled.
functorDrawable =
- mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(functor, asSkCanvas());
+ mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
} else {
functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
}
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index 2f8d381..fe2d41e 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -43,7 +43,9 @@
, mImageInfo(image_info) {}
VkFunctorDrawHandler::~VkFunctorDrawHandler() {
- mFunctorHandle->postDrawVk();
+ if (mDrawn) {
+ mFunctorHandle->postDrawVk();
+ }
}
void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) {
@@ -77,6 +79,7 @@
params.format = vulkan_info.fFormat;
mFunctorHandle->drawVk(params);
+ mDrawn = true;
vulkan_info.fDrawBounds->offset.x = mClip.fLeft;
vulkan_info.fDrawBounds->offset.y = mClip.fTop;
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.h b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
index 1a53c8f..d3f9777 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.h
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.h
@@ -44,6 +44,8 @@
const SkMatrix mMatrix;
const SkIRect mClip;
const SkImageInfo mImageInfo;
+
+ bool mDrawn = false;
};
/**
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 925ca0d..f7afa31 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -86,6 +86,12 @@
/**
* MediaPlayer2 class can be used to control playback of audio/video files and streams.
*
+ * <p>
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
+ * for consistent behavior across all devices.
+ *
* <p>Topics covered here are:
* <ol>
* <li><a href="#PlayerStates">Player states</a>
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index 6deb47f..e43a60c 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -177,9 +177,6 @@
webview_functor_callbacks.vk.initialize = &initializeVk;
webview_functor_callbacks.vk.draw = &drawVk;
webview_functor_callbacks.vk.postDraw = &postDrawVk;
- // TODO(boliu): Remove this once SkiaRecordingCanvas::drawWebViewFunctor
- // no longer uses GL interop.
- webview_functor_callbacks.gles.draw = &draw_gl;
break;
}
callbacks_initialized = true;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 404f2e5..9a9a52f 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -186,7 +186,12 @@
* Set a listener to be notified of bubble expand events.
*/
public void setExpandListener(BubbleExpandListener listener) {
- mExpandListener = listener;
+ mExpandListener = ((isExpanding, key) -> {
+ if (listener != null) {
+ listener.onBubbleExpandChanged(isExpanding, key);
+ }
+ mStatusBarWindowController.setBubbleExpanded(isExpanding);
+ });
if (mStackView != null) {
mStackView.setExpandListener(mExpandListener);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
index 40f2392..974de4b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSwitchAction.java
@@ -22,7 +22,6 @@
import android.annotation.NonNull;
import android.graphics.Rect;
import android.os.RemoteException;
-import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
@@ -34,7 +33,6 @@
*/
public class QuickSwitchAction extends NavigationGestureAction {
private static final String TAG = "QuickSwitchAction";
- private static final String QUICKSWITCH_ENABLED_SETTING = "QUICK_SWITCH";
protected final Rect mDragOverRect = new Rect();
@@ -71,10 +69,6 @@
@Override
protected void onGestureStart(MotionEvent event) {
- // Temporarily enable launcher to allow quick switch instead of quick scrub
- Settings.Global.putInt(mNavigationBarView.getContext().getContentResolver(),
- QUICKSWITCH_ENABLED_SETTING, 1 /* enabled */);
-
startQuickGesture(event);
}
@@ -105,10 +99,6 @@
@Override
protected void onGestureEnd() {
endQuickGesture(true /* animate */);
-
- // Disable launcher to use quick switch instead of quick scrub
- Settings.Global.putInt(mNavigationBarView.getContext().getContentResolver(),
- QUICKSWITCH_ENABLED_SETTING, 0 /* disabled */);
}
protected void startQuickGesture(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index ffaa236..86e17f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -202,7 +202,8 @@
private void applyFocusableFlag(State state) {
boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
if (state.bouncerShowing && (state.keyguardOccluded || state.keyguardNeedsInput)
- || ENABLE_REMOTE_INPUT && state.remoteInputActive) {
+ || ENABLE_REMOTE_INPUT && state.remoteInputActive
+ || state.bubbleExpanded) {
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
@@ -486,6 +487,21 @@
return mCurrentState.bubblesShowing;
}
+ /**
+ * Sets if there is a bubble being expanded on the screen.
+ */
+ public void setBubbleExpanded(boolean bubbleExpanded) {
+ mCurrentState.bubbleExpanded = bubbleExpanded;
+ apply(mCurrentState);
+ }
+
+ /**
+ * The bubble is shown in expanded state for the status bar.
+ */
+ public boolean getBubbleExpanded() {
+ return mCurrentState.bubbleExpanded;
+ }
+
public void setStateListener(OtherwisedCollapsedListener listener) {
mListener = listener;
}
@@ -539,6 +555,7 @@
boolean wallpaperSupportsAmbientMode;
boolean notTouchable;
boolean bubblesShowing;
+ boolean bubbleExpanded;
/**
* The {@link StatusBar} state from the status bar.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
index e32d48d..49b4641 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/bubbles/BubbleControllerTest.java
@@ -168,12 +168,14 @@
// We should have bubbles & their notifs should show in the shade
assertTrue(mBubbleController.hasBubbles());
assertTrue(mRow.getEntry().showInShadeWhenBubble());
+ assertFalse(mStatusBarWindowController.getBubbleExpanded());
// Expand the stack
BubbleStackView stackView = mBubbleController.getStackView();
stackView.expandStack();
assertTrue(mBubbleController.isStackExpanded());
verify(mBubbleExpandListener).onBubbleExpandChanged(true, mRow.getEntry().key);
+ assertTrue(mStatusBarWindowController.getBubbleExpanded());
// Make sure it's no longer in the shade
assertFalse(mRow.getEntry().showInShadeWhenBubble());
@@ -182,6 +184,7 @@
stackView.collapseStack();
verify(mBubbleExpandListener).onBubbleExpandChanged(false, mRow.getEntry().key);
assertFalse(mBubbleController.isStackExpanded());
+ assertFalse(mStatusBarWindowController.getBubbleExpanded());
}
@Test
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 251cb61..de63d0e 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1710,7 +1710,7 @@
Log.d(TAG, "adjustSreamVolume: postSetAvrcpAbsoluteVolumeIndex index="
+ newIndex + "stream=" + streamType);
}
- mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex);
+ mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
}
// Check if volume update should be send to Hearing Aid
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 95df21e..b63af8a 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -191,8 +191,8 @@
Log.i(TAG, "setAvrcpAbsoluteVolumeIndex index=" + index);
}
AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
- AudioServiceEvents.VolumeEvent.VOL_SET_AVRCP_VOL, index / 10));
- mA2dp.setAvrcpAbsoluteVolume(index / 10);
+ AudioServiceEvents.VolumeEvent.VOL_SET_AVRCP_VOL, index));
+ mA2dp.setAvrcpAbsoluteVolume(index);
}
/*package*/ synchronized int getA2dpCodec(@NonNull BluetoothDevice device) {
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index d20508a..9d9721d 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -4697,7 +4697,7 @@
mSettings.getCurrentUserId(),
mContext.getBasePackageName());
nextIme = mSettings.getSelectedInputMethod();
- nextEnabledImes = getEnabledInputMethodList();
+ nextEnabledImes = mSettings.getEnabledInputMethodListLocked();
final PrintWriter pr = shellCommand.getOutPrintWriter();
pr.println("Reset current and enabled IMEs");
pr.println("Newly selected IME:");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index a0a2f6c..e18da7f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3941,13 +3941,13 @@
if (apex != null) {
try {
final ApexInfo activePkg = apex.getActivePackage(packageName);
- if (activePkg != null) {
+ if (activePkg != null && !TextUtils.isEmpty(activePkg.packagePath)) {
try {
return PackageParser.generatePackageInfoFromApex(
new File(activePkg.packagePath), true /* collect certs */);
} catch (PackageParserException pe) {
- throw new IllegalStateException("Unable to parse: " + activePkg,
- pe);
+ Log.e(TAG, "Unable to parse package at "
+ + activePkg.packagePath, pe);
}
}
} catch (RemoteException e) {
@@ -13426,6 +13426,10 @@
return false;
}
+ if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
+ return false;
+ }
+
boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
// Check if installing from ADB
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index 0371663..cc6cfbb 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -186,6 +186,7 @@
private void preRebootVerification(@NonNull PackageInstallerSession session) {
boolean success = true;
+ // STOPSHIP: TODO(b/123753157): Verify APKs through Package Verifier.
if (!sessionContainsApex(session)) {
// TODO: Decide whether we want to fail fast by detecting signature mismatches for APKs,
// right away.
@@ -336,6 +337,7 @@
PackageInstaller.SessionParams params = originalSession.params.copy();
params.isStaged = false;
+ params.installFlags |= PackageManager.INSTALL_DISABLE_VERIFICATION;
int apkSessionId = mPi.createSession(
params, originalSession.getInstallerPackageName(), originalSession.userId);
PackageInstallerSession apkSession = mPi.getSession(apkSessionId);
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 0f7407b..3586772 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -1780,8 +1780,8 @@
long elapsedNanos, final long wallClockNanos, List<StatsLogEventWrapper> pulledData) {
StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
final long elapsedMillis = SystemClock.elapsedRealtime();
- // Fails every 10 buckets.
- if (mDebugFailingElapsedClockPullCount++ % 10 == 0) {
+ // Fails every 5 buckets.
+ if (mDebugFailingElapsedClockPullCount++ % 5 == 0) {
mDebugFailingElapsedClockPreviousValue = elapsedMillis;
throw new RuntimeException("Failing debug elapsed clock");
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 111808b..18df88b 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -20,8 +20,10 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -3250,6 +3252,7 @@
mInputMethodTarget = target;
mInputMethodTargetWaitingAnim = targetWaitingAnim;
assignWindowLayers(false /* setLayoutNeeded */);
+ mInsetsStateController.onImeTargetChanged(target);
}
boolean getNeedsMenu(WindowState top, WindowManagerPolicy.WindowState bottom) {
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 66666e6..f67b11b 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -26,6 +26,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
import android.view.InsetsState;
@@ -135,6 +136,12 @@
mTmpRect.inset(mWin.mGivenContentInsets);
}
mSource.setFrame(mTmpRect);
+ if (mControl != null) {
+ final Rect frame = mWin.getWindowFrames().mFrame;
+ if (mControl.setSurfacePosition(frame.left, frame.top)) {
+ mStateController.notifyControlChanged(mControllingWin);
+ }
+ }
setServerVisible(mWin.wouldBeVisibleIfPolicyIgnored() && mWin.mPolicyVisibility
&& !mWin.mGivenInsetsPending);
}
@@ -157,7 +164,8 @@
mWin.startAnimation(mDisplayContent.getPendingTransaction(), mAdapter,
!mClientVisible /* hidden */);
mControllingWin = target;
- mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash);
+ mControl = new InsetsSourceControl(mSource.getType(), mAdapter.mCapturedLeash,
+ new Point(mWin.getWindowFrames().mFrame.left, mWin.getWindowFrames().mFrame.top));
}
boolean onInsetsModified(WindowState caller, InsetsSource modifiedSource) {
@@ -213,7 +221,8 @@
public void startAnimation(SurfaceControl animationLeash, Transaction t,
OnAnimationFinishedCallback finishCallback) {
mCapturedLeash = animationLeash;
- t.setPosition(mCapturedLeash, mSource.getFrame().left, mSource.getFrame().top);
+ final Rect frame = mWin.getWindowFrames().mFrame;
+ t.setPosition(mCapturedLeash, frame.left, frame.top);
}
@Override
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index bb0cbb1..afae9c4 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -204,6 +204,11 @@
mTypeWinControlMap.put(type, win);
}
+ void notifyControlChanged(WindowState target) {
+ mPendingControlChanged.add(target);
+ notifyPendingInsetsControlChanged();
+ }
+
private void notifyPendingInsetsControlChanged() {
if (mPendingControlChanged.isEmpty()) {
return;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index caeedee..ab30cda 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1285,47 +1285,45 @@
}
traceEnd();
- if (!mOnlyCore) {
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI)) {
- // Wifi Service must be started first for wifi-related services.
- traceBeginAndSlog("StartWifi");
- mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
- traceEnd();
- traceBeginAndSlog("StartWifiScanning");
- mSystemServiceManager.startService(
- "com.android.server.wifi.scanner.WifiScanningService");
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI)) {
+ // Wifi Service must be started first for wifi-related services.
+ traceBeginAndSlog("StartWifi");
+ mSystemServiceManager.startService(WIFI_SERVICE_CLASS);
+ traceEnd();
+ traceBeginAndSlog("StartWifiScanning");
+ mSystemServiceManager.startService(
+ "com.android.server.wifi.scanner.WifiScanningService");
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_RTT)) {
- traceBeginAndSlog("StartRttService");
- mSystemServiceManager.startService(
- "com.android.server.wifi.rtt.RttService");
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI_RTT)) {
+ traceBeginAndSlog("StartRttService");
+ mSystemServiceManager.startService(
+ "com.android.server.wifi.rtt.RttService");
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_AWARE)) {
- traceBeginAndSlog("StartWifiAware");
- mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI_AWARE)) {
+ traceBeginAndSlog("StartWifiAware");
+ mSystemServiceManager.startService(WIFI_AWARE_SERVICE_CLASS);
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_DIRECT)) {
- traceBeginAndSlog("StartWifiP2P");
- mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_WIFI_DIRECT)) {
+ traceBeginAndSlog("StartWifiP2P");
+ mSystemServiceManager.startService(WIFI_P2P_SERVICE_CLASS);
+ traceEnd();
+ }
- if (context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_LOWPAN)) {
- traceBeginAndSlog("StartLowpan");
- mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
- traceEnd();
- }
+ if (context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LOWPAN)) {
+ traceBeginAndSlog("StartLowpan");
+ mSystemServiceManager.startService(LOWPAN_SERVICE_CLASS);
+ traceEnd();
}
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_ETHERNET) ||
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index 48c8902..11bd29d 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -23,8 +23,10 @@
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.os.Looper;
import android.os.test.TestLooper;
+
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,9 +44,8 @@
private TestLooper mTestLooper = new TestLooper();
private boolean mSendCecCommandSuccess;
private boolean mShouldDispatchReportArcTerminated;
- private boolean mArcEnabled;
- private boolean mSetArcStatusCalled;
private Instrumentation mInstrumentation;
+ @Nullable private Boolean mArcEnabled = null;
@Before
public void setUp() {
@@ -102,7 +103,6 @@
@Override
void setArcStatus(boolean enabled) {
- mSetArcStatusCalled = true;
mArcEnabled = enabled;
}
};
@@ -110,45 +110,38 @@
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
- mArcEnabled = true;
mAction = new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem);
}
@Test
- public void testSendMessage_NotSuccess() {
+ public void testSendMessage_notSuccess() {
mSendCecCommandSuccess = false;
mShouldDispatchReportArcTerminated = false;
- mSetArcStatusCalled = false;
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
mTestLooper.dispatchAll();
- assertThat(mSetArcStatusCalled).isFalse();
- assertThat(mArcEnabled).isTrue();
+ assertThat(mArcEnabled).isNull();
}
@Test
- public void testReportArcTerminated_NotReceived() {
+ public void testReportArcTerminated_notReceived() {
mSendCecCommandSuccess = true;
mShouldDispatchReportArcTerminated = false;
- mSetArcStatusCalled = false;
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
mTestLooper.moveTimeForward(1000);
mTestLooper.dispatchAll();
- assertThat(mSetArcStatusCalled).isFalse();
- assertThat(mArcEnabled).isTrue();
+ assertThat(mArcEnabled).isNull();
}
@Test
- public void testReportArcTerminated_Received() {
+ public void testReportArcTerminated_received() {
mSendCecCommandSuccess = true;
mShouldDispatchReportArcTerminated = true;
- mSetArcStatusCalled = false;
mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
mTestLooper.moveTimeForward(1000);
mTestLooper.dispatchAll();
- assertThat(mSetArcStatusCalled).isTrue();
assertThat(mArcEnabled).isFalse();
}
}
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index f5b4308..37caeb2 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -58,6 +58,8 @@
"util.cc",
"layout_validation.cc",
],
+ // b/123880763, clang-tidy analyzer has segmentation fault with dex_builder.cc
+ tidy_checks: ["-clang-analyzer-*"],
host_supported: true,
}
diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java
index 4da79b3..b407b2a 100644
--- a/telephony/java/android/telephony/AvailableNetworkInfo.java
+++ b/telephony/java/android/telephony/AvailableNetworkInfo.java
@@ -114,7 +114,7 @@
in.readStringList(mMccMncs);
}
- public AvailableNetworkInfo(int subId, int priority, ArrayList<String> mccMncs) {
+ public AvailableNetworkInfo(int subId, int priority, List<String> mccMncs) {
mSubId = subId;
mPriority = priority;
mMccMncs = new ArrayList<String>(mccMncs);
diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java
index a4cce9c..0d4f09f 100644
--- a/telephony/java/android/telephony/CallAttributes.java
+++ b/telephony/java/android/telephony/CallAttributes.java
@@ -117,9 +117,9 @@
CallAttributes s = (CallAttributes) o;
- return (mPreciseCallState == s.mPreciseCallState
+ return (Objects.equals(mPreciseCallState, s.mPreciseCallState)
&& mNetworkType == s.mNetworkType
- && mCallQuality == s.mCallQuality);
+ && Objects.equals(mCallQuality, s.mCallQuality));
}
/**
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index 59f3e1f..19e1931 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -287,11 +287,11 @@
return false;
}
PreciseCallState other = (PreciseCallState) obj;
- return (mRingingCallState != other.mRingingCallState &&
- mForegroundCallState != other.mForegroundCallState &&
- mBackgroundCallState != other.mBackgroundCallState &&
- mDisconnectCause != other.mDisconnectCause &&
- mPreciseDisconnectCause != other.mPreciseDisconnectCause);
+ return (mRingingCallState == other.mRingingCallState
+ && mForegroundCallState == other.mForegroundCallState
+ && mBackgroundCallState == other.mBackgroundCallState
+ && mDisconnectCause == other.mDisconnectCause
+ && mPreciseDisconnectCause == other.mPreciseDisconnectCause);
}
@Override
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 7c3bde4..f2a9340 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -7974,9 +7974,7 @@
* support for the feature and device firmware support.
*
* @return {@code true} if the device and carrier both support RTT, {@code false} otherwise.
- * @hide
*/
- @TestApi
public boolean isRttSupported() {
try {
ITelephony telephony = getITelephony();
@@ -9702,10 +9700,10 @@
*
* <p>
* Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
* @hide
*/
- @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isOpportunisticNetworkEnabled() {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
boolean isEnabled = false;
@@ -10093,12 +10091,17 @@
* Get preferred opportunistic data subscription Id
*
* <p>Requires that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}),
- * or has permission {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}.
+ * or has either READ_PRIVILEGED_PHONE_STATE
+ * or {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} permission.
* @return subId preferred opportunistic subscription id or
* {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} if there are no preferred
* subscription id
*
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+ android.Manifest.permission.READ_PHONE_STATE
+ })
public int getPreferredOpportunisticDataSubscription() {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 4d95e55..d8d2d9e 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -465,7 +465,7 @@
public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511;
/**
- * Upgrade Downgrade request cacncelled by the user who initiated it
+ * Upgrade Downgrade request cancelled by the user who initiated it
*/
public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512;
@@ -887,6 +887,185 @@
public static final int CODE_OEM_CAUSE_15 = 0xf00f;
/**
+ * @hide
+ */
+ @IntDef(value = {
+ CODE_UNSPECIFIED,
+ CODE_LOCAL_ILLEGAL_ARGUMENT,
+ CODE_LOCAL_ILLEGAL_STATE,
+ CODE_LOCAL_INTERNAL_ERROR,
+ CODE_LOCAL_IMS_SERVICE_DOWN,
+ CODE_LOCAL_NO_PENDING_CALL,
+ CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE,
+ CODE_LOCAL_POWER_OFF,
+ CODE_LOCAL_LOW_BATTERY,
+ CODE_LOCAL_NETWORK_NO_SERVICE,
+ CODE_LOCAL_NETWORK_NO_LTE_COVERAGE,
+ CODE_LOCAL_NETWORK_ROAMING,
+ CODE_LOCAL_NETWORK_IP_CHANGED,
+ CODE_LOCAL_SERVICE_UNAVAILABLE,
+ CODE_LOCAL_NOT_REGISTERED,
+ CODE_LOCAL_CALL_EXCEEDED,
+ CODE_LOCAL_CALL_BUSY,
+ CODE_LOCAL_CALL_DECLINE,
+ CODE_LOCAL_CALL_VCC_ON_PROGRESSING,
+ CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED,
+ CODE_LOCAL_CALL_CS_RETRY_REQUIRED,
+ CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED,
+ CODE_LOCAL_CALL_TERMINATED,
+ CODE_LOCAL_HO_NOT_FEASIBLE,
+ CODE_TIMEOUT_1XX_WAITING,
+ CODE_TIMEOUT_NO_ANSWER,
+ CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE,
+ CODE_CALL_BARRED,
+ CODE_FDN_BLOCKED,
+ CODE_IMEI_NOT_ACCEPTED,
+ CODE_DIAL_MODIFIED_TO_USSD,
+ CODE_DIAL_MODIFIED_TO_SS,
+ CODE_DIAL_MODIFIED_TO_DIAL,
+ CODE_DIAL_MODIFIED_TO_DIAL_VIDEO,
+ CODE_DIAL_VIDEO_MODIFIED_TO_DIAL,
+ CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO,
+ CODE_DIAL_VIDEO_MODIFIED_TO_SS,
+ CODE_DIAL_VIDEO_MODIFIED_TO_USSD,
+ CODE_SIP_REDIRECTED,
+ CODE_SIP_BAD_REQUEST,
+ CODE_SIP_FORBIDDEN,
+ CODE_SIP_NOT_FOUND,
+ CODE_SIP_NOT_SUPPORTED,
+ CODE_SIP_REQUEST_TIMEOUT,
+ CODE_SIP_TEMPRARILY_UNAVAILABLE,
+ CODE_SIP_BAD_ADDRESS,
+ CODE_SIP_BUSY,
+ CODE_SIP_REQUEST_CANCELLED,
+ CODE_SIP_NOT_ACCEPTABLE,
+ CODE_SIP_NOT_REACHABLE,
+ CODE_SIP_CLIENT_ERROR,
+ CODE_SIP_TRANSACTION_DOES_NOT_EXIST,
+ CODE_SIP_SERVER_INTERNAL_ERROR,
+ CODE_SIP_SERVICE_UNAVAILABLE,
+ CODE_SIP_SERVER_TIMEOUT,
+ CODE_SIP_SERVER_ERROR,
+ CODE_SIP_USER_REJECTED,
+ CODE_SIP_GLOBAL_ERROR,
+ CODE_EMERGENCY_TEMP_FAILURE,
+ CODE_EMERGENCY_PERM_FAILURE,
+ CODE_SIP_USER_MARKED_UNWANTED,
+ CODE_SIP_METHOD_NOT_ALLOWED,
+ CODE_SIP_PROXY_AUTHENTICATION_REQUIRED,
+ CODE_SIP_REQUEST_ENTITY_TOO_LARGE,
+ CODE_SIP_REQUEST_URI_TOO_LARGE,
+ CODE_SIP_EXTENSION_REQUIRED,
+ CODE_SIP_INTERVAL_TOO_BRIEF,
+ CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST,
+ CODE_SIP_LOOP_DETECTED,
+ CODE_SIP_TOO_MANY_HOPS,
+ CODE_SIP_AMBIGUOUS,
+ CODE_SIP_REQUEST_PENDING,
+ CODE_SIP_UNDECIPHERABLE,
+ CODE_MEDIA_INIT_FAILED,
+ CODE_MEDIA_NO_DATA,
+ CODE_MEDIA_NOT_ACCEPTABLE,
+ CODE_MEDIA_UNSPECIFIED,
+ CODE_USER_TERMINATED,
+ CODE_USER_NOANSWER,
+ CODE_USER_IGNORE,
+ CODE_USER_DECLINE,
+ CODE_LOW_BATTERY,
+ CODE_BLACKLISTED_CALL_ID,
+ CODE_USER_TERMINATED_BY_REMOTE,
+ CODE_USER_REJECTED_SESSION_MODIFICATION,
+ CODE_USER_CANCELLED_SESSION_MODIFICATION,
+ CODE_SESSION_MODIFICATION_FAILED,
+ CODE_UT_NOT_SUPPORTED,
+ CODE_UT_SERVICE_UNAVAILABLE,
+ CODE_UT_OPERATION_NOT_ALLOWED,
+ CODE_UT_NETWORK_ERROR,
+ CODE_UT_CB_PASSWORD_MISMATCH,
+ CODE_UT_SS_MODIFIED_TO_DIAL,
+ CODE_UT_SS_MODIFIED_TO_USSD,
+ CODE_UT_SS_MODIFIED_TO_SS,
+ CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO,
+ CODE_ECBM_NOT_SUPPORTED,
+ CODE_MULTIENDPOINT_NOT_SUPPORTED,
+ CODE_REGISTRATION_ERROR,
+ CODE_ANSWERED_ELSEWHERE,
+ CODE_CALL_PULL_OUT_OF_SYNC,
+ CODE_CALL_END_CAUSE_CALL_PULL,
+ CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE,
+ CODE_REJECTED_ELSEWHERE,
+ CODE_SUPP_SVC_FAILED,
+ CODE_SUPP_SVC_CANCELLED,
+ CODE_SUPP_SVC_REINVITE_COLLISION,
+ CODE_IWLAN_DPD_FAILURE,
+ CODE_EPDG_TUNNEL_ESTABLISH_FAILURE,
+ CODE_EPDG_TUNNEL_REKEY_FAILURE,
+ CODE_EPDG_TUNNEL_LOST_CONNECTION,
+ CODE_MAXIMUM_NUMBER_OF_CALLS_REACHED,
+ CODE_REMOTE_CALL_DECLINE,
+ CODE_DATA_LIMIT_REACHED,
+ CODE_DATA_DISABLED,
+ CODE_WIFI_LOST,
+ CODE_IKEV2_AUTH_FAILURE,
+ CODE_RADIO_OFF,
+ CODE_NO_VALID_SIM,
+ CODE_RADIO_INTERNAL_ERROR,
+ CODE_NETWORK_RESP_TIMEOUT,
+ CODE_NETWORK_REJECT,
+ CODE_RADIO_ACCESS_FAILURE,
+ CODE_RADIO_LINK_FAILURE,
+ CODE_RADIO_LINK_LOST,
+ CODE_RADIO_UPLINK_FAILURE,
+ CODE_RADIO_SETUP_FAILURE,
+ CODE_RADIO_RELEASE_NORMAL,
+ CODE_RADIO_RELEASE_ABNORMAL,
+ CODE_ACCESS_CLASS_BLOCKED,
+ CODE_NETWORK_DETACH,
+ CODE_SIP_ALTERNATE_EMERGENCY_CALL,
+ CODE_UNOBTAINABLE_NUMBER,
+ CODE_NO_CSFB_IN_CS_ROAM,
+ CODE_REJECT_UNKNOWN,
+ CODE_REJECT_ONGOING_CALL_WAITING_DISABLED,
+ CODE_REJECT_CALL_ON_OTHER_SUB,
+ CODE_REJECT_1X_COLLISION,
+ CODE_REJECT_SERVICE_NOT_REGISTERED,
+ CODE_REJECT_CALL_TYPE_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_E911_CALL,
+ CODE_REJECT_ONGOING_CALL_SETUP,
+ CODE_REJECT_MAX_CALL_LIMIT_REACHED,
+ CODE_REJECT_UNSUPPORTED_SIP_HEADERS,
+ CODE_REJECT_UNSUPPORTED_SDP_HEADERS,
+ CODE_REJECT_ONGOING_CALL_TRANSFER,
+ CODE_REJECT_INTERNAL_ERROR,
+ CODE_REJECT_QOS_FAILURE,
+ CODE_REJECT_ONGOING_HANDOVER,
+ CODE_REJECT_VT_TTY_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_CALL_UPGRADE,
+ CODE_REJECT_CONFERENCE_TTY_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_CONFERENCE_CALL,
+ CODE_REJECT_VT_AVPF_NOT_ALLOWED,
+ CODE_REJECT_ONGOING_ENCRYPTED_CALL,
+ CODE_REJECT_ONGOING_CS_CALL,
+ CODE_OEM_CAUSE_1,
+ CODE_OEM_CAUSE_2,
+ CODE_OEM_CAUSE_3,
+ CODE_OEM_CAUSE_4,
+ CODE_OEM_CAUSE_5,
+ CODE_OEM_CAUSE_6,
+ CODE_OEM_CAUSE_7,
+ CODE_OEM_CAUSE_8,
+ CODE_OEM_CAUSE_9,
+ CODE_OEM_CAUSE_10,
+ CODE_OEM_CAUSE_11,
+ CODE_OEM_CAUSE_12,
+ CODE_OEM_CAUSE_13,
+ CODE_OEM_CAUSE_14,
+ CODE_OEM_CAUSE_15
+ }, prefix = "CODE_")
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ImsCode {}
+
+ /**
* Network string error messages.
* mExtraMessage may have these values.
*/
@@ -964,7 +1143,7 @@
/**
* @return an integer representing more information about the completion of an operation.
*/
- public int getCode() {
+ public @ImsCode int getCode() {
return mCode;
}
diff --git a/telephony/java/android/telephony/mbms/GroupCallCallback.java b/telephony/java/android/telephony/mbms/GroupCallCallback.java
index 77e36bb..603f4e6 100644
--- a/telephony/java/android/telephony/mbms/GroupCallCallback.java
+++ b/telephony/java/android/telephony/mbms/GroupCallCallback.java
@@ -57,7 +57,7 @@
* @param errorCode The error code.
* @param message A human-readable message generated by the middleware for debugging purposes.
*/
- void onError(@GroupCallError int errorCode, @Nullable String message);
+ default void onError(@GroupCallError int errorCode, @Nullable String message) {}
/**
* Called to indicate this call has changed state.
@@ -65,8 +65,8 @@
* See {@link GroupCall#STATE_STOPPED}, {@link GroupCall#STATE_STARTED}
* and {@link GroupCall#STATE_STALLED}.
*/
- void onGroupCallStateChanged(@GroupCall.GroupCallState int state,
- @GroupCall.GroupCallStateChangeReason int reason);
+ default void onGroupCallStateChanged(@GroupCall.GroupCallState int state,
+ @GroupCall.GroupCallStateChangeReason int reason) {}
/**
* Broadcast Signal Strength updated.
@@ -78,5 +78,6 @@
* {@link #SIGNAL_STRENGTH_UNAVAILABLE} if broadcast is not available
* for this call due to timing, geography or popularity.
*/
- void onBroadcastSignalStrengthUpdated(@IntRange(from = -1, to = 4) int signalStrength);
+ default void onBroadcastSignalStrengthUpdated(
+ @IntRange(from = -1, to = 4) int signalStrength) {}
}
diff --git a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
index 04e7ba1..ac7e172 100644
--- a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
+++ b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java
@@ -57,7 +57,7 @@
* @param errorCode The error code.
* @param message A human-readable message generated by the middleware for debugging purposes.
*/
- void onError(@GroupCallError int errorCode, @Nullable String message);
+ default void onError(@GroupCallError int errorCode, @Nullable String message) {}
/**
* Indicates that the list of currently available SAIs has been updated. The app may use this
@@ -70,8 +70,8 @@
* @param availableSais A list of lists of available SAIS in neighboring cells, where each list
* contains the available SAIs in an individual cell.
*/
- void onAvailableSaisUpdated(@NonNull List<Integer> currentSais,
- @NonNull List<List<Integer>> availableSais);
+ default void onAvailableSaisUpdated(@NonNull List<Integer> currentSais,
+ @NonNull List<List<Integer>> availableSais) {}
/**
* Called soon after the app calls {@link MbmsGroupCallSession#create}. The information supplied
@@ -85,7 +85,7 @@
* @param interfaceName The interface name for the data link.
* @param index The index for the data link.
*/
- void onServiceInterfaceAvailable(@NonNull String interfaceName, int index);
+ default void onServiceInterfaceAvailable(@NonNull String interfaceName, int index) {}
/**
* Called to indicate that the middleware has been initialized and is ready.
@@ -95,5 +95,5 @@
* delivered via {@link #onError(int, String)} with error code
* {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}.
*/
- void onMiddlewareReady();
+ default void onMiddlewareReady() {}
}