diff options
57 files changed, 990 insertions, 266 deletions
diff --git a/api/current.txt b/api/current.txt index 9dec22e7ca65..ad321c6288b3 100644 --- a/api/current.txt +++ b/api/current.txt @@ -44136,7 +44136,7 @@ package android.telephony { } 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 @@ package android.telephony { 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 @@ package android.telephony { 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 @@ package android.telephony.mbms { } 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 @@ package android.telephony.mbms { } 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 2a9a149063a7..ca1f0cce0215 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1761,6 +1761,7 @@ package android.provider { 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 @@ package android.telephony { 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 eaba9bee6bf0..40a4070d2974 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -559,7 +559,7 @@ void LogEvent::init(android_log_context context) { // 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 @@ void LogEvent::init(android_log_context context) { // 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 @@ void LogEvent::init(android_log_context context) { } // 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 3a5be43ed695..eec3c735057c 100644 --- a/cmds/statsd/tests/LogEvent_test.cpp +++ b/cmds/statsd/tests/LogEvent_test.cpp @@ -155,7 +155,7 @@ TEST(LogEventTest, TestKeyValuePairsAtomParsing) { 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 @@ TEST(LogEventTest, TestKeyValuePairsAtomParsing) { 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 @@ TEST(LogEventTest, TestKeyValuePairsAtomParsing) { 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 @@ TEST(LogEventTest, TestKeyValuePairsAtomParsing) { 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 @@ TEST(LogEventTest, TestKeyValuePairsAtomParsing) { 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 @@ TEST(LogEventTest, TestKeyValuePairsAtomParsing) { 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 9ee2f039ce3f..ea145f0b9d21 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -4485,6 +4485,7 @@ public class AppOpsManager { * @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 @@ public class AppOpsManager { */ @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 @@ public class AppOpsManager { * @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 @@ public class AppOpsManager { * @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 @@ public class AppOpsManager { 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 @@ public class AppOpsManager { // 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 e2907e219b1f..6e52b33692c8 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -866,6 +866,14 @@ public abstract class PackageManager { */ 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 b2288fc4492d..87568e857d6d 100644 --- a/core/java/android/ddm/DdmHandleHello.java +++ b/core/java/android/ddm/DdmHandleHello.java @@ -16,14 +16,16 @@ package android.ddm; -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 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 java.nio.ByteBuffer; /** @@ -35,6 +37,8 @@ public class DdmHandleHello extends ChunkHandler { 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 @@ public class DdmHandleHello extends ChunkHandler { + 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 843db6d28d30..ffae361e76d4 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -51,6 +51,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub 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 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub 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 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub } @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 333cfbd400dd..ab630fd7467b 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -592,7 +592,6 @@ public class InputMethodService extends AbstractInputMethodService { 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 @@ public class InputMethodService extends AbstractInputMethodService { } } + 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 @@ public class InputMethodService extends AbstractInputMethodService { } 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 b4b541dc5cd0..31c948a14698 100644 --- a/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java +++ b/core/java/android/inputmethodservice/MultiClientInputMethodClientCallbackAdaptor.java @@ -290,6 +290,12 @@ final class MultiClientInputMethodClientCallbackAdaptor { 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 141d33bc4145..1f3369376b10 100644 --- a/core/java/android/os/AsyncTask.java +++ b/core/java/android/os/AsyncTask.java @@ -19,6 +19,7 @@ package android.os; 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 @@ import java.util.concurrent.atomic.AtomicInteger; * 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 @@ import java.util.concurrent.atomic.AtomicInteger; * </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 @@ public abstract class AsyncTask<Params, Progress, Result> { * 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 @@ public abstract class AsyncTask<Params, Progress, Result> { /** * 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 @@ public abstract class AsyncTask<Params, Progress, Result> { /** * <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 @@ public abstract class AsyncTask<Params, Progress, Result> { /** * 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 @@ public abstract class AsyncTask<Params, Progress, Result> { /** * <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 @@ public abstract class AsyncTask<Params, Progress, Result> { * 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 ddec688931cb..68f9288a93cf 100644 --- a/core/java/android/os/GraphicsEnvironment.java +++ b/core/java/android/os/GraphicsEnvironment.java @@ -103,7 +103,7 @@ public class GraphicsEnvironment { * 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { // 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 @@ public class GraphicsEnvironment { } } - 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { } 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { * 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 @@ public class GraphicsEnvironment { * - 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { * 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { // 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { * 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 @@ public class GraphicsEnvironment { // 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 @@ public class GraphicsEnvironment { // 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 @@ public class GraphicsEnvironment { } return; } - boolean isOptIn = + final boolean isOptIn = getGlobalSettingsString(coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS) .contains(ai.packageName); if (!isOptIn @@ -563,13 +560,13 @@ public class GraphicsEnvironment { // 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 @@ public class GraphicsEnvironment { } } - 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 @@ public class GraphicsEnvironment { 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 @@ public class GraphicsEnvironment { * 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 @@ public class GraphicsEnvironment { } 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 0743c23080fd..67c840006948 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -110,6 +110,16 @@ public final class MediaStore { 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 7026d2b1389c..2ba1e016e03d 100644 --- a/core/java/android/view/ImeInsetsSourceConsumer.java +++ b/core/java/android/view/ImeInsetsSourceConsumer.java @@ -18,10 +18,10 @@ package android.view; 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 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { return; } - if (setVisible) { - mController.show(Type.IME); - } else { - mController.hide(Type.IME); - } + mController.applyImeVisibility(setVisible); } @Override @@ -91,6 +87,30 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { 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 625ddc2549cc..583651dee379 100644 --- a/core/java/android/view/InsetsAnimationControlImpl.java +++ b/core/java/android/view/InsetsAnimationControlImpl.java @@ -180,9 +180,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll 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 93a6741ae303..7ad97a6d393e 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -29,10 +29,13 @@ import android.graphics.Rect; 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 @@ public class InsetsController implements WindowInsetsController { 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 @@ public class InsetsController implements WindowInsetsController { private ObjectAnimator mAnimator; private @AnimationDirection int mAnimationDirection; + private int mPendingTypesToShow; + public InsetsController(ViewRootImpl viewRoot) { mViewRoot = viewRoot; mAnimCallback = () -> { @@ -196,6 +202,12 @@ public class InsetsController implements WindowInsetsController { @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 @@ public class InsetsController implements WindowInsetsController { // 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 @@ public class InsetsController implements WindowInsetsController { 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 @@ public class InsetsController implements WindowInsetsController { 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 @@ public class InsetsController implements WindowInsetsController { } } - 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 @@ public class InsetsController implements WindowInsetsController { // 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 cccfd870a3e4..eab83ce34708 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 @@ import java.util.function.Supplier; */ 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 @@ public class InsetsSourceConsumer { 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 9383e6c57854..9fb6bdba48e3 100644 --- a/core/java/android/view/InsetsSourceControl.java +++ b/core/java/android/view/InsetsSourceControl.java @@ -29,10 +29,13 @@ public class InsetsSourceControl implements Parcelable { 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 class InsetsSourceControl implements Parcelable { 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 class InsetsSourceControl implements Parcelable { 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 9a317db84f5d..61fb38f8298f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -180,7 +180,7 @@ public final class ViewRootImpl implements ViewParent, * @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 7fee3ef29a09..ce94cb064416 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1887,6 +1887,36 @@ public final class InputMethodManager { } /** + * 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 de15f332d51d..eb81628f9e27 100644 --- a/core/java/android/view/inputmethod/InputMethodSession.java +++ b/core/java/android/view/inputmethod/InputMethodSession.java @@ -184,4 +184,11 @@ public interface InputMethodSession { * 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 794238a3826e..664643cc9b4d 100644 --- a/core/java/com/android/internal/view/IInputMethodSession.aidl +++ b/core/java/com/android/internal/view/IInputMethodSession.aidl @@ -48,4 +48,6 @@ oneway interface IInputMethodSession { 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 b07cb99f35c5..da81d176de8a 100644 --- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java +++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java @@ -24,6 +24,7 @@ import static junit.framework.Assert.assertTrue; 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 @@ public class ImeInsetsSourceConsumerTest { @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 7cd3c44d9a4e..71ce02d859f5 100644 --- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java +++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java @@ -19,13 +19,23 @@ package android.view; 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 @@ public class InsetsAnimationControlImplTest { private SurfaceSession mSession = new SurfaceSession(); private SurfaceControl mTopLeash; private SurfaceControl mNavLeash; + private InsetsState mInsetsState; @Mock Transaction mMockTransaction; @Mock InsetsController mMockController; @@ -63,6 +74,7 @@ public class InsetsAnimationControlImplTest { @Before public void setup() { + ViewRootImpl.sNewInsetsMode = NEW_INSETS_MODE_FULL; MockitoAnnotations.initMocks(this); mTopLeash = new SurfaceControl.Builder(mSession) .setName("testSurface") @@ -70,24 +82,25 @@ public class InsetsAnimationControlImplTest { 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 @@ public class InsetsAnimationControlImplTest { 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 8f2109676dfb..6dad6a22f7ea 100644 --- a/core/tests/coretests/src/android/view/InsetsControllerTest.java +++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java @@ -27,6 +27,7 @@ import static junit.framework.Assert.assertTrue; 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 @@ public class InsetsControllerTest { 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 @@ public class InsetsControllerTest { @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 @@ public class InsetsControllerTest { @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 @@ public class InsetsControllerTest { mController.show(Type.ime()); mController.cancelExistingAnimation(); + // no focused view, no IME. + assertFalse(mController.getSourceConsumer(ime.getType()).isVisible()); + }); + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); + } + + @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(); + } - mController.hide(Type.ime()); + @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 82cd2131ab4e..66146c936dca 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.reset; 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 @@ public class InsetsSourceConsumerTest { .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 @@ public class InsetsSourceConsumerTest { 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 035ee108c6da..bb4765835890 100644 --- a/data/etc/Android.bp +++ b/data/etc/Android.bp @@ -58,6 +58,14 @@ prebuilt_etc { } 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 000000000000..ccdb21fa5040 --- /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 2e7b9981f965..4ef5adb78b6c 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -49,17 +49,6 @@ applications that come with the platform <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 b67aea224055..d9456355cb88 100644 --- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp +++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp @@ -142,10 +142,8 @@ void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor, 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 2f8d381f15f5..fe2d41ef630b 100644 --- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp +++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp @@ -43,7 +43,9 @@ VkFunctorDrawHandler::VkFunctorDrawHandler(sp<WebViewFunctor::Handle> functor_ha , mImageInfo(image_info) {} VkFunctorDrawHandler::~VkFunctorDrawHandler() { - mFunctorHandle->postDrawVk(); + if (mDrawn) { + mFunctorHandle->postDrawVk(); + } } void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { @@ -77,6 +79,7 @@ void VkFunctorDrawHandler::draw(const GrBackendDrawableInfo& info) { 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 1a53c8fd55db..d3f97773b91d 100644 --- a/libs/hwui/pipeline/skia/VkFunctorDrawable.h +++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.h @@ -44,6 +44,8 @@ private: 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 925ca0dd8a7d..f7afa31e6173 100644 --- a/media/apex/java/android/media/MediaPlayer2.java +++ b/media/apex/java/android/media/MediaPlayer2.java @@ -86,6 +86,12 @@ import java.util.concurrent.atomic.AtomicLong; /** * 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 6deb47f09347..e43a60c3f396 100644 --- a/native/webview/plat_support/draw_functor.cpp +++ b/native/webview/plat_support/draw_functor.cpp @@ -177,9 +177,6 @@ int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) { 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 404f2e541ba2..9a9a52f40227 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 @@ public class BubbleController { * 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 40f2392d2610..974de4b87ebc 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 static com.android.systemui.recents.OverviewProxyService.TAG_OPS; 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 @@ import com.android.systemui.shared.recents.utilities.Utilities; */ 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 @@ public class QuickSwitchAction extends NavigationGestureAction { @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 @@ public class QuickSwitchAction extends NavigationGestureAction { @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 ffaa236218fb..86e17f33fc77 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 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat 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 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat 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 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat 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 e32d48d2ab94..49b4641399f1 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 @@ public class BubbleControllerTest extends SysuiTestCase { // 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 @@ public class BubbleControllerTest extends SysuiTestCase { 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 251cb61c3de8..de63d0ef8edf 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 @@ public class AudioService extends IAudioService.Stub 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 95df21e729e4..b63af8a31cd9 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 @@ public class BtHelper { 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 d20508a5e704..9d9721d5d402 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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 a0a2f6c6d70c..e18da7f7b319 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 @@ public class PackageManagerService extends IPackageManager.Stub 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 @@ public class PackageManagerService extends IPackageManager.Stub 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 03716638bbeb..cc6cfbb33fd0 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 @@ public class StagingManager { 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 @@ public class StagingManager { 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 0f7407bdd72a..35867728f2c9 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 @@ public class StatsCompanionService extends IStatsCompanionService.Stub { 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 111808b54802..18df88b37c61 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.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LE 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 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo 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 66666e681e7a..f67b11b26b12 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 static android.view.ViewRootImpl.sNewInsetsMode; 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 @@ class InsetsSourceProvider { 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 @@ class InsetsSourceProvider { 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 @@ class InsetsSourceProvider { 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 bb0cbb1de470..afae9c4ac228 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 @@ class InsetsStateController { 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 caeedeeaf182..ab30cda271f0 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -1285,47 +1285,45 @@ public final class SystemServer { } 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 48c89025e865..11bd29d8a163 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.hdmi.HdmiDeviceInfo; 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 @@ public class ArcTerminationActionFromAvrTest { 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 @@ public class ArcTerminationActionFromAvrTest { @Override void setArcStatus(boolean enabled) { - mSetArcStatusCalled = true; mArcEnabled = enabled; } }; @@ -110,45 +110,38 @@ public class ArcTerminationActionFromAvrTest { 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 f5b4308a1b50..37caeb2044ff 100644 --- a/startop/view_compiler/Android.bp +++ b/startop/view_compiler/Android.bp @@ -58,6 +58,8 @@ cc_library_static { "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 4da79b34a55e..b407b2a03bc4 100644 --- a/telephony/java/android/telephony/AvailableNetworkInfo.java +++ b/telephony/java/android/telephony/AvailableNetworkInfo.java @@ -114,7 +114,7 @@ public final class AvailableNetworkInfo implements Parcelable { 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 a4cce9c9a7b9..0d4f09f98b43 100644 --- a/telephony/java/android/telephony/CallAttributes.java +++ b/telephony/java/android/telephony/CallAttributes.java @@ -117,9 +117,9 @@ public class CallAttributes implements Parcelable { 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 59f3e1f0e7f7..19e1931a30df 100644 --- a/telephony/java/android/telephony/PreciseCallState.java +++ b/telephony/java/android/telephony/PreciseCallState.java @@ -287,11 +287,11 @@ public final class PreciseCallState implements Parcelable { 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 7c3bde4293c7..f2a93400fd13 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -7974,9 +7974,7 @@ public class TelephonyManager { * 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 @@ public class TelephonyManager { * * <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 @@ public class TelephonyManager { * 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 4d95e552c1da..d8d2d9e5951a 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -465,7 +465,7 @@ public final class ImsReasonInfo implements Parcelable { 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 final class ImsReasonInfo implements Parcelable { 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 @@ public final class ImsReasonInfo implements Parcelable { /** * @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 77e36bbcf2ae..603f4e6d2030 100644 --- a/telephony/java/android/telephony/mbms/GroupCallCallback.java +++ b/telephony/java/android/telephony/mbms/GroupCallCallback.java @@ -57,7 +57,7 @@ public interface GroupCallCallback { * @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 @@ public interface GroupCallCallback { * 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 @@ public interface GroupCallCallback { * {@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 04e7ba1af372..ac7e17271e34 100644 --- a/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java +++ b/telephony/java/android/telephony/mbms/MbmsGroupCallSessionCallback.java @@ -57,7 +57,7 @@ public interface MbmsGroupCallSessionCallback { * @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 @@ public interface MbmsGroupCallSessionCallback { * @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 @@ public interface MbmsGroupCallSessionCallback { * @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 @@ public interface MbmsGroupCallSessionCallback { * delivered via {@link #onError(int, String)} with error code * {@link MbmsErrors.GeneralErrors#ERROR_MIDDLEWARE_NOT_YET_READY}. */ - void onMiddlewareReady(); + default void onMiddlewareReady() {} } |