Merge "Squashed merge of master-sim into master."
diff --git a/api/current.txt b/api/current.txt
index 5de72bf..b1a1936 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();
@@ -10327,12 +10333,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 +10888,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 +10903,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 +10916,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);
@@ -45995,7 +46001,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();
@@ -46007,6 +46012,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();
@@ -46015,6 +46021,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();
@@ -46022,7 +46029,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 c690ba4..0d1c907 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -183,7 +183,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";
@@ -3802,7 +3802,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);
@@ -3810,7 +3811,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();
@@ -4326,7 +4328,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";
@@ -4776,11 +4778,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();
@@ -4865,11 +4869,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();
@@ -9764,6 +9770,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";
@@ -10952,12 +10960,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
@@ -11601,9 +11609,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();
@@ -11616,7 +11624,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();
@@ -11629,11 +11637,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);
@@ -49490,7 +49498,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();
@@ -49502,6 +49509,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();
@@ -49510,6 +49518,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();
@@ -49517,7 +49526,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 913970b..7aedea0 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();
@@ -10363,12 +10369,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 +10928,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 +10943,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 +10956,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);
@@ -37521,6 +37527,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();
@@ -46372,7 +46379,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();
@@ -46388,6 +46394,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();
@@ -46396,6 +46403,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();
@@ -46403,7 +46411,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/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/content/Intent.java b/core/java/android/content/Intent.java
index 6a720fd..8f44fcd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1093,6 +1093,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 +1104,8 @@
* <p>Output: nothing.
* @hide
*/
+ @SystemApi
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
/**
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..912ce3d 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;
}
@@ -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/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/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/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/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c98de05..48a460d 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
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..344f3c8 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -181,10 +181,6 @@
<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" />
-
<!-- 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/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/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index f6e92dc..8630902 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -193,7 +193,9 @@
const float* vArray = (const float*)vertices->positions();
const float* tArray = (const float*)vertices->texCoords();
const int* cArray = (const int*)vertices->colors();
- mCanvas->drawVertices(vertices->mode(), floatCount, vArray, tArray, cArray,
+ // Can remove this cast after changing to SkVertices::VertexMode
+ SkCanvas::VertexMode vmode = static_cast<SkCanvas::VertexMode>(vertices->mode());
+ mCanvas->drawVertices(vmode, floatCount, vArray, tArray, cArray,
vertices->indices(), vertices->indexCount(), paint);
}
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 6b81f960..c811f11 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/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/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8b0665c..9ad945f 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;
@@ -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;
@@ -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 c27fa1b..7618144 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -11516,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...
@@ -12291,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();
@@ -19784,6 +19791,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/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/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/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 8227753..4e1166b 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -178,6 +178,7 @@
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;
@@ -213,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;
@@ -269,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";
@@ -420,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")
@@ -1055,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
@@ -1092,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);
}
}
}
@@ -1142,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);
@@ -1262,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
}
@@ -4125,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/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..0b40fc5 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -445,8 +445,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 +457,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 +909,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 9e275a8..5a54917 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -569,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);
@@ -1182,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 {
@@ -3037,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) {
@@ -4022,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;
@@ -4039,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))
@@ -5589,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 =
@@ -5624,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) {
@@ -5915,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) {
@@ -6081,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;
@@ -6150,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();
@@ -6784,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();
@@ -6964,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) {
@@ -7000,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,
@@ -7016,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) {
@@ -7035,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;
}
@@ -7046,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) {
@@ -7067,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) {
@@ -12402,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) {
@@ -12916,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) {
@@ -22241,7 +22349,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;
@@ -22305,7 +22413,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);
@@ -23149,10 +23257,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 9bf6895..0a0ef58 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;
@@ -1754,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);
@@ -1794,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.
@@ -1864,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) {
@@ -2020,7 +2009,7 @@
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
- ShortcutInfo::isDynamicOrChooser);
+ ShortcutInfo::isDynamic);
}
}
@@ -2213,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.
@@ -2393,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<>();
@@ -2415,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);
});
}
}
@@ -2430,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);
@@ -2455,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;
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/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/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 0f51c49..d0d23f8 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;
@@ -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..cd98654 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"));
}
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/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 02ee085..8357a2b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2392,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.
*/
@@ -2409,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.
*