diff options
25 files changed, 468 insertions, 86 deletions
diff --git a/api/current.txt b/api/current.txt index 3ff1ad598694..8be92566f31d 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5608,8 +5608,6 @@ package android.app { method public void enableCarMode(int); method public int getCurrentModeType(); method public int getNightMode(); - method public boolean isNightModeLocked(); - method public boolean isUiModeLocked(); method public void setNightMode(int); field public static java.lang.String ACTION_ENTER_CAR_MODE; field public static java.lang.String ACTION_ENTER_DESK_MODE; @@ -34542,7 +34540,7 @@ package android.service.notification { method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap); method public final void requestInterruptionFilter(int); method public final void requestListenerHints(int); - method public static final void requestRebind(android.content.ComponentName) throws android.os.RemoteException; + method public static void requestRebind(android.content.ComponentName) throws android.os.RemoteException; method public final void requestUnbind() throws android.os.RemoteException; method public final void setNotificationsShown(java.lang.String[]); field public static final java.lang.String CATEGORY_VR_NOTIFICATIONS = "android.intent.category.vr.notifications"; @@ -50674,6 +50672,7 @@ package java.lang { } public abstract interface Iterable { + method public default void forEach(java.util.function.Consumer<? super T>); method public abstract java.util.Iterator<T> iterator(); } @@ -54149,6 +54148,7 @@ package java.security { public abstract class Provider extends java.util.Properties { ctor protected Provider(java.lang.String, double, java.lang.String); + method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>); method public java.lang.String getInfo(); method public java.lang.String getName(); method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String); @@ -57098,6 +57098,7 @@ package java.util { ctor public ArrayList(java.util.Collection<? extends E>); method public java.lang.Object clone(); method public void ensureCapacity(int); + method public void forEach(java.util.function.Consumer<? super E>); method public E get(int); method public int size(); method public void trimToSize(); @@ -57661,6 +57662,7 @@ package java.util { ctor public HashMap(java.util.Map<? extends K, ? extends V>); method public java.lang.Object clone(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } public class HashSet extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set { @@ -57685,6 +57687,7 @@ package java.util { method public boolean containsValue(java.lang.Object); method public synchronized java.util.Enumeration<V> elements(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public synchronized V get(java.lang.Object); method public synchronized boolean isEmpty(); method public java.util.Set<K> keySet(); @@ -57703,6 +57706,7 @@ package java.util { ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>); method public java.lang.Object clone(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } public class IllegalFormatCodePointException extends java.util.IllegalFormatException { @@ -57942,6 +57946,7 @@ package java.util { method public abstract boolean containsValue(java.lang.Object); method public abstract java.util.Set<java.util.Map.Entry<K, V>> entrySet(); method public abstract boolean equals(java.lang.Object); + method public default void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public abstract V get(java.lang.Object); method public abstract int hashCode(); method public abstract boolean isEmpty(); @@ -58403,6 +58408,7 @@ package java.util { method public K firstKey(); method public java.util.Map.Entry<K, V> floorEntry(K); method public K floorKey(K); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public java.util.NavigableMap<K, V> headMap(K, boolean); method public java.util.SortedMap<K, V> headMap(K); method public java.util.Map.Entry<K, V> higherEntry(K); @@ -58485,6 +58491,7 @@ package java.util { method public java.util.Enumeration<E> elements(); method public synchronized void ensureCapacity(int); method public synchronized E firstElement(); + method public synchronized void forEach(java.util.function.Consumer<? super E>); method public synchronized E get(int); method public synchronized int indexOf(java.lang.Object, int); method public synchronized void insertElementAt(E, int); @@ -58508,6 +58515,7 @@ package java.util { ctor public WeakHashMap(); ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } } diff --git a/api/system-current.txt b/api/system-current.txt index 8c77b4739f83..96c903cce55b 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5740,8 +5740,6 @@ package android.app { method public void enableCarMode(int); method public int getCurrentModeType(); method public int getNightMode(); - method public boolean isNightModeLocked(); - method public boolean isUiModeLocked(); method public void setNightMode(int); field public static java.lang.String ACTION_ENTER_CAR_MODE; field public static java.lang.String ACTION_ENTER_DESK_MODE; @@ -37031,6 +37029,7 @@ package android.service.notification { public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService { ctor public NotificationAssistantService(); method public final void adjustImportance(java.lang.String, android.service.notification.NotificationAssistantService.Adjustment); + method public final android.os.IBinder onBind(android.content.Intent); method public void onNotificationActionClick(java.lang.String, long, int); method public void onNotificationClick(java.lang.String, long); method public abstract android.service.notification.NotificationAssistantService.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification, int, boolean); @@ -37083,7 +37082,7 @@ package android.service.notification { method public void registerAsSystemService(android.content.Context, android.content.ComponentName, int) throws android.os.RemoteException; method public final void requestInterruptionFilter(int); method public final void requestListenerHints(int); - method public static final void requestRebind(android.content.ComponentName) throws android.os.RemoteException; + method public static void requestRebind(android.content.ComponentName) throws android.os.RemoteException; method public final void requestUnbind() throws android.os.RemoteException; method public final void setNotificationsShown(java.lang.String[]); method public final void setOnNotificationPostedTrim(int); @@ -53794,6 +53793,7 @@ package java.lang { } public abstract interface Iterable { + method public default void forEach(java.util.function.Consumer<? super T>); method public abstract java.util.Iterator<T> iterator(); } @@ -57269,6 +57269,7 @@ package java.security { public abstract class Provider extends java.util.Properties { ctor protected Provider(java.lang.String, double, java.lang.String); + method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>); method public java.lang.String getInfo(); method public java.lang.String getName(); method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String); @@ -60218,6 +60219,7 @@ package java.util { ctor public ArrayList(java.util.Collection<? extends E>); method public java.lang.Object clone(); method public void ensureCapacity(int); + method public void forEach(java.util.function.Consumer<? super E>); method public E get(int); method public int size(); method public void trimToSize(); @@ -60781,6 +60783,7 @@ package java.util { ctor public HashMap(java.util.Map<? extends K, ? extends V>); method public java.lang.Object clone(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } public class HashSet extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set { @@ -60805,6 +60808,7 @@ package java.util { method public boolean containsValue(java.lang.Object); method public synchronized java.util.Enumeration<V> elements(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public synchronized V get(java.lang.Object); method public synchronized boolean isEmpty(); method public java.util.Set<K> keySet(); @@ -60823,6 +60827,7 @@ package java.util { ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>); method public java.lang.Object clone(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } public class IllegalFormatCodePointException extends java.util.IllegalFormatException { @@ -61062,6 +61067,7 @@ package java.util { method public abstract boolean containsValue(java.lang.Object); method public abstract java.util.Set<java.util.Map.Entry<K, V>> entrySet(); method public abstract boolean equals(java.lang.Object); + method public default void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public abstract V get(java.lang.Object); method public abstract int hashCode(); method public abstract boolean isEmpty(); @@ -61523,6 +61529,7 @@ package java.util { method public K firstKey(); method public java.util.Map.Entry<K, V> floorEntry(K); method public K floorKey(K); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public java.util.NavigableMap<K, V> headMap(K, boolean); method public java.util.SortedMap<K, V> headMap(K); method public java.util.Map.Entry<K, V> higherEntry(K); @@ -61605,6 +61612,7 @@ package java.util { method public java.util.Enumeration<E> elements(); method public synchronized void ensureCapacity(int); method public synchronized E firstElement(); + method public synchronized void forEach(java.util.function.Consumer<? super E>); method public synchronized E get(int); method public synchronized int indexOf(java.lang.Object, int); method public synchronized void insertElementAt(E, int); @@ -61628,6 +61636,7 @@ package java.util { ctor public WeakHashMap(); ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } } diff --git a/api/test-current.txt b/api/test-current.txt index d68355a7d487..ebeae1c97e7e 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -34557,7 +34557,7 @@ package android.service.notification { method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap); method public final void requestInterruptionFilter(int); method public final void requestListenerHints(int); - method public static final void requestRebind(android.content.ComponentName) throws android.os.RemoteException; + method public static void requestRebind(android.content.ComponentName) throws android.os.RemoteException; method public final void requestUnbind() throws android.os.RemoteException; method public final void setNotificationsShown(java.lang.String[]); field public static final java.lang.String CATEGORY_VR_NOTIFICATIONS = "android.intent.category.vr.notifications"; @@ -50691,6 +50691,7 @@ package java.lang { } public abstract interface Iterable { + method public default void forEach(java.util.function.Consumer<? super T>); method public abstract java.util.Iterator<T> iterator(); } @@ -54166,6 +54167,7 @@ package java.security { public abstract class Provider extends java.util.Properties { ctor protected Provider(java.lang.String, double, java.lang.String); + method public synchronized void forEach(java.util.function.BiConsumer<? super java.lang.Object, ? super java.lang.Object>); method public java.lang.String getInfo(); method public java.lang.String getName(); method public synchronized java.security.Provider.Service getService(java.lang.String, java.lang.String); @@ -57115,6 +57117,7 @@ package java.util { ctor public ArrayList(java.util.Collection<? extends E>); method public java.lang.Object clone(); method public void ensureCapacity(int); + method public void forEach(java.util.function.Consumer<? super E>); method public E get(int); method public int size(); method public void trimToSize(); @@ -57678,6 +57681,7 @@ package java.util { ctor public HashMap(java.util.Map<? extends K, ? extends V>); method public java.lang.Object clone(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } public class HashSet extends java.util.AbstractSet implements java.lang.Cloneable java.io.Serializable java.util.Set { @@ -57702,6 +57706,7 @@ package java.util { method public boolean containsValue(java.lang.Object); method public synchronized java.util.Enumeration<V> elements(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public synchronized void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public synchronized V get(java.lang.Object); method public synchronized boolean isEmpty(); method public java.util.Set<K> keySet(); @@ -57720,6 +57725,7 @@ package java.util { ctor public IdentityHashMap(java.util.Map<? extends K, ? extends V>); method public java.lang.Object clone(); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } public class IllegalFormatCodePointException extends java.util.IllegalFormatException { @@ -57959,6 +57965,7 @@ package java.util { method public abstract boolean containsValue(java.lang.Object); method public abstract java.util.Set<java.util.Map.Entry<K, V>> entrySet(); method public abstract boolean equals(java.lang.Object); + method public default void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public abstract V get(java.lang.Object); method public abstract int hashCode(); method public abstract boolean isEmpty(); @@ -58420,6 +58427,7 @@ package java.util { method public K firstKey(); method public java.util.Map.Entry<K, V> floorEntry(K); method public K floorKey(K); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); method public java.util.NavigableMap<K, V> headMap(K, boolean); method public java.util.SortedMap<K, V> headMap(K); method public java.util.Map.Entry<K, V> higherEntry(K); @@ -58502,6 +58510,7 @@ package java.util { method public java.util.Enumeration<E> elements(); method public synchronized void ensureCapacity(int); method public synchronized E firstElement(); + method public synchronized void forEach(java.util.function.Consumer<? super E>); method public synchronized E get(int); method public synchronized int indexOf(java.lang.Object, int); method public synchronized void insertElementAt(E, int); @@ -58525,6 +58534,7 @@ package java.util { ctor public WeakHashMap(); ctor public WeakHashMap(java.util.Map<? extends K, ? extends V>); method public java.util.Set<java.util.Map.Entry<K, V>> entrySet(); + method public void forEach(java.util.function.BiConsumer<? super K, ? super V>); } } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 32751b2b47fe..c1069d7c2d6e 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -41,6 +41,7 @@ import android.content.Intent; import android.content.IntentSender; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; @@ -68,6 +69,7 @@ import android.os.Parcelable; import android.os.PersistableBundle; import android.os.RemoteException; import android.os.StrictMode; +import android.os.SystemProperties; import android.os.UserHandle; import android.text.Selection; import android.text.SpannableStringBuilder; @@ -110,6 +112,7 @@ import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView; +import android.widget.Toast; import android.widget.Toolbar; import com.android.internal.app.IVoiceInteractor; @@ -832,6 +835,8 @@ public class Activity extends ContextThemeWrapper private boolean mHasCurrentPermissionsRequest; private boolean mEatKeyUpEvent; + private static native String getDlWarning(); + /** Return the intent that started this activity. */ public Intent getIntent() { return mIntent; @@ -6621,6 +6626,31 @@ public class Activity extends ContextThemeWrapper } mFragments.dispatchStart(); mFragments.reportLoaderStart(); + + // This property is set for all builds except final release + boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1; + boolean isAppDebuggable = + (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + + if (isAppDebuggable || isDlwarningEnabled) { + String dlwarning = getDlWarning(); + if (dlwarning != null) { + String appName = getString(mApplication.getApplicationInfo().labelRes); + String warning = "Detected problems with app native libraries\n" + + "(please consult log for detail):\n" + dlwarning; + if (isAppDebuggable) { + new AlertDialog.Builder(this). + setTitle(appName). + setMessage(warning). + setPositiveButton(android.R.string.ok, null). + setCancelable(false). + show(); + } else { + Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show(); + } + } + } + mActivityTransitionState.enterReady(this); } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f2a8ea5eb148..0d8069e18b96 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4804,8 +4804,9 @@ public final class ActivityThread { // Keep in sync with installd (frameworks/native/cmds/installd/commands.cpp). private static File getPrimaryProfileFile(String packageName) { - return new File("/data/misc/profiles/cur/" + UserHandle.myUserId() + - "/" + packageName + "/primary.prof"); + File profileDir = Environment.getDataProfilesDePackageDirectory( + UserHandle.myUserId(), packageName); + return new File(profileDir, "primary.prof"); } private static void setupJitProfileSupport(LoadedApk loadedApk, File cacheDir) { @@ -4848,8 +4849,17 @@ public final class ActivityThread { } } + final File foreignDexProfilesFile = + Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId()); + String foreignDexProfilesPath = null; + if (!foreignDexProfilesFile.exists()) { + Log.v(TAG, "ForeignDexProfilesPath does not exists:" + + foreignDexProfilesFile.getPath()); + } else { + foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath(); + } VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), appInfo.dataDir, - codePaths.toArray(new String[codePaths.size()])); + codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath); } private void updateDefaultDensity() { diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 78a054b3a717..04110c674dba 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -1525,7 +1525,7 @@ final class FragmentManagerImpl extends FragmentManager implements LayoutInflate throw new IllegalStateException("Must be called from main thread of fragment host"); } - if (allowStateLoss) { + if (!allowStateLoss) { checkStateLoss(); } diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java index 56b4249b619d..1ec68784ecce 100644 --- a/core/java/android/app/UiModeManager.java +++ b/core/java/android/app/UiModeManager.java @@ -17,6 +17,7 @@ package android.app; import android.annotation.IntDef; +import android.annotation.TestApi; import android.content.Context; import android.content.res.Configuration; import android.os.RemoteException; @@ -266,7 +267,9 @@ public class UiModeManager { /** * @return If UI mode is locked or not. When UI mode is locked, calls to change UI mode * like {@link #enableCarMode(int)} will silently fail. + * @hide */ + @TestApi public boolean isUiModeLocked() { if (mService != null) { try { @@ -286,7 +289,9 @@ public class UiModeManager { * mode will fail silently. * * @return {@code true} if night mode is locked or {@code false} otherwise + * @hide */ + @TestApi public boolean isNightModeLocked() { if (mService != null) { try { diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java index 2410503c217b..307bd2d13f83 100644 --- a/core/java/android/os/Environment.java +++ b/core/java/android/os/Environment.java @@ -258,6 +258,20 @@ public class Environment { return buildPath(getDataDirectory(), "misc_de", String.valueOf(userId)); } + private static File getDataProfilesDeDirectory(int userId) { + return buildPath(getDataDirectory(), "misc", "profiles", "cur", String.valueOf(userId)); + } + + /** {@hide} */ + public static File getDataProfilesDePackageDirectory(int userId, String packageName) { + return buildPath(getDataProfilesDeDirectory(userId), packageName); + } + + /** {@hide} */ + public static File getDataProfilesDeForeignDexDirectory(int userId) { + return buildPath(getDataProfilesDeDirectory(userId), "foreign-dex"); + } + /** {@hide} */ public static File getDataAppDirectory(String volumeUuid) { return new File(getDataDirectory(volumeUuid), "app"); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 95fcdc179643..f19bf02a238f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -662,11 +662,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ private int mDeviceProvisionedState = DEVICE_PROVISIONED_UNKNOWN; - /* + /** * Kick-start the font cache for the zygote process (to pay the cost of * initializing freetype for our default font only once). + * @hide */ - static { + public static void preloadFontCache() { Paint p = new Paint(); p.setAntiAlias(true); // We don't care about the result, just the side-effect of measuring. diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 6ad9e20360e0..eb509c2632c1 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -36,6 +36,7 @@ import android.text.Hyphenator; import android.util.EventLog; import android.util.Log; import android.webkit.WebViewFactory; +import android.widget.TextView; import com.android.internal.os.InstallerConnection.InstallerException; @@ -214,6 +215,7 @@ public class ZygoteInit { private static void preloadTextResources() { Hyphenator.init(); + TextView.preloadFontCache(); } /** diff --git a/core/jni/Android.mk b/core/jni/Android.mk index d5f080ae4b27..ed3fe428b5a3 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -33,6 +33,7 @@ LOCAL_SRC_FILES:= \ com_android_internal_content_NativeLibraryHelper.cpp \ com_google_android_gles_jni_EGLImpl.cpp \ com_google_android_gles_jni_GLImpl.cpp.arm \ + android_app_Activity.cpp \ android_app_ApplicationLoaders.cpp \ android_app_NativeActivity.cpp \ android_auditing_SecurityLog.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 6ed07a7c9990..2a04526ed3eb 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -178,6 +178,7 @@ extern int register_android_backup_FileBackupHelperBase(JNIEnv *env); extern int register_android_backup_BackupHelperDispatcher(JNIEnv *env); extern int register_android_app_backup_FullBackup(JNIEnv *env); extern int register_android_app_ApplicationLoaders(JNIEnv* env); +extern int register_android_app_Activity(JNIEnv *env); extern int register_android_app_ActivityThread(JNIEnv *env); extern int register_android_app_NativeActivity(JNIEnv *env); extern int register_android_media_RemoteDisplay(JNIEnv *env); @@ -1373,6 +1374,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_backup_BackupHelperDispatcher), REG_JNI(register_android_app_backup_FullBackup), REG_JNI(register_android_app_ApplicationLoaders), + REG_JNI(register_android_app_Activity), REG_JNI(register_android_app_ActivityThread), REG_JNI(register_android_app_NativeActivity), REG_JNI(register_android_util_jar_StrictJarFile), diff --git a/core/jni/android_app_Activity.cpp b/core/jni/android_app_Activity.cpp new file mode 100644 index 000000000000..b1d7e82c73ae --- /dev/null +++ b/core/jni/android_app_Activity.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 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. + */ + +#include <poll.h> +#include <android/dlext.h> + +#include "core_jni_helpers.h" + +namespace android +{ + +static jstring getDlWarning_native(JNIEnv* env, jobject) { + const char* text = android_dlwarning(); + return text == nullptr ? nullptr : env->NewStringUTF(text); +} + +static const JNINativeMethod g_methods[] = { + { "getDlWarning", + "()Ljava/lang/String;", + reinterpret_cast<void*>(getDlWarning_native) }, +}; + +static const char* const kActivityPathName = "android/app/Activity"; + +int register_android_app_Activity(JNIEnv* env) { + return RegisterMethodsOrDie(env, kActivityPathName, g_methods, NELEM(g_methods)); +} + +} // namespace android diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java index 8618ec98c6c3..ebe509ce1a29 100644 --- a/media/java/android/media/MediaMuxer.java +++ b/media/java/android/media/MediaMuxer.java @@ -127,7 +127,8 @@ final public class MediaMuxer { * @param path The path of the output media file. * @param format The format of the output media file. * @see android.media.MediaMuxer.OutputFormat - * @throws IOException if failed to open the file for write + * @throws IllegalArgumentException if path is invalid or format is not supported. + * @throws IOException if failed to open the file for write. */ public MediaMuxer(@NonNull String path, @Format int format) throws IOException { if (path == null) { @@ -165,6 +166,8 @@ final public class MediaMuxer { * By default, the rotation degree is 0.</p> * @param degrees the angle to be rotated clockwise in degrees. * The supported angles are 0, 90, 180, and 270 degrees. + * @throws IllegalArgumentException if degree is not supported. + * @throws IllegalStateException If this method is called after {@link #start}. */ public void setOrientationHint(int degrees) { if (degrees != 0 && degrees != 90 && degrees != 180 && degrees != 270) { @@ -217,6 +220,8 @@ final public class MediaMuxer { * Starts the muxer. * <p>Make sure this is called after {@link #addTrack} and before * {@link #writeSampleData}.</p> + * @throws IllegalStateException If this method is called after {@link #start} + * or Muxer is released */ public void start() { if (mNativeObject == 0) { @@ -233,6 +238,7 @@ final public class MediaMuxer { /** * Stops the muxer. * <p>Once the muxer stops, it can not be restarted.</p> + * @throws IllegalStateException if muxer is in the wrong state. */ public void stop() { if (mState == MUXER_STATE_STARTED) { @@ -264,6 +270,8 @@ final public class MediaMuxer { * MediaFormat. * @return The track index for this newly added track, and it should be used * in the {@link #writeSampleData}. + * @throws IllegalArgumentException if format is invalid. + * @throws IllegalStateException if muxer is in the wrong state. */ public int addTrack(@NonNull MediaFormat format) { if (format == null) { @@ -314,6 +322,8 @@ final public class MediaMuxer { * @param byteBuf The encoded sample. * @param trackIndex The track index for this sample. * @param bufferInfo The buffer information related to this sample. + * @throws IllegalArgumentException if trackIndex, byteBuf or bufferInfo is invalid. + * @throws IllegalStateException if muxer is in wrong state. * MediaMuxer uses the flags provided in {@link MediaCodec.BufferInfo}, * to signal sync frames. */ diff --git a/packages/SystemUI/res/layout/notification_guts.xml b/packages/SystemUI/res/layout/notification_guts.xml index 62f2b479cde9..4b0c834d8415 100644 --- a/packages/SystemUI/res/layout/notification_guts.xml +++ b/packages/SystemUI/res/layout/notification_guts.xml @@ -39,7 +39,7 @@ android:layout_gravity="center_vertical|start"> <ImageView - android:id="@android:id/icon" + android:id="@+id/app_icon" android:layout_width="18dp" android:layout_height="18dp" android:layout_marginEnd="6dp" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index d0358f4cda60..178838ea939d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -983,7 +983,7 @@ public abstract class BaseStatusBar extends SystemUI implements pkgicon = pmUser.getDefaultActivityIcon(); } - ((ImageView) row.findViewById(android.R.id.icon)).setImageDrawable(pkgicon); + ((ImageView) row.findViewById(R.id.app_icon)).setImageDrawable(pkgicon); ((TextView) row.findViewById(R.id.pkgname)).setText(appname); final View settingsButton = guts.findViewById(R.id.more_settings); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java index 5796edbeea61..ed71e5708ce1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java @@ -22,8 +22,12 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; +import android.graphics.Paint; import android.graphics.PixelFormat; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffColorFilter; import android.graphics.Rect; +import android.graphics.PorterDuff.Mode; import android.graphics.drawable.Drawable; import android.os.SystemClock; import android.util.Log; @@ -55,6 +59,7 @@ public class BarTransitions { private final BarBackgroundDrawable mBarBackground; private int mMode; + private boolean mAlwaysOpaque = false; public BarTransitions(View view, int gradientResourceId) { mTag = "BarTransitions." + view.getClass().getSimpleName(); @@ -69,13 +74,25 @@ public class BarTransitions { return mMode; } + /** + * @param alwaysOpaque if {@code true}, the bar's background will always be opaque, regardless + * of what mode it is currently set to. + */ + public void setAlwaysOpaque(boolean alwaysOpaque) { + mAlwaysOpaque = alwaysOpaque; + } + + public boolean isAlwaysOpaque() { + // Low-end devices do not support translucent modes, fallback to opaque + return !HIGH_END || mAlwaysOpaque; + } + public void transitionTo(int mode, boolean animate) { - // low-end devices do not support translucent modes, fallback to opaque - if (!HIGH_END && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT + if (isAlwaysOpaque() && (mode == MODE_SEMI_TRANSPARENT || mode == MODE_TRANSLUCENT || mode == MODE_TRANSPARENT)) { mode = MODE_OPAQUE; } - if (!HIGH_END && (mode == MODE_LIGHTS_OUT_TRANSPARENT)) { + if (isAlwaysOpaque() && (mode == MODE_LIGHTS_OUT_TRANSPARENT)) { mode = MODE_LIGHTS_OUT; } if (mMode == mode) return; @@ -131,10 +148,13 @@ public class BarTransitions { private int mGradientAlpha; private int mColor; + private PorterDuffColorFilter mTintFilter; + private Paint mPaint = new Paint(); private int mGradientAlphaStart; private int mColorStart; + public BarBackgroundDrawable(Context context, int gradientResourceId) { final Resources res = context.getResources(); if (DEBUG_COLORS) { @@ -163,6 +183,26 @@ public class BarTransitions { } @Override + public void setTint(int color) { + if (mTintFilter == null) { + mTintFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN); + } else { + mTintFilter.setColor(color); + } + invalidateSelf(); + } + + @Override + public void setTintMode(Mode tintMode) { + if (mTintFilter == null) { + mTintFilter = new PorterDuffColorFilter(0, tintMode); + } else { + mTintFilter.setMode(tintMode); + } + invalidateSelf(); + } + + @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); mGradient.setBounds(bounds); @@ -208,6 +248,7 @@ public class BarTransitions { } else { targetColor = mOpaque; } + if (!mAnimating) { mColor = targetColor; mGradientAlpha = targetGradientAlpha; @@ -234,7 +275,11 @@ public class BarTransitions { mGradient.draw(canvas); } if (Color.alpha(mColor) > 0) { - canvas.drawColor(mColor); + mPaint.setColor(mColor); + if (mTintFilter != null) { + mPaint.setColorFilter(mTintFilter); + } + canvas.drawPaint(mPaint); } if (mAnimating) { invalidateSelf(); // keep going diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 20f8285cfee7..c7fc5e24669a 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2186,7 +2186,7 @@ public final class ActivityStackSupervisor implements DisplayListener { final int resizeMode = task.mResizeMode; - if (stackId == DOCKED_STACK_ID && resizeMode == RESIZE_MODE_UNRESIZEABLE) { + if (stackId == DOCKED_STACK_ID && !task.isResizeable()) { // We don't allow moving a unresizeable task to the docked stack since the docked // stack is used for split-screen mode and will cause things like the docked divider to // show up. We instead leave the task in its current stack or move it to the fullscreen diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index 5d81daeccc6b..7b134cab2b95 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -905,13 +905,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe // Group ID is arbitrarily set to parent profile user ID. It just represents // the default fingerprints for the user. - final int effectiveGroupId = getEffectiveUserId(groupId); + if (!isCurrentUserOrProfile(groupId)) { + return; + } final boolean restricted = isRestricted(); mHandler.post(new Runnable() { @Override public void run() { - startEnrollment(token, cryptoClone, effectiveGroupId, receiver, flags, restricted); + startEnrollment(token, cryptoClone, groupId, receiver, flags, restricted); } }); } @@ -1011,15 +1013,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe @Override // Binder call public void rename(final int fingerId, final int groupId, final String name) { checkPermission(MANAGE_FINGERPRINT); - - // Group ID is arbitrarily set to parent profile user ID. It just represents - // the default fingerprints for the user. - final int effectiveGroupId = getEffectiveUserId(groupId); + if (!isCurrentUserOrProfile(groupId)) { + return; + } mHandler.post(new Runnable() { @Override public void run() { mFingerprintUtils.renameFingerprintForUser(mContext, fingerId, - effectiveGroupId, name); + groupId, name); } }); } @@ -1029,9 +1030,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe if (!canUseFingerprint(opPackageName, false /* foregroundOnly */)) { return Collections.emptyList(); } - int effectiveUserId = getEffectiveUserId(userId); + if (!isCurrentUserOrProfile(userId)) { + return Collections.emptyList(); + } - return FingerprintService.this.getEnrolledFingerprints(effectiveUserId); + return FingerprintService.this.getEnrolledFingerprints(userId); } @Override // Binder call @@ -1040,8 +1043,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return false; } - int effectiveUserId = getEffectiveUserId(userId); - return FingerprintService.this.hasEnrolledFingerprints(effectiveUserId); + if (!isCurrentUserOrProfile(userId)) { + return false; + } + return FingerprintService.this.hasEnrolledFingerprints(userId); } @Override // Binder call diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index ed439c937fee..5c5c8f854105 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -271,8 +271,11 @@ public class ZenModeHelper { throw new IllegalArgumentException("Owner is not a condition provider service"); } - final int ruleInstanceLimit = owner.metaData.getInt( - ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1); + int ruleInstanceLimit = -1; + if (owner.metaData != null) { + ruleInstanceLimit = owner.metaData.getInt( + ConditionProviderService.META_DATA_RULE_INSTANCE_LIMIT, -1); + } if (ruleInstanceLimit > 0 && ruleInstanceLimit < (getCurrentInstanceCount(automaticZenRule.getOwner()) + 1)) { throw new IllegalArgumentException("Rule instance limit exceeded"); diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index a3af561bf44f..a084d866ec64 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageParser; import android.content.pm.PackageParser.Package; +import android.os.Environment; import android.os.PowerManager; import android.os.UserHandle; import android.os.WorkSource; @@ -164,6 +165,10 @@ class PackageDexOptimizer { } for (String path : paths) { + if (useProfiles && isUsedByOtherApps(path)) { + // We cannot use profile guided compilation if the apk was used by another app. + useProfiles = false; + } int dexoptNeeded; try { @@ -204,8 +209,10 @@ class PackageDexOptimizer { + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable + " extractOnly=" + extractOnly + " oatDir = " + oatDir); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); + // Profile guide compiled oat files should not be public. + final boolean isPublic = !pkg.isForwardLocked() && !useProfiles; final int dexFlags = adjustDexoptFlags( - (!pkg.isForwardLocked() ? DEXOPT_PUBLIC : 0) + ( isPublic ? DEXOPT_PUBLIC : 0) | (vmSafeMode ? DEXOPT_SAFEMODE : 0) | (debuggable ? DEXOPT_DEBUGGABLE : 0) | (extractOnly ? DEXOPT_EXTRACTONLY : 0) @@ -275,6 +282,25 @@ class PackageDexOptimizer { mSystemReady = true; } + private boolean isUsedByOtherApps(String apkPath) { + try { + apkPath = new File(apkPath).getCanonicalPath(); + } catch (IOException e) { + // Log an error but continue without it. + Slog.w(TAG, "Failed to get canonical path", e); + } + String useMarker = apkPath.replace('/', '@'); + final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); + for (int i = 0; i < currentUserIds.length; i++) { + File profileDir = Environment.getDataProfilesDeForeignDexDirectory(currentUserIds[i]); + File foreignUseMark = new File(profileDir, useMarker); + if (foreignUseMark.exists()) { + return true; + } + } + return false; + } + /** * A specialized PackageDexOptimizer that overrides already-installed checks, forcing a * dexopt path. diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 998869472c17..f3937c812d01 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2888,7 +2888,8 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public boolean isPackageAvailable(String packageName, int userId) { if (!sUserManager.exists(userId)) return false; - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "is package available"); synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); if (p != null) { @@ -2908,7 +2909,8 @@ public class PackageManagerService extends IPackageManager.Stub { public PackageInfo getPackageInfo(String packageName, int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForPackage(flags, userId, packageName); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get package info"); // reader synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); @@ -2954,7 +2956,8 @@ public class PackageManagerService extends IPackageManager.Stub { public int getPackageUid(String packageName, int flags, int userId) { if (!sUserManager.exists(userId)) return -1; flags = updateFlagsForPackage(flags, userId, packageName); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get package uid"); // reader synchronized (mPackages) { @@ -2977,7 +2980,8 @@ public class PackageManagerService extends IPackageManager.Stub { public int[] getPackageGids(String packageName, int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForPackage(flags, userId, packageName); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "getPackageGids"); // reader @@ -3117,7 +3121,8 @@ public class PackageManagerService extends IPackageManager.Stub { public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForApplication(flags, userId, packageName); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get application info"); // writer synchronized (mPackages) { PackageParser.Package p = mPackages.get(packageName); @@ -3332,7 +3337,8 @@ public class PackageManagerService extends IPackageManager.Stub { public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForComponent(flags, userId, component); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get activity info"); synchronized (mPackages) { PackageParser.Activity a = mActivities.mActivities.get(component); @@ -3377,7 +3383,8 @@ public class PackageManagerService extends IPackageManager.Stub { public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForComponent(flags, userId, component); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get receiver info"); synchronized (mPackages) { PackageParser.Activity a = mReceivers.mActivities.get(component); if (DEBUG_PACKAGE_INFO) Log.v( @@ -3396,7 +3403,8 @@ public class PackageManagerService extends IPackageManager.Stub { public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForComponent(flags, userId, component); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get service info"); synchronized (mPackages) { PackageParser.Service s = mServices.mServices.get(component); if (DEBUG_PACKAGE_INFO) Log.v( @@ -3415,7 +3423,8 @@ public class PackageManagerService extends IPackageManager.Stub { public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForComponent(flags, userId, component); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get provider info"); synchronized (mPackages) { PackageParser.Provider p = mProviders.mProviders.get(component); if (DEBUG_PACKAGE_INFO) Log.v( @@ -3807,7 +3816,8 @@ public class PackageManagerService extends IPackageManager.Stub { android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS, "grantRuntimePermission"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, true /* checkShell */, "grantRuntimePermission"); final int uid; @@ -3918,7 +3928,8 @@ public class PackageManagerService extends IPackageManager.Stub { android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, "revokeRuntimePermission"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, true /* checkShell */, "revokeRuntimePermission"); final int appId; @@ -4022,7 +4033,8 @@ public class PackageManagerService extends IPackageManager.Stub { enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, "getPermissionFlags"); synchronized (mPackages) { @@ -4055,7 +4067,8 @@ public class PackageManagerService extends IPackageManager.Stub { enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, true /* checkShell */, "updatePermissionFlags"); // Only the system can change these flags and nothing else. @@ -4112,7 +4125,8 @@ public class PackageManagerService extends IPackageManager.Stub { enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, true /* checkShell */, "updatePermissionFlagsForAllApps"); // Only the system can change system fixed flags. @@ -4545,7 +4559,8 @@ public class PackageManagerService extends IPackageManager.Stub { int flags, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForResolve(flags, userId, intent); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "resolve intent"); List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); final ResolveInfo bestChoice = chooseBestActivity(intent, resolvedType, flags, query, userId); @@ -5006,7 +5021,9 @@ public class PackageManagerService extends IPackageManager.Stub { String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); flags = updateFlagsForResolve(flags, userId, intent); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, + "query intent activities"); ComponentName comp = intent.getComponent(); if (comp == null) { if (intent.getSelector() != null) { @@ -5496,8 +5513,9 @@ public class PackageManagerService extends IPackageManager.Stub { String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); flags = updateFlagsForResolve(flags, userId, intent); - enforceCrossUserPermission(Binder.getCallingUid(), userId, false, - false, "query intent activity options"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, + "query intent activity options"); final String resultsAction = intent.getAction(); List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags @@ -5798,7 +5816,9 @@ public class PackageManagerService extends IPackageManager.Stub { if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); flags = updateFlagsForPackage(flags, userId, null); final boolean listUninstalled = (flags & MATCH_UNINSTALLED_PACKAGES) != 0; - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, + "get installed packages"); // writer synchronized (mPackages) { @@ -5950,7 +5970,8 @@ public class PackageManagerService extends IPackageManager.Stub { mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, "getEphemeralApplications"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, "getEphemeralApplications"); synchronized (mPackages) { List<EphemeralApplicationInfo> ephemeralApps = mEphemeralApplicationRegistry @@ -5964,7 +5985,8 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public boolean isEphemeralApplication(String packageName, int userId) { - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, "isEphemeral"); if (DISABLE_EPHEMERAL_APPS) { return false; @@ -5988,7 +6010,8 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, "getCookie"); if (!isCallerSameApp(packageName)) { return null; @@ -6005,7 +6028,8 @@ public class PackageManagerService extends IPackageManager.Stub { return true; } - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, true /* checkShell */, "setCookie"); if (!isCallerSameApp(packageName)) { return false; @@ -6024,7 +6048,8 @@ public class PackageManagerService extends IPackageManager.Stub { mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_EPHEMERAL_APPS, "getEphemeralApplicationIcon"); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, "getEphemeralApplicationIcon"); synchronized (mPackages) { return mEphemeralApplicationRegistry.getEphemeralApplicationIconLPw( @@ -10390,7 +10415,8 @@ public class PackageManagerService extends IPackageManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); final int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, true, true, "installPackageAsUser"); + enforceCrossUserPermission(callingUid, userId, + true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser"); if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { try { @@ -10521,7 +10547,8 @@ public class PackageManagerService extends IPackageManager.Stub { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); PackageSetting pkgSetting; final int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, true, true, + enforceCrossUserPermission(uid, userId, + true /* requireFullPermission */, true /* checkShell */, "setApplicationHiddenSetting for user " + userId); if (hidden && isPackageDeviceAdmin(packageName, userId)) { @@ -10594,8 +10621,9 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, - false, "getApplicationHidden for user " + userId); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, + "getApplicationHidden for user " + userId); PackageSetting pkgSetting; long callingId = Binder.clearCallingIdentity(); try { @@ -10621,8 +10649,9 @@ public class PackageManagerService extends IPackageManager.Stub { null); PackageSetting pkgSetting; final int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user " - + userId); + enforceCrossUserPermission(uid, userId, + true /* requireFullPermission */, true /* checkShell */, + "installExistingPackage for user " + userId); if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) { return PackageManager.INSTALL_FAILED_USER_RESTRICTED; } @@ -10671,7 +10700,8 @@ public class PackageManagerService extends IPackageManager.Stub { public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended, int userId) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, true, + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, true /* checkShell */, "setPackagesSuspended for user " + userId); if (ArrayUtils.isEmpty(packageNames)) { @@ -10729,8 +10759,9 @@ public class PackageManagerService extends IPackageManager.Stub { @Override public boolean isPackageSuspendedForUser(String packageName, int userId) { - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, - false, "isPackageSuspendedForUser for user " + userId); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, + "isPackageSuspendedForUser for user " + userId); synchronized (mPackages) { final PackageSetting pkgSetting = mSettings.mPackages.get(packageName); return pkgSetting != null && pkgSetting.getSuspended(userId); @@ -14102,25 +14133,48 @@ public class PackageManagerService extends IPackageManager.Stub { return; } - for (int currentUserId : users) { - if (getBlockUninstallForUser(packageName, currentUserId)) { - try { - observer.onPackageDeleted(packageName, - PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); - } catch (RemoteException re) { - } - return; + if (!deleteAllUsers && getBlockUninstallForUser(packageName, userId)) { + try { + observer.onPackageDeleted(packageName, + PackageManager.DELETE_FAILED_OWNER_BLOCKED, null); + } catch (RemoteException re) { } + return; } if (DEBUG_REMOVE) { - Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId); + Slog.d(TAG, "deletePackageAsUser: pkg=" + packageName + " user=" + userId + + " deleteAllUsers: " + deleteAllUsers ); } // Queue up an async operation since the package deletion may take a little while. mHandler.post(new Runnable() { public void run() { mHandler.removeCallbacks(this); - final int returnCode = deletePackageX(packageName, userId, flags); + int returnCode; + if (!deleteAllUsers) { + returnCode = deletePackageX(packageName, userId, flags); + } else { + int[] blockUninstallUserIds = getBlockUninstallForUsers(packageName, users); + // If nobody is blocking uninstall, proceed with delete for all users + if (ArrayUtils.isEmpty(blockUninstallUserIds)) { + returnCode = deletePackageX(packageName, userId, flags); + } else { + // Otherwise uninstall individually for users with blockUninstalls=false + final int userFlags = flags & ~PackageManager.DELETE_ALL_USERS; + for (int userId : users) { + if (!ArrayUtils.contains(blockUninstallUserIds, userId)) { + returnCode = deletePackageX(packageName, userId, userFlags); + if (returnCode != PackageManager.DELETE_SUCCEEDED) { + Slog.w(TAG, "Package delete failed for user " + userId + + ", returnCode " + returnCode); + } + } + } + // The app has only been marked uninstalled for certain users. + // We still need to report that delete was blocked + returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED; + } + } try { observer.onPackageDeleted(packageName, returnCode, null); } catch (RemoteException e) { @@ -14130,6 +14184,16 @@ public class PackageManagerService extends IPackageManager.Stub { }); } + private int[] getBlockUninstallForUsers(String packageName, int[] userIds) { + int[] result = EMPTY_INT_ARRAY; + for (int userId : userIds) { + if (getBlockUninstallForUser(packageName, userId)) { + result = ArrayUtils.appendInt(result, userId); + } + } + return result; + } + @Override public boolean isPackageDeviceAdminOnAnyUser(String packageName) { return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL); @@ -14981,7 +15045,8 @@ public class PackageManagerService extends IPackageManager.Stub { final IPackageDataObserver observer, final int userId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.CLEAR_APP_USER_DATA, null); - enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data"); + enforceCrossUserPermission(Binder.getCallingUid(), userId, + true /* requireFullPermission */, false /* checkShell */, "clear application data"); // Queue up an async operation since the package deletion may take a little while. mHandler.post(new Runnable() { public void run() { @@ -15444,7 +15509,8 @@ public class PackageManagerService extends IPackageManager.Stub { String opname) { // writer int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity"); + enforceCrossUserPermission(callingUid, userId, + true /* requireFullPermission */, false /* checkShell */, "add preferred activity"); if (filter.countActions() == 0) { Slog.w(TAG, "Cannot set a preferred activity with no filter actions"); return; @@ -15489,7 +15555,9 @@ public class PackageManagerService extends IPackageManager.Stub { } final int callingUid = Binder.getCallingUid(); - enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity"); + enforceCrossUserPermission(callingUid, userId, + true /* requireFullPermission */, false /* checkShell */, + "replace preferred activity"); synchronized (mPackages) { if (mContext.checkCallingOrSelfPermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS) @@ -16307,7 +16375,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final int uid = Binder.getCallingUid(); final int permission = mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); - enforceCrossUserPermission(uid, userId, false, true, "set enabled"); + enforceCrossUserPermission(uid, userId, + false /* requireFullPermission */, true /* checkShell */, "set enabled"); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); boolean sendNow = false; boolean isApp = (className == null); @@ -16446,7 +16515,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final int permission = mContext.checkCallingOrSelfPermission( android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE); final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED); - enforceCrossUserPermission(uid, userId, true, true, "stop package"); + enforceCrossUserPermission(uid, userId, + true /* requireFullPermission */, true /* checkShell */, "stop package"); // writer synchronized (mPackages) { if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped, @@ -16468,7 +16538,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); public int getApplicationEnabledSetting(String packageName, int userId) { if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, false, false, "get enabled"); + enforceCrossUserPermission(uid, userId, + false /* requireFullPermission */, false /* checkShell */, "get enabled"); // reader synchronized (mPackages) { return mSettings.getApplicationEnabledSettingLPr(packageName, userId); @@ -16479,7 +16550,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); public int getComponentEnabledSetting(ComponentName componentName, int userId) { if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, false, false, "get component enabled"); + enforceCrossUserPermission(uid, userId, + false /* requireFullPermission */, false /* checkShell */, "get component enabled"); // reader synchronized (mPackages) { return mSettings.getComponentEnabledSettingLPr(componentName, userId); diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index de9020250f25..10808da8785e 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -624,6 +624,21 @@ public final class Call { parcelableCall.getExtras(), parcelableCall.getIntentExtras()); } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[pa: "); + sb.append(mAccountHandle); + sb.append(", hdl: "); + sb.append(Log.pii(mHandle)); + sb.append(", caps: "); + sb.append(capabilitiesToString(mCallCapabilities)); + sb.append(", props: "); + sb.append(mCallProperties); + sb.append("]"); + return sb.toString(); + } } public static abstract class Callback { @@ -1000,6 +1015,48 @@ public final class Call { } } + @Override + public String toString() { + return new StringBuilder(). + append("Call [id: "). + append(mTelecomCallId). + append(", state: "). + append(stateToString(mState)). + append(", details: "). + append(mDetails). + append("]").toString(); + } + + /** + * @param state An integer value of a {@code STATE_*} constant. + * @return A string representation of the value. + */ + private static String stateToString(int state) { + switch (state) { + case STATE_NEW: + return "NEW"; + case STATE_RINGING: + return "RINGING"; + case STATE_DIALING: + return "DIALING"; + case STATE_ACTIVE: + return "ACTIVE"; + case STATE_HOLDING: + return "HOLDING"; + case STATE_DISCONNECTED: + return "DISCONNECTED"; + case STATE_CONNECTING: + return "CONNECTING"; + case STATE_DISCONNECTING: + return "DISCONNECTING"; + case STATE_SELECT_PHONE_ACCOUNT: + return "SELECT_PHONE_ACCOUNT"; + default: + Log.w(Call.class, "Unknown state %d", state); + return "UNKNOWN"; + } + } + /** * Adds a listener to this {@code Call}. * diff --git a/telecomm/java/android/telecom/Log.java b/telecomm/java/android/telecom/Log.java index 3f32dbe0fdbe..2ab0525a33c4 100644 --- a/telecomm/java/android/telecom/Log.java +++ b/telecomm/java/android/telecom/Log.java @@ -16,7 +16,10 @@ package android.telecom; +import android.net.Uri; import android.os.AsyncTask; +import android.telephony.PhoneNumberUtils; +import android.text.TextUtils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -152,10 +155,37 @@ final public class Log { public static String pii(Object pii) { if (pii == null || VERBOSE) { return String.valueOf(pii); + } if (pii instanceof Uri) { + return piiUri((Uri) pii); } return "[" + secureHash(String.valueOf(pii).getBytes()) + "]"; } + private static String piiUri(Uri handle) { + StringBuilder sb = new StringBuilder(); + String scheme = handle.getScheme(); + if (!TextUtils.isEmpty(scheme)) { + sb.append(scheme).append(":"); + } + String value = handle.getSchemeSpecificPart(); + if (!TextUtils.isEmpty(value)) { + for (int i = 0; i < value.length(); i++) { + char c = value.charAt(i); + if (PhoneNumberUtils.isStartsPostDial(c)) { + sb.append(c); + } else if (PhoneNumberUtils.isDialable(c)) { + sb.append("*"); + } else if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) { + sb.append("*"); + } else { + sb.append(c); + } + } + } + return sb.toString(); + + } + private static String secureHash(byte[] input) { if (sMessageDigest != null) { sMessageDigest.reset(); diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp index 9837c4efc4d2..bbf7f411d07e 100644 --- a/tools/aapt2/compile/Png.cpp +++ b/tools/aapt2/compile/Png.cpp @@ -1175,7 +1175,7 @@ getout: if (errorMsg) { std::stringstream err; err << "9-patch malformed: " << errorMsg; - if (!errorEdge) { + if (errorEdge) { err << "." << std::endl; if (errorPixel >= 0) { err << "Found at pixel #" << errorPixel << " along " << errorEdge << " edge"; |