Merge "Adds appropriate filtering for instant apps" into oc-dev
diff --git a/Android.mk b/Android.mk
index eb649c9..634272b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -102,6 +102,7 @@
core/java/android/app/IUserSwitchObserver.aidl \
core/java/android/app/IWallpaperManager.aidl \
core/java/android/app/IWallpaperManagerCallback.aidl \
+ core/java/android/app/admin/IDeviceAdminService.aidl \
core/java/android/app/admin/IDevicePolicyManager.aidl \
core/java/android/app/trust/IStrongAuthTracker.aidl \
core/java/android/app/trust/ITrustManager.aidl \
diff --git a/api/current.txt b/api/current.txt
index 392b60d..af3ef9e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -104,7 +104,7 @@
field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
- field public static final java.lang.String READ_PHONE_NUMBER = "android.permission.READ_PHONE_NUMBER";
+ field public static final java.lang.String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
@@ -3675,7 +3675,8 @@
method public boolean onMenuItemSelected(int, android.view.MenuItem);
method public boolean onMenuOpened(int, android.view.Menu);
method public void onMovedToDisplay(int, android.content.res.Configuration);
- method public void onMultiWindowModeChanged(boolean);
+ method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onMultiWindowModeChanged(boolean);
method public boolean onNavigateUp();
method public boolean onNavigateUpFromChild(android.app.Activity);
method protected void onNewIntent(android.content.Intent);
@@ -3683,7 +3684,8 @@
method public void onOptionsMenuClosed(android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method protected void onPause();
- method public void onPictureInPictureModeChanged(boolean);
+ method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onPictureInPictureModeChanged(boolean);
method protected void onPostCreate(android.os.Bundle);
method public void onPostCreate(android.os.Bundle, android.os.PersistableBundle);
method protected void onPostResume();
@@ -4180,7 +4182,7 @@
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
- field public static final java.lang.String OPSTR_READ_PHONE_NUMBER = "android:read_phone_number";
+ field public static final java.lang.String OPSTR_READ_PHONE_NUMBERS = "android:read_phone_numbers";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -4616,11 +4618,13 @@
method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
method public deprecated void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
method public void onLowMemory();
- method public void onMultiWindowModeChanged(boolean);
+ method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onMultiWindowModeChanged(boolean);
method public boolean onOptionsItemSelected(android.view.MenuItem);
method public void onOptionsMenuClosed(android.view.Menu);
method public void onPause();
- method public void onPictureInPictureModeChanged(boolean);
+ method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onPictureInPictureModeChanged(boolean);
method public void onPrepareOptionsMenu(android.view.Menu);
method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
method public void onResume();
@@ -4705,11 +4709,13 @@
method public void dispatchDestroy();
method public void dispatchDestroyView();
method public void dispatchLowMemory();
- method public void dispatchMultiWindowModeChanged(boolean);
+ method public deprecated void dispatchMultiWindowModeChanged(boolean);
+ method public void dispatchMultiWindowModeChanged(boolean, android.content.res.Configuration);
method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
method public void dispatchOptionsMenuClosed(android.view.Menu);
method public void dispatchPause();
- method public void dispatchPictureInPictureModeChanged(boolean);
+ method public deprecated void dispatchPictureInPictureModeChanged(boolean);
+ method public void dispatchPictureInPictureModeChanged(boolean, android.content.res.Configuration);
method public boolean dispatchPrepareOptionsMenu(android.view.Menu);
method public void dispatchResume();
method public void dispatchStart();
@@ -6226,6 +6232,11 @@
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
}
+ public class DeviceAdminService extends android.app.Service {
+ ctor public DeviceAdminService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ }
+
public class DevicePolicyManager {
method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -6392,6 +6403,7 @@
method public void wipeData(int);
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
+ field public static final java.lang.String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
field public static final java.lang.String ACTION_PROVISIONING_SUCCESSFUL = "android.app.action.PROVISIONING_SUCCESSFUL";
@@ -9264,6 +9276,8 @@
field public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT";
field public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
field public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW";
+ field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED";
+ field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED";
field public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK";
@@ -9463,8 +9477,9 @@
field public static final deprecated java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
- field public static final deprecated java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
+ field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
+ field public static final java.lang.String EXTRA_SUBSCRIPTION_INDEX = "android.intent.extra.SUBSCRIPTION_INDEX";
field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT";
field public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE";
@@ -9823,6 +9838,7 @@
}
public abstract interface ServiceConnection {
+ method public default void onBindingDead(android.content.ComponentName);
method public abstract void onServiceConnected(android.content.ComponentName, android.os.IBinder);
method public abstract void onServiceDisconnected(android.content.ComponentName);
}
@@ -10327,12 +10343,12 @@
ctor public LauncherApps.ShortcutQuery();
method public android.content.pm.LauncherApps.ShortcutQuery setActivity(android.content.ComponentName);
method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
- method public android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
+ method public deprecated android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
method public android.content.pm.LauncherApps.ShortcutQuery setPackage(java.lang.String);
method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
- field public static final int FLAG_MATCH_CHOOSER = 16; // 0x10
+ field public static final deprecated int FLAG_MATCH_CHOOSER = 16; // 0x10
field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
field public static final int FLAG_MATCH_PINNED = 2; // 0x2
@@ -10882,9 +10898,9 @@
method public int describeContents();
method public android.content.ComponentName getActivity();
method public java.util.Set<java.lang.String> getCategories();
- method public android.content.ComponentName[] getChooserComponentNames();
- method public android.os.PersistableBundle getChooserExtras();
- method public android.content.IntentFilter[] getChooserIntentFilters();
+ method public deprecated android.content.ComponentName[] getChooserComponentNames();
+ method public deprecated android.os.PersistableBundle getChooserExtras();
+ method public deprecated android.content.IntentFilter[] getChooserIntentFilters();
method public java.lang.CharSequence getDisabledMessage();
method public android.os.PersistableBundle getExtras();
method public java.lang.String getId();
@@ -10897,7 +10913,7 @@
method public java.lang.CharSequence getShortLabel();
method public android.os.UserHandle getUserHandle();
method public boolean hasKeyFieldsOnly();
- method public boolean isChooser();
+ method public deprecated boolean isChooser();
method public boolean isDeclaredInManifest();
method public boolean isDynamic();
method public boolean isEnabled();
@@ -10910,11 +10926,11 @@
public static class ShortcutInfo.Builder {
ctor public ShortcutInfo.Builder(android.content.Context, java.lang.String);
- method public android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
+ method public deprecated android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
method public android.content.pm.ShortcutInfo build();
method public android.content.pm.ShortcutInfo.Builder setActivity(android.content.ComponentName);
method public android.content.pm.ShortcutInfo.Builder setCategories(java.util.Set<java.lang.String>);
- method public android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
+ method public deprecated android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
method public android.content.pm.ShortcutInfo.Builder setDisabledMessage(java.lang.CharSequence);
method public android.content.pm.ShortcutInfo.Builder setExtras(android.os.PersistableBundle);
method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
@@ -12687,7 +12703,7 @@
enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP;
}
- public final class Color {
+ public class Color {
ctor public Color();
method public static int HSVToColor(float[]);
method public static int HSVToColor(int, float[]);
@@ -24532,12 +24548,12 @@
field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
- field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
field public static final java.lang.String COLUMN_AUTHOR = "author";
field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+ field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
@@ -39991,7 +40007,7 @@
method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
- method public boolean isConcurrentVoiceAndDataAllowed();
+ method public boolean isConcurrentVoiceAndDataSupported();
method public boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
@@ -40004,7 +40020,7 @@
method public deprecated boolean sendDialerCode(java.lang.String);
method public void sendDialerSpecialCode(java.lang.String);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
- method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
+ method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
method public void setDataEnabled(boolean);
method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
method public boolean setOperatorBrandOverride(java.lang.String);
@@ -40080,14 +40096,17 @@
field public static final int SIM_STATE_PUK_REQUIRED = 3; // 0x3
field public static final int SIM_STATE_READY = 5; // 0x5
field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
+ field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe
+ field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff
+ field public static final int USSD_RETURN_SUCCESS = 100; // 0x64
field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
- public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
- ctor public TelephonyManager.OnReceiveUssdResponseCallback();
- method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
- method public void onReceiveUssdResponseFailed(java.lang.String, int);
+ public static abstract class TelephonyManager.UssdResponseCallback {
+ ctor public TelephonyManager.UssdResponseCallback();
+ method public void onReceiveUssdResponse(android.telephony.TelephonyManager, java.lang.String, java.lang.CharSequence);
+ method public void onReceiveUssdResponseFailed(android.telephony.TelephonyManager, java.lang.String, int);
}
public abstract class VisualVoicemailService extends android.app.Service {
@@ -45992,7 +46011,6 @@
method public static deprecated int getEdgeSlop();
method public static deprecated int getFadingEdgeLength();
method public static deprecated long getGlobalActionKeyTimeout();
- method public float getScaledHorizontalScrollFactor();
method public static int getJumpTapTimeout();
method public static int getKeyRepeatDelay();
method public static int getKeyRepeatTimeout();
@@ -46004,6 +46022,7 @@
method public int getScaledDoubleTapSlop();
method public int getScaledEdgeSlop();
method public int getScaledFadingEdgeLength();
+ method public float getScaledHorizontalScrollFactor();
method public int getScaledMaximumDrawingCacheSize();
method public int getScaledMaximumFlingVelocity();
method public int getScaledMinimumFlingVelocity();
@@ -46012,6 +46031,7 @@
method public int getScaledPagingTouchSlop();
method public int getScaledScrollBarSize();
method public int getScaledTouchSlop();
+ method public float getScaledVerticalScrollFactor();
method public int getScaledWindowTouchSlop();
method public static int getScrollBarFadeDuration();
method public static deprecated int getScrollBarSize();
@@ -46019,7 +46039,6 @@
method public static float getScrollFriction();
method public static int getTapTimeout();
method public static deprecated int getTouchSlop();
- method public float getScaledVerticalScrollFactor();
method public static deprecated int getWindowTouchSlop();
method public static long getZoomControlsTimeout();
method public boolean hasPermanentMenuKey();
diff --git a/api/system-current.txt b/api/system-current.txt
index ac1597f..73cf776 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -182,7 +182,7 @@
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
field public static final java.lang.String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE";
- field public static final java.lang.String READ_PHONE_NUMBER = "android.permission.READ_PHONE_NUMBER";
+ field public static final java.lang.String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE";
field public static final java.lang.String READ_SEARCH_INDEXABLES = "android.permission.READ_SEARCH_INDEXABLES";
@@ -3801,7 +3801,8 @@
method public boolean onMenuItemSelected(int, android.view.MenuItem);
method public boolean onMenuOpened(int, android.view.Menu);
method public void onMovedToDisplay(int, android.content.res.Configuration);
- method public void onMultiWindowModeChanged(boolean);
+ method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onMultiWindowModeChanged(boolean);
method public boolean onNavigateUp();
method public boolean onNavigateUpFromChild(android.app.Activity);
method protected void onNewIntent(android.content.Intent);
@@ -3809,7 +3810,8 @@
method public void onOptionsMenuClosed(android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method protected void onPause();
- method public void onPictureInPictureModeChanged(boolean);
+ method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onPictureInPictureModeChanged(boolean);
method protected void onPostCreate(android.os.Bundle);
method public void onPostCreate(android.os.Bundle, android.os.PersistableBundle);
method protected void onPostResume();
@@ -4325,7 +4327,7 @@
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
- field public static final java.lang.String OPSTR_READ_PHONE_NUMBER = "android:read_phone_number";
+ field public static final java.lang.String OPSTR_READ_PHONE_NUMBERS = "android:read_phone_numbers";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -4775,11 +4777,13 @@
method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
method public deprecated void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
method public void onLowMemory();
- method public void onMultiWindowModeChanged(boolean);
+ method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onMultiWindowModeChanged(boolean);
method public boolean onOptionsItemSelected(android.view.MenuItem);
method public void onOptionsMenuClosed(android.view.Menu);
method public void onPause();
- method public void onPictureInPictureModeChanged(boolean);
+ method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onPictureInPictureModeChanged(boolean);
method public void onPrepareOptionsMenu(android.view.Menu);
method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
method public void onResume();
@@ -4864,11 +4868,13 @@
method public void dispatchDestroy();
method public void dispatchDestroyView();
method public void dispatchLowMemory();
- method public void dispatchMultiWindowModeChanged(boolean);
+ method public deprecated void dispatchMultiWindowModeChanged(boolean);
+ method public void dispatchMultiWindowModeChanged(boolean, android.content.res.Configuration);
method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
method public void dispatchOptionsMenuClosed(android.view.Menu);
method public void dispatchPause();
- method public void dispatchPictureInPictureModeChanged(boolean);
+ method public deprecated void dispatchPictureInPictureModeChanged(boolean);
+ method public void dispatchPictureInPictureModeChanged(boolean, android.content.res.Configuration);
method public boolean dispatchPrepareOptionsMenu(android.view.Menu);
method public void dispatchResume();
method public void dispatchStart();
@@ -6429,6 +6435,11 @@
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
}
+ public class DeviceAdminService extends android.app.Service {
+ ctor public DeviceAdminService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ }
+
public class DevicePolicyManager {
method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -6616,6 +6627,7 @@
field public static final java.lang.String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
+ field public static final java.lang.String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
field public static final java.lang.String ACTION_PROVISIONING_SUCCESSFUL = "android.app.action.PROVISIONING_SUCCESSFUL";
@@ -9763,6 +9775,8 @@
field public static final java.lang.String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT";
field public static final java.lang.String ACTION_CALL = "android.intent.action.CALL";
field public static final java.lang.String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON";
+ field public static final java.lang.String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
+ field public static final java.lang.String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
field public static final java.lang.String ACTION_CAMERA_BUTTON = "android.intent.action.CAMERA_BUTTON";
field public static final java.lang.String ACTION_CARRIER_SETUP = "android.intent.action.CARRIER_SETUP";
field public static final java.lang.String ACTION_CHOOSER = "android.intent.action.CHOOSER";
@@ -9773,6 +9787,8 @@
field public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT";
field public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
field public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW";
+ field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED";
+ field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED";
field public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK";
@@ -9992,8 +10008,9 @@
field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
field public static final java.lang.String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";
- field public static final deprecated java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
+ field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
+ field public static final java.lang.String EXTRA_SUBSCRIPTION_INDEX = "android.intent.extra.SUBSCRIPTION_INDEX";
field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT";
field public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE";
@@ -10354,6 +10371,7 @@
}
public abstract interface ServiceConnection {
+ method public default void onBindingDead(android.content.ComponentName);
method public abstract void onServiceConnected(android.content.ComponentName, android.os.IBinder);
method public abstract void onServiceDisconnected(android.content.ComponentName);
}
@@ -10949,12 +10967,12 @@
ctor public LauncherApps.ShortcutQuery();
method public android.content.pm.LauncherApps.ShortcutQuery setActivity(android.content.ComponentName);
method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
- method public android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
+ method public deprecated android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
method public android.content.pm.LauncherApps.ShortcutQuery setPackage(java.lang.String);
method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
- field public static final int FLAG_MATCH_CHOOSER = 16; // 0x10
+ field public static final deprecated int FLAG_MATCH_CHOOSER = 16; // 0x10
field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
field public static final int FLAG_MATCH_PINNED = 2; // 0x2
@@ -11598,9 +11616,9 @@
method public int describeContents();
method public android.content.ComponentName getActivity();
method public java.util.Set<java.lang.String> getCategories();
- method public android.content.ComponentName[] getChooserComponentNames();
- method public android.os.PersistableBundle getChooserExtras();
- method public android.content.IntentFilter[] getChooserIntentFilters();
+ method public deprecated android.content.ComponentName[] getChooserComponentNames();
+ method public deprecated android.os.PersistableBundle getChooserExtras();
+ method public deprecated android.content.IntentFilter[] getChooserIntentFilters();
method public java.lang.CharSequence getDisabledMessage();
method public android.os.PersistableBundle getExtras();
method public java.lang.String getId();
@@ -11613,7 +11631,7 @@
method public java.lang.CharSequence getShortLabel();
method public android.os.UserHandle getUserHandle();
method public boolean hasKeyFieldsOnly();
- method public boolean isChooser();
+ method public deprecated boolean isChooser();
method public boolean isDeclaredInManifest();
method public boolean isDynamic();
method public boolean isEnabled();
@@ -11626,11 +11644,11 @@
public static class ShortcutInfo.Builder {
ctor public ShortcutInfo.Builder(android.content.Context, java.lang.String);
- method public android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
+ method public deprecated android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
method public android.content.pm.ShortcutInfo build();
method public android.content.pm.ShortcutInfo.Builder setActivity(android.content.ComponentName);
method public android.content.pm.ShortcutInfo.Builder setCategories(java.util.Set<java.lang.String>);
- method public android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
+ method public deprecated android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
method public android.content.pm.ShortcutInfo.Builder setDisabledMessage(java.lang.CharSequence);
method public android.content.pm.ShortcutInfo.Builder setExtras(android.os.PersistableBundle);
method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
@@ -13417,7 +13435,7 @@
enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP;
}
- public final class Color {
+ public class Color {
ctor public Color();
method public static int HSVToColor(float[]);
method public static int HSVToColor(int, float[]);
@@ -26471,12 +26489,12 @@
field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
- field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
field public static final java.lang.String COLUMN_AUTHOR = "author";
field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+ field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
@@ -43391,7 +43409,7 @@
method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
- method public boolean isConcurrentVoiceAndDataAllowed();
+ method public boolean isConcurrentVoiceAndDataSupported();
method public boolean isDataConnectivityPossible();
method public boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
@@ -43412,7 +43430,7 @@
method public deprecated boolean sendDialerCode(java.lang.String);
method public void sendDialerSpecialCode(java.lang.String);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
- method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
+ method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
method public void setDataEnabled(boolean);
method public void setDataEnabled(int, boolean);
@@ -43504,14 +43522,17 @@
field public static final int SIM_STATE_PUK_REQUIRED = 3; // 0x3
field public static final int SIM_STATE_READY = 5; // 0x5
field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
+ field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe
+ field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff
+ field public static final int USSD_RETURN_SUCCESS = 100; // 0x64
field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
- public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
- ctor public TelephonyManager.OnReceiveUssdResponseCallback();
- method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
- method public void onReceiveUssdResponseFailed(java.lang.String, int);
+ public static abstract class TelephonyManager.UssdResponseCallback {
+ ctor public TelephonyManager.UssdResponseCallback();
+ method public void onReceiveUssdResponse(android.telephony.TelephonyManager, java.lang.String, java.lang.CharSequence);
+ method public void onReceiveUssdResponseFailed(android.telephony.TelephonyManager, java.lang.String, int);
}
public abstract class VisualVoicemailService extends android.app.Service {
@@ -49449,7 +49470,6 @@
method public static deprecated int getEdgeSlop();
method public static deprecated int getFadingEdgeLength();
method public static deprecated long getGlobalActionKeyTimeout();
- method public float getScaledHorizontalScrollFactor();
method public static int getJumpTapTimeout();
method public static int getKeyRepeatDelay();
method public static int getKeyRepeatTimeout();
@@ -49461,6 +49481,7 @@
method public int getScaledDoubleTapSlop();
method public int getScaledEdgeSlop();
method public int getScaledFadingEdgeLength();
+ method public float getScaledHorizontalScrollFactor();
method public int getScaledMaximumDrawingCacheSize();
method public int getScaledMaximumFlingVelocity();
method public int getScaledMinimumFlingVelocity();
@@ -49469,6 +49490,7 @@
method public int getScaledPagingTouchSlop();
method public int getScaledScrollBarSize();
method public int getScaledTouchSlop();
+ method public float getScaledVerticalScrollFactor();
method public int getScaledWindowTouchSlop();
method public static int getScrollBarFadeDuration();
method public static deprecated int getScrollBarSize();
@@ -49476,7 +49498,6 @@
method public static float getScrollFriction();
method public static int getTapTimeout();
method public static deprecated int getTouchSlop();
- method public float getScaledVerticalScrollFactor();
method public static deprecated int getWindowTouchSlop();
method public static long getZoomControlsTimeout();
method public boolean hasPermanentMenuKey();
diff --git a/api/test-current.txt b/api/test-current.txt
index fc3c9e7..382f5fe 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -104,7 +104,7 @@
field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
field public static final deprecated java.lang.String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
- field public static final java.lang.String READ_PHONE_NUMBER = "android.permission.READ_PHONE_NUMBER";
+ field public static final java.lang.String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
@@ -3677,7 +3677,8 @@
method public boolean onMenuItemSelected(int, android.view.MenuItem);
method public boolean onMenuOpened(int, android.view.Menu);
method public void onMovedToDisplay(int, android.content.res.Configuration);
- method public void onMultiWindowModeChanged(boolean);
+ method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onMultiWindowModeChanged(boolean);
method public boolean onNavigateUp();
method public boolean onNavigateUpFromChild(android.app.Activity);
method protected void onNewIntent(android.content.Intent);
@@ -3685,7 +3686,8 @@
method public void onOptionsMenuClosed(android.view.Menu);
method public void onPanelClosed(int, android.view.Menu);
method protected void onPause();
- method public void onPictureInPictureModeChanged(boolean);
+ method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onPictureInPictureModeChanged(boolean);
method protected void onPostCreate(android.os.Bundle);
method public void onPostCreate(android.os.Bundle, android.os.PersistableBundle);
method protected void onPostResume();
@@ -4192,7 +4194,7 @@
field public static final java.lang.String OPSTR_READ_CELL_BROADCASTS = "android:read_cell_broadcasts";
field public static final java.lang.String OPSTR_READ_CONTACTS = "android:read_contacts";
field public static final java.lang.String OPSTR_READ_EXTERNAL_STORAGE = "android:read_external_storage";
- field public static final java.lang.String OPSTR_READ_PHONE_NUMBER = "android:read_phone_number";
+ field public static final java.lang.String OPSTR_READ_PHONE_NUMBERS = "android:read_phone_numbers";
field public static final java.lang.String OPSTR_READ_PHONE_STATE = "android:read_phone_state";
field public static final java.lang.String OPSTR_READ_SMS = "android:read_sms";
field public static final java.lang.String OPSTR_RECEIVE_MMS = "android:receive_mms";
@@ -4628,11 +4630,13 @@
method public void onInflate(android.content.Context, android.util.AttributeSet, android.os.Bundle);
method public deprecated void onInflate(android.app.Activity, android.util.AttributeSet, android.os.Bundle);
method public void onLowMemory();
- method public void onMultiWindowModeChanged(boolean);
+ method public void onMultiWindowModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onMultiWindowModeChanged(boolean);
method public boolean onOptionsItemSelected(android.view.MenuItem);
method public void onOptionsMenuClosed(android.view.Menu);
method public void onPause();
- method public void onPictureInPictureModeChanged(boolean);
+ method public void onPictureInPictureModeChanged(boolean, android.content.res.Configuration);
+ method public deprecated void onPictureInPictureModeChanged(boolean);
method public void onPrepareOptionsMenu(android.view.Menu);
method public void onRequestPermissionsResult(int, java.lang.String[], int[]);
method public void onResume();
@@ -4717,11 +4721,13 @@
method public void dispatchDestroy();
method public void dispatchDestroyView();
method public void dispatchLowMemory();
- method public void dispatchMultiWindowModeChanged(boolean);
+ method public deprecated void dispatchMultiWindowModeChanged(boolean);
+ method public void dispatchMultiWindowModeChanged(boolean, android.content.res.Configuration);
method public boolean dispatchOptionsItemSelected(android.view.MenuItem);
method public void dispatchOptionsMenuClosed(android.view.Menu);
method public void dispatchPause();
- method public void dispatchPictureInPictureModeChanged(boolean);
+ method public deprecated void dispatchPictureInPictureModeChanged(boolean);
+ method public void dispatchPictureInPictureModeChanged(boolean, android.content.res.Configuration);
method public boolean dispatchPrepareOptionsMenu(android.view.Menu);
method public void dispatchResume();
method public void dispatchStart();
@@ -6245,6 +6251,11 @@
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
}
+ public class DeviceAdminService extends android.app.Service {
+ ctor public DeviceAdminService();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ }
+
public class DevicePolicyManager {
method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
@@ -6420,6 +6431,7 @@
field public static final java.lang.String ACCOUNT_FEATURE_DEVICE_OR_PROFILE_OWNER_DISALLOWED = "android.account.DEVICE_OR_PROFILE_OWNER_DISALLOWED";
field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
field public static final java.lang.String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
+ field public static final java.lang.String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
field public static final java.lang.String ACTION_PROVISIONING_SUCCESSFUL = "android.app.action.PROVISIONING_SUCCESSFUL";
@@ -9297,6 +9309,8 @@
field public static final java.lang.String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT";
field public static final java.lang.String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
field public static final java.lang.String ACTION_DEFAULT = "android.intent.action.VIEW";
+ field public static final java.lang.String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED";
+ field public static final java.lang.String ACTION_DEFAULT_SUBSCRIPTION_CHANGED = "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED";
field public static final java.lang.String ACTION_DELETE = "android.intent.action.DELETE";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW";
field public static final deprecated java.lang.String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK";
@@ -9496,8 +9510,9 @@
field public static final deprecated java.lang.String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
field public static final deprecated java.lang.String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
field public static final java.lang.String EXTRA_SHUTDOWN_USERSPACE_ONLY = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";
- field public static final deprecated java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
+ field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
+ field public static final java.lang.String EXTRA_SUBSCRIPTION_INDEX = "android.intent.extra.SUBSCRIPTION_INDEX";
field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT";
field public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE";
@@ -9856,6 +9871,7 @@
}
public abstract interface ServiceConnection {
+ method public default void onBindingDead(android.content.ComponentName);
method public abstract void onServiceConnected(android.content.ComponentName, android.os.IBinder);
method public abstract void onServiceDisconnected(android.content.ComponentName);
}
@@ -10363,12 +10379,12 @@
ctor public LauncherApps.ShortcutQuery();
method public android.content.pm.LauncherApps.ShortcutQuery setActivity(android.content.ComponentName);
method public android.content.pm.LauncherApps.ShortcutQuery setChangedSince(long);
- method public android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
+ method public deprecated android.content.pm.LauncherApps.ShortcutQuery setIntent(android.content.Intent);
method public android.content.pm.LauncherApps.ShortcutQuery setPackage(java.lang.String);
method public android.content.pm.LauncherApps.ShortcutQuery setQueryFlags(int);
method public android.content.pm.LauncherApps.ShortcutQuery setShortcutIds(java.util.List<java.lang.String>);
field public static final int FLAG_GET_KEY_FIELDS_ONLY = 4; // 0x4
- field public static final int FLAG_MATCH_CHOOSER = 16; // 0x10
+ field public static final deprecated int FLAG_MATCH_CHOOSER = 16; // 0x10
field public static final int FLAG_MATCH_DYNAMIC = 1; // 0x1
field public static final int FLAG_MATCH_MANIFEST = 8; // 0x8
field public static final int FLAG_MATCH_PINNED = 2; // 0x2
@@ -10922,9 +10938,9 @@
method public int describeContents();
method public android.content.ComponentName getActivity();
method public java.util.Set<java.lang.String> getCategories();
- method public android.content.ComponentName[] getChooserComponentNames();
- method public android.os.PersistableBundle getChooserExtras();
- method public android.content.IntentFilter[] getChooserIntentFilters();
+ method public deprecated android.content.ComponentName[] getChooserComponentNames();
+ method public deprecated android.os.PersistableBundle getChooserExtras();
+ method public deprecated android.content.IntentFilter[] getChooserIntentFilters();
method public java.lang.CharSequence getDisabledMessage();
method public android.os.PersistableBundle getExtras();
method public java.lang.String getId();
@@ -10937,7 +10953,7 @@
method public java.lang.CharSequence getShortLabel();
method public android.os.UserHandle getUserHandle();
method public boolean hasKeyFieldsOnly();
- method public boolean isChooser();
+ method public deprecated boolean isChooser();
method public boolean isDeclaredInManifest();
method public boolean isDynamic();
method public boolean isEnabled();
@@ -10950,11 +10966,11 @@
public static class ShortcutInfo.Builder {
ctor public ShortcutInfo.Builder(android.content.Context, java.lang.String);
- method public android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
+ method public deprecated android.content.pm.ShortcutInfo.Builder addChooserIntentFilter(android.content.IntentFilter, android.content.ComponentName);
method public android.content.pm.ShortcutInfo build();
method public android.content.pm.ShortcutInfo.Builder setActivity(android.content.ComponentName);
method public android.content.pm.ShortcutInfo.Builder setCategories(java.util.Set<java.lang.String>);
- method public android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
+ method public deprecated android.content.pm.ShortcutInfo.Builder setChooserExtras(android.os.PersistableBundle);
method public android.content.pm.ShortcutInfo.Builder setDisabledMessage(java.lang.CharSequence);
method public android.content.pm.ShortcutInfo.Builder setExtras(android.os.PersistableBundle);
method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
@@ -12737,7 +12753,7 @@
enum_constant public static final android.graphics.Canvas.VertexMode TRIANGLE_STRIP;
}
- public final class Color {
+ public class Color {
ctor public Color();
method public static int HSVToColor(float[]);
method public static int HSVToColor(int, float[]);
@@ -24645,12 +24661,12 @@
field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
- field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
field public static final java.lang.String COLUMN_AUTHOR = "author";
field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+ field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
@@ -37522,6 +37538,7 @@
ctor public TileService();
method public final android.service.quicksettings.Tile getQsTile();
method public final boolean isLocked();
+ method public static boolean isQuickSettingsSupported();
method public final boolean isSecure();
method public android.os.IBinder onBind(android.content.Intent);
method public void onClick();
@@ -40194,7 +40211,7 @@
method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
- method public boolean isConcurrentVoiceAndDataAllowed();
+ method public boolean isConcurrentVoiceAndDataSupported();
method public boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
@@ -40207,7 +40224,7 @@
method public deprecated boolean sendDialerCode(java.lang.String);
method public void sendDialerSpecialCode(java.lang.String);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
- method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
+ method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
method public void setDataEnabled(boolean);
method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
method public boolean setOperatorBrandOverride(java.lang.String);
@@ -40283,14 +40300,17 @@
field public static final int SIM_STATE_PUK_REQUIRED = 3; // 0x3
field public static final int SIM_STATE_READY = 5; // 0x5
field public static final int SIM_STATE_UNKNOWN = 0; // 0x0
+ field public static final int USSD_ERROR_SERVICE_UNAVAIL = -2; // 0xfffffffe
+ field public static final int USSD_RETURN_FAILURE = -1; // 0xffffffff
+ field public static final int USSD_RETURN_SUCCESS = 100; // 0x64
field public static final java.lang.String VVM_TYPE_CVVM = "vvm_type_cvvm";
field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
- public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
- ctor public TelephonyManager.OnReceiveUssdResponseCallback();
- method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
- method public void onReceiveUssdResponseFailed(java.lang.String, int);
+ public static abstract class TelephonyManager.UssdResponseCallback {
+ ctor public TelephonyManager.UssdResponseCallback();
+ method public void onReceiveUssdResponse(android.telephony.TelephonyManager, java.lang.String, java.lang.CharSequence);
+ method public void onReceiveUssdResponseFailed(android.telephony.TelephonyManager, java.lang.String, int);
}
public abstract class VisualVoicemailService extends android.app.Service {
@@ -46369,7 +46389,6 @@
method public static deprecated int getEdgeSlop();
method public static deprecated int getFadingEdgeLength();
method public static deprecated long getGlobalActionKeyTimeout();
- method public float getScaledHorizontalScrollFactor();
method public static int getHoverTooltipHideShortTimeout();
method public static int getHoverTooltipHideTimeout();
method public static int getHoverTooltipShowTimeout();
@@ -46385,6 +46404,7 @@
method public int getScaledDoubleTapSlop();
method public int getScaledEdgeSlop();
method public int getScaledFadingEdgeLength();
+ method public float getScaledHorizontalScrollFactor();
method public int getScaledMaximumDrawingCacheSize();
method public int getScaledMaximumFlingVelocity();
method public int getScaledMinimumFlingVelocity();
@@ -46393,6 +46413,7 @@
method public int getScaledPagingTouchSlop();
method public int getScaledScrollBarSize();
method public int getScaledTouchSlop();
+ method public float getScaledVerticalScrollFactor();
method public int getScaledWindowTouchSlop();
method public static int getScrollBarFadeDuration();
method public static deprecated int getScrollBarSize();
@@ -46400,7 +46421,6 @@
method public static float getScrollFriction();
method public static int getTapTimeout();
method public static deprecated int getTouchSlop();
- method public float getScaledVerticalScrollFactor();
method public static deprecated int getWindowTouchSlop();
method public static long getZoomControlsTimeout();
method public boolean hasPermanentMenuKey();
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 3a92b9e..0e2c13e 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -26,7 +26,8 @@
libGLESv1_CM \
libgui \
libOpenSLES \
- libtinyalsa
+ libtinyalsa \
+ libbase
LOCAL_MODULE:= bootanimation
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index a6d2986..2435ffa 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -38,6 +38,8 @@
#include <utils/Log.h>
#include <utils/SystemClock.h>
+#include <android-base/properties.h>
+
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
#include <ui/Region.h>
@@ -67,6 +69,9 @@
static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip";
static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip";
static const char SYSTEM_ENCRYPTED_BOOTANIMATION_FILE[] = "/system/media/bootanimation-encrypted.zip";
+static const char OEM_SHUTDOWNANIMATION_FILE[] = "/oem/media/shutdownanimation.zip";
+static const char SYSTEM_SHUTDOWNANIMATION_FILE[] = "/system/media/shutdownanimation.zip";
+
static const char SYSTEM_DATA_DIR_PATH[] = "/data/system";
static const char SYSTEM_TIME_DIR_NAME[] = "time";
static const char SYSTEM_TIME_DIR_PATH[] = "/data/system/time";
@@ -106,7 +111,13 @@
mSession = new SurfaceComposerClient();
// If the system has already booted, the animation is not being used for a boot.
- mSystemBoot = !property_get_bool(BOOT_COMPLETED_PROP_NAME, 0);
+ mSystemBoot = !android::base::GetBoolProperty(BOOT_COMPLETED_PROP_NAME, false);
+ std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
+ if (powerCtl.empty()) {
+ mShuttingDown = false;
+ } else {
+ mShuttingDown = true;
+ }
}
void BootAnimation::onFirstRef() {
@@ -314,16 +325,23 @@
char decrypt[PROPERTY_VALUE_MAX];
property_get("vold.decrypt", decrypt, "");
- bool encryptedAnimation = atoi(decrypt) != 0 || !strcmp("trigger_restart_min_framework", decrypt);
+ bool encryptedAnimation = atoi(decrypt) != 0 ||
+ !strcmp("trigger_restart_min_framework", decrypt);
- if (encryptedAnimation && (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0)) {
+ if (!mShuttingDown && encryptedAnimation &&
+ (access(SYSTEM_ENCRYPTED_BOOTANIMATION_FILE, R_OK) == 0)) {
mZipFileName = SYSTEM_ENCRYPTED_BOOTANIMATION_FILE;
+ return NO_ERROR;
}
- else if (access(OEM_BOOTANIMATION_FILE, R_OK) == 0) {
- mZipFileName = OEM_BOOTANIMATION_FILE;
- }
- else if (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) {
- mZipFileName = SYSTEM_BOOTANIMATION_FILE;
+ static const char* bootFiles[] = {OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE};
+ static const char* shutdownFiles[] =
+ {OEM_SHUTDOWNANIMATION_FILE, SYSTEM_SHUTDOWNANIMATION_FILE};
+
+ for (const char* f : (!mShuttingDown ? bootFiles : shutdownFiles)) {
+ if (access(f, R_OK) == 0) {
+ mZipFileName = f;
+ return NO_ERROR;
+ }
}
return NO_ERROR;
}
@@ -1047,7 +1065,9 @@
if (!mSystemBoot) {
return false;
}
-
+ if (mShuttingDown) { // no audio while shutting down
+ return false;
+ }
// Read the system property to see if we should play the sound.
// If it's not present, default to allowed.
if (!property_get_bool(PLAY_SOUND_PROP_NAME, 1)) {
@@ -1073,7 +1093,7 @@
if (mTimeIsAccurate) {
return true;
}
-
+ if (mShuttingDown) return true;
struct stat statResult;
if(stat(TIME_FORMAT_12_HOUR_FLAG_FILE_PATH, &statResult) == 0) {
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index f1fc98e..181ef1c 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -163,6 +163,7 @@
bool mTimeIsAccurate;
bool mTimeFormat12Hour;
bool mSystemBoot;
+ bool mShuttingDown;
String8 mZipFileName;
SortedVector<String8> mLoadedFiles;
sp<TimeCheckThread> mTimeCheckThread = nullptr;
diff --git a/cmds/bootanimation/bootanim.rc b/cmds/bootanimation/bootanim.rc
index 7344ba7..469c964 100644
--- a/cmds/bootanimation/bootanim.rc
+++ b/cmds/bootanimation/bootanim.rc
@@ -1,7 +1,7 @@
service bootanim /system/bin/bootanimation
- class core
+ class core animation
user graphics
group graphics audio
disabled
oneshot
- writepid /dev/stune/top-app/tasks
\ No newline at end of file
+ writepid /dev/stune/top-app/tasks
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 5c7a12c..fe496e3 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -431,12 +431,10 @@
// Force all the animations to end when the duration scale is 0.
private void forceToEnd() {
- // TODO: Below is commented out to temp work around b/36241584, uncomment this when it's
- // fixed.
-// if (mEndCanBeCalled) {
-// end();
-// return;
-// }
+ if (mEndCanBeCalled) {
+ end();
+ return;
+ }
// Note: we don't want to combine this case with the end() method below because in
// the case of developer calling end(), we still need to make sure end() is explicitly
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 147b5d0..dbf81f9 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1889,11 +1889,32 @@
/**
* Called by the system when the activity changes from fullscreen mode to multi-window mode and
- * visa-versa.
+ * visa-versa. This method provides the same configuration that will be sent in the following
+ * {@link #onConfigurationChanged(Configuration)} call after the activity enters this mode.
+ *
* @see android.R.attr#resizeableActivity
*
* @param isInMultiWindowMode True if the activity is in multi-window mode.
+ * @param newConfig The new configuration of the activity with the state
+ * {@param isInMultiWindowMode}.
*/
+ public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
+ // Left deliberately empty. There should be no side effects if a direct
+ // subclass of Activity does not call super.
+ onMultiWindowModeChanged(isInMultiWindowMode);
+ }
+
+ /**
+ * Called by the system when the activity changes from fullscreen mode to multi-window mode and
+ * visa-versa.
+ *
+ * @see android.R.attr#resizeableActivity
+ *
+ * @param isInMultiWindowMode True if the activity is in multi-window mode.
+ *
+ * @deprecated Use {@link #onMultiWindowModeChanged(boolean, Configuration)} instead.
+ */
+ @Deprecated
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
// Left deliberately empty. There should be no side effects if a direct
// subclass of Activity does not call super.
@@ -1914,11 +1935,33 @@
}
/**
- * Called by the system when the activity changes to and from picture-in-picture mode.
+ * Called by the system when the activity changes to and from picture-in-picture mode. This
+ * method provides the same configuration that will be sent in the following
+ * {@link #onConfigurationChanged(Configuration)} call after the activity enters this mode.
+ *
* @see android.R.attr#supportsPictureInPicture
*
* @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
+ * @param newConfig The new configuration of the activity with the state
+ * {@param isInPictureInPictureMode}.
*/
+ public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode,
+ Configuration newConfig) {
+ // Left deliberately empty. There should be no side effects if a direct
+ // subclass of Activity does not call super.
+ onPictureInPictureModeChanged(isInPictureInPictureMode);
+ }
+
+ /**
+ * Called by the system when the activity changes to and from picture-in-picture mode.
+ *
+ * @see android.R.attr#supportsPictureInPicture
+ *
+ * @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
+ *
+ * @deprecated Use {@link #onPictureInPictureModeChanged(boolean, Configuration)} instead.
+ */
+ @Deprecated
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
// Left deliberately empty. There should be no side effects if a direct
// subclass of Activity does not call super.
@@ -6993,21 +7036,25 @@
}
}
- final void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
+ final void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
+ Configuration newConfig) {
if (DEBUG_LIFECYCLE) Slog.v(TAG,
- "dispatchMultiWindowModeChanged " + this + ": " + isInMultiWindowMode);
- mFragments.dispatchMultiWindowModeChanged(isInMultiWindowMode);
+ "dispatchMultiWindowModeChanged " + this + ": " + isInMultiWindowMode
+ + " " + newConfig);
+ mFragments.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
if (mWindow != null) {
mWindow.onMultiWindowModeChanged();
}
- onMultiWindowModeChanged(isInMultiWindowMode);
+ onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
}
- final void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
+ final void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
+ Configuration newConfig) {
if (DEBUG_LIFECYCLE) Slog.v(TAG,
- "dispatchPictureInPictureModeChanged " + this + ": " + isInPictureInPictureMode);
- mFragments.dispatchPictureInPictureModeChanged(isInPictureInPictureMode);
- onPictureInPictureModeChanged(isInPictureInPictureMode);
+ "dispatchPictureInPictureModeChanged " + this + ": " + isInPictureInPictureMode
+ + " " + newConfig);
+ mFragments.dispatchPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
+ onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b5d1fa8..e49aad2 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1411,15 +1411,23 @@
}
@Override
- public void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode)
- throws RemoteException {
- sendMessage(H.MULTI_WINDOW_MODE_CHANGED, token, isInMultiWindowMode ? 1 : 0);
+ public void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
+ Configuration overrideConfig) throws RemoteException {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = token;
+ args.arg2 = overrideConfig;
+ args.argi1 = isInMultiWindowMode ? 1 : 0;
+ sendMessage(H.MULTI_WINDOW_MODE_CHANGED, args);
}
@Override
- public void schedulePictureInPictureModeChanged(IBinder token, boolean isInPipMode)
- throws RemoteException {
- sendMessage(H.PICTURE_IN_PICTURE_MODE_CHANGED, token, isInPipMode ? 1 : 0);
+ public void schedulePictureInPictureModeChanged(IBinder token, boolean isInPipMode,
+ Configuration overrideConfig) throws RemoteException {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = token;
+ args.arg2 = overrideConfig;
+ args.argi1 = isInPipMode ? 1 : 0;
+ sendMessage(H.PICTURE_IN_PICTURE_MODE_CHANGED, args);
}
@Override
@@ -1816,10 +1824,14 @@
handleStopBinderTrackingAndDump((ParcelFileDescriptor) msg.obj);
break;
case MULTI_WINDOW_MODE_CHANGED:
- handleMultiWindowModeChanged((IBinder) msg.obj, msg.arg1 == 1);
+ handleMultiWindowModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
+ ((SomeArgs) msg.obj).argi1 == 1,
+ (Configuration) ((SomeArgs) msg.obj).arg2);
break;
case PICTURE_IN_PICTURE_MODE_CHANGED:
- handlePictureInPictureModeChanged((IBinder) msg.obj, msg.arg1 == 1);
+ handlePictureInPictureModeChanged((IBinder) ((SomeArgs) msg.obj).arg1,
+ ((SomeArgs) msg.obj).argi1 == 1,
+ (Configuration) ((SomeArgs) msg.obj).arg2);
break;
case LOCAL_VOICE_INTERACTION_STARTED:
handleLocalVoiceInteractionStarted((IBinder) ((SomeArgs) msg.obj).arg1,
@@ -3119,17 +3131,27 @@
}
}
- private void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode) {
+ private void handleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
+ Configuration overrideConfig) {
final ActivityClientRecord r = mActivities.get(token);
if (r != null) {
- r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode);
+ final Configuration newConfig = new Configuration(mConfiguration);
+ if (overrideConfig != null) {
+ newConfig.updateFrom(overrideConfig);
+ }
+ r.activity.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
}
}
- private void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode) {
+ private void handlePictureInPictureModeChanged(IBinder token, boolean isInPipMode,
+ Configuration overrideConfig) {
final ActivityClientRecord r = mActivities.get(token);
if (r != null) {
- r.activity.dispatchPictureInPictureModeChanged(isInPipMode);
+ final Configuration newConfig = new Configuration(mConfiguration);
+ if (overrideConfig != null) {
+ newConfig.updateFrom(overrideConfig);
+ }
+ r.activity.dispatchPictureInPictureModeChanged(isInPipMode, newConfig);
}
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index cbd7b9d..8292152 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -242,7 +242,7 @@
/** @hide */
public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
/** @hide Read the phone number. */
- public static final int OP_READ_PHONE_NUMBER = 65;
+ public static final int OP_READ_PHONE_NUMBERS = 65;
/** @hide Request package installs through package installer */
public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
/** @hide Enter picture-in-picture. */
@@ -353,8 +353,8 @@
/** @hide Get device accounts. */
public static final String OPSTR_GET_ACCOUNTS
= "android:get_accounts";
- public static final String OPSTR_READ_PHONE_NUMBER
- = "android:read_phone_number";
+ public static final String OPSTR_READ_PHONE_NUMBERS
+ = "android:read_phone_numbers";
/** Access to picture-in-picture. */
public static final String OPSTR_PICTURE_IN_PICTURE
= "android:picture_in_picture";
@@ -391,7 +391,7 @@
OP_FINE_LOCATION,
// Phone
OP_READ_PHONE_STATE,
- OP_READ_PHONE_NUMBER,
+ OP_READ_PHONE_NUMBERS,
OP_CALL_PHONE,
OP_READ_CALL_LOG,
OP_WRITE_CALL_LOG,
@@ -487,7 +487,7 @@
OP_GET_ACCOUNTS,
OP_RUN_IN_BACKGROUND,
OP_AUDIO_ACCESSIBILITY_VOLUME,
- OP_READ_PHONE_NUMBER,
+ OP_READ_PHONE_NUMBERS,
OP_REQUEST_INSTALL_PACKAGES,
OP_PICTURE_IN_PICTURE,
OP_INSTANT_APP_START_FOREGROUND,
@@ -564,7 +564,7 @@
OPSTR_GET_ACCOUNTS,
null,
null, // OP_AUDIO_ACCESSIBILITY_VOLUME
- OPSTR_READ_PHONE_NUMBER,
+ OPSTR_READ_PHONE_NUMBERS,
null, // OP_REQUEST_INSTALL_PACKAGES
OPSTR_PICTURE_IN_PICTURE,
OPSTR_INSTANT_APP_START_FOREGROUND,
@@ -641,7 +641,7 @@
"GET_ACCOUNTS",
"RUN_IN_BACKGROUND",
"AUDIO_ACCESSIBILITY_VOLUME",
- "READ_PHONE_NUMBER",
+ "READ_PHONE_NUMBERS",
"REQUEST_INSTALL_PACKAGES",
"PICTURE_IN_PICTURE",
"INSTANT_APP_START_FOREGROUND",
@@ -718,7 +718,7 @@
Manifest.permission.GET_ACCOUNTS,
null, // no permission for running in background
null, // no permission for changing accessibility volume
- Manifest.permission.READ_PHONE_NUMBER,
+ Manifest.permission.READ_PHONE_NUMBERS,
Manifest.permission.REQUEST_INSTALL_PACKAGES,
null, // no permission for entering picture-in-picture on hide
Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
@@ -796,7 +796,7 @@
null, // GET_ACCOUNTS
null, // RUN_IN_BACKGROUND
UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
- null, // READ_PHONE_NUMBER
+ null, // READ_PHONE_NUMBERS
null, // REQUEST_INSTALL_PACKAGES
null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
null, // INSTANT_APP_START_FOREGROUND
@@ -873,7 +873,7 @@
false, // GET_ACCOUNTS
false, // RUN_IN_BACKGROUND
false, // AUDIO_ACCESSIBILITY_VOLUME
- false, // READ_PHONE_NUMBER
+ false, // READ_PHONE_NUMBERS
false, // REQUEST_INSTALL_PACKAGES
false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
false, // INSTANT_APP_START_FOREGROUND
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 02fe101..3102a93 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -1716,19 +1716,55 @@
/**
* Called when the Fragment's activity changes from fullscreen mode to multi-window mode and
* visa-versa. This is generally tied to {@link Activity#onMultiWindowModeChanged} of the
+ * containing Activity. This method provides the same configuration that will be sent in the
+ * following {@link #onConfigurationChanged(Configuration)} call after the activity enters this
+ * mode.
+ *
+ * @param isInMultiWindowMode True if the activity is in multi-window mode.
+ * @param newConfig The new configuration of the activity with the state
+ * {@param isInMultiWindowMode}.
+ */
+ public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
+ onMultiWindowModeChanged(isInMultiWindowMode);
+ }
+
+ /**
+ * Called when the Fragment's activity changes from fullscreen mode to multi-window mode and
+ * visa-versa. This is generally tied to {@link Activity#onMultiWindowModeChanged} of the
* containing Activity.
*
* @param isInMultiWindowMode True if the activity is in multi-window mode.
+ *
+ * @deprecated Use {@link #onMultiWindowModeChanged(boolean, Configuration)} instead.
*/
+ @Deprecated
public void onMultiWindowModeChanged(boolean isInMultiWindowMode) {
}
/**
* Called by the system when the activity changes to and from picture-in-picture mode. This is
* generally tied to {@link Activity#onPictureInPictureModeChanged} of the containing Activity.
+ * This method provides the same configuration that will be sent in the following
+ * {@link #onConfigurationChanged(Configuration)} call after the activity enters this mode.
+ *
+ * @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
+ * @param newConfig The new configuration of the activity with the state
+ * {@param isInPictureInPictureMode}.
+ */
+ public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode,
+ Configuration newConfig) {
+ onPictureInPictureModeChanged(isInPictureInPictureMode);
+ }
+
+ /**
+ * Called by the system when the activity changes to and from picture-in-picture mode. This is
+ * generally tied to {@link Activity#onPictureInPictureModeChanged} of the containing Activity.
*
* @param isInPictureInPictureMode True if the activity is in picture-in-picture mode.
+ *
+ * @deprecated Use {@link #onPictureInPictureModeChanged(boolean, Configuration)} instead.
*/
+ @Deprecated
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
}
@@ -2572,6 +2608,7 @@
}
}
+ @Deprecated
void performMultiWindowModeChanged(boolean isInMultiWindowMode) {
onMultiWindowModeChanged(isInMultiWindowMode);
if (mChildFragmentManager != null) {
@@ -2579,6 +2616,14 @@
}
}
+ void performMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
+ onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
+ if (mChildFragmentManager != null) {
+ mChildFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
+ }
+ }
+
+ @Deprecated
void performPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
onPictureInPictureModeChanged(isInPictureInPictureMode);
if (mChildFragmentManager != null) {
@@ -2586,6 +2631,15 @@
}
}
+ void performPictureInPictureModeChanged(boolean isInPictureInPictureMode,
+ Configuration newConfig) {
+ onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
+ if (mChildFragmentManager != null) {
+ mChildFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode,
+ newConfig);
+ }
+ }
+
void performConfigurationChanged(Configuration newConfig) {
onConfigurationChanged(newConfig);
if (mChildFragmentManager != null) {
diff --git a/core/java/android/app/FragmentController.java b/core/java/android/app/FragmentController.java
index 9ea15a0..cff94d8 100644
--- a/core/java/android/app/FragmentController.java
+++ b/core/java/android/app/FragmentController.java
@@ -250,20 +250,49 @@
* <p>Call when the multi-window mode of the activity changed.
*
* @see Fragment#onMultiWindowModeChanged
+ * @deprecated use {@link #dispatchMultiWindowModeChanged(boolean, Configuration)}
*/
+ @Deprecated
public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
mHost.mFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode);
}
/**
+ * Lets all Fragments managed by the controller's FragmentManager know the multi-window mode of
+ * the activity changed.
+ * <p>Call when the multi-window mode of the activity changed.
+ *
+ * @see Fragment#onMultiWindowModeChanged
+ */
+ public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
+ Configuration newConfig) {
+ mHost.mFragmentManager.dispatchMultiWindowModeChanged(isInMultiWindowMode, newConfig);
+ }
+
+ /**
+ * Lets all Fragments managed by the controller's FragmentManager know the picture-in-picture
+ * mode of the activity changed.
+ * <p>Call when the picture-in-picture mode of the activity changed.
+ *
+ * @see Fragment#onPictureInPictureModeChanged
+ * @deprecated use {@link #dispatchPictureInPictureModeChanged(boolean, Configuration)}
+ */
+ @Deprecated
+ public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
+ mHost.mFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode);
+ }
+
+ /**
* Lets all Fragments managed by the controller's FragmentManager know the picture-in-picture
* mode of the activity changed.
* <p>Call when the picture-in-picture mode of the activity changed.
*
* @see Fragment#onPictureInPictureModeChanged
*/
- public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
- mHost.mFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode);
+ public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
+ Configuration newConfig) {
+ mHost.mFragmentManager.dispatchPictureInPictureModeChanged(isInPictureInPictureMode,
+ newConfig);
}
/**
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 0c1be07..279b900 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1844,6 +1844,10 @@
}
synchronized (this) {
if (mDestroyed || mHost == null) {
+ if (allowStateLoss) {
+ // This FragmentManager isn't attached, so drop the entire transaction.
+ return;
+ }
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
@@ -1960,6 +1964,10 @@
}
public void execSingleAction(OpGenerator action, boolean allowStateLoss) {
+ if (allowStateLoss && (mHost == null || mDestroyed)) {
+ // This FragmentManager isn't attached, so drop the entire transaction.
+ return;
+ }
ensureExecReady(allowStateLoss);
if (action.generateOps(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
@@ -2944,6 +2952,10 @@
}
}
+ /**
+ * @deprecated use {@link #dispatchMultiWindowModeChanged(boolean, Configuration)}
+ */
+ @Deprecated
public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode) {
if (mAdded == null) {
return;
@@ -2956,6 +2968,23 @@
}
}
+ public void dispatchMultiWindowModeChanged(boolean isInMultiWindowMode,
+ Configuration newConfig) {
+ if (mAdded == null) {
+ return;
+ }
+ for (int i = mAdded.size() - 1; i >= 0; --i) {
+ final Fragment f = mAdded.get(i);
+ if (f != null) {
+ f.performMultiWindowModeChanged(isInMultiWindowMode, newConfig);
+ }
+ }
+ }
+
+ /**
+ * @deprecated use {@link #dispatchPictureInPictureModeChanged(boolean, Configuration)}
+ */
+ @Deprecated
public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
if (mAdded == null) {
return;
@@ -2968,6 +2997,19 @@
}
}
+ public void dispatchPictureInPictureModeChanged(boolean isInPictureInPictureMode,
+ Configuration newConfig) {
+ if (mAdded == null) {
+ return;
+ }
+ for (int i = mAdded.size() - 1; i >= 0; --i) {
+ final Fragment f = mAdded.get(i);
+ if (f != null) {
+ f.performPictureInPictureModeChanged(isInPictureInPictureMode, newConfig);
+ }
+ }
+ }
+
public void dispatchConfigurationChanged(Configuration newConfig) {
if (mAdded != null) {
for (int i=0; i<mAdded.size(); i++) {
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index e99691d..6c43fe3 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -146,9 +146,10 @@
void notifyCleartextNetwork(in byte[] firstPacket);
void startBinderTracking();
void stopBinderTrackingAndDump(in ParcelFileDescriptor fd);
- void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode);
- void schedulePictureInPictureModeChanged(IBinder token,
- boolean isInPictureInPictureMode);
+ void scheduleMultiWindowModeChanged(IBinder token, boolean isInMultiWindowMode,
+ in Configuration newConfig);
+ void schedulePictureInPictureModeChanged(IBinder token, boolean isInPictureInPictureMode,
+ in Configuration newConfig);
void scheduleLocalVoiceInteractionStarted(IBinder token,
IVoiceInteractor voiceInteractor);
void handleTrustStorageUpdate();
diff --git a/core/java/android/app/IServiceConnection.aidl b/core/java/android/app/IServiceConnection.aidl
index 6804071..97042aa 100644
--- a/core/java/android/app/IServiceConnection.aidl
+++ b/core/java/android/app/IServiceConnection.aidl
@@ -21,6 +21,6 @@
/** @hide */
oneway interface IServiceConnection {
- void connected(in ComponentName name, IBinder service);
+ void connected(in ComponentName name, IBinder service, boolean dead);
}
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index dbed1be..4205db0 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -88,8 +88,8 @@
* @hide
*/
public final class LoadedApk {
-
- private static final String TAG = "LoadedApk";
+ static final String TAG = "LoadedApk";
+ static final boolean DEBUG = false;
private final ActivityThread mActivityThread;
final String mPackageName;
@@ -641,8 +641,7 @@
final String zip = (zipPaths.size() == 1) ? zipPaths.get(0) :
TextUtils.join(File.pathSeparator, zipPaths);
- if (ActivityThread.localLOGV)
- Slog.v(ActivityThread.TAG, "Class path: " + zip +
+ if (DEBUG) Slog.v(ActivityThread.TAG, "Class path: " + zip +
", JNI path: " + librarySearchPath);
boolean needToSetupJitProfiles = false;
@@ -1371,12 +1370,14 @@
LoadedApk.ServiceDispatcher sd = null;
ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
if (map != null) {
+ if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
sd = map.get(c);
}
if (sd == null) {
sd = new ServiceDispatcher(c, context, handler, flags);
+ if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
if (map == null) {
- map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();
+ map = new ArrayMap<>();
mServices.put(context, map);
}
map.put(c, sd);
@@ -1396,6 +1397,7 @@
if (map != null) {
sd = map.get(c);
if (sd != null) {
+ if (DEBUG) Slog.d(TAG, "Removing dispatcher " + sd + " for conn " + c);
map.remove(c);
sd.doForget();
if (map.size() == 0) {
@@ -1461,10 +1463,11 @@
mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
}
- public void connected(ComponentName name, IBinder service) throws RemoteException {
+ public void connected(ComponentName name, IBinder service, boolean dead)
+ throws RemoteException {
LoadedApk.ServiceDispatcher sd = mDispatcher.get();
if (sd != null) {
- sd.connected(name, service);
+ sd.connected(name, service, dead);
}
}
}
@@ -1533,23 +1536,23 @@
return mUnbindLocation;
}
- public void connected(ComponentName name, IBinder service) {
+ public void connected(ComponentName name, IBinder service, boolean dead) {
if (mActivityThread != null) {
- mActivityThread.post(new RunConnection(name, service, 0));
+ mActivityThread.post(new RunConnection(name, service, 0, dead));
} else {
- doConnected(name, service);
+ doConnected(name, service, dead);
}
}
public void death(ComponentName name, IBinder service) {
if (mActivityThread != null) {
- mActivityThread.post(new RunConnection(name, service, 1));
+ mActivityThread.post(new RunConnection(name, service, 1, false));
} else {
doDeath(name, service);
}
}
- public void doConnected(ComponentName name, IBinder service) {
+ public void doConnected(ComponentName name, IBinder service, boolean dead) {
ServiceDispatcher.ConnectionInfo old;
ServiceDispatcher.ConnectionInfo info;
@@ -1594,6 +1597,9 @@
if (old != null) {
mConnection.onServiceDisconnected(name);
}
+ if (dead) {
+ mConnection.onBindingDead(name);
+ }
// If there is a new service, it is now connected.
if (service != null) {
mConnection.onServiceConnected(name, service);
@@ -1616,15 +1622,16 @@
}
private final class RunConnection implements Runnable {
- RunConnection(ComponentName name, IBinder service, int command) {
+ RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
mName = name;
mService = service;
mCommand = command;
+ mDead = dead;
}
public void run() {
if (mCommand == 0) {
- doConnected(mName, mService);
+ doConnected(mName, mService, mDead);
} else if (mCommand == 1) {
doDeath(mName, mService);
}
@@ -1633,6 +1640,7 @@
final ComponentName mName;
final IBinder mService;
final int mCommand;
+ final boolean mDead;
}
private final class DeathMonitor implements IBinder.DeathRecipient
diff --git a/core/java/android/app/admin/DeviceAdminService.java b/core/java/android/app/admin/DeviceAdminService.java
new file mode 100644
index 0000000..cd0b1bf
--- /dev/null
+++ b/core/java/android/app/admin/DeviceAdminService.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+package android.app.admin;
+
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * Base class for a service that device owner/profile owners can optionally have.
+ *
+ * <p>The system searches for it with an intent filter with the
+ * {@link DevicePolicyManager#ACTION_DEVICE_ADMIN_SERVICE} action, and tries to keep a bound
+ * connection as long as the hosting user is running, so that the device/profile owner is always
+ * considered to be in the foreground.
+ *
+ * <p>Device/profile owners can use
+ * {@link android.content.pm.PackageManager#setComponentEnabledSetting(ComponentName, int, int)}
+ * to disable/enable its own service. For example, when a device/profile owner no longer needs
+ * to be in the foreground, it can (and should) disable its service.
+ *
+ * <p>The service must not be exported.
+ *
+ * <p>TODO: Describe how the system handles crashes in DO/PO.
+ */
+public class DeviceAdminService extends Service {
+ private final IDeviceAdminServiceImpl mImpl;
+
+ public DeviceAdminService() {
+ mImpl = new IDeviceAdminServiceImpl();
+ }
+
+ @Override
+ public final IBinder onBind(Intent intent) {
+ return mImpl.asBinder();
+ }
+
+ private class IDeviceAdminServiceImpl extends IDeviceAdminService.Stub {
+ }
+
+ // So far, we have no methods in this class.
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 6d8d5e9..2f0a630 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1515,6 +1515,16 @@
public @interface ProvisioningPreCondition {}
/**
+ * Service action: Action for a service that device owner and profile owner can optionally
+ * own. If a device owner or a profile owner has such a service, the system tries to keep
+ * a bound connection to it, in order to keep their process always running.
+ * The service must not be exported.
+ */
+ @SdkConstant(SdkConstantType.SERVICE_ACTION)
+ public static final String ACTION_DEVICE_ADMIN_SERVICE
+ = "android.app.action.DEVICE_ADMIN_SERVICE";
+
+ /**
* Return true if the given administrator component is currently active (enabled) in the system.
*
* @param admin The administrator component to check for.
diff --git a/core/java/android/app/admin/IDeviceAdminService.aidl b/core/java/android/app/admin/IDeviceAdminService.aidl
new file mode 100644
index 0000000..5276ed5
--- /dev/null
+++ b/core/java/android/app/admin/IDeviceAdminService.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.app.admin;
+
+/**
+ * @hide
+ */
+interface IDeviceAdminService {
+}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 116224b..da887af 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -16,8 +16,6 @@
package android.content;
-import static android.content.ContentProvider.maybeAddUserId;
-
import android.annotation.AnyRes;
import android.annotation.BroadcastBehavior;
import android.annotation.IntDef;
@@ -43,6 +41,7 @@
import android.os.ShellCommand;
import android.os.StrictMode;
import android.os.UserHandle;
+import android.os.storage.StorageManager;
import android.provider.DocumentsContract;
import android.provider.DocumentsProvider;
import android.provider.MediaStore;
@@ -50,9 +49,7 @@
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.Log;
-
import com.android.internal.util.XmlUtils;
-
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -70,6 +67,8 @@
import java.util.Objects;
import java.util.Set;
+import static android.content.ContentProvider.maybeAddUserId;
+
/**
* An intent is an abstract description of an operation to be performed. It
* can be used with {@link Context#startActivity(Intent) startActivity} to
@@ -1093,6 +1092,8 @@
* <p>Output: nothing.
* @hide
*/
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
/**
* Activity action: Perform a call to any number (emergency or not)
@@ -1102,6 +1103,8 @@
* <p>Output: nothing.
* @hide
*/
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
/**
@@ -3349,6 +3352,32 @@
ACTION_DYNAMIC_SENSOR_CHANGED = "android.intent.action.DYNAMIC_SENSOR_CHANGED";
/**
+ * Broadcast Action: The default subscription has changed. This has the following
+ * extra values:</p>
+ * The {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default subscription index
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
+ = "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED";
+
+ /**
+ * Broadcast Action: The default sms subscription has changed. This has the following
+ * extra values:</p>
+ * {@link #EXTRA_SUBSCRIPTION_INDEX} extra indicates the current default sms
+ * subscription index
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
+ = "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED";
+
+ /**
+ * Integer extra used with {@link #ACTION_DEFAULT_SUBSCRIPTION_CHANGED} and
+ * {@link #ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED} to indicate the subscription
+ * which has changed.
+ */
+ public static final String EXTRA_SUBSCRIPTION_INDEX = "android.intent.extra.SUBSCRIPTION_INDEX";
+
+ /**
* Deprecated - use {@link #ACTION_FACTORY_RESET} instead.
*
* {@hide}
@@ -3868,23 +3897,9 @@
public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
/**
- * A content: URI holding a stream of data associated with the Intent, used
- * with {@link #ACTION_SEND} to supply the data being sent.
- * <p>
- * Starting in {@link android.os.Build.VERSION_CODES#JELLY_BEAN} this value
- * will be automatically promoted to {@link Intent#setClipData(ClipData)}
- * when that value is not already defined.
- * <p>
- * Starting in {@link android.os.Build.VERSION_CODES#O} this value will be
- * automatically demoted from {@link Intent#getClipData()} when this value
- * is not already defined.
- *
- * @deprecated apps should use {@link Intent#setClipData(ClipData)} and
- * {@link Intent#getClipData()} instead of this extra, since
- * only those APIs can extend temporary permission grants to the
- * underlying resource.
+ * A content: URI holding a stream of data associated with the Intent,
+ * used with {@link #ACTION_SEND} to supply the data being sent.
*/
- @Deprecated
public static final String EXTRA_STREAM = "android.intent.extra.STREAM";
/**
@@ -9429,21 +9444,6 @@
mContentUserHint = UserHandle.USER_CURRENT;
}
}
-
- // If someone is sending us ClipData, but not EXTRA_STREAM, offer to
- // downgrade that content for older apps to find
- if (mClipData != null && mClipData.getItemCount() > 0 && !hasExtra(EXTRA_STREAM)) {
- final String action = getAction();
- if (ACTION_SEND.equals(action)) {
- putExtra(EXTRA_STREAM, mClipData.getItemAt(0).getUri());
- } else if (ACTION_SEND_MULTIPLE.equals(action)) {
- final ArrayList<Uri> list = new ArrayList<>();
- for (int i = 0; i < mClipData.getItemCount(); i++) {
- list.add(mClipData.getItemAt(i).getUri());
- }
- putExtra(EXTRA_STREAM, list);
- }
- }
}
/**
diff --git a/core/java/android/content/ServiceConnection.java b/core/java/android/content/ServiceConnection.java
index d115ce4..8e428f9 100644
--- a/core/java/android/content/ServiceConnection.java
+++ b/core/java/android/content/ServiceConnection.java
@@ -37,7 +37,7 @@
* @param service The IBinder of the Service's communication channel,
* which you can now make calls on.
*/
- public void onServiceConnected(ComponentName name, IBinder service);
+ void onServiceConnected(ComponentName name, IBinder service);
/**
* Called when a connection to the Service has been lost. This typically
@@ -49,5 +49,18 @@
* @param name The concrete component name of the service whose
* connection has been lost.
*/
- public void onServiceDisconnected(ComponentName name);
+ void onServiceDisconnected(ComponentName name);
+
+ /**
+ * Called when the binding to this connection is dead. This means the
+ * interface will never receive another connection. The application will
+ * need to unbind and rebind the connection to activate it again. This may
+ * happen, for example, if the application hosting the service it is bound to
+ * has been updated.
+ *
+ * @param name The concrete component name of the service whose
+ * connection is dead.
+ */
+ default void onBindingDead(ComponentName name) {
+ }
}
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index 41311eb..c08bd1d 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -55,8 +55,7 @@
String callingPackage, String packageName, int flags, in UserHandle user);
ParceledListSlice getShortcuts(String callingPackage, long changedSince, String packageName,
- in List shortcutIds, in ComponentName componentName, in Intent intent, int flags,
- in UserHandle user);
+ in List shortcutIds, in ComponentName componentName, int flags, in UserHandle user);
void pinShortcuts(String callingPackage, String packageName, in List<String> shortcutIds,
in UserHandle user);
boolean startShortcut(String callingPackage, String packageName, String id,
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index abdef08..4d76755 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -275,11 +275,8 @@
@Deprecated
public static final int FLAG_GET_MANIFEST = FLAG_MATCH_MANIFEST;
- /**
- * Include chooser shortcuts in the result.
- * STOPSHIP TODO: Unless explicitly requesting chooser fields, we should strip out chooser
- * relevant fields from the Shortcut. This should also be adequately documented.
- */
+ /** @deprecated punted, don't use. */
+ @Deprecated
public static final int FLAG_MATCH_CHOOSER = 1 << 4;
/**
@@ -319,7 +316,6 @@
FLAG_MATCH_DYNAMIC,
FLAG_MATCH_PINNED,
FLAG_MATCH_MANIFEST,
- FLAG_MATCH_CHOOSER,
FLAG_GET_KEY_FIELDS_ONLY,
})
@Retention(RetentionPolicy.SOURCE)
@@ -336,9 +332,6 @@
@Nullable
ComponentName mActivity;
- @Nullable
- Intent mIntent;
-
@QueryFlags
int mQueryFlags;
@@ -382,11 +375,9 @@
return this;
}
- /**
- * If non-null, returns only shortcuts with intent filters that match this intent.
- */
+ /** @deprecated punted, don't use. */
+ @Deprecated
public ShortcutQuery setIntent(@Nullable Intent intent) {
- mIntent = intent;
return this;
}
@@ -428,7 +419,7 @@
*/
private void logErrorForInvalidProfileAccess(@NonNull UserHandle target) {
if (UserHandle.myUserId() != target.getIdentifier() && mUserManager.isManagedProfile()) {
- Log.e(TAG, "Accessing other profiles/users from managed profile is no longer allowed.");
+ Log.w(TAG, "Accessing other profiles/users from managed profile is no longer allowed.");
}
}
@@ -704,7 +695,7 @@
try {
return mService.getShortcuts(mContext.getPackageName(),
query.mChangedSince, query.mPackage, query.mShortcutIds, query.mActivity,
- query.mIntent, query.mQueryFlags, user)
+ query.mQueryFlags, user)
.getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 16d582ef..7bfde75 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -310,12 +310,18 @@
List<String> overlayPackageNames);
/**
- * Resolves an intent, allowing instant apps to be resolved.
+ * Resolves an activity intent, allowing instant apps to be resolved.
*/
public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId);
/**
+ * Resolves a service intent, allowing instant apps to be resolved.
+ */
+ public abstract ResolveInfo resolveService(Intent intent, String resolvedType,
+ int flags, int userId, int callingUid);
+
+ /**
* Track the creator of a new isolated uid.
* @param isolatedUid The newly created isolated uid.
* @param ownerUid The uid of the app that created the isolated process.
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 5201694..3f4a090 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -21,7 +21,6 @@
import android.annotation.UserIdInt;
import android.app.TaskStackBuilder;
import android.content.ComponentName;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -40,12 +39,10 @@
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -99,14 +96,6 @@
public static final int FLAG_ADAPTIVE_BITMAP = 1 << 9;
/** @hide */
- public static final int FLAG_CHOOSER = 1 << 10;
-
- /**
- * TODO: Add FLAG_CHOOSER_INFO_OMITTED to reflect that chooser info was omitted in the Shortcut
- * due to the context in which it was retrieved.
- * TODO: Add a FLAG_LAUNCHABLE to reflect whether or not the Shortcut has a launchable intent
- * @hide
- */
@IntDef(flag = true,
value = {
FLAG_DYNAMIC,
@@ -119,7 +108,6 @@
FLAG_STRINGS_RESOLVED,
FLAG_IMMUTABLE,
FLAG_ADAPTIVE_BITMAP,
- FLAG_CHOOSER,
})
@Retention(RetentionPolicy.SOURCE)
public @interface ShortcutFlags {}
@@ -214,24 +202,6 @@
@Nullable
private PersistableBundle[] mIntentPersistableExtrases;
- /**
- * If used in a chooser, extras that should be added into the intent passed through.
- */
- @Nullable
- private PersistableBundle mChooserExtras;
-
- /**
- * Intent filters to be used if the shortcut is to be used in a chooser context.
- */
- @Nullable
- private IntentFilter[] mChooserIntentFilters;
-
- /**
- * Component names corresponding to the above intent filters.
- */
- @Nullable
- private ComponentName[] mChooserComponentNames;
-
private int mRank;
/**
@@ -281,13 +251,6 @@
mDisabledMessageResId = b.mDisabledMessageResId;
mCategories = cloneCategories(b.mCategories);
mIntents = cloneIntents(b.mIntents);
- if (b.mChooserIntentFilters != null) {
- mChooserIntentFilters = b.mChooserIntentFilters.toArray(new IntentFilter[0]);
- }
- if (b.mChooserComponentNames != null) {
- mChooserComponentNames = b.mChooserComponentNames.toArray(new ComponentName[0]);
- }
- mChooserExtras = b.mChooserExtras;
fixUpIntentExtras();
mRank = b.mRank;
mExtras = b.mExtras;
@@ -368,28 +331,8 @@
if (mTitle == null && mTitleResId == 0) {
throw new IllegalArgumentException("Short label must be provided");
}
-
- // For a shortcut to be valid, there should either be an Intent, or a non-empty set of
- // intent filters.
- if (mIntents == null || mIntents.length == 0) {
- Preconditions.checkNotNull(mChooserIntentFilters,
- "Intent must be provided if not a chooser target");
- Preconditions.checkNotNull(mChooserComponentNames,
- "Intent must be provided if not a chooser target");
- }
-
- // If ChooserIntentFilter are provided, they should match the length of the provided
- // component names.
- if (mChooserIntentFilters != null) {
- if (mChooserComponentNames == null
- || mChooserIntentFilters.length != mChooserComponentNames.length) {
- throw new IllegalArgumentException("Inconsistent intent filters and "
- + "component names given");
- }
- if (mChooserIntentFilters.length == 0 || mChooserComponentNames.length == 0) {
- throw new IllegalArgumentException("Empty intent filter and component names given");
- }
- }
+ Preconditions.checkNotNull(mIntents, "Shortcut Intent must be provided");
+ Preconditions.checkArgument(mIntents.length > 0, "Shortcut Intent must be provided");
}
/**
@@ -434,10 +377,6 @@
mDisabledMessageResName = source.mDisabledMessageResName;
mIconResName = source.mIconResName;
}
- // TODO: Omit these by default and add a new clone flag.
- mChooserIntentFilters = source.mChooserIntentFilters;
- mChooserComponentNames = source.mChooserComponentNames;
- mChooserExtras = source.mChooserExtras;
} else {
// Set this bit.
mFlags |= FLAG_KEY_FIELDS_ONLY;
@@ -565,25 +504,6 @@
}
/**
- * Whether the shortcut has any intentFilter matching the passed in one.
- * @hide
- */
- @VisibleForTesting
- public boolean hasMatchingFilter(ContentResolver resolver, Intent intent) {
- if (mChooserIntentFilters == null) {
- return false;
- }
- for (IntentFilter filter : mChooserIntentFilters) {
- int match = filter.match(resolver, intent, false, TAG);
- if (match > 0) {
- return true;
- }
- }
- return false;
- }
-
-
- /**
* Extract the entry name from a fully-donated resource name.
* e.g. "com.android.app1:drawable/icon1" -> "icon1"
* @hide
@@ -766,15 +686,6 @@
if (source.mExtras != null) {
mExtras = source.mExtras;
}
- if (source.mChooserExtras != null) {
- mChooserExtras = source.mChooserExtras;
- }
- if (source.mChooserIntentFilters != null) {
- mChooserIntentFilters = source.mChooserIntentFilters;
- }
- if (source.mChooserComponentNames != null) {
- mChooserComponentNames = source.mChooserComponentNames;
- }
}
/**
@@ -836,12 +747,6 @@
private PersistableBundle mExtras;
- private PersistableBundle mChooserExtras;
-
- private List<IntentFilter> mChooserIntentFilters;
-
- private List<ComponentName> mChooserComponentNames;
-
/**
* Old style constructor.
* @hide
@@ -1127,37 +1032,17 @@
return this;
}
- /**
- * Extras that can be added which will be added to the Intent used to launch the app if
- * launched from a chooser context.
- */
+ /** @deprecated punted, don't use. */
+ @Deprecated
@NonNull
public Builder setChooserExtras(@NonNull PersistableBundle extras) {
- mChooserExtras = extras;
return this;
}
- /**
- * IntentFilters and the components that should resolve a match for a given chooser target.
- * If multiple matches are found, the component corresponding to the closest match will be
- * used.
- *
- * @param filter IntendFilter that if matched will have the intent forwarded to the given
- * component
- * @param name The component that an intent that passes this filter will resolve to.
- */
+ /** @deprecated punted, don't use. */
+ @Deprecated
public Builder addChooserIntentFilter(@NonNull IntentFilter filter,
@NonNull ComponentName name) {
- Preconditions.checkNotNull(filter, "intent filter cannot be null");
- Preconditions.checkNotNull(name, "component name cannot be null");
-
- if (mChooserIntentFilters == null || mChooserComponentNames == null) {
- mChooserIntentFilters = new ArrayList<>();
- mChooserComponentNames = new ArrayList<>();
- }
-
- mChooserIntentFilters.add(filter);
- mChooserComponentNames.add(name);
return this;
}
@@ -1361,28 +1246,25 @@
return mIntentPersistableExtrases;
}
- /**
- * Retrieve the extras that will be added in to any intent launched through the chooser.
- */
+ /** @deprecated punted, don't use. */
+ @Deprecated
@NonNull
public PersistableBundle getChooserExtras() {
- return mChooserExtras;
+ return new PersistableBundle();
}
- /**
- * Retrieve the list of intent filters for chooser targets.
- */
+ /** @deprecated punted, don't use. */
+ @Deprecated
@NonNull
public IntentFilter[] getChooserIntentFilters() {
- return mChooserIntentFilters;
+ return new IntentFilter[0];
}
- /**
- * Retrieve the list of component names corresponding to the above intent filters.
- */
+ /** @deprecated punted, don't use. */
+ @Deprecated
@NonNull
public ComponentName[] getChooserComponentNames() {
- return mChooserComponentNames;
+ return new ComponentName[0];
}
/**
@@ -1506,9 +1388,10 @@
return hasFlags(FLAG_PINNED);
}
- /** Return whether a shortcut can be shown in the chooser. */
+ /** @deprecated punted, don't use. */
+ @Deprecated
public boolean isChooser() {
- return hasFlags(FLAG_CHOOSER);
+ return false;
}
/**
@@ -1539,14 +1422,6 @@
return isPinned() && !(isDynamic() || isManifestShortcut());
}
- /**
- * @return true if pinned but neither static nor dynamic.
- * @hide
- */
- public boolean isDynamicOrChooser() {
- return hasFlags(FLAG_DYNAMIC) || hasFlags(FLAG_CHOOSER);
- }
-
/** @hide */
public boolean isOriginallyFromManifest() {
return hasFlags(FLAG_IMMUTABLE);
@@ -1829,19 +1704,6 @@
mCategories.add(source.readString().intern());
}
}
-
- // We put a placeholder empty array in to keep the parcelable order, but can do away with
- // them at this point if they're empty.
- mChooserComponentNames = source.readParcelableArray(cl, ComponentName.class);
- if (mChooserComponentNames.length == 0) {
- mChooserComponentNames = null;
- }
-
- mChooserIntentFilters = source.readParcelableArray(cl, IntentFilter.class);
- if (mChooserIntentFilters.length == 0) {
- mChooserIntentFilters = null;
- }
- mChooserExtras = source.readPersistableBundle(cl);
}
@Override
@@ -1888,17 +1750,6 @@
} else {
dest.writeInt(0);
}
- if (mChooserComponentNames != null) {
- dest.writeParcelableArray(mChooserComponentNames, flags);
- } else {
- dest.writeParcelableArray(new ComponentName[0], flags);
- }
- if (mChooserIntentFilters != null) {
- dest.writeParcelableArray(mChooserIntentFilters, flags);
- } else {
- dest.writeParcelableArray(new IntentFilter[0], flags);
- }
- dest.writePersistableBundle(mChooserExtras);
}
public static final Creator<ShortcutInfo> CREATOR =
diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java
index 3de19d1..7b7d8ae 100644
--- a/core/java/android/content/pm/ShortcutServiceInternal.java
+++ b/core/java/android/content/pm/ShortcutServiceInternal.java
@@ -45,8 +45,8 @@
getShortcuts(int launcherUserId,
@NonNull String callingPackage, long changedSince,
@Nullable String packageName, @Nullable List<String> shortcutIds,
- @Nullable ComponentName componentName, @Nullable Intent intent,
- @ShortcutQuery.QueryFlags int flags, int userId);
+ @Nullable ComponentName componentName, @ShortcutQuery.QueryFlags int flags,
+ int userId);
public abstract boolean
isPinnedByCaller(int launcherUserId, @NonNull String callingPackage,
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 99fbee1..c8353c9 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -16,6 +16,11 @@
package android.content.res;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+import android.view.Display;
+import android.view.DisplayInfo;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -293,6 +298,16 @@
*/
public int screenLayout;
+ /**
+ * @hide
+ * {@link android.graphics.Rect} defining app bounds. The dimensions override usages of
+ * {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at
+ * the display level. Lower levels can override these values to provide custom bounds to enforce
+ * features such as a max aspect ratio.
+ * TODO(b/36812336): Move appBounds out of {@link Configuration}.
+ */
+ public Rect appBounds;
+
/** @hide */
static public int resetScreenLayout(int curLayout) {
return (curLayout&~(SCREENLAYOUT_LONG_MASK | SCREENLAYOUT_SIZE_MASK
@@ -882,6 +897,7 @@
compatScreenWidthDp = o.compatScreenWidthDp;
compatScreenHeightDp = o.compatScreenHeightDp;
compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
+ setAppBounds(o.appBounds);
assetsSeq = o.assetsSeq;
seq = o.seq;
}
@@ -1032,6 +1048,9 @@
case NAVIGATIONHIDDEN_YES: sb.append("/h"); break;
default: sb.append("/"); sb.append(navigationHidden); break;
}
+ if (appBounds != null) {
+ sb.append(" appBounds="); sb.append(appBounds);
+ }
if (assetsSeq != 0) {
sb.append(" as.").append(assetsSeq);
}
@@ -1066,6 +1085,7 @@
smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
densityDpi = DENSITY_DPI_UNDEFINED;
assetsSeq = ASSETS_SEQ_UNDEFINED;
+ appBounds = null;
seq = 0;
}
@@ -1253,6 +1273,10 @@
if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) {
compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp;
}
+ if (delta.appBounds != null && !delta.appBounds.equals(appBounds)) {
+ changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ setAppBounds(delta.appBounds);
+ }
if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED) {
changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
assetsSeq = delta.assetsSeq;
@@ -1399,6 +1423,13 @@
changed |= ActivityInfo.CONFIG_ASSETS_PATHS;
}
+ // Make sure that one of the values is not null and that they are not equal.
+ if ((compareUndefined || delta.appBounds != null)
+ && appBounds != delta.appBounds
+ && (appBounds == null || !appBounds.equals(delta.appBounds))) {
+ changed |= ActivityInfo.CONFIG_SCREEN_SIZE;
+ }
+
return changed;
}
@@ -1494,6 +1525,7 @@
dest.writeInt(compatScreenWidthDp);
dest.writeInt(compatScreenHeightDp);
dest.writeInt(compatSmallestScreenWidthDp);
+ dest.writeValue(appBounds);
dest.writeInt(assetsSeq);
dest.writeInt(seq);
}
@@ -1529,6 +1561,7 @@
compatScreenWidthDp = source.readInt();
compatScreenHeightDp = source.readInt();
compatSmallestScreenWidthDp = source.readInt();
+ appBounds = (Rect) source.readValue(null);
assetsSeq = source.readInt();
seq = source.readInt();
}
@@ -1706,6 +1739,33 @@
/**
* @hide
*
+ * Helper method for setting the app bounds.
+ */
+ public void setAppBounds(Rect rect) {
+ if (rect == null) {
+ appBounds = null;
+ return;
+ }
+
+ setAppBounds(rect.left, rect.top, rect.right, rect.bottom);
+ }
+
+ /**
+ * @hide
+ *
+ * Helper method for setting the app bounds.
+ */
+ public void setAppBounds(int left, int top, int right, int bottom) {
+ if (appBounds == null) {
+ appBounds = new Rect();
+ }
+
+ appBounds.set(left, top, right, bottom);
+ }
+
+ /**
+ * @hide
+ *
* Clears the locale without changing layout direction.
*/
public void clearLocales() {
@@ -2212,6 +2272,7 @@
private static final String XML_ATTR_SCREEN_HEIGHT = "height";
private static final String XML_ATTR_SMALLEST_WIDTH = "sw";
private static final String XML_ATTR_DENSITY = "density";
+ private static final String XML_ATTR_APP_BOUNDS = "app_bounds";
/**
* Reads the attributes corresponding to Configuration member fields from the Xml parser.
@@ -2261,6 +2322,8 @@
SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY,
DENSITY_DPI_UNDEFINED);
+ configOut.appBounds =
+ Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS));
// For persistence, we don't care about assetsSeq, so do not read it out.
}
@@ -2332,6 +2395,11 @@
XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi);
}
+ if (config.appBounds != null) {
+ XmlUtils.writeStringAttribute(xml, XML_ATTR_APP_BOUNDS,
+ config.appBounds.flattenToString());
+ }
+
// For persistence, we do not care about assetsSeq, so do not write it out.
}
}
diff --git a/core/java/android/os/StatFs.java b/core/java/android/os/StatFs.java
index 13e9a15..d9e516c 100644
--- a/core/java/android/os/StatFs.java
+++ b/core/java/android/os/StatFs.java
@@ -61,15 +61,15 @@
*/
@Deprecated
public int getBlockSize() {
- return (int) mStat.f_bsize;
+ return (int) mStat.f_frsize;
}
/**
* The size, in bytes, of a block on the file system. This corresponds to
- * the Unix {@code statvfs.f_bsize} field.
+ * the Unix {@code statvfs.f_frsize} field.
*/
public long getBlockSizeLong() {
- return mStat.f_bsize;
+ return mStat.f_frsize;
}
/**
@@ -112,7 +112,7 @@
* will want to use {@link #getAvailableBytes()} instead.
*/
public long getFreeBytes() {
- return mStat.f_bfree * mStat.f_bsize;
+ return mStat.f_bfree * mStat.f_frsize;
}
/**
@@ -136,13 +136,13 @@
* applications.
*/
public long getAvailableBytes() {
- return mStat.f_bavail * mStat.f_bsize;
+ return mStat.f_bavail * mStat.f_frsize;
}
/**
* The total number of bytes supported by the file system.
*/
public long getTotalBytes() {
- return mStat.f_blocks * mStat.f_bsize;
+ return mStat.f_blocks * mStat.f_frsize;
}
}
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 8e01030..56b267f 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -19,11 +19,13 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.Dialog;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.res.Resources;
import android.graphics.drawable.Icon;
import android.os.Handler;
import android.os.IBinder;
@@ -34,6 +36,8 @@
import android.view.View.OnAttachStateChangeListener;
import android.view.WindowManager;
+import com.android.internal.R;
+
/**
* A TileService provides the user a tile that can be added to Quick Settings.
* Quick Settings is a space provided that allows the user to change settings and
@@ -425,6 +429,15 @@
}
/**
+ * @return True if the device supports quick settings and its assocated APIs.
+ * @hide
+ */
+ @TestApi
+ public static boolean isQuickSettingsSupported() {
+ return Resources.getSystem().getBoolean(R.bool.config_quickSettingsSupported);
+ }
+
+ /**
* Requests that a tile be put in the listening state so it can send an update.
*
* This method is only applicable to tiles that have {@link #META_DATA_ACTIVE_TILE} defined
diff --git a/core/java/android/text/BidiFormatter.java b/core/java/android/text/BidiFormatter.java
index d84502f..f65f397 100644
--- a/core/java/android/text/BidiFormatter.java
+++ b/core/java/android/text/BidiFormatter.java
@@ -592,10 +592,21 @@
static {
DIR_TYPE_CACHE = new byte[DIR_TYPE_CACHE_SIZE];
for (int i = 0; i < DIR_TYPE_CACHE_SIZE; i++) {
+ // Calling Character.getDirectionality() is OK here, since new emojis start after
+ // the end of our cache.
DIR_TYPE_CACHE[i] = Character.getDirectionality(i);
}
}
+ private static byte getDirectionality(int codePoint) {
+ if (Emoji.isNewEmoji(codePoint)) {
+ // TODO: Fix or remove once emoji-data.text 5.0 is in ICU or update to 6.0.
+ return Character.DIRECTIONALITY_OTHER_NEUTRALS;
+ } else {
+ return Character.getDirectionality(codePoint);
+ }
+ }
+
// Internal instance variables.
/**
@@ -809,7 +820,7 @@
* cache.
*/
private static byte getCachedDirectionality(char c) {
- return c < DIR_TYPE_CACHE_SIZE ? DIR_TYPE_CACHE[c] : Character.getDirectionality(c);
+ return c < DIR_TYPE_CACHE_SIZE ? DIR_TYPE_CACHE[c] : getDirectionality(c);
}
/**
@@ -826,7 +837,7 @@
if (Character.isHighSurrogate(lastChar)) {
int codePoint = Character.codePointAt(text, charIndex);
charIndex += Character.charCount(codePoint);
- return Character.getDirectionality(codePoint);
+ return getDirectionality(codePoint);
}
charIndex++;
byte dirType = getCachedDirectionality(lastChar);
@@ -856,7 +867,7 @@
if (Character.isLowSurrogate(lastChar)) {
int codePoint = Character.codePointBefore(text, charIndex);
charIndex -= Character.charCount(codePoint);
- return Character.getDirectionality(codePoint);
+ return getDirectionality(codePoint);
}
charIndex--;
byte dirType = getCachedDirectionality(lastChar);
diff --git a/core/java/android/text/Emoji.java b/core/java/android/text/Emoji.java
index ee016c1..d33aad9 100644
--- a/core/java/android/text/Emoji.java
+++ b/core/java/android/text/Emoji.java
@@ -65,22 +65,32 @@
return UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI_MODIFIER_BASE);
}
- // Returns true if the character has Emoji property.
- public static boolean isEmoji(int codePoint) {
+ /**
+ * Returns true if the character is a new emoji still not supported in our version of ICU.
+ */
+ public static boolean isNewEmoji(int codePoint) {
// Emoji characters new in Unicode emoji 5.0.
// From http://www.unicode.org/Public/emoji/5.0/emoji-data.txt
// TODO: Remove once emoji-data.text 5.0 is in ICU or update to 6.0.
- if ((0x1F6F7 <= codePoint && codePoint <= 0x1F6F8)
+ if (codePoint < 0x1F6F7 || codePoint > 0x1F9E6) {
+ // Optimization for characters outside the new emoji range.
+ return false;
+ }
+ return (0x1F6F7 <= codePoint && codePoint <= 0x1F6F8)
|| codePoint == 0x1F91F
|| (0x1F928 <= codePoint && codePoint <= 0x1F92F)
|| (0x1F931 <= codePoint && codePoint <= 0x1F932)
|| codePoint == 0x1F94C
|| (0x1F95F <= codePoint && codePoint <= 0x1F96B)
|| (0x1F992 <= codePoint && codePoint <= 0x1F997)
- || (0x1F9D0 <= codePoint && codePoint <= 0x1F9E6)) {
- return true;
- }
- return UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI);
+ || (0x1F9D0 <= codePoint && codePoint <= 0x1F9E6);
+ }
+
+ /**
+ * Returns true if the character has Emoji property.
+ */
+ public static boolean isEmoji(int codePoint) {
+ return isNewEmoji(codePoint) || UCharacter.hasBinaryProperty(codePoint, UProperty.EMOJI);
}
// Returns true if the character can be a base character of COMBINING ENCLOSING KEYCAP.
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 3d11dcb..0cec496 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -562,12 +562,10 @@
outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
- width = (configuration != null
- && configuration.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED)
- ? (int)((configuration.screenWidthDp * outMetrics.density) + 0.5f) : width;
- height = (configuration != null
- && configuration.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED)
- ? (int)((configuration.screenHeightDp * outMetrics.density) + 0.5f) : height;
+ width = configuration != null && configuration.appBounds != null
+ ? configuration.appBounds.width() : width;
+ height = configuration != null && configuration.appBounds != null
+ ? configuration.appBounds.height() : height;
outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index ae1ee42..d25e5f0 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -118,7 +118,7 @@
* @return the "effective" root of {@param focused}
*/
private ViewGroup getEffectiveRoot(ViewGroup root, View focused) {
- if (focused == null) {
+ if (focused == null || focused == root) {
return root;
}
ViewParent effective = focused.getParent();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 884283d..b12a767 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -25523,7 +25523,7 @@
* <p>
* The tooltip will be displayed:
* <ul>
- * <li>On long click, unless is not handled otherwise (by OnLongClickListener or a context
+ * <li>On long click, unless it is handled otherwise (by OnLongClickListener or a context
* menu). </li>
* <li>On hover, after a brief delay since the pointer has stopped moving </li>
* </ul>
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 79b0420..958d761 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1018,9 +1018,20 @@
}
}
- /** @hide */
+ /**
+ * This method is still kept for a while until android.support.v7.widget.SearchView ver. 26.0
+ * is publicly released because previous implementations of that class had relied on this method
+ * via reflection.
+ *
+ * @deprecated This is a hidden API. You should never use this.
+ * @hide
+ */
+ @Deprecated
public void showSoftInputUnchecked(int flags, ResultReceiver resultReceiver) {
try {
+ Log.w(TAG, "showSoftInputUnchecked() is a hidden method, which will be removed "
+ + "soon. If you are using android.support.v7.widget.SearchView, please update "
+ + "to version 26.0 or newer version.");
mService.showSoftInput(mClient, flags, resultReceiver);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index c235ebd..df65659 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -23,21 +23,15 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
import android.content.pm.LabeledIntent;
-import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
-import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutManager;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
@@ -362,7 +356,6 @@
mChooserListAdapter.addServiceResults(null, Lists.newArrayList(mCallerChooserTargets));
}
mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter);
- mChooserRowAdapter.updateRowScales();
mChooserRowAdapter.registerDataSetObserver(new OffsetDataSetObserver(adapterView));
adapterView.setAdapter(mChooserRowAdapter);
if (listView != null) {
@@ -849,9 +842,7 @@
return false;
}
intent.setComponent(mChooserTarget.getComponentName());
- if (mChooserTarget.getIntentExtras() != null) {
- intent.putExtras(mChooserTarget.getIntentExtras());
- }
+ intent.putExtras(mChooserTarget.getIntentExtras());
// Important: we will ignore the target security checks in ActivityManager
// if and only if the ChooserTarget's target package is the same package
@@ -934,8 +925,6 @@
private static final int MAX_SERVICE_TARGETS = 8;
private static final int MAX_TARGETS_PER_SERVICE = 4;
- private boolean mAreChooserShortcutsRetrieved;
-
private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
private final List<TargetInfo> mCallerTargets = new ArrayList<>();
private boolean mShowServiceTargets;
@@ -1027,21 +1016,6 @@
if (mServiceTargets != null) {
pruneServiceTargets();
}
-
- if (DEBUG) Log.d(TAG, "Adding pushed chooser targets");
-
- if (!mAreChooserShortcutsRetrieved) {
- LauncherApps launcherApps = getLauncherApps();
- LauncherApps.ShortcutQuery query = new LauncherApps.ShortcutQuery();
- query.setIntent(getTargetIntent());
- query.setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_CHOOSER);
- List<ShortcutInfo> shortcuts = launcherApps.getShortcuts(query,
- android.os.Process.myUserHandle());
- if (DEBUG) Log.d(TAG, "Adding " + shortcuts.size() + " chooser shortcuts");
- addShortcuts(shortcuts);
- mAreChooserShortcutsRetrieved = true;
- }
-
if (DEBUG) Log.d(TAG, "List built querying services");
queryTargetServices(this);
}
@@ -1067,7 +1041,6 @@
public int getServiceTargetCount() {
if (!mShowServiceTargets) {
- if (DEBUG) Log.d("TAG", "Hiding service targets");
return 0;
}
return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS);
@@ -1159,71 +1132,6 @@
notifyDataSetChanged();
}
- // TODO: Pushed targets need to be scored correctly
- public void addShortcuts(List<ShortcutInfo> infos) {
- for (ShortcutInfo info : infos) {
- List<ChooserTarget> newTargets = new ArrayList<>();
- final ComponentName cn = info.getActivity();
- ActivityInfo ai;
- ResolveInfo ri = new ResolveInfo();
- if (cn != null) {
- try {
- ai = getPackageManager().getActivityInfo(cn, 0);
- ri.activityInfo = ai;
- UserManager userManager =
- (UserManager) getSystemService(Context.USER_SERVICE);
- ri.iconResourceId = ai.icon;
- ri.labelRes = ai.labelRes;
- ri.resolvePackageName = ai.packageName;
- ri.activityInfo.applicationInfo = new ApplicationInfo(
- ri.activityInfo.applicationInfo);
- ri.activityInfo.applicationInfo = ai.applicationInfo;
- ri.activityInfo.applicationInfo.uid = getUserId();
- } catch (PackageManager.NameNotFoundException ignored) {
- if (DEBUG) Log.d(TAG, "Package not found, skipping this shortcut");
- continue;
- }
- }
-
- DisplayResolveInfo resolveInfo = new DisplayResolveInfo(getTargetIntent(),
- ri,
- info.getShortLabel(),
- info.getLongLabel(),
- getTargetIntent());
-
- int bestMatch = 0;
- ComponentName bestComponent = null;
- for (int i = 0; i < info.getChooserIntentFilters().length; i++) {
- int newMatch = info.getChooserIntentFilters()[i]
- .match(getContentResolver(), getTargetIntent(), false, TAG);
- if (DEBUG) Log.d(TAG, "A match was found with value: " + newMatch);
- if (newMatch > bestMatch) {
- bestMatch = newMatch;
- bestComponent = info.getChooserComponentNames()[i];
- }
- }
- if (bestMatch == 0) {
- Log.e(TAG, "Unexpectedly, no match was found for the provided chooser intent");
- return;
- }
-
- Bundle extrasToAdd =
- info.getChooserExtras() == null ? null: new Bundle(info.getChooserExtras());
- if (DEBUG) Log.d(TAG, "Adding service target " + info.getShortLabel());
- newTargets.add(new ChooserTarget(
- info.getShortLabel(),
- info.getIcon(),
- 1,
- bestComponent,
- extrasToAdd));
- addServiceResults(resolveInfo, newTargets);
- }
- if (mChooserRowAdapter != null) {
- mChooserRowAdapter.updateRowScales();
- }
- setShowServiceTargets(true);
- }
-
/**
* Set to true to reveal all service targets at once.
*/
@@ -1338,7 +1246,37 @@
@Override
public void onChanged() {
super.onChanged();
- updateRowScales();
+ final int rcount = getServiceTargetRowCount();
+ if (mServiceTargetScale == null
+ || mServiceTargetScale.length != rcount) {
+ RowScale[] old = mServiceTargetScale;
+ int oldRCount = old != null ? old.length : 0;
+ mServiceTargetScale = new RowScale[rcount];
+ if (old != null && rcount > 0) {
+ System.arraycopy(old, 0, mServiceTargetScale, 0,
+ Math.min(old.length, rcount));
+ }
+
+ for (int i = rcount; i < oldRCount; i++) {
+ old[i].cancelAnimation();
+ }
+
+ for (int i = oldRCount; i < rcount; i++) {
+ final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f)
+ .setInterpolator(mInterpolator);
+ mServiceTargetScale[i] = rs;
+ }
+
+ // Start the animations in a separate loop.
+ // The process of starting animations will result in
+ // binding views to set up initial values, and we must
+ // have ALL of the new RowScale objects created above before
+ // we get started.
+ for (int i = oldRCount; i < rcount; i++) {
+ mServiceTargetScale[i].startAnimation();
+ }
+ }
+
notifyDataSetChanged();
}
@@ -1355,40 +1293,6 @@
});
}
- void updateRowScales() {
- final int rcount = getServiceTargetRowCount();
- if (mServiceTargetScale == null
- || mServiceTargetScale.length != rcount) {
- if (DEBUG) Log.d(TAG, "Row scales need adjusting to " + rcount + " rows.");
- RowScale[] old = mServiceTargetScale;
- int oldRCount = old != null ? old.length : 0;
- mServiceTargetScale = new RowScale[rcount];
- if (old != null && rcount > 0) {
- System.arraycopy(old, 0, mServiceTargetScale, 0,
- Math.min(old.length, rcount));
- }
-
- for (int i = rcount; i < oldRCount; i++) {
- old[i].cancelAnimation();
- }
-
- for (int i = oldRCount; i < rcount; i++) {
- final RowScale rs = new RowScale(ChooserRowAdapter.this, 0.f, 1.f)
- .setInterpolator(mInterpolator);
- mServiceTargetScale[i] = rs;
- }
-
- // Start the animations in a separate loop.
- // The process of starting animations will result in
- // binding views to set up initial values, and we must
- // have ALL of the new RowScale objects created above before
- // we get started.
- for (int i = oldRCount; i < rcount; i++) {
- mServiceTargetScale[i].startAnimation();
- }
- }
- }
-
private float getRowScale(int rowPosition) {
final int start = getCallerTargetRowCount();
final int end = start + getServiceTargetRowCount();
@@ -1659,10 +1563,6 @@
}
}
- public LauncherApps getLauncherApps() {
- return (LauncherApps) getSystemService(Context.LAUNCHER_APPS_SERVICE);
- }
-
static class ServiceResultInfo {
public final DisplayResolveInfo originalTarget;
public final List<ChooserTarget> resultTargets;
diff --git a/core/java/com/android/internal/os/FuseAppLoop.java b/core/java/com/android/internal/os/FuseAppLoop.java
index 8edd637..088e726 100644
--- a/core/java/com/android/internal/os/FuseAppLoop.java
+++ b/core/java/com/android/internal/os/FuseAppLoop.java
@@ -20,6 +20,7 @@
import android.annotation.Nullable;
import android.os.ProxyFileDescriptorCallback;
import android.os.Handler;
+import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.OsConstants;
@@ -28,10 +29,11 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.ThreadFactory;
-public class FuseAppLoop {
+public class FuseAppLoop implements Handler.Callback {
private static final String TAG = "FuseAppLoop";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final int ROOT_INODE = 1;
@@ -43,13 +45,11 @@
}
};
private static final int FUSE_OK = 0;
+ private static final int ARGS_POOL_SIZE = 50;
private final Object mLock = new Object();
private final int mMountPointId;
private final Thread mThread;
- private final Handler mDefaultHandler;
-
- private static final int CMD_FSYNC = 1;
@GuardedBy("mLock")
private final SparseArray<CallbackEntry> mCallbackMap = new SparseArray<>();
@@ -57,6 +57,9 @@
@GuardedBy("mLock")
private final BytesMap mBytesMap = new BytesMap();
+ @GuardedBy("mLock")
+ private final LinkedList<Args> mArgsPool = new LinkedList<>();
+
/**
* Sequential number can be used as file name and inode in AppFuse.
* 0 is regarded as an error, 1 is mount point. So we start the number from 2.
@@ -83,7 +86,6 @@
}
});
mThread.start();
- mDefaultHandler = null;
}
public int registerCallback(@NonNull ProxyFileDescriptorCallback callback,
@@ -110,7 +112,8 @@
break;
}
}
- mCallbackMap.put(id, new CallbackEntry(callback, handler));
+ mCallbackMap.put(id, new CallbackEntry(
+ callback, new Handler(handler.getLooper(), this)));
return id;
}
}
@@ -137,78 +140,113 @@
// Defined in FuseBuffer.h
private static final int FUSE_MAX_WRITE = 256 * 1024;
+ @Override
+ public boolean handleMessage(Message msg) {
+ final Args args = (Args) msg.obj;
+ final CallbackEntry entry = args.entry;
+ final long inode = args.inode;
+ final long unique = args.unique;
+ final int size = args.size;
+ final long offset = args.offset;
+ final byte[] data = args.data;
+
+ try {
+ switch (msg.what) {
+ case FUSE_LOOKUP: {
+ final long fileSize = entry.callback.onGetSize();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyLookup(mInstance, unique, inode, fileSize);
+ }
+ recycleLocked(args);
+ }
+ break;
+ }
+ case FUSE_GETATTR: {
+ final long fileSize = entry.callback.onGetSize();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyGetAttr(mInstance, unique, inode, fileSize);
+ }
+ recycleLocked(args);
+ }
+ break;
+ }
+ case FUSE_READ:
+ final int readSize = entry.callback.onRead(
+ offset, size, data);
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyRead(mInstance, unique, readSize, data);
+ }
+ recycleLocked(args);
+ }
+ break;
+ case FUSE_WRITE:
+ final int writeSize = entry.callback.onWrite(offset, size, data);
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replyWrite(mInstance, unique, writeSize);
+ }
+ recycleLocked(args);
+ }
+ break;
+ case FUSE_FSYNC:
+ entry.callback.onFsync();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replySimple(mInstance, unique, FUSE_OK);
+ }
+ recycleLocked(args);
+ }
+ break;
+ case FUSE_RELEASE:
+ entry.callback.onRelease();
+ synchronized (mLock) {
+ if (mInstance != 0) {
+ native_replySimple(mInstance, unique, FUSE_OK);
+ }
+ mBytesMap.stopUsing(entry.getThreadId());
+ recycleLocked(args);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown FUSE command: " + msg.what);
+ }
+ } catch (Exception error) {
+ synchronized (mLock) {
+ Log.e(TAG, "", error);
+ replySimpleLocked(unique, getError(error));
+ recycleLocked(args);
+ }
+ }
+
+ return true;
+ }
+
// Called by JNI.
@SuppressWarnings("unused")
private void onCommand(int command, long unique, long inode, long offset, int size,
byte[] data) {
- synchronized(mLock) {
+ synchronized (mLock) {
try {
- final CallbackEntry entry = getCallbackEntryOrThrowLocked(inode);
- entry.postRunnable(() -> {
- try {
- switch (command) {
- case FUSE_LOOKUP: {
- final long fileSize = entry.callback.onGetSize();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyLookup(mInstance, unique, inode, fileSize);
- }
- }
- break;
- }
- case FUSE_GETATTR: {
- final long fileSize = entry.callback.onGetSize();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyGetAttr(mInstance, unique, inode, fileSize);
- }
- }
- break;
- }
- case FUSE_READ:
- final int readSize = entry.callback.onRead(offset, size, data);
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyRead(mInstance, unique, readSize, data);
- }
- }
- break;
- case FUSE_WRITE:
- final int writeSize = entry.callback.onWrite(offset, size, data);
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replyWrite(mInstance, unique, writeSize);
- }
- }
- break;
- case FUSE_FSYNC:
- entry.callback.onFsync();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replySimple(mInstance, unique, FUSE_OK);
- }
- }
- break;
- case FUSE_RELEASE:
- entry.callback.onRelease();
- synchronized (mLock) {
- if (mInstance != 0) {
- native_replySimple(mInstance, unique, FUSE_OK);
- }
- mBytesMap.stopUsing(entry.getThreadId());
- }
- break;
- default:
- throw new IllegalArgumentException(
- "Unknown FUSE command: " + command);
- }
- } catch (Exception error) {
- Log.e(TAG, "", error);
- replySimple(unique, getError(error));
- }
- });
- } catch (ErrnoException error) {
- Log.e(TAG, "", error);
+ final Args args;
+ if (mArgsPool.size() == 0) {
+ args = new Args();
+ } else {
+ args = mArgsPool.pop();
+ }
+ args.unique = unique;
+ args.inode = inode;
+ args.offset = offset;
+ args.size = size;
+ args.data = data;
+ args.entry = getCallbackEntryOrThrowLocked(inode);
+ if (!args.entry.handler.sendMessage(
+ Message.obtain(args.entry.handler, command, 0, 0, args))) {
+ throw new ErrnoException("onCommand", OsConstants.EBADF);
+ }
+ } catch (Exception error) {
replySimpleLocked(unique, getError(error));
}
}
@@ -253,9 +291,9 @@
return entry;
}
- private void replySimple(long unique, int result) {
- synchronized (mLock) {
- replySimpleLocked(unique, result);
+ private void recycleLocked(Args args) {
+ if (mArgsPool.size() < ARGS_POOL_SIZE) {
+ mArgsPool.add(args);
}
}
@@ -296,13 +334,6 @@
long getThreadId() {
return handler.getLooper().getThread().getId();
}
-
- void postRunnable(Runnable runnable) throws ErrnoException {
- final boolean result = handler.post(runnable);
- if (!result) {
- throw new ErrnoException("postRunnable", OsConstants.EBADF);
- }
- }
}
/**
@@ -342,4 +373,13 @@
mEntries.clear();
}
}
+
+ private static class Args {
+ long unique;
+ long inode;
+ long offset;
+ int size;
+ byte[] data;
+ CallbackEntry entry;
+ }
}
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index 64e1d10..4659d3c 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -16,7 +16,12 @@
package com.android.internal.util;
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
import android.os.Handler;
+import android.util.Slog;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -25,6 +30,9 @@
* Helper functions for dumping the state of system services.
*/
public final class DumpUtils {
+ private static final String TAG = "DumpUtils";
+ private static final boolean DEBUG = true;
+
private DumpUtils() {
}
@@ -55,4 +63,90 @@
public interface Dump {
void dump(PrintWriter pw, String prefix);
}
+
+ private static void logMessage(PrintWriter pw, String msg) {
+ if (DEBUG) Slog.v(TAG, msg);
+ pw.println(msg);
+ }
+
+ /**
+ * Verify that caller holds {@link android.Manifest.permission#DUMP}.
+ *
+ * @return true if access should be granted.
+ * @hide
+ */
+ public static boolean checkDumpPermission(Context context, String tag, PrintWriter pw) {
+ if (context.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " due to missing android.permission.DUMP permission");
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * Verify that caller holds
+ * {@link android.Manifest.permission#PACKAGE_USAGE_STATS} and that they
+ * have {@link AppOpsManager#OP_GET_USAGE_STATS} access.
+ *
+ * @return true if access should be granted.
+ * @hide
+ */
+ public static boolean checkUsageStatsPermission(Context context, String tag, PrintWriter pw) {
+ // System internals always get access
+ final int uid = Binder.getCallingUid();
+ switch (uid) {
+ case android.os.Process.ROOT_UID:
+ case android.os.Process.SYSTEM_UID:
+ case android.os.Process.SHELL_UID:
+ return true;
+ }
+
+ // Caller always needs to hold permission
+ if (context.checkCallingOrSelfPermission(android.Manifest.permission.PACKAGE_USAGE_STATS)
+ != PackageManager.PERMISSION_GRANTED) {
+ logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " due to missing android.permission.PACKAGE_USAGE_STATS permission");
+ return false;
+ }
+
+ // And finally, caller needs to have appops access; this is totally
+ // hacky, but it's the easiest way to wire this up without retrofitting
+ // Binder.dump() to pass through package names.
+ final AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+ final String[] pkgs = context.getPackageManager().getPackagesForUid(uid);
+ if (pkgs != null) {
+ for (String pkg : pkgs) {
+ if (appOps.checkOpNoThrow(AppOpsManager.OP_GET_USAGE_STATS, uid,
+ pkg) == AppOpsManager.MODE_ALLOWED) {
+ appOps.noteOp(AppOpsManager.OP_GET_USAGE_STATS, uid, pkg);
+ if (DEBUG) Slog.v(TAG, "Found package " + pkg + " with "
+ + "android:get_usage_stats access");
+ return true;
+ }
+ }
+ }
+
+ logMessage(pw, "Permission Denial: can't dump " + tag + " from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ + " due to android:get_usage_stats app-op not allowed");
+ return false;
+ }
+
+ /**
+ * Verify that caller holds both {@link android.Manifest.permission#DUMP}
+ * and {@link android.Manifest.permission#PACKAGE_USAGE_STATS}, and that
+ * they have {@link AppOpsManager#OP_GET_USAGE_STATS} access.
+ *
+ * @return true if access should be granted.
+ * @hide
+ */
+ public static boolean checkDumpAndUsageStatsPermission(Context context, String tag,
+ PrintWriter pw) {
+ return checkDumpPermission(context, tag, pw) && checkUsageStatsPermission(context, tag, pw);
+ }
}
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index b926270..d606c2d 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -78,6 +78,9 @@
camera_frame_metadata_t *metadata);
virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
virtual void postRecordingFrameHandleTimestamp(nsecs_t timestamp, native_handle_t* handle);
+ virtual void postRecordingFrameHandleTimestampBatch(
+ const std::vector<nsecs_t>& timestamps,
+ const std::vector<native_handle_t*>& handles);
void postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata);
void addCallbackBuffer(JNIEnv *env, jbyteArray cbb, int msgType);
void setCallbackMode(JNIEnv *env, bool installed, bool manualMode);
@@ -362,6 +365,22 @@
}
}
+void JNICameraContext::postRecordingFrameHandleTimestampBatch(
+ const std::vector<nsecs_t>&,
+ const std::vector<native_handle_t*>& handles) {
+ // Video buffers are not needed at app layer so just return the video buffers here.
+ // This may be called when stagefright just releases camera but there are still outstanding
+ // video buffers.
+ if (mCamera != nullptr) {
+ mCamera->releaseRecordingFrameHandleBatch(handles);
+ } else {
+ for (auto& handle : handles) {
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ }
+ }
+}
+
void JNICameraContext::postMetadata(JNIEnv *env, int32_t msgType, camera_frame_metadata_t *metadata)
{
jobjectArray obj = NULL;
diff --git a/core/jni/android_text_AndroidBidi.cpp b/core/jni/android_text_AndroidBidi.cpp
index 2a3f036..d744b7c 100644
--- a/core/jni/android_text_AndroidBidi.cpp
+++ b/core/jni/android_text_AndroidBidi.cpp
@@ -22,6 +22,7 @@
#include "utils/misc.h"
#include "utils/Log.h"
#include "unicode/ubidi.h"
+#include <minikin/Emoji.h>
namespace android {
@@ -38,6 +39,9 @@
if (info != NULL) {
UErrorCode status = U_ZERO_ERROR;
UBiDi* bidi = ubidi_openSized(n, 0, &status);
+ // Set callbacks to override bidi classes of new emoji
+ ubidi_setClassCallback(
+ bidi, minikin::emojiBidiOverride, nullptr, nullptr, nullptr, &status);
ubidi_setPara(bidi, chs, n, dir, NULL, &status);
if (U_SUCCESS(status)) {
for (int i = 0; i < n; ++i) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 362794e..e7a447c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -798,13 +798,13 @@
android:description="@string/permdesc_readPhoneState"
android:protectionLevel="dangerous" />
- <!-- Allows read access to the device's phone number. This is a subset of the capabilities
+ <!-- Allows read access to the device's phone number(s). This is a subset of the capabilities
granted by {@link #READ_PHONE_STATE} but is exposed to ephemeral applications.
<p>Protection level: dangerous-->
- <permission android:name="android.permission.READ_PHONE_NUMBER"
+ <permission android:name="android.permission.READ_PHONE_NUMBERS"
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_readPhoneNumber"
- android:description="@string/permdesc_readPhoneNumber"
+ android:description="@string/permdesc_readPhoneNumbers"
android:protectionLevel="dangerous|ephemeral" />
<!-- Allows an application to initiate a phone call without going through
@@ -3346,7 +3346,8 @@
android:documentLaunchMode="never"
android:relinquishTaskIdentity="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
- android:process=":ui">
+ android:process=":ui"
+ android:visibleToInstantApps="true">
<intent-filter>
<action android:name="android.intent.action.CHOOSER" />
<category android:name="android.intent.category.DEFAULT" />
@@ -3360,7 +3361,8 @@
android:documentLaunchMode="never"
android:relinquishTaskIdentity="true"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
- android:process=":ui">
+ android:process=":ui"
+ android:visibleToInstantApps="true">
<intent-filter>
<action android:name="android.intent.action.CHOOSE_ACCESSIBILITY_BUTTON" />
<category android:name="android.intent.category.DEFAULT" />
@@ -3421,7 +3423,8 @@
android:exported="true"
android:theme="@style/Theme.DeviceDefault.Light.Dialog"
android:label="@string/choose_account_label"
- android:process=":ui">
+ android:process=":ui"
+ android:visibleToInstantApps="true">
</activity>
<activity android:name="android.accounts.ChooseTypeAndAccountActivity"
@@ -3429,14 +3432,16 @@
android:exported="true"
android:theme="@style/Theme.DeviceDefault.Light.Dialog"
android:label="@string/choose_account_label"
- android:process=":ui">
+ android:process=":ui"
+ android:visibleToInstantApps="true">
</activity>
<activity android:name="android.accounts.ChooseAccountTypeActivity"
android:excludeFromRecents="true"
android:theme="@style/Theme.DeviceDefault.Light.Dialog"
android:label="@string/choose_account_label"
- android:process=":ui">
+ android:process=":ui"
+ android:visibleToInstantApps="true">
</activity>
<activity android:name="android.accounts.CantAddAccountActivity"
@@ -3450,7 +3455,8 @@
android:excludeFromRecents="true"
android:exported="true"
android:theme="@style/Theme.DeviceDefault.Light.DialogWhenLarge"
- android:process=":ui">
+ android:process=":ui"
+ android:visibleToInstantApps="true">
</activity>
<activity android:name="android.content.SyncActivityTooManyDeletes"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index bcd8a8a..85ecaff 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2819,4 +2819,7 @@
density will be scaled accordingly to maintain aspect ratio. A value of 0 indicates no
constraint will be enforced. -->
<integer name="config_maxUiWidth">0</integer>
+
+ <!-- Whether the device supports quick settings and its associated APIs -->
+ <bool name="config_quickSettingsSupported">true</bool>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4afa8dc..831cf89 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -20,10 +20,8 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Suffix added to a number to signify size in bytes. -->
<string name="byteShort">B</string>
- <!-- Suffix added to a number to signify size in kilobytes (1000 bytes).
- If you retain the Latin script for the localization, please use the lowercase
- 'k', as it signifies 1000 bytes as opposed to 1024 bytes. -->
- <string name="kilobyteShort">kB</string>
+ <!-- Suffix added to a number to signify size in kilobytes (1000 bytes). -->
+ <string name="kilobyteShort">KB</string>
<!-- Suffix added to a number to signify size in megabytes. -->
<string name="megabyteShort">MB</string>
<!-- Suffix added to a number to signify size in gigabytes. -->
@@ -1094,9 +1092,9 @@
order to improve the calling experience.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_readPhoneNumber">read phone number</string>
+ <string name="permlab_readPhoneNumbers">read phone numbers</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_readPhoneNumber">Allows the app to access the phone number of the device.</string>
+ <string name="permdesc_readPhoneNumbers">Allows the app to access the phone numbers of the device.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_wakeLock" product="tablet">prevent tablet from sleeping</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index dfd18e7..ae05a69 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2955,4 +2955,5 @@
<java-symbol type="string" name="etws_primary_default_message_test" />
<java-symbol type="string" name="etws_primary_default_message_others" />
+ <java-symbol type="bool" name="config_quickSettingsSupported" />
</resources>
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 3dfecc6..1080a9f 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -16,17 +16,6 @@
package com.android.internal.app;
-import android.app.Instrumentation;
-import android.content.ComponentName;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherApps;
-import android.content.pm.PackageManager;
-import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutManager;
-import android.graphics.drawable.Icon;
-import android.os.SystemClock;
import com.android.internal.R;
import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
@@ -59,31 +48,25 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.isA;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.times;
/**
* Chooser activity instrumentation tests
*/
@RunWith(AndroidJUnit4.class)
public class ChooserActivityTest {
- private Instrumentation instrumentation;
-
- @Before
- public void setUp() {
- instrumentation = InstrumentationRegistry.getInstrumentation();
- sOverrides.reset();
- }
-
@Rule
public ActivityTestRule<ChooserWrapperActivity> mActivityRule =
new ActivityTestRule<>(ChooserWrapperActivity.class, false,
false);
+ @Before
+ public void cleanOverrideData() {
+ sOverrides.reset();
+ }
+
@Test
public void customTitle() throws InterruptedException {
Intent sendIntent = createSendImageIntent();
@@ -252,6 +235,7 @@
chosen[0] = targetInfo.getResolveInfo();
return true;
};
+
// Make a stable copy of the components as the original list may be modified
List<ResolvedComponentInfo> stableCopy =
createResolvedComponentsForTestWithOtherProfile(2);
@@ -340,32 +324,6 @@
assertThat(chosen[0], is(toChoose));
}
- public void pushedChooserTarget() {
- ResolveInfo[] chosen = new ResolveInfo[1];
- sOverrides.onSafelyStartCallback = targetInfo -> {
- chosen[0] = targetInfo.getResolveInfo();
- return true;
- };
-
- setChooserShortcuts(1);
- List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
- when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
- Mockito.anyBoolean(),
- Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
-
- Intent sendIntent = createSendImageIntent();
- final ChooserWrapperActivity activity = mActivityRule
- .launchActivity(Intent.createChooser(sendIntent, null));
-
- waitForIdle();
-
- onView(withText("short chooser label 0"))
- .perform(click());
- waitForIdle();
- assertThat(chosen[0].resolvePackageName,
- is(ResolverDataProvider.createActivityInfo(0).packageName));
- }
-
private Intent createSendImageIntent() {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
@@ -413,48 +371,4 @@
}
return packageStats.mChooserCounts.get(action).getOrDefault(annotation, 0);
}
-
- private void setChooserShortcuts(int numShortcuts) {
- ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
- for (int i = 0; i < numShortcuts; i++) {
- shortcuts.add(makeShortcut(i));
- }
- when(sOverrides.launcherApps.getShortcuts(
- Mockito.isA(LauncherApps.ShortcutQuery.class),
- Mockito.eq(UserHandle.SYSTEM)))
- .thenReturn(shortcuts);
- }
-
- private ShortcutInfo makeShortcut(int i) {
- try {
- IntentFilter filter = new IntentFilter(Intent.ACTION_SEND, "image/jpeg");
-
- ComponentName component = new ComponentName("foo.bar", "foo.bar" + ".MainActivity");
- ShortcutInfo.Builder b = new ShortcutInfo.Builder(instrumentation.getContext(), "" + i)
- .setActivity(component)
- .setShortLabel("short chooser label " + i)
- .setLongLabel("long chooser label" + i)
- .setRank(i)
- .setIntent(createSendImageIntent())
- .setIcon(Icon.createWithResource(instrumentation.getContext(),
- android.R.drawable.ic_menu_add))
- .addChooserIntentFilter(
- filter,
- component);
-
- sOverrides.createPackageManager = pm -> {
- final PackageManager spied = spy(pm);
- try {
- doAnswer(invocation -> ResolverDataProvider.createActivityInfo(i))
- .when(spied).getActivityInfo(
- Mockito.isA(ComponentName.class), Mockito.anyInt());
- } catch (Exception e) {
- // this is ok, just not found
- e.printStackTrace();
- }
- return spied;
- };
- return b.build();
- } catch (Exception e) {return null;}
- }
}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 0dac260..c446f3c 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -18,7 +18,6 @@
import android.app.usage.UsageStatsManager;
import android.content.Context;
-import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import java.util.function.Function;
@@ -75,11 +74,6 @@
return super.getPackageManager();
}
- @Override
- public LauncherApps getLauncherApps() {
- return sOverrides.launcherApps;
- }
-
/**
* We cannot directly mock the activity created since instrumentation creates it.
* <p>
@@ -88,7 +82,6 @@
static class OverrideData {
@SuppressWarnings("Since15")
public Function<PackageManager, PackageManager> createPackageManager;
- public LauncherApps launcherApps;
public Function<TargetInfo, Boolean> onSafelyStartCallback;
public ResolverListController resolverListController;
public Boolean isVoiceInteraction;
@@ -97,7 +90,6 @@
onSafelyStartCallback = null;
isVoiceInteraction = null;
createPackageManager = null;
- launcherApps = mock(LauncherApps.class);
resolverListController = mock(ResolverListController.class);
}
}
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 5e3488c..86ab3dc 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -181,9 +181,8 @@
<allow-in-power-save package="com.android.cellbroadcastreceiver" />
<allow-in-power-save package="com.android.shell" />
- <!-- Package in charge of provisioning that needs to freely run in the background -->
- <!-- STOPSHIP: Revert this once it is fixed properly -->
- <allow-in-power-save package="com.android.managedprovisioning" />
+ <!-- STOPSHIP(b/36856786): Revert this once it is fixed properly -->
+ <allow-in-power-save package="com.google.android.apps.enterprise.dmagent" />
<!-- These are the packages that are white-listed to be able to run as system user -->
<system-user-whitelisted-app package="com.android.settings" />
diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java
index d69f67d..218b857c 100644
--- a/graphics/java/android/graphics/Color.java
+++ b/graphics/java/android/graphics/Color.java
@@ -289,7 +289,7 @@
* and <code>(1.0, 0.0, 0.0, 0.5)</code>.</p>
*/
@AnyThread
-public final class Color {
+public class Color {
@ColorInt public static final int BLACK = 0xFF000000;
@ColorInt public static final int DKGRAY = 0xFF444444;
@ColorInt public static final int GRAY = 0xFF888888;
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 7f579a2..deafb66 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -20,6 +20,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import java.io.PrintWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -170,6 +171,10 @@
* or null if the string is not of that form.
*/
public static Rect unflattenFromString(String str) {
+ if (TextUtils.isEmpty(str)) {
+ return null;
+ }
+
Matcher matcher = UnflattenHelper.getMatcher(str);
if (!matcher.matches()) {
return null;
@@ -179,7 +184,7 @@
Integer.parseInt(matcher.group(3)),
Integer.parseInt(matcher.group(4)));
}
-
+
/**
* Print short representation to given writer.
* @hide
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index c6c9271..643c0da 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -304,6 +304,9 @@
@Override
public void draw(Canvas canvas) {
+ if (mLayersBitmap == null) {
+ return;
+ }
if (mLayersShader == null) {
mCanvas.setBitmap(mLayersBitmap);
for (int i = 0; i < mLayerState.N_CHILDREN; i++) {
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index d88aee9..04864bd 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -88,7 +88,9 @@
}
@Override
- public @Config int getChangingConfigurations() {
+ public
+ @Config
+ int getChangingConfigurations() {
return super.getChangingConfigurations()
| mDrawableContainerState.getChangingConfigurations();
}
@@ -210,6 +212,7 @@
/**
* Change the global fade duration when a new drawable is entering
* the scene.
+ *
* @param ms The amount of time to fade in milliseconds.
*/
public void setEnterFadeDuration(int ms) {
@@ -219,6 +222,7 @@
/**
* Change the global fade duration when a new drawable is leaving
* the scene.
+ *
* @param ms The amount of time to fade in milliseconds.
*/
public void setExitFadeDuration(int ms) {
@@ -375,6 +379,13 @@
@Override
public void invalidateDrawable(@NonNull Drawable who) {
+ // This may have been called as the result of a tint changing, in
+ // which case we may need to refresh the cached statefulness or
+ // opacity.
+ if (mDrawableContainerState != null) {
+ mDrawableContainerState.invalidateCache();
+ }
+
if (who == mCurrDrawable && getCallback() != null) {
getCallback().invalidateDrawable(this);
}
@@ -822,8 +833,8 @@
mDrawables[pos] = dr;
mNumChildren++;
mChildrenChangingConfigurations |= dr.getChangingConfigurations();
- mCheckedStateful = false;
- mCheckedOpacity = false;
+
+ invalidateCache();
mConstantPadding = null;
mCheckedPadding = false;
@@ -833,6 +844,14 @@
return pos;
}
+ /**
+ * Invalidates the cached opacity and statefulness.
+ */
+ void invalidateCache() {
+ mCheckedOpacity = false;
+ mCheckedStateful = false;
+ }
+
final int getCapacity() {
return mDrawables.length;
}
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 355e45e..322e55b 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -986,6 +986,11 @@
if (mSuspendChildInvalidation) {
mChildRequestedInvalidation = true;
} else {
+ // This may have been called as the result of a tint changing, in
+ // which case we may need to refresh the cached statefulness or
+ // opacity.
+ mLayerState.invalidateCache();
+
invalidateSelf();
}
}
@@ -2121,7 +2126,10 @@
return true;
}
- public void invalidateCache() {
+ /**
+ * Invalidates the cached opacity and statefulness.
+ */
+ void invalidateCache() {
mCheckedOpacity = false;
mCheckedStateful = false;
}
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 06fc4bc..fc60571 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1299,18 +1299,17 @@
String COLUMN_DURATION_MILLIS = "duration_millis";
/**
- * The intent URI which is launched when the preview video is selected.
+ * The intent URI which is launched when the preview program is selected.
*
* <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
* and converted back to the original intent with {@link Intent#parseUri}. The intent is
- * launched when the user selects the preview video item.
+ * launched when the user selects the preview program item.
*
* <p>Can be empty.
*
* <p>Type: TEXT
*/
- String COLUMN_APP_LINK_INTENT_URI =
- "app_link_intent_uri";
+ String COLUMN_INTENT_URI = "intent_uri";
/**
* The flag indicating whether this program is transient or not.
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index cc1e01a..37a68e0 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -220,14 +220,8 @@
public long[] getFileSystemStats(String path) {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
- try {
- final StructStatVfs stat = Os.statvfs(path);
- final long totalSize = stat.f_blocks * stat.f_bsize;
- final long availSize = stat.f_bavail * stat.f_bsize;
- return new long[] { totalSize, availSize };
- } catch (ErrnoException e) {
- throw new IllegalStateException(e);
- }
+ final File file = new File(path);
+ return new long[] { file.getTotalSpace(), file.getUsableSpace() };
}
@Override
diff --git a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java b/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
index 18863ca..862f50b2 100644
--- a/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
+++ b/packages/ExtServices/src/android/ext/services/storage/CacheQuotaServiceImpl.java
@@ -1,4 +1,3 @@
-
/*
* Copyright (C) 2017 The Android Open Source Project
*
@@ -123,10 +122,10 @@
StorageManager storageManager = getSystemService(StorageManager.class);
long freeBytes = 0;
if (uuid == StorageManager.UUID_PRIVATE_INTERNAL) { // regular equals because of null
- freeBytes = Environment.getDataDirectory().getFreeSpace();
+ freeBytes = Environment.getDataDirectory().getUsableSpace();
} else {
final VolumeInfo vol = storageManager.findVolumeByUuid(uuid);
- freeBytes = vol.getPath().getFreeSpace();
+ freeBytes = vol.getPath().getUsableSpace();
}
return Math.round(freeBytes * CACHE_RESERVE_RATIO);
}
diff --git a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java b/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
index cc1699a..df4738f 100644
--- a/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/storage/CacheQuotaServiceImplTest.java
@@ -61,7 +61,7 @@
setContext(mContext);
when(mContext.getSystemService(Context.STORAGE_SERVICE)).thenReturn(mStorageManager);
- when(mFile.getFreeSpace()).thenReturn(10000L);
+ when(mFile.getUsableSpace()).thenReturn(10000L);
when(mVolume.getPath()).thenReturn(mFile);
when(mStorageManager.findVolumeByUuid(sTestVolUuid)).thenReturn(mVolume);
when(mStorageManager.findVolumeByUuid(sSecondTestVolUuid)).thenReturn(mVolume);
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index b60e2fe..b958c28 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -386,7 +386,7 @@
row.add(Root.COLUMN_TITLE, root.title);
row.add(Root.COLUMN_DOCUMENT_ID, root.docId);
row.add(Root.COLUMN_AVAILABLE_BYTES,
- root.reportAvailableBytes ? root.path.getFreeSpace() : -1);
+ root.reportAvailableBytes ? root.path.getUsableSpace() : -1);
}
}
return result;
diff --git a/packages/SettingsLib/res/values/attrs.xml b/packages/SettingsLib/res/values/attrs.xml
index 1f35d3e..ea538fb 100644
--- a/packages/SettingsLib/res/values/attrs.xml
+++ b/packages/SettingsLib/res/values/attrs.xml
@@ -36,6 +36,9 @@
<declare-styleable name="WifiEncryptionState">
<attr name="state_encrypted" format="boolean" />
</declare-styleable>
+ <declare-styleable name="WifiMeteredState">
+ <attr name="state_metered" format="boolean" />
+ </declare-styleable>
<declare-styleable name="WifiSavedState">
<attr name="state_saved" format="boolean" />
</declare-styleable>
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
index ca8edf5..40abb6c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
@@ -16,18 +16,15 @@
package com.android.settingslib.deviceinfo;
-import android.os.storage.StorageManager;
+import android.app.AppGlobals;
+import android.app.usage.StorageStatsManager;
+import android.content.Context;
import android.os.storage.VolumeInfo;
-import android.util.Log;
-
-import java.io.File;
-import java.util.Objects;
/**
* PrivateStorageInfo provides information about the total and free storage on the device.
*/
public class PrivateStorageInfo {
- private static final String TAG = "PrivateStorageInfo";
public final long freeBytes;
public final long totalBytes;
@@ -37,45 +34,23 @@
}
public static PrivateStorageInfo getPrivateStorageInfo(StorageVolumeProvider sm) {
- long totalInternalStorage = sm.getPrimaryStorageSize();
+ final Context context = AppGlobals.getInitialApplication();
+ final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
+
long privateFreeBytes = 0;
long privateTotalBytes = 0;
for (VolumeInfo info : sm.getVolumes()) {
- final File path = info.getPath();
- if (info.getType() != VolumeInfo.TYPE_PRIVATE || path == null) {
- continue;
+ if (info.getType() == VolumeInfo.TYPE_PRIVATE && info.isMountedReadable()) {
+ privateTotalBytes += stats.getTotalBytes(info.getFsUuid());
+ privateFreeBytes += stats.getFreeBytes(info.getFsUuid());
}
- privateTotalBytes += getTotalSize(info, totalInternalStorage);
- privateFreeBytes += path.getFreeSpace();
}
return new PrivateStorageInfo(privateFreeBytes, privateTotalBytes);
}
- /**
- * Returns the total size in bytes for a given volume info.
- * @param info Info of the volume to check.
- * @param totalInternalStorage Total number of bytes in the internal storage to use if the
- * volume is the internal disk.
- */
public static long getTotalSize(VolumeInfo info, long totalInternalStorage) {
- // Device could have more than one primary storage, which could be located in the
- // internal flash (UUID_PRIVATE_INTERNAL) or in an external disk.
- // If it's internal, try to get its total size from StorageManager first
- // (totalInternalStorage), because that size is more precise because it accounts for
- // the system partition.
- if (info.getType() == VolumeInfo.TYPE_PRIVATE
- && Objects.equals(info.getFsUuid(), StorageManager.UUID_PRIVATE_INTERNAL)
- && totalInternalStorage > 0) {
- return totalInternalStorage;
- } else {
- final File path = info.getPath();
- if (path == null) {
- // Should not happen, caller should have checked.
- Log.e(TAG, "info's path is null on getTotalSize(): " + info);
- return 0;
- }
- return path.getTotalSpace();
- }
+ final Context context = AppGlobals.getInitialApplication();
+ final StorageStatsManager stats = context.getSystemService(StorageStatsManager.class);
+ return stats.getTotalBytes(info.getFsUuid());
}
-
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
index 0f443d6..61ca13d 100755
--- a/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/BatteryMeterDrawableBase.java
@@ -63,7 +63,7 @@
mPlusPaint;
private float mTextHeight, mWarningTextHeight;
private int mIconTint = Color.WHITE;
- private float mOldDarkIntensity = 0f;
+ private float mOldDarkIntensity = -1f;
private int mHeight;
private int mWidth;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index a9aaa05..8f8167e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -44,6 +44,10 @@
R.attr.state_encrypted
};
+ private static final int[] STATE_METERED = {
+ R.attr.state_metered
+ };
+
private static final int[] wifi_friction_attributes = { R.attr.wifi_friction };
private final StateListDrawable mFrictionSld;
@@ -179,6 +183,8 @@
}
if (mAccessPoint.getSecurity() != AccessPoint.SECURITY_NONE) {
mFrictionSld.setState(STATE_SECURED);
+ } else if (mAccessPoint.getConfig() != null && mAccessPoint.getConfig().meteredHint) {
+ mFrictionSld.setState(STATE_METERED);
}
Drawable drawable = mFrictionSld.getCurrent();
frictionImageView.setImageDrawable(drawable);
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 6f52dca..ec94841 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -26,7 +26,9 @@
private final WifiManager mWifiManager;
public boolean enabled;
+ public int state;
public boolean connected;
+ public boolean connecting;
public String ssid;
public int rssi;
public int level;
@@ -39,11 +41,18 @@
public void handleBroadcast(Intent intent) {
String action = intent.getAction();
if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+ state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_UNKNOWN);
+ enabled = state == WifiManager.WIFI_STATE_ENABLED;
+
+
enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
final NetworkInfo networkInfo = (NetworkInfo)
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ connecting = networkInfo != null && !networkInfo.isConnected()
+ && networkInfo.isConnectedOrConnecting();
connected = networkInfo != null && networkInfo.isConnected();
WifiInfo info = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO) != null
? (WifiInfo) intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO)
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk
index 635c96f..53c5b1b 100644
--- a/packages/SystemUI/Android.mk
+++ b/packages/SystemUI/Android.mk
@@ -34,6 +34,7 @@
android-support-v7-recyclerview \
android-support-v7-preference \
android-support-v7-appcompat \
+ android-support-v7-mediarouter \
android-support-v14-preference \
android-support-v17-leanback
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml
new file mode 100644
index 0000000..26c6aa7
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_1_animation.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml
new file mode 100644
index 0000000..e1f8989
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_bluetooth_transient_group_2_animation.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_bluetooth_transient_animation_interpolator_0" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@interpolator/ic_bluetooth_transient_animation_interpolator_0" />
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:valueFrom="1.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/fast_out_slow_in" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/anim/ic_signal_wifi_transient_wifi_1_animation.xml b/packages/SystemUI/res/anim/ic_signal_wifi_transient_wifi_1_animation.xml
new file mode 100644
index 0000000..919a4dd
--- /dev/null
+++ b/packages/SystemUI/res/anim/ic_signal_wifi_transient_wifi_1_animation.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0169982910156,18.4394989014 c 0.0,0.0 23.2140045166,-28.766998291 23.2140045166,-28.766998291 c -0.900009155273,-0.675003051758 -9.82899475098,-8.13400268555 -23.2320098877,-8.13400268555 c -13.4029998779,0.0 -22.3299865723,7.45899963379 -23.2299957275,8.13400268555 c 0.0,0.0 23.2140045166,28.766998291 23.2140045166,28.766998291 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueTo="M 0.0169982910156,18.4394989014 c 0.0,0.0 23.2140045166,-28.766998291 23.2140045166,-28.766998291 c -0.900009155273,-0.675003051758 -9.82899475098,-8.13400268555 -23.2320098877,-8.13400268555 c -13.4029998779,0.0 -22.3299865723,7.45899963379 -23.2299957275,8.13400268555 c 0.0,0.0 23.2140045166,28.766998291 23.2140045166,28.766998291 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0169982910156,18.4394989014 c 0.0,0.0 23.2140045166,-28.766998291 23.2140045166,-28.766998291 c -0.900009155273,-0.675003051758 -9.82899475098,-8.13400268555 -23.2320098877,-8.13400268555 c -13.4029998779,0.0 -22.3299865723,7.45899963379 -23.2299957275,8.13400268555 c 0.0,0.0 23.2140045166,28.766998291 23.2140045166,28.766998291 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueTo="M 0.0169982910156,18.4394989014 c 0.0,0.0 9.55569458008,-11.8414916992 9.55569458008,-11.8414916992 c 0.0,0.0 -3.32373046875,-3.83329772949 -9.59307861328,-3.7864074707 c -6.26933288574,0.046875 -9.61039733887,3.71441650391 -9.61039733887,3.71441650391 c 0.0,0.0 9.61378479004,11.913482666 9.61378479004,11.913482666 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0169982910156,18.4394989014 c 0.0,0.0 9.55569458008,-11.8414916992 9.55569458008,-11.8414916992 c 0.0,0.0 -3.32373046875,-3.83329772949 -9.59307861328,-3.7864074707 c -6.26933288574,0.046875 -9.61039733887,3.71441650391 -9.61039733887,3.71441650391 c 0.0,0.0 9.61378479004,11.913482666 9.61378479004,11.913482666 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueTo="M 0.0169982910156,18.4394989014 c 0.0,0.0 9.55569458008,-11.8414916992 9.55569458008,-11.8414916992 c 0.0,0.0 -3.32373046875,-3.83329772949 -9.59307861328,-3.7864074707 c -6.26933288574,0.046875 -9.61039733887,3.71441650391 -9.61039733887,3.71441650391 c 0.0,0.0 9.61378479004,11.913482666 9.61378479004,11.913482666 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0169982910156,18.4394989014 c 0.0,0.0 9.55569458008,-11.8414916992 9.55569458008,-11.8414916992 c 0.0,0.0 -3.32373046875,-3.83329772949 -9.59307861328,-3.7864074707 c -6.26933288574,0.046875 -9.61039733887,3.71441650391 -9.61039733887,3.71441650391 c 0.0,0.0 9.61378479004,11.913482666 9.61378479004,11.913482666 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueTo="M 0.0169982910156,18.4394989014 c 0.0,0.0 16.9385528564,-20.9904174805 16.9385528564,-20.9904174805 c -0.486480712891,-0.364868164062 -6.84008789062,-6.15798950195 -16.9654541016,-6.13645935059 c -10.1253662109,0.0215454101562 -16.4858551025,5.73852539062 -16.9723510742,6.10339355469 c 0.0,0.0 16.9652557373,21.0234832764 16.9652557373,21.0234832764 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="316"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0169982910156,18.4394989014 c 0.0,0.0 16.9385528564,-20.9904174805 16.9385528564,-20.9904174805 c -0.486480712891,-0.364868164062 -6.84008789062,-6.15798950195 -16.9654541016,-6.13645935059 c -10.1253662109,0.0215454101562 -16.4858551025,5.73852539062 -16.9723510742,6.10339355469 c 0.0,0.0 16.9652557373,21.0234832764 16.9652557373,21.0234832764 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueTo="M 0.0169982910156,18.4394989014 c 0.0,0.0 16.9385528564,-20.9904174805 16.9385528564,-20.9904174805 c -0.486480712891,-0.364868164062 -6.84008789062,-6.15798950195 -16.9654541016,-6.13645935059 c -10.1253662109,0.0215454101562 -16.4858551025,5.73852539062 -16.9723510742,6.10339355469 c 0.0,0.0 16.9652557373,21.0234832764 16.9652557373,21.0234832764 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0169982910156,18.4394989014 c 0.0,0.0 16.9385528564,-20.9904174805 16.9385528564,-20.9904174805 c -0.486480712891,-0.364868164062 -6.84008789062,-6.15798950195 -16.9654541016,-6.13645935059 c -10.1253662109,0.0215454101562 -16.4858551025,5.73852539062 -16.9723510742,6.10339355469 c 0.0,0.0 16.9652557373,21.0234832764 16.9652557373,21.0234832764 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueTo="M 0.0169982910156,18.4394989014 c 0.0,0.0 23.2140045166,-28.766998291 23.2140045166,-28.766998291 c -0.900009155273,-0.675003051758 -9.82899475098,-8.13400268555 -23.2320098877,-8.13400268555 c -13.4029998779,0.0 -22.3299865723,7.45899963379 -23.2299957275,8.13400268555 c 0.0,0.0 23.2140045166,28.766998291 23.2140045166,28.766998291 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:valueType="pathType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+ <set
+ android:ordering="sequentially" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.0"
+ android:valueTo="0.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ <objectAnimator
+ android:duration="16"
+ android:propertyName="fillAlpha"
+ android:valueFrom="0.0"
+ android:valueTo="1.0"
+ android:valueType="floatType"
+ android:interpolator="@android:interpolator/linear" />
+ </set>
+</set>
diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml b/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
new file mode 100644
index 0000000..76026af
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_bluetooth_transient.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="ic_bluetooth_transient"
+ android:width="48dp"
+ android:viewportWidth="48"
+ android:height="48dp"
+ android:viewportHeight="48" >
+ <group
+ android:name="ic_signal_wifi_4_bar_48px_outlines_"
+ android:translateX="21.9995"
+ android:translateY="25.73401" >
+ <group
+ android:name="ic_signal_wifi_4_bar_48px_outlines__pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <group
+ android:name="bluetooth"
+ android:translateX="22.08789"
+ android:translateY="18.72031" >
+ <group
+ android:name="bluetooth_pivot"
+ android:translateX="-22.08789"
+ android:translateY="-18.72031" >
+ <group
+ android:name="cross"
+ android:rotation="-1.88453" >
+ <path
+ android:name="extented_cross"
+ android:pathData="M 10.6188659668,6.56344604492 c 0.0,0.0 21.7386016846,23.1297454834 21.7386016846,23.1297454834"
+ android:strokeColor="#FFFFFFFF"
+ android:strokeWidth="4" />
+ </group>
+ <group
+ android:name="bluetooth_0"
+ android:translateX="23.38789"
+ android:translateY="18.72031" >
+ <path
+ android:name="b_shape_merged"
+ android:pathData="M 11.3999938965,-8.60000610352 c 0.0,0.0 -11.3999938965,-11.3999938965 -11.3999938965,-11.3999938965 c 0.0,0.0 -2.0,0.0 -2.0,0.0 c 0.0,0.0 0.0,15.1999969482 0.0,15.1999969482 c 0.0,0.0 -9.19999694824,-9.19999694824 -9.19999694824,-9.19999694824 c 0.0,0.0 -2.80000305176,2.80000305176 -2.80000305176,2.80000305176 c 0.0,0.0 11.1999969482,11.1999969482 11.1999969482,11.1999969482 c 0.0,0.0 -11.1999969482,11.1999969482 -11.1999969482,11.1999969482 c 0.0,0.0 2.80000305176,2.80000305176 2.80000305176,2.80000305176 c 0.0,0.0 9.19999694824,-9.19999694824 9.19999694824,-9.19999694824 c 0.0,0.0 0.0,15.1999969482 0.0,15.1999969482 c 0.0,0.0 2.0,0.0 2.0,0.0 c 0.0,0.0 11.3999938965,-11.3999938965 11.3999938965,-11.3999938965 c 0.0,0.0 -8.59999084473,-8.60000610352 -8.59999084473,-8.60000610352 c 0.0,0.0 8.59999084473,-8.60000610352 8.59999084473,-8.60000610352 Z M 2.0,-12.3000030518 c 0.0,0.0 3.80000305176,3.80000305176 3.80000305176,3.80000305176 c 0.0,0.0 -3.80000305176,3.69999694824 -3.80000305176,3.69999694824 c 0.0,0.0 0.0,-7.5 0.0,-7.5 Z M 5.80000305176,8.60000610352 c 0.0,0.0 -3.80000305176,3.69999694824 -3.80000305176,3.69999694824 c 0.0,0.0 0.0,-7.5 0.0,-7.5 c 0.0,0.0 3.80000305176,3.80000305176 3.80000305176,3.80000305176 Z"
+ android:fillColor="#FFFFFFFF" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="dot_left"
+ android:translateX="20.16992"
+ android:translateY="18.64258" >
+ <group
+ android:name="dot_left_pivot"
+ android:translateX="-20.16992"
+ android:translateY="-18.64258" >
+ <group
+ android:name="group_1"
+ android:translateX="9.38789"
+ android:translateY="18.72031" >
+ <group
+ android:name="group_1_pivot"
+ android:translateX="-9.38789"
+ android:translateY="-18.72031" >
+ <path
+ android:name="dot_left_0"
+ android:pathData="M 13.3878936768,18.7203063965 c 0.0,0.0 -4.0,-4.0 -4.0,-4.0 c 0.0,0.0 -4.0,4.0 -4.0,4.0 c 0.0,0.0 4.0,4.0 4.0,4.0 c 0.0,0.0 4.0,-4.0 4.0,-4.0 Z"
+ android:fillColor="#FFFFFFFF" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="dot_right"
+ android:translateX="26.16094"
+ android:translateY="18.60898" >
+ <group
+ android:name="dot_right_pivot"
+ android:translateX="-26.16094"
+ android:translateY="-18.60898" >
+ <group
+ android:name="group_2"
+ android:translateX="37.38789"
+ android:translateY="18.72031"
+ android:scaleX="0"
+ android:scaleY="0" >
+ <group
+ android:name="group_1_pivot_0"
+ android:translateX="-37.38789"
+ android:translateY="-18.72031" >
+ <path
+ android:name="dot_right_0"
+ android:pathData="M 37.3878936768,14.7203063965 c 0.0,0.0 -4.0,4.0 -4.0,4.0 c 0.0,0.0 4.0,4.0 4.0,4.0 c 0.0,0.0 4.0,-4.0 4.0,-4.0 c 0.0,0.0 -4.0,-4.0 -4.0,-4.0 Z"
+ android:fillColor="#FFFFFFFF" />
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml b/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
new file mode 100644
index 0000000..f7eb23c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_bluetooth_transient_animation.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_bluetooth_transient" >
+ <target
+ android:name="group_1"
+ android:animation="@anim/ic_bluetooth_transient_group_1_animation" />
+ <target
+ android:name="group_2"
+ android:animation="@anim/ic_bluetooth_transient_group_2_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_wifi_transient.xml b/packages/SystemUI/res/drawable/ic_signal_wifi_transient.xml
new file mode 100644
index 0000000..880e1bb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_wifi_transient.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:name="ic_signal_wifi_transient"
+ android:width="48dp"
+ android:viewportWidth="48"
+ android:height="48dp"
+ android:viewportHeight="48" >
+ <group
+ android:name="ic_signal_wifi_4_bar_48px_2"
+ android:translateX="24.25"
+ android:translateY="25.73401" >
+ <group
+ android:name="ic_signal_wifi_4_bar_48px_2_pivot"
+ android:translateX="-23.21545"
+ android:translateY="-18.86649" >
+ <group
+ android:name="wifi_2"
+ android:translateX="23.481"
+ android:translateY="18.71151" >
+ <path
+ android:name="wifi"
+ android:pathData="M 0.0169982910156,18.4394989014 c 0.0,0.0 23.2140045166,-28.766998291 23.2140045166,-28.766998291 c -0.900009155273,-0.675003051758 -9.82899475098,-8.13400268555 -23.2320098877,-8.13400268555 c -13.4029998779,0.0 -22.3299865723,7.45899963379 -23.2299957275,8.13400268555 c 0.0,0.0 23.2140045166,28.766998291 23.2140045166,28.766998291 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0.5" />
+ </group>
+ <group
+ android:name="wifi_0"
+ android:translateX="23.481"
+ android:translateY="18.71151" >
+ <path
+ android:name="wifi_1"
+ android:pathData="M 0.0169982910156,18.4394989014 c 0.0,0.0 23.2140045166,-28.766998291 23.2140045166,-28.766998291 c -0.900009155273,-0.675003051758 -9.82899475098,-8.13400268555 -23.2320098877,-8.13400268555 c -13.4029998779,0.0 -22.3299865723,7.45899963379 -23.2299957275,8.13400268555 c 0.0,0.0 23.2140045166,28.766998291 23.2140045166,28.766998291 c 0.0,0.0 0.0159912109375,0.0220031738281 0.0159912109375,0.0220031738281 c 0.0,0.0 0.00100708007812,-0.00100708007812 0.00100708007812,-0.0010070800781 c 0.0,0.0 0.00100708007812,0.00100708007812 0.00100708007812,0.0010070800781 c 0.0,0.0 0.0159912109375,-0.0220031738281 0.0159912109375,-0.0220031738281 Z"
+ android:fillColor="#FFFFFFFF"
+ android:fillAlpha="0" />
+ </group>
+ </group>
+ </group>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_signal_wifi_transient_animation.xml b/packages/SystemUI/res/drawable/ic_signal_wifi_transient_animation.xml
new file mode 100644
index 0000000..9f5aaeb
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_signal_wifi_transient_animation.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:drawable="@drawable/ic_signal_wifi_transient" >
+ <target
+ android:name="wifi_1"
+ android:animation="@anim/ic_signal_wifi_transient_wifi_1_animation" />
+</animated-vector>
diff --git a/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml b/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml
new file mode 100644
index 0000000..c421f9e
--- /dev/null
+++ b/packages/SystemUI/res/interpolator/ic_bluetooth_transient_animation_interpolator_0.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<pathInterpolator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:pathData="M 0.0,0.0 c 0.16666666667,0.0 0.83333333333,1.0 1.0,1.0" />
diff --git a/packages/SystemUI/res/layout/menu_ime.xml b/packages/SystemUI/res/layout/menu_ime.xml
index 6bd79a4..8078c41 100644
--- a/packages/SystemUI/res/layout/menu_ime.xml
+++ b/packages/SystemUI/res/layout/menu_ime.xml
@@ -27,6 +27,7 @@
android:layout_marginEnd="2dp"
android:scaleType="centerInside"
systemui:keyCode="82"
+ systemui:playSound="false"
android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
/>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index f405943..008fcf0 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -20,6 +20,8 @@
<attr name="keyCode" format="integer" />
<!-- does this button generate longpress / repeat events? -->
<attr name="keyRepeat" format="boolean" />
+ <!-- Should this button play sound effects, default true -->
+ <attr name="playSound" format="boolean" />
<attr name="android:contentDescription" />
</declare-styleable>
<declare-styleable name="ToggleSliderView">
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 8c1062b..d57e88c 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -98,6 +98,8 @@
addView(mBatteryIconView, mlp);
updateShowPercent();
+ // Init to not dark at all.
+ onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
}
public void setForceShowPercent(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index 17228b9..bcf1957 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -417,17 +417,17 @@
}
private void updateDismissFraction(float fraction) {
- setDecorViewVisibility(true);
int alpha;
if (mMenuVisible) {
- mMenuContainer.setAlpha(1-fraction);
+ mMenuContainer.setAlpha(1 - fraction);
final float interpolatedAlpha =
MENU_BACKGROUND_ALPHA * (1.0f - fraction) + DISMISS_BACKGROUND_ALPHA * fraction;
- alpha = (int) (interpolatedAlpha*255);
+ alpha = (int) (interpolatedAlpha * 255);
} else {
- alpha = (int) (fraction*DISMISS_BACKGROUND_ALPHA*255);
+ alpha = (int) (fraction * DISMISS_BACKGROUND_ALPHA * 255);
}
mBackgroundDrawable.setAlpha(alpha);
+ setDecorViewVisibility(alpha > 0);
}
private void notifyRegisterInputConsumer() {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index dd8cd2b..ad290c3 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -113,6 +113,7 @@
private IWindowManager mWindowManager;
private MediaSessionManager mMediaSessionManager;
private int mState = STATE_NO_PIP;
+ private int mResumeResizePinnedStackRunnable = STATE_NO_PIP;
private final Handler mHandler = new Handler();
private List<Listener> mListeners = new ArrayList<>();
private List<MediaListener> mMediaListeners = new ArrayList<>();
@@ -133,7 +134,7 @@
private final Runnable mResizePinnedStackRunnable = new Runnable() {
@Override
public void run() {
- resizePinnedStack(mState);
+ resizePinnedStack(mResumeResizePinnedStackRunnable);
}
};
private final Runnable mClosePipRunnable = new Runnable() {
@@ -364,16 +365,17 @@
void resizePinnedStack(int state) {
if (DEBUG) Log.d(TAG, "resizePinnedStack() state=" + state);
boolean wasStateNoPip = (mState == STATE_NO_PIP);
- mState = state;
+ mResumeResizePinnedStackRunnable = state;
for (int i = mListeners.size() - 1; i >= 0; --i) {
mListeners.get(i).onPipResizeAboutToStart();
}
if (mSuspendPipResizingReason != 0) {
- if (DEBUG) Log.d(TAG,
- "resizePinnedStack() deferring mSuspendPipResizingReason=" +
- mSuspendPipResizingReason);
+ if (DEBUG) Log.d(TAG, "resizePinnedStack() deferring"
+ + " mSuspendPipResizingReason=" + mSuspendPipResizingReason
+ + " mResumeResizePinnedStackRunnable=" + mResumeResizePinnedStackRunnable);
return;
}
+ mState = state;
switch (mState) {
case STATE_NO_PIP:
mCurrentPipBounds = null;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 4e4de15..75e9d5a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -114,7 +114,8 @@
protected void handleUpdateState(BooleanState state, Object arg) {
final boolean enabled = mController.isBluetoothEnabled();
final boolean connected = mController.isBluetoothConnected();
- final boolean connecting = mController.isBluetoothConnecting();
+ state.isTransient = mController.isBluetoothConnecting()
+ || mController.getBluetoothState() == BluetoothAdapter.STATE_TURNING_ON;
state.dualTarget = true;
state.value = enabled;
if (enabled) {
@@ -124,8 +125,8 @@
state.label = mController.getLastDeviceName();
state.contentDescription = mContext.getString(
R.string.accessibility_bluetooth_name, state.label);
- } else if (connecting) {
- state.icon = ResourceIcon.get(R.drawable.ic_qs_bluetooth_connecting);
+ } else if (state.isTransient) {
+ state.icon = ResourceIcon.get(R.drawable.ic_bluetooth_transient_animation);
state.contentDescription = mContext.getString(
R.string.accessibility_quick_settings_bluetooth_connecting);
state.label = mContext.getString(R.string.quick_settings_bluetooth_label);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 22b6a63..2725a32 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -20,22 +20,29 @@
import android.content.Intent;
import android.provider.Settings;
import android.service.quicksettings.Tile;
+import android.support.v7.app.MediaRouteChooserDialog;
+import android.support.v7.app.MediaRouteControllerDialog;
+import android.support.v7.media.MediaControlIntent;
+import android.support.v7.media.MediaRouteSelector;
import android.util.Log;
+import android.view.ContextThemeWrapper;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.widget.Button;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.R.style;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
+import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSDetailItems;
import com.android.systemui.qs.QSDetailItems.Item;
import com.android.systemui.qs.QSHost;
-import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
@@ -109,7 +116,6 @@
if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
showDetail(true);
- mHost.openPanels();
});
return;
}
@@ -117,6 +123,29 @@
}
@Override
+ public void showDetail(boolean show) {
+ mUiHandler.post(() -> {
+ Context context = new ContextThemeWrapper(mContext,
+ R.style.Theme_AppCompat_Light_Dialog_Alert);
+ if (mState.value) {
+ MediaRouteControllerDialog dialog = new MediaRouteControllerDialog(context);
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+ dialog.show();
+ } else {
+ // Instead of showing detail, show standard media routing UI.
+ MediaRouteChooserDialog dialog = new MediaRouteChooserDialog(context);
+ MediaRouteSelector selector = new MediaRouteSelector.Builder()
+ .addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO)
+ .build();
+ dialog.setRouteSelector(selector);
+ dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
+ dialog.show();
+ }
+ mHost.collapsePanels();
+ });
+ }
+
+ @Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.quick_settings_cast_title);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index 04be7de..9b3ee30 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -180,7 +180,7 @@
private final CallbackInfo mInfo = new CallbackInfo();
@Override
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
- boolean activityIn, boolean activityOut, String description) {
+ boolean activityIn, boolean activityOut, String description, boolean isTransient) {
mInfo.wifiEnabled = enabled;
refreshState(mInfo);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 79b4c4a..7d2d210 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -157,7 +157,10 @@
state.activityOut = cb.enabled && cb.activityOut;
final StringBuffer minimalContentDescription = new StringBuffer();
final Resources r = mContext.getResources();
- if (!state.value) {
+ if (cb.isTransient) {
+ state.icon = ResourceIcon.get(R.drawable.ic_signal_wifi_transient_animation);
+ state.label = r.getString(R.string.quick_settings_wifi_label);
+ } else if (!state.value) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disabled);
state.label = r.getString(R.string.quick_settings_wifi_label);
} else if (wifiConnected) {
@@ -182,7 +185,7 @@
state.dualLabelContentDescription = r.getString(
R.string.accessibility_quick_settings_open_settings, getTileLabel());
state.expandedAccessibilityClassName = Switch.class.getName();
- state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+ state.state = state.value || cb.isTransient ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
}
@Override
@@ -226,6 +229,7 @@
boolean activityIn;
boolean activityOut;
String wifiSignalContentDescription;
+ boolean isTransient;
@Override
public String toString() {
@@ -237,6 +241,7 @@
.append(",activityIn=").append(activityIn)
.append(",activityOut=").append(activityOut)
.append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
+ .append(",isTransient=").append(isTransient)
.append(']').toString();
}
}
@@ -246,7 +251,7 @@
@Override
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
- boolean activityIn, boolean activityOut, String description) {
+ boolean activityIn, boolean activityOut, String description, boolean isTransient) {
if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled);
mInfo.enabled = enabled;
mInfo.connected = qsIcon.visible;
@@ -255,6 +260,7 @@
mInfo.activityIn = activityIn;
mInfo.activityOut = activityOut;
mInfo.wifiSignalContentDescription = qsIcon.contentDescription;
+ mInfo.isTransient = isTransient;
refreshState(mInfo);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 67be99e5..88711fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -266,7 +266,7 @@
@Override
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
- boolean activityIn, boolean activityOut, String description) {
+ boolean activityIn, boolean activityOut, String description, boolean isTransient) {
mWifiVisible = statusIcon.visible && !mBlockWifi;
mWifiStrengthId = statusIcon.icon;
mWifiBadgeId = statusIcon.iconOverlay;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index c339da7..a3ef91d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -15,6 +15,7 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
import android.util.ArraySet;
import android.view.Gravity;
@@ -22,6 +23,7 @@
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.Dependency;
@@ -71,13 +73,18 @@
}
@Override
- protected void onIconAdded(int index, String slot, boolean blocked, StatusBarIcon icon) {
- StatusBarIconView view = new StatusBarIconView(mContext, slot, null, blocked);
+ protected void onIconAdded(int index, String slot, boolean blocked,
+ StatusBarIcon icon) {
+ StatusBarIconView v = addIcon(index, slot, blocked, icon);
+ mDarkIconDispatcher.addDarkReceiver(v);
+ }
+
+ @Override
+ protected LayoutParams onCreateLayoutParams() {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
- mGroup.addView(view, index, lp);
- mDarkIconDispatcher.addDarkReceiver(view);
+ return lp;
}
@Override
@@ -116,11 +123,26 @@
com.android.internal.R.dimen.status_bar_icon_size);
}
- protected void onIconAdded(int index, String slot, boolean blocked, StatusBarIcon icon) {
- StatusBarIconView view = new StatusBarIconView(mContext, slot, null, blocked);
+ protected void onIconAdded(int index, String slot, boolean blocked,
+ StatusBarIcon icon) {
+ addIcon(index, slot, blocked, icon);
+ }
+
+ protected StatusBarIconView addIcon(int index, String slot, boolean blocked,
+ StatusBarIcon icon) {
+ StatusBarIconView view = onCreateStatusBarIconView(slot, blocked);
view.set(icon);
- mGroup.addView(view, index, new LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
+ mGroup.addView(view, index, onCreateLayoutParams());
+ return view;
+ }
+
+ @VisibleForTesting
+ protected StatusBarIconView onCreateStatusBarIconView(String slot, boolean blocked) {
+ return new StatusBarIconView(mContext, slot, null, blocked);
+ }
+
+ protected LinearLayout.LayoutParams onCreateLayoutParams() {
+ return new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
}
protected void destroy() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
index 5ab99e9..a456786 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
@@ -109,13 +109,13 @@
@Override
public void setWifiIndicators(final boolean enabled, final IconState statusIcon,
final IconState qsIcon, final boolean activityIn, final boolean activityOut,
- final String description) {
+ final String description, boolean isTransient) {
post(new Runnable() {
@Override
public void run() {
for (SignalCallback callback : mSignalCallbacks) {
callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut,
- description);
+ description, isTransient);
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 882902e..b5d22b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -49,6 +49,7 @@
public class KeyButtonView extends ImageView implements ButtonInterface {
+ private final boolean mPlaySounds;
private int mContentDescriptionRes;
private long mDownTime;
private int mCode;
@@ -90,6 +91,7 @@
mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
+ mPlaySounds = a.getBoolean(R.styleable.KeyButtonView_playSound, true);
TypedValue value = new TypedValue();
if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) {
@@ -241,8 +243,9 @@
}
public void playSoundEffect(int soundConstant) {
+ if (!mPlaySounds) return;
mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
- };
+ }
public void sendEvent(int action, int flags) {
sendEvent(action, flags, SystemClock.uptimeMillis());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 5657560..c02ce0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -19,12 +19,10 @@
import android.content.Context;
import android.content.Intent;
import android.telephony.SubscriptionInfo;
-import android.view.View;
import com.android.settingslib.net.DataUsageController;
import com.android.settingslib.wifi.AccessPoint;
import com.android.systemui.DemoMode;
-import com.android.systemui.Dumpable;
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
import java.util.List;
@@ -48,7 +46,7 @@
public interface SignalCallback {
default void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
- boolean activityIn, boolean activityOut, String description) {}
+ boolean activityIn, boolean activityOut, String description, boolean isTransient) {}
default void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 12b7098..2104cb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -150,7 +150,7 @@
Utils.getWifiBadgeResource(mCurrentState.badgeEnum), contentDescription);
callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
- wifiDesc);
+ wifiDesc, mCurrentState.isTransient);
}
@Override
@@ -170,6 +170,9 @@
mWifiTracker.handleBroadcast(intent);
updateScoreCacheIfNecessary(previousNetworkKey);
+ mCurrentState.isTransient = mWifiTracker.state == WifiManager.WIFI_STATE_ENABLING
+ || mWifiTracker.state == WifiManager.WIFI_AP_STATE_DISABLING
+ || mWifiTracker.connecting;
mCurrentState.enabled = mWifiTracker.enabled;
mCurrentState.connected = mWifiTracker.connected;
mCurrentState.ssid = mWifiTracker.ssid;
@@ -252,6 +255,7 @@
static class WifiState extends SignalController.State {
String ssid;
int badgeEnum;
+ boolean isTransient;
@Override
public void copyFrom(State s) {
@@ -259,19 +263,23 @@
WifiState state = (WifiState) s;
ssid = state.ssid;
badgeEnum = state.badgeEnum;
+ isTransient = state.isTransient;
}
@Override
protected void toString(StringBuilder builder) {
super.toString(builder);
builder.append(',').append("ssid=").append(ssid);
+ builder.append(',').append("badgeEnum=").append(badgeEnum);
+ builder.append(',').append("isTransient=").append(isTransient);
}
@Override
public boolean equals(Object o) {
return super.equals(o)
&& Objects.equals(((WifiState) o).ssid, ssid)
- && (((WifiState) o).badgeEnum == badgeEnum);
+ && (((WifiState) o).badgeEnum == badgeEnum)
+ && (((WifiState) o).isTransient == isTransient);
}
}
}
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index ddd8d7b..8eedf31 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -41,6 +41,7 @@
android-support-v7-recyclerview \
android-support-v7-preference \
android-support-v7-appcompat \
+ android-support-v7-mediarouter \
android-support-v14-preference \
android-support-v17-leanback
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
new file mode 100644
index 0000000..ecae39a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
+import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
+import com.android.systemui.statusbar.policy.DarkIconDispatcher;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper
+public class StatusBarIconControllerTest extends LeakCheckedTest {
+
+ @Before
+ public void setup() {
+ injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+ mDependency.injectMockDependency(DarkIconDispatcher.class);
+ }
+
+ @Test
+ public void testSetCalledOnAdd_IconManager() {
+ LinearLayout layout = new LinearLayout(mContext);
+ TestIconManager manager = new TestIconManager(layout);
+ StatusBarIcon icon = mock(StatusBarIcon.class);
+
+ manager.onIconAdded(0, "test_slot", false, icon);
+ verify(manager.mMock).set(eq(icon));
+ }
+
+ @Test
+ public void testSetCalledOnAdd_DarkIconManager() {
+ LinearLayout layout = new LinearLayout(mContext);
+ TestDarkIconManager manager = new TestDarkIconManager(layout);
+ StatusBarIcon icon = mock(StatusBarIcon.class);
+
+ manager.onIconAdded(0, "test_slot", false, icon);
+ verify(manager.mMock).set(eq(icon));
+ }
+
+ private static class TestDarkIconManager extends DarkIconManager {
+
+ private final StatusBarIconView mMock;
+
+ public TestDarkIconManager(LinearLayout group) {
+ super(group);
+ mMock = mock(StatusBarIconView.class);
+ }
+
+ @Override
+ protected StatusBarIconView onCreateStatusBarIconView(String slot, boolean blocked) {
+ return mMock;
+ }
+ }
+
+ private static class TestIconManager extends IconManager {
+
+ private final StatusBarIconView mMock;
+
+ public TestIconManager(ViewGroup group) {
+ super(group);
+ mMock = mock(StatusBarIconView.class);
+ }
+
+ @Override
+ protected StatusBarIconView onCreateStatusBarIconView(String slot, boolean blocked) {
+ return mMock;
+ }
+ }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index b544d9d..3ed1681 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -79,7 +79,7 @@
boolean in = true;
boolean out = true;
String description = "Test";
- mHandler.setWifiIndicators(enabled, status, qs, in, out, description);
+ mHandler.setWifiIndicators(enabled, status, qs, in, out, description, true);
waitForCallbacks();
ArgumentCaptor<Boolean> enableArg = ArgumentCaptor.forClass(Boolean.class);
@@ -88,15 +88,17 @@
ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
+ ArgumentCaptor<Boolean> isTransient = ArgumentCaptor.forClass(Boolean.class);
Mockito.verify(mSignalCallback).setWifiIndicators(enableArg.capture(),
statusArg.capture(), qsArg.capture(), inArg.capture(), outArg.capture(),
- descArg.capture());
+ descArg.capture(), isTransient.capture());
assertEquals(enabled, (boolean) enableArg.getValue());
assertEquals(status, statusArg.getValue());
assertEquals(qs, qsArg.getValue());
assertEquals(in, (boolean) inArg.getValue());
assertEquals(out, (boolean) outArg.getValue());
assertEquals(description, descArg.getValue());
+ assertTrue(isTransient.getValue());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index efa232b..483a837 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -122,7 +122,7 @@
ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
anyBoolean(), iconArg.capture(), any(), anyBoolean(), anyBoolean(),
- any());
+ any(), anyBoolean());
IconState iconState = iconArg.getValue();
assertEquals("Badged Wifi Resource is set",
@@ -269,7 +269,7 @@
ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
- anyBoolean(), any(), any(), inArg.capture(), outArg.capture(), any());
+ anyBoolean(), any(), any(), inArg.capture(), outArg.capture(), any(), anyBoolean());
assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue());
assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue());
}
@@ -282,7 +282,7 @@
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
enabledArg.capture(), any(), iconArg.capture(), anyBoolean(),
- anyBoolean(), descArg.capture());
+ anyBoolean(), descArg.capture(), anyBoolean());
IconState iconState = iconArg.getValue();
assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
assertEquals("WiFi connected, in quick settings", connected, iconState.visible);
@@ -295,7 +295,7 @@
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
anyBoolean(), iconArg.capture(), any(), anyBoolean(), anyBoolean(),
- any());
+ any(), anyBoolean());
IconState iconState = iconArg.getValue();
assertEquals("WiFi visible, in status bar", visible, iconState.visible);
assertEquals("WiFi signal, in status bar", icon, iconState.icon);
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index da441f5..78bc01d 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3188,21 +3188,21 @@
// ACTION: Logged when a provisioning session has completed
PROVISIONING_SESSION_COMPLETED = 735;
- // ACTION: An app requested the permission READ_PHONE_NUMBER
+ // ACTION: An app requested the permission READ_PHONE_NUMBERS
// PACKAGE: The package name of the app requesting the permission
- ACTION_PERMISSION_REQUEST_READ_PHONE_NUMBER = 736;
+ ACTION_PERMISSION_REQUEST_READ_PHONE_NUMBERS = 736;
- // ACTION: An app was granted the permission READ_PHONE_NUMBER
+ // ACTION: An app was granted the permission READ_PHONE_NUMBERS
// PACKAGE: The package name of the app that was granted the permission
- ACTION_PERMISSION_GRANT_READ_PHONE_NUMBER = 737;
+ ACTION_PERMISSION_GRANT_READ_PHONE_NUMBERS = 737;
- // ACTION: An app requested the permission READ_PHONE_NUMBER and the request was denied
+ // ACTION: An app requested the permission READ_PHONE_NUMBERS and the request was denied
// PACKAGE: The package name of the app requesting the permission
- ACTION_PERMISSION_DENIED_READ_PHONE_NUMBER = 738;
+ ACTION_PERMISSION_DENIED_READ_PHONE_NUMBERS = 738;
- // ACTION: The permission READ_PHONE_NUMBER was revoked for an app
+ // ACTION: The permission READ_PHONE_NUMBERS was revoked for an app
// PACKAGE: The package name of the app the permission was revoked for
- ACTION_PERMISSION_REVOKE_READ_PHONE_NUMBER = 739;
+ ACTION_PERMISSION_REVOKE_READ_PHONE_NUMBERS = 739;
// ACTION: QS Brightness Slider (with auto brightness disabled, and VR enabled)
// SUBTYPE: slider value
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 6b917b5..f6d91f4 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -153,6 +153,18 @@
// Package: android
NOTE_SSL_CERT_INFO = 33;
+ // Warn the user they are approaching their data limit.
+ // Package: android
+ NOTE_NET_WARNING = 34;
+
+ // Warn the user they have reached their data limit.
+ // Package: android
+ NOTE_NET_LIMIT = 35;
+
+ // Warn the user they have exceeded their data limit.
+ // Package: android
+ NOTE_NET_LIMIT_SNOOZED = 36;
+
// ADD_NEW_IDS_ABOVE_THIS_LINE
// Legacy IDs with arbitrary values appear below
// Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index acaae7b..087c248 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -104,6 +104,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IntPair;
import com.android.server.LocalServices;
import com.android.server.policy.AccessibilityShortcutController;
@@ -2360,7 +2361,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (mLock) {
pw.println("ACCESSIBILITY MANAGER (dumpsys accessibility)");
pw.println();
@@ -3658,7 +3659,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- mSecurityPolicy.enforceCallingPermission(Manifest.permission.DUMP, FUNCTION_DUMP);
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (mLock) {
pw.append("Service[label=" + mAccessibilityServiceInfo.getResolveInfo()
.loadLabel(mContext.getPackageManager()));
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 8aa37ef..0482e73 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -97,6 +97,7 @@
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.widget.IRemoteViewsAdapterConnection;
import com.android.internal.widget.IRemoteViewsFactory;
@@ -714,10 +715,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
- "Permission Denial: can't dump from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
if (args.length > 0 && "--proto".equals(args[0])) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 72d37ad..be14440 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -60,6 +60,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -418,13 +419,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingPermission(
- Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump autofill from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.print("Disabled users: "); pw.println(mDisabledUsers);
final int size = mServicesCache.size();
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 57d3570..413746f 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -117,6 +117,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.backup.IObbBackupService;
+import com.android.internal.util.DumpUtils;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.SystemConfig;
@@ -11138,7 +11139,7 @@
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
long identityToken = Binder.clearCallingIdentity();
try {
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index c40f2ca..a109e631 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -35,6 +35,8 @@
import android.os.UserHandle;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -372,7 +374,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
BackupManagerService svc = mService;
if (svc != null) {
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index c6af290..8b32c16 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -80,6 +80,7 @@
import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
import static android.app.AlarmManager.ELAPSED_REALTIME;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.LocalLog;
class AlarmManagerService extends SystemService {
@@ -1384,14 +1385,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump AlarmManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
dumpImpl(pw);
}
};
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index a5e357c..dcf6fd7 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -70,6 +70,7 @@
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
@@ -2028,13 +2029,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ApOps service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
if (args != null) {
for (int i=0; i<args.length; i++) {
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index fd44794..83bd9eb 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -24,6 +24,7 @@
import android.os.ShellCallback;
import android.os.ShellCommand;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.util.DumpUtils;
import com.android.server.am.BatteryStatsService;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
@@ -945,14 +946,7 @@
private final class BinderService extends Binder {
@Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump Battery service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
if (args.length > 0 && "--proto".equals(args[0])) {
dumpProto(fd);
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 58e8631..6c4895c 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -60,6 +60,7 @@
import android.provider.Settings.SettingNotFoundException;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
import com.android.server.pm.PackageManagerService;
import java.io.FileDescriptor;
@@ -2084,7 +2085,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
String errorMsg = null;
boolean protoOut = (args.length > 0) && args[0].startsWith("--proto");
diff --git a/services/core/java/com/android/server/CommonTimeManagementService.java b/services/core/java/com/android/server/CommonTimeManagementService.java
index 60b366a..07c8679 100644
--- a/services/core/java/com/android/server/CommonTimeManagementService.java
+++ b/services/core/java/com/android/server/CommonTimeManagementService.java
@@ -37,6 +37,7 @@
import android.os.SystemProperties;
import android.util.Log;
+import com.android.internal.util.DumpUtils;
import com.android.server.net.BaseNetworkObserver;
/**
@@ -177,13 +178,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println(String.format(
- "Permission Denial: can't dump CommonTimeManagement service from from " +
- "pid=%d, uid=%d", Binder.getCallingPid(), Binder.getCallingUid()));
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
if (!mDetectedAtStartup) {
pw.println("Native Common Time service was not detected at startup. " +
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d02b726..0e752ff 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -125,6 +125,7 @@
import com.android.internal.net.VpnInfo;
import com.android.internal.net.VpnProfile;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.WakeupMessage;
@@ -1927,14 +1928,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ConnectivityService " +
- "from from pid=" + Binder.getCallingPid() + ", uid=" +
- Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
if (argsContain(args, "--diag")) {
dumpNetworkDiagnostics(pw);
diff --git a/services/core/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java
index a478b2f..d8a2fe3 100644
--- a/services/core/java/com/android/server/CountryDetectorService.java
+++ b/services/core/java/com/android/server/CountryDetectorService.java
@@ -21,6 +21,7 @@
import java.util.HashMap;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.server.location.ComprehensiveCountryDetector;
import android.content.Context;
@@ -208,8 +209,7 @@
@SuppressWarnings("unused")
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
if (!DEBUG) return;
try {
final Printer p = new PrintWriterPrinter(fout);
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 26b15d8..8945952 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -81,6 +81,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.AtomicFile;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.server.am.BatteryStatsService;
@@ -2879,13 +2880,7 @@
}
void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump DeviceIdleController from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
if (args != null) {
int userId = UserHandle.USER_SYSTEM;
diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java
index 1bdff6b..800081e 100644
--- a/services/core/java/com/android/server/DiskStatsService.java
+++ b/services/core/java/com/android/server/DiskStatsService.java
@@ -30,6 +30,7 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.util.DumpUtils;
import com.android.server.storage.DiskStatsFileLogger;
import com.android.server.storage.DiskStatsLoggingService;
@@ -62,7 +63,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
// Run a quick-and-dirty performance test: write 512 bytes
byte[] junk = new byte[512];
diff --git a/services/core/java/com/android/server/DockObserver.java b/services/core/java/com/android/server/DockObserver.java
index 122074b..e5a7b4e 100644
--- a/services/core/java/com/android/server/DockObserver.java
+++ b/services/core/java/com/android/server/DockObserver.java
@@ -35,6 +35,8 @@
import android.util.Log;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
+
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileReader;
@@ -252,14 +254,7 @@
private final class BinderService extends Binder {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump dock observer service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index 040d22c..9d3d531 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -40,6 +40,7 @@
import libcore.io.IoUtils;
import com.android.internal.os.IDropBoxManagerService;
+import com.android.internal.util.DumpUtils;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -350,11 +351,7 @@
}
public synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: Can't dump DropBoxManagerService");
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
try {
init();
diff --git a/services/core/java/com/android/server/GraphicsStatsService.java b/services/core/java/com/android/server/GraphicsStatsService.java
index 19bedfb..d3f77b6 100644
--- a/services/core/java/com/android/server/GraphicsStatsService.java
+++ b/services/core/java/com/android/server/GraphicsStatsService.java
@@ -37,6 +37,8 @@
import android.view.IGraphicsStats;
import android.view.IGraphicsStatsCallback;
+import com.android.internal.util.DumpUtils;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -345,7 +347,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, fout)) return;
boolean dumpProto = false;
for (String str : args) {
if ("--proto".equals(str)) {
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index e619e8b..39bfeda 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -33,6 +33,7 @@
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
import com.android.internal.os.TransferPipe;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethod;
@@ -4378,14 +4379,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump InputMethodManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
IInputMethod method;
ClientState client;
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 979096e..f0720f3 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -26,6 +26,7 @@
import com.android.internal.location.ProviderRequest;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.server.location.ActivityRecognitionProxy;
import com.android.server.location.FlpHardwareProvider;
import com.android.server.location.FusedProxy;
@@ -3026,13 +3027,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump LocationManagerService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("Current Location Manager state:");
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 6f3ff10..e26630b 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -79,6 +79,7 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.widget.ICheckCredentialProgressCallback;
import com.android.internal.widget.ILockSettings;
import com.android.internal.widget.LockPatternUtils;
@@ -2178,14 +2179,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args){
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump LockSettingsService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (this) {
pw.println("Current lock settings service state:");
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 74328c0..ce4efd1 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -95,6 +95,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.net.NetworkStatsFactory;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.HexDump;
import com.android.internal.util.Preconditions;
import com.android.server.NativeDaemonConnector.Command;
@@ -2313,7 +2314,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("NetworkManagementService NativeDaemonConnector Log:");
mConnector.dump(fd, pw, args);
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 78c0fe6..a5debda 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -69,6 +69,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.TransferPipe;
+import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
import java.io.IOException;
@@ -925,7 +926,7 @@
@Override
protected void dump(final FileDescriptor fd, final PrintWriter writer, final String[] args) {
- mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final long token = Binder.clearCallingIdentity();
try {
NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer();
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index b64c65d..ebcda44 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -40,6 +40,7 @@
import android.util.TrustedTime;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -323,15 +324,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump NetworkTimeUpdateService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " without permission "
- + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.print("PollingIntervalMs: ");
TimeUtils.formatDuration(mPollingIntervalMs, pw);
pw.print("\nPollingIntervalShorterMs: ");
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index a44b065..8ae95d5 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -41,6 +41,7 @@
import java.util.concurrent.CountDownLatch;
import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
@@ -811,13 +812,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ServiceDiscoverService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
for (ClientInfo client : mClients.values()) {
pw.println("Client Info");
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index fa5a52c..a94bf79 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -37,6 +37,7 @@
import com.android.internal.app.ResolverActivity;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import dalvik.system.DexFile;
import dalvik.system.VMRuntime;
@@ -333,7 +334,7 @@
private final class BinderService extends Binder {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("Pinned Files:");
synchronized(this) {
for (int i = 0; i < mPinnedFiles.size(); i++) {
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index cecd7e5..3b36c3c 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -18,14 +18,13 @@
import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.UserInfo;
import android.os.Build;
+import android.os.Environment;
import android.os.FileUtils;
import android.os.RecoverySystem;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.util.ExceptionUtils;
@@ -70,7 +69,7 @@
private static boolean isDisabled() {
// Check if we're explicitly enabled for testing
- if (SystemProperties.getBoolean(PROP_ENABLE_RESCUE, true)) {
+ if (SystemProperties.getBoolean(PROP_ENABLE_RESCUE, false)) {
return false;
}
@@ -203,7 +202,7 @@
} catch (Throwable t) {
res = new RuntimeException("Failed to reset global settings", t);
}
- for (int userId : getAllUserIds(context)) {
+ for (int userId : getAllUserIds()) {
try {
Settings.Secure.resetToDefaultsAsUser(resolver, null, mode, userId);
} catch (Throwable t) {
@@ -314,13 +313,16 @@
@Override public void setStart(long start) { this.start = start; }
}
- private static int[] getAllUserIds(Context context) {
+ private static int[] getAllUserIds() {
int[] userIds = { UserHandle.USER_SYSTEM };
try {
- final UserManager um = context.getSystemService(UserManager.class);
- for (UserInfo user : um.getUsers()) {
- if (user.id != UserHandle.USER_SYSTEM) {
- userIds = ArrayUtils.appendInt(userIds, user.id);
+ for (File file : FileUtils.listFilesOrEmpty(Environment.getDataSystemDeDirectory())) {
+ try {
+ final int userId = Integer.parseInt(file.getName());
+ if (userId != UserHandle.USER_SYSTEM) {
+ userIds = ArrayUtils.appendInt(userIds, userId);
+ }
+ } catch (NumberFormatException ignored) {
}
}
} catch (Throwable t) {
diff --git a/services/core/java/com/android/server/SamplingProfilerService.java b/services/core/java/com/android/server/SamplingProfilerService.java
index fbf1aa4..5f92695 100644
--- a/services/core/java/com/android/server/SamplingProfilerService.java
+++ b/services/core/java/com/android/server/SamplingProfilerService.java
@@ -27,6 +27,7 @@
import android.os.SystemProperties;
import android.provider.Settings;
import com.android.internal.os.SamplingProfilerIntegration;
+import com.android.internal.util.DumpUtils;
import java.io.File;
import java.io.FileDescriptor;
@@ -96,7 +97,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("SamplingProfilerService:");
pw.println("Watching directory: " + SNAPSHOT_DIR);
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index c68000a..d796098 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -102,6 +102,7 @@
import com.android.internal.os.SomeArgs;
import com.android.internal.os.Zygote;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
@@ -3911,7 +3912,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ", 160);
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 531df81..7c1a609 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -60,6 +60,7 @@
import com.android.internal.telephony.PhoneConstantConversions;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
import com.android.server.am.BatteryStatsService;
/**
@@ -1391,12 +1392,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump telephony.registry from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mRecords) {
final int recordCount = mRecords.size();
pw.println("last known state:");
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index feda273..9068745 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -25,6 +25,7 @@
import com.android.internal.textservice.ISpellCheckerSessionListener;
import com.android.internal.textservice.ITextServicesManager;
import com.android.internal.textservice.ITextServicesSessionListener;
+import com.android.internal.util.DumpUtils;
import org.xmlpull.v1.XmlPullParserException;
@@ -757,14 +758,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump TextServicesManagerService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized(mSpellCheckerMap) {
pw.println("Current Text Services Manager state:");
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 227e2a2..04421cc 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -60,6 +60,7 @@
import com.android.internal.app.DisableCarModeActivity;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.DumpUtils;
import com.android.server.power.ShutdownThread;
import com.android.server.twilight.TwilightListener;
import com.android.server.twilight.TwilightManager;
@@ -352,15 +353,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump uimode service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
dumpImpl(pw);
}
};
diff --git a/services/core/java/com/android/server/UpdateLockService.java b/services/core/java/com/android/server/UpdateLockService.java
index 7f33973..06f73e2 100644
--- a/services/core/java/com/android/server/UpdateLockService.java
+++ b/services/core/java/com/android/server/UpdateLockService.java
@@ -29,6 +29,8 @@
import android.os.UserHandle;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -112,14 +114,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump update lock service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
mLocks.dump(pw);
}
}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index c4676d1..678ae38 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -54,6 +54,7 @@
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IBatteryStats;
+import com.android.internal.util.DumpUtils;
import com.android.server.power.BatterySaverPolicy.ServiceType;
import java.io.FileDescriptor;
@@ -874,14 +875,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
- pw.println("Permission Denial: can't dump vibrator service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
pw.println("Previous vibrations:");
synchronized (mLock) {
for (VibrationInfo info : mPreviousVibrations) {
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index ad2ed93..d996ee2 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -92,6 +92,7 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
@@ -4867,13 +4868,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- fout.println("Permission Denial: can't dump AccountsManager from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c");
final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " ");
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8b0665c..4cbfb27 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -398,7 +398,7 @@
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
- service, neededGrants));
+ service, neededGrants, callingUid));
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
@@ -1140,7 +1140,7 @@
// Service is already running, so we can immediately
// publish the connection.
try {
- c.conn.connected(s.name, b.intent.binder);
+ c.conn.connected(s.name, b.intent.binder, false);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + s.shortName
+ " to connection " + c.conn.asBinder()
@@ -1194,7 +1194,7 @@
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
try {
- c.conn.connected(r.name, service);
+ c.conn.connected(r.name, service, false);
} catch (Exception e) {
Slog.w(TAG, "Failure sending service " + r.name +
" to connection " + c.conn.asBinder() +
@@ -1355,10 +1355,10 @@
if (r == null) {
try {
// TODO: come back and remove this assumption to triage all services
- ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService(service,
+ ResolveInfo rInfo = mAm.getPackageManagerInternalLocked().resolveService(service,
resolvedType, ActivityManagerService.STOCK_PM_FLAGS
| PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
- userId);
+ userId, callingUid);
ServiceInfo sInfo =
rInfo != null ? rInfo.serviceInfo : null;
if (sInfo == null) {
@@ -1927,7 +1927,7 @@
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
- null, null));
+ null, null, 0));
}
sendServiceArgsLocked(r, execInFg, true);
@@ -1979,7 +1979,8 @@
mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
si.getUriPermissionsLocked());
}
- // TODO b/34123112; Insert ephemeral grant here
+ mAm.grantEphemeralAccessLocked(r.userId, si.intent,
+ r.appInfo.uid, UserHandle.getAppId(si.callingId));
bumpServiceExecutingLocked(r, execInFg, "start");
if (!oomAdjusted) {
oomAdjusted = true;
@@ -2080,7 +2081,7 @@
// being brought down. Mark it as dead.
cr.serviceDead = true;
try {
- cr.conn.connected(r.name, null);
+ cr.conn.connected(r.name, null, true);
} catch (Exception e) {
Slog.w(TAG, "Failure disconnecting service " + r.name +
" to connection " + c.get(i).conn.asBinder() +
@@ -2591,7 +2592,7 @@
stopServiceLocked(sr);
} else {
sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
- sr.makeNextStartId(), baseIntent, null));
+ sr.makeNextStartId(), baseIntent, null, 0));
if (sr.app != null && sr.app.thread != null) {
// We always run in the foreground, since this is called as
// part of the "remove task" UI operation.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 81d0a7c..b4ea49b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -350,6 +350,7 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.MemInfoReader;
@@ -2656,14 +2657,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump meminfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "meminfo", pw)) return;
mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
}
}
@@ -2676,14 +2671,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump gfxinfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "gfxinfo", pw)) return;
mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
}
}
@@ -2696,14 +2685,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump dbinfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "dbinfo", pw)) return;
mActivityManagerService.dumpDbInfo(fd, pw, args);
}
}
@@ -2716,14 +2699,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump cpuinfo from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
+ "cpuinfo", pw)) return;
synchronized (mActivityManagerService.mProcessCpuTracker) {
pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
@@ -11539,6 +11516,9 @@
}
}
checkTime(startTime, "getContentProviderImpl: done!");
+
+ grantEphemeralAccessLocked(userId, null /*intent*/,
+ cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
}
// Wait for the provider to be published...
@@ -12314,13 +12294,17 @@
mRecentTasks.notifyTaskPersisterLocked(task, flush);
}
- /** Notifies all listeners when the pinned stack animation starts. */
+ /**
+ * Notifies all listeners when the pinned stack animation starts.
+ */
@Override
public void notifyPinnedStackAnimationStarted() {
mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
}
- /** Notifies all listeners when the pinned stack animation ends. */
+ /**
+ * Notifies all listeners when the pinned stack animation ends.
+ */
@Override
public void notifyPinnedStackAnimationEnded() {
mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
@@ -14758,15 +14742,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ActivityManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " without permission "
- + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
boolean dumpAll = false;
boolean dumpClient = false;
@@ -17667,7 +17643,6 @@
*/
private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
- Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
if (index >= 0) {
removeLruProcessLocked(app);
ProcessList.remove(app.pid);
@@ -19815,6 +19790,10 @@
}
}
+ /**
+ * NOTE: For the pinned stack, this method is only called after the bounds animation has
+ * animated the stack to the fullscreen.
+ */
@Override
public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 47e11b1..cbb51e1 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -284,6 +284,10 @@
boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
boolean immersive; // immersive mode (don't interrupt if possible)
boolean forceNewConfig; // force re-create with new config next time
+ private boolean mInMultiWindowMode; // whether or not this activity is currently in multi-window
+ // mode (default false)
+ private boolean mInPictureInPictureMode; // whether or not this activity is currently in
+ // picture-in-picture mode (default false)
boolean supportsPictureInPictureWhilePausing; // This flag is set by the system to indicate
// that the activity can enter picture in picture while pausing (ie. only when another
// task is brought to front or started)
@@ -615,25 +619,51 @@
}
}
- void scheduleMultiWindowModeChanged() {
+ void updateMultiWindowMode() {
if (task == null || task.getStack() == null || app == null || app.thread == null) {
return;
}
+
+ // An activity is considered to be in multi-window mode if its task isn't fullscreen.
+ final boolean inMultiWindowMode = !task.mFullscreen;
+ if (inMultiWindowMode != mInMultiWindowMode) {
+ mInMultiWindowMode = inMultiWindowMode;
+ scheduleMultiWindowModeChanged(getConfiguration());
+ }
+ }
+
+ private void scheduleMultiWindowModeChanged(Configuration overrideConfig) {
try {
- // An activity is considered to be in multi-window mode if its task isn't fullscreen.
- app.thread.scheduleMultiWindowModeChanged(appToken, !task.mFullscreen);
+ app.thread.scheduleMultiWindowModeChanged(appToken, mInMultiWindowMode,
+ overrideConfig);
} catch (Exception e) {
// If process died, I don't care.
}
}
- void schedulePictureInPictureModeChanged() {
+ void updatePictureInPictureMode(Rect targetStackBounds) {
if (task == null || task.getStack() == null || app == null || app.thread == null) {
return;
}
+
+ final boolean inPictureInPictureMode = (task.getStackId() == PINNED_STACK_ID) &&
+ (targetStackBounds != null);
+ if (inPictureInPictureMode != mInPictureInPictureMode) {
+ // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
+ // update that here in order
+ mInPictureInPictureMode = inPictureInPictureMode;
+ mInMultiWindowMode = inPictureInPictureMode;
+ final Configuration newConfig = task.computeNewOverrideConfigurationForBounds(
+ targetStackBounds, null);
+ schedulePictureInPictureModeChanged(newConfig);
+ scheduleMultiWindowModeChanged(newConfig);
+ }
+ }
+
+ private void schedulePictureInPictureModeChanged(Configuration overrideConfig) {
try {
- app.thread.schedulePictureInPictureModeChanged(
- appToken, task.getStackId() == PINNED_STACK_ID);
+ app.thread.schedulePictureInPictureModeChanged(appToken, mInPictureInPictureMode,
+ overrideConfig);
} catch (Exception e) {
// If process died, no one cares.
}
@@ -2122,23 +2152,31 @@
return true;
}
- /** Computes the override configuration for this activity */
+ /**
+ * Computes the bounds to fit the Activity within the bounds of the {@link Configuration}.
+ */
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
private void computeBounds(Rect outBounds) {
outBounds.setEmpty();
final float maxAspectRatio = info.maxAspectRatio;
final ActivityStack stack = getStack();
- if ((task != null && !task.mFullscreen) || maxAspectRatio == 0 || stack == null) {
+ if (task == null || stack == null || !task.mFullscreen || maxAspectRatio == 0) {
// We don't set override configuration if that activity task isn't fullscreen. I.e. the
// activity is in multi-window mode. Or, there isn't a max aspect ratio specified for
- // the activity.
+ // the activity. This is indicated by an empty {@link outBounds}.
return;
}
- stack.getDisplaySize(mTmpPoint);
- int maxActivityWidth = mTmpPoint.x;
- int maxActivityHeight = mTmpPoint.y;
- if (mTmpPoint.x < mTmpPoint.y) {
+ // We must base this on the parent configuration, because we set our override
+ // configuration's appBounds based on the result of this method. If we used our own
+ // configuration, it would be influenced by past invocations.
+ final Configuration configuration = getParent().getConfiguration();
+ final int containingAppWidth = configuration.appBounds.width();
+ final int containingAppHeight = configuration.appBounds.height();
+ int maxActivityWidth = containingAppWidth;
+ int maxActivityHeight = containingAppHeight;
+
+ if (containingAppWidth < containingAppHeight) {
// Width is the shorter side, so we use that to figure-out what the max. height should
// be given the aspect ratio.
maxActivityHeight = (int) ((maxActivityWidth * maxAspectRatio) + 0.5f);
@@ -2148,8 +2186,14 @@
maxActivityWidth = (int) ((maxActivityHeight * maxAspectRatio) + 0.5f);
}
- if (mTmpPoint.x <= maxActivityWidth && mTmpPoint.y <= maxActivityHeight) {
+ if (containingAppWidth <= maxActivityWidth && containingAppHeight <= maxActivityHeight) {
// The display matches or is less than the activity aspect ratio, so nothing else to do.
+ // Return the existing bounds. If this method is running for the first time,
+ // {@link mBounds} will be empty (representing no override). If the method has run
+ // before, then effect of {@link mBounds} will already have been applied to the
+ // value returned from {@link getConfiguration}. Refer to
+ // {@link TaskRecord#computeOverrideConfiguration}.
+ outBounds.set(mBounds);
return;
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 498de63..ee37463 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -342,7 +342,7 @@
private final Rect mTmpRect2 = new Rect();
/** Run all ActivityStacks through this */
- private final ActivityStackSupervisor mStackSupervisor;
+ protected final ActivityStackSupervisor mStackSupervisor;
private final LaunchingTaskPositioner mTaskPositioner;
@@ -5074,7 +5074,7 @@
}
void addTask(final TaskRecord task, final boolean toTop, String reason) {
- addTask(task, toTop ? MAX_VALUE : 0, reason);
+ addTask(task, toTop ? MAX_VALUE : 0, true /* schedulePictureInPictureModeChange */, reason);
if (toTop) {
// TODO: figure-out a way to remove this call.
mWindowContainerController.positionChildAtTop(task.getWindowContainerController(),
@@ -5084,7 +5084,8 @@
// TODO: This shouldn't allow automatic reparenting. Remove the call to preAddTask and deal
// with the fall-out...
- void addTask(final TaskRecord task, int position, String reason) {
+ void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange,
+ String reason) {
// TODO: Is this remove really needed? Need to look into the call path for the other addTask
mTaskHistory.remove(task);
position = getAdjustedPositionForTask(task, position, null /* starting */);
@@ -5100,7 +5101,7 @@
updateTaskMovement(task, toTop);
- postAddTask(task, prevStack);
+ postAddTask(task, prevStack, schedulePictureInPictureModeChange);
}
void positionChildAt(TaskRecord task, int index) {
@@ -5116,7 +5117,7 @@
final boolean wasResumed = topRunningActivity == task.getStack().mResumedActivity;
insertTaskAtPosition(task, index);
task.setStack(this);
- postAddTask(task, null /* prevStack */);
+ postAddTask(task, null /* prevStack */, true /* schedulePictureInPictureModeChange */);
if (wasResumed) {
if (mResumedActivity != null) {
@@ -5142,9 +5143,15 @@
return prevStack;
}
- private void postAddTask(TaskRecord task, ActivityStack prevStack) {
- if (prevStack != null) {
- mStackSupervisor.scheduleReportPictureInPictureModeChangedIfNeeded(task, prevStack);
+ /**
+ * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
+ * change. Callers may set this to false if they are explicitly scheduling PiP mode
+ * changes themselves, like during the PiP animation
+ */
+ private void postAddTask(TaskRecord task, ActivityStack prevStack,
+ boolean schedulePictureInPictureModeChange) {
+ if (schedulePictureInPictureModeChange && prevStack != null) {
+ mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, prevStack);
} else if (task.voiceSession != null) {
try {
task.voiceSession.taskStarted(task.intent, task.taskId);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c65ca79..f16849d 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -371,6 +371,10 @@
* application */
final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
+ /** The target stack bounds for the picture-in-picture mode changed that we need to report to
+ * the application */
+ Rect mPipModeChangedTargetStackBounds;
+
/** Used on user changes */
final ArrayList<UserState> mStartingUsers = new ArrayList<>();
@@ -2334,6 +2338,9 @@
ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
final boolean isFullscreenStackVisible = fullscreenStack != null &&
fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
+ // If we are moving from the pinned stack, then the animation takes care of updating
+ // the picture-in-picture mode.
+ final boolean schedulePictureInPictureModeChange = (fromStackId != PINNED_STACK_ID);
final ArrayList<TaskRecord> tasks = stack.getAllTasks();
final int size = tasks.size();
if (onTop) {
@@ -2352,6 +2359,7 @@
// Defer resume until all the tasks have been moved to the fullscreen stack
task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
REPARENT_MOVE_STACK_TO_FRONT, isTopTask /* animate */, DEFER_RESUME,
+ schedulePictureInPictureModeChange,
"moveTasksToFullscreenStack - onTop");
}
} else {
@@ -2361,8 +2369,9 @@
? Math.max(fullscreenStack.getAllTasks().size() - 1, 0) : 0;
// Defer resume until all the tasks have been moved to the fullscreen stack
task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, position,
- REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE,
- DEFER_RESUME, "moveTasksToFullscreenStack - NOT_onTop");
+ REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME,
+ schedulePictureInPictureModeChange,
+ "moveTasksToFullscreenStack - NOT_onTop");
}
}
@@ -2506,9 +2515,8 @@
fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
for (int i = 0; i < tasks.size(); i++) {
// Insert the task either at the top of the fullscreen stack if it is hidden,
- // or just under the top task if it is currently visible
- final int insertPosition = isFullscreenStackVisible
- ? Math.max(0, fullscreenStack.getChildCount() - 1)
+ // or to the bottom if it is currently visible
+ final int insertPosition = isFullscreenStackVisible ? 0
: fullscreenStack.getChildCount();
final TaskRecord task = tasks.get(i);
// Defer resume until we remove all the tasks
@@ -2856,9 +2864,9 @@
// was launched from home so home should be visible behind it.
moveHomeStackToFront(reason);
}
- // Defer resume until below
+ // Defer resume until below, and do not schedule PiP changes until we animate below
task.reparent(PINNED_STACK_ID, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
- DEFER_RESUME, reason);
+ DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
} else {
// There are multiple activities in the task and moving the top activity should
// reveal/leave the other activities in their original task.
@@ -2873,9 +2881,9 @@
r.mActivityType);
r.reparent(newTask, MAX_VALUE, "moveActivityToStack");
- // Defer resume until below
+ // Defer resume until below, and do not schedule PiP changes until we animate below
newTask.reparent(PINNED_STACK_ID, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, !ANIMATE,
- DEFER_RESUME, reason);
+ DEFER_RESUME, false /* schedulePictureInPictureModeChange */, reason);
}
// Reset the state that indicates it can enter PiP while pausing after we've moved it
@@ -4109,7 +4117,7 @@
mActivityMetricsLogger.logWindowState();
}
- void scheduleReportMultiWindowModeChanged(TaskRecord task) {
+ void scheduleUpdateMultiWindowMode(TaskRecord task) {
for (int i = task.mActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = task.mActivities.get(i);
if (r.app != null && r.app.thread != null) {
@@ -4122,22 +4130,39 @@
}
}
- void scheduleReportPictureInPictureModeChangedIfNeeded(TaskRecord task, ActivityStack prevStack) {
+ void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, ActivityStack prevStack) {
final ActivityStack stack = task.getStack();
if (prevStack == null || prevStack == stack
|| (prevStack.mStackId != PINNED_STACK_ID && stack.mStackId != PINNED_STACK_ID)) {
return;
}
- for (int i = task.mActivities.size() - 1; i >= 0; i--) {
- final ActivityRecord r = task.mActivities.get(i);
- if (r.app != null && r.app.thread != null) {
- mPipModeChangedActivities.add(r);
- }
- }
+ scheduleUpdatePictureInPictureModeIfNeeded(task, stack.mBounds, false /* immediate */);
+ }
- if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
- mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
+ void scheduleUpdatePictureInPictureModeIfNeeded(TaskRecord task, Rect targetStackBounds,
+ boolean immediate) {
+
+ if (immediate) {
+ mHandler.removeMessages(REPORT_PIP_MODE_CHANGED_MSG);
+ for (int i = task.mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = task.mActivities.get(i);
+ if (r.app != null && r.app.thread != null) {
+ r.updatePictureInPictureMode(targetStackBounds);
+ }
+ }
+ } else {
+ for (int i = task.mActivities.size() - 1; i >= 0; i--) {
+ final ActivityRecord r = task.mActivities.get(i);
+ if (r.app != null && r.app.thread != null) {
+ mPipModeChangedActivities.add(r);
+ }
+ }
+ mPipModeChangedTargetStackBounds = targetStackBounds;
+
+ if (!mHandler.hasMessages(REPORT_PIP_MODE_CHANGED_MSG)) {
+ mHandler.sendEmptyMessage(REPORT_PIP_MODE_CHANGED_MSG);
+ }
}
}
@@ -4165,7 +4190,7 @@
synchronized (mService) {
for (int i = mMultiWindowModeChangedActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = mMultiWindowModeChangedActivities.remove(i);
- r.scheduleMultiWindowModeChanged();
+ r.updateMultiWindowMode();
}
}
} break;
@@ -4173,7 +4198,7 @@
synchronized (mService) {
for (int i = mPipModeChangedActivities.size() - 1; i >= 0; i--) {
final ActivityRecord r = mPipModeChangedActivities.remove(i);
- r.schedulePictureInPictureModeChanged();
+ r.updatePictureInPictureMode(mPipModeChangedTargetStackBounds);
}
}
} break;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d3935d1..e5b2eca 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -59,6 +59,7 @@
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.PowerProfile;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.ServiceThread;
import com.android.server.power.BatterySaverPolicy.ServiceType;
@@ -1188,13 +1189,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump BatteryStats from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
int flags = 0;
boolean useCheckinFormat = false;
diff --git a/services/core/java/com/android/server/am/PersistentConnection.java b/services/core/java/com/android/server/am/PersistentConnection.java
new file mode 100644
index 0000000..c34c097
--- /dev/null
+++ b/services/core/java/com/android/server/am/PersistentConnection.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+package com.android.server.am;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.PrintWriter;
+
+/**
+ * Connects to a given service component on a given user.
+ *
+ * - Call {@link #connect()} to create a connection.
+ * - Call {@link #disconnect()} to disconnect. Make sure to disconnect when the user stops.
+ *
+ * Add onConnected/onDisconnected callbacks as needed.
+ */
+public abstract class PersistentConnection<T> {
+ private final Object mLock = new Object();
+
+ private final String mTag;
+ private final Context mContext;
+ private final Handler mHandler;
+ private final int mUserId;
+ private final ComponentName mComponentName;
+
+ @GuardedBy("mLock")
+ private boolean mStarted;
+
+ @GuardedBy("mLock")
+ private boolean mIsConnected;
+
+ @GuardedBy("mLock")
+ private T mService;
+
+ private final ServiceConnection mServiceConnection = new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mLock) {
+ Slog.i(mTag, "Connected: " + mComponentName.flattenToShortString()
+ + " u" + mUserId);
+
+ mIsConnected = true;
+ mService = asInterface(service);
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ synchronized (mLock) {
+ Slog.i(mTag, "Disconnected: " + mComponentName.flattenToShortString()
+ + " u" + mUserId);
+
+ cleanUpConnectionLocked();
+ }
+ }
+ };
+
+ public PersistentConnection(@NonNull String tag, @NonNull Context context,
+ @NonNull Handler handler, int userId, @NonNull ComponentName componentName) {
+ mTag = tag;
+ mContext = context;
+ mHandler = handler;
+ mUserId = userId;
+ mComponentName = componentName;
+ }
+
+ public final ComponentName getComponentName() {
+ return mComponentName;
+ }
+
+ /**
+ * @return whether connected.
+ */
+ public final boolean isConnected() {
+ synchronized (mLock) {
+ return mIsConnected;
+ }
+ }
+
+ /**
+ * @return the service binder interface.
+ */
+ public final T getServiceBinder() {
+ synchronized (mLock) {
+ return mService;
+ }
+ }
+
+ /**
+ * Connects to the service.
+ */
+ public final void connect() {
+ synchronized (mLock) {
+ if (mStarted) {
+ return;
+ }
+ mStarted = true;
+
+ final Intent service = new Intent().setComponent(mComponentName);
+
+ final boolean success = mContext.bindServiceAsUser(service, mServiceConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ mHandler, UserHandle.of(mUserId));
+
+ if (!success) {
+ Slog.e(mTag, "Binding: " + service.getComponent() + " u" + mUserId
+ + " failed.");
+ }
+ }
+ }
+
+ private void cleanUpConnectionLocked() {
+ mIsConnected = false;
+ mService = null;
+ }
+
+ /**
+ * Disconnect from the service.
+ */
+ public final void disconnect() {
+ synchronized (mLock) {
+ if (!mStarted) {
+ return;
+ }
+ Slog.i(mTag, "Stopping: " + mComponentName.flattenToShortString() + " u" + mUserId);
+ mStarted = false;
+ mContext.unbindService(mServiceConnection);
+
+ cleanUpConnectionLocked();
+ }
+ }
+
+ /** Must be implemented by a subclass to convert an {@link IBinder} to a stub. */
+ protected abstract T asInterface(IBinder binder);
+
+ public void dump(String prefix, PrintWriter pw) {
+ synchronized (mLock) {
+ pw.print(prefix);
+ pw.print(mComponentName.flattenToShortString());
+ pw.print(mStarted ? " [started]" : " [not started]");
+ pw.print(mIsConnected ? " [connected]" : " [not connected]");
+ pw.println();
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/am/PinnedActivityStack.java b/services/core/java/com/android/server/am/PinnedActivityStack.java
index 32d3082..394e902 100644
--- a/services/core/java/com/android/server/am/PinnedActivityStack.java
+++ b/services/core/java/com/android/server/am/PinnedActivityStack.java
@@ -23,6 +23,7 @@
import com.android.server.wm.PinnedStackWindowController;
import com.android.server.wm.StackWindowController;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -57,4 +58,18 @@
boolean isBoundsAnimatingToFullscreen() {
return getWindowContainerController().isBoundsAnimatingToFullscreen();
}
+
+ @Override
+ public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
+ // It is guaranteed that the activities requiring the update will be in the pinned stack at
+ // this point (either reparented before the animation into PiP, or before reparenting after
+ // the animation out of PiP)
+ synchronized(this) {
+ ArrayList<TaskRecord> tasks = getAllTasks();
+ for (int i = 0; i < tasks.size(); i++ ) {
+ mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(tasks.get(i),
+ targetStackBounds, true /* immediate */);
+ }
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 40effff..0dc6788 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -350,58 +350,58 @@
String procState;
switch (curProcState) {
case ActivityManager.PROCESS_STATE_PERSISTENT:
- procState = "P ";
+ procState = "PER ";
break;
case ActivityManager.PROCESS_STATE_PERSISTENT_UI:
- procState = "PU";
+ procState = "PERU";
break;
case ActivityManager.PROCESS_STATE_TOP:
- procState = "T ";
+ procState = "TOP";
break;
case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
- procState = "SB";
+ procState = "BFGS";
break;
case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
- procState = "SF";
+ procState = "FGS ";
break;
case ActivityManager.PROCESS_STATE_TOP_SLEEPING:
- procState = "TS";
+ procState = "TPSL";
break;
case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
- procState = "IF";
+ procState = "IMPF";
break;
case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
- procState = "IB";
+ procState = "IMPB";
break;
case ActivityManager.PROCESS_STATE_BACKUP:
- procState = "BU";
+ procState = "BKUP";
break;
case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT:
- procState = "HW";
+ procState = "HVY ";
break;
case ActivityManager.PROCESS_STATE_SERVICE:
- procState = "S ";
+ procState = "SVC ";
break;
case ActivityManager.PROCESS_STATE_RECEIVER:
- procState = "R ";
+ procState = "RCVR";
break;
case ActivityManager.PROCESS_STATE_HOME:
- procState = "HO";
+ procState = "HOME";
break;
case ActivityManager.PROCESS_STATE_LAST_ACTIVITY:
- procState = "LA";
+ procState = "LAST";
break;
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
- procState = "CA";
+ procState = "CAC ";
break;
case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
- procState = "Ca";
+ procState = "CACC";
break;
case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
- procState = "CE";
+ procState = "CEM ";
break;
case ActivityManager.PROCESS_STATE_NONEXISTENT:
- procState = "N ";
+ procState = "NONE";
break;
default:
procState = "??";
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 2d27204..3c5c5fd 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -287,7 +287,9 @@
pw.print(" setSchedGroup="); pw.print(setSchedGroup);
pw.print(" systemNoUi="); pw.print(systemNoUi);
pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
- pw.print(prefix); pw.print("vrThreadTid="); pw.print(vrThreadTid);
+ if (vrThreadTid != 0) {
+ pw.print(prefix); pw.print("vrThreadTid="); pw.println(vrThreadTid);
+ }
pw.print(prefix); pw.print("curProcState="); pw.print(curProcState);
pw.print(" repProcState="); pw.print(repProcState);
pw.print(" pssProcState="); pw.print(pssProcState);
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index d210ed7..deb3b28 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -616,13 +616,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mAm.checkCallingPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump procstats from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!com.android.internal.util.DumpUtils.checkDumpAndUsageStatsPermission(mAm.mContext,
+ TAG, pw)) return;
long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 44ebf50..b57f6c3 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -124,6 +124,7 @@
final ServiceRecord sr;
final boolean taskRemoved;
final int id;
+ final int callingId;
final Intent intent;
final ActivityManagerService.NeededUriGrants neededGrants;
long deliveredTime;
@@ -134,12 +135,13 @@
String stringName; // caching of toString
StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent,
- ActivityManagerService.NeededUriGrants _neededGrants) {
+ ActivityManagerService.NeededUriGrants _neededGrants, int _callingId) {
sr = _sr;
taskRemoved = _taskRemoved;
id = _id;
intent = _intent;
neededGrants = _neededGrants;
+ callingId = _callingId;
}
UriPermissionOwner getUriPermissionsLocked() {
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ce32f84..27a2461 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -568,7 +568,27 @@
boolean reparent(int preferredStackId, boolean toTop, @ReparentMoveStackMode int moveStackMode,
boolean animate, boolean deferResume, String reason) {
return reparent(preferredStackId, toTop ? MAX_VALUE : 0, moveStackMode, animate,
- deferResume, reason);
+ deferResume, true /* schedulePictureInPictureModeChange */, reason);
+ }
+
+ /**
+ * Convenience method to reparent a task to the top or bottom position of the stack, with
+ * an option to skip scheduling the picture-in-picture mode change.
+ */
+ boolean reparent(int preferredStackId, boolean toTop, @ReparentMoveStackMode int moveStackMode,
+ boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange,
+ String reason) {
+ return reparent(preferredStackId, toTop ? MAX_VALUE : 0, moveStackMode, animate,
+ deferResume, schedulePictureInPictureModeChange, reason);
+ }
+
+ /**
+ * Convenience method to reparent a task to a specific position of the stack.
+ */
+ boolean reparent(int preferredStackId, int position, @ReparentMoveStackMode int moveStackMode,
+ boolean animate, boolean deferResume, String reason) {
+ return reparent(preferredStackId, position, moveStackMode, animate, deferResume,
+ true /* schedulePictureInPictureModeChange */, reason);
}
/**
@@ -577,16 +597,20 @@
* @param preferredStackId the stack id of the target stack to move this task
* @param position the position to place this task in the new stack
* @param animate whether or not we should wait for the new window created as a part of the
- * reparenting to be drawn and animated in
+ * reparenting to be drawn and animated in
* @param moveStackMode whether or not to move the stack to the front always, only if it was
- * previously focused & in front, or never
+ * previously focused & in front, or never
* @param deferResume whether or not to update the visibility of other tasks and stacks that may
- * have changed as a result of this reparenting
+ * have changed as a result of this reparenting
+ * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
+ * change. Callers may set this to false if they are explicitly scheduling PiP mode
+ * changes themselves, like during the PiP animation
* @param reason the caller of this reparenting
- * @return
+ * @return whether the task was reparented
*/
boolean reparent(int preferredStackId, int position, @ReparentMoveStackMode int moveStackMode,
- boolean animate, boolean deferResume, String reason) {
+ boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange,
+ String reason) {
final ActivityStackSupervisor supervisor = mService.mStackSupervisor;
final WindowManagerService windowManager = mService.mWindowManager;
final ActivityStack sourceStack = getStack();
@@ -649,11 +673,12 @@
// Move the task
sourceStack.removeTask(this, reason, REMOVE_TASK_MODE_MOVING);
- toStack.addTask(this, position, reason);
+ toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
- // TODO: Ensure that this is actually necessary here
- // Notify of picture-in-picture mode changes
- supervisor.scheduleReportPictureInPictureModeChangedIfNeeded(this, sourceStack);
+ if (schedulePictureInPictureModeChange) {
+ // Notify of picture-in-picture mode changes
+ supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
+ }
// TODO: Ensure that this is actually necessary here
// Notify the voice session if required
@@ -1979,6 +2004,25 @@
}
/**
+ * @return a new Configuration for this Task, given the provided {@param bounds} and
+ * {@param insetBounds}.
+ */
+ Configuration computeNewOverrideConfigurationForBounds(Rect bounds, Rect insetBounds) {
+ // Compute a new override configuration for the given bounds, if fullscreen bounds
+ // (bounds == null), then leave the override config unset
+ final Configuration newOverrideConfig = new Configuration();
+ if (bounds != null) {
+ newOverrideConfig.setTo(getOverrideConfiguration());
+ mTmpRect.set(bounds);
+ adjustForMinimalTaskDimensions(mTmpRect);
+ computeOverrideConfiguration(newOverrideConfig, mTmpRect, insetBounds,
+ mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
+ }
+
+ return newOverrideConfig;
+ }
+
+ /**
* Update task's override configuration based on the bounds.
* @param bounds The bounds of the task.
* @return True if the override configuration was updated.
@@ -2027,7 +2071,7 @@
onOverrideConfigurationChanged(newConfig);
if (mFullscreen != oldFullscreen) {
- mService.mStackSupervisor.scheduleReportMultiWindowModeChanged(this);
+ mService.mStackSupervisor.scheduleUpdateMultiWindowMode(this);
}
return !mTmpConfig.equals(newConfig);
@@ -2044,6 +2088,7 @@
config.unset();
final Configuration parentConfig = getParent().getConfiguration();
+
final float density = parentConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
if (mStack != null) {
@@ -2052,11 +2097,7 @@
mTmpNonDecorBounds, mTmpStableBounds, overrideWidth, overrideHeight, density,
config, parentConfig);
} else {
- // No stack, give some default values
- config.smallestScreenWidthDp =
- mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
- config.screenWidthDp = config.screenHeightDp = config.smallestScreenWidthDp;
- Slog.wtf(TAG, "Expected stack when calculating override config");
+ throw new IllegalArgumentException("Expected stack when calculating override config");
}
config.orientation = (config.screenWidthDp <= config.screenHeightDp)
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 49d1521..70e56b0 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -114,6 +114,7 @@
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityManager;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.XmlUtils;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -6116,7 +6117,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
mMediaFocusControl.dump(pw);
dumpStreamStates(pw);
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 07ab067..0e593bd 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -70,6 +70,7 @@
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils;
import com.android.internal.util.Protocol;
@@ -1585,13 +1586,7 @@
// Binder.java closes the resource for us.
@SuppressWarnings("resource")
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ConnectivityService.Tether " +
- "from from pid=" + Binder.getCallingPid() + ", uid=" +
- Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("Tethering:");
pw.increaseIndent();
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index f47a9079..13054a6 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -60,6 +60,7 @@
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -162,9 +163,7 @@
@Override
protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP,
- "caller doesn't have the DUMP permission");
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw_)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, " ");
// This makes it so that future permission checks will be in the context of this
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index fd89b97..a1a7437 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -23,6 +23,7 @@
import static android.hardware.display.DisplayManager
.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import android.Manifest;
@@ -1538,13 +1539,7 @@
@Override // Binder call
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext == null
- || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump DisplayManager from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long token = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 1991c00..313abab 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -479,14 +479,7 @@
private final class BinderService extends IDreamManager.Stub {
@Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump DreamManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
try {
dumpInternal(pw);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 7d97ce4..2b85570 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -56,6 +56,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.DumpUtils;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.SystemService;
@@ -1071,13 +1072,7 @@
@Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump Fingerprint from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 6864e1e..807b1b1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -68,6 +68,7 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
@@ -1677,7 +1678,7 @@
@Override
protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
- getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
pw.println("mHdmiControlEnabled: " + mHdmiControlEnabled);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 65a4604..aafc9a8 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -27,6 +27,7 @@
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.SomeArgs;
import com.android.internal.R;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.DisplayThread;
@@ -1747,13 +1748,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump InputManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("INPUT MANAGER (dumpsys input)\n");
String dumpStr = nativeDump(mPtr);
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 2de9aae..7c231ff 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -72,6 +72,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.internal.app.procstats.ProcessStats;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.server.DeviceIdleController;
import com.android.server.LocalServices;
import com.android.server.job.JobStore.JobStatusFunctor;
@@ -1790,7 +1791,7 @@
*/
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
long identityToken = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index 0a15db6..5e9f355 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -31,6 +31,8 @@
import android.os.RemoteException;
import android.util.Log;
+import com.android.internal.util.DumpUtils;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
@@ -242,11 +244,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump contexthub service");
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("Dumping ContextHub Service");
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index f91ea8c..7b0e51e 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -16,6 +16,7 @@
package com.android.server.media;
+import com.android.internal.util.DumpUtils;
import com.android.server.Watchdog;
import android.Manifest;
@@ -258,13 +259,7 @@
// Binder call
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump MediaRouterService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
pw.println("MEDIA ROUTER SERVICE (dumpsys media_router)");
pw.println();
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 4bf9d8f..64ab848 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -71,6 +71,7 @@
import android.view.KeyEvent;
import android.view.ViewConfiguration;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.Watchdog;
@@ -1283,13 +1284,7 @@
@Override
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump MediaSessionService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
pw.println("MEDIA SESSION SERVICE (dumpsys media_session)");
pw.println();
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 3ea4f2c..9d92cbc 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -39,6 +39,7 @@
import android.util.ArrayMap;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
import com.android.server.SystemService;
import java.io.FileDescriptor;
@@ -314,14 +315,7 @@
@Override // Binder call
public void dump(FileDescriptor fd, final PrintWriter pw, String[] args) {
- if (mContext == null
- || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump MediaProjectionManager from from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long token = Binder.clearCallingIdentity();
try {
MediaProjectionManagerService.this.dump(pw);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index f180c50..4e1166b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -178,9 +178,11 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.DeviceIdleController;
@@ -212,6 +214,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Calendar;
+import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -268,11 +271,11 @@
ActivityManager.isLowRamDeviceStatic() ? 50 : 200;
@VisibleForTesting
- public static final int TYPE_WARNING = 0x1;
+ public static final int TYPE_WARNING = SystemMessage.NOTE_NET_WARNING;
@VisibleForTesting
- public static final int TYPE_LIMIT = 0x2;
+ public static final int TYPE_LIMIT = SystemMessage.NOTE_NET_LIMIT;
@VisibleForTesting
- public static final int TYPE_LIMIT_SNOOZED = 0x3;
+ public static final int TYPE_LIMIT_SNOOZED = SystemMessage.NOTE_NET_LIMIT_SNOOZED;
private static final String TAG_POLICY_LIST = "policy-list";
private static final String TAG_NETWORK_POLICY = "network-policy";
@@ -419,7 +422,7 @@
/** Set of currently active {@link Notification} tags. */
@GuardedBy("mNetworkPoliciesSecondLock")
- private final ArraySet<String> mActiveNotifs = new ArraySet<String>();
+ private final ArraySet<NotificationId> mActiveNotifs = new ArraySet<>();
/** Foreground at UID granularity. */
@GuardedBy("mUidRulesFirstLock")
@@ -1054,7 +1057,7 @@
if (LOGV) Slog.v(TAG, "updateNotificationsNL()");
// keep track of previously active notifications
- final ArraySet<String> beforeNotifs = new ArraySet<String>(mActiveNotifs);
+ final ArraySet<NotificationId> beforeNotifs = new ArraySet<NotificationId>(mActiveNotifs);
mActiveNotifs.clear();
// TODO: when switching to kernel notifications, compute next future
@@ -1091,9 +1094,9 @@
// cancel stale notifications that we didn't renew above
for (int i = beforeNotifs.size()-1; i >= 0; i--) {
- final String tag = beforeNotifs.valueAt(i);
- if (!mActiveNotifs.contains(tag)) {
- cancelNotification(tag);
+ final NotificationId notificationId = beforeNotifs.valueAt(i);
+ if (!mActiveNotifs.contains(notificationId)) {
+ cancelNotification(notificationId);
}
}
}
@@ -1141,19 +1144,11 @@
}
/**
- * Build unique tag that identifies an active {@link NetworkPolicy}
- * notification of a specific type, like {@link #TYPE_LIMIT}.
- */
- private String buildNotificationTag(NetworkPolicy policy, int type) {
- return TAG + ":" + policy.template.hashCode() + ":" + type;
- }
-
- /**
* Show notification for combined {@link NetworkPolicy} and specific type,
* like {@link #TYPE_LIMIT}. Okay to call multiple times.
*/
private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
- final String tag = buildNotificationTag(policy, type);
+ final NotificationId notificationId = new NotificationId(policy, type);
final Notification.Builder builder =
new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
builder.setOnlyAlertOnce(true);
@@ -1261,25 +1256,26 @@
try {
final String packageName = mContext.getPackageName();
final int[] idReceived = new int[1];
- if(!TextUtils.isEmpty(body)) {
+ if (!TextUtils.isEmpty(body)) {
builder.setStyle(new Notification.BigTextStyle()
.bigText(body));
}
mNotifManager.enqueueNotificationWithTag(
- packageName, packageName, tag, 0x0, builder.build(), idReceived,
- UserHandle.USER_ALL);
- mActiveNotifs.add(tag);
+ packageName, packageName, notificationId.getTag(), notificationId.getId(),
+ builder.build(), idReceived, UserHandle.USER_ALL);
+ mActiveNotifs.add(notificationId);
} catch (RemoteException e) {
// ignored; service lives in system_server
}
}
- private void cancelNotification(String tag) {
+ private void cancelNotification(NotificationId notificationId) {
// TODO: move to NotificationManager once we can mock it
try {
final String packageName = mContext.getPackageName();
mNotifManager.cancelNotificationWithTag(
- packageName, tag, 0x0, UserHandle.USER_ALL);
+ packageName, notificationId.getTag(), notificationId.getId(),
+ UserHandle.USER_ALL);
} catch (RemoteException e) {
// ignored; service lives in system_server
}
@@ -2585,7 +2581,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter fout = new IndentingPrintWriter(writer, " ");
@@ -4124,4 +4120,43 @@
return next;
}
}
+
+ private class NotificationId {
+ private final String mTag;
+ private final int mId;
+
+ NotificationId(NetworkPolicy policy, int type) {
+ mTag = buildNotificationTag(policy, type);
+ mId = type;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof NotificationId)) return false;
+ NotificationId that = (NotificationId) o;
+ return Objects.equals(mTag, that.mTag);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mTag);
+ }
+
+ /**
+ * Build unique tag that identifies an active {@link NetworkPolicy}
+ * notification of a specific type, like {@link #TYPE_LIMIT}.
+ */
+ private String buildNotificationTag(NetworkPolicy policy, int type) {
+ return TAG + ":" + policy.template.hashCode() + ":" + type;
+ }
+
+ public String getTag() {
+ return mTag;
+ }
+
+ public int getId() {
+ return mId;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 6d666e8..e746355 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -122,6 +122,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.VpnInfo;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FileRotator;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.EventLogTags;
@@ -1234,7 +1235,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter rawWriter, String[] args) {
- mContext.enforceCallingOrSelfPermission(DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, rawWriter)) return;
long duration = DateUtils.DAY_IN_MILLIS;
final HashSet<String> argSet = new HashSet<String>();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ede5a5e..44c715b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -144,6 +144,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.server.DeviceIdleController;
@@ -2451,14 +2452,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump NotificationManager from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
final DumpFilter filter = DumpFilter.parseFromArguments(args);
if (filter != null && filter.stats) {
dumpJson(pw, filter);
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 73afaa0..65aaee0 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -282,7 +282,7 @@
for (int i = 0; i < size; i++) {
final NotificationChannel notificationChannel = r.channels.valueAt(i);
if (notificationChannel != null &&
- notificationChannel.getId() != NotificationChannel.DEFAULT_CHANNEL_ID) {
+ !notificationChannel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
hasCreatedAChannel = true;
break;
}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index e1426fd..f79f6f4 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -242,18 +242,8 @@
try {
UserInfo callingUserInfo = mUm.getUserInfo(callingUserId);
if (callingUserInfo.isManagedProfile()) {
-
- // STOPSHIP Remove the whitelist.
- if ("com.google.android.talk".equals(callingPackage)
- || "com.google.android.quicksearchbox".equals(callingPackage)
- || "com.google.android.googlequicksearchbox".equals(callingPackage)
- ) {
- return false;
- }
- // STOPSHIP Change it to 'e'.
- Slog.wtfStack(TAG, message + " by " + callingPackage + " for another profile "
+ Slog.w(TAG, message + " by " + callingPackage + " for another profile "
+ targetUserId + " from " + callingUserId);
-
return false;
}
@@ -445,8 +435,8 @@
@Override
public ParceledListSlice getShortcuts(String callingPackage, long changedSince,
- String packageName, List shortcutIds, ComponentName componentName, Intent intent,
- int flags, UserHandle targetUser) {
+ String packageName, List shortcutIds, ComponentName componentName, int flags,
+ UserHandle targetUser) {
ensureShortcutPermission(callingPackage);
if (!canAccessProfile(callingPackage, targetUser, "Cannot get shortcuts")
|| !isUserEnabled(targetUser)) {
@@ -457,17 +447,11 @@
"To query by shortcut ID, package name must also be set");
}
- if ((flags & ShortcutQuery.FLAG_MATCH_CHOOSER) == 0
- && intent != null) {
- throw new IllegalArgumentException("Supplied an intent in the query, but did "
- + "not request chooser targets");
- }
-
// TODO(b/29399275): Eclipse compiler requires explicit List<ShortcutInfo> cast below.
return new ParceledListSlice<>((List<ShortcutInfo>)
mShortcutServiceInternal.getShortcuts(getCallingUserId(),
callingPackage, changedSince, packageName, shortcutIds,
- componentName, intent, flags, targetUser.getIdentifier()));
+ componentName, flags, targetUser.getIdentifier()));
}
@Override
@@ -915,7 +899,6 @@
cookie.packageName,
/* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
/* component= */ null,
- /* intent= */ null,
ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
| ShortcutQuery.FLAG_GET_ALL_KINDS
, userId);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2115f31..365a8e8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -254,6 +254,7 @@
import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
@@ -568,7 +569,7 @@
Manifest.permission.RECEIVE_MMS,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
- Manifest.permission.READ_PHONE_NUMBER,
+ Manifest.permission.READ_PHONE_NUMBERS,
Manifest.permission.ANSWER_PHONE_CALLS);
@@ -1181,7 +1182,6 @@
// Stores a list of users whose package restrictions file needs to be updated
private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
- static final long DEFAULT_CONTAINER_WHITELIST_DURATION = 10 * 60 * 1000;
final private DefaultContainerConnection mDefContainerConn =
new DefaultContainerConnection();
class DefaultContainerConnection implements ServiceConnection {
@@ -3036,13 +3036,14 @@
return null;
}
+ final int callingUid = Binder.getCallingUid();
final int resolveFlags =
MATCH_DIRECT_BOOT_AWARE
| MATCH_DIRECT_BOOT_UNAWARE
| (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
- resolveFlags, UserHandle.USER_SYSTEM);
+ resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
final int N = resolvers.size();
if (N == 0) {
@@ -4021,12 +4022,12 @@
* action and a {@code android.intent.category.BROWSABLE} category</li>
* </ul>
*/
- int updateFlagsForResolve(int flags, int userId, Intent intent, boolean includeInstantApp) {
+ int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
+ boolean includeInstantApps) {
// Safe mode means we shouldn't match any third-party components
if (mSafeMode) {
flags |= PackageManager.MATCH_SYSTEM_ONLY;
}
- final int callingUid = Binder.getCallingUid();
if (getInstantAppPackageName(callingUid) != null) {
// But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
@@ -4038,7 +4039,7 @@
|| callingUid == Process.SHELL_UID
|| callingUid == 0;
final boolean allowMatchInstant =
- (includeInstantApp
+ (includeInstantApps
&& Intent.ACTION_VIEW.equals(intent.getAction())
&& intent.hasCategory(Intent.CATEGORY_BROWSABLE)
&& hasWebURI(intent))
@@ -5588,22 +5589,23 @@
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
return resolveIntentInternal(
- intent, resolvedType, flags, userId, false /*includeInstantApp*/);
+ intent, resolvedType, flags, userId, false /*includeInstantApps*/);
}
private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
- int flags, int userId, boolean includeInstantApp) {
+ int flags, int userId, boolean includeInstantApps) {
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
if (!sUserManager.exists(userId)) return null;
- flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ final int callingUid = Binder.getCallingUid();
+ flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
+ enforceCrossUserPermission(callingUid, userId,
false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
- flags, userId, includeInstantApp);
+ flags, userId, includeInstantApps);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
final ResolveInfo bestChoice =
@@ -5623,9 +5625,11 @@
if (!sUserManager.exists(userId)) {
return null;
}
+ final int callingUid = Binder.getCallingUid();
intent = updateIntentForResolve(intent);
final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
- final int flags = updateFlagsForResolve(0, userId, intent, false);
+ final int flags = updateFlagsForResolve(
+ 0, userId, intent, callingUid, false /*includeInstantApps*/);
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
userId);
synchronized (mPackages) {
@@ -5914,7 +5918,9 @@
List<ResolveInfo> query, int priority, boolean always,
boolean removeMatches, boolean debug, int userId) {
if (!sUserManager.exists(userId)) return null;
- flags = updateFlagsForResolve(flags, userId, intent, false);
+ final int callingUid = Binder.getCallingUid();
+ flags = updateFlagsForResolve(
+ flags, userId, intent, callingUid, false /*includeInstantApps*/);
intent = updateIntentForResolve(intent);
// writer
synchronized (mPackages) {
@@ -6080,9 +6086,11 @@
}
if (hasWebURI(intent)) {
// cross-profile app linking works only towards the parent.
+ final int callingUid = Binder.getCallingUid();
final UserInfo parent = getProfileParent(sourceUserId);
synchronized(mPackages) {
- int flags = updateFlagsForResolve(0, parent.id, intent, false);
+ int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
+ false /*includeInstantApps*/);
CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
intent, resolvedType, flags, sourceUserId, parent.id);
return xpDomainInfo != null;
@@ -6149,11 +6157,12 @@
}
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
- String resolvedType, int flags, int userId, boolean includeInstantApp) {
+ String resolvedType, int flags, int userId, boolean includeInstantApps) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
- flags = updateFlagsForResolve(flags, userId, intent, includeInstantApp);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
+ final int callingUid = Binder.getCallingUid();
+ final String instantAppPkgName = getInstantAppPackageName(callingUid);
+ flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
+ enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */,
"query intent activities");
ComponentName comp = intent.getComponent();
@@ -6783,9 +6792,11 @@
Intent[] specifics, String[] specificTypes, Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- flags = updateFlagsForResolve(flags, userId, intent, false);
- enforceCrossUserPermission(Binder.getCallingUid(), userId,
- false /* requireFullPermission */, false /* checkShell */,
+ final int callingUid = Binder.getCallingUid();
+ flags = updateFlagsForResolve(flags, userId, intent, callingUid,
+ false /*includeInstantApps*/);
+ enforceCrossUserPermission(callingUid, userId,
+ false /*requireFullPermission*/, false /*checkShell*/,
"query intent activity options");
final String resultsAction = intent.getAction();
@@ -6963,7 +6974,9 @@
private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- flags = updateFlagsForResolve(flags, userId, intent, false);
+ final int callingUid = Binder.getCallingUid();
+ flags = updateFlagsForResolve(flags, userId, intent, callingUid,
+ false /*includeInstantApps*/);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -6999,9 +7012,17 @@
@Override
public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
+ final int callingUid = Binder.getCallingUid();
+ return resolveServiceInternal(
+ intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
+ }
+
+ private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
+ int userId, int callingUid, boolean includeInstantApps) {
if (!sUserManager.exists(userId)) return null;
- flags = updateFlagsForResolve(flags, userId, intent, false);
- List<ResolveInfo> query = queryIntentServicesInternal(intent, resolvedType, flags, userId);
+ flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
+ List<ResolveInfo> query = queryIntentServicesInternal(
+ intent, resolvedType, flags, userId, callingUid, includeInstantApps);
if (query != null) {
if (query.size() >= 1) {
// If there is more than one service with the same priority,
@@ -7015,14 +7036,17 @@
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
String resolvedType, int flags, int userId) {
- return new ParceledListSlice<>(
- queryIntentServicesInternal(intent, resolvedType, flags, userId));
+ final int callingUid = Binder.getCallingUid();
+ return new ParceledListSlice<>(queryIntentServicesInternal(
+ intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
}
private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
- String resolvedType, int flags, int userId) {
+ String resolvedType, int flags, int userId, int callingUid,
+ boolean includeInstantApps) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- flags = updateFlagsForResolve(flags, userId, intent, false);
+ final String instantAppPkgName = getInstantAppPackageName(callingUid);
+ flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -7034,9 +7058,27 @@
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
final ServiceInfo si = getServiceInfo(comp, flags, userId);
if (si != null) {
- final ResolveInfo ri = new ResolveInfo();
- ri.serviceInfo = si;
- list.add(ri);
+ // When specifying an explicit component, we prevent the service from being
+ // used when either 1) the service is in an instant application and the
+ // caller is not the same instant application or 2) the calling package is
+ // ephemeral and the activity is not visible to ephemeral applications.
+ final boolean matchVisibleToInstantAppOnly =
+ (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean isCallerInstantApp =
+ instantAppPkgName != null;
+ final boolean isTargetSameInstantApp =
+ comp.getPackageName().equals(instantAppPkgName);
+ final boolean isTargetHiddenFromInstantApp =
+ (si.flags & ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0;
+ final boolean blockResolution =
+ !isTargetSameInstantApp
+ && ((matchVisibleToInstantAppOnly && isCallerInstantApp
+ && isTargetHiddenFromInstantApp));
+ if (!blockResolution) {
+ final ResolveInfo ri = new ResolveInfo();
+ ri.serviceInfo = si;
+ list.add(ri);
+ }
}
return list;
}
@@ -7045,17 +7087,67 @@
synchronized (mPackages) {
String pkgName = intent.getPackage();
if (pkgName == null) {
- return mServices.queryIntent(intent, resolvedType, flags, userId);
+ return applyPostServiceResolutionFilter(
+ mServices.queryIntent(intent, resolvedType, flags, userId),
+ instantAppPkgName);
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
- return mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
- userId);
+ return applyPostServiceResolutionFilter(
+ mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
+ userId),
+ instantAppPkgName);
}
return Collections.emptyList();
}
}
+ private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
+ String instantAppPkgName) {
+ // TODO: When adding on-demand split support for non-instant apps, remove this check
+ // and always apply post filtering
+ if (instantAppPkgName == null) {
+ return resolveInfos;
+ }
+ for (int i = resolveInfos.size() - 1; i >= 0; i--) {
+ final ResolveInfo info = resolveInfos.get(i);
+ final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
+ // allow services that are defined in the provided package
+ if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
+ if (info.serviceInfo.splitName != null
+ && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
+ info.serviceInfo.splitName)) {
+ // requested service is defined in a split that hasn't been installed yet.
+ // add the installer to the resolve list
+ if (DEBUG_EPHEMERAL) {
+ Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
+ }
+ final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
+ installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
+ info.serviceInfo.packageName, info.serviceInfo.splitName,
+ info.serviceInfo.applicationInfo.versionCode);
+ // make sure this resolver is the default
+ installerInfo.isDefault = true;
+ installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
+ | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
+ // add a non-generic filter
+ installerInfo.filter = new IntentFilter();
+ // load resources from the correct package
+ installerInfo.resolvePackageName = info.getComponentInfo().packageName;
+ resolveInfos.set(i, installerInfo);
+ }
+ continue;
+ }
+ // allow services that have been explicitly exposed to ephemeral apps
+ if (!isEphemeralApp
+ && ((info.serviceInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0)) {
+ continue;
+ }
+ resolveInfos.remove(i);
+ }
+ return resolveInfos;
+ }
+
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
String resolvedType, int flags, int userId) {
@@ -7066,7 +7158,9 @@
private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
Intent intent, String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- flags = updateFlagsForResolve(flags, userId, intent, false);
+ final int callingUid = Binder.getCallingUid();
+ flags = updateFlagsForResolve(flags, userId, intent, callingUid,
+ false /*includeInstantApps*/);
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -12401,11 +12495,29 @@
if (ps == null) {
return null;
}
+ final PackageUserState userState = ps.readUserState(userId);
ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
- ps.readUserState(userId), userId);
+ userState, userId);
if (si == null) {
return null;
}
+ final boolean matchVisibleToInstantApp =
+ (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ // throw out filters that aren't visible to ephemeral apps
+ if (matchVisibleToInstantApp
+ && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+ return null;
+ }
+ // throw out ephemeral filters if we're not explicitly requesting them
+ if (!isInstantApp && userState.instantApp) {
+ return null;
+ }
+ // throw out instant app filters if updates are available; will trigger
+ // instant app resolution
+ if (userState.instantApp && ps.isUpdateAvailable()) {
+ return null;
+ }
final ResolveInfo res = new ResolveInfo();
res.serviceInfo = si;
if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
@@ -12915,9 +13027,6 @@
IActivityManager am = ActivityManager.getService();
if (am != null) {
try {
- getDeviceIdleController().addPowerSaveTempWhitelistApp(Process.SYSTEM_UID,
- DEFAULT_CONTAINER_PACKAGE, DEFAULT_CONTAINER_WHITELIST_DURATION,
- UserHandle.USER_SYSTEM, false, "cleaning packages");
am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
@@ -20230,15 +20339,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump ActivityManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " without permission "
- + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
DumpState dumpState = new DumpState();
boolean fullPreferred = false;
@@ -22238,7 +22339,7 @@
if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
+ stats.dataSize);
- final long startFreeBytes = measurePath.getFreeSpace();
+ final long startFreeBytes = measurePath.getUsableSpace();
final long sizeBytes;
if (moveCompleteApp) {
sizeBytes = stats.codeSize + stats.dataSize;
@@ -22302,7 +22403,7 @@
} catch (InterruptedException ignored) {
}
- final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
+ final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
final int progress = 10 + (int) MathUtils.constrain(
((deltaFreeBytes * 80) / sizeBytes), 0, 80);
mMoveCallbacks.notifyStatusChanged(moveId, progress);
@@ -23146,10 +23247,18 @@
}
}
+ @Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
return resolveIntentInternal(
- intent, resolvedType, flags, userId, true /*includeInstantApp*/);
+ intent, resolvedType, flags, userId, true /*includeInstantApps*/);
+ }
+
+ @Override
+ public ResolveInfo resolveService(Intent intent, String resolvedType,
+ int flags, int userId, int callingUid) {
+ return resolveServiceInternal(
+ intent, resolvedType, flags, userId, callingUid, true /*includeInstantApps*/);
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 8739089..6fb056a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3375,7 +3375,7 @@
private void applyDefaultPreferredActivityLPw(PackageManagerService service,
Intent intent, int flags, ComponentName cn, String scheme, PatternMatcher ssp,
IntentFilter.AuthorityEntry auth, PatternMatcher path, int userId) {
- flags = service.updateFlagsForResolve(flags, userId, intent, false);
+ flags = service.updateFlagsForResolve(flags, userId, intent, Binder.getCallingUid(), false);
List<ResolveInfo> ri = service.mActivities.queryIntent(intent,
intent.getType(), flags, 0);
if (PackageManagerService.DEBUG_PREFERRED) Log.d(TAG, "Queried " + intent
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 6f7e0de..5035e68 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -20,7 +20,6 @@
import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.content.res.Resources;
@@ -32,7 +31,6 @@
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.pm.ShortcutService.ShortcutOperation;
@@ -70,9 +68,6 @@
private static final String TAG_EXTRAS = "extras";
private static final String TAG_SHORTCUT = "shortcut";
private static final String TAG_CATEGORIES = "categories";
- private static final String TAG_CHOOSER_EXTRAS = "chooser-extras";
- private static final String TAG_CHOOSER_INTENT_FILTERS = "chooser-intent-filters";
- private static final String TAG_CHOOSER_COMPONENT_NAMES = "chooser-component-names";
private static final String ATTR_NAME = "name";
private static final String ATTR_CALL_COUNT = "call-count";
@@ -96,7 +91,6 @@
private static final String ATTR_ICON_RES_ID = "icon-res";
private static final String ATTR_ICON_RES_NAME = "icon-resname";
private static final String ATTR_BITMAP_PATH = "bitmap-path";
- private static final String ATTR_COMPONENT_NAMES = "component-names";
private static final String NAME_CATEGORIES = "categories";
@@ -206,7 +200,7 @@
if (shortcut != null) {
mShortcutUser.mService.removeIcon(getPackageUserId(), shortcut);
shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED
- | ShortcutInfo.FLAG_MANIFEST | ShortcutInfo.FLAG_CHOOSER);
+ | ShortcutInfo.FLAG_MANIFEST);
}
return shortcut;
}
@@ -232,7 +226,7 @@
Preconditions.checkArgument(newShortcut.isEnabled(),
"add/setDynamicShortcuts() cannot publish disabled shortcuts");
- addCorrectDynamicFlags(newShortcut);
+ newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);
final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId());
@@ -256,17 +250,6 @@
addShortcutInner(newShortcut);
}
- // TODO: Sample code & JavaDoc for ShortcutManager needs updating to reflect the fact that
- // Chooser shortcuts are not always dynamic.
- public void addCorrectDynamicFlags(@NonNull ShortcutInfo shortcut) {
- if (shortcut.getIntent() != null) {
- shortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC);
- }
- if (!ArrayUtils.isEmpty(shortcut.getChooserIntentFilters())) {
- shortcut.addFlags(ShortcutInfo.FLAG_CHOOSER);
- }
- }
-
/**
* Remove all shortcuts that aren't pinned nor dynamic.
*/
@@ -299,11 +282,11 @@
boolean changed = false;
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
final ShortcutInfo si = mShortcuts.valueAt(i);
- if (si.isDynamic() || si.isChooser()) {
+ if (si.isDynamic()) {
changed = true;
si.setTimestamp(now);
- si.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_CHOOSER);
+ si.clearFlags(ShortcutInfo.FLAG_DYNAMIC);
si.setRank(0); // It may still be pinned, so clear the rank.
}
}
@@ -372,8 +355,7 @@
if (oldShortcut.isPinned()) {
oldShortcut.setRank(0);
- oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST
- | ShortcutInfo.FLAG_CHOOSER);
+ oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_MANIFEST);
if (disable) {
oldShortcut.addFlags(ShortcutInfo.FLAG_DISABLED);
}
@@ -1133,8 +1115,8 @@
// Don't adjust ranks for manifest shortcuts.
continue;
}
- // At this point, it must be dynamic or a chooser.
- if (!si.isDynamicOrChooser()) {
+ // At this point, it must be dynamic.
+ if (!si.isDynamic()) {
s.wtf("Non-dynamic shortcut found.");
continue;
}
@@ -1311,7 +1293,7 @@
ShortcutService.writeAttr(out, ATTR_FLAGS,
si.getFlags() &
~(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES
- | ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_CHOOSER));
+ | ShortcutInfo.FLAG_DYNAMIC));
} else {
// When writing for backup, ranks shouldn't be saved, since shortcuts won't be restored
// as dynamic.
@@ -1334,37 +1316,16 @@
}
final Intent[] intentsNoExtras = si.getIntentsNoExtras();
final PersistableBundle[] intentsExtras = si.getIntentPersistableExtrases();
- if (intentsNoExtras != null) {
- final int numIntents = intentsNoExtras.length;
- for (int i = 0; i < numIntents; i++) {
- out.startTag(null, TAG_INTENT);
- ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
- ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
- out.endTag(null, TAG_INTENT);
- }
+ final int numIntents = intentsNoExtras.length;
+ for (int i = 0; i < numIntents; i++) {
+ out.startTag(null, TAG_INTENT);
+ ShortcutService.writeAttr(out, ATTR_INTENT_NO_EXTRA, intentsNoExtras[i]);
+ ShortcutService.writeTagExtra(out, TAG_EXTRAS, intentsExtras[i]);
+ out.endTag(null, TAG_INTENT);
}
+
ShortcutService.writeTagExtra(out, TAG_EXTRAS, si.getExtras());
- ShortcutService.writeTagExtra(out, TAG_CHOOSER_EXTRAS, si.getChooserExtras());
-
- final IntentFilter[] intentFilters = si.getChooserIntentFilters();
- if (intentFilters != null) {
- for (int i = 0; i < intentFilters.length; i++) {
- out.startTag(null, TAG_CHOOSER_INTENT_FILTERS);
- intentFilters[i].writeToXml(out);
- out.endTag(null, TAG_CHOOSER_INTENT_FILTERS);
- }
- }
-
- final ComponentName[] componentNames = si.getChooserComponentNames();
- if (componentNames != null) {
- for (int i = 0; i < componentNames.length; i++) {
- out.startTag(null, TAG_CHOOSER_COMPONENT_NAMES);
- ShortcutService.writeAttr(out, ATTR_COMPONENT_NAMES, componentNames[i]);
- out.endTag(null, TAG_CHOOSER_COMPONENT_NAMES);
- }
- }
-
out.endTag(null, TAG_SHORTCUT);
}
@@ -1436,9 +1397,6 @@
String iconResName;
String bitmapPath;
ArraySet<String> categories = null;
- PersistableBundle chooserExtras;
- List<IntentFilter> chooserIntentFilters = new ArrayList<>();
- List<ComponentName> chooserComponentNames = new ArrayList<>();
id = ShortcutService.parseStringAttribute(parser, ATTR_ID);
activityComponent = ShortcutService.parseComponentNameAttribute(parser,
@@ -1499,18 +1457,6 @@
}
}
continue;
- case TAG_CHOOSER_EXTRAS:
- chooserExtras = PersistableBundle.restoreFromXml(parser);
- continue;
- case TAG_CHOOSER_COMPONENT_NAMES:
- chooserComponentNames.add(ShortcutService.parseComponentNameAttribute(parser,
- ATTR_ACTIVITY));
- continue;
- case TAG_CHOOSER_INTENT_FILTERS:
- IntentFilter toAdd = new IntentFilter();
- toAdd.readFromXml(parser);
- chooserIntentFilters.add(toAdd);
- continue;
}
throw ShortcutService.throwForInvalidTag(depth, tag);
}
@@ -1604,10 +1550,10 @@
// Verify each shortcut's status.
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
final ShortcutInfo si = mShortcuts.valueAt(i);
- if (!(si.isDeclaredInManifest() || si.isDynamicOrChooser() || si.isPinned())) {
+ if (!(si.isDeclaredInManifest() || si.isDynamic() || si.isPinned())) {
failed = true;
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
- + " is not manifest, dynamic, chooser or pinned.");
+ + " is not manifest, dynamic or pinned.");
}
if (si.isDeclaredInManifest() && si.isDynamic()) {
failed = true;
@@ -1649,11 +1595,6 @@
Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
+ " has a dummy target activity");
}
- if (si.getIntent() == null && !si.isChooser()) {
- failed = true;
- Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
- + " has a null intent, but is not a chooser");
- }
}
if (failed) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index a5b739e..7c89e1c 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -27,7 +27,6 @@
import android.appwidget.AppWidgetProviderInfo;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -65,7 +64,6 @@
import android.os.Handler;
import android.os.LocaleList;
import android.os.Looper;
-import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.Process;
@@ -96,6 +94,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
@@ -1753,7 +1752,6 @@
ps.clearAllImplicitRanks();
assignImplicitRanks(newShortcuts);
- // TODO: Consider removing Chooser fields. If so, the FLAG_CHOOSER should be removed
for (int i = 0; i < size; i++) {
final ShortcutInfo source = newShortcuts.get(i);
fixUpIncomingShortcutInfo(source, /* forUpdate= */ true);
@@ -1793,13 +1791,6 @@
if (replacingIcon || source.hasStringResources()) {
fixUpShortcutResourceNamesAndValues(target);
}
-
- // While updating, we keep the dynamic flag as it previously was, but refresh the
- // chooser flag.
- // TODO: If we support clearing Chooser fields, we should also remove the flag.
- if (target.getChooserIntentFilters() != null) {
- target.addFlags(ShortcutInfo.FLAG_CHOOSER);
- }
}
// Lastly, adjust the ranks.
@@ -1863,7 +1854,6 @@
return true;
}
- // TODO: Ensure non-launchable shortcuts can not be pinned
@Override
public boolean requestPinShortcut(String packageName, ShortcutInfo shortcut,
IntentSender resultIntent, int userId) {
@@ -2019,7 +2009,7 @@
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
- ShortcutInfo::isDynamicOrChooser);
+ ShortcutInfo::isDynamic);
}
}
@@ -2212,14 +2202,6 @@
synchronized (mLock) {
throwIfUserLockedL(userId);
- // For the chooser, we just check is the system is calling.
- // STOPSHIP: We need to implement a new permission here rather than this terrible check.
- // The packageName check is to try to distinguish between when an actual
- // launcher is making the call, and when it's the system.
- if (isCallerSystem() && packageName.equals("android")) {
- return true;
- }
-
final ShortcutUser user = getUserShortcutsLocked(userId);
// Always trust the cached component.
@@ -2392,7 +2374,7 @@
public List<ShortcutInfo> getShortcuts(int launcherUserId,
@NonNull String callingPackage, long changedSince,
@Nullable String packageName, @Nullable List<String> shortcutIds,
- @Nullable ComponentName componentName, @Nullable Intent intent,
+ @Nullable ComponentName componentName,
int queryFlags, int userId) {
final ArrayList<ShortcutInfo> ret = new ArrayList<>();
@@ -2414,13 +2396,13 @@
if (packageName != null) {
getShortcutsInnerLocked(launcherUserId,
callingPackage, packageName, shortcutIds, changedSince,
- componentName, intent, queryFlags, userId, ret, cloneFlag);
+ componentName, queryFlags, userId, ret, cloneFlag);
} else {
final List<String> shortcutIdsF = shortcutIds;
getUserShortcutsLocked(userId).forAllPackages(p -> {
getShortcutsInnerLocked(launcherUserId,
callingPackage, p.getPackageName(), shortcutIdsF, changedSince,
- componentName, intent, queryFlags, userId, ret, cloneFlag);
+ componentName, queryFlags, userId, ret, cloneFlag);
});
}
}
@@ -2429,7 +2411,7 @@
private void getShortcutsInnerLocked(int launcherUserId, @NonNull String callingPackage,
@Nullable String packageName, @Nullable List<String> shortcutIds, long changedSince,
- @Nullable ComponentName componentName, Intent intent, int queryFlags,
+ @Nullable ComponentName componentName, int queryFlags,
int userId, ArrayList<ShortcutInfo> ret, int cloneFlag) {
final ArraySet<String> ids = shortcutIds == null ? null
: new ArraySet<>(shortcutIds);
@@ -2454,15 +2436,6 @@
return false;
}
}
- if (intent != null
- && !si.hasMatchingFilter(mContext.getContentResolver(), intent)) {
- return false;
- }
-
- if (((queryFlags & ShortcutQuery.FLAG_MATCH_CHOOSER) != 0)
- && si.isChooser()) {
- return true;
- }
if (((queryFlags & ShortcutQuery.FLAG_GET_DYNAMIC) != 0)
&& si.isDynamic()) {
return true;
@@ -3447,8 +3420,12 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- enforceCallingOrSelfPermission(android.Manifest.permission.DUMP,
- "can't dump by this caller");
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
+ dumpNoCheck(fd, pw, args);
+ }
+
+ @VisibleForTesting
+ void dumpNoCheck(FileDescriptor fd, PrintWriter pw, String[] args) {
boolean checkin = false;
boolean clear = false;
if (args != null) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 8ecf6f7..63e2d47 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -89,6 +89,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IAppOpsService;
import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
@@ -3358,15 +3359,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump UserManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " without permission "
- + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
long now = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 4f67e8c..9c4e700 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -75,6 +75,7 @@
import com.android.internal.hardware.AmbientDisplayConfiguration;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
import com.android.server.LockGuard;
import com.android.server.RescueParty;
@@ -4503,13 +4504,7 @@
@Override // Binder call
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump PowerManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index edeb774..8c31731 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -47,6 +47,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -371,7 +372,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
synchronized (mSearchables) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 83ea075..212bd61 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -39,6 +39,7 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.notification.NotificationDelegate;
import com.android.server.power.ShutdownThread;
@@ -981,13 +982,7 @@
// ================================================================================
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump StatusBar from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println(" mDisabled1=0x" + Integer.toHexString(mDisabled1));
diff --git a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
index 963a572..40bb496 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
@@ -17,6 +17,8 @@
import android.content.ComponentName;
import android.os.RemoteException;
import android.os.ShellCommand;
+import android.service.quicksettings.TileService;
+
import com.android.internal.statusbar.IStatusBarService;
import java.io.PrintWriter;
@@ -48,6 +50,10 @@
return runRemoveTile();
case "click-tile":
return runClickTile();
+ case "check-support":
+ final PrintWriter pw = getOutPrintWriter();
+ pw.println(String.valueOf(TileService.isQuickSettingsSupported()));
+ return 0;
default:
return handleDefaultCommands(cmd);
}
@@ -113,5 +119,8 @@
pw.println(" click-tile COMPONENT");
pw.println(" Click on a TileService of the specified component");
pw.println("");
+ pw.println(" check-support");
+ pw.println(" Check if this device supports QS + APIs");
+ pw.println("");
}
}
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index a847a3c..275b612 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -20,6 +20,7 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.util.DumpUtils;
import com.android.server.EventLogTags;
import com.android.server.SystemService;
import com.android.server.pm.InstructionSets;
@@ -467,15 +468,7 @@
private final Binder mRemoteService = new Binder() {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump " + SERVICE + " from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
dumpImpl(fd, pw, args);
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 4570b0d..f4f7e24 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -59,6 +59,7 @@
import android.view.WindowManagerGlobal;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.SystemService;
import java.io.FileDescriptor;
@@ -849,8 +850,7 @@
@Override
protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
- mContext.enforceCallingPermission(Manifest.permission.DUMP,
- "dumping TrustManagerService");
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
if (isSafeMode()) {
fout.println("disabled because the system is in safe mode.");
return;
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 08eca73..6117da7 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -59,6 +59,7 @@
import android.view.KeyEvent;
import android.view.Surface;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
@@ -549,12 +550,7 @@
public void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump TvInputHardwareManager from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("TvInputHardwareManager Info:");
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 52763a1..be91f48 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -77,6 +77,7 @@
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.IoThread;
import com.android.server.SystemService;
@@ -1912,12 +1913,7 @@
@SuppressWarnings("resource")
protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump TvInputManager from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("User Ids (Current user: " + mCurrentUserId + "):");
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index 324faff..cc08918 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -55,6 +55,7 @@
import android.util.SparseArray;
import com.android.internal.R;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
@@ -444,12 +445,8 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump VrManagerService from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+
pw.println("********* Dump of VrManagerService *********");
pw.println("VR mode is currently: " + ((mVrModeAllowed) ? "allowed" : "disallowed"));
pw.println("Persistent VR mode is currently: " +
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index c6b032b..6a18beb 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -87,6 +87,7 @@
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.server.EventLogTags;
@@ -2297,14 +2298,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump wallpaper service from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (mLock) {
pw.println("System wallpaper state:");
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 4a105e1..3b400b4 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -33,6 +33,7 @@
import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;
+import com.android.internal.util.DumpUtils;
import com.android.server.SystemService;
import java.io.FileDescriptor;
@@ -293,14 +294,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump webviewupdate service from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
- return;
- }
-
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
WebViewUpdateService.this.mImpl.dumpState(pw);
}
}
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 62414e5..9f0ed21 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static com.android.server.wm.AppTransition.DEFAULT_APP_TRANSITION_DURATION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -32,7 +31,6 @@
import android.util.Slog;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
import android.view.WindowManagerInternal;
/**
@@ -111,10 +109,15 @@
private final boolean mMoveToFullScreen;
// True if this this animation was cancelled and will be replaced the another animation from
// the same {@link #AnimateBoundsUser} target.
- private boolean mWillReplace;
- // True to true if this animation replaced a previous animation of the same
+ private boolean mSkipAnimationEnd;
+ // True if this animation replaced a previous animation of the same
// {@link #AnimateBoundsUser} target.
- private final boolean mReplacement;
+ private final boolean mSkipAnimationStart;
+ // True if this animation is not replacing a previous animation, or if the previous
+ // animation is animating to a different fullscreen state than the current animation.
+ // We use this to ensure that we always provide a consistent set/order of callbacks when we
+ // transition to/from PiP.
+ private final boolean mAnimatingToNewFullscreenState;
// Depending on whether we are animating from
// a smaller to a larger size
@@ -122,13 +125,14 @@
private final int mFrozenTaskHeight;
BoundsAnimator(AnimateBoundsUser target, Rect from, Rect to, boolean moveToFullScreen,
- boolean replacement) {
+ boolean replacingExistingAnimation, boolean animatingToNewFullscreenState) {
super();
mTarget = target;
mFrom.set(from);
mTo.set(to);
mMoveToFullScreen = moveToFullScreen;
- mReplacement = replacement;
+ mSkipAnimationStart = replacingExistingAnimation;
+ mAnimatingToNewFullscreenState = animatingToNewFullscreenState;
addUpdateListener(this);
addListener(this);
@@ -145,11 +149,32 @@
}
}
- boolean animatingToLargerSize() {
- if (mFrom.width() * mFrom.height() > mTo.width() * mTo.height()) {
- return false;
+ @Override
+ public void onAnimationStart(Animator animation) {
+ if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
+ + " mSkipAnimationStart=" + mSkipAnimationStart);
+ mFinishAnimationAfterTransition = false;
+ mTmpRect.set(mFrom.left, mFrom.top, mFrom.left + mFrozenTaskWidth,
+ mFrom.top + mFrozenTaskHeight);
+
+ // Ensure that we have prepared the target for animation before
+ // we trigger any size changes, so it can swap surfaces
+ // in to appropriate modes, or do as it wishes otherwise.
+ if (!mSkipAnimationStart) {
+ mTarget.onAnimationStart(mMoveToFullScreen);
}
- return true;
+
+ // If we are animating to a new fullscreen state (either to/from fullscreen), then
+ // notify the target of the change with the new frozen task bounds
+ if (mAnimatingToNewFullscreenState) {
+ mTarget.updatePictureInPictureMode(mMoveToFullScreen ? null : mTo);
+ }
+
+ // Immediately update the task bounds if they have to become larger, but preserve
+ // the starting position so we don't jump at the beginning of the animation.
+ if (animatingToLargerSize()) {
+ mTarget.setPinnedStackSize(mFrom, mTmpRect);
+ }
}
@Override
@@ -174,32 +199,11 @@
}
}
-
- @Override
- public void onAnimationStart(Animator animation) {
- if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
- + " mReplacement=" + mReplacement);
- mFinishAnimationAfterTransition = false;
- // Ensure that we have prepared the target for animation before
- // we trigger any size changes, so it can swap surfaces
- // in to appropriate modes, or do as it wishes otherwise.
- if (!mReplacement) {
- mTarget.onAnimationStart(mMoveToFullScreen);
- }
-
- // Immediately update the task bounds if they have to become larger, but preserve
- // the starting position so we don't jump at the beginning of the animation.
- if (animatingToLargerSize()) {
- mTmpRect.set(mFrom.left, mFrom.top,
- mFrom.left + mFrozenTaskWidth, mFrom.top + mFrozenTaskHeight);
- mTarget.setPinnedStackSize(mFrom, mTmpRect);
- }
- }
-
@Override
public void onAnimationEnd(Animator animation) {
if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
- + " mMoveToFullScreen=" + mMoveToFullScreen + " mWillReplace=" + mWillReplace);
+ + " mMoveToFullScreen=" + mMoveToFullScreen
+ + " mSkipAnimationEnd=" + mSkipAnimationEnd);
// There could be another animation running. For example in the
// move to fullscreen case, recents will also be closing while the
@@ -214,7 +218,7 @@
finishAnimation();
mTarget.setPinnedStackSize(mTo, null);
- if (mMoveToFullScreen && !mWillReplace) {
+ if (mMoveToFullScreen && !mSkipAnimationEnd) {
mTarget.moveToFullscreen();
}
}
@@ -226,20 +230,27 @@
@Override
public void cancel() {
- mWillReplace = true;
+ mSkipAnimationEnd = true;
if (DEBUG) Slog.d(TAG, "cancel: willReplace mTarget=" + mTarget);
super.cancel();
}
/** Returns true if the animation target is the same as the input bounds. */
- public boolean isAnimatingTo(Rect bounds) {
+ boolean isAnimatingTo(Rect bounds) {
return mTo.equals(bounds);
}
+ private boolean animatingToLargerSize() {
+ if (mFrom.width() * mFrom.height() > mTo.width() * mTo.height()) {
+ return false;
+ }
+ return true;
+ }
+
private void finishAnimation() {
if (DEBUG) Slog.d(TAG, "finishAnimation: mTarget=" + mTarget
+ " callers" + Debug.getCallers(2));
- if (!mWillReplace) {
+ if (!mSkipAnimationEnd) {
mTarget.onAnimationEnd();
}
removeListener(this);
@@ -249,7 +260,7 @@
@Override
public void onAnimationRepeat(Animator animation) {
-
+ // Do nothing
}
}
@@ -266,14 +277,27 @@
boolean setSize(Rect bounds);
/**
* Behaves as setSize, but freezes the bounds of any tasks in the target at taskBounds,
- * to allow for more flexibility during resizing. Only
- * works for the pinned stack at the moment.
+ * to allow for more flexibility during resizing. Only works for the pinned stack at the
+ * moment.
*/
boolean setPinnedStackSize(Rect bounds, Rect taskBounds);
+ /**
+ * Callback for the target to inform it that the animation has started, so it can do some
+ * necessary preparation.
+ */
void onAnimationStart(boolean toFullscreen);
/**
+ * Callback for the target to inform it that the animation is going to a new fullscreen
+ * state and should update the picture-in-picture mode accordingly.
+ *
+ * @param targetStackBounds the target stack bounds we are animating to, can be null if
+ * we are animating to fullscreen
+ */
+ void updatePictureInPictureMode(Rect targetStackBounds);
+
+ /**
* Callback for the target to inform it that the animation has ended, so it can do some
* necessary cleanup.
*/
@@ -286,9 +310,12 @@
boolean moveToFullscreen) {
final BoundsAnimator existing = mRunningAnimations.get(target);
final boolean replacing = existing != null;
+ final boolean animatingToNewFullscreenState = (existing == null) ||
+ (existing.mMoveToFullScreen != moveToFullscreen);
if (DEBUG) Slog.d(TAG, "animateBounds: target=" + target + " from=" + from + " to=" + to
- + " moveToFullscreen=" + moveToFullscreen + " replacing=" + replacing);
+ + " moveToFullscreen=" + moveToFullscreen + " replacing=" + replacing
+ + " animatingToNewFullscreenState=" + animatingToNewFullscreenState);
if (replacing) {
if (existing.isAnimatingTo(to)) {
@@ -300,8 +327,8 @@
}
existing.cancel();
}
- final BoundsAnimator animator =
- new BoundsAnimator(target, from, to, moveToFullscreen, replacing);
+ final BoundsAnimator animator = new BoundsAnimator(target, from, to, moveToFullscreen,
+ replacing, animatingToNewFullscreenState);
mRunningAnimations.put(target, animator);
animator.setFloatValues(0f, 1f);
animator.setDuration((animationDuration != -1 ? animationDuration
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index ae413e5..3c68e4f 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1134,6 +1134,13 @@
config.screenHeightDp =
(int)(mService.mPolicy.getConfigDisplayHeight(dw, dh, displayInfo.rotation,
config.uiMode, mDisplayId) / mDisplayMetrics.density);
+
+ mService.mPolicy.getNonDecorInsetsLw(displayInfo.rotation, dw, dh, mTmpRect);
+ final int leftInset = mTmpRect.left;
+ final int topInset = mTmpRect.top;
+ // appBounds at the root level should mirror the app screen size.
+ config.setAppBounds(leftInset /*left*/, topInset /*top*/, leftInset + displayInfo.appWidth /*right*/,
+ topInset + displayInfo.appHeight /*bottom*/);
final boolean rotated = (displayInfo.rotation == Surface.ROTATION_90
|| displayInfo.rotation == Surface.ROTATION_270);
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 85eae02..e300256 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -225,14 +225,25 @@
mService.mPolicy.getStableInsetsLw(rotation, dw, dh, mTmpRect);
config.unset();
config.orientation = (dw <= dh) ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
+
+ final int displayId = mDisplayContent.getDisplayId();
+ final int appWidth = mService.mPolicy.getNonDecorDisplayWidth(dw, dh, rotation,
+ baseConfig.uiMode, displayId);
+ final int appHeight = mService.mPolicy.getNonDecorDisplayHeight(dw, dh, rotation,
+ baseConfig.uiMode, displayId);
+ mService.mPolicy.getNonDecorInsetsLw(rotation, dw, dh, mTmpRect);
+ final int leftInset = mTmpRect.left;
+ final int topInset = mTmpRect.top;
+
+ config.setAppBounds(leftInset /*left*/, topInset /*top*/, leftInset + appWidth /*right*/,
+ topInset + appHeight /*bottom*/);
+
config.screenWidthDp = (int)
(mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode,
- mDisplayContent.getDisplayId()) /
- mDisplayContent.getDisplayMetrics().density);
+ displayId) / mDisplayContent.getDisplayMetrics().density);
config.screenHeightDp = (int)
(mService.mPolicy.getConfigDisplayHeight(dw, dh, rotation, baseConfig.uiMode,
- mDisplayContent.getDisplayId()) /
- mDisplayContent.getDisplayMetrics().density);
+ displayId) / mDisplayContent.getDisplayMetrics().density);
final Context rotationContext = mService.mContext.createConfigurationContext(config);
mSnapAlgorithmForRotation[rotation] = new DividerSnapAlgorithm(
rotationContext.getResources(), dw, dh, getContentWidth(),
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 8186d30..635527e 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -270,6 +270,12 @@
int width;
int height;
+
+ final Rect parentAppBounds = parentConfig.appBounds;
+
+ config.setAppBounds(!bounds.isEmpty() ? bounds : null);
+ boolean intersectParentBounds = false;
+
if (StackId.tasksAreFloating(mStackId)) {
// Floating tasks should not be resized to the screen's bounds.
@@ -280,6 +286,7 @@
// the fullscreen stack, without intersecting it with the display bounds
stableBounds.inset(mTmpStableInsets);
nonDecorBounds.inset(mTmpNonDecorInsets);
+ intersectParentBounds = true;
}
width = (int) (stableBounds.width() / density);
height = (int) (stableBounds.height() / density);
@@ -299,6 +306,11 @@
parentConfig.screenWidthDp);
height = Math.min((int) (stableBounds.height() / density),
parentConfig.screenHeightDp);
+ intersectParentBounds = true;
+ }
+
+ if (intersectParentBounds && config.appBounds != null) {
+ config.appBounds.intersect(parentAppBounds);
}
config.screenWidthDp = width;
@@ -350,6 +362,13 @@
}
}
+ /** Calls directly into activity manager so window manager lock shouldn't held. */
+ public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
+ if (mListener != null) {
+ mListener.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
+ }
+ }
+
void requestResize(Rect bounds) {
mHandler.obtainMessage(H.REQUEST_RESIZE, bounds).sendToTarget();
}
diff --git a/services/core/java/com/android/server/wm/StackWindowListener.java b/services/core/java/com/android/server/wm/StackWindowListener.java
index c763c17..a55f9df 100644
--- a/services/core/java/com/android/server/wm/StackWindowListener.java
+++ b/services/core/java/com/android/server/wm/StackWindowListener.java
@@ -26,4 +26,10 @@
/** Called when the stack container would like its controller to resize. */
void requestResize(Rect bounds);
+
+ /**
+ * Called when the stack container pinned stack animation will change the picture-in-picture
+ * mode. This is a direct call into ActivityManager.
+ */
+ default void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {}
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 8b5f5ac..1a67ac7 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -1483,6 +1483,14 @@
}
@Override // AnimatesBounds
+ public void updatePictureInPictureMode(Rect targetStackBounds) {
+ final StackWindowController controller = getController();
+ if (controller != null) {
+ controller.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
+ }
+ }
+
+ @Override // AnimatesBounds
public void onAnimationEnd() {
synchronized (mService.mWindowMap) {
mBoundsAnimating = false;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 6c7da50..95fbbb8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -204,6 +204,7 @@
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -6517,13 +6518,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump WindowManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
boolean dumpAll = false;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
new file mode 100644
index 0000000..97fa9d5
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+package com.android.server.devicepolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.IDeviceAdminService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ParceledListSlice;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.BackgroundThread;
+import com.android.server.am.PersistentConnection;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Manages connections to persistent services in owner packages.
+ */
+public class DeviceAdminServiceController {
+ static final String TAG = DevicePolicyManagerService.LOG_TAG;
+
+ static final boolean DEBUG = false; // DO NOT MERGE WITH TRUE.
+
+ final Object mLock = new Object();
+ final Context mContext;
+
+ private final DevicePolicyManagerService mService;
+ private final DevicePolicyManagerService.Injector mInjector;
+
+ private final Handler mHandler; // needed?
+
+ static void debug(String format, Object... args) {
+ if (!DEBUG) {
+ return;
+ }
+ Slog.d(TAG, String.format(format, args));
+ }
+
+ private class DevicePolicyServiceConnection
+ extends PersistentConnection<IDeviceAdminService> {
+ public DevicePolicyServiceConnection(int userId, @NonNull ComponentName componentName) {
+ super(TAG, mContext, mHandler, userId, componentName);
+ }
+
+ @Override
+ protected IDeviceAdminService asInterface(IBinder binder) {
+ return IDeviceAdminService.Stub.asInterface(binder);
+ }
+ }
+
+ /**
+ * User-ID -> {@link PersistentConnection}.
+ */
+ @GuardedBy("mLock")
+ private final SparseArray<DevicePolicyServiceConnection> mConnections = new SparseArray<>();
+
+ public DeviceAdminServiceController(DevicePolicyManagerService service) {
+ mService = service;
+ mInjector = service.mInjector;
+ mContext = mInjector.mContext;
+ mHandler = new Handler(BackgroundThread.get().getLooper());
+ }
+
+ /**
+ * Find a service that handles {@link DevicePolicyManager#ACTION_DEVICE_ADMIN_SERVICE}
+ * in a given package.
+ */
+ @Nullable
+ private ServiceInfo findService(@NonNull String packageName, int userId) {
+ final Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_ADMIN_SERVICE);
+ intent.setPackage(packageName);
+
+ try {
+ final ParceledListSlice<ResolveInfo> pls = mInjector.getIPackageManager()
+ .queryIntentServices(intent, null, /* flags=*/ 0, userId);
+ if (pls == null) {
+ return null;
+ }
+ final List<ResolveInfo> list = pls.getList();
+ if (list.size() == 0) {
+ return null;
+ }
+ // Note if multiple services are found, that's an error, even if only one of them
+ // is exported.
+ if (list.size() > 1) {
+ Log.e(TAG, "More than one DeviceAdminService's found in package "
+ + packageName
+ + ". They'll all be ignored.");
+ return null;
+ }
+ final ServiceInfo si = list.get(0).serviceInfo;
+ if (si.exported) {
+ Log.e(TAG, "DeviceAdminService must not be exported: '"
+ + si.getComponentName().flattenToShortString()
+ + "' will be ignored.");
+ return null;
+ }
+ return si;
+ } catch (RemoteException e) {
+ }
+ return null;
+ }
+
+ /**
+ * Find a service that handles {@link DevicePolicyManager#ACTION_DEVICE_ADMIN_SERVICE}
+ * in an owner package and connect to it.
+ */
+ public void startServiceForOwner(@NonNull String packageName, int userId,
+ @NonNull String actionForLog) {
+ final long token = mInjector.binderClearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ final ServiceInfo service = findService(packageName, userId);
+ if (service == null) {
+ debug("Owner package %s on u%d has no service.",
+ packageName, userId);
+ disconnectServiceOnUserLocked(userId, actionForLog);
+ return;
+ }
+ // See if it's already running.
+ final PersistentConnection<IDeviceAdminService> existing =
+ mConnections.get(userId);
+ if (existing != null) {
+ if (existing.getComponentName().equals(service.getComponentName())) {
+ return;
+ }
+ disconnectServiceOnUserLocked(userId, actionForLog);
+ }
+
+ debug("Owner package %s on u%d has service %s for %s",
+ packageName, userId,
+ service.getComponentName().flattenToShortString(), actionForLog);
+
+ final DevicePolicyServiceConnection conn =
+ new DevicePolicyServiceConnection(
+ userId, service.getComponentName());
+ mConnections.put(userId, conn);
+ conn.connect();
+ }
+ } finally {
+ mInjector.binderRestoreCallingIdentity(token);
+ }
+ }
+
+ /**
+ * Stop an owner service on a given user.
+ */
+ public void stopServiceForOwner(int userId, @NonNull String actionForLog) {
+ final long token = mInjector.binderClearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ disconnectServiceOnUserLocked(userId, actionForLog);
+ }
+ } finally {
+ mInjector.binderRestoreCallingIdentity(token);
+ }
+ }
+
+ private void disconnectServiceOnUserLocked(int userId, @NonNull String actionForLog) {
+ final DevicePolicyServiceConnection conn = mConnections.get(userId);
+ if (conn != null) {
+ debug("Stopping service for u%d if already running for %s.",
+ userId, actionForLog);
+ conn.disconnect();
+ mConnections.remove(userId);
+ }
+ }
+
+ public void dump(String prefix, PrintWriter pw) {
+ synchronized (mLock) {
+ if (mConnections.size() == 0) {
+ return;
+ }
+ pw.println();
+ pw.print(prefix); pw.println("Owner Services:");
+ for (int i = 0; i < mConnections.size(); i++) {
+ final int userId = mConnections.keyAt(i);
+ pw.print(prefix); pw.print(" "); pw.print("User: "); pw.println(userId);
+
+ final DevicePolicyServiceConnection con = mConnections.valueAt(i);
+ con.dump(prefix + " ", pw);
+ }
+ }
+ }
+}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index db7c99e..bfa1b99 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -140,7 +140,6 @@
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsInternal;
import android.provider.Settings;
-import android.security.Credentials;
import android.security.IKeyChainAliasCallback;
import android.security.IKeyChainService;
import android.security.KeyChain;
@@ -169,6 +168,7 @@
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.os.BackgroundThread;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.JournaledFile;
import com.android.internal.util.Preconditions;
@@ -193,7 +193,6 @@
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
-import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -364,6 +363,7 @@
final UserManagerInternal mUserManagerInternal;
final TelephonyManager mTelephonyManager;
private final LockPatternUtils mLockPatternUtils;
+ private final DeviceAdminServiceController mDeviceAdminServiceController;
/**
* Contains (package-user) pairs to remove. An entry (p, u) implies that removal of package p
@@ -458,7 +458,17 @@
@Override
public void onStartUser(int userHandle) {
- mService.onStartUser(userHandle);
+ mService.handleStartUser(userHandle);
+ }
+
+ @Override
+ public void onUnlockUser(int userHandle) {
+ mService.handleUnlockUser(userHandle);
+ }
+
+ @Override
+ public void onStopUser(int userHandle) {
+ mService.handleStopUser(userHandle);
}
}
@@ -1419,7 +1429,7 @@
}
}
- private void handlePackagesChanged(String packageName, int userHandle) {
+ private void handlePackagesChanged(@Nullable String packageName, int userHandle) {
boolean removedAdmin = false;
if (VERBOSE_LOG) Slog.d(LOG_TAG, "Handling package changes for user " + userHandle);
DevicePolicyData policy = getUserData(userHandle);
@@ -1433,9 +1443,9 @@
if (packageName == null || packageName.equals(adminPackage)) {
if (mIPackageManager.getPackageInfo(adminPackage, 0, userHandle) == null
|| mIPackageManager.getReceiverInfo(aa.info.getComponent(),
- PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
- userHandle) == null) {
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+ userHandle) == null) {
removedAdmin = true;
policy.mAdminList.remove(i);
policy.mAdminMap.remove(aa.info.getComponent());
@@ -1460,6 +1470,13 @@
}
}
+ // If it's an owner package, we may need to refresh the bound connection.
+ final ComponentName owner = getOwnerComponent(userHandle);
+ if ((packageName != null) && (owner != null)
+ && (owner.getPackageName().equals(packageName))) {
+ startOwnerService(userHandle, "package-broadcast");
+ }
+
// Persist updates if the removed package was an admin or delegate.
if (removedAdmin || removedDelegate) {
saveSettingsLocked(policy.mUserHandle);
@@ -1790,6 +1807,8 @@
// Needed when mHasFeature == false, because it controls the certificate warning text.
mCertificateMonitor = new CertificateMonitor(this, mInjector, mBackgroundHandler);
+ mDeviceAdminServiceController = new DeviceAdminServiceController(this);
+
if (!mHasFeature) {
// Skip the rest of the initialization
return;
@@ -2942,7 +2961,7 @@
loadOwners();
cleanUpOldUsers();
ensureUnknownSourcesRestrictionForProfileOwners();
- onStartUser(UserHandle.USER_SYSTEM);
+ handleStartUser(UserHandle.USER_SYSTEM);
// Register an observer for watching for user setup complete and settings changes.
mSetupContentObserver.register();
@@ -2989,10 +3008,32 @@
}
}
- private void onStartUser(int userId) {
+ void handleStartUser(int userId) {
updateScreenCaptureDisabledInWindowManager(userId,
getScreenCaptureDisabled(null, userId));
pushUserRestrictions(userId);
+
+ startOwnerService(userId, "start-user");
+ }
+
+ void handleUnlockUser(int userId) {
+ startOwnerService(userId, "unlock-user");
+ }
+
+ void handleStopUser(int userId) {
+ stopOwnerService(userId, "stop-user");
+ }
+
+ private void startOwnerService(int userId, String actionForLog) {
+ final ComponentName owner = getOwnerComponent(userId);
+ if (owner != null) {
+ mDeviceAdminServiceController.startServiceForOwner(
+ owner.getPackageName(), userId, actionForLog);
+ }
+ }
+
+ private void stopOwnerService(int userId, String actionForLog) {
+ mDeviceAdminServiceController.stopServiceForOwner(userId, actionForLog);
}
private void cleanUpOldUsers() {
@@ -5077,7 +5118,7 @@
* @param callerPackage the name of the calling package. Required if {@code who} is
* {@code null}.
* @param reqPolicy the policy used in the API whose access permission is being checked.
- * @param scoppe the delegation scope corresponding to the API being checked.
+ * @param scope the delegation scope corresponding to the API being checked.
* @throws SecurityException if {@code who} is given and is not an owner for {@code reqPolicy};
* or when {@code who} is {@code null} and {@code callerPackage} is not a delegate
* of {@code scope}.
@@ -6459,6 +6500,9 @@
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
+ mDeviceAdminServiceController.startServiceForOwner(
+ admin.getPackageName(), userId, "set-device-owner");
+
Slog.i(LOG_TAG, "Device owner set: " + admin + " on user " + userId);
return true;
}
@@ -6614,6 +6658,8 @@
}
private void clearDeviceOwnerLocked(ActiveAdmin admin, int userId) {
+ mDeviceAdminServiceController.stopServiceForOwner(userId, "clear-device-owner");
+
if (admin != null) {
admin.disableCamera = false;
admin.userRestrictions = null;
@@ -6691,6 +6737,8 @@
} finally {
mInjector.binderRestoreCallingIdentity(id);
}
+ mDeviceAdminServiceController.startServiceForOwner(
+ who.getPackageName(), userHandle, "set-profile-owner");
return true;
}
}
@@ -6722,6 +6770,8 @@
}
public void clearProfileOwnerLocked(ActiveAdmin admin, int userId) {
+ mDeviceAdminServiceController.stopServiceForOwner(userId, "clear-profile-owner");
+
if (admin != null) {
admin.disableCamera = false;
admin.userRestrictions = null;
@@ -7269,18 +7319,12 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid="
- + mInjector.binderGetCallingPid()
- + ", uid=" + mInjector.binderGetCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (this) {
pw.println("Current Device Policy Manager state:");
mOwners.dump(" ", pw);
+ mDeviceAdminServiceController.dump(" ", pw);
int userCount = mUserData.size();
for (int u = 0; u < userCount; u++) {
DevicePolicyData policy = getUserData(mUserData.keyAt(u));
@@ -9630,6 +9674,21 @@
return null;
}
+ /**
+ * Return device owner or profile owner set on a given user.
+ */
+ private @Nullable ComponentName getOwnerComponent(int userId) {
+ synchronized (this) {
+ if (mOwners.getDeviceOwnerUserId() == userId) {
+ return mOwners.getDeviceOwnerComponent();
+ }
+ if (mOwners.hasProfileOwner(userId)) {
+ return mOwners.getProfileOwnerComponent(userId);
+ }
+ }
+ return null;
+ }
+
private int checkManagedUserProvisioningPreCondition(int callingUserId) {
if (!hasFeatureManagedUsers()) {
return CODE_MANAGED_USERS_NOT_SUPPORTED;
diff --git a/services/midi/java/com/android/server/midi/MidiService.java b/services/midi/java/com/android/server/midi/MidiService.java
index 1c18c9b..100e459 100644
--- a/services/midi/java/com/android/server/midi/MidiService.java
+++ b/services/midi/java/com/android/server/midi/MidiService.java
@@ -45,6 +45,7 @@
import android.util.Log;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;
import com.android.server.SystemService;
@@ -1011,7 +1012,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
pw.println("MIDI Manager State:");
diff --git a/services/print/java/com/android/server/print/PrintManagerService.java b/services/print/java/com/android/server/print/PrintManagerService.java
index d7666d9..3ec8380 100644
--- a/services/print/java/com/android/server/print/PrintManagerService.java
+++ b/services/print/java/com/android/server/print/PrintManagerService.java
@@ -19,7 +19,6 @@
import static android.content.pm.PackageManager.GET_SERVICES;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
-import android.Manifest;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.ComponentName;
@@ -40,22 +39,23 @@
import android.print.IPrintDocumentAdapter;
import android.print.IPrintJobStateChangeListener;
import android.print.IPrintManager;
-import android.printservice.recommendation.IRecommendationsChangeListener;
import android.print.IPrintServicesChangeListener;
import android.print.IPrinterDiscoveryObserver;
import android.print.PrintAttributes;
import android.print.PrintJobId;
import android.print.PrintJobInfo;
import android.print.PrintManager;
-import android.printservice.recommendation.RecommendationInfo;
import android.print.PrinterId;
import android.printservice.PrintServiceInfo;
+import android.printservice.recommendation.IRecommendationsChangeListener;
+import android.printservice.recommendation.RecommendationInfo;
import android.provider.Settings;
import android.util.Log;
import android.util.SparseArray;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
@@ -628,13 +628,7 @@
fd = Preconditions.checkNotNull(fd);
pw = Preconditions.checkNotNull(pw);
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump PrintManager from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, pw)) return;
synchronized (mLock) {
final long identity = Binder.clearCallingIdentity();
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 0f51c49..d281e5a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -36,7 +36,6 @@
import static org.mockito.Mockito.when;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.Activity;
import android.app.ActivityManager;
@@ -1276,7 +1275,7 @@
try {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
final PrintWriter pw = new PrintWriter(out);
- mService.dump(/* fd */ null, pw, args);
+ mService.dumpNoCheck(/* fd */ null, pw, args);
pw.close();
return out.toString();
@@ -1345,23 +1344,20 @@
protected ShortcutInfo makeShortcut(String id) {
return makeShortcut(
id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
}
@Deprecated // Title was renamed to short label.
protected ShortcutInfo makeShortcutWithTitle(String id, String title) {
return makeShortcut(
id, title, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
}
protected ShortcutInfo makeShortcutWithShortLabel(String id, String shortLabel) {
return makeShortcut(
id, shortLabel, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
}
/**
@@ -1370,8 +1366,7 @@
protected ShortcutInfo makeShortcutWithTimestamp(String id, long timestamp) {
final ShortcutInfo s = makeShortcut(
id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
s.setTimestamp(timestamp);
return s;
}
@@ -1383,8 +1378,7 @@
ComponentName activity) {
final ShortcutInfo s = makeShortcut(
id, "Title-" + id, activity, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
s.setTimestamp(timestamp);
return s;
}
@@ -1395,27 +1389,7 @@
protected ShortcutInfo makeShortcutWithIcon(String id, Icon icon) {
return makeShortcut(
id, "Title-" + id, /* activity =*/ null, icon,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
- }
-
- protected ShortcutInfo makeChooserShortcut(String id, int i, boolean includeIntent) {
- List<IntentFilter> filters = new ArrayList<>();
- List<ComponentName> componentNames = new ArrayList<>();
- for(int j = 0; j < i; j++) {
- final IntentFilter filter = new IntentFilter();
- filter.addAction("view");
- filters.add(filter);
-
- componentNames.add(new ComponentName("xxxx", "yy" + i));
- }
- Intent intent = null;
- if (includeIntent) {
- intent = makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class);
- }
- return makeShortcut(
- id, "Title-" + id, /* activity =*/ null, /* icon */ null,
- intent, /* rank =*/ 0, filters, componentNames);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
}
protected ShortcutInfo makePackageShortcut(String packageName, String id) {
@@ -1424,8 +1398,7 @@
setCaller(packageName);
ShortcutInfo s = makeShortcut(
id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
setCaller(origCaller); // restore the caller
return s;
@@ -1449,52 +1422,39 @@
protected ShortcutInfo makeShortcutWithActivity(String id, ComponentName activity) {
return makeShortcut(
id, "Title-" + id, activity, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilters =*/ null, /* chooserComponentNames =*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
}
protected ShortcutInfo makeShortcutWithIntent(String id, Intent intent) {
return makeShortcut(
id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
- intent, /* rank =*/ 0, /* chooserFilters =*/ null,
- /* chooserComponentNames =*/ null);
-
+ intent, /* rank =*/ 0);
}
protected ShortcutInfo makeShortcutWithActivityAndTitle(String id, ComponentName activity,
String title) {
return makeShortcut(
id, title, activity, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0,
- /* chooserFilters =*/ null, /* chooserComponentNames =*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
}
protected ShortcutInfo makeShortcutWithActivityAndRank(String id, ComponentName activity,
int rank) {
return makeShortcut(
id, "Title-" + id, activity, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), rank,
- /* chooserFilters =*/ null, /* chooserComponentNames =*/ null);
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), rank);
}
/**
* Make a shortcut with details.
*/
protected ShortcutInfo makeShortcut(String id, String title, ComponentName activity,
- Icon icon, Intent intent, int rank, @Nullable List<IntentFilter> chooserFilters,
- @Nullable List<ComponentName> chooserComponentNames) {
+ Icon icon, Intent intent, int rank) {
final ShortcutInfo.Builder b = new ShortcutInfo.Builder(mClientContext, id)
.setActivity(new ComponentName(mClientContext.getPackageName(), "main"))
.setShortLabel(title)
- .setRank(rank);
- if (intent != null) {
- b.setIntent(intent);
- }
- if (chooserFilters != null) {
- for (int i = 0; i < chooserFilters.size(); i++) {
- b.addChooserIntentFilter(chooserFilters.get(i), chooserComponentNames.get(i));
- }
- }
+ .setRank(rank)
+ .setIntent(intent);
if (icon != null) {
b.setIcon(icon);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index dd0871a..9861aa1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -17,7 +17,6 @@
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyStringOrNull;
-import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllChooser;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDisabled;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamic;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamicOrPinned;
@@ -58,7 +57,6 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -261,9 +259,7 @@
icon1,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
"key1", "val1", "nest", makeBundle("key", 123)),
- /* weight */ 10,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 10);
final ShortcutInfo si2 = makeShortcut(
"shortcut2",
@@ -271,18 +267,14 @@
/* activity */ null,
icon2,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
- /* weight */ 12,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 12);
final ShortcutInfo si3 = makeShortcut(
"shortcut3",
"Title 3",
/* activity */ null,
icon3,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
- /* weight */ 13,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 13);
assertTrue(mManager.setDynamicShortcuts(list(si1, si2, si3)));
assertShortcutIds(assertAllNotKeyFieldsOnly(
@@ -993,10 +985,8 @@
makeShortcut("s2"),
makeShortcut("s3"),
makeShortcut("s4"),
- makeShortcut("s5"),
- makeChooserShortcut("s6", 2, true),
- makeChooserShortcut("s7", 2, true),
- makeChooserShortcut("s8", 1, true))));
+ makeShortcut("s5")
+ )));
});
runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
assertTrue(mManager.setDynamicShortcuts(list(
@@ -1004,13 +994,11 @@
makeShortcut("s2"),
makeShortcut("s3"),
makeShortcut("s4"),
- makeShortcut("s5"),
- makeChooserShortcut("s6", 2, true),
- makeChooserShortcut("s7", 2, true),
- makeChooserShortcut("s8", 1, true))));
+ makeShortcut("s5")
+ )));
});
runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3", "s6"),
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s3"),
getCallingUser());
mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s4", "s5"),
getCallingUser());
@@ -1023,20 +1011,19 @@
mManager.removeDynamicShortcuts(list("s1"));
mManager.removeDynamicShortcuts(list("s3"));
mManager.removeDynamicShortcuts(list("s5"));
- mManager.removeDynamicShortcuts(list("s7"));
});
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
- "s3", "s4", "s5", "s6", "s7", "s8");
+ "s3", "s4", "s5");
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
- "s2", "s3", "s6");
+ "s2", "s3");
});
runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
- "s2", "s4", "s6", "s8");
+ "s2", "s4");
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
"s4", "s5");
@@ -1073,10 +1060,10 @@
runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
- "s3", "s4", "s5", "s6", "s7", "s8");
+ "s3", "s4", "s5");
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
- "s2", "s3", "s6");
+ "s2", "s3");
ShortcutInfo s = getCallerShortcut("s2");
assertTrue(s.hasIconResource());
@@ -1092,7 +1079,7 @@
runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> {
assertShortcutIds(assertAllDynamic(
mManager.getDynamicShortcuts()),
- "s2", "s4", "s6", "s8");
+ "s2", "s4");
assertShortcutIds(assertAllPinned(
mManager.getPinnedShortcuts()),
"s4", "s5");
@@ -1189,46 +1176,7 @@
});
}
- public void testUpdateShortcuts_chooser() {
- runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"),
- makeChooserShortcut("s2", 2, false),
- makeChooserShortcut("s3", 2, false)
- )));
-
- assertFalse(getCallerShortcut("s1").isChooser());
- assertTrue(getCallerShortcut("s2").isChooser());
- assertTrue(getCallerShortcut("s3").isChooser());
-
- ShortcutInfo s = getCallerShortcut("s1");
- assertNull(s.getChooserIntentFilters());
- assertNull(s.getChooserComponentNames());
-
- assertTrue(getCallerShortcut("s1").isDynamic());
- assertFalse(getCallerShortcut("s2").isDynamic());
- assertFalse(getCallerShortcut("s3").isDynamic());
-
-
- // Replace 2 with a chooser shortcut
- mManager.updateShortcuts(list(makeChooserShortcut("s1", 2, true)));
-
- s = getCallerShortcut("s1");
- assertEquals(2, s.getChooserIntentFilters().length);
- assertEquals(2, s.getChooserComponentNames().length);
-
- assertShortcutIds(assertAllChooser(
- mManager.getDynamicShortcuts()),
- "s1", "s2", "s3");
-
- assertTrue(getCallerShortcut("s1").isDynamic());
- assertFalse(getCallerShortcut("s2").isDynamic());
- assertFalse(getCallerShortcut("s3").isDynamic());
- });
- }
-
-
- // === Test for launcher side APIs ===
+ // === Test for launcher side APIs ===
public void testGetShortcuts() {
@@ -1539,17 +1487,15 @@
/* icon =*/ null,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
"key1", "val1", "nest", makeBundle("key", 123)),
- /* weight */ 10, /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 10);
final ShortcutInfo s1_2 = makeShortcut(
- "s2", "Title 2",
+ "s2",
+ "Title 2",
/* activity */ null,
/* icon =*/ null,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
- /* weight */ 12,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 12);
assertTrue(mManager.setDynamicShortcuts(list(s1_1, s1_2)));
dumpsysOnLogcat();
@@ -1562,9 +1508,7 @@
/* icon =*/ null,
makeIntent(Intent.ACTION_ANSWER, ShortcutActivity2.class,
"key1", "val1", "nest", makeBundle("key", 123)),
- /* weight */ 10,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 10);
assertTrue(mManager.setDynamicShortcuts(list(s2_1)));
dumpsysOnLogcat();
@@ -2733,12 +2677,10 @@
final ShortcutInfo s1_2 = makeShortcut(
"s2",
"Title 2",
- /* activity */ null,
- /* icon =*/ null,
+ /* activity */ null,
+ /* icon =*/ null,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
- /* rank */ 12,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* rank */ 12);
final ShortcutInfo s1_3 = makeShortcut("s3");
@@ -2753,9 +2695,7 @@
/* icon =*/ null,
makeIntent(Intent.ACTION_ANSWER, ShortcutActivity.class,
"key1", "val1", "nest", makeBundle("key", 123)),
- /* weight */ 10,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 10);
assertTrue(mManager.setDynamicShortcuts(list(s2_1)));
});
@@ -3175,9 +3115,7 @@
icon1,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
"key1", "val1", "nest", makeBundle("key", 123)),
- /* weight */ 10,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 10);
final ShortcutInfo si2 = makeShortcut(
"s2",
@@ -3185,9 +3123,7 @@
/* activity */ null,
icon2,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
- /* weight */ 12,
- /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 12);
assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
@@ -3205,8 +3141,8 @@
makeComponent(ShortcutActivity.class),
icon1,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
- "key1", "val1", "nest", makeBundle("key", 123)), /* weight */ 10,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null);
+ "key1", "val1", "nest", makeBundle("key", 123)),
+ /* weight */ 10);
final ShortcutInfo si2 = makeShortcut(
"s2",
@@ -3214,8 +3150,7 @@
/* activity */ null,
icon2,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
- /* weight */ 12, /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 12);
assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
@@ -3237,8 +3172,7 @@
icon1,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class,
"key1", "val1", "nest", makeBundle("key", 123)),
- /* weight */ 10, /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 10);
final ShortcutInfo si2 = makeShortcut(
"s2",
@@ -3246,8 +3180,7 @@
/* activity */ null,
icon2,
makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class),
- /* weight */ 12, /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null);
+ /* weight */ 12);
assertTrue(mManager.setDynamicShortcuts(list(si1, si2)));
@@ -6884,12 +6817,10 @@
mManager.setDynamicShortcuts(list(
makeShortcut("ms1", "title1",
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
- /* icon */ null, new Intent("action1"), /* rank */ 0,
- /* chooserFilter=*/ null, /* chooserComponentNames=*/ null),
+ /* icon */ null, new Intent("action1"), /* rank */ 0),
makeShortcut("ms2", "title2",
new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
- /* icon */ null, new Intent("action1"), /* rank */ 0, /* chooserFilter=*/ null,
- /* chooserComponentNames=*/ null)));
+ /* icon */ null, new Intent("action1"), /* rank */ 0)));
});
runWithCaller(LAUNCHER_1, USER_0, () -> {
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index 7c5eb07..9880caa 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -34,7 +34,6 @@
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.pm.ShortcutInfo;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
@@ -93,6 +92,11 @@
assertExpectException(
RuntimeException.class,
+ "intents cannot contain null",
+ () -> new ShortcutInfo.Builder(getTestContext(), "id").setIntent(null));
+
+ assertExpectException(
+ RuntimeException.class,
"action must be set",
() -> new ShortcutInfo.Builder(getTestContext(), "id").setIntent(new Intent()));
@@ -137,19 +141,6 @@
"disabledMessage cannot be empty",
() -> new ShortcutInfo.Builder(getTestContext(), "id").setDisabledMessage(""));
-
- assertExpectException(
- RuntimeException.class,
- "component name cannot be null",
- () -> new ShortcutInfo.Builder(getTestContext(), "id")
- .addChooserIntentFilter(new IntentFilter(Intent.ACTION_SEND), null));
-
- assertExpectException(
- RuntimeException.class,
- "intent filter cannot be null",
- () -> new ShortcutInfo.Builder(getTestContext(), "id")
- .addChooserIntentFilter(null, new ComponentName("xxx", "s")));
-
assertExpectException(NullPointerException.class, "action must be set",
() -> new ShortcutInfo.Builder(getTestContext(), "id").setIntent(new Intent()));
@@ -248,10 +239,6 @@
PersistableBundle pb = new PersistableBundle();
pb.putInt("k", 1);
- IntentFilter chooserFilter = new IntentFilter();
- chooserFilter.addAction(Intent.ACTION_VIEW);
- PersistableBundle pb2 = new PersistableBundle();
- pb2.putInt("l", 1);
si = new ShortcutInfo.Builder(getTestContext())
.setId("id")
@@ -264,8 +251,6 @@
.setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
.setRank(123)
.setExtras(pb)
- .addChooserIntentFilter(chooserFilter, new ComponentName("a", "b"))
- .setChooserExtras(pb2)
.build();
si.addFlags(ShortcutInfo.FLAG_PINNED);
si.setBitmapPath("abc");
@@ -296,12 +281,6 @@
assertEquals(null, si.getTextResName());
assertEquals(0, si.getDisabledMessageResourceId());
assertEquals(null, si.getDisabledMessageResName());
-
- assertEquals(1, si.getChooserIntentFilters().length);
- assertEquals(Intent.ACTION_VIEW, si.getChooserIntentFilters()[0].getAction(0));
- assertEquals(1, si.getChooserComponentNames().length);
- assertEquals(new ComponentName("a", "b"), si.getChooserComponentNames()[0]);
- assertEquals(1, si.getChooserExtras().getInt("l"));
}
public void testShortcutInfoParcel_resId() {
@@ -310,10 +289,6 @@
PersistableBundle pb = new PersistableBundle();
pb.putInt("k", 1);
- IntentFilter chooserFilter = new IntentFilter();
- chooserFilter.addAction(Intent.ACTION_VIEW);
- PersistableBundle pb2 = new PersistableBundle();
- pb2.putInt("l", 1);
si = new ShortcutInfo.Builder(getTestContext())
.setId("id")
@@ -326,8 +301,6 @@
.setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
.setRank(123)
.setExtras(pb)
- .addChooserIntentFilter(chooserFilter, new ComponentName("a", "b"))
- .setChooserExtras(pb2)
.build();
si.addFlags(ShortcutInfo.FLAG_PINNED);
si.setBitmapPath("abc");
@@ -364,11 +337,6 @@
PersistableBundle pb = new PersistableBundle();
pb.putInt("k", 1);
- IntentFilter chooserFilter = new IntentFilter();
- chooserFilter.addAction(Intent.ACTION_VIEW);
- PersistableBundle pb2 = new PersistableBundle();
- pb2.putInt("l", 1);
-
ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
.setId("id")
.setActivity(new ComponentName("a", "b"))
@@ -380,8 +348,6 @@
.setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
.setRank(123)
.setExtras(pb)
- .addChooserIntentFilter(chooserFilter, new ComponentName("a", "b"))
- .setChooserExtras(pb2)
.build();
sorig.addFlags(ShortcutInfo.FLAG_PINNED);
sorig.setBitmapPath("abc");
@@ -411,12 +377,6 @@
assertEquals(456, si.getIconResourceId());
assertEquals("string/r456", si.getIconResName());
- assertEquals(1, si.getChooserIntentFilters().length);
- assertEquals(Intent.ACTION_VIEW, si.getChooserIntentFilters()[0].getAction(0));
- assertEquals(1, si.getChooserComponentNames().length);
- assertEquals(new ComponentName("a", "b"), si.getChooserComponentNames()[0]);
- assertEquals(1, si.getChooserExtras().getInt("l"));
-
si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
assertEquals(mClientContext.getPackageName(), si.getPackage());
@@ -484,10 +444,6 @@
PersistableBundle pb = new PersistableBundle();
pb.putInt("k", 1);
- IntentFilter chooserFilter = new IntentFilter();
- chooserFilter.addAction(Intent.ACTION_VIEW);
- PersistableBundle pb2 = new PersistableBundle();
- pb2.putInt("l", 1);
ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
.setId("id")
.setActivity(new ComponentName("a", "b"))
@@ -499,8 +455,6 @@
.setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
.setRank(123)
.setExtras(pb)
- .addChooserIntentFilter(chooserFilter, new ComponentName("a", "b"))
- .setChooserExtras(pb2)
.build();
sorig.addFlags(ShortcutInfo.FLAG_PINNED);
sorig.setBitmapPath("abc");
@@ -533,12 +487,6 @@
assertEquals(456, si.getIconResourceId());
assertEquals("string/r456", si.getIconResName());
- assertEquals(1, si.getChooserIntentFilters().length);
- assertEquals(Intent.ACTION_VIEW, si.getChooserIntentFilters()[0].getAction(0));
- assertEquals(1, si.getChooserComponentNames().length);
- assertEquals(new ComponentName("a", "b"), si.getChooserComponentNames()[0]);
- assertEquals(1, si.getChooserExtras().getInt("l"));
-
si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
assertEquals(mClientContext.getPackageName(), si.getPackage());
@@ -654,10 +602,6 @@
public void testShortcutInfoCopyNonNullFieldsFrom() throws InterruptedException {
PersistableBundle pb = new PersistableBundle();
pb.putInt("k", 1);
- IntentFilter chooserFilter = new IntentFilter();
- chooserFilter.addAction(Intent.ACTION_VIEW);
- PersistableBundle pb2 = new PersistableBundle();
- pb2.putInt("l", 1);
ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
.setId("id")
.setActivity(new ComponentName("a", "b"))
@@ -769,12 +713,12 @@
assertEquals(999, si.getRank());
- PersistableBundle pb3 = new PersistableBundle();
- pb3.putInt("x", 99);
+ PersistableBundle pb2 = new PersistableBundle();
+ pb2.putInt("x", 99);
si = sorig.clone(/* flags=*/ 0);
si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setExtras(pb3).build());
+ .setExtras(pb2).build());
assertEquals("text", si.getText());
assertEquals(99, si.getExtras().getInt("x"));
}
@@ -2096,16 +2040,6 @@
assertEquals(expected, dumpCheckin());
}
- public void testDumpsysNoPermission() {
- assertExpectException(SecurityException.class, "android.permission.DUMP",
- () -> mService.dump(null, new PrintWriter(new StringWriter()), null));
-
- // System can call it without the permission.
- runWithSystemUid(() -> {
- mService.dump(null, new PrintWriter(new StringWriter()), null);
- });
- }
-
/**
* Make sure the legacy file format that only supported a single intent per shortcut
* can still be read.
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
new file mode 100644
index 0000000..f68e06a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 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
+ */
+
+package com.android.server.wm;
+
+import android.app.ActivityManager;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Debug;
+import android.view.DisplayInfo;
+import org.junit.Test;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Test class to exercise logic related to {@link android.content.res.Configuration#appBounds}.
+ *
+ * Build/Install/Run:
+ * bit FrameworksServicesTests:com.android.server.wm.AppBoundsTests
+ */
+@SmallTest
+@Presubmit
+@org.junit.runner.RunWith(AndroidJUnit4.class)
+public class AppBoundsTests extends WindowTestsBase {
+ private Rect mParentBounds;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/);
+ }
+
+ /**
+ * Ensures the configuration app bounds at the root level match the app dimensions.
+ */
+ @Test
+ public void testRootConfigurationBounds() throws Exception {
+ final DisplayInfo info = sDisplayContent.getDisplayInfo();
+ info.appWidth = 1024;
+ info.appHeight = 768;
+
+ final Configuration config = sWm.computeNewConfiguration(sDisplayContent.getDisplayId());
+ // The bounds should always be positioned in the top left.
+ assertEquals(config.appBounds.left, 0);
+ assertEquals(config.appBounds.top, 0);
+
+ // The bounds should equal the defined app width and height
+ assertEquals(config.appBounds.width(), info.appWidth);
+ assertEquals(config.appBounds.height(), info.appHeight);
+ }
+
+ /**
+ * Ensures that bounds are clipped to their parent.
+ */
+ @Test
+ public void testBoundsClipping() throws Exception {
+ final Rect shiftedBounds = new Rect(mParentBounds);
+ shiftedBounds.offset(10, 10);
+ final Rect expectedBounds = new Rect(mParentBounds);
+ expectedBounds.intersect(shiftedBounds);
+ testStackBoundsConfiguration(null /*stackId*/, mParentBounds, shiftedBounds,
+ expectedBounds);
+ }
+
+ /**
+ * Ensures that empty bounds are not propagated to the configuration.
+ */
+ @Test
+ public void testEmptyBounds() throws Exception {
+ final Rect emptyBounds = new Rect();
+ testStackBoundsConfiguration(null /*stackId*/, mParentBounds, emptyBounds,
+ null /*ExpectedBounds*/);
+ }
+
+ /**
+ * Ensures that bounds on freeform stacks are not clipped.
+ */
+ @Test
+ public void testFreeFormBounds() throws Exception {
+ final Rect freeFormBounds = new Rect(mParentBounds);
+ freeFormBounds.offset(10, 10);
+ testStackBoundsConfiguration(ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID,
+ mParentBounds, freeFormBounds, freeFormBounds);
+ }
+
+ /**
+ * Ensures that fully contained bounds are not clipped.
+ */
+ @Test
+ public void testContainedBounds() throws Exception {
+ final Rect insetBounds = new Rect(mParentBounds);
+ insetBounds.inset(5, 5, 5, 5);
+ testStackBoundsConfiguration(null /*stackId*/, mParentBounds, insetBounds, insetBounds);
+ }
+
+ /**
+ * Ensures that full screen free form bounds are clipped
+ */
+ @Test
+ public void testFullScreenFreeFormBounds() throws Exception {
+ final Rect fullScreenBounds = new Rect(0, 0, sDisplayInfo.logicalWidth,
+ sDisplayInfo.logicalHeight);
+ testStackBoundsConfiguration(null /*stackId*/, mParentBounds, fullScreenBounds,
+ mParentBounds);
+ }
+
+
+ private void testStackBoundsConfiguration(Integer stackId, Rect parentBounds, Rect bounds,
+ Rect expectedConfigBounds) {
+ final StackWindowController stackController = stackId != null ?
+ createStackControllerOnStackOnDisplay(stackId, sDisplayContent)
+ : createStackControllerOnDisplay(sDisplayContent);
+
+ final Configuration parentConfig = sDisplayContent.getConfiguration();
+ parentConfig.setAppBounds(parentBounds);
+
+ final Configuration config = new Configuration();
+ stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/,
+ new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/,
+ false /*overrideHeight*/, sDisplayInfo.logicalDensityDpi, config, parentConfig);
+ // Assert that both expected and actual are null or are equal to each other
+
+ assertTrue((expectedConfigBounds == null && config.appBounds == null)
+ || expectedConfigBounds.equals(config.appBounds));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 1729cee..e3ccd6e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -213,10 +213,10 @@
*/
@Test
public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
- final Configuration currentOverrideConfig = sDisplayContent.getOverrideConfiguration();
+ final Configuration currentConfig = sDisplayContent.getConfiguration();
// Create new, slightly changed override configuration and apply it to the display.
- final Configuration newOverrideConfig = new Configuration(currentOverrideConfig);
+ final Configuration newOverrideConfig = new Configuration(currentConfig);
newOverrideConfig.densityDpi += 120;
newOverrideConfig.fontScale += 0.3;
@@ -228,10 +228,10 @@
assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
// Return back to original values.
- sWm.setNewDisplayOverrideConfiguration(currentOverrideConfig, DEFAULT_DISPLAY);
+ sWm.setNewDisplayOverrideConfiguration(currentConfig, DEFAULT_DISPLAY);
globalConfig = sWm.mRoot.getConfiguration();
- assertEquals(currentOverrideConfig.densityDpi, globalConfig.densityDpi);
- assertEquals(currentOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
+ assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
+ assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 0b72a21..fbeda0a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -23,6 +23,7 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doAnswer;
+import android.content.pm.ActivityInfo;
import android.os.PowerSaveState;
import org.mockito.invocation.InvocationOnMock;
@@ -449,9 +450,8 @@
}
@Override
- public boolean rotationHasCompatibleMetricsLw(int orientation,
- int rotation) {
- return false;
+ public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
+ return true;
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 1b1984d..2e6eac0 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -250,37 +250,57 @@
@Test
public void testLayoutNonfullscreenTask() {
- final Rect taskBounds = new Rect(300, 300, 700, 700);
+ final DisplayInfo displayInfo = sWm.getDefaultDisplayContentLocked().getDisplayInfo();
+ final int logicalWidth = displayInfo.logicalWidth;
+ final int logicalHeight = displayInfo.logicalHeight;
+
+ final int taskLeft = logicalWidth / 4;
+ final int taskTop = logicalHeight / 4;
+ final int taskRight = logicalWidth / 4 * 3;
+ final int taskBottom = logicalHeight / 4 * 3;
+ final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
TaskWithBounds task = new TaskWithBounds(taskBounds);
task.mFullscreenForTest = false;
WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
- final Rect pf = new Rect(0, 0, 1000, 1000);
+ final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, null);
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
- assertRect(w.mFrame, 300, 300, 700, 700);
- assertRect(w.getContentFrameLw(), 300, 300, 700, 700);
+ assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+ assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
assertRect(w.mContentInsets, 0, 0, 0, 0);
- pf.set(0, 0, 1000, 1000);
+ pf.set(0, 0, logicalWidth, logicalHeight);
// We still produce insets against the containing frame the same way.
- final Rect cf = new Rect(0, 0, 500, 500);
+ final int cfRight = logicalWidth / 2;
+ final int cfBottom = logicalHeight / 2;
+ final Rect cf = new Rect(0, 0, cfRight, cfBottom);
w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null);
- assertRect(w.mFrame, 300, 300, 700, 700);
- assertRect(w.getContentFrameLw(), 300, 300, 500, 500);
- assertRect(w.mContentInsets, 0, 0, 200, 200);
+ assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+ int contentInsetRight = taskRight - cfRight;
+ int contentInsetBottom = taskBottom - cfBottom;
+ assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
+ assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
+ taskBottom - contentInsetBottom);
- pf.set(0, 0, 1000, 1000);
+ pf.set(0, 0, logicalWidth, logicalHeight);
// However if we set temp inset bounds, the insets will be computed
// as if our window was laid out there, but it will be laid out according to
// the task bounds.
- task.mInsetBounds.set(200, 200, 600, 600);
+ final int insetLeft = logicalWidth / 5;
+ final int insetTop = logicalHeight / 5;
+ final int insetRight = insetLeft + (taskRight - taskLeft);
+ final int insetBottom = insetTop + (taskBottom - taskTop);
+ task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
w.computeFrameLw(pf, pf, pf, cf, cf, pf, cf, null);
- assertRect(w.mFrame, 300, 300, 700, 700);
- assertRect(w.getContentFrameLw(), 300, 300, 600, 600);
- assertRect(w.mContentInsets, 0, 0, 100, 100);
+ assertRect(w.mFrame, taskLeft, taskTop, taskRight, taskBottom);
+ contentInsetRight = insetRight - cfRight;
+ contentInsetBottom = insetBottom - cfBottom;
+ assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
+ assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
+ taskBottom - contentInsetBottom);
}
@Test
@@ -289,13 +309,16 @@
new TaskWithBounds(null), FILL_PARENT, FILL_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
- final Rect pf = new Rect(0, 0, 1000, 1000);
+ final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
+ final int logicalWidth = displayInfo.logicalWidth;
+ final int logicalHeight = displayInfo.logicalHeight;
+ final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
final Rect df = pf;
final Rect of = df;
final Rect cf = new Rect(pf);
// Produce some insets
- cf.top += 50;
- cf.bottom -= 100;
+ cf.top += displayInfo.logicalWidth / 10;
+ cf.bottom -= displayInfo.logicalWidth / 5;
final Rect vf = cf;
final Rect sf = vf;
// We use a decor content frame with insets to produce cropping.
@@ -308,35 +331,34 @@
// If we were above system decor we wouldnt' get any cropping though
w.mLayer = sWm.mSystemDecorLayer + 1;
w.calculatePolicyCrop(policyCrop);
- assertRect(policyCrop, 0, 0, 1000, 1000);
+ assertRect(policyCrop, 0, 0, logicalWidth, logicalHeight);
w.mLayer = 1;
dcf.setEmpty();
// Likewise with no decor frame we would get no crop
w.computeFrameLw(pf, df, of, cf, vf, dcf, sf, null);
w.calculatePolicyCrop(policyCrop);
- assertRect(policyCrop, 0, 0, 1000, 1000);
+ assertRect(policyCrop, 0, 0, logicalWidth, logicalHeight);
// Now we set up a window which doesn't fill the entire decor frame.
// Normally it would be cropped to it's frame but in the case of docked resizing
// we need to account for the fact the windows surface will be made
// fullscreen and thus also make the crop fullscreen.
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
- w.mAttrs.width = 500;
- w.mAttrs.height = 500;
- w.mRequestedWidth = 500;
- w.mRequestedHeight = 500;
+ w.mAttrs.width = logicalWidth / 2;
+ w.mAttrs.height = logicalHeight / 2;
+ w.mRequestedWidth = logicalWidth / 2;
+ w.mRequestedHeight = logicalHeight / 2;
w.computeFrameLw(pf, pf, pf, pf, pf, pf, pf, pf);
w.calculatePolicyCrop(policyCrop);
// Normally the crop is shrunk from the decor frame
// to the computed window frame.
- assertRect(policyCrop, 0, 0, 500, 500);
+ assertRect(policyCrop, 0, 0, logicalWidth / 2, logicalHeight / 2);
w.mDockedResizingForTest = true;
w.calculatePolicyCrop(policyCrop);
// But if we are docked resizing it won't be, however we will still be
// shrunk to the decor frame and the display.
- final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
assertRect(policyCrop, 0, 0,
Math.min(pf.width(), displayInfo.logicalWidth),
Math.min(pf.height(), displayInfo.logicalHeight));
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index c342933..922f08d 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -512,13 +512,6 @@
return actualShortcuts;
}
- public static List<ShortcutInfo> assertAllChooser(List<ShortcutInfo> actualShortcuts) {
- for (ShortcutInfo s : actualShortcuts) {
- assertTrue("ID " + s.getId(), s.isChooser());
- }
- return actualShortcuts;
- }
-
public static List<ShortcutInfo> assertAllPinned(List<ShortcutInfo> actualShortcuts) {
for (ShortcutInfo s : actualShortcuts) {
assertTrue("ID " + s.getId(), s.isPinned());
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 68c4c56..3f39e4f 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -398,7 +398,7 @@
super(looper);
// TODO: Handle all private volumes.
mStats = new StatFs(Environment.getDataDirectory().getAbsolutePath());
- mPreviousBytes = mStats.getFreeBytes();
+ mPreviousBytes = mStats.getAvailableBytes();
mMinimumThresholdBytes = mStats.getTotalBytes() * MINIMUM_CHANGE_DELTA;
}
@@ -413,9 +413,9 @@
switch (msg.what) {
case MSG_CHECK_STORAGE_DELTA: {
- long bytesDelta = Math.abs(mPreviousBytes - mStats.getFreeBytes());
+ long bytesDelta = Math.abs(mPreviousBytes - mStats.getAvailableBytes());
if (bytesDelta > mMinimumThresholdBytes) {
- mPreviousBytes = mStats.getFreeBytes();
+ mPreviousBytes = mStats.getAvailableBytes();
recalculateQuotas(getInitializedStrategy());
}
sendEmptyMessageDelayed(MSG_CHECK_STORAGE_DELTA, DELAY_IN_MILLIS);
@@ -434,7 +434,7 @@
// If errors occurred getting the quotas from disk, let's re-calc them.
if (mPreviousBytes < 0) {
- mPreviousBytes = mStats.getFreeBytes();
+ mPreviousBytes = mStats.getAvailableBytes();
recalculateQuotas(strategy);
}
sendEmptyMessageDelayed(MSG_CHECK_STORAGE_DELTA, DELAY_IN_MILLIS);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 7be2b0f..4ba457d 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -78,6 +78,7 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.SystemService;
@@ -1465,13 +1466,7 @@
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump UsageStats from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
- + " without permission " + android.Manifest.permission.DUMP);
- return;
- }
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
UsageStatsService.this.dump(args, pw);
}
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 7b8ebd4..01e36f5 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -1039,18 +1039,34 @@
* Start the appropriate package when an device/accessory got attached.
*
* @param intent The intent to start the package
- * @param matches The available resolutions of the intent
+ * @param rawMatches The available resolutions of the intent
* @param defaultActivity The default activity for the device (if set)
* @param device The device if a device was attached
* @param accessory The accessory if a device was attached
*/
- private void resolveActivity(@NonNull Intent intent, @NonNull ArrayList<ResolveInfo> matches,
+ private void resolveActivity(@NonNull Intent intent, @NonNull ArrayList<ResolveInfo> rawMatches,
@Nullable ActivityInfo defaultActivity, @Nullable UsbDevice device,
@Nullable UsbAccessory accessory) {
- int count = matches.size();
+ final int numRawMatches = rawMatches.size();
+
+ // The raw matches contain the activities that can be started but also the intents to switch
+ // between the profiles
+ int numParentActivityMatches = 0;
+ int numNonParentActivityMatches = 0;
+ for (int i = 0; i < numRawMatches; i++) {
+ final ResolveInfo rawMatch = rawMatches.get(i);
+ if (!rawMatch.getComponentInfo().name.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
+ if (UserHandle.getUserHandleForUid(
+ rawMatch.activityInfo.applicationInfo.uid).equals(mParentUser)) {
+ numParentActivityMatches++;
+ } else {
+ numNonParentActivityMatches++;
+ }
+ }
+ }
// don't show the resolver activity if there are no choices available
- if (count == 0) {
+ if (numParentActivityMatches + numNonParentActivityMatches == 0) {
if (accessory != null) {
String uri = accessory.getUri();
if (uri != null && uri.length() > 0) {
@@ -1073,6 +1089,21 @@
return;
}
+ // If only one profile has activity matches, we need to remove all switch intents
+ ArrayList<ResolveInfo> matches;
+ if (numParentActivityMatches == 0 || numNonParentActivityMatches == 0) {
+ matches = new ArrayList<>(numParentActivityMatches + numNonParentActivityMatches);
+
+ for (int i = 0; i < numRawMatches; i++) {
+ ResolveInfo rawMatch = rawMatches.get(i);
+ if (!rawMatch.getComponentInfo().name.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
+ matches.add(rawMatch);
+ }
+ }
+ } else {
+ matches = rawMatches;
+ }
+
if (defaultActivity != null) {
UsbUserSettingsManager defaultRIUserSettings = mSettingsManager.getSettingsForUser(
UserHandle.getUserId(defaultActivity.applicationInfo.uid));
@@ -1101,7 +1132,7 @@
resolverIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
UserHandle user;
- if (count == 1) {
+ if (matches.size() == 1) {
ResolveInfo rInfo = matches.get(0);
// start UsbConfirmActivity if there is only one choice
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index a87ac9e..61e1e8f 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -40,6 +40,7 @@
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
@@ -480,7 +481,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
final long ident = Binder.clearCallingIdentity();
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 03a7db7..dc4b41c 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -62,6 +62,7 @@
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.DumpUtils;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.UiThread;
@@ -1117,13 +1118,7 @@
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump voiceinteraction from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
+ if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
synchronized (this) {
pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)");
pw.println(" mEnableService: " + mEnableService);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 201f3ad..81f6600 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1178,6 +1178,7 @@
public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) {
if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
+ intent.putExtra(Intent.EXTRA_SUBSCRIPTION_INDEX, subId);
intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
//FIXME this is using phoneId and slotIndex interchangeably
//Eventually, this should be removed as it is not the slot id
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 26c9430..8357a2b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -877,19 +877,16 @@
/**
* USSD return code success.
- * @hide
*/
public static final int USSD_RETURN_SUCCESS = 100;
/**
* USSD return code for failure case.
- * @hide
*/
public static final int USSD_RETURN_FAILURE = -1;
/**
* USSD return code for failure case.
- * @hide
*/
public static final int USSD_ERROR_SERVICE_UNAVAIL = -2;
@@ -2395,7 +2392,7 @@
* OR
* {@link android.Manifest.permission#READ_SMS}
* OR
- * {@link android.Manifest.permission#READ_PHONE_NUMBER}
+ * {@link android.Manifest.permission#READ_PHONE_NUMBERS}
* <p>
* The default SMS app can also use this.
*/
@@ -2412,7 +2409,7 @@
* OR
* {@link android.Manifest.permission#READ_SMS}
* OR
- * {@link android.Manifest.permission#READ_PHONE_NUMBER}
+ * {@link android.Manifest.permission#READ_PHONE_NUMBERS}
* <p>
* The default SMS app can also use this.
*
@@ -5113,16 +5110,32 @@
return new int[0];
}
- public static abstract class OnReceiveUssdResponseCallback {
+ /* The caller of {@link #sendUssdRequest(String, UssdResponseCallback, Handler} provides
+ * once the network returns a USSD message or if there is failure.
+ * Either {@link #onReceiveUssdResponse(TelephonyManager, String, CharSequence} or
+ * {@link #onReceiveUssdResponseFailed(TelephonyManager, String, int} will be called.
+ */
+ public static abstract class UssdResponseCallback {
/**
- ** Called when USSD has succeeded.
+ * Called when USSD has succeeded. The calling app can choose to either display the message
+ * or interpret the message.
+ * @param telephonyManager the TelephonyManager the callback is registered to.
+ * @param request the ussd code sent to the network.
+ * @param response the response from the network.
**/
- public void onReceiveUssdResponse(String request, CharSequence response) {};
+ public void onReceiveUssdResponse(final TelephonyManager telephonyManager,
+ String request, CharSequence response) {};
/**
- ** Called when USSD has failed.
+ * Called when USSD has failed.
+ * @param telephonyManager the TelephonyManager the callback is registered to
+ * @param request the ussd code.
+ * @param failureCode failure code, should be either of
+ * {@link TelephonyManager#USSD_RETURN_FAILURE} or
+ * {@link TelephonyManager#USSD_ERROR_SERVICE_UNAVAIL}.
**/
- public void onReceiveUssdResponseFailed(String request, int failureCode) {};
+ public void onReceiveUssdResponseFailed(final TelephonyManager telephonyManager,
+ String request, int failureCode) {};
}
/**
@@ -5134,13 +5147,14 @@
* {@link android.Manifest.permission#CALL_PHONE}
* @param ussdRequest the USSD command to be executed.
* @param callback called by the framework to inform the caller of the result of executing the
- * USSD request (see {@link OnReceiveUssdResponseCallback}).
+ * USSD request (see {@link UssdResponseCallback}).
* @param handler the {@link Handler} to run the request on.
*/
@RequiresPermission(android.Manifest.permission.CALL_PHONE)
public void sendUssdRequest(String ussdRequest,
- final OnReceiveUssdResponseCallback callback, Handler handler) {
- checkNotNull(callback, "OnReceiveUssdResponseCallback cannot be null.");
+ final UssdResponseCallback callback, Handler handler) {
+ checkNotNull(callback, "UssdResponseCallback cannot be null.");
+ final TelephonyManager telephonyManager = this;
ResultReceiver wrappedCallback = new ResultReceiver(handler) {
@Override
@@ -5150,10 +5164,11 @@
UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE);
if (resultCode == USSD_RETURN_SUCCESS) {
- callback.onReceiveUssdResponse(response.getUssdRequest(),
+ callback.onReceiveUssdResponse(telephonyManager, response.getUssdRequest(),
response.getReturnMessage());
} else {
- callback.onReceiveUssdResponseFailed(response.getUssdRequest(), resultCode);
+ callback.onReceiveUssdResponseFailed(telephonyManager,
+ response.getUssdRequest(), resultCode);
}
}
};
@@ -5172,11 +5187,13 @@
}
}
- /*
- * @return true, if the device is currently on a technology (e.g. UMTS or LTE) which can support
- * voice and data simultaneously. This can change based on location or network condition.
- */
- public boolean isConcurrentVoiceAndDataAllowed() {
+ /**
+ * Whether the device is currently on a technology (e.g. UMTS or LTE) which can support
+ * voice and data simultaneously. This can change based on location or network condition.
+ *
+ * @return {@code true} if simultaneous voice and data supported, and {@code false} otherwise.
+ */
+ public boolean isConcurrentVoiceAndDataSupported() {
try {
ITelephony telephony = getITelephony();
return (telephony == null ? false : telephony.isConcurrentVoiceAndDataAllowed(mSubId));
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index 73ee25a..b4c531e 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -334,9 +334,11 @@
* <ul>
* <li><em>subscription</em> - A int, the current default subscription.</li>
* </ul>
+ * @deprecated Use {@link Intent#ACTION_DEFAULT_SUBSCRIPTION_CHANGED}
*/
+ @Deprecated
public static final String ACTION_DEFAULT_SUBSCRIPTION_CHANGED
- = "android.intent.action.ACTION_DEFAULT_SUBSCRIPTION_CHANGED";
+ = Intent.ACTION_DEFAULT_SUBSCRIPTION_CHANGED;
/**
* Broadcast Action: The default data subscription has changed. This has the following
@@ -364,9 +366,11 @@
* <ul>
* <li><em>subscription</em> - A int, the current sms default subscription.</li>
* </ul>
+ * @deprecated Use {@link Intent#ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED}
*/
+ @Deprecated
public static final String ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED
- = "android.intent.action.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED";
+ = Intent.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED;
/*
* Broadcast Action: An attempt to set phone radio type and access technology has changed.
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
index 00dddee..8739b7f 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTestBase.java
@@ -311,7 +311,6 @@
sFrameworkRepo = null;
sProjectResources = null;
sLogger = null;
- sBridge.dispose();
sBridge = null;
TestUtils.gc();
@@ -329,7 +328,6 @@
RenderSession session = sBridge.createSession(params);
try {
-
if (frameTimeNanos != -1) {
session.setElapsedFrameTimeNanos(frameTimeNanos);
}
@@ -338,11 +336,13 @@
getLogger().error(session.getResult().getException(),
session.getResult().getErrorMessage());
}
- // Render the session with a timeout of 50s.
- Result renderResult = session.render(50000);
- if (!renderResult.isSuccess()) {
- getLogger().error(session.getResult().getException(),
- session.getResult().getErrorMessage());
+ else {
+ // Render the session with a timeout of 50s.
+ Result renderResult = session.render(50000);
+ if (!renderResult.isSuccess()) {
+ getLogger().error(session.getResult().getException(),
+ session.getResult().getErrorMessage());
+ }
}
return RenderResult.getFromSession(session);