Merge "Add null checks to WindowState.getStack() calls." into lmp-dev
diff --git a/Android.mk b/Android.mk
index 35d13d7..d0c8070 100644
--- a/Android.mk
+++ b/Android.mk
@@ -156,7 +156,7 @@
core/java/android/hardware/hdmi/IHdmiDeviceEventListener.aidl \
core/java/android/hardware/hdmi/IHdmiHotplugEventListener.aidl \
core/java/android/hardware/hdmi/IHdmiInputChangeListener.aidl \
- core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl \
+ core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl \
core/java/android/hardware/hdmi/IHdmiRecordListener.aidl \
core/java/android/hardware/hdmi/IHdmiSystemAudioModeChangeListener.aidl \
core/java/android/hardware/hdmi/IHdmiVendorCommandListener.aidl \
diff --git a/api/current.txt b/api/current.txt
index 48e34d7..96aac9b2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -588,6 +588,7 @@
field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
field public static final int fillAfter = 16843197; // 0x10101bd
+ field public static final int fillAlpha = 16843981; // 0x10104cd
field public static final int fillBefore = 16843196; // 0x10101bc
field public static final int fillColor = 16843806; // 0x101041e
field public static final int fillEnabled = 16843343; // 0x101024f
@@ -1203,6 +1204,7 @@
field public static final int streamType = 16843273; // 0x1010209
field public static final int stretchColumns = 16843081; // 0x1010149
field public static final int stretchMode = 16843030; // 0x1010116
+ field public static final int strokeAlpha = 16843980; // 0x10104cc
field public static final int strokeColor = 16843808; // 0x1010420
field public static final int strokeLineCap = 16843813; // 0x1010425
field public static final int strokeLineJoin = 16843814; // 0x1010426
@@ -1427,6 +1429,7 @@
field public static final int windowActionBar = 16843469; // 0x10102cd
field public static final int windowActionBarOverlay = 16843492; // 0x10102e4
field public static final int windowActionModeOverlay = 16843485; // 0x10102dd
+ field public static final int windowActivityTransitions = 16843982; // 0x10104ce
field public static final int windowAllowEnterTransitionOverlap = 16843836; // 0x101043c
field public static final int windowAllowReturnTransitionOverlap = 16843835; // 0x101043b
field public static final int windowAnimationStyle = 16842926; // 0x10100ae
@@ -2395,7 +2398,6 @@
field public static final int Widget_Holo_DropDownItem_Spinner = 16973995; // 0x10300ab
field public static final int Widget_Holo_EditText = 16973971; // 0x1030093
field public static final int Widget_Holo_ExpandableListView = 16973972; // 0x1030094
- field public static final int Widget_Holo_FastScroll = 16974341; // 0x1030205
field public static final int Widget_Holo_GridView = 16973973; // 0x1030095
field public static final int Widget_Holo_HorizontalScrollView = 16973988; // 0x10300a4
field public static final int Widget_Holo_ImageButton = 16973974; // 0x1030096
@@ -2416,7 +2418,6 @@
field public static final int Widget_Holo_Light_ActionMode_Inverse = 16974119; // 0x1030127
field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb
field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6
- field public static final int Widget_Holo_Light_Button_Borderless = 16974343; // 0x1030207
field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974107; // 0x103011b
field public static final int Widget_Holo_Light_Button_Inset = 16974008; // 0x10300b8
field public static final int Widget_Holo_Light_Button_Small = 16974007; // 0x10300b7
@@ -2430,7 +2431,6 @@
field public static final int Widget_Holo_Light_DropDownItem_Spinner = 16974041; // 0x10300d9
field public static final int Widget_Holo_Light_EditText = 16974014; // 0x10300be
field public static final int Widget_Holo_Light_ExpandableListView = 16974015; // 0x10300bf
- field public static final int Widget_Holo_Light_FastScroll = 16974344; // 0x1030208
field public static final int Widget_Holo_Light_GridView = 16974016; // 0x10300c0
field public static final int Widget_Holo_Light_HorizontalScrollView = 16974034; // 0x10300d2
field public static final int Widget_Holo_Light_ImageButton = 16974017; // 0x10300c1
@@ -2454,7 +2454,6 @@
field public static final int Widget_Holo_Light_ScrollView = 16974033; // 0x10300d1
field public static final int Widget_Holo_Light_SeekBar = 16974028; // 0x10300cc
field public static final int Widget_Holo_Light_Spinner = 16974035; // 0x10300d3
- field public static final int Widget_Holo_Light_StackView = 16974345; // 0x1030209
field public static final int Widget_Holo_Light_Tab = 16974052; // 0x10300e4
field public static final int Widget_Holo_Light_TabWidget = 16974037; // 0x10300d5
field public static final int Widget_Holo_Light_TextView = 16974010; // 0x10300ba
@@ -2478,7 +2477,6 @@
field public static final int Widget_Holo_ScrollView = 16973987; // 0x10300a3
field public static final int Widget_Holo_SeekBar = 16973982; // 0x103009e
field public static final int Widget_Holo_Spinner = 16973989; // 0x10300a5
- field public static final int Widget_Holo_StackView = 16974342; // 0x1030206
field public static final int Widget_Holo_Tab = 16974051; // 0x10300e3
field public static final int Widget_Holo_TabWidget = 16973991; // 0x10300a7
field public static final int Widget_Holo_TextView = 16973967; // 0x103008f
@@ -2552,6 +2550,7 @@
field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974504; // 0x10302a8
field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974505; // 0x10302a9
field public static final int Widget_Material_Light_CompoundButton_Star = 16974506; // 0x10302aa
+ field public static final int Widget_Material_Light_DatePicker = 16974578; // 0x10302f2
field public static final int Widget_Material_Light_DropDownItem = 16974507; // 0x10302ab
field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974508; // 0x10302ac
field public static final int Widget_Material_Light_EditText = 16974509; // 0x10302ad
@@ -2579,6 +2578,7 @@
field public static final int Widget_Material_Light_RatingBar_Indicator = 16974531; // 0x10302c3
field public static final int Widget_Material_Light_RatingBar_Small = 16974532; // 0x10302c4
field public static final int Widget_Material_Light_ScrollView = 16974533; // 0x10302c5
+ field public static final int Widget_Material_Light_SearchView = 16974575; // 0x10302ef
field public static final int Widget_Material_Light_SeekBar = 16974534; // 0x10302c6
field public static final int Widget_Material_Light_SegmentedButton = 16974535; // 0x10302c7
field public static final int Widget_Material_Light_Spinner = 16974537; // 0x10302c9
@@ -2588,6 +2588,7 @@
field public static final int Widget_Material_Light_TabWidget = 16974539; // 0x10302cb
field public static final int Widget_Material_Light_TextView = 16974540; // 0x10302cc
field public static final int Widget_Material_Light_TextView_SpinnerItem = 16974541; // 0x10302cd
+ field public static final int Widget_Material_Light_TimePicker = 16974577; // 0x10302f1
field public static final int Widget_Material_Light_WebTextView = 16974542; // 0x10302ce
field public static final int Widget_Material_Light_WebView = 16974543; // 0x10302cf
field public static final int Widget_Material_ListPopupWindow = 16974455; // 0x1030277
@@ -2606,6 +2607,7 @@
field public static final int Widget_Material_RatingBar_Indicator = 16974468; // 0x1030284
field public static final int Widget_Material_RatingBar_Small = 16974469; // 0x1030285
field public static final int Widget_Material_ScrollView = 16974470; // 0x1030286
+ field public static final int Widget_Material_SearchView = 16974574; // 0x10302ee
field public static final int Widget_Material_SeekBar = 16974471; // 0x1030287
field public static final int Widget_Material_SegmentedButton = 16974472; // 0x1030288
field public static final int Widget_Material_Spinner = 16974474; // 0x103028a
@@ -2615,6 +2617,7 @@
field public static final int Widget_Material_TabWidget = 16974476; // 0x103028c
field public static final int Widget_Material_TextView = 16974477; // 0x103028d
field public static final int Widget_Material_TextView_SpinnerItem = 16974478; // 0x103028e
+ field public static final int Widget_Material_TimePicker = 16974576; // 0x10302f0
field public static final int Widget_Material_Toolbar = 16974479; // 0x103028f
field public static final int Widget_Material_Toolbar_Button_Navigation = 16974480; // 0x1030290
field public static final int Widget_Material_WebTextView = 16974481; // 0x1030291
@@ -2641,7 +2644,12 @@
field public static final int Widget_Toolbar = 16974339; // 0x1030203
field public static final int Widget_Toolbar_Button_Navigation = 16974340; // 0x1030204
field public static final int Widget_WebView = 16973875; // 0x1030033
- field public static final int __removed = 16974559; // 0x10302df
+ field public static final int __removed1 = 16974559; // 0x10302df
+ field public static final int __removed3 = 16974341; // 0x1030205
+ field public static final int __removed4 = 16974342; // 0x1030206
+ field public static final int __removed5 = 16974343; // 0x1030207
+ field public static final int __removed6 = 16974344; // 0x1030208
+ field public static final int __removed7 = 16974345; // 0x1030209
field public static final int l_resource_pad1 = 16974336; // 0x1030200
field public static final int l_resource_pad10 = 16974327; // 0x10301f7
field public static final int l_resource_pad11 = 16974326; // 0x10301f6
@@ -5449,6 +5457,7 @@
method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
method public boolean installCaCert(android.content.ComponentName, byte[]);
+ method public boolean installKeyPair(android.content.ComponentName, java.security.PrivateKey, java.security.cert.Certificate, java.lang.String);
method public boolean isActivePasswordSufficient();
method public boolean isAdminActive(android.content.ComponentName);
method public boolean isApplicationHidden(android.content.ComponentName, java.lang.String);
@@ -5679,6 +5688,7 @@
method public int describeContents();
method public android.os.PersistableBundle getExtras();
method public int getJobId();
+ method public boolean isOverrideDeadlineExpired();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
}
@@ -6384,7 +6394,6 @@
method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
- method public void onConnectionCongested(android.bluetooth.BluetoothGatt, boolean);
method public void onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int);
method public void onDescriptorRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
method public void onDescriptorWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattDescriptor, int);
@@ -6484,7 +6493,6 @@
ctor public BluetoothGattServerCallback();
method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
- method public void onConnectionCongested(android.bluetooth.BluetoothDevice, boolean);
method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
method public void onDescriptorReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattDescriptor);
method public void onDescriptorWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattDescriptor, boolean, boolean, int, byte[]);
@@ -14075,29 +14083,6 @@
method public android.media.AudioAttributes.Builder setUsage(int);
}
- public class AudioDevice {
- field public static final int DEVICE_TYPE_AUX_LINE = 19; // 0x13
- field public static final int DEVICE_TYPE_BLUETOOTH_A2DP = 8; // 0x8
- field public static final int DEVICE_TYPE_BLUETOOTH_SCO = 7; // 0x7
- field public static final int DEVICE_TYPE_BUILTIN_EARPIECE = 1; // 0x1
- field public static final int DEVICE_TYPE_BUILTIN_MIC = 15; // 0xf
- field public static final int DEVICE_TYPE_BUILTIN_SPEAKER = 2; // 0x2
- field public static final int DEVICE_TYPE_DOCK = 13; // 0xd
- field public static final int DEVICE_TYPE_FM = 14; // 0xe
- field public static final int DEVICE_TYPE_FM_TUNER = 16; // 0x10
- field public static final int DEVICE_TYPE_HDMI = 9; // 0x9
- field public static final int DEVICE_TYPE_HDMI_ARC = 10; // 0xa
- field public static final int DEVICE_TYPE_LINE_ANALOG = 5; // 0x5
- field public static final int DEVICE_TYPE_LINE_DIGITAL = 6; // 0x6
- field public static final int DEVICE_TYPE_TELEPHONY = 18; // 0x12
- field public static final int DEVICE_TYPE_TV_TUNER = 17; // 0x11
- field public static final int DEVICE_TYPE_UNKNOWN = 0; // 0x0
- field public static final int DEVICE_TYPE_USB_ACCESSORY = 12; // 0xc
- field public static final int DEVICE_TYPE_USB_DEVICE = 11; // 0xb
- field public static final int DEVICE_TYPE_WIRED_HEADPHONES = 4; // 0x4
- field public static final int DEVICE_TYPE_WIRED_HEADSET = 3; // 0x3
- }
-
public class AudioFormat {
method public int getChannelMask();
method public int getEncoding();
@@ -16190,12 +16175,16 @@
method public short getRoundedStrength() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
method public boolean getSpeakerAngles(int, int, int[]) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
method public boolean getStrengthSupported();
- method public int getVirtualizationMode() throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
+ method public int getVirtualizationMode() throws java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
method public void setParameterListener(android.media.audiofx.Virtualizer.OnParameterChangeListener);
method public void setProperties(android.media.audiofx.Virtualizer.Settings) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
method public void setStrength(short) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.UnsupportedOperationException;
field public static final int PARAM_STRENGTH = 1; // 0x1
field public static final int PARAM_STRENGTH_SUPPORTED = 0; // 0x0
+ field public static final int VIRTUALIZATION_MODE_AUTO = 1; // 0x1
+ field public static final int VIRTUALIZATION_MODE_BINAURAL = 2; // 0x2
+ field public static final int VIRTUALIZATION_MODE_OFF = 0; // 0x0
+ field public static final int VIRTUALIZATION_MODE_TRANSAURAL = 3; // 0x3
}
public static abstract interface Virtualizer.OnParameterChangeListener {
@@ -16358,10 +16347,10 @@
package android.media.projection {
public final class MediaProjection {
- method public void addCallback(android.media.projection.MediaProjection.Callback, android.os.Handler);
method public android.hardware.display.VirtualDisplay createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay.Callback, android.os.Handler);
- method public void removeCallback(android.media.projection.MediaProjection.Callback);
+ method public void registerCallback(android.media.projection.MediaProjection.Callback, android.os.Handler);
method public void stop();
+ method public void unregisterCallback(android.media.projection.MediaProjection.Callback);
}
public static abstract class MediaProjection.Callback {
@@ -16370,8 +16359,8 @@
}
public final class MediaProjectionManager {
+ method public android.content.Intent createScreenCaptureIntent();
method public android.media.projection.MediaProjection getMediaProjection(int, android.content.Intent);
- method public android.content.Intent getScreenCaptureIntent();
}
}
@@ -17550,14 +17539,12 @@
public class VpnService extends android.app.Service {
ctor public VpnService();
- method public boolean addAddress(java.net.InetAddress, int);
method public android.os.IBinder onBind(android.content.Intent);
method public void onRevoke();
method public static android.content.Intent prepare(android.content.Context);
method public boolean protect(int);
method public boolean protect(java.net.Socket);
method public boolean protect(java.net.DatagramSocket);
- method public boolean removeAddress(java.net.InetAddress, int);
field public static final java.lang.String SERVICE_INTERFACE = "android.net.VpnService";
}
@@ -22266,9 +22253,9 @@
field public static final int ON_AFTER_RELEASE = 536870912; // 0x20000000
field public static final int PARTIAL_WAKE_LOCK = 1; // 0x1
field public static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; // 0x20
+ field public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; // 0x1
field public static final deprecated int SCREEN_BRIGHT_WAKE_LOCK = 10; // 0xa
field public static final deprecated int SCREEN_DIM_WAKE_LOCK = 6; // 0x6
- field public static final int WAIT_FOR_DISTANT_PROXIMITY = 1; // 0x1
}
public final class PowerManager.WakeLock {
@@ -28254,6 +28241,8 @@
method public static android.telecomm.Connection createCanceledConnection();
method public static android.telecomm.Connection createFailedConnection(int, java.lang.String);
method public final void destroy();
+ method public final android.net.Uri getAddress();
+ method public final int getAddressPresentation();
method public final boolean getAudioModeIsVoip();
method public final android.telecomm.AudioState getAudioState();
method public final int getCallCapabilities();
@@ -28263,26 +28252,24 @@
method public final java.util.List<android.telecomm.Connection> getConferenceableConnections();
method public final int getDisconnectCause();
method public final java.lang.String getDisconnectMessage();
- method public final android.net.Uri getHandle();
- method public final int getHandlePresentation();
method public final int getState();
method public final android.telecomm.StatusHints getStatusHints();
- method public final boolean isRequestingRingback();
+ method public final boolean isRingbackRequested();
method public void onAbort();
method public void onAnswer();
+ method public void onAudioStateChanged(android.telecomm.AudioState);
method public void onConferenceWith(android.telecomm.Connection);
method public void onDisconnect();
method public void onHold();
- method public void onPhoneAccountClicked();
method public void onPlayDtmfTone(char);
method public void onPostDialContinue(boolean);
method public void onReject();
method public void onSeparate();
- method public void onSetAudioState(android.telecomm.AudioState);
- method public void onSetState(int);
+ method public void onStateChanged(int);
method public void onStopDtmfTone();
method public void onUnhold();
method public final void setActive();
+ method public final void setAddress(android.net.Uri, int);
method public final void setAudioModeIsVoip(boolean);
method public final void setCallCapabilities(int);
method public final void setCallerDisplayName(java.lang.String, int);
@@ -28290,12 +28277,11 @@
method public final void setConnectionService(android.telecomm.ConnectionService);
method public final void setDialing();
method public final void setDisconnected(int, java.lang.String);
- method public final void setHandle(android.net.Uri, int);
method public final void setInitialized();
method public final void setInitializing();
method public final void setOnHold();
method public final void setPostDialWait(java.lang.String);
- method public final void setRequestingRingback(boolean);
+ method public final void setRingbackRequested(boolean);
method public final void setRinging();
method public final void setStatusHints(android.telecomm.StatusHints);
method public static java.lang.String stateToString(int);
@@ -28335,9 +28321,9 @@
public class GatewayInfo implements android.os.Parcelable {
method public int describeContents();
- method public android.net.Uri getGatewayHandle();
+ method public android.net.Uri getGatewayAddress();
method public java.lang.String getGatewayProviderPackageName();
- method public android.net.Uri getOriginalHandle();
+ method public android.net.Uri getOriginalAddress();
method public boolean isEmpty();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
@@ -28355,9 +28341,12 @@
method public java.lang.CharSequence getShortDescription();
method public android.net.Uri getSubscriptionAddress();
method public java.util.List<java.lang.String> getSupportedUriSchemes();
+ method public boolean hasCapabilities(int);
+ method public boolean isEnabled();
method public boolean supportsUriScheme(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final int CAPABILITY_CONNECTION_MANAGER = 1; // 0x1
+ field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10
field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
field public static final android.os.Parcelable.Creator CREATOR;
field public static final java.lang.String SCHEME_SIP = "sip";
@@ -28367,6 +28356,7 @@
public static class PhoneAccount.Builder {
ctor public PhoneAccount.Builder(android.telecomm.PhoneAccountHandle, java.lang.CharSequence);
+ ctor public PhoneAccount.Builder(android.telecomm.PhoneAccount);
method public android.telecomm.PhoneAccount build();
method public android.telecomm.PhoneAccount.Builder setAddress(android.net.Uri);
method public android.telecomm.PhoneAccount.Builder setCapabilities(int);
@@ -28388,26 +28378,19 @@
public final class PhoneCapabilities {
method public static java.lang.String toString(int);
field public static final int ADD_CALL = 16; // 0x10
- field public static final int ALL = 255; // 0xff
+ field public static final int ALL = 12543; // 0x30ff
+ field public static final int DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000
field public static final int HOLD = 1; // 0x1
field public static final int MANAGE_CONFERENCE = 128; // 0x80
field public static final int MERGE_CONFERENCE = 4; // 0x4
field public static final int MUTE = 64; // 0x40
field public static final int RESPOND_VIA_TEXT = 32; // 0x20
+ field public static final int SEPARATE_FROM_CONFERENCE = 4096; // 0x1000
field public static final int SUPPORT_HOLD = 2; // 0x2
field public static final int SWAP_CONFERENCE = 8; // 0x8
}
- public class PropertyPresentation {
- ctor public PropertyPresentation();
- field public static final int ALLOWED = 1; // 0x1
- field public static final int PAYPHONE = 4; // 0x4
- field public static final int RESTRICTED = 2; // 0x2
- field public static final int UNKNOWN = 3; // 0x3
- }
-
public final class RemoteConference {
- method public final void addCallback(android.telecomm.RemoteConference.Callback);
method public void disconnect();
method public final int getCallCapabilities();
method public final java.util.List<android.telecomm.RemoteConnection> getConnections();
@@ -28415,9 +28398,10 @@
method public java.lang.String getDisconnectMessage();
method public final int getState();
method public void hold();
- method public final void removeCallback(android.telecomm.RemoteConference.Callback);
+ method public final void registerCallback(android.telecomm.RemoteConference.Callback);
method public void separate(android.telecomm.RemoteConnection);
method public void unhold();
+ method public final void unregisterCallback(android.telecomm.RemoteConference.Callback);
}
public static abstract class RemoteConference.Callback {
@@ -28432,57 +28416,48 @@
public final class RemoteConnection {
method public void abort();
- method public void addListener(android.telecomm.RemoteConnection.Listener);
method public void answer();
method public void disconnect();
- method public boolean getAudioModeIsVoip();
+ method public android.net.Uri getAddress();
+ method public int getAddressPresentation();
method public int getCallCapabilities();
- method public java.lang.String getCallerDisplayName();
+ method public java.lang.CharSequence getCallerDisplayName();
method public int getCallerDisplayNamePresentation();
- method public java.util.List<android.telecomm.RemoteConnection> getChildren();
method public android.telecomm.RemoteConference getConference();
method public java.util.List<android.telecomm.RemoteConnection> getConferenceableConnections();
method public int getDisconnectCauseCode();
method public java.lang.String getDisconnectCauseMessage();
method public int getFailureCode();
method public java.lang.String getFailureMessage();
- method public android.net.Uri getHandle();
- method public int getHandlePresentation();
- method public android.telecomm.RemoteConnection getParent();
method public int getState();
method public android.telecomm.StatusHints getStatusHints();
method public void hold();
- method public boolean isRequestingRingback();
+ method public boolean isRingbackRequested();
+ method public boolean isVoipAudioMode();
method public void playDtmfTone(char);
method public void postDialContinue(boolean);
+ method public void registerCallback(android.telecomm.RemoteConnection.Callback);
method public void reject();
- method public void removeListener(android.telecomm.RemoteConnection.Listener);
method public void setAudioState(android.telecomm.AudioState);
method public void stopDtmfTone();
method public void unhold();
+ method public void unregisterCallback(android.telecomm.RemoteConnection.Callback);
}
- public static abstract class RemoteConnection.Listener {
- ctor public RemoteConnection.Listener();
- method public void onAudioModeIsVoipChanged(android.telecomm.RemoteConnection, boolean);
+ public static abstract class RemoteConnection.Callback {
+ ctor public RemoteConnection.Callback();
+ method public void onAddressChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
method public void onCallCapabilitiesChanged(android.telecomm.RemoteConnection, int);
method public void onCallerDisplayNameChanged(android.telecomm.RemoteConnection, java.lang.String, int);
- method public void onChildrenChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
method public void onConferenceChanged(android.telecomm.RemoteConnection, android.telecomm.RemoteConference);
method public void onConferenceableConnectionsChanged(android.telecomm.RemoteConnection, java.util.List<android.telecomm.RemoteConnection>);
method public void onDestroyed(android.telecomm.RemoteConnection);
method public void onDisconnected(android.telecomm.RemoteConnection, int, java.lang.String);
- method public void onHandleChanged(android.telecomm.RemoteConnection, android.net.Uri, int);
- method public void onParentChanged(android.telecomm.RemoteConnection, android.telecomm.RemoteConnection);
method public void onPostDialWait(android.telecomm.RemoteConnection, java.lang.String);
- method public void onRequestingRingback(android.telecomm.RemoteConnection, boolean);
+ method public void onRingbackRequested(android.telecomm.RemoteConnection, boolean);
method public void onStateChanged(android.telecomm.RemoteConnection, int);
method public void onStatusHintsChanged(android.telecomm.RemoteConnection, android.telecomm.StatusHints);
- }
-
- public abstract interface Response {
- method public abstract void onError(IN, int, java.lang.String);
- method public abstract void onResult(IN, OUT...);
+ method public void onVoipAudioChanged(android.telecomm.RemoteConnection, boolean);
}
public final class StatusHints implements android.os.Parcelable {
@@ -28500,7 +28475,7 @@
public class TelecommManager {
method public void addNewIncomingCall(android.telecomm.PhoneAccountHandle, android.os.Bundle);
method public void cancelMissedCallsNotification();
- method public void clearAccounts(java.lang.String);
+ method public void clearAccounts();
method public android.telecomm.PhoneAccountHandle getConnectionManager();
method public android.telecomm.PhoneAccountHandle getDefaultOutgoingPhoneAccount(java.lang.String);
method public java.util.List<android.telecomm.PhoneAccountHandle> getEnabledPhoneAccounts();
@@ -28514,6 +28489,8 @@
method public void unregisterPhoneAccount(android.telecomm.PhoneAccountHandle);
field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecomm.action.CHANGE_PHONE_ACCOUNTS";
field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecomm.action.CONNECTION_SERVICE_CONFIGURE";
+ field public static final java.lang.String ACTION_PHONE_ACCOUNT_DISABLED = "android.telecom.action.PHONE_ACCOUNT_DISABLED";
+ field public static final java.lang.String ACTION_PHONE_ACCOUNT_ENABLED = "android.telecom.action.PHONE_ACCOUNT_ENABLED";
field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecomm.action.SHOW_CALL_SETTINGS";
field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ','
field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';'
@@ -28523,6 +28500,12 @@
field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecomm.extra.CONNECTION_SERVICE";
field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telecomm.extra.PHONE_ACCOUNT_HANDLE";
field public static final java.lang.String EXTRA_START_CALL_WITH_SPEAKERPHONE = "android.telecomm.extra.START_CALL_WITH_SPEAKERPHONE";
+ field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecomm.extra.GATEWAY_ORIGINAL_ADDRESS";
+ field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecomm.extra.GATEWAY_PROVIDER_PACKAGE";
+ field public static final int PRESENTATION_ALLOWED = 1; // 0x1
+ field public static final int PRESENTATION_PAYPHONE = 4; // 0x4
+ field public static final int PRESENTATION_RESTRICTED = 2; // 0x2
+ field public static final int PRESENTATION_UNKNOWN = 3; // 0x3
}
}
@@ -32149,6 +32132,7 @@
ctor public SizeF(float, float);
method public float getHeight();
method public float getWidth();
+ method public static android.util.SizeF parseSizeF(java.lang.String) throws java.lang.NumberFormatException;
}
public class SparseArray implements java.lang.Cloneable {
@@ -33852,8 +33836,6 @@
method public boolean hasTransientState();
method public boolean hasWindowFocus();
method public static android.view.View inflate(android.content.Context, int, android.view.ViewGroup);
- method protected void initializeFadingEdge(android.content.res.TypedArray);
- method protected void initializeScrollbars(android.content.res.TypedArray);
method public void invalidate(android.graphics.Rect);
method public void invalidate(int, int, int, int);
method public void invalidate();
@@ -34900,6 +34882,7 @@
field public static final int FEATURE_ACTION_BAR = 8; // 0x8
field public static final int FEATURE_ACTION_BAR_OVERLAY = 9; // 0x9
field public static final int FEATURE_ACTION_MODE_OVERLAY = 10; // 0xa
+ field public static final int FEATURE_ACTIVITY_TRANSITIONS = 13; // 0xd
field public static final int FEATURE_CONTENT_TRANSITIONS = 12; // 0xc
field public static final int FEATURE_CONTEXT_MENU = 6; // 0x6
field public static final int FEATURE_CUSTOM_TITLE = 7; // 0x7
@@ -36501,23 +36484,18 @@
public static abstract class WebChromeClient.FileChooserParams {
ctor public WebChromeClient.FileChooserParams();
+ method public abstract android.content.Intent createIntent();
method public abstract java.lang.String[] getAcceptTypes();
method public abstract java.lang.String getFilenameHint();
method public abstract int getMode();
method public abstract java.lang.CharSequence getTitle();
- method public abstract android.webkit.WebChromeClient.UploadHelper getUploadHelper();
method public abstract boolean isCaptureEnabled();
+ method public static android.net.Uri[] parseResult(int, android.content.Intent);
field public static final int MODE_OPEN = 0; // 0x0
field public static final int MODE_OPEN_MULTIPLE = 1; // 0x1
field public static final int MODE_SAVE = 3; // 0x3
}
- public static abstract class WebChromeClient.UploadHelper {
- ctor public WebChromeClient.UploadHelper();
- method public abstract android.content.Intent buildIntent();
- method public abstract android.net.Uri[] parseResult(int, android.content.Intent);
- }
-
public class WebHistoryItem implements java.lang.Cloneable {
method public android.graphics.Bitmap getFavicon();
method public java.lang.String getOriginalUrl();
@@ -39141,9 +39119,7 @@
method public float getShadowRadius();
method public final boolean getShowSoftInputOnFocus();
method public java.lang.CharSequence getText();
- method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
method public final android.content.res.ColorStateList getTextColors();
- method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
method public java.util.Locale getTextLocale();
method public float getTextScaleX();
method public float getTextSize();
diff --git a/api/removed.txt b/api/removed.txt
index c8a3b4b..527f6c2 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -24,6 +24,11 @@
package android.view {
+ public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+ method protected void initializeFadingEdge(android.content.res.TypedArray);
+ method protected void initializeScrollbars(android.content.res.TypedArray);
+ }
+
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
field public static final int TYPE_KEYGUARD = 2004; // 0x7d4
}
@@ -65,3 +70,12 @@
}
+package android.widget {
+
+ public class TextView extends android.view.View implements android.view.ViewTreeObserver.OnPreDrawListener {
+ method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
+ method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
+ }
+
+}
+
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index c06ef0d..57c1505 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -28,10 +28,15 @@
import android.app.Instrumentation;
import android.app.ProfilerInfo;
import android.app.UiAutomationConnection;
+import android.app.usage.ConfigurationStats;
+import android.app.usage.IUsageStatsManager;
+import android.app.usage.UsageStatsManager;
import android.content.ComponentName;
+import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.IPackageManager;
+import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
@@ -47,6 +52,7 @@
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.AndroidException;
+import android.util.ArrayMap;
import android.view.IWindowManager;
import android.view.View;
@@ -61,6 +67,9 @@
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
@@ -846,7 +855,7 @@
}
private void sendBroadcast() throws Exception {
- Intent intent = makeIntent(UserHandle.USER_ALL);
+ Intent intent = makeIntent(UserHandle.USER_CURRENT);
IntentReceiver receiver = new IntentReceiver();
System.out.println("Broadcasting: " + intent);
mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, mReceiverPermission,
@@ -1722,7 +1731,64 @@
}
}
+ private List<Configuration> getRecentConfigurations(int days) {
+ IUsageStatsManager usm = IUsageStatsManager.Stub.asInterface(ServiceManager.getService(
+ Context.USAGE_STATS_SERVICE));
+ final long now = System.currentTimeMillis();
+ final long nDaysAgo = now - (days * 24 * 60 * 60 * 1000);
+ try {
+ @SuppressWarnings("unchecked")
+ ParceledListSlice<ConfigurationStats> configStatsSlice = usm.queryConfigurationStats(
+ UsageStatsManager.INTERVAL_BEST, nDaysAgo, now, "com.android.shell");
+ if (configStatsSlice == null) {
+ return Collections.emptyList();
+ }
+
+ final ArrayMap<Configuration, Integer> recentConfigs = new ArrayMap<>();
+ final List<ConfigurationStats> configStatsList = configStatsSlice.getList();
+ final int configStatsListSize = configStatsList.size();
+ for (int i = 0; i < configStatsListSize; i++) {
+ final ConfigurationStats stats = configStatsList.get(i);
+ final int indexOfKey = recentConfigs.indexOfKey(stats.getConfiguration());
+ if (indexOfKey < 0) {
+ recentConfigs.put(stats.getConfiguration(), stats.getActivationCount());
+ } else {
+ recentConfigs.setValueAt(indexOfKey,
+ recentConfigs.valueAt(indexOfKey) + stats.getActivationCount());
+ }
+ }
+
+ final Comparator<Configuration> comparator = new Comparator<Configuration>() {
+ @Override
+ public int compare(Configuration a, Configuration b) {
+ return recentConfigs.get(b).compareTo(recentConfigs.get(a));
+ }
+ };
+
+ ArrayList<Configuration> configs = new ArrayList<>(recentConfigs.size());
+ configs.addAll(recentConfigs.keySet());
+ Collections.sort(configs, comparator);
+ return configs;
+
+ } catch (RemoteException e) {
+ return Collections.emptyList();
+ }
+ }
+
private void runGetConfig() throws Exception {
+ int days = 14;
+ String option = nextOption();
+ if (option != null) {
+ if (!option.equals("--days")) {
+ throw new IllegalArgumentException("unrecognized option " + option);
+ }
+
+ days = Integer.parseInt(nextArgRequired());
+ if (days <= 0) {
+ throw new IllegalArgumentException("--days must be a positive integer");
+ }
+ }
+
try {
Configuration config = mAm.getConfiguration();
if (config == null) {
@@ -1733,6 +1799,17 @@
System.out.println("config: " + Configuration.resourceQualifierString(config));
System.out.println("abi: " + TextUtils.join(",", Build.SUPPORTED_ABIS));
+ final List<Configuration> recentConfigs = getRecentConfigurations(days);
+ final int recentConfigSize = recentConfigs.size();
+ if (recentConfigSize > 0) {
+ System.out.println("recentConfigs:");
+ }
+
+ for (int i = 0; i < recentConfigSize; i++) {
+ System.out.println(" config: " + Configuration.resourceQualifierString(
+ recentConfigs.get(i)));
+ }
+
} catch (RemoteException e) {
}
}
diff --git a/cmds/app_process/app_main.cpp b/cmds/app_process/app_main.cpp
index 6e77e13..1bb28c3 100644
--- a/cmds/app_process/app_main.cpp
+++ b/cmds/app_process/app_main.cpp
@@ -133,8 +133,7 @@
// names if the zygote command line decreases in size.
uintptr_t start = reinterpret_cast<uintptr_t>(argv[0]);
uintptr_t end = reinterpret_cast<uintptr_t>(argv[argc - 1]);
- end += strlen(argv[argc - 1]);
-
+ end += strlen(argv[argc - 1]) + 1;
return (end - start);
}
@@ -220,15 +219,27 @@
//
// For zygote starts, all remaining arguments are passed to the zygote.
// main function.
+ //
+ // Note that we must copy argument string values since we will rewrite the
+ // entire argument block when we apply the nice name to argv0.
-
- int i = runtime.addVmArguments(argc, argv);
+ int i;
+ for (i = 0; i < argc; i++) {
+ if (argv[i][0] != '-') {
+ break;
+ }
+ if (argv[i][1] == '-' && argv[i][2] == 0) {
+ ++i; // Skip --.
+ break;
+ }
+ runtime.addOption(strdup(argv[i]));
+ }
// Parse runtime arguments. Stop at first unrecognized option.
bool zygote = false;
bool startSystemServer = false;
bool application = false;
- const char* niceName = NULL;
+ String8 niceName;
String8 className;
++i; // Skip unused "parent dir" argument.
@@ -242,7 +253,7 @@
} else if (strcmp(arg, "--application") == 0) {
application = true;
} else if (strncmp(arg, "--nice-name=", 12) == 0) {
- niceName = arg + 12;
+ niceName.setTo(arg + 12);
} else if (strncmp(arg, "--", 2) != 0) {
className.setTo(arg);
break;
@@ -287,9 +298,9 @@
}
}
- if (niceName && *niceName) {
- runtime.setArgv0(niceName);
- set_process_name(niceName);
+ if (!niceName.isEmpty()) {
+ runtime.setArgv0(niceName.string());
+ set_process_name(niceName.string());
}
if (zygote) {
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 7c13dbe..0aa8fdd 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -636,6 +636,7 @@
anim.mNodes = new ArrayList<Node>();
anim.mSortedNodes = new ArrayList<Node>();
anim.mReversible = mReversible;
+ anim.mSetListener = null;
// Walk through the old nodes list, cloning each node and adding it to the new nodemap.
// One problem is that the old node dependencies point to nodes in the old AnimatorSet.
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 89a9692..701ab1d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4756,7 +4756,7 @@
* Activity through a returning activity transition, giving you the resultCode
* and any additional data from it. This method will only be called if the activity
* set a result code other than {@link #RESULT_CANCELED} and it supports activity
- * transitions with {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+ * transitions with {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
*
* <p>The purpose of this function is to let the called Activity send a hint about
* its state so that this underlying Activity can prepare to be exposed. A call to
@@ -5781,7 +5781,7 @@
* When {@link android.app.ActivityOptions#makeSceneTransitionAnimation(Activity,
* android.view.View, String)} was used to start an Activity, <var>callback</var>
* will be called to handle shared elements on the <i>launched</i> Activity. This requires
- * {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+ * {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param callback Used to manipulate shared element transitions on the launched Activity.
*/
@@ -5797,7 +5797,7 @@
* android.view.View, String)} was used to start an Activity, <var>callback</var>
* will be called to handle shared elements on the <i>launching</i> Activity. Most
* calls will only come when returning from the started Activity.
- * This requires {@link Window#FEATURE_CONTENT_TRANSITIONS}.
+ * This requires {@link Window#FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param callback Used to manipulate shared element transitions on the launching Activity.
*/
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 394b183..677fcef 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2295,6 +2295,13 @@
reply.writeNoException();
return true;
}
+
+ case BOOT_ANIMATION_COMPLETE_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ bootAnimationComplete();
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -5301,5 +5308,16 @@
reply.recycle();
}
+ @Override
+ public void bootAnimationComplete() throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ mRemote.transact(BOOT_ANIMATION_COMPLETE_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 213c7f6..cd6a4f5 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -414,7 +414,7 @@
* exit Transition. The position of the shared element in the launched Activity will be the
* epicenter of its entering Transition.
*
- * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
+ * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
* enabled on the calling Activity to cause an exit transition. The same must be in
* the called Activity to get an entering transition.</p>
* @param activity The Activity whose window contains the shared elements.
@@ -438,7 +438,7 @@
* will be used as the epicenter for the exit Transition. The position of the associated
* shared element in the launched Activity will be the epicenter of its entering Transition.
*
- * <p>This requires {@link android.view.Window#FEATURE_CONTENT_TRANSITIONS} to be
+ * <p>This requires {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS} to be
* enabled on the calling Activity to cause an exit transition. The same must be in
* the called Activity to get an entering transition.</p>
* @param activity The Activity whose window contains the shared elements.
@@ -453,7 +453,7 @@
public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
Pair<View, String>... sharedElements) {
ActivityOptions opts = new ActivityOptions();
- if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
+ if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
opts.mAnimationType = ANIM_DEFAULT;
return opts;
}
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index ad4a22b..bc2e6ca 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -144,7 +144,7 @@
}
public void setEnterActivityOptions(Activity activity, ActivityOptions options) {
- if (activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)
+ if (activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)
&& options != null && mEnterActivityOptions == null
&& mEnterTransitionCoordinator == null
&& options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
@@ -272,7 +272,7 @@
}
public void startExitOutTransition(Activity activity, Bundle options) {
- if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
+ if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
return;
}
ActivityOptions activityOptions = new ActivityOptions(options);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 404268c..d746745 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1645,30 +1645,6 @@
/**
* @hide
*/
- public void addCrossProfileIntentsForPackage(String packageName,
- int sourceUserId, int targetUserId) {
- try {
- mPM.addCrossProfileIntentsForPackage(packageName, sourceUserId, targetUserId);
- } catch (RemoteException e) {
- // Should never happen!
- }
- }
-
- /**
- * @hide
- */
- public void removeCrossProfileIntentsForPackage(String packageName,
- int sourceUserId, int targetUserId) {
- try {
- mPM.removeCrossProfileIntentsForPackage(packageName, sourceUserId, targetUserId);
- } catch (RemoteException e) {
- // Should never happen!
- }
- }
-
- /**
- * @hide
- */
@Override
public void clearCrossProfileIntentFilters(int sourceUserId) {
try {
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index 8227915..b09f169 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -38,7 +38,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collection;
final class BackStackState implements Parcelable {
final int[] mOps;
@@ -745,13 +744,8 @@
SparseArray<Fragment> firstOutFragments = new SparseArray<Fragment>();
SparseArray<Fragment> lastInFragments = new SparseArray<Fragment>();
-
calculateFragments(firstOutFragments, lastInFragments);
-
- TransitionState state = null;
- if (firstOutFragments.size() != 0 || lastInFragments.size() != 0) {
- state = beginTransition(firstOutFragments, lastInFragments, false);
- }
+ beginTransition(firstOutFragments, lastInFragments, false);
Op op = mHead;
while (op != null) {
@@ -842,10 +836,6 @@
if (mAddToBackStack) {
mManager.addBackStackState(this);
}
-
- if (state != null) {
- updateTransitionEndState(state, firstOutFragments, lastInFragments, false);
- }
}
private static void setFirstOut(SparseArray<Fragment> fragments, Fragment fragment) {
@@ -920,43 +910,6 @@
op = op.next;
}
-
- if (!haveTransitions(firstOutFragments, lastInFragments, false)) {
- firstOutFragments.clear();
- lastInFragments.clear();
- }
- }
-
- /**
- * @return true if custom transitions exist on any fragment in firstOutFragments or
- * lastInFragments or false otherwise.
- */
- private static boolean haveTransitions(SparseArray<Fragment> firstOutFragments,
- SparseArray<Fragment> lastInFragments, boolean isBack) {
- for (int i = firstOutFragments.size() - 1; i >= 0; i--) {
- Fragment f = firstOutFragments.valueAt(i);
- if (isBack) {
- if (f.getReturnTransition() != null ||
- f.getSharedElementReturnTransition() != null) {
- return true;
- }
- } else if (f.getExitTransition() != null) {
- return true;
- }
- }
-
- for (int i = lastInFragments.size() - 1; i >= 0; i--) {
- Fragment f = lastInFragments.valueAt(i);
- if (isBack) {
- if (f.getReenterTransition() != null) {
- return true;
- }
- } else if (f.getEnterTransition() != null ||
- f.getSharedElementEnterTransition() != null) {
- return true;
- }
- }
- return false;
}
/**
@@ -1003,11 +956,6 @@
op = op.next;
}
-
- if (!haveTransitions(firstOutFragments, lastInFragments, true)) {
- firstOutFragments.clear();
- lastInFragments.clear();
- }
}
/**
@@ -1038,8 +986,8 @@
* @param isBack true if this is popping the back stack or false if this is a
* forward operation.
* @return The TransitionState used to complete the operation of the transition
- * in {@link #updateTransitionEndState(android.app.BackStackRecord.TransitionState,
- * android.util.SparseArray, android.util.SparseArray, boolean)}.
+ * in {@link #setNameOverrides(android.app.BackStackRecord.TransitionState, java.util.ArrayList,
+ * java.util.ArrayList)}.
*/
private TransitionState beginTransition(SparseArray<Fragment> firstOutFragments,
SparseArray<Fragment> lastInFragments, boolean isBack) {
@@ -1050,16 +998,11 @@
// add any, then no views will be targeted.
state.nonExistentView = new View(mManager.mActivity);
- ArrayMap<String, View> tempViews1 = new ArrayMap<String, View>();
- ArrayMap<String, View> tempViews2 = new ArrayMap<String, View>();
- ArrayList<String> tempNames = new ArrayList<String>();
- ArrayList<View> tempViewList = new ArrayList<View>();
-
// Go over all leaving fragments.
for (int i = 0; i < firstOutFragments.size(); i++) {
int containerId = firstOutFragments.keyAt(i);
configureTransitions(containerId, state, isBack, firstOutFragments,
- lastInFragments, tempViews1, tempViews2, tempNames, tempViewList);
+ lastInFragments);
}
// Now go over all entering fragments that didn't have a leaving fragment.
@@ -1067,28 +1010,33 @@
int containerId = lastInFragments.keyAt(i);
if (firstOutFragments.get(containerId) == null) {
configureTransitions(containerId, state, isBack, firstOutFragments,
- lastInFragments, tempViews1, tempViews2, tempNames, tempViewList);
+ lastInFragments);
}
}
-
- if (state.overallTransitions.size() == 0) {
- state = null;
- }
return state;
}
+ private static Transition cloneTransition(Transition transition) {
+ if (transition != null) {
+ transition = transition.clone();
+ }
+ return transition;
+ }
+
private static Transition getEnterTransition(Fragment inFragment, boolean isBack) {
if (inFragment == null) {
return null;
}
- return isBack ? inFragment.getReenterTransition() : inFragment.getEnterTransition();
+ return cloneTransition(isBack ? inFragment.getReenterTransition() :
+ inFragment.getEnterTransition());
}
private static Transition getExitTransition(Fragment outFragment, boolean isBack) {
if (outFragment == null) {
return null;
}
- return isBack ? outFragment.getReturnTransition() : outFragment.getExitTransition();
+ return cloneTransition(isBack ? outFragment.getReturnTransition() :
+ outFragment.getExitTransition());
}
private static Transition getSharedElementTransition(Fragment inFragment, Fragment outFragment,
@@ -1096,34 +1044,32 @@
if (inFragment == null || outFragment == null) {
return null;
}
- return isBack ? outFragment.getSharedElementReturnTransition() :
- inFragment.getSharedElementEnterTransition();
+ return cloneTransition(isBack ? outFragment.getSharedElementReturnTransition() :
+ inFragment.getSharedElementEnterTransition());
}
- private static Transition captureExitingViews(Transition exitTransition, Fragment outFragment,
- ArrayList<View> viewList) {
+ private static ArrayList<View> captureExitingViews(Transition exitTransition,
+ Fragment outFragment) {
+ ArrayList<View> viewList = null;
if (exitTransition != null) {
+ viewList = new ArrayList<View>();
View root = outFragment.getView();
- viewList.clear();
root.captureTransitioningViews(viewList);
- if (viewList.isEmpty()) {
- exitTransition = null;
- } else {
- addTransitioningViews(exitTransition, viewList);
- }
+ addTargets(exitTransition, viewList);
}
- return exitTransition;
+ return viewList;
}
private ArrayMap<String, View> remapSharedElements(TransitionState state, Fragment outFragment,
- ArrayMap<String, View> namedViews, ArrayMap<String, View> tempViews2, boolean isBack) {
+ boolean isBack) {
+ ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
if (mSharedElementSourceNames != null) {
outFragment.getView().findNamedViews(namedViews);
if (isBack) {
namedViews.retainAll(mSharedElementTargetNames);
} else {
namedViews = remapNames(mSharedElementSourceNames, mSharedElementTargetNames,
- namedViews, tempViews2);
+ namedViews);
}
}
@@ -1147,41 +1093,94 @@
* We will add to the views before the end state of the transition is captured so that the
* views will appear. At the start of the transition, we clear the list of targets so that
* we can restore the state of the transition and use it again.
+ *
+ * <p>The shared element transition maps its shared elements immediately prior to
+ * capturing the final state of the Transition.</p>
*/
- private void prepareEnterTransition(TransitionState state, final Transition enterTransition,
- final View container, final Fragment inFragment) {
- if (enterTransition != null) {
- final ArrayList<View> enteringViews = new ArrayList<View>();
- final View nonExistentView = state.nonExistentView;
- enterTransition.addTarget(state.nonExistentView);
- enterTransition.addListener(new Transition.TransitionListenerAdapter() {
- @Override
- public void onTransitionStart(Transition transition) {
- transition.removeListener(this);
- transition.removeTarget(nonExistentView);
- int numViews = enteringViews.size();
- for (int i = 0; i < numViews; i++) {
- transition.removeTarget(enteringViews.get(i));
- }
- }
- });
- container.getViewTreeObserver().addOnPreDrawListener(
- new ViewTreeObserver.OnPreDrawListener() {
- @Override
- public boolean onPreDraw() {
- container.getViewTreeObserver().removeOnPreDrawListener(this);
+ private ArrayList<View> addTransitionTargets(final TransitionState state,
+ final Transition enterTransition, final Transition sharedElementTransition,
+ final Transition overallTransition, final View container,
+ final Fragment inFragment, final Fragment outFragment,
+ final ArrayList<View> hiddenFragmentViews, final boolean isBack) {
+ if (enterTransition == null && sharedElementTransition == null &&
+ overallTransition == null) {
+ return null;
+ }
+ final ArrayList<View> enteringViews = new ArrayList<View>();
+ container.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ container.getViewTreeObserver().removeOnPreDrawListener(this);
+
+ // Don't include any newly-hidden fragments in the transition.
+ excludeHiddenFragments(hiddenFragmentViews, inFragment.mContainerId,
+ overallTransition);
+
+ if (sharedElementTransition != null) {
+ ArrayMap<String, View> namedViews = mapSharedElementsIn(
+ state, isBack, inFragment);
+
+ setEpicenterIn(namedViews, state);
+
+ callSharedElementEnd(state, inFragment, outFragment, isBack,
+ namedViews);
+ }
+
+ if (enterTransition != null) {
View view = inFragment.getView();
if (view != null) {
view.captureTransitioningViews(enteringViews);
- addTransitioningViews(enterTransition, enteringViews);
+ addTargets(enterTransition, enteringViews);
}
- return true;
+ setSharedElementEpicenter(enterTransition, state);
}
- });
- setSharedElementEpicenter(enterTransition, state);
+ return true;
+ }
+ });
+ return enteringViews;
+ }
+
+ private void callSharedElementEnd(TransitionState state, Fragment inFragment,
+ Fragment outFragment, boolean isBack, ArrayMap<String, View> namedViews) {
+ SharedElementCallback sharedElementCallback = isBack ?
+ outFragment.mEnterTransitionCallback :
+ inFragment.mEnterTransitionCallback;
+ ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
+ ArrayList<View> views = new ArrayList<View>(namedViews.values());
+ sharedElementCallback.onSharedElementEnd(names, views, null);
+ }
+
+ private void setEpicenterIn(ArrayMap<String, View> namedViews, TransitionState state) {
+ if (mSharedElementTargetNames != null && !namedViews.isEmpty()) {
+ // now we know the epicenter of the entering transition.
+ View epicenter = namedViews
+ .get(mSharedElementTargetNames.get(0));
+ if (epicenter != null) {
+ state.enteringEpicenterView = epicenter;
+ }
}
}
+ private ArrayMap<String, View> mapSharedElementsIn(TransitionState state,
+ boolean isBack, Fragment inFragment) {
+ // Now map the shared elements in the incoming fragment
+ ArrayMap<String, View> namedViews = mapEnteringSharedElements(state, inFragment, isBack);
+
+ // remap shared elements and set the name mapping used
+ // in the shared element transition.
+ if (isBack) {
+ inFragment.mExitTransitionCallback.onMapSharedElements(
+ mSharedElementTargetNames, namedViews);
+ setBackNameOverrides(state, namedViews, true);
+ } else {
+ inFragment.mEnterTransitionCallback.onMapSharedElements(
+ mSharedElementTargetNames, namedViews);
+ setNameOverrides(state, namedViews, true);
+ }
+ return namedViews;
+ }
+
private static Transition mergeTransitions(Transition enterTransition,
Transition exitTransition, Transition sharedElementTransition, Fragment inFragment,
boolean isBack) {
@@ -1209,26 +1208,16 @@
* Configures custom transitions for a specific fragment container.
*
* @param containerId The container ID of the fragments to configure the transition for.
- * @param state The Transition State to be shared with {@link #updateTransitionEndState(
- * android.app.BackStackRecord.TransitionState, android.util.SparseArray,
- * android.util.SparseArray, boolean)} later.
+ * @param state The Transition State keeping track of the executing transitions.
* @param firstOutFragments The list of first fragments to be removed, keyed on the
* container ID.
* @param lastInFragments The list of last fragments to be added, keyed on the
* container ID.
* @param isBack true if this is popping the back stack or false if this is a
* forward operation.
- * @param tempViews1 A temporary mapping of names to Views, used to avoid allocation
- * inside a loop.
- * @param tempViews2 A temporary mapping of names to Views, used to avoid allocation
- * inside a loop.
- * @param tempNames A temporary list of Strings, used to avoid allocation inside a loop.
- * @param tempViewList A temporary list of Views, used to avoid allocation inside a loop.
*/
private void configureTransitions(int containerId, TransitionState state, boolean isBack,
- SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments,
- ArrayMap<String, View> tempViews1, ArrayMap<String, View> tempViews2,
- ArrayList<String> tempNames, ArrayList<View> tempViewList) {
+ SparseArray<Fragment> firstOutFragments, SparseArray<Fragment> lastInFragments) {
ViewGroup sceneRoot = (ViewGroup) mManager.mContainer.findViewById(containerId);
if (sceneRoot != null) {
Fragment inFragment = lastInFragments.get(containerId);
@@ -1238,146 +1227,150 @@
Transition sharedElementTransition = getSharedElementTransition(inFragment, outFragment,
isBack);
Transition exitTransition = getExitTransition(outFragment, isBack);
- exitTransition = captureExitingViews(exitTransition, outFragment, tempViewList);
- ArrayMap<String, View> namedViews = tempViews1;
- namedViews.clear();
- if (sharedElementTransition != null) {
- namedViews = remapSharedElements(state,
- outFragment, namedViews, tempViews2, isBack);
+ if (enterTransition == null && sharedElementTransition == null &&
+ exitTransition == null) {
+ return; // no transitions!
+ }
+ ArrayList<View> exitingViews = captureExitingViews(exitTransition, outFragment);
+ if (exitingViews == null || exitingViews.isEmpty()) {
+ exitTransition = null;
}
- // Notify the start of the transition.
- SharedElementCallback callback = isBack ?
- outFragment.mEnterTransitionCallback :
- inFragment.mEnterTransitionCallback;
- tempNames.clear();
- tempNames.addAll(namedViews.keySet());
- tempViewList.clear();
- tempViewList.addAll(namedViews.values());
- callback.onSharedElementStart(tempNames, tempViewList, null);
+ ArrayMap<String, View> namedViews = null;
+ if (sharedElementTransition != null) {
+ namedViews = remapSharedElements(state, outFragment, isBack);
+
+ // Notify the start of the transition.
+ SharedElementCallback callback = isBack ?
+ outFragment.mEnterTransitionCallback :
+ inFragment.mEnterTransitionCallback;
+ ArrayList<String> names = new ArrayList<String>(namedViews.keySet());
+ ArrayList<View> views = new ArrayList<View>(namedViews.values());
+ callback.onSharedElementStart(names, views, null);
+ }
// Set the epicenter of the exit transition
- if (mSharedElementTargetNames != null && exitTransition != null) {
+ if (mSharedElementTargetNames != null && exitTransition != null && namedViews != null) {
View epicenterView = namedViews.get(mSharedElementTargetNames.get(0));
if (epicenterView != null) {
setEpicenter(exitTransition, epicenterView);
}
}
- prepareEnterTransition(state, enterTransition, sceneRoot, inFragment);
-
Transition transition = mergeTransitions(enterTransition, exitTransition,
sharedElementTransition, inFragment, isBack);
if (transition != null) {
- state.overallTransitions.put(containerId, transition);
+ ArrayList<View> hiddenFragments = new ArrayList<View>();
+ ArrayList<View> enteringViews = addTransitionTargets(state, enterTransition,
+ sharedElementTransition, transition, sceneRoot, inFragment, outFragment,
+ hiddenFragments, isBack);
+
transition.setNameOverrides(state.nameOverrides);
// We want to exclude hidden views later, so we need a non-null list in the
// transition now.
transition.excludeTarget(state.nonExistentView, true);
// Now exclude all currently hidden fragments.
- excludeHiddenFragments(state, containerId, transition);
- cleanupHiddenFragments(transition, state);
+ excludeHiddenFragments(hiddenFragments, containerId, transition);
TransitionManager.beginDelayedTransition(sceneRoot, transition);
+ // Remove the view targeting after the transition starts
+ removeTargetedViewsFromTransitions(sceneRoot, state.nonExistentView,
+ enterTransition, enteringViews, exitTransition, exitingViews,
+ transition, hiddenFragments);
}
}
}
/**
+ * After the transition has started, remove all targets that we added to the transitions
+ * so that the transitions are left in a clean state.
+ */
+ private void removeTargetedViewsFromTransitions(
+ final ViewGroup sceneRoot, final View nonExistingView,
+ final Transition enterTransition, final ArrayList<View> enteringViews,
+ final Transition exitTransition, final ArrayList<View> exitingViews,
+ final Transition overallTransition, final ArrayList<View> hiddenViews) {
+ if (enterTransition != null || exitTransition != null) {
+ sceneRoot.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this);
+ if (enterTransition != null) {
+ enterTransition.removeTarget(nonExistingView);
+ removeTargets(enterTransition, enteringViews);
+ }
+ if (exitTransition != null) {
+ removeTargets(exitTransition, exitingViews);
+ }
+ int numViews = hiddenViews.size();
+ for (int i = 0; i < numViews; i++) {
+ overallTransition.excludeTarget(hiddenViews.get(i), false);
+ }
+ overallTransition.excludeTarget(nonExistingView, false);
+ return true;
+ }
+ });
+ }
+ }
+
+ private static void removeTargets(Transition transition, ArrayList<View> views) {
+ int numViews = views.size();
+ for (int i = 0; i < numViews; i++) {
+ transition.removeTarget(views.get(i));
+ }
+ }
+
+ private static void addTargets(Transition transition, ArrayList<View> views) {
+ int numViews = views.size();
+ for (int i = 0; i < numViews; i++) {
+ transition.addTarget(views.get(i));
+ }
+ }
+
+ /**
* Remaps a name-to-View map, substituting different names for keys.
*
* @param inMap A list of keys found in the map, in the order in toGoInMap
* @param toGoInMap A list of keys to use for the new map, in the order of inMap
* @param namedViews The current mapping
- * @param tempMap A temporary mapping that will be filled with the new values.
- * @return tempMap after it has been mapped with the new names as keys.
+ * @return a new Map after it has been mapped with the new names as keys.
*/
private static ArrayMap<String, View> remapNames(ArrayList<String> inMap,
- ArrayList<String> toGoInMap, ArrayMap<String, View> namedViews,
- ArrayMap<String, View> tempMap) {
- tempMap.clear();
+ ArrayList<String> toGoInMap, ArrayMap<String, View> namedViews) {
+ ArrayMap<String, View> remappedViews = new ArrayMap<String, View>();
if (!namedViews.isEmpty()) {
int numKeys = inMap.size();
for (int i = 0; i < numKeys; i++) {
View view = namedViews.get(inMap.get(i));
+
if (view != null) {
- tempMap.put(toGoInMap.get(i), view);
+ remappedViews.put(toGoInMap.get(i), view);
}
}
}
- return tempMap;
+ return remappedViews;
}
/**
- * After making all fragment changes, this updates the custom transitions to take into
- * account the entering views and any remapping.
+ * Maps shared elements to views in the entering fragment.
*
* @param state The transition State as returned from {@link #beginTransition(
* android.util.SparseArray, android.util.SparseArray, boolean)}.
- * @param outFragments The list of first fragments to be removed, keyed on the
- * container ID.
- * @param inFragments The list of last fragments to be added, keyed on the
- * container ID.
+ * @param inFragment The last fragment to be added.
* @param isBack true if this is popping the back stack or false if this is a
* forward operation.
*/
- private void updateTransitionEndState(TransitionState state, SparseArray<Fragment> outFragments,
- SparseArray<Fragment> inFragments, boolean isBack) {
- ArrayMap<String, View> tempViews1 = new ArrayMap<String, View>();
- ArrayMap<String, View> tempViews2 = new ArrayMap<String, View>();
- ArrayList<String> tempNames = new ArrayList<String>();
- ArrayList<View> tempViews = new ArrayList<View>();
-
- int numInFragments = inFragments.size();
- for (int i = 0; i < numInFragments; i++) {
- Fragment inFragment = inFragments.valueAt(i);
- tempViews1.clear();
- ArrayMap<String, View> namedViews = mapEnteringSharedElements(inFragment, tempViews1,
- tempViews2, isBack);
- // remap shared elements and set the name mapping used in the shared element transition.
- if (isBack) {
- inFragment.mExitTransitionCallback.onMapSharedElements(
- mSharedElementTargetNames, namedViews);
- setBackNameOverrides(state, namedViews, true);
- } else {
- inFragment.mEnterTransitionCallback.onMapSharedElements(
- mSharedElementTargetNames, namedViews);
- setNameOverrides(state, namedViews, true);
- }
-
- if (mSharedElementTargetNames != null && !namedViews.isEmpty()) {
- // now we know the epicenter of the entering transition.
- View epicenter = namedViews.get(mSharedElementTargetNames.get(0));
- if (epicenter != null) {
- state.enteringEpicenterView = epicenter;
- }
- }
-
- int containerId = inFragments.keyAt(i);
- SharedElementCallback sharedElementCallback = isBack ?
- outFragments.get(containerId).mEnterTransitionCallback :
- inFragment.mEnterTransitionCallback;
- tempNames.clear();
- tempNames.addAll(namedViews.keySet());
- tempViews.clear();
- tempViews.addAll(namedViews.values());
- sharedElementCallback.onSharedElementEnd(tempNames, tempViews, null);
- }
-
- // Don't include any newly-hidden fragments in the transition.
- excludeHiddenFragments(state);
- }
-
- private ArrayMap<String, View> mapEnteringSharedElements(Fragment inFragment,
- ArrayMap<String, View> namedViews, ArrayMap<String, View> tempViews2, boolean isBack) {
+ private ArrayMap<String, View> mapEnteringSharedElements(TransitionState state,
+ Fragment inFragment, boolean isBack) {
+ ArrayMap<String, View> namedViews = new ArrayMap<String, View>();
View root = inFragment.getView();
if (root != null) {
if (mSharedElementSourceNames != null) {
root.findNamedViews(namedViews);
if (isBack) {
namedViews = remapNames(mSharedElementSourceNames,
- mSharedElementTargetNames, namedViews, tempViews2);
+ mSharedElementTargetNames, namedViews);
} else {
namedViews.retainAll(mSharedElementTargetNames);
}
@@ -1386,21 +1379,7 @@
return namedViews;
}
- private static void cleanupHiddenFragments(Transition transition, TransitionState state) {
- final ArrayList<View> hiddenViews = state.hiddenFragmentViews;
- transition.addListener(new Transition.TransitionListenerAdapter() {
- @Override
- public void onTransitionStart(Transition transition) {
- transition.removeListener(this);
- int numViews = hiddenViews.size();
- for (int i = 0; i < numViews; i++) {
- transition.excludeTarget(hiddenViews.get(i), false);
- }
- }
- });
- }
-
- private void excludeHiddenFragments(TransitionState state, int containerId,
+ private void excludeHiddenFragments(final ArrayList<View> hiddenFragmentViews, int containerId,
Transition transition) {
if (mManager.mAdded != null) {
for (int i = 0; i < mManager.mAdded.size(); i++) {
@@ -1408,44 +1387,19 @@
if (fragment.mView != null && fragment.mContainer != null &&
fragment.mContainerId == containerId) {
if (fragment.mHidden) {
- if (!state.hiddenFragmentViews.contains(fragment.mView)) {
+ if (!hiddenFragmentViews.contains(fragment.mView)) {
transition.excludeTarget(fragment.mView, true);
- state.hiddenFragmentViews.add(fragment.mView);
+ hiddenFragmentViews.add(fragment.mView);
}
} else {
transition.excludeTarget(fragment.mView, false);
- state.hiddenFragmentViews.remove(fragment.mView);
+ hiddenFragmentViews.remove(fragment.mView);
}
}
}
}
}
- private void excludeHiddenFragments(TransitionState state) {
- int numTransitions = state.overallTransitions.size();
- for (int i = 0; i < numTransitions; i++) {
- Transition transition = state.overallTransitions.valueAt(i);
- int containerId = state.overallTransitions.keyAt(i);
- excludeHiddenFragments(state, containerId, transition);
- }
- }
-
- private static void addTransitioningViews(Transition transition, final Collection<View> views) {
- for (View view : views) {
- transition.addTarget(view);
- }
-
- transition.addListener(new Transition.TransitionListenerAdapter() {
- @Override
- public void onTransitionStart(Transition transition) {
- transition.removeListener(this);
- for (View view : views) {
- transition.removeTarget(view);
- }
- }
- });
- }
-
private static void setEpicenter(Transition transition, View view) {
final Rect epicenter = new Rect();
view.getBoundsOnScreen(epicenter);
@@ -1566,10 +1520,7 @@
if (doStateMove) {
mManager.moveToState(mManager.mCurState,
FragmentManagerImpl.reverseTransit(mTransition), mTransitionStyle, true);
- if (state != null) {
- updateTransitionEndState(state, firstOutFragments, lastInFragments, true);
- state = null;
- }
+ state = null;
}
if (mIndex >= 0) {
@@ -1609,11 +1560,14 @@
for (int i = 0; i < count; i++) {
String source = mSharedElementSourceNames.get(i);
String originalTarget = mSharedElementTargetNames.get(i);
- String target = namedViews.get(originalTarget).getTransitionName();
- if (isEnd) {
- setNameOverride(state.nameOverrides, source, target);
- } else {
- setNameOverride(state.nameOverrides, target, source);
+ View view = namedViews.get(originalTarget);
+ if (view != null) {
+ String target = view.getTransitionName();
+ if (isEnd) {
+ setNameOverride(state.nameOverrides, source, target);
+ } else {
+ setNameOverride(state.nameOverrides, target, source);
+ }
}
}
}
@@ -1649,10 +1603,7 @@
}
public class TransitionState {
- public SparseArray<Transition> overallTransitions = new SparseArray<Transition>();
public ArrayMap<String, String> nameOverrides = new ArrayMap<String, String>();
- public ArrayList<View> hiddenFragmentViews = new ArrayList<View>();
-
public View enteringEpicenterView;
public View nonExistentView;
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 91a0aed..64eafb0 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2237,7 +2237,6 @@
mUser = user;
mPackageInfo = packageInfo;
- mContentResolver = new ApplicationContentResolver(this, mainThread, user);
mResourcesManager = ResourcesManager.getInstance();
mDisplay = display;
mOverrideConfiguration = overrideConfiguration;
@@ -2284,6 +2283,8 @@
mOpPackageName = mBasePackageName;
}
}
+
+ mContentResolver = new ApplicationContentResolver(this, mainThread, user);
}
void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index 9c7728e..922561d 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -136,11 +136,12 @@
if (sharedElements.isEmpty() || !sharedElements.valueAt(0).isLayoutRequested()) {
viewsReady(sharedElements);
} else {
- sharedElements.valueAt(0).getViewTreeObserver()
+ final View sharedElement = sharedElements.valueAt(0);
+ sharedElement.getViewTreeObserver()
.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
- sharedElements.valueAt(0).getViewTreeObserver().removeOnPreDrawListener(this);
+ sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
viewsReady(sharedElements);
return true;
}
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 672ef7b..4374622 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -166,11 +166,12 @@
* activity: if the activity is stopped, no fragments inside of it can be
* started; when the activity is destroyed, all fragments will be destroyed.
*
- * <p>All subclasses of Fragment must include a public empty constructor.
+ * <p>All subclasses of Fragment must include a public no-argument constructor.
* The framework will often re-instantiate a fragment class when needed,
* in particular during state restore, and needs to be able to find this
- * constructor to instantiate it. If the empty constructor is not available,
- * a runtime exception will occur in some cases during state restore.
+ * constructor to instantiate it. If the no-argument constructor is not
+ * available, a runtime exception will occur in some cases during state
+ * restore.
*
* <p>Topics covered here:
* <ol>
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 9483680..8fa1fd53 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -327,6 +327,8 @@
public void notifyActivityDrawn(IBinder token) throws RemoteException;
public ActivityOptions getActivityOptions(IBinder token) throws RemoteException;
+ public void bootAnimationComplete() throws RemoteException;
+
public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
public boolean isImmersive(IBinder token) throws RemoteException;
public boolean isTopActivityImmersive() throws RemoteException;
@@ -772,4 +774,5 @@
int GET_APP_TASK_THUMBNAIL_SIZE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+234;
int RELEASE_ACTIVITY_INSTANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+235;
int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
+ int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ea041e8..4a21913 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -38,6 +38,7 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.security.Credentials;
import android.service.restrictions.RestrictionsReceiver;
import android.util.Log;
@@ -49,6 +50,8 @@
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -1838,6 +1841,32 @@
}
/**
+ * Called by a device or profile owner to install a certificate and private key pair. The
+ * keypair will be visible to all apps within the profile.
+ *
+ * @param who Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param privKey The private key to install.
+ * @param cert The certificate to install.
+ * @param alias The private key alias under which to install the certificate. If a certificate
+ * with that alias already exists, it will be overwritten.
+ * @return {@code true} if the keys were installed, {@code false} otherwise.
+ */
+ public boolean installKeyPair(ComponentName who, PrivateKey privKey, Certificate cert,
+ String alias) {
+ try {
+ final byte[] pemCert = Credentials.convertToPem(cert);
+ return mService.installKeyPair(who, privKey.getEncoded(), pemCert, alias);
+ } catch (CertificateException e) {
+ Log.w(TAG, "Error encoding certificate", e);
+ } catch (IOException e) {
+ Log.w(TAG, "Error writing certificate", e);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy service", e);
+ }
+ return false;
+ }
+
+ /**
* Returns the alias of a given CA certificate in the certificate store, or null if it
* doesn't exist.
*/
@@ -3245,11 +3274,15 @@
* Called by profile or device owners to update {@link Settings.Secure} settings. Validation
* that the value of the setting is in the correct form for the setting type should be performed
* by the caller.
- * <p>The settings that can be updated with this method are:
+ * <p>The settings that can be updated by a profile or device owner with this method are:
* <ul>
* <li>{@link Settings.Secure#DEFAULT_INPUT_METHOD}</li>
* <li>{@link Settings.Secure#SKIP_FIRST_USE_HINTS}</li>
* </ul>
+ * <p>A device owner can additionally update the following settings:
+ * <ul>
+ * <li>{@link Settings.Secure#LOCATION_MODE}</li>
+ * </ul>
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param setting The name of the setting to update.
* @param value The value to update the setting to.
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 57d8b95..c8e1780 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -126,6 +126,8 @@
void uninstallCaCert(in ComponentName admin, in String alias);
void enforceCanManageCaCerts(in ComponentName admin);
+ boolean installKeyPair(in ComponentName who, in byte[] privKeyBuffer, in byte[] certBuffer, String alias);
+
void addPersistentPreferredActivity(in ComponentName admin, in IntentFilter filter, in ComponentName activity);
void clearPackagePersistentPreferredActivities(in ComponentName admin, String packageName);
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index 724856a..62734f2 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -32,12 +32,15 @@
private final int jobId;
private final PersistableBundle extras;
private final IBinder callback;
+ private final boolean overrideDeadlineExpired;
/** @hide */
- public JobParameters(int jobId, PersistableBundle extras, IBinder callback) {
+ public JobParameters(IBinder callback, int jobId, PersistableBundle extras,
+ boolean overrideDeadlineExpired) {
this.jobId = jobId;
this.extras = extras;
this.callback = callback;
+ this.overrideDeadlineExpired = overrideDeadlineExpired;
}
/**
@@ -56,6 +59,16 @@
return extras;
}
+ /**
+ * For jobs with {@link android.app.job.JobInfo.Builder#setOverrideDeadline(long)} set, this
+ * provides an easy way to tell whether the job is being executed due to the deadline
+ * expiring. Note: If the job is running because its deadline expired, it implies that its
+ * constraints will not be met.
+ */
+ public boolean isOverrideDeadlineExpired() {
+ return overrideDeadlineExpired;
+ }
+
/** @hide */
public IJobCallback getCallback() {
return IJobCallback.Stub.asInterface(callback);
@@ -65,6 +78,7 @@
jobId = in.readInt();
extras = in.readPersistableBundle();
callback = in.readStrongBinder();
+ overrideDeadlineExpired = in.readInt() == 1;
}
@Override
@@ -77,6 +91,7 @@
dest.writeInt(jobId);
dest.writePersistableBundle(extras);
dest.writeStrongBinder(callback);
+ dest.writeInt(overrideDeadlineExpired ? 1 : 0);
}
public static final Creator<JobParameters> CREATOR = new Creator<JobParameters>() {
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index d77a77b..2276229 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -51,6 +51,7 @@
private int mConnState;
private final Object mStateLock = new Object();
private Boolean mDeviceBusy = false;
+ private Boolean mIsCongested = false;
private int mTransport;
private static final int CONN_STATE_IDLE = 0;
@@ -616,7 +617,7 @@
+ " congested=" + congested);
if (!address.equals(mDevice.getAddress())) return;
try {
- mCallback.onConnectionCongested(BluetoothGatt.this, congested);
+ mIsCongested = congested;
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 19900ec..a915620 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -152,18 +152,4 @@
*/
public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
}
-
- /**
- * Callback indicating that a remote device connection congestestion status has changed.
- *
- * An application should refrain from sending additional data to a remote device when
- * a callback is received with the congested flag set to true. Once the congestion status
- * is cleared up, the application will receive an additional callback with the congested
- * flag set to false.
- *
- * @param gatt The GATT client associated with the remote device
- * @param congested true, if the connection is currently congested
- */
- public void onConnectionCongested(BluetoothGatt gatt, boolean congested) {
- }
}
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index c8df60e..a7f117b 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -48,6 +48,7 @@
private BluetoothAdapter mAdapter;
private IBluetoothGatt mService;
private BluetoothGattServerCallback mCallback;
+ private Boolean mIsCongested = false;
private Object mServerIfLock = new Object();
private int mServerIf;
@@ -297,7 +298,7 @@
if (device == null) return;
try {
- mCallback.onConnectionCongested(device, congested);
+ mIsCongested = congested;
} catch (Exception ex) {
Log.w(TAG, "Unhandled exception in callback", ex);
}
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index b0ddc26..1dd06f2 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -145,18 +145,4 @@
*/
public void onNotificationSent(BluetoothDevice device, int status) {
}
-
- /**
- * Callback indicating that a remote device connection congestestion status has changed.
- *
- * An application should refrain from sending additional data (notifications, indications
- * etc.) to a remote device when a callback is received with the congested flag set
- * to true. Once the congestion status is cleared up, the application will receive an
- * additional callback with the congested flag set to false.
- *
- * @param device The remote device that triggered the congestion state change
- * @param congested true, if the connection is currently congested
- */
- public void onConnectionCongested(BluetoothDevice device, boolean congested) {
- }
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index b2b48e8..a09fee9 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -1763,7 +1763,7 @@
* @param extras any extras to pass to the SyncAdapter.
*/
public static void requestSync(Account account, String authority, Bundle extras) {
- requestSyncAsUser(account, authority, UserHandle.getCallingUserId(), extras);
+ requestSyncAsUser(account, authority, UserHandle.myUserId(), extras);
}
/**
@@ -1938,7 +1938,7 @@
* @param sync true if the provider should be synced when tickles are received for it
*/
public static void setSyncAutomatically(Account account, String authority, boolean sync) {
- setSyncAutomaticallyAsUser(account, authority, sync, UserHandle.getCallingUserId());
+ setSyncAutomaticallyAsUser(account, authority, sync, UserHandle.myUserId());
}
/**
@@ -2165,7 +2165,7 @@
* @param sync the master auto-sync setting that applies to all the providers and accounts
*/
public static void setMasterSyncAutomatically(boolean sync) {
- setMasterSyncAutomaticallyAsUser(sync, UserHandle.getCallingUserId());
+ setMasterSyncAutomaticallyAsUser(sync, UserHandle.myUserId());
}
/**
@@ -2297,7 +2297,7 @@
* @return true if there is a pending sync with the matching account and authority
*/
public static boolean isSyncPending(Account account, String authority) {
- return isSyncPendingAsUser(account, authority, UserHandle.getCallingUserId());
+ return isSyncPendingAsUser(account, authority, UserHandle.myUserId());
}
/**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index f979a0c..4f20705 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2037,6 +2037,7 @@
* argument for use by system server and other multi-user aware code.
* @hide
*/
+ @SystemApi
public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, UserHandle user) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
@@ -3062,6 +3063,14 @@
* "content://foo". It will not remove any prefix grants that exist at a
* higher level.
*
+ * <p>Prior to {@link android.os.Build.VERSION_CODES#L}, if you did not have
+ * regular permission access to a Uri, but had received access to it through
+ * a specific Uri permission grant, you could not revoke that grant with this
+ * function and a {@link SecurityException} would be thrown. As of
+ * {@link android.os.Build.VERSION_CODES#L}, this function will not throw a security exception,
+ * but will remove whatever permission grants to the Uri had been given to the app
+ * (or none).</p>
+ *
* @param uri The Uri you would like to revoke access to.
* @param modeFlags The desired access modes. Any combination of
* {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 8d3126d..641f843e 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -657,6 +657,7 @@
softInputMode = orig.softInputMode;
uiOptions = orig.uiOptions;
parentActivityName = orig.parentActivityName;
+ maxRecents = orig.maxRecents;
}
/**
@@ -728,6 +729,7 @@
dest.writeInt(uiOptions);
dest.writeString(parentActivityName);
dest.writeInt(persistableMode);
+ dest.writeInt(maxRecents);
}
public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -754,5 +756,6 @@
uiOptions = source.readInt();
parentActivityName = source.readString();
persistableMode = source.readInt();
+ maxRecents = source.readInt();
}
}
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 3e1f60a..6d9c58b 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -259,12 +259,6 @@
void addCrossProfileIntentFilter(in IntentFilter intentFilter, String ownerPackage,
int ownerUserId, int sourceUserId, int targetUserId, int flags);
- void addCrossProfileIntentsForPackage(in String packageName, int sourceUserId,
- int targetUserId);
-
- void removeCrossProfileIntentsForPackage(String packageName, int sourceUserId,
- int targetUserId);
-
void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage, int ownerUserId);
/**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5ce968b..8f3d90f 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3893,22 +3893,6 @@
public abstract void clearCrossProfileIntentFilters(int sourceUserId);
/**
- * Forwards all intents for {@link packageName} for user {@link sourceUserId} to user
- * {@link targetUserId}.
- * @hide
- */
- public abstract void addCrossProfileIntentsForPackage(String packageName,
- int sourceUserId, int targetUserId);
-
- /**
- * Removes all intents for {@link packageName} for user {@link sourceUserId} to user
- * {@link targetUserId}.
- * @hide
- */
- public abstract void removeCrossProfileIntentsForPackage(String packageName,
- int sourceUserId, int targetUserId);
-
- /**
* @hide
*/
public abstract Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index ddb0a6d..ffde7ce 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3308,7 +3308,8 @@
info.softInputMode = target.info.softInputMode;
info.uiOptions = target.info.uiOptions;
info.parentActivityName = target.info.parentActivityName;
-
+ info.maxRecents = target.info.maxRecents;
+
Activity a = new Activity(mParseActivityAliasArgs, info);
if (outError[0] != null) {
sa.recycle();
diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
index 843f117..0057f61 100644
--- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java
@@ -143,7 +143,6 @@
}
checkNotClosed();
- checkLegalToCapture();
handler = checkHandler(handler, callback);
@@ -166,7 +165,6 @@
}
checkNotClosed();
- checkLegalToCapture();
handler = checkHandler(handler, callback);
@@ -188,7 +186,6 @@
}
checkNotClosed();
- checkLegalToCapture();
handler = checkHandler(handler, callback);
@@ -211,7 +208,6 @@
}
checkNotClosed();
- checkLegalToCapture();
handler = checkHandler(handler, callback);
@@ -542,13 +538,6 @@
}
}
- private void checkLegalToCapture() {
- if (mAborting) {
- throw new IllegalStateException(
- "Session is aborting captures; new captures are not permitted");
- }
- }
-
private void checkNotClosed() {
if (mClosed) {
throw new IllegalStateException(
diff --git a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
index 3c0e0e4..c36b63a 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
@@ -165,6 +165,12 @@
private static void mapCharacteristicsFromParameters(CameraMetadataNative m,
Camera.Parameters p) {
+
+ /*
+ * colorCorrection.*
+ */
+ m.set(COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES,
+ new int[] { COLOR_CORRECTION_ABERRATION_MODE_FAST });
/*
* control.ae*
*/
@@ -196,6 +202,12 @@
mapJpeg(m, p);
/*
+ * noiseReduction.*
+ */
+ m.set(NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES,
+ new int[] { NOISE_REDUCTION_MODE_FAST });
+
+ /*
* scaler.*
*/
mapScaler(m, p);
@@ -626,6 +638,7 @@
// Note: We only list public keys. Native HALs should list ALL keys regardless of visibility.
Key<?> availableKeys[] = new Key<?>[] {
+ CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES ,
CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES ,
CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES ,
CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES ,
@@ -642,6 +655,7 @@
CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES ,
CameraCharacteristics.LENS_FACING ,
CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS ,
+ CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES ,
CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES ,
CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_STREAMS ,
CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT ,
@@ -653,6 +667,7 @@
CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE ,
CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE ,
CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE ,
+ CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE ,
CameraCharacteristics.SENSOR_ORIENTATION ,
CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES ,
CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT ,
@@ -676,6 +691,7 @@
*/
{
CaptureRequest.Key<?> defaultAvailableKeys[] = new CaptureRequest.Key<?>[] {
+ CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE,
CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
CaptureRequest.CONTROL_AE_LOCK,
@@ -699,6 +715,7 @@
CaptureRequest.JPEG_THUMBNAIL_QUALITY,
CaptureRequest.JPEG_THUMBNAIL_SIZE,
CaptureRequest.LENS_FOCAL_LENGTH,
+ CaptureRequest.NOISE_REDUCTION_MODE,
CaptureRequest.SCALER_CROP_REGION,
CaptureRequest.STATISTICS_FACE_DETECT_MODE,
};
@@ -723,6 +740,7 @@
*/
{
CaptureResult.Key<?> defaultAvailableKeys[] = new CaptureResult.Key<?>[] {
+ CaptureResult.COLOR_CORRECTION_ABERRATION_MODE ,
CaptureResult.CONTROL_AE_ANTIBANDING_MODE ,
CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION ,
CaptureResult.CONTROL_AE_LOCK ,
@@ -740,6 +758,7 @@
CaptureResult.JPEG_QUALITY ,
CaptureResult.JPEG_THUMBNAIL_QUALITY ,
CaptureResult.LENS_FOCAL_LENGTH ,
+ CaptureResult.NOISE_REDUCTION_MODE ,
CaptureResult.REQUEST_PIPELINE_DEPTH ,
CaptureResult.SCALER_CROP_REGION ,
CaptureResult.SENSOR_TIMESTAMP ,
@@ -844,6 +863,13 @@
m.set(SENSOR_INFO_PHYSICAL_SIZE, new SizeF(width, height)); // in mm
}
+
+ /*
+ * sensor.info.timestampSource
+ */
+ {
+ m.set(SENSOR_INFO_TIMESTAMP_SOURCE, SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN);
+ }
}
private static void mapStatistics(CameraMetadataNative m, Parameters p) {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
index 42ee4fa..42fe897 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyRequestMapper.java
@@ -80,6 +80,20 @@
}
}
+ /*
+ * colorCorrection.*
+ */
+ // colorCorrection.aberrationMode
+ {
+ int aberrationMode = ParamsUtils.getOrDefault(request,
+ COLOR_CORRECTION_ABERRATION_MODE,
+ /*defaultValue*/COLOR_CORRECTION_ABERRATION_MODE_FAST);
+
+ if (aberrationMode != COLOR_CORRECTION_ABERRATION_MODE_FAST) {
+ Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
+ "colorCorrection.aberrationMode = " + aberrationMode);
+ }
+ }
/*
* control.ae*
@@ -419,6 +433,21 @@
}
}
}
+
+ /*
+ * noiseReduction.*
+ */
+ // noiseReduction.mode
+ {
+ int mode = ParamsUtils.getOrDefault(request,
+ NOISE_REDUCTION_MODE,
+ /*defaultValue*/NOISE_REDUCTION_MODE_FAST);
+
+ if (mode != NOISE_REDUCTION_MODE_FAST) {
+ Log.w(TAG, "convertRequestToMetadata - Ignoring unsupported " +
+ "noiseReduction.mode = " + mode);
+ }
+ }
}
private static boolean checkForCompleteGpsData(Location location) {
diff --git a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
index ddaa6ee..bad1d28 100644
--- a/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
+++ b/core/java/android/hardware/camera2/legacy/LegacyResultMapper.java
@@ -28,14 +28,12 @@
import android.hardware.camera2.params.MeteringRectangle;
import android.hardware.camera2.utils.ListUtils;
import android.hardware.camera2.utils.ParamsUtils;
-import android.location.Location;
import android.util.Log;
import android.util.Size;
import java.util.ArrayList;
import java.util.List;
-import static com.android.internal.util.Preconditions.*;
import static android.hardware.camera2.CaptureResult.*;
/**
@@ -73,7 +71,7 @@
result = new CameraMetadataNative(mCachedResult);
cached = true;
} else {
- result = convertResultMetadata(legacyRequest, timestamp);
+ result = convertResultMetadata(legacyRequest);
cached = false;
// Always cache a *copy* of the metadata result,
@@ -106,12 +104,9 @@
* Generate capture result metadata from the legacy camera request.
*
* @param legacyRequest a non-{@code null} legacy request containing the latest parameters
- * @param timestamp the timestamp to use for this result in nanoseconds.
- *
* @return a {@link CameraMetadataNative} object containing result metadata.
*/
- private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest,
- long timestamp) {
+ private static CameraMetadataNative convertResultMetadata(LegacyRequest legacyRequest) {
CameraCharacteristics characteristics = legacyRequest.characteristics;
CaptureRequest request = legacyRequest.captureRequest;
Size previewSize = legacyRequest.previewSize;
@@ -125,6 +120,15 @@
request.get(CaptureRequest.SCALER_CROP_REGION), previewSize, params);
/*
+ * colorCorrection
+ */
+ // colorCorrection.aberrationMode
+ {
+ // Always hardcoded to FAST
+ result.set(COLOR_CORRECTION_ABERRATION_MODE, COLOR_CORRECTION_ABERRATION_MODE_FAST);
+ }
+
+ /*
* control
*/
@@ -274,7 +278,12 @@
Log.w(TAG, "Null thumbnail size received from parameters.");
}
- // TODO: Remaining result metadata tags conversions.
+ /*
+ * noiseReduction.*
+ */
+ // noiseReduction.mode
+ result.set(NOISE_REDUCTION_MODE, NOISE_REDUCTION_MODE_FAST);
+
return result;
}
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index e6ff17b..e6da670 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -374,6 +374,9 @@
}
mIntermediateBufferSize = bestPreviewDimen;
+ mParams.setPreviewSize(mIntermediateBufferSize.getWidth(),
+ mIntermediateBufferSize.getHeight());
+
if (DEBUG) {
Log.d(TAG, "Intermediate buffer selected with dimens: " +
bestPreviewDimen.toString());
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java
index c37fb5b..9d92fd9 100644
--- a/core/java/android/hardware/hdmi/HdmiTvClient.java
+++ b/core/java/android/hardware/hdmi/HdmiTvClient.java
@@ -36,9 +36,9 @@
private static final String TAG = "HdmiTvClient";
/**
- * Size of MHL scratchpad register.
+ * Size of MHL register for vendor command
*/
- public static final int SCRATCHPAD_DATA_SIZE = 16;
+ public static final int VENDOR_DATA_SIZE = 16;
HdmiTvClient(IHdmiControlService service) {
super(service);
@@ -332,31 +332,31 @@
}
/**
- * Interface used to get incoming MHL scratchpad command.
+ * Interface used to get incoming MHL vendor command.
*/
- public interface HdmiMhlScratchpadCommandListener {
+ public interface HdmiMhlVendorCommandListener {
void onReceived(int portId, int offset, int length, byte[] data);
}
/**
- * Set {@link HdmiMhlScratchpadCommandListener} to get incoming MHL sSratchpad command.
+ * Set {@link HdmiMhlVendorCommandListener} to get incoming MHL vendor command.
*
- * @param listener to receive incoming MHL Scratchpad command
+ * @param listener to receive incoming MHL vendor command
*/
- public void setHdmiMhlScratchpadCommandListener(HdmiMhlScratchpadCommandListener listener) {
+ public void setHdmiMhlVendorCommandListener(HdmiMhlVendorCommandListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null.");
}
try {
- mService.addHdmiMhlScratchpadCommandListener(getListenerWrapper(listener));
+ mService.addHdmiMhlVendorCommandListener(getListenerWrapper(listener));
} catch (RemoteException e) {
- Log.e(TAG, "failed to set hdmi mhl scratchpad command listener: ", e);
+ Log.e(TAG, "failed to set hdmi mhl vendor command listener: ", e);
}
}
- private IHdmiMhlScratchpadCommandListener getListenerWrapper(
- final HdmiMhlScratchpadCommandListener listener) {
- return new IHdmiMhlScratchpadCommandListener.Stub() {
+ private IHdmiMhlVendorCommandListener getListenerWrapper(
+ final HdmiMhlVendorCommandListener listener) {
+ return new IHdmiMhlVendorCommandListener.Stub() {
@Override
public void onReceived(int portId, int offset, int length, byte[] data) {
listener.onReceived(portId, offset, length, data);
@@ -365,29 +365,29 @@
}
/**
- * Send MHL Scratchpad command to the device connected to a port of the given portId.
+ * Send MHL vendor command to the device connected to a port of the given portId.
*
- * @param portId id of port to send MHL Scratchpad command
+ * @param portId id of port to send MHL vendor command
* @param offset offset in the in given data
* @param length length of data. offset + length should be bound to length of data.
- * @param data container for Scratchpad data. It should be 16 bytes.
+ * @param data container for vendor command data. It should be 16 bytes.
* @throws IllegalArgumentException if the given parameters are invalid
*/
- public void sendScratchpadCommand(int portId, int offset, int length, byte[] data) {
- if (data == null || data.length != SCRATCHPAD_DATA_SIZE) {
- throw new IllegalArgumentException("Invalid scratchpad data.");
+ public void sendMhlVendorCommand(int portId, int offset, int length, byte[] data) {
+ if (data == null || data.length != VENDOR_DATA_SIZE) {
+ throw new IllegalArgumentException("Invalid vendor command data.");
}
- if (offset < 0 || offset >= SCRATCHPAD_DATA_SIZE) {
+ if (offset < 0 || offset >= VENDOR_DATA_SIZE) {
throw new IllegalArgumentException("Invalid offset:" + offset);
}
- if (length < 0 || offset + length > SCRATCHPAD_DATA_SIZE) {
+ if (length < 0 || offset + length > VENDOR_DATA_SIZE) {
throw new IllegalArgumentException("Invalid length:" + length);
}
try {
- mService.sendScratchpadCommand(portId, offset, length, data);
+ mService.sendMhlVendorCommand(portId, offset, length, data);
} catch (RemoteException e) {
- Log.e(TAG, "failed to send scratchpad command: ", e);
+ Log.e(TAG, "failed to send vendor command: ", e);
}
}
}
diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
index 3bd45ed..602f866 100644
--- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl
@@ -22,7 +22,7 @@
import android.hardware.hdmi.IHdmiDeviceEventListener;
import android.hardware.hdmi.IHdmiHotplugEventListener;
import android.hardware.hdmi.IHdmiInputChangeListener;
-import android.hardware.hdmi.IHdmiMhlScratchpadCommandListener;
+import android.hardware.hdmi.IHdmiMhlVendorCommandListener;
import android.hardware.hdmi.IHdmiRecordListener;
import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
import android.hardware.hdmi.IHdmiVendorCommandListener;
@@ -67,6 +67,6 @@
void stopOneTouchRecord(int recorderAddress);
void startTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource);
void clearTimerRecording(int recorderAddress, int sourceType, in byte[] recordSource);
- void sendScratchpadCommand(int portId, int offset, int length, in byte[] data);
- void addHdmiMhlScratchpadCommandListener(IHdmiMhlScratchpadCommandListener listener);
+ void sendMhlVendorCommand(int portId, int offset, int length, in byte[] data);
+ void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener);
}
diff --git a/core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl b/core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl
similarity index 84%
rename from core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl
rename to core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl
index 4176597..4696677 100644
--- a/core/java/android/hardware/hdmi/IHdmiMhlScratchpadCommandListener.aidl
+++ b/core/java/android/hardware/hdmi/IHdmiMhlVendorCommandListener.aidl
@@ -17,11 +17,10 @@
package android.hardware.hdmi;
/**
- * Callback interface definition for MHL client to get the scratchpad
- * command.
+ * Callback interface definition for MHL client to get the vendor command.
*
* @hide
*/
- oneway interface IHdmiMhlScratchpadCommandListener {
+ oneway interface IHdmiMhlVendorCommandListener {
void onReceived(int portId, int offset, int length, in byte[] data);
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 70b402d..7c69a7d 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -48,6 +48,8 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.HashMap;
+import libcore.net.event.NetworkEventDispatcher;
+
/**
* Class that answers queries about the state of network connectivity. It also
* notifies applications when network connectivity changes. Get an instance
@@ -2467,7 +2469,20 @@
* @return {@code true} on success, {@code false} if the {@link Network} is no longer valid.
*/
public static boolean setProcessDefaultNetwork(Network network) {
- return NetworkUtils.bindProcessToNetwork(network == null ? NETID_UNSET : network.netId);
+ int netId = (network == null) ? NETID_UNSET : network.netId;
+ if (netId == NetworkUtils.getNetworkBoundToProcess()) {
+ return true;
+ }
+ if (NetworkUtils.bindProcessToNetwork(netId)) {
+ // Must flush DNS cache as new network may have different DNS resolutions.
+ InetAddress.clearDnsCache();
+ // Must flush socket pool as idle sockets will be bound to previous network and may
+ // cause subsequent fetches to be performed on old network.
+ NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged();
+ return true;
+ } else {
+ return false;
+ }
}
/**
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index e686be7..58f0fc0 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -37,6 +37,8 @@
import com.android.okhttp.ConnectionPool;
import com.android.okhttp.HostResolver;
+import com.android.okhttp.HttpHandler;
+import com.android.okhttp.HttpsHandler;
import com.android.okhttp.OkHttpClient;
/**
@@ -58,7 +60,10 @@
// Objects used to perform per-network operations such as getSocketFactory
// and openConnection, and a lock to protect access to them.
private volatile NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
- private volatile OkHttpClient mOkHttpClient = null;
+ // mLock should be used to control write access to mConnectionPool and mHostResolver.
+ // maybeInitHttpClient() must be called prior to reading either variable.
+ private volatile ConnectionPool mConnectionPool = null;
+ private volatile HostResolver mHostResolver = null;
private Object mLock = new Object();
// Default connection pool values. These are evaluated at startup, just
@@ -195,37 +200,34 @@
return mNetworkBoundSocketFactory;
}
- // TODO: This creates an OkHttpClient with its own connection pool for
+ // TODO: This creates a connection pool and host resolver for
// every Network object, instead of one for every NetId. This is
// suboptimal, because an app could potentially have more than one
// Network object for the same NetId, causing increased memory footprint
// and performance penalties due to lack of connection reuse (connection
// setup time, congestion window growth time, etc.).
//
- // Instead, investigate only having one OkHttpClient for every NetId,
- // perhaps by using a static HashMap of NetIds to OkHttpClient objects. The
- // tricky part is deciding when to remove an OkHttpClient; a WeakHashMap
- // shouldn't be used because whether a Network is referenced doesn't
- // correlate with whether a new Network will be instantiated in the near
- // future with the same NetID. A good solution would involve purging empty
- // (or when all connections are timed out) ConnectionPools.
+ // Instead, investigate only having one connection pool and host resolver
+ // for every NetId, perhaps by using a static HashMap of NetIds to
+ // connection pools and host resolvers. The tricky part is deciding when
+ // to remove a map entry; a WeakHashMap shouldn't be used because whether
+ // a Network is referenced doesn't correlate with whether a new Network
+ // will be instantiated in the near future with the same NetID. A good
+ // solution would involve purging empty (or when all connections are timed
+ // out) ConnectionPools.
private void maybeInitHttpClient() {
- if (mOkHttpClient == null) {
- synchronized (mLock) {
- if (mOkHttpClient == null) {
- HostResolver hostResolver = new HostResolver() {
- @Override
- public InetAddress[] getAllByName(String host) throws UnknownHostException {
- return Network.this.getAllByName(host);
- }
- };
- ConnectionPool pool = new ConnectionPool(httpMaxConnections,
- httpKeepAliveDurationMs);
- mOkHttpClient = new OkHttpClient()
- .setSocketFactory(getSocketFactory())
- .setHostResolver(hostResolver)
- .setConnectionPool(pool);
- }
+ synchronized (mLock) {
+ if (mHostResolver == null) {
+ mHostResolver = new HostResolver() {
+ @Override
+ public InetAddress[] getAllByName(String host) throws UnknownHostException {
+ return Network.this.getAllByName(host);
+ }
+ };
+ }
+ if (mConnectionPool == null) {
+ mConnectionPool = new ConnectionPool(httpMaxConnections,
+ httpKeepAliveDurationMs);
}
}
}
@@ -242,13 +244,23 @@
public URLConnection openConnection(URL url) throws IOException {
maybeInitHttpClient();
String protocol = url.getProtocol();
- URLStreamHandler handler = mOkHttpClient.createURLStreamHandler(protocol);
- if (handler == null) {
+ OkHttpClient client;
+ // TODO: HttpHandler creates OkHttpClients that share the default ResponseCache.
+ // Could this cause unexpected behavior?
+ // TODO: Should the network's proxy be specified?
+ if (protocol.equals("http")) {
+ client = HttpHandler.createHttpOkHttpClient(null /* proxy */);
+ } else if (protocol.equals("https")) {
+ client = HttpsHandler.createHttpsOkHttpClient(null /* proxy */);
+ } else {
// OkHttpClient only supports HTTP and HTTPS and returns a null URLStreamHandler if
// passed another protocol.
throw new MalformedURLException("Invalid URL or unrecognized protocol " + protocol);
}
- return new URL(url, "", handler).openConnection();
+ return client.setSocketFactory(getSocketFactory())
+ .setHostResolver(mHostResolver)
+ .setConnectionPool(mConnectionPool)
+ .open(url);
}
/**
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 8df9916..80e5b91 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -223,6 +223,9 @@
* Called by the bearer code when it has a new score for this network.
*/
public void sendNetworkScore(int score) {
+ if (score < 0) {
+ throw new IllegalArgumentException("Score must be >= 0");
+ }
queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
}
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 050be40..c848993 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -62,7 +62,8 @@
* conflict with each other. The system takes several actions to address
* these issues. Here are some key points:
* <ul>
- * <li>User action is required to create a VPN connection.</li>
+ * <li>User action is required the first time an application creates a VPN
+ * connection.</li>
* <li>There can be only one VPN connection running at the same time. The
* existing interface is deactivated when a new one is created.</li>
* <li>A system-managed notification is shown during the lifetime of a
@@ -82,8 +83,8 @@
* other methods in this class, and the right can be revoked at any time.
* Here are the general steps to create a VPN connection:
* <ol>
- * <li>When the user press the button to connect, call {@link #prepare}
- * and launch the returned intent.</li>
+ * <li>When the user presses the button to connect, call {@link #prepare}
+ * and launch the returned intent, if non-null.</li>
* <li>When the application becomes prepared, start the service.</li>
* <li>Create a tunnel to the remote server and negotiate the network
* parameters for the VPN connection.</li>
@@ -130,7 +131,8 @@
/**
* Prepare to establish a VPN connection. This method returns {@code null}
- * if the VPN application is already prepared. Otherwise, it returns an
+ * if the VPN application is already prepared or if the user has previously
+ * consented to the VPN application. Otherwise, it returns an
* {@link Intent} to a system activity. The application should launch the
* activity using {@link Activity#startActivityForResult} to get itself
* prepared. The activity may pop up a dialog to require user action, and
@@ -144,6 +146,10 @@
* it becomes prepared again, subsequent calls to other methods in this
* class will fail.
*
+ * <p>The user may disable the VPN at any time while it is activated, in
+ * which case this method will return an intent the next time it is
+ * executed to obtain the user's consent again.
+ *
* @see #onRevoke
*/
public static Intent prepare(Context context) {
@@ -212,6 +218,8 @@
*
* @return {@code true} on success.
* @see Builder#addAddress
+ *
+ * @hide
*/
public boolean addAddress(InetAddress address, int prefixLength) {
check(address, prefixLength);
@@ -240,6 +248,8 @@
* @param prefixLength The prefix length of the address.
*
* @return {@code true} on success.
+ *
+ * @hide
*/
public boolean removeAddress(InetAddress address, int prefixLength) {
check(address, prefixLength);
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 3286627..b5295fb 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -41,6 +41,7 @@
int getUserSerialNumber(int userHandle);
int getUserHandle(int userSerialNumber);
Bundle getUserRestrictions(int userHandle);
+ boolean hasUserRestriction(in String restrictionKey, int userHandle);
void setUserRestrictions(in Bundle restrictions, int userHandle);
void setApplicationRestrictions(in String packageName, in Bundle restrictions,
int userHandle);
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 00e2e22..18b2082 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -248,7 +248,7 @@
* {@link #PROXIMITY_SCREEN_OFF_WAKE_LOCK} wake lock until the proximity sensor
* indicates that an object is not in close proximity.
*/
- public static final int WAIT_FOR_DISTANT_PROXIMITY = 1;
+ public static final int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1;
/**
* Brightness value for fully on.
@@ -961,8 +961,8 @@
* </p>
*
* @param flags Combination of flag values to modify the release behavior.
- * Currently only {@link #WAIT_FOR_DISTANT_PROXIMITY} is supported. Passing 0 is
- * equivalent to calling {@link #release()}.
+ * Currently only {@link #RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY} is supported.
+ * Passing 0 is equivalent to calling {@link #release()}.
*/
public void release(int flags) {
synchronized (mToken) {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 33fda4a..c76ff11 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -630,7 +630,13 @@
* @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
*/
public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
- return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
+ try {
+ return mService.hasUserRestriction(restrictionKey,
+ userHandle.getIdentifier());
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not check user restrictions", re);
+ return false;
+ }
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 01fda47..440b1ec 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3150,6 +3150,11 @@
/** @hide */
public static boolean putStringForUser(ContentResolver resolver, String name, String value,
int userHandle) {
+ if (LOCATION_MODE.equals(name)) {
+ // HACK ALERT: temporary hack to work around b/10491283.
+ // TODO: once b/10491283 fixed, remove this hack
+ return setLocationModeForUser(resolver, Integer.parseInt(value), userHandle);
+ }
if (MOVED_TO_GLOBAL.contains(name)) {
Log.w(TAG, "Setting " + name + " has moved from android.provider.Settings.System"
+ " to android.provider.Settings.Global");
@@ -3265,11 +3270,6 @@
/** @hide */
public static boolean putIntForUser(ContentResolver cr, String name, int value,
int userHandle) {
- if (LOCATION_MODE.equals(name)) {
- // HACK ALERT: temporary hack to work around b/10491283.
- // TODO: once b/10491283 fixed, remove this hack
- return setLocationModeForUser(cr, value, userHandle);
- }
return putStringForUser(cr, name, Integer.toString(value), userHandle);
}
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index a4b6e92..9be220e 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -46,7 +46,6 @@
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
-import java.util.TreeSet;
/**
*
@@ -1567,10 +1566,10 @@
@Override
public Set<Locale> run(ITextToSpeechService service) throws RemoteException {
List<Voice> voices = service.getVoices();
- if (voices != null) {
- return new TreeSet<Locale>();
+ if (voices == null) {
+ return new HashSet<Locale>();
}
- TreeSet<Locale> locales = new TreeSet<Locale>();
+ HashSet<Locale> locales = new HashSet<Locale>();
for (Voice voice : voices) {
locales.add(voice.getLocale());
}
@@ -1593,7 +1592,7 @@
@Override
public Set<Voice> run(ITextToSpeechService service) throws RemoteException {
List<Voice> voices = service.getVoices();
- return (voices != null) ? new TreeSet<Voice>(voices) : new TreeSet<Voice>();
+ return (voices != null) ? new HashSet<Voice>(voices) : new HashSet<Voice>();
}
}, null, "getVoices");
}
diff --git a/core/java/android/transition/TransitionSet.java b/core/java/android/transition/TransitionSet.java
index 56db674..669621eb3 100644
--- a/core/java/android/transition/TransitionSet.java
+++ b/core/java/android/transition/TransitionSet.java
@@ -390,7 +390,20 @@
ArrayList<TransitionValues> endValuesList) {
startValues = removeExcludes(startValues);
endValues = removeExcludes(endValues);
- for (Transition childTransition : mTransitions) {
+ long startDelay = getStartDelay();
+ int numTransitions = mTransitions.size();
+ for (int i = 0; i < numTransitions; i++) {
+ Transition childTransition = mTransitions.get(i);
+ // We only set the start delay on the first transition if we are playing
+ // the transitions sequentially.
+ if (startDelay > 0 && (mPlayTogether || i == 0)) {
+ long childStartDelay = childTransition.getStartDelay();
+ if (childStartDelay > 0) {
+ childTransition.setStartDelay(startDelay + childStartDelay);
+ } else {
+ childTransition.setStartDelay(startDelay);
+ }
+ }
childTransition.createAnimators(sceneRoot, startValues, endValues, startValuesList,
endValuesList);
}
@@ -419,11 +432,17 @@
*/
@Override
protected void runAnimators() {
+ if (mTransitions.isEmpty()) {
+ start();
+ end();
+ return;
+ }
setupStartEndListeners();
+ int numTransitions = mTransitions.size();
if (!mPlayTogether) {
// Setup sequence with listeners
// TODO: Need to add listeners in such a way that we can remove them later if canceled
- for (int i = 1; i < mTransitions.size(); ++i) {
+ for (int i = 1; i < numTransitions; ++i) {
Transition previousTransition = mTransitions.get(i - 1);
final Transition nextTransition = mTransitions.get(i);
previousTransition.addListener(new TransitionListenerAdapter() {
@@ -439,8 +458,8 @@
firstTransition.runAnimators();
}
} else {
- for (Transition childTransition : mTransitions) {
- childTransition.runAnimators();
+ for (int i = 0; i < numTransitions; ++i) {
+ mTransitions.get(i).runAnimators();
}
}
}
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index d648ca6..d87d0f9 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -277,6 +277,18 @@
if ((mMode & MODE_IN) != MODE_IN || endValues == null) {
return null;
}
+ if (startValues == null) {
+ VisibilityInfo parentVisibilityInfo = null;
+ View endParent = (View) endValues.view.getParent();
+ TransitionValues startParentValues = getMatchedTransitionValues(endParent,
+ false);
+ TransitionValues endParentValues = getTransitionValues(endParent, false);
+ parentVisibilityInfo =
+ getVisibilityChangeInfo(startParentValues, endParentValues);
+ if (parentVisibilityInfo.visibilityChange) {
+ return null;
+ }
+ }
return onAppear(sceneRoot, endValues.view, startValues, endValues);
}
diff --git a/core/java/android/util/SizeF.java b/core/java/android/util/SizeF.java
index ac4f187..2edc4a7f 100644
--- a/core/java/android/util/SizeF.java
+++ b/core/java/android/util/SizeF.java
@@ -16,6 +16,7 @@
package android.util;
+import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.internal.util.Preconditions.checkArgumentFinite;
/**
@@ -95,6 +96,61 @@
return mWidth + "x" + mHeight;
}
+ private static NumberFormatException invalidSizeF(String s) {
+ throw new NumberFormatException("Invalid SizeF: \"" + s + "\"");
+ }
+
+ /**
+ * Parses the specified string as a size value.
+ * <p>
+ * The ASCII characters {@code \}{@code u002a} ('*') and
+ * {@code \}{@code u0078} ('x') are recognized as separators between
+ * the width and height.</p>
+ * <p>
+ * For any {@code SizeF s}: {@code SizeF.parseSizeF(s.toString()).equals(s)}.
+ * However, the method also handles sizes expressed in the
+ * following forms:</p>
+ * <p>
+ * "<i>width</i>{@code x}<i>height</i>" or
+ * "<i>width</i>{@code *}<i>height</i>" {@code => new SizeF(width, height)},
+ * where <i>width</i> and <i>height</i> are string floats potentially
+ * containing a sign, such as "-10.3", "+7" or "5.2", but not containing
+ * an {@code 'x'} (such as a float in hexadecimal string format).</p>
+ *
+ * <pre>{@code
+ * SizeF.parseSizeF("3.2*+6").equals(new SizeF(3.2f, 6.0f)) == true
+ * SizeF.parseSizeF("-3x-6").equals(new SizeF(-3.0f, -6.0f)) == true
+ * SizeF.parseSizeF("4 by 3") => throws NumberFormatException
+ * }</pre>
+ *
+ * @param string the string representation of a size value.
+ * @return the size value represented by {@code string}.
+ *
+ * @throws NumberFormatException if {@code string} cannot be parsed
+ * as a size value.
+ * @throws NullPointerException if {@code string} was {@code null}
+ */
+ public static SizeF parseSizeF(String string)
+ throws NumberFormatException {
+ checkNotNull(string, "string must not be null");
+
+ int sep_ix = string.indexOf('*');
+ if (sep_ix < 0) {
+ sep_ix = string.indexOf('x');
+ }
+ if (sep_ix < 0) {
+ throw invalidSizeF(string);
+ }
+ try {
+ return new SizeF(Float.parseFloat(string.substring(0, sep_ix)),
+ Float.parseFloat(string.substring(sep_ix + 1)));
+ } catch (NumberFormatException e) {
+ throw invalidSizeF(string);
+ } catch (IllegalArgumentException e) {
+ throw invalidSizeF(string);
+ }
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index edb3798..d23e115 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -339,7 +339,8 @@
* @param attachInfo AttachInfo tied to the specified view.
* @param callbacks Callbacks invoked when drawing happens.
*/
- abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks);
+ abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+ boolean isStartingWindow);
/**
* Creates a new hardware layer. A hardware layer built by calling this
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 5d2822d..3d1332c 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -16,6 +16,7 @@
package android.view;
+import android.graphics.Color;
import com.android.internal.R;
import android.content.Context;
@@ -267,7 +268,8 @@
view.mRecreateDisplayList = false;
}
- private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
+ private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks,
+ boolean isStartingWindow) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
updateViewTreeDisplayList(view);
@@ -279,6 +281,12 @@
callbacks.onHardwarePreDraw(canvas);
canvas.insertReorderBarrier();
+ if (isStartingWindow) {
+ // Compensate for some situations in which a hw-accelerated surface
+ // will not be filled with anything by default; this is equivalent
+ // to the old behavior when the system process was not hw-accelerated
+ canvas.drawColor(Color.BLACK);
+ }
canvas.drawRenderNode(view.getDisplayList());
canvas.insertInorderBarrier();
@@ -298,7 +306,8 @@
}
@Override
- void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks) {
+ void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+ boolean isStartingWindow) {
attachInfo.mIgnoreDirtyState = true;
long frameTimeNanos = mChoreographer.getFrameTimeNanos();
attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
@@ -308,7 +317,7 @@
recordDuration = System.nanoTime();
}
- updateRootDisplayList(view, callbacks);
+ updateRootDisplayList(view, callbacks, isStartingWindow);
if (mProfilingEnabled) {
recordDuration = System.nanoTime() - recordDuration;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 82c5425..eb8f3bf 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4299,6 +4299,8 @@
* </p>
*
* @param a the styled attributes set to initialize the fading edges from
+ *
+ * @removed
*/
protected void initializeFadingEdge(TypedArray a) {
// This method probably shouldn't have been included in the SDK to begin with.
@@ -4439,6 +4441,8 @@
* </p>
*
* @param a the styled attributes set to initialize the scrollbars from
+ *
+ * @removed
*/
protected void initializeScrollbars(TypedArray a) {
// It's not safe to use this method from apps. The parameter 'a' must have been obtained
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index a94f973..12a49d5 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -875,6 +875,11 @@
data[i + 1] = theme.resolveAttribute(attributeId, outValue, true) ?
outValue.coerceToString().toString() : nullString;
i += 2;
+
+ // attempt to replace reference data with its name
+ if (outValue.type == TypedValue.TYPE_REFERENCE) {
+ data[i - 1] = resources.getResourceName(outValue.resourceId);
+ }
} catch (Resources.NotFoundException e) {
// ignore resources we can't resolve
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 43ab4ef..ae6e4e7 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -711,17 +711,10 @@
// can be used by code on the system process to escape that and enable
// HW accelerated drawing. (This is basically for the lock screen.)
- final boolean fakeHwAccelerated = (attrs.privateFlags &
- WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED) != 0;
final boolean forceHwAccelerated = (attrs.privateFlags &
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED) != 0;
- if (fakeHwAccelerated) {
- // This is exclusively for the preview windows the window manager
- // shows for launching applications, so they will look more like
- // the app being launched.
- mAttachInfo.mHardwareAccelerationRequested = true;
- } else if (!HardwareRenderer.sRendererDisabled
+ if (!HardwareRenderer.sRendererDisabled
|| (HardwareRenderer.sSystemRendererDisabled && forceHwAccelerated)) {
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy();
@@ -2486,7 +2479,8 @@
dirty.setEmpty();
mBlockResizeBuffer = false;
- mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this);
+ mAttachInfo.mHardwareRenderer.draw(mView, mAttachInfo, this,
+ params.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING);
} else {
// If we get here with a disabled & requested hardware renderer, something went
// wrong (an invalidate posted right before we destroyed the hardware surface
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index ebc683a..63ab7d2 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -111,10 +111,19 @@
public static final int FEATURE_CONTENT_TRANSITIONS = 12;
/**
+ * Enables Activities to run Activity Transitions either through sending or receiving
+ * ActivityOptions bundle created with
+ * {@link android.app.ActivityOptions#makeSceneTransitionAnimation(android.app.Activity,
+ * android.util.Pair[])} or {@link android.app.ActivityOptions#makeSceneTransitionAnimation(
+ * android.app.Activity, View, String)}.
+ */
+ public static final int FEATURE_ACTIVITY_TRANSITIONS = 13;
+
+ /**
* Max value used as a feature ID
* @hide
*/
- public static final int FEATURE_MAX = FEATURE_CONTENT_TRANSITIONS;
+ public static final int FEATURE_MAX = FEATURE_ACTIVITY_TRANSITIONS;
/** Flag for setting the progress bar's visibility to VISIBLE */
public static final int PROGRESS_VISIBILITY_ON = -1;
@@ -1459,7 +1468,7 @@
* have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
* {@link android.transition.Visibility} as exiting is governed by changing visibility
* from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
- * remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param transition The Transition to use to move Views out of the scene when calling a
* new Activity.
@@ -1475,7 +1484,7 @@
* visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null,
* the views will remain unaffected. If nothing is set, the default will be to use the same
* transition as {@link #setExitTransition(android.transition.Transition)}.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param transition The Transition to use to move Views into the scene when reentering from a
* previously-started Activity.
@@ -1489,7 +1498,7 @@
* {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
* {@link android.transition.Visibility} as entering is governed by changing visibility from
* {@link View#INVISIBLE} to {@link View#VISIBLE}. If <code>transition</code> is null,
- * entering Views will remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * entering Views will remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @return the Transition to use to move Views into the initial Scene.
* @attr ref android.R.styleable#Window_windowEnterTransition
@@ -1517,7 +1526,7 @@
* have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions will extend
* {@link android.transition.Visibility} as exiting is governed by changing visibility
* from {@link View#VISIBLE} to {@link View#INVISIBLE}. If transition is null, the views will
- * remain unaffected. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * remain unaffected. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @return the Transition to use to move Views out of the scene when calling a
* new Activity.
@@ -1531,7 +1540,7 @@
* or ViewGroups that have {@link ViewGroup#isTransitionGroup} return true. Typical Transitions
* will extend {@link android.transition.Visibility} as exiting is governed by changing
* visibility from {@link View#VISIBLE} to {@link View#INVISIBLE}.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @return The Transition to use to move Views into the scene when reentering from a
* previously-started Activity.
@@ -1544,7 +1553,7 @@
* Scene. Typical Transitions will affect size and location, such as
* {@link android.transition.ChangeBounds}. A null
* value will cause transferred shared elements to blink to the final position.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param transition The Transition to use for shared elements transferred into the content
* Scene.
@@ -1559,7 +1568,7 @@
* value will cause transferred shared elements to blink to the final position.
* If no value is set, the default will be to use the same value as
* {@link #setSharedElementEnterTransition(android.transition.Transition)}.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param transition The Transition to use for shared elements transferred out of the content
* Scene.
@@ -1569,7 +1578,7 @@
/**
* Returns the Transition that will be used for shared elements transferred into the content
- * Scene. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Scene. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @return Transition to use for sharend elements transferred into the content Scene.
* @attr ref android.R.styleable#Window_windowSharedElementEnterTransition
@@ -1578,7 +1587,7 @@
/**
* Returns the Transition that will be used for shared elements transferred back to a
- * calling Activity. Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * calling Activity. Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @return Transition to use for sharend elements transferred into the content Scene.
* @attr ref android.R.styleable#Window_windowSharedElementReturnTransition
@@ -1590,7 +1599,7 @@
* before the shared elements are transferred to the called Activity. If the shared elements
* must animate during the exit transition, this Transition should be used. Upon completion,
* the shared elements may be transferred to the started Activity.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param transition The Transition to use for shared elements in the launching Window
* prior to transferring to the launched Activity's Window.
@@ -1603,7 +1612,7 @@
* Activity after it has returned the shared element to it start location. If no value
* is set, this will default to
* {@link #setSharedElementExitTransition(android.transition.Transition)}.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @param transition The Transition to use for shared elements in the launching Window
* after the shared element has returned to the Window.
@@ -1614,7 +1623,7 @@
/**
* Returns the Transition to use for shared elements in the launching Window prior
* to transferring to the launched Activity's Window.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @return the Transition to use for shared elements in the launching Window prior
* to transferring to the launched Activity's Window.
@@ -1625,7 +1634,7 @@
/**
* Returns the Transition that will be used for shared elements reentering from a started
* Activity after it has returned the shared element to it start location.
- * Requires {@link #FEATURE_CONTENT_TRANSITIONS}.
+ * Requires {@link #FEATURE_ACTIVITY_TRANSITIONS}.
*
* @return the Transition that will be used for shared elements reentering from a started
* Activity after it has returned the shared element to it start location.
@@ -1703,7 +1712,7 @@
* Returns the duration, in milliseconds, of the window background fade
* when transitioning into or away from an Activity when called with an Activity Transition.
* <p>When executing the enter transition, the background starts transparent
- * and fades in. This requires {@link #FEATURE_CONTENT_TRANSITIONS}. The default is
+ * and fades in. This requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. The default is
* 300 milliseconds.</p>
*
* @return The duration of the window background fade to opaque during enter transition.
@@ -1716,7 +1725,7 @@
* Sets the duration, in milliseconds, of the window background fade
* when transitioning into or away from an Activity when called with an Activity Transition.
* <p>When executing the enter transition, the background starts transparent
- * and fades in. This requires {@link #FEATURE_CONTENT_TRANSITIONS}. The default is
+ * and fades in. This requires {@link #FEATURE_ACTIVITY_TRANSITIONS}. The default is
* 300 milliseconds.</p>
*
* @param fadeDurationMillis The duration of the window background fade to or from opaque
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 47ee52e..273ec9d 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1024,26 +1024,6 @@
public int flags;
/**
- * If the window has requested hardware acceleration, but this is not
- * allowed in the process it is in, then still render it as if it is
- * hardware accelerated. This is used for the starting preview windows
- * in the system process, which don't need to have the overhead of
- * hardware acceleration (they are just a static rendering), but should
- * be rendered as such to match the actual window of the app even if it
- * is hardware accelerated.
- * Even if the window isn't hardware accelerated, still do its rendering
- * as if it was.
- * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
- * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
- * is generally disabled. This flag must be specified in addition to
- * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
- * windows.
- *
- * @hide
- */
- public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
-
- /**
* In the system process, we globally do not use hardware acceleration
* because there are many threads doing UI there and they conflict.
* If certain parts of the UI that really do want to use hardware
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 2ed125d..fec7550 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -638,6 +638,11 @@
public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs);
/**
+ * Return the window that is hiding the keyguard, if such a thing exists.
+ */
+ public WindowState getWinShowWhenLockedLw();
+
+ /**
* Called when the system would like to show a UI to indicate that an
* application is starting. You can use this to add a
* APPLICATION_STARTING_TYPE window with the given appToken to the window
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 547acfa..46a7fd0 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -416,38 +416,6 @@
}
/**
- * UploadHelper simplifies file upload operations by providing helper methods that
- * would handle most common file picker/media capture requests. The application
- * can use the helper to build an intent to start a file picker, and then parse
- * the result returned by the activity.
- *
- * How to use:
- * 1. Create a helper using {@link FileChooserParams#getUploadHelper}
- * 2. Build an intent using {@link UploadHelper#buildIntent}
- * 3. Fire the intent using {@link android.app.Activity#startActivityForResult}.
- * 4. Check for ActivityNotFoundException and take a user friendly action if thrown.
- * 5. Listen the result using {@link android.app.Activity#onActivityResult}
- * 6. Parse the result using {@link UploadHelper#parseResult}
- * 7. Send the result using filePathCallback of {@link WebChromeClient#onShowFileChooser}
- */
- public static abstract class UploadHelper {
- /**
- * Returns an intent that would start a file picker for file selection/media capture.
- */
- public abstract Intent buildIntent();
-
- /**
- * Parses the result returned by the file picker activity.
- *
- * @param resultCode the integer result code returned by the file picker activity.
- * @param data the intent returned by the file picker activity.
- * @return the Uris of selected file(s) or null if the resultCode indicates
- * activity canceled or any other error.
- */
- public abstract Uri[] parseResult(int resultCode, Intent data);
- }
-
- /**
* Parameters used in the {@link #onShowFileChooser} method.
*/
public static abstract class FileChooserParams {
@@ -464,11 +432,17 @@
public static final int MODE_SAVE = 3;
/**
- * Returns a helper to simplify choosing and uploading files. The helper builds a default
- * intent that the application can send using startActivityForResult and processes the
- * results.
+ * Parse the result returned by the file picker activity. This method should be used with
+ * {@link #createIntent}. Refer to {@link #createIntent} for how to use it.
+ *
+ * @param resultCode the integer result code returned by the file picker activity.
+ * @param data the intent returned by the file picker activity.
+ * @return the Uris of selected file(s) or null if the resultCode indicates
+ * activity canceled or any other error.
*/
- public abstract UploadHelper getUploadHelper();
+ public static Uri[] parseResult(int resultCode, Intent data) {
+ return WebViewFactory.getProvider().getStatics().parseFileChooserResult(resultCode, data);
+ }
/**
* Returns file chooser mode.
@@ -500,7 +474,28 @@
* The file name of a default selection if specified, or null.
*/
public abstract String getFilenameHint();
- };
+
+ /**
+ * Creates an intent that would start a file picker for file selection.
+ * The Intent supports choosing files from simple file sources available
+ * on the device. Some advanced sources (for example, live media capture)
+ * may not be supported and applications wishing to support these sources
+ * or more advanced file operations should build their own Intent.
+ *
+ * <pre>
+ * How to use:
+ * 1. Build an intent using {@link #createIntent}
+ * 2. Fire the intent using {@link android.app.Activity#startActivityForResult}.
+ * 3. Check for ActivityNotFoundException and take a user friendly action if thrown.
+ * 4. Listen the result using {@link android.app.Activity#onActivityResult}
+ * 5. Parse the result using {@link #parseResult} only if media capture was not requested.
+ * 6. Send the result using filePathCallback of {@link WebChromeClient#onShowFileChooser}
+ * </pre>
+ *
+ * @return an Intent that supports basic file chooser sources.
+ */
+ public abstract Intent createIntent();
+ }
/**
* Tell the client to open a file chooser.
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 20bb932..d37d217 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -17,6 +17,8 @@
package android.webkit;
import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
/**
* This is the main entry-point into the WebView back end implementations, which the WebView
@@ -64,6 +66,12 @@
* {@link android.webkit.WebView#setSlowWholeDocumentDrawEnabled(boolean) }
*/
void enableSlowWholeDocumentDraw();
+
+ /**
+ * Implement the API method
+ * {@link android.webkit.WebChromeClient.FileChooserParams#parseResult(int, Intent)}
+ */
+ Uri[] parseFileChooserResult(int resultCode, Intent intent);
}
Statics getStatics();
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 3f168e8..128a06c 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1860,9 +1860,8 @@
}
final int originalLength = mTextView.getText().length();
- long minMax = mTextView.prepareSpacesAroundPaste(offset, offset, content);
- int min = TextUtils.unpackRangeStartFromLong(minMax);
- int max = TextUtils.unpackRangeEndFromLong(minMax);
+ int min = offset;
+ int max = offset;
Selection.setSelection((Spannable) mTextView.getText(), max);
mTextView.replaceText_internal(min, max, content);
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 0289ccc..dfdf606 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -262,7 +262,7 @@
attrs, R.styleable.SearchView, defStyleAttr, defStyleRes);
final LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- final int layoutResId = a.getResourceId(R.styleable.SearchView_layout, 0);
+ final int layoutResId = a.getResourceId(R.styleable.SearchView_layout, R.layout.search_view);
inflater.inflate(layoutResId, this, true);
mQueryTextView = (SearchAutoComplete) findViewById(R.id.search_src_text);
@@ -288,7 +288,8 @@
mSearchHintIcon.setImageDrawable(a.getDrawable(R.styleable.SearchView_searchIcon));
// Extract dropdown layout resource IDs for later use.
- mSuggestionRowLayout = a.getResourceId(R.styleable.SearchView_suggestionRowLayout, 0);
+ mSuggestionRowLayout = a.getResourceId(R.styleable.SearchView_suggestionRowLayout,
+ R.layout.search_dropdown_item_icons_2line);
mSuggestionCommitIconResId = a.getResourceId(R.styleable.SearchView_commitIcon, 0);
mSearchButton.setOnClickListener(mOnClickListener);
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 27763eb..a76241e 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -31,6 +31,7 @@
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
+import android.util.MathUtils;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
@@ -300,7 +301,11 @@
}
private static boolean isValidDayOfWeek(int day) {
- return (day >= Time.SUNDAY && day <= Time.SATURDAY);
+ return day >= Calendar.SUNDAY && day <= Calendar.SATURDAY;
+ }
+
+ private static boolean isValidMonth(int month) {
+ return month >= Calendar.JANUARY && month <= Calendar.DECEMBER;
}
/**
@@ -312,8 +317,8 @@
* @param selectedDay the selected day of the month, or -1 for no selection.
* @param month the month.
* @param year the year.
- * @param weekStart which day the week should start on. {@link Time#SUNDAY} through
- * {@link Time#SATURDAY}.
+ * @param weekStart which day the week should start on. {@link Calendar#SUNDAY} through
+ * {@link Calendar#SATURDAY}.
* @param enabledDayStart the first enabled day.
* @param enabledDayEnd the last enabled day.
*/
@@ -325,7 +330,7 @@
mSelectedDay = selectedDay;
- if (month >= Calendar.JANUARY && month <= Calendar.DECEMBER) {
+ if (isValidMonth(month)) {
mMonth = month;
}
mYear = year;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 80ea6ea..1509e80 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -17,6 +17,7 @@
package android.widget;
import android.R;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ClipData;
import android.content.ClipboardManager;
@@ -1976,23 +1977,34 @@
}
/**
- * Sets the Drawables (if any) to appear to the left of, above,
- * to the right of, and below the text. Use null if you do not
- * want a Drawable there. The Drawables must already have had
+ * Sets the Drawables (if any) to appear to the left of, above, to the
+ * right of, and below the text. Use {@code null} if you do not want a
+ * Drawable there. The Drawables must already have had
* {@link Drawable#setBounds} called.
+ * <p>
+ * Calling this method will overwrite any Drawables previously set using
+ * {@link #setCompoundDrawablesRelative} or related methods.
*
* @attr ref android.R.styleable#TextView_drawableLeft
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableRight
* @attr ref android.R.styleable#TextView_drawableBottom
*/
- public void setCompoundDrawables(Drawable left, Drawable top,
- Drawable right, Drawable bottom) {
+ public void setCompoundDrawables(@Nullable Drawable left, @Nullable Drawable top,
+ @Nullable Drawable right, @Nullable Drawable bottom) {
Drawables dr = mDrawables;
- final boolean drawables = left != null || top != null
- || right != null || bottom != null;
+ // We're switching to absolute, discard relative.
+ if (dr != null) {
+ if (dr.mDrawableStart != null) dr.mDrawableStart.setCallback(null);
+ dr.mDrawableStart = null;
+ if (dr.mDrawableEnd != null) dr.mDrawableEnd.setCallback(null);
+ dr.mDrawableEnd = null;
+ dr.mDrawableSizeStart = dr.mDrawableHeightStart = 0;
+ dr.mDrawableSizeEnd = dr.mDrawableHeightEnd = 0;
+ }
+ final boolean drawables = left != null || top != null || right != null || bottom != null;
if (!drawables) {
// Clearing drawables... can we free the data structure?
if (dr != null) {
@@ -2101,10 +2113,12 @@
}
/**
- * Sets the Drawables (if any) to appear to the left of, above,
- * to the right of, and below the text. Use 0 if you do not
- * want a Drawable there. The Drawables' bounds will be set to
- * their intrinsic bounds.
+ * Sets the Drawables (if any) to appear to the left of, above, to the
+ * right of, and below the text. Use 0 if you do not want a Drawable there.
+ * The Drawables' bounds will be set to their intrinsic bounds.
+ * <p>
+ * Calling this method will overwrite any Drawables previously set using
+ * {@link #setCompoundDrawablesRelative} or related methods.
*
* @param left Resource identifier of the left Drawable.
* @param top Resource identifier of the top Drawable.
@@ -2126,18 +2140,21 @@
}
/**
- * Sets the Drawables (if any) to appear to the left of, above,
- * to the right of, and below the text. Use null if you do not
- * want a Drawable there. The Drawables' bounds will be set to
- * their intrinsic bounds.
+ * Sets the Drawables (if any) to appear to the left of, above, to the
+ * right of, and below the text. Use {@code null} if you do not want a
+ * Drawable there. The Drawables' bounds will be set to their intrinsic
+ * bounds.
+ * <p>
+ * Calling this method will overwrite any Drawables previously set using
+ * {@link #setCompoundDrawablesRelative} or related methods.
*
* @attr ref android.R.styleable#TextView_drawableLeft
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableRight
* @attr ref android.R.styleable#TextView_drawableBottom
*/
- public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top,
- Drawable right, Drawable bottom) {
+ public void setCompoundDrawablesWithIntrinsicBounds(@Nullable Drawable left,
+ @Nullable Drawable top, @Nullable Drawable right, @Nullable Drawable bottom) {
if (left != null) {
left.setBounds(0, 0, left.getIntrinsicWidth(), left.getIntrinsicHeight());
@@ -2155,20 +2172,33 @@
}
/**
- * Sets the Drawables (if any) to appear to the start of, above,
- * to the end of, and below the text. Use null if you do not
- * want a Drawable there. The Drawables must already have had
- * {@link Drawable#setBounds} called.
+ * Sets the Drawables (if any) to appear to the start of, above, to the end
+ * of, and below the text. Use {@code null} if you do not want a Drawable
+ * there. The Drawables must already have had {@link Drawable#setBounds}
+ * called.
+ * <p>
+ * Calling this method will overwrite any Drawables previously set using
+ * {@link #setCompoundDrawables} or related methods.
*
* @attr ref android.R.styleable#TextView_drawableStart
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
*/
- public void setCompoundDrawablesRelative(Drawable start, Drawable top,
- Drawable end, Drawable bottom) {
+ public void setCompoundDrawablesRelative(@Nullable Drawable start, @Nullable Drawable top,
+ @Nullable Drawable end, @Nullable Drawable bottom) {
Drawables dr = mDrawables;
+ // We're switching to relative, discard absolute.
+ if (dr != null) {
+ if (dr.mDrawableLeft != null) dr.mDrawableLeft.setCallback(null);
+ dr.mDrawableLeft = dr.mDrawableLeftInitial = null;
+ if (dr.mDrawableRight != null) dr.mDrawableRight.setCallback(null);
+ dr.mDrawableRight = dr.mDrawableRightInitial = null;
+ dr.mDrawableSizeLeft = dr.mDrawableHeightLeft = 0;
+ dr.mDrawableSizeRight = dr.mDrawableHeightRight = 0;
+ }
+
final boolean drawables = start != null || top != null
|| end != null || bottom != null;
@@ -2274,10 +2304,12 @@
}
/**
- * Sets the Drawables (if any) to appear to the start of, above,
- * to the end of, and below the text. Use 0 if you do not
- * want a Drawable there. The Drawables' bounds will be set to
- * their intrinsic bounds.
+ * Sets the Drawables (if any) to appear to the start of, above, to the end
+ * of, and below the text. Use 0 if you do not want a Drawable there. The
+ * Drawables' bounds will be set to their intrinsic bounds.
+ * <p>
+ * Calling this method will overwrite any Drawables previously set using
+ * {@link #setCompoundDrawables} or related methods.
*
* @param start Resource identifier of the start Drawable.
* @param top Resource identifier of the top Drawable.
@@ -2301,18 +2333,20 @@
}
/**
- * Sets the Drawables (if any) to appear to the start of, above,
- * to the end of, and below the text. Use null if you do not
- * want a Drawable there. The Drawables' bounds will be set to
- * their intrinsic bounds.
+ * Sets the Drawables (if any) to appear to the start of, above, to the end
+ * of, and below the text. Use {@code null} if you do not want a Drawable
+ * there. The Drawables' bounds will be set to their intrinsic bounds.
+ * <p>
+ * Calling this method will overwrite any Drawables previously set using
+ * {@link #setCompoundDrawables} or related methods.
*
* @attr ref android.R.styleable#TextView_drawableStart
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
*/
- public void setCompoundDrawablesRelativeWithIntrinsicBounds(Drawable start, Drawable top,
- Drawable end, Drawable bottom) {
+ public void setCompoundDrawablesRelativeWithIntrinsicBounds(@Nullable Drawable start,
+ @Nullable Drawable top, @Nullable Drawable end, @Nullable Drawable bottom) {
if (start != null) {
start.setBounds(0, 0, start.getIntrinsicWidth(), start.getIntrinsicHeight());
@@ -2337,6 +2371,7 @@
* @attr ref android.R.styleable#TextView_drawableRight
* @attr ref android.R.styleable#TextView_drawableBottom
*/
+ @NonNull
public Drawable[] getCompoundDrawables() {
final Drawables dr = mDrawables;
if (dr != null) {
@@ -2356,6 +2391,7 @@
* @attr ref android.R.styleable#TextView_drawableEnd
* @attr ref android.R.styleable#TextView_drawableBottom
*/
+ @NonNull
public Drawable[] getCompoundDrawablesRelative() {
final Drawables dr = mDrawables;
if (dr != null) {
@@ -8142,6 +8178,8 @@
* Returns the TextView_textColor attribute from the TypedArray, if set, or
* the TextAppearance_textColor from the TextView_textAppearance attribute,
* if TextView_textColor was not set directly.
+ *
+ * @removed
*/
public static ColorStateList getTextColors(Context context, TypedArray attrs) {
// It's not safe to use this method from apps. The parameter 'attrs'
@@ -8169,6 +8207,8 @@
* AttributeSet, if set, or the default color from the
* TextAppearance_textColor from the TextView_textAppearance attribute, if
* TextView_textColor was not set directly.
+ *
+ * @removed
*/
public static int getTextColor(Context context, TypedArray attrs, int def) {
final ColorStateList colors = getTextColors(context, attrs);
@@ -8754,57 +8794,6 @@
}
/**
- * Prepare text so that there are not zero or two spaces at beginning and end of region defined
- * by [min, max] when replacing this region by paste.
- * Note that if there were two spaces (or more) at that position before, they are kept. We just
- * make sure we do not add an extra one from the paste content.
- */
- long prepareSpacesAroundPaste(int min, int max, CharSequence paste) {
- if (paste.length() > 0) {
- if (min > 0) {
- final char charBefore = mTransformed.charAt(min - 1);
- final char charAfter = paste.charAt(0);
-
- if (Character.isSpaceChar(charBefore) && Character.isSpaceChar(charAfter)) {
- // Two spaces at beginning of paste: remove one
- final int originalLength = mText.length();
- deleteText_internal(min - 1, min);
- // Due to filters, there is no guarantee that exactly one character was
- // removed: count instead.
- final int delta = mText.length() - originalLength;
- min += delta;
- max += delta;
- } else if (!Character.isSpaceChar(charBefore) && charBefore != '\n' &&
- !Character.isSpaceChar(charAfter) && charAfter != '\n') {
- // No space at beginning of paste: add one
- final int originalLength = mText.length();
- replaceText_internal(min, min, " ");
- // Taking possible filters into account as above.
- final int delta = mText.length() - originalLength;
- min += delta;
- max += delta;
- }
- }
-
- if (max < mText.length()) {
- final char charBefore = paste.charAt(paste.length() - 1);
- final char charAfter = mTransformed.charAt(max);
-
- if (Character.isSpaceChar(charBefore) && Character.isSpaceChar(charAfter)) {
- // Two spaces at end of paste: remove one
- deleteText_internal(max, max + 1);
- } else if (!Character.isSpaceChar(charBefore) && charBefore != '\n' &&
- !Character.isSpaceChar(charAfter) && charAfter != '\n') {
- // No space at end of paste: add one
- replaceText_internal(max, max, " ");
- }
- }
- }
-
- return TextUtils.packRangeInLong(min, max);
- }
-
- /**
* Paste clipboard content between min and max positions.
*/
private void paste(int min, int max) {
@@ -8817,9 +8806,6 @@
CharSequence paste = clip.getItemAt(i).coerceToStyledText(getContext());
if (paste != null) {
if (!didFirst) {
- long minMax = prepareSpacesAroundPaste(min, max, paste);
- min = TextUtils.unpackRangeStartFromLong(minMax);
- max = TextUtils.unpackRangeEndFromLong(minMax);
Selection.setSelection((Spannable) mText, max);
((Editable) mText).replace(min, max, paste);
didFirst = true;
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index be28199..ba2d5b8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -37,7 +37,6 @@
import android.view.ViewGroup;
import com.android.internal.R;
-import com.android.internal.app.ToolbarActionBar;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuItemImpl;
import com.android.internal.view.menu.MenuPresenter;
@@ -1007,8 +1006,15 @@
}
private void addSystemView(View v) {
- final LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT);
+ final ViewGroup.LayoutParams vlp = v.getLayoutParams();
+ final LayoutParams lp;
+ if (vlp == null) {
+ lp = generateDefaultLayoutParams();
+ } else if (!checkLayoutParams(vlp)) {
+ lp = generateLayoutParams(vlp);
+ } else {
+ lp = (LayoutParams) vlp;
+ }
lp.mViewType = LayoutParams.SYSTEM;
addView(v, lp);
}
@@ -1280,27 +1286,36 @@
final int[] collapsingMargins = mTempMargins;
collapsingMargins[0] = collapsingMargins[1] = 0;
+ // Align views within the minimum toolbar height, if set.
+ final int alignmentHeight = getMinimumHeight();
+
if (shouldLayout(mNavButtonView)) {
if (isRtl) {
- right = layoutChildRight(mNavButtonView, right, collapsingMargins);
+ right = layoutChildRight(mNavButtonView, right, collapsingMargins,
+ alignmentHeight);
} else {
- left = layoutChildLeft(mNavButtonView, left, collapsingMargins);
+ left = layoutChildLeft(mNavButtonView, left, collapsingMargins,
+ alignmentHeight);
}
}
if (shouldLayout(mCollapseButtonView)) {
if (isRtl) {
- right = layoutChildRight(mCollapseButtonView, right, collapsingMargins);
+ right = layoutChildRight(mCollapseButtonView, right, collapsingMargins,
+ alignmentHeight);
} else {
- left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins);
+ left = layoutChildLeft(mCollapseButtonView, left, collapsingMargins,
+ alignmentHeight);
}
}
if (shouldLayout(mMenuView)) {
if (isRtl) {
- left = layoutChildLeft(mMenuView, left, collapsingMargins);
+ left = layoutChildLeft(mMenuView, left, collapsingMargins,
+ alignmentHeight);
} else {
- right = layoutChildRight(mMenuView, right, collapsingMargins);
+ right = layoutChildRight(mMenuView, right, collapsingMargins,
+ alignmentHeight);
}
}
@@ -1311,17 +1326,21 @@
if (shouldLayout(mExpandedActionView)) {
if (isRtl) {
- right = layoutChildRight(mExpandedActionView, right, collapsingMargins);
+ right = layoutChildRight(mExpandedActionView, right, collapsingMargins,
+ alignmentHeight);
} else {
- left = layoutChildLeft(mExpandedActionView, left, collapsingMargins);
+ left = layoutChildLeft(mExpandedActionView, left, collapsingMargins,
+ alignmentHeight);
}
}
if (shouldLayout(mLogoView)) {
if (isRtl) {
- right = layoutChildRight(mLogoView, right, collapsingMargins);
+ right = layoutChildRight(mLogoView, right, collapsingMargins,
+ alignmentHeight);
} else {
- left = layoutChildLeft(mLogoView, left, collapsingMargins);
+ left = layoutChildLeft(mLogoView, left, collapsingMargins,
+ alignmentHeight);
}
}
@@ -1434,13 +1453,15 @@
addCustomViewsWithGravity(mTempViews, Gravity.LEFT);
final int leftViewsCount = mTempViews.size();
for (int i = 0; i < leftViewsCount; i++) {
- left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins);
+ left = layoutChildLeft(mTempViews.get(i), left, collapsingMargins,
+ alignmentHeight);
}
addCustomViewsWithGravity(mTempViews, Gravity.RIGHT);
final int rightViewsCount = mTempViews.size();
for (int i = 0; i < rightViewsCount; i++) {
- right = layoutChildRight(mTempViews.get(i), right, collapsingMargins);
+ right = layoutChildRight(mTempViews.get(i), right, collapsingMargins,
+ alignmentHeight);
}
// Centered views try to center with respect to the whole bar, but views pinned
@@ -1459,8 +1480,10 @@
final int centerViewsCount = mTempViews.size();
for (int i = 0; i < centerViewsCount; i++) {
- centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins);
+ centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft, collapsingMargins,
+ alignmentHeight);
}
+
mTempViews.clear();
}
@@ -1483,46 +1506,49 @@
return width;
}
- private int layoutChildLeft(View child, int left, int[] collapsingMargins) {
+ private int layoutChildLeft(View child, int left, int[] collapsingMargins,
+ int alignmentHeight) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int l = lp.leftMargin - collapsingMargins[0];
left += Math.max(0, l);
collapsingMargins[0] = Math.max(0, -l);
- final int top = getChildTop(child);
+ final int top = getChildTop(child, alignmentHeight);
final int childWidth = child.getMeasuredWidth();
child.layout(left, top, left + childWidth, top + child.getMeasuredHeight());
left += childWidth + lp.rightMargin;
return left;
}
- private int layoutChildRight(View child, int right, int[] collapsingMargins) {
+ private int layoutChildRight(View child, int right, int[] collapsingMargins,
+ int alignmentHeight) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int r = lp.rightMargin - collapsingMargins[1];
right -= Math.max(0, r);
collapsingMargins[1] = Math.max(0, -r);
- final int top = getChildTop(child);
+ final int top = getChildTop(child, alignmentHeight);
final int childWidth = child.getMeasuredWidth();
child.layout(right - childWidth, top, right, top + child.getMeasuredHeight());
right -= childWidth + lp.leftMargin;
return right;
}
- private int getChildTop(View child) {
+ private int getChildTop(View child, int alignmentHeight) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ final int childHeight = child.getMeasuredHeight();
+ final int alignmentOffset = alignmentHeight > 0 ? (childHeight - alignmentHeight) / 2 : 0;
switch (getChildVerticalGravity(lp.gravity)) {
case Gravity.TOP:
- return getPaddingTop();
+ return getPaddingTop() - alignmentOffset;
case Gravity.BOTTOM:
- return getHeight() - getPaddingBottom() -
- child.getMeasuredHeight() - lp.bottomMargin;
+ return getHeight() - getPaddingBottom() - childHeight
+ - lp.bottomMargin - alignmentOffset;
default:
case Gravity.CENTER_VERTICAL:
final int paddingTop = getPaddingTop();
final int paddingBottom = getPaddingBottom();
final int height = getHeight();
- final int childHeight = child.getMeasuredHeight();
final int space = height - paddingTop - paddingBottom;
int spaceAbove = (space - childHeight) / 2;
if (spaceAbove < lp.topMargin) {
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 99c87ea..4410f25 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -22,7 +22,6 @@
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
-import android.text.TextUtils;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -33,7 +32,6 @@
import android.view.WindowCallbackWrapper;
import android.widget.SpinnerAdapter;
import android.widget.Toolbar;
-import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.view.menu.MenuPresenter;
import com.android.internal.widget.DecorToolbar;
@@ -48,8 +46,6 @@
private Window.Callback mWindowCallback;
private boolean mMenuCallbackSet;
- private CharSequence mHomeDescription;
-
private boolean mLastMenuVisibility;
private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
new ArrayList<OnMenuVisibilityListener>();
@@ -76,8 +72,6 @@
mDecorToolbar.setWindowCallback(mWindowCallback);
toolbar.setOnMenuItemClickListener(mMenuClicker);
mDecorToolbar.setWindowTitle(title);
- mHomeDescription = mToolbar.getNavigationContentDescription();
- updateNavDescription();
}
public Window.Callback getWrappedWindowCallback() {
@@ -168,8 +162,7 @@
@Override
public void setHomeActionContentDescription(CharSequence description) {
- mToolbar.setNavigationContentDescription(description);
- mHomeDescription = description;
+ mDecorToolbar.setNavigationContentDescription(description);
}
@Override
@@ -179,8 +172,7 @@
@Override
public void setHomeActionContentDescription(int resId) {
- mToolbar.setNavigationContentDescription(resId);
- mHomeDescription = mToolbar.getNavigationContentDescription();
+ mDecorToolbar.setNavigationContentDescription(resId);
}
@Override
@@ -258,21 +250,7 @@
@Override
public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) {
final int currentOptions = mDecorToolbar.getDisplayOptions();
- final int changed = (options ^ currentOptions) & mask;
mDecorToolbar.setDisplayOptions(options & mask | currentOptions & ~mask);
- if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
- updateNavDescription();
- }
- }
-
- private void updateNavDescription() {
- if ((mDecorToolbar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
- if (TextUtils.isEmpty(mHomeDescription)) {
- mToolbar.setNavigationContentDescription(R.string.action_bar_up_description);
- } else {
- mToolbar.setNavigationContentDescription(mHomeDescription);
- }
- }
}
@Override
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index e58d68f..86f580d 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -64,7 +64,9 @@
/** Stores user time and system time in 100ths of a second. */
private final long[] mProcessStatsData = new long[4];
- /** Stores user time and system time in 100ths of a second. */
+
+ /** Stores user time and system time in 100ths of a second. Used for
+ * public API to retrieve CPU use for a process. Must lock while in use. */
private final long[] mSinglePidStatsData = new long[4];
private static final int[] PROCESS_FULL_STATS_FORMAT = new int[] {
@@ -533,18 +535,20 @@
/**
* Returns the total time (in clock ticks, or 1/100 sec) spent executing in
- * both user and system code.
+ * both user and system code. Safe to call without lock held.
*/
public long getCpuTimeForPid(int pid) {
- final String statFile = "/proc/" + pid + "/stat";
- final long[] statsData = mSinglePidStatsData;
- if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
- null, statsData, null)) {
- long time = statsData[PROCESS_STAT_UTIME]
- + statsData[PROCESS_STAT_STIME];
- return time;
+ synchronized (mSinglePidStatsData) {
+ final String statFile = "/proc/" + pid + "/stat";
+ final long[] statsData = mSinglePidStatsData;
+ if (Process.readProcFile(statFile, PROCESS_STATS_FORMAT,
+ null, statsData, null)) {
+ long time = statsData[PROCESS_STAT_UTIME]
+ + statsData[PROCESS_STAT_STIME];
+ return time;
+ }
+ return 0;
}
- return 0;
}
/**
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 0aee0e3..40c9ed2 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -254,12 +254,20 @@
preloadClasses();
preloadResources();
preloadOpenGL();
+ preloadSharedLibraries();
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();
Log.d(TAG, "end preload");
}
+ private static void preloadSharedLibraries() {
+ Log.i(TAG, "Preloading shared libraries...");
+ System.loadLibrary("android");
+ System.loadLibrary("compiler_rt");
+ System.loadLibrary("jnigraphics");
+ }
+
private static void preloadOpenGL() {
if (!SystemProperties.getBoolean(PROPERTY_DISABLE_OPENGL_PRELOADING, false)) {
EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 3ed4d51..8e786da 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -107,7 +107,7 @@
return (T[]) EmptyArray.OBJECT;
}
- int bucket = ((System.identityHashCode(kind) / 8) & 0x7FFFFFFF) % CACHE_SIZE;
+ int bucket = (kind.hashCode() & 0x7FFFFFFF) % CACHE_SIZE;
Object cache = sCache[bucket];
if (cache == null || cache.getClass().getComponentType() != kind) {
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index e53af69..fb44e58 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -135,6 +135,7 @@
private ExpandedActionViewMenuPresenter mExpandedMenuPresenter;
View mExpandedActionView;
+ private int mDefaultUpDescription = R.string.action_bar_up_description;
Window.Callback mWindowCallback;
@@ -187,7 +188,7 @@
mExpandedHomeLayout.setShowUp(true);
mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
mExpandedHomeLayout.setContentDescription(getResources().getText(
- R.string.action_bar_up_description));
+ mDefaultUpDescription));
// This needs to highlight/be focusable on its own.
// TODO: Clean up the handoff between expanded/normal.
@@ -579,7 +580,7 @@
homeDesc = mHomeDescription;
} else {
if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
- homeDesc = mContext.getResources().getText(R.string.action_bar_up_description);
+ homeDesc = mContext.getResources().getText(mDefaultUpDescription);
} else {
homeDesc = mContext.getResources().getText(R.string.action_bar_home_description);
}
@@ -1330,6 +1331,15 @@
updateHomeAccessibility(mUpGoerFive.isEnabled());
}
+ @Override
+ public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) {
+ if (mDefaultUpDescription == defaultNavigationContentDescription) {
+ return;
+ }
+ mDefaultUpDescription = defaultNavigationContentDescription;
+ updateHomeAccessibility(mUpGoerFive.isEnabled());
+ }
+
static class SavedState extends BaseSavedState {
int expandedMenuItemId;
boolean isOverflowOpen;
diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java
index 5281045..fee3015 100644
--- a/core/java/com/android/internal/widget/DecorToolbar.java
+++ b/core/java/com/android/internal/widget/DecorToolbar.java
@@ -89,6 +89,7 @@
void setNavigationIcon(int resId);
void setNavigationContentDescription(CharSequence description);
void setNavigationContentDescription(int resId);
+ void setDefaultNavigationContentDescription(int defaultNavigationContentDescription);
void saveHierarchyState(SparseArray<Parcelable> toolbarStates);
void restoreHierarchyState(SparseArray<Parcelable> toolbarStates);
}
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index 250bbac..8446e06 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -76,14 +76,21 @@
private boolean mTitleSet;
private CharSequence mTitle;
private CharSequence mSubtitle;
+ private CharSequence mHomeDescription;
private Window.Callback mWindowCallback;
private boolean mMenuPrepared;
private ActionMenuPresenter mActionMenuPresenter;
private int mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
+ private int mDefaultNavigationContentDescription = 0;
public ToolbarWidgetWrapper(Toolbar toolbar, boolean style) {
+ this(toolbar, style, R.string.action_bar_up_description);
+ }
+
+ public ToolbarWidgetWrapper(Toolbar toolbar, boolean style,
+ int defaultNavigationContentDescription) {
mToolbar = toolbar;
mTitle = toolbar.getTitle();
@@ -166,10 +173,8 @@
mDisplayOpts = detectDisplayOptions();
}
- if (TextUtils.isEmpty(mToolbar.getNavigationContentDescription())) {
- mToolbar.setNavigationContentDescription(
- getContext().getResources().getText(R.string.action_bar_up_description));
- }
+ setDefaultNavigationContentDescription(defaultNavigationContentDescription);
+ mHomeDescription = mToolbar.getNavigationContentDescription();
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
final ActionMenuItem mNavItem = new ActionMenuItem(mToolbar.getContext(),
@@ -183,6 +188,17 @@
});
}
+ @Override
+ public void setDefaultNavigationContentDescription(int defaultNavigationContentDescription) {
+ if (defaultNavigationContentDescription == mDefaultNavigationContentDescription) {
+ return;
+ }
+ mDefaultNavigationContentDescription = defaultNavigationContentDescription;
+ if (TextUtils.isEmpty(mToolbar.getNavigationContentDescription())) {
+ setNavigationContentDescription(mDefaultNavigationContentDescription);
+ }
+ }
+
private int detectDisplayOptions() {
int opts = ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_HOME |
ActionBar.DISPLAY_USE_LOGO;
@@ -395,6 +411,7 @@
if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
if ((newOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
mToolbar.setNavigationIcon(mNavIcon);
+ updateHomeAccessibility();
} else {
mToolbar.setNavigationIcon(null);
}
@@ -602,12 +619,23 @@
@Override
public void setNavigationContentDescription(CharSequence description) {
- mToolbar.setNavigationContentDescription(description);
+ mHomeDescription = description;
+ updateHomeAccessibility();
}
@Override
public void setNavigationContentDescription(int resId) {
- mToolbar.setNavigationContentDescription(resId);
+ setNavigationContentDescription(resId == 0 ? null : getContext().getString(resId));
+ }
+
+ private void updateHomeAccessibility() {
+ if ((mDisplayOpts & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ if (TextUtils.isEmpty(mHomeDescription)) {
+ mToolbar.setNavigationContentDescription(mDefaultNavigationContentDescription);
+ } else {
+ mToolbar.setNavigationContentDescription(mHomeDescription);
+ }
+ }
}
@Override
diff --git a/core/java/com/android/server/BootReceiver.java b/core/java/com/android/server/BootReceiver.java
index 7249985..468d7f1 100644
--- a/core/java/com/android/server/BootReceiver.java
+++ b/core/java/com/android/server/BootReceiver.java
@@ -123,8 +123,15 @@
}
if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) {
- String now = Long.toString(System.currentTimeMillis());
- SystemProperties.set("ro.runtime.firstboot", now);
+ if ("encrypted".equals(SystemProperties.get("ro.crypto.state"))
+ && "trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))){
+ // Encrypted, first boot to get PIN/pattern/password so data is tmpfs
+ // Don't set ro.runtime.firstboot so that we will do this again
+ // when data is properly mounted
+ } else {
+ String now = Long.toString(System.currentTimeMillis());
+ SystemProperties.set("ro.runtime.firstboot", now);
+ }
if (db != null) db.addText("SYSTEM_BOOT", headers);
// Negative sizes mean to take the *tail* of the file (see FileUtils.readTextFile())
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index a63258c..1573106 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -271,6 +271,7 @@
}
void AndroidRuntime::setArgv0(const char* argv0) {
+ memset(mArgBlockStart, 0, mArgBlockLength);
strlcpy(mArgBlockStart, argv0, mArgBlockLength);
}
@@ -345,28 +346,6 @@
return state && state->getStrictModePolicy() != 0;
}
-
-/**
- * Add VM arguments to the to-be-executed VM
- * Stops at first non '-' argument (also stops at an argument of '--')
- * Returns the number of args consumed
- */
-int AndroidRuntime::addVmArguments(int argc, const char* const argv[])
-{
- int i;
-
- for (i = 0; i<argc; i++) {
- if (argv[i][0] != '-') {
- return i;
- }
- if (argv[i][1] == '-' && argv[i][2] == 0) {
- return i+1;
- }
- addOption(argv[i]);
- }
- return i;
-}
-
static int hasDir(const char* dir)
{
struct stat s;
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index 6ef1d2c..9d3e74b 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -435,19 +435,32 @@
std::vector<float> lengths;
float errorSquared = acceptableError * acceptableError;
- while ((verb = pathIter.next(points)) != SkPath::kDone_Verb) {
+ while ((verb = pathIter.next(points, false)) != SkPath::kDone_Verb) {
createVerbSegments(verb, points, segmentPoints, lengths, errorSquared);
}
if (segmentPoints.empty()) {
- return NULL;
+ int numVerbs = path->countVerbs();
+ if (numVerbs == 1) {
+ addMove(segmentPoints, lengths, path->getPoint(0));
+ } else {
+ // Invalid or empty path. Fall back to point(0,0)
+ addMove(segmentPoints, lengths, SkPoint());
+ }
+ }
+
+ float totalLength = lengths.back();
+ if (totalLength == 0) {
+ // Lone Move instructions should still be able to animate at the same value.
+ segmentPoints.push_back(segmentPoints.back());
+ lengths.push_back(1);
+ totalLength = 1;
}
size_t numPoints = segmentPoints.size();
size_t approximationArraySize = numPoints * 3;
float* approximation = new float[approximationArraySize];
- float totalLength = lengths.back();
int approximationIndex = 0;
for (size_t i = 0; i < numPoints; i++) {
diff --git a/core/res/res/drawable/ic_corp_icon_badge.xml b/core/res/res/drawable/ic_corp_icon_badge.xml
index 834ae68..0021a8f 100644
--- a/core/res/res/drawable/ic_corp_icon_badge.xml
+++ b/core/res/res/drawable/ic_corp_icon_badge.xml
@@ -20,11 +20,13 @@
android:viewportHeight="64.0">
<path
- android:fillColor="#33000000"
- android:pathData="M49.062,50.0m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"/>
+ android:fillColor="#FF000000"
+ android:pathData="M49.062,50.0m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"
+ android:fillAlpha="0.2"/>
<path
- android:fillColor="#33000000"
- android:pathData="M49.0,49.5m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"/>
+ android:fillColor="#FF000000"
+ android:pathData="M49.0,49.5m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"
+ android:fillAlpha="0.2"/>
<path
android:pathData="M49.0,49.0m-14.0,0.0a14.0,14.0 0.0,1.0 1.0,28.0 0.0a14.0,14.0 0.0,1.0 1.0,-28.0 0.0"
android:fillColor="#FF5722"/>
diff --git a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
index 7ceb772..cd999d5 100644
--- a/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
+++ b/core/res/res/drawable/vector_drawable_progress_indeterminate_horizontal.xml
@@ -26,11 +26,11 @@
android:translateY="5" >
<group android:name="v21_pivot" >
<group
- android:name="rectangle_path_1_position"
- android:alpha="0.1" >
+ android:name="rectangle_path_1_position">
<path
android:name="rectangle_path_1"
android:fillColor="?attr/colorControlActivated"
+ android:fillAlpha="0.1"
android:pathData="M -180.0 -1.0 l 360 0 l 0 2 l -360 0 Z" />
</group>
<group
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index be89e41..e5ef629 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -56,8 +56,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical"
- android:minHeight="64dp"
- android:paddingTop="@dimen/alert_dialog_padding_top_material">
+ android:minHeight="64dp">
<ScrollView android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -67,6 +66,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/alert_dialog_padding_material"
+ android:paddingTop="@dimen/alert_dialog_padding_top_material"
android:paddingEnd="@dimen/alert_dialog_padding_material" />
</ScrollView>
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_part_line1.xml b/core/res/res/layout/notification_template_part_line1.xml
index 7de4089..78bc1ed 100644
--- a/core/res/res/layout/notification_template_part_line1.xml
+++ b/core/res/res/layout/notification_template_part_line1.xml
@@ -24,7 +24,7 @@
>
<TextView android:id="@+id/title"
android:textAppearance="@style/TextAppearance.Material.Notification.Title"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
diff --git a/core/res/res/layout/preference_material.xml b/core/res/res/layout/preference_material.xml
index a137149..39c979c 100644
--- a/core/res/res/layout/preference_material.xml
+++ b/core/res/res/layout/preference_material.xml
@@ -42,6 +42,7 @@
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
android:maxWidth="48dp"
android:maxHeight="48dp" />
</LinearLayout>
diff --git a/core/res/res/layout/simple_spinner_dropdown_item.xml b/core/res/res/layout/simple_spinner_dropdown_item.xml
index e2bd474..f276cfa 100644
--- a/core/res/res/layout/simple_spinner_dropdown_item.xml
+++ b/core/res/res/layout/simple_spinner_dropdown_item.xml
@@ -4,24 +4,23 @@
**
** Copyright 2008, 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
+** 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
+** 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
+** 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.
*/
-->
-<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
+<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="?android:attr/dropdownListPreferredItemHeight"
- android:ellipsize="marquee"
- android:textAlignment="inherit"/>
+ android:ellipsize="marquee"/>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 35ff766..3356081 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -183,9 +183,9 @@
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Tichý režim"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zvuk je VYPNUTÝ."</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zvuk je zapnutý"</string>
- <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Režim V letadle"</string>
- <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim V letadle je ZAPNUTÝ"</string>
- <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim V letadle je VYPNUTÝ"</string>
+ <string name="global_actions_toggle_airplane_mode" msgid="5884330306926307456">"Režim Letadlo"</string>
+ <string name="global_actions_airplane_mode_on_status" msgid="2719557982608919750">"Režim Letadlo je ZAPNUTÝ"</string>
+ <string name="global_actions_airplane_mode_off_status" msgid="5075070442854490296">"Režim Letadlo je VYPNUTÝ"</string>
<string name="global_action_settings" msgid="1756531602592545966">"Nastavení"</string>
<string name="global_action_lockdown" msgid="8751542514724332873">"Zamknout"</string>
<string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string>
@@ -280,10 +280,10 @@
<string name="permdesc_receiveSms" msgid="6424387754228766939">"Umožňuje aplikaci přijmout a zpracovat zprávy SMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
<string name="permlab_receiveMms" msgid="1821317344668257098">"příjem textových zpráv (MMS)"</string>
<string name="permdesc_receiveMms" msgid="533019437263212260">"Umožňuje aplikaci přijmout a zpracovat zprávy MMS. Znamená to, že aplikace může sledovat zprávy odeslané do vašeho zařízení nebo je smazat, aniž by se vám zobrazily."</string>
- <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"příjem nouzového vysílání"</string>
- <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Umožňuje aplikaci přijmout a zpracovat zprávy tísňového vysílání. Toto oprávnění je dostupné pouze pro systémové aplikace."</string>
- <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čtení zpráv informační služby"</string>
- <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje aplikaci číst zprávy informační služby přijaté ve vašem zařízení. Upozornění informační služby jsou v některých oblastech odesílána za účelem varování před mimořádnými událostmi. Škodlivé aplikace mohou narušit výkon či provoz vašeho zařízení během přijímání zpráv informační služby."</string>
+ <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"příjem výstražných zpráv o výjimečné situaci"</string>
+ <string name="permdesc_receiveEmergencyBroadcast" msgid="848524070262431974">"Umožňuje aplikaci přijmout a zpracovat výstražné zprávy o výjimečných situacích. Toto oprávnění je dostupné pouze pro systémové aplikace."</string>
+ <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"čtení zpráv informačních služeb"</string>
+ <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"Umožňuje aplikaci číst zprávy informačních služeb přijaté ve vašem zařízení. Výstražná upozornění informačních služeb jsou v některých oblastech odesílána za účelem varování před výjimečnými událostmi. Škodlivé aplikace mohou narušit výkon či provoz vašeho zařízení během přijímání zpráv informačních služeb."</string>
<string name="permlab_sendSms" msgid="5600830612147671529">"odesílaní zpráv SMS"</string>
<string name="permdesc_sendSms" msgid="7094729298204937667">"Umožňuje aplikaci odesílat zprávy SMS. Může to mít za následek účtování neočekávaných poplatků. Škodlivé aplikace vás mohou připravit o peníze odesíláním zpráv bez vašeho svolení."</string>
<string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"odesílání událostí typu „odpovězte zprávou“"</string>
@@ -772,7 +772,7 @@
<item msgid="8901098336658710359">"Domů"</item>
<item msgid="869923650527136615">"Mobil"</item>
<item msgid="7897544654242874543">"Práce"</item>
- <item msgid="1103601433382158155">"Pracovní fax"</item>
+ <item msgid="1103601433382158155">"Fax práce"</item>
<item msgid="1735177144948329370">"Fax domů"</item>
<item msgid="603878674477207394">"Pager"</item>
<item msgid="1650824275177931637">"Ostatní"</item>
@@ -827,7 +827,7 @@
<string name="phoneTypeOtherFax" msgid="8587657145072446565">"Jiný fax"</string>
<string name="phoneTypeRadio" msgid="4093738079908667513">"Radiotelefon"</string>
<string name="phoneTypeTelex" msgid="3367879952476250512">"Telex"</string>
- <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Telefon pro sluchově postižené (TTY/TDD)"</string>
+ <string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TDD"</string>
<string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Pracovní mobil"</string>
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Pracovní pager"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Asistent"</string>
@@ -1255,7 +1255,7 @@
<string name="volume_icon_description_media" msgid="4217311719665194215">"Hlasitost médií"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitost oznámení"</string>
<string name="ringtone_default" msgid="3789758980357696936">"Výchozí vyzváněcí tón"</string>
- <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Výchozí vyzváněcí tón (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Výchozí tón (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="7937634392408977062">"Žádné"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"Vyzváněcí tóny"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"Neznámý vyzváněcí tón"</string>
@@ -1639,7 +1639,7 @@
<string name="accessibility_enabled" msgid="1381972048564547685">"Usnadnění přístupu je aktivováno."</string>
<string name="enable_accessibility_canceled" msgid="3833923257966635673">"Usnadnění zrušeno."</string>
<string name="user_switched" msgid="3768006783166984410">"Aktuální uživatel je <xliff:g id="NAME">%1$s</xliff:g>."</string>
- <string name="user_switching_message" msgid="2871009331809089783">"Přepínání na uživatele <xliff:g id="NAME">%1$s</xliff:g>…"</string>
+ <string name="user_switching_message" msgid="2871009331809089783">"Přepínání na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
<string name="owner_name" msgid="2716755460376028154">"Vlastník"</string>
<string name="error_message_title" msgid="4510373083082500195">"Chyba"</string>
<string name="error_message_change_not_allowed" msgid="1347282344200417578">"Administrátor tuto změnu zakázal"</string>
@@ -1774,6 +1774,6 @@
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Před uvolněním požádat o kód PIN"</string>
<string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Před uvolněním požádat o bezpečnostní gesto"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Před uvolněním požádat o heslo"</string>
- <string name="battery_saver_description" msgid="2510530476513605742">"Za účelem zvýšení životnosti baterie režim úspory baterie sníží výkon vašeho zařízení a omezí vibrace a většinu dat na pozadí. E-mail, zprávy a další aplikace, které používají synchronizaci, nemusejí být aktualizovány, dokud je nespustíte.\n\nPři nabíjení zařízení se režim úspory baterie automaticky vypne."</string>
+ <string name="battery_saver_description" msgid="2510530476513605742">"Za účelem zvýšení životnosti baterie spořič baterie sníží výkon vašeho zařízení a omezí vibrace a většinu dat na pozadí. E-mail, zprávy a další aplikace, které používají synchronizaci, nemusejí být aktualizovány, dokud je nespustíte.\n\nPři nabíjení zařízení se spořič baterie automaticky vypne."</string>
<string name="downtime_condition_summary" msgid="8761776337475705749">"Dokud v <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> neskončí pozastavení"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 95125eb..2fa54dc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1241,7 +1241,7 @@
<string name="new_app_description" msgid="1932143598371537340">"Interrompi la vecchia applicazione senza salvare."</string>
<string name="sendText" msgid="5209874571959469142">"Scegli un\'azione per il testo"</string>
<string name="volume_ringtone" msgid="6885421406845734650">"Volume suoneria"</string>
- <string name="volume_music" msgid="5421651157138628171">"Volume app. multimediali"</string>
+ <string name="volume_music" msgid="5421651157138628171">"Volume contenuti multimediali"</string>
<string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Riproduzione tramite Bluetooth"</string>
<string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Suoneria silenziosa impostata"</string>
<string name="volume_call" msgid="3941680041282788711">"Volume chiamate"</string>
@@ -1764,7 +1764,7 @@
<string name="lock_to_app_toast" msgid="1230563865743799321">"Per sbloccare questa schermata, tocca e tieni premuto contemporaneamente Indietro e Recenti."</string>
<string name="lock_to_app_toast_accessible" msgid="3340628918851844044">"Per sbloccare questa schermata, tocca e tieni premuto Recenti."</string>
<string name="lock_to_app_toast_locked" msgid="8739004135132606329">"La schermata è bloccata. La tua organizzazione non ne consente lo sblocco."</string>
- <string name="lock_to_app_title" msgid="1682643873107812874">"Utilizzare blocco schermata?"</string>
+ <string name="lock_to_app_title" msgid="1682643873107812874">"Utilizzare il blocco su schermo?"</string>
<string name="lock_to_app_description" msgid="9076084599283282800">"Il blocco schermata fissa la visualizzazione su una stessa immagine.\n\nPer uscire, tocca e tieni premuto contemporaneamente Indietro e Recenti."</string>
<string name="lock_to_app_description_accessible" msgid="2132076937479670601">"Il blocco schermata fissa la visualizzazione su una stessa immagine.\n\nPer uscire, tocca e tieni premuto Recenti."</string>
<string name="lock_to_app_negative" msgid="2259143719362732728">"NO, GRAZIE"</string>
diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml
index 62001d9..24e55b1 100644
--- a/core/res/res/values-mcc310-mnc120/config.xml
+++ b/core/res/res/values-mcc310-mnc120/config.xml
@@ -25,4 +25,6 @@
-->
<integer name="config_mobile_mtu">1422</integer>
+ <!-- Sprint need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">70</integer>
</resources>
diff --git a/core/res/res/values-mcc311-mnc220/config.xml b/core/res/res/values-mcc311-mnc220/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc220/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc221/config.xml b/core/res/res/values-mcc311-mnc221/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc221/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc222/config.xml b/core/res/res/values-mcc311-mnc222/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc222/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc223/config.xml b/core/res/res/values-mcc311-mnc223/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc223/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc224/config.xml b/core/res/res/values-mcc311-mnc224/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc224/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc225/config.xml b/core/res/res/values-mcc311-mnc225/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc225/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc226/config.xml b/core/res/res/values-mcc311-mnc226/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc226/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc227/config.xml b/core/res/res/values-mcc311-mnc227/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc227/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc228/config.xml b/core/res/res/values-mcc311-mnc228/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc228/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc229/config.xml b/core/res/res/values-mcc311-mnc229/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc229/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc490/config.xml b/core/res/res/values-mcc311-mnc490/config.xml
new file mode 100644
index 0000000..defe78d
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc490/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Sprint need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">70</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc580/config.xml b/core/res/res/values-mcc311-mnc580/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc580/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc581/config.xml b/core/res/res/values-mcc311-mnc581/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc581/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc582/config.xml b/core/res/res/values-mcc311-mnc582/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc582/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc583/config.xml b/core/res/res/values-mcc311-mnc583/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc583/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc584/config.xml b/core/res/res/values-mcc311-mnc584/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc584/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc585/config.xml b/core/res/res/values-mcc311-mnc585/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc585/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc586/config.xml b/core/res/res/values-mcc311-mnc586/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc586/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc587/config.xml b/core/res/res/values-mcc311-mnc587/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc587/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc588/config.xml b/core/res/res/values-mcc311-mnc588/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc588/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc589/config.xml b/core/res/res/values-mcc311-mnc589/config.xml
new file mode 100644
index 0000000..811e9c7
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc589/config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2014, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- USC need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">300</integer>
+</resources>
diff --git a/core/res/res/values-mcc311-mnc870/config.xml b/core/res/res/values-mcc311-mnc870/config.xml
new file mode 100644
index 0000000..24e55b1
--- /dev/null
+++ b/core/res/res/values-mcc311-mnc870/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Configure mobile network MTU. Carrier specific value is set here.
+ -->
+ <integer name="config_mobile_mtu">1422</integer>
+
+ <!-- Sprint need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">70</integer>
+</resources>
diff --git a/core/res/res/values-mcc312-mnc530/config.xml b/core/res/res/values-mcc312-mnc530/config.xml
new file mode 100644
index 0000000..24e55b1
--- /dev/null
+++ b/core/res/res/values-mcc312-mnc530/config.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2013, 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 my 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds. -->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+ <!-- Configure mobile network MTU. Carrier specific value is set here.
+ -->
+ <integer name="config_mobile_mtu">1422</integer>
+
+ <!-- Sprint need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">70</integer>
+</resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index 83e1baa..dc0b1ab 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -254,13 +254,13 @@
<string name="permgrouplab_storage" msgid="1971118770546336966">"သိုလှောင်မှုများ"</string>
<string name="permgroupdesc_storage" product="nosdcard" msgid="7442318502446874999">"USBအားချိတ်ဆက်ရန်"</string>
<string name="permgroupdesc_storage" product="default" msgid="9203302214915355774">"SDကတ်အားချိတ်ဆက်ရန်"</string>
- <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"လွယ်ကူစွာ ရရှိနိုင်မှု ပေးသော စွမ်းရည်"</string>
+ <string name="permgrouplab_accessibilityFeatures" msgid="7919025602283593907">"အများသုံးစွဲနိုင်မှု စွမ်းရည်"</string>
<string name="permgroupdesc_accessibilityFeatures" msgid="4205196881678144335">"ကူညီပေးမှု နည်းပညာများမှ တောင်းဆိုနိုင်သော ထူးခြားချက်များ"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ဝင်းဒိုးမှာပါရှိသည်များကို ထုတ်ယူခြင်း"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"သင် အပြန်အလှန်လုပ်နေသော ဝင်းဒိုးမှာပါရှိသည်များကို သေချာစွာ ကြည့်ရှုစစ်ဆေးပါ"</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ထိတို့ခြင်းဖြင့် ရှာဖွေပေးနိုင်တာကို ဖွင့်လိုက်ပါ"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"ထိတွေ့လိုက်တဲ့ အရာများကို အသံနဲ့ ထုတ်ပြောမှာဖြစ်ပြီး ဖန်သားပြင်ပေါကနေ လက်နဲ့ ထပ်မံ ကြည့်ရှုနိုင်ပါတယ်"</string>
- <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"ဝက်ဘ် လွယ်ကူစွာ အသုံးပြုနိုင်မှု စွမ်းရည် မြှင့်တင်ခြင်းကို ဖွင့်ရန်"</string>
+ <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"ပိုမိုကောင်းမွန်သော ဝက်ဘ်အများသုံးစွဲနိုင်မှုကို ဖွင့်ရန်"</string>
<string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"အပလီကေးရှင်းကို ပိုမိုပြည့်စုံစေရန် စကရစ်များကို သွင်းနိုင်ပါတယ်"</string>
<string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ရိုက်သောစာများကို သေချာစွာ စစ်ဆေးပါ"</string>
<string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"အရေးကြီးသော ကိုယ်ရေးအချက်အလက်များဖြစ်တဲ့ ခရက်ဒစ်ကဒ်နံပါတ်များနှင့် စကားဝှက်များ ပါဝင်ပါတယ်."</string>
@@ -1188,7 +1188,7 @@
<string name="ok" msgid="5970060430562524910">"ကောင်းပြီ"</string>
<string name="cancel" msgid="6442560571259935130">"ပယ်ဖျက်ရန်"</string>
<string name="yes" msgid="5362982303337969312">"ကောင်းပြီ"</string>
- <string name="no" msgid="5141531044935541497">"ပယ်ဖျက်သည်"</string>
+ <string name="no" msgid="5141531044935541497">"နေတော့"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"သတိပြုရန်"</string>
<string name="loading" msgid="7933681260296021180">"တင်နေ…"</string>
<string name="capital_on" msgid="1544682755514494298">"ဖွင့်ရန်"</string>
@@ -1297,7 +1297,7 @@
<string name="sms_short_code_details" msgid="5873295990846059400"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် "</b>" ကုန်ကျမှု ရှိလာနိုင်သည်။"</string>
<string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် ကုန်ကျမှု ရှိလာနိုင်သည်။"</b></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ပို့ရန်"</string>
- <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ပယ်ဖျက်သည်"</string>
+ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"နေတော့"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ကျွန်ပ်၏ရွေးချယ်မှုကို မှတ်ထားရန်"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"နောင်တွင် ဆက်တင် > အပလီကေးရှင်းများ မှပြောင်းနိုင်သည်"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"အမြဲခွင့်ပြုရန်"</string>
@@ -1410,7 +1410,7 @@
<string name="ime_action_go" msgid="8320845651737369027">"သွားပါ"</string>
<string name="ime_action_search" msgid="658110271822807811">"ရှာဖွေခြင်း"</string>
<string name="ime_action_send" msgid="2316166556349314424">"ပို့ခြင်း"</string>
- <string name="ime_action_next" msgid="3138843904009813834">"အရှေ့သို့"</string>
+ <string name="ime_action_next" msgid="3138843904009813834">"ရှေ့သို့"</string>
<string name="ime_action_done" msgid="8971516117910934605">"ပြီးပါပြီ"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"အနောက်သို့"</string>
<string name="ime_action_default" msgid="2840921885558045721">"လုပ်ဆောင်ချက်"</string>
@@ -1525,7 +1525,7 @@
<string name="action_menu_overflow_description" msgid="2295659037509008453">"ပိုမိုရွေးချယ်စရာများ"</string>
<string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s ၊ %2$s"</string>
<string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s ၊ %2$s ၊ %3$s"</string>
- <string name="storage_internal" msgid="4891916833657929263">"စက်အတွင်းသိမ်းဆည်းရန်နေရာ"</string>
+ <string name="storage_internal" msgid="4891916833657929263">"စက်တွင်း သိုလှောင်ထားမှု"</string>
<string name="storage_sd_card" msgid="3282948861378286745">"SD ကဒ်"</string>
<string name="storage_usb" msgid="3017954059538517278">"USBဖြင့် သိမ်းဆည်း"</string>
<string name="extract_edit_menu_button" msgid="8940478730496610137">"ပြင်ဆင်ရန်"</string>
diff --git a/core/res/res/values-sw600dp-land/dimens_material.xml b/core/res/res/values-sw600dp-land/dimens_material.xml
new file mode 100644
index 0000000..f8f16e2
--- /dev/null
+++ b/core/res/res/values-sw600dp-land/dimens_material.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+<resources>
+
+ <!-- Use the default title sizes on tablets. -->
+ <dimen name="text_size_title_material_toolbar">@dimen/text_size_title_material</dimen>
+ <!-- Use the default subtitle sizes on tablets. -->
+ <dimen name="text_size_subtitle_material_toolbar">@dimen/text_size_subhead_material</dimen>
+
+</resources>
diff --git a/core/res/res/values-sw720dp/styles.xml b/core/res/res/values-sw720dp/styles.xml
index fee1c24f..94ec0a6 100644
--- a/core/res/res/values-sw720dp/styles.xml
+++ b/core/res/res/values-sw720dp/styles.xml
@@ -16,10 +16,9 @@
<resources>
<style name="PreferencePanel">
- <item name="android:layout_marginStart">@dimen/preference_screen_side_margin</item>
- <item name="android:layout_marginEnd">@dimen/preference_screen_side_margin</item>
- <item name="android:layout_marginTop">@dimen/preference_screen_top_margin</item>
- <item name="android:layout_marginBottom">@dimen/preference_screen_bottom_margin</item>
- <item name="android:background">?attr/detailsElementBackground</item>
+ <item name="layout_marginStart">@dimen/preference_screen_side_margin</item>
+ <item name="layout_marginEnd">@dimen/preference_screen_side_margin</item>
+ <item name="layout_marginTop">@dimen/preference_screen_top_margin</item>
+ <item name="layout_marginBottom">@dimen/preference_screen_bottom_margin</item>
</style>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a00ed5d..438d1fb 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -458,6 +458,10 @@
transitions between different window content. -->
<attr name="windowContentTransitionManager" format="reference" />
+ <!-- Flag indicating whether this window allows Activity Transitions.
+ Corresponds to {@link android.view.Window#FEATURE_ACTIVITY_TRANSITIONS}. -->
+ <attr name="windowActivityTransitions" format="boolean" />
+
<!-- Reference to a Transition XML resource defining the desired Transition
used to move Views into the initial Window's content Scene. Corresponds to
{@link android.view.Window#setEnterTransition(android.transition.Transition)}. -->
@@ -1792,6 +1796,7 @@
<attr name="windowTranslucentNavigation" />
<attr name="windowSwipeToDismiss" />
<attr name="windowContentTransitions" />
+ <attr name="windowActivityTransitions" />
<attr name="windowContentTransitionManager" />
<attr name="windowActionBarFullscreenDecorLayout" />
@@ -5286,8 +5291,6 @@
<attr name="scaleX" />
<!-- The amount to scale the group on X coordinate -->
<attr name="scaleY" />
- <!-- The alpha of the group (0 is transparent and 1 is opaque) -->
- <attr name="alpha" />
</declare-styleable>
<!-- Defines the path used in VectorDrawables. -->
@@ -5298,8 +5301,14 @@
<attr name="strokeWidth" format="float" />
<!-- The color to stroke the path if not defined implies no stroke-->
<attr name="strokeColor" format="color" />
+ <!-- The opacity of a path stroke, as a value between 0 (completely transparent)
+ and 1 (completely opaque) -->
+ <attr name="strokeAlpha" format="float" />
<!-- The color to fill the path if not defined implies no fill-->
<attr name="fillColor" format="color" />
+ <!-- The alpha of the path fill, as a value between 0 (completely transparent)
+ and 1 (completely opaque)-->
+ <attr name="fillAlpha" format="float" />
<!-- The specification of the operations that define the path -->
<attr name="pathData" format="string" />
<!-- The fraction of the path to trim from the start from 0 to 1 -->
@@ -7434,12 +7443,6 @@
<attr name="settingsActivity" />
</declare-styleable>
- <!-- @removed -->
- <attr name="__removed1" format="reference" />
-
- <!-- TODO: Spacer to be removed from here and public.xml -->
- <attr name="__removed2" format="reference" />
-
<!-- Attributes that can be used with <code>rating-system-definition</code> tags inside of the
XML resource that describes TV content rating of a {@link android.media.tv.TvInputService},
which is referenced from its
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b36387f..3907fc5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -354,6 +354,15 @@
<!-- Integer indicating associated scan interval in milliseconds -->
<integer translatable="false" name="config_wifi_framework_associated_scan_interval">10000</integer>
+ <!-- Boolean indicating associated scan are allowed -->
+ <bool translatable="false" name="config_wifi_framework_enable_associated_autojoin_scan">true</bool>
+
+ <!-- Boolean indicating associated network selection is allowed -->
+ <bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
+
+ <!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
+ <bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
+
<!-- Wifi driver stop delay, in milliseconds.
Default value is 2 minutes. -->
<integer translatable="false" name="config_wifi_driver_stop_delay">120000</integer>
@@ -1740,4 +1749,7 @@
(3) If the config_default_vm_number array has gid special item but it doesn't match the
current sim's gid, the last one without gid will be picked -->
<string-array translatable="false" name="config_default_vm_number" />
+
+ <!-- Sprint need a 70 ms delay for 3way call -->
+ <integer name="config_cdma_3waycall_flash_delay">0</integer>
</resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index 275a5ec..3e64f30 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -41,11 +41,11 @@
<dimen name="text_size_headline_material">24sp</dimen>
<dimen name="text_size_title_material">20sp</dimen>
<dimen name="text_size_subhead_material">16sp</dimen>
- <dimen name="text_size_title_material_toolbar">20dp</dimen>
- <dimen name="text_size_subtitle_material_toolbar">16dp</dimen>
+ <dimen name="text_size_title_material_toolbar">@dimen/text_size_title_material</dimen>
+ <dimen name="text_size_subtitle_material_toolbar">@dimen/text_size_subhead_material</dimen>
<dimen name="text_size_menu_material">16sp</dimen>
- <dimen name="text_size_body_2_material">14sp</dimen>
- <dimen name="text_size_body_1_material">14sp</dimen>
+ <dimen name="text_size_body_2_material">16sp</dimen>
+ <dimen name="text_size_body_1_material">16sp</dimen>
<dimen name="text_size_caption_material">12sp</dimen>
<dimen name="text_size_button_material">14sp</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 5b047f7..99918a0 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2291,6 +2291,9 @@
<public type="attr" name="fragmentAllowEnterTransitionOverlap" />
<public type="attr" name="fragmentAllowReturnTransitionOverlap" />
<public type="attr" name="patternPathData" />
+ <public type="attr" name="strokeAlpha" />
+ <public type="attr" name="fillAlpha" />
+ <public type="attr" name="windowActivityTransitions" />
<public-padding type="dimen" name="l_resource_pad" end="0x01050010" />
@@ -2307,16 +2310,14 @@
<public type="style" name="Widget.Toolbar" />
<public type="style" name="Widget.Toolbar.Button.Navigation" />
- <public type="style" name="Widget.Holo.FastScroll" />
- <public type="style" name="Widget.Holo.StackView" />
-
- <public type="style" name="Widget.Holo.Light.Button.Borderless" />
- <public type="style" name="Widget.Holo.Light.FastScroll" />
- <public type="style" name="Widget.Holo.Light.StackView" />
+ <public type="style" name="__removed3" />
+ <public type="style" name="__removed4" />
+ <public type="style" name="__removed5" />
+ <public type="style" name="__removed6" />
+ <public type="style" name="__removed7" />
<public type="style" name="Widget.DeviceDefault.FastScroll" />
<public type="style" name="Widget.DeviceDefault.StackView" />
-
<public type="style" name="Widget.DeviceDefault.Light.FastScroll" />
<public type="style" name="Widget.DeviceDefault.Light.StackView" />
@@ -2540,7 +2541,7 @@
<public type="style" name="Theme.Leanback.FormWizard"/>
- <public type="style" name="__removed" />
+ <public type="style" name="__removed1" />
<public type="style" name="TextAppearance.Material.Notification" />
<public type="style" name="TextAppearance.Material.Notification.Title" />
<public type="style" name="TextAppearance.Material.Notification.Line2" />
@@ -2559,6 +2560,12 @@
<public type="style" name="Theme.Material.Light.Dialog.Alert" />
<public type="style" name="Theme.Material.Light.Dialog.Presentation" />
+ <public type="style" name="Widget.Material.SearchView" />
+ <public type="style" name="Widget.Material.Light.SearchView" />
+ <public type="style" name="Widget.Material.TimePicker" />
+ <public type="style" name="Widget.Material.Light.TimePicker" />
+ <public type="style" name="Widget.Material.Light.DatePicker" />
+
<public-padding type="string" name="l_resource_pad" end="0x01040030" />
<public type="string" name="config_webSettingsDefaultTextEncoding" />
diff --git a/core/res/res/values/removed.xml b/core/res/res/values/removed.xml
new file mode 100644
index 0000000..8eaca29
--- /dev/null
+++ b/core/res/res/values/removed.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Placeholder resources to be removed before release. -->
+<resources>
+ <style name="__removed1" />
+ <attr name="__removed2" />
+ <style name="__removed3" />
+ <style name="__removed4" />
+ <style name="__removed5" />
+ <style name="__removed6" />
+ <style name="__removed7" />
+</resources>
diff --git a/core/res/res/values/styles_leanback.xml b/core/res/res/values/styles_leanback.xml
index 7606c86..aaeaadd 100644
--- a/core/res/res/values/styles_leanback.xml
+++ b/core/res/res/values/styles_leanback.xml
@@ -36,24 +36,28 @@
<!-- Setup and form wizard themes -->
<style name="TextAppearance.Leanback.FormWizard" parent="@style/TextAppearance.Material">
<item name="textSize">18sp</item>
+ <item name="lineSpacingExtra">24sp</item>
<item name="fontFamily">sans-serif-light</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Leanback.FormWizard.Small" parent="@style/TextAppearance.Material.Small">
- <item name="textSize">18sp</item>
+ <item name="textSize">14sp</item>
+ <item name="lineSpacingExtra">24sp</item>
<item name="fontFamily">sans-serif-light</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Leanback.FormWizard.Medium" parent="@style/TextAppearance.Material.Medium">
<item name="textSize">36sp</item>
+ <item name="lineSpacingExtra">40sp</item>
<item name="fontFamily">sans-serif-thin</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Leanback.FormWizard.Large" parent="@style/TextAppearance.Material.Large">
- <item name="textSize">56sp</item>
+ <item name="textSize">42sp</item>
+ <item name="lineSpacingExtra">48sp</item>
<item name="fontFamily">sans-serif-thin</item>
<item name="textColor">?attr/textColorPrimary</item>
</style>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 26c7d10..836f886 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -851,10 +851,7 @@
<item name="src">@drawable/ic_menu_moreoverflow_material</item>
<item name="background">?attr/actionBarItemBackground</item>
<item name="contentDescription">@string/action_menu_overflow_description</item>
- <item name="minWidth">@dimen/action_button_min_width_material</item>
- <item name="minHeight">@dimen/action_button_min_height_material</item>
<item name="paddingEnd">12dp</item>
- <item name="scaleType">center</item>
</style>
<style name="Widget.Material.ActionBar.TabView" parent="Widget.ActionBar.TabView">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 556c07f..7fc522f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -294,7 +294,9 @@
<java-symbol type="bool" name="config_hasRecents" />
<java-symbol type="bool" name="config_windowShowCircularMask" />
<java-symbol type="bool" name="config_windowEnableCircularEmulatorDisplayOverlay" />
-
+ <java-symbol type="bool" name="config_wifi_framework_enable_associated_autojoin_scan" />
+ <java-symbol type="bool" name="config_wifi_framework_enable_associated_network_selection" />
+ <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
<java-symbol type="integer" name="config_bluetooth_max_advertisers" />
<java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
<java-symbol type="integer" name="config_cursorWindowSize" />
@@ -2012,4 +2014,5 @@
<java-symbol type="attr" name="closeItemLayout" />
<java-symbol type="layout" name="resolver_different_item_header" />
<java-symbol type="array" name="config_default_vm_number" />
+ <java-symbol type="integer" name="config_cdma_3waycall_flash_delay"/>
</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 48de5ad..d0097aac 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -192,6 +192,7 @@
<item name="navigationBarColor">@color/black</item>
<item name="windowActionBarFullscreenDecorLayout">@layout/screen_action_bar</item>
<item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">false</item>
<!-- Define these here; ContextThemeWrappers around themes that define them should
always clear these values. -->
@@ -816,6 +817,7 @@
<!-- Theme for the dialog shown when an app crashes or ANRs. -->
<style name="Theme.Dialog.AppError" parent="Theme.DeviceDefault.Light.Dialog.Alert">
<item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">false</item>
<item name="windowCloseOnTouchOutside">false</item>
</style>
@@ -827,6 +829,7 @@
<item name="textColor">@color/secondary_text_nofocus</item>
<item name="windowCloseOnTouchOutside">false</item>
<item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">false</item>
</style>
<!-- Theme for a window that looks like a toast. -->
@@ -836,6 +839,7 @@
<item name="backgroundDimEnabled">false</item>
<item name="windowCloseOnTouchOutside">false</item>
<item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">false</item>
</style>
</resources>
diff --git a/core/res/res/values/themes_leanback.xml b/core/res/res/values/themes_leanback.xml
index 720733f..82cf288 100644
--- a/core/res/res/values/themes_leanback.xml
+++ b/core/res/res/values/themes_leanback.xml
@@ -76,6 +76,7 @@
<style name="Theme.Leanback.Dialog.AppError" parent="Theme.Leanback.Dialog">
<item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">false</item>
<item name="windowCloseOnTouchOutside">false</item>
</style>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 4aca02e..008e170 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -157,7 +157,8 @@
<item name="windowTitleStyle">@style/WindowTitle.Material</item>
<item name="windowTitleSize">@dimen/action_bar_default_height_material</item>
<item name="windowTitleBackgroundStyle">@style/WindowTitleBackground.Material</item>
- <item name="windowContentTransitions">true</item>
+ <item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">true</item>
<item name="windowAnimationStyle">@style/Animation.Material.Activity</item>
<item name="windowSoftInputMode">stateUnspecified|adjustUnspecified</item>
<item name="windowActionBar">true</item>
@@ -511,7 +512,8 @@
<item name="windowEnterTransition">@transition/fade</item>
<item name="windowSharedElementEnterTransition">@transition/move</item>
<item name="windowSharedElementExitTransition">@transition/move</item>
- <item name="windowContentTransitions">true</item>
+ <item name="windowContentTransitions">false</item>
+ <item name="windowActivityTransitions">true</item>
<!-- Dialog attributes -->
<item name="dialogTheme">@style/Theme.Material.Light.Dialog</item>
@@ -1256,7 +1258,4 @@
<item name="colorPrimaryDark">@color/material_blue_grey_950</item>
<item name="colorAccent">@color/material_deep_teal_500</item>
</style>
-
- <!-- TODO: Spacer to be removed from here and public.xml -->
- <style name="__removed" />
</resources>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
index 2354484..f4ea6f2 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/WifiAssociationTestRunner.java
@@ -16,17 +16,12 @@
package com.android.connectivitymanagertest;
-import android.content.Context;
-import android.net.wifi.WifiManager;
-import android.os.Bundle;
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
-import android.util.Log;
import com.android.connectivitymanagertest.functional.WifiAssociationTest;
import junit.framework.TestSuite;
-import junit.framework.Assert;
/**
* Instrumentation Test Runner for wifi association test.
@@ -39,8 +34,6 @@
* -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
*/
public class WifiAssociationTestRunner extends InstrumentationTestRunner {
- private static final String TAG = "WifiAssociationTestRunner";
- public int mBand;
@Override
public TestSuite getAllTests() {
@@ -53,35 +46,4 @@
public ClassLoader getLoader() {
return WifiAssociationTestRunner.class.getClassLoader();
}
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- String mFrequencyBand = icicle.getString("frequency-band");
- if (mFrequencyBand != null) {
- setFrequencyBand(mFrequencyBand);
- }
- }
-
- private void setFrequencyBand(String band) {
- WifiManager mWifiManager = (WifiManager)getContext().getSystemService(Context.WIFI_SERVICE);
- if (band.equals("2.4")) {
- Log.v(TAG, "set frequency band to 2.4");
- mBand = WifiManager.WIFI_FREQUENCY_BAND_2GHZ;
- } else if (band.equals("5.0")) {
- Log.v(TAG, "set frequency band to 5.0");
- mBand = WifiManager.WIFI_FREQUENCY_BAND_5GHZ;
- } else if (band.equals("auto")) {
- Log.v(TAG, "set frequency band to auto");
- mBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO;
- } else {
- Assert.fail("invalid frequency band");
- }
- int currentFreq = mWifiManager.getFrequencyBand();
- if (mBand == currentFreq) {
- Log.v(TAG, "frequency band has been set");
- return;
- }
- mWifiManager.setFrequencyBand(mBand, true);
- }
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
index c2b80dc..68f3179 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiAssociationTest.java
@@ -16,14 +16,13 @@
package com.android.connectivitymanagertest.functional;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo.State;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiConfiguration.AuthAlgorithm;
import android.net.wifi.WifiConfiguration.GroupCipher;
import android.net.wifi.WifiConfiguration.PairwiseCipher;
import android.net.wifi.WifiConfiguration.Protocol;
import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.test.suitebuilder.annotation.LargeTest;
@@ -39,13 +38,7 @@
* -w com.android.connectivitymanagertest/.WifiAssociationTestRunner"
*/
public class WifiAssociationTest extends ConnectivityManagerTestBase {
- private String mSsid = null;
- private String mPassword = null;
- private String mSecurityType = null;
- private String mFrequencyBand = null;
- private int mBand;
-
- enum SECURITY_TYPE {
+ private enum SecurityType {
OPEN, WEP64, WEP128, WPA_TKIP, WPA2_AES
}
@@ -53,86 +46,106 @@
super(WifiAssociationTest.class.getSimpleName());
}
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- WifiAssociationTestRunner runner = (WifiAssociationTestRunner)getInstrumentation();
- Bundle arguments = runner.getArguments();
- mSecurityType = arguments.getString("security-type");
- mSsid = arguments.getString("ssid");
- mPassword = arguments.getString("password");
- mFrequencyBand = arguments.getString("frequency-band");
- mBand = runner.mBand;
- assertNotNull("security type is empty", mSecurityType);
- assertNotNull("ssid is empty", mSsid);
- validateFrequencyBand();
-
- // enable wifi and verify wpa_supplicant is started
- assertTrue("enable Wifi failed", enableWifi());
- assertTrue("wifi not connected", waitForNetworkState(
- ConnectivityManager.TYPE_WIFI, State.CONNECTED, LONG_TIMEOUT));
- WifiInfo wi = mWifiManager.getConnectionInfo();
- assertNotNull("no active wifi info", wi);
- assertTrue("failed to ping wpa_supplicant ", mWifiManager.pingSupplicant());
- }
-
- private void validateFrequencyBand() {
- if (mFrequencyBand != null) {
- int currentFreq = mWifiManager.getFrequencyBand();
- logv("read frequency band: " + currentFreq);
- assertEquals("specified frequency band does not match operational band of WifiManager",
- currentFreq, mBand);
- }
- }
-
+ /**
+ * Test that the wifi can associate with a given access point.
+ */
@LargeTest
public void testWifiAssociation() {
- assertNotNull("no test ssid", mSsid);
+ WifiAssociationTestRunner runner = (WifiAssociationTestRunner) getInstrumentation();
+ Bundle arguments = runner.getArguments();
+
+ String ssid = arguments.getString("ssid");
+ assertNotNull("ssid is empty", ssid);
+
+ String securityTypeStr = arguments.getString("security-type");
+ assertNotNull("security-type is empty", securityTypeStr);
+ SecurityType securityType = SecurityType.valueOf(securityTypeStr);
+
+ String password = arguments.getString("password");
+
+ String freqStr = arguments.getString("frequency-band");
+ if (freqStr != null) {
+ setFrequencyBand(freqStr);
+ }
+
+ assertTrue("enable Wifi failed", enableWifi());
+ WifiInfo wi = mWifiManager.getConnectionInfo();
+ logv("%s", wi);
+ assertNotNull("no active wifi info", wi);
+
+ WifiConfiguration config = getConfig(ssid, securityType, password);
+
+ logv("Network config: %s", config.toString());
+ connectToWifi(config);
+ }
+
+ /**
+ * Set the frequency band and verify that it has been set.
+ */
+ private void setFrequencyBand(String frequencyBandStr) {
+ int frequencyBand = -1;
+ if ("2.4".equals(frequencyBandStr)) {
+ frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_2GHZ;
+ } else if ("5.0".equals(frequencyBandStr)) {
+ frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_5GHZ;
+ } else if ("auto".equals(frequencyBandStr)) {
+ frequencyBand = WifiManager.WIFI_FREQUENCY_BAND_AUTO;
+ } else {
+ fail("Invalid frequency-band");
+ }
+ if (mWifiManager.getFrequencyBand() != frequencyBand) {
+ logv("Set frequency band to %s", frequencyBandStr);
+ mWifiManager.setFrequencyBand(frequencyBand, true);
+ }
+ assertEquals("Specified frequency band does not match operational band",
+ frequencyBand, mWifiManager.getFrequencyBand());
+ }
+
+ /**
+ * Get the {@link WifiConfiguration} based on ssid, security, and password.
+ */
+ private WifiConfiguration getConfig(String ssid, SecurityType securityType, String password) {
+ logv("Security type is %s", securityType.toString());
+
WifiConfiguration config = null;
- SECURITY_TYPE security = SECURITY_TYPE.valueOf(mSecurityType);
- logv("Security type is " + security.toString());
- switch (security) {
- // set network configurations
+ switch (securityType) {
case OPEN:
- config = WifiConfigurationHelper.createOpenConfig(mSsid);
+ config = WifiConfigurationHelper.createOpenConfig(ssid);
break;
case WEP64:
- assertNotNull("password is empty", mPassword);
+ assertNotNull("password is empty", password);
// always use hex pair for WEP-40
- assertTrue(WifiConfigurationHelper.isHex(mPassword, 10));
- config = WifiConfigurationHelper.createWepConfig(mSsid, mPassword);
+ assertTrue(WifiConfigurationHelper.isHex(password, 10));
+ config = WifiConfigurationHelper.createWepConfig(ssid, password);
config.allowedGroupCiphers.set(GroupCipher.WEP40);
break;
case WEP128:
- assertNotNull("password is empty", mPassword);
+ assertNotNull("password is empty", password);
// always use hex pair for WEP-104
- assertTrue(WifiConfigurationHelper.isHex(mPassword, 26));
- config = WifiConfigurationHelper.createWepConfig(mSsid, mPassword);
+ assertTrue(WifiConfigurationHelper.isHex(password, 26));
+ config = WifiConfigurationHelper.createWepConfig(ssid, password);
config.allowedGroupCiphers.set(GroupCipher.WEP104);
break;
case WPA_TKIP:
- assertNotNull("password is empty", mPassword);
- config = WifiConfigurationHelper.createPskConfig(mSsid, mPassword);
+ assertNotNull("password is empty", password);
+ config = WifiConfigurationHelper.createPskConfig(ssid, password);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedProtocols.set(Protocol.WPA);
config.allowedPairwiseCiphers.set(PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(GroupCipher.TKIP);
break;
case WPA2_AES:
- assertNotNull("password is empty", mPassword);
- config = WifiConfigurationHelper.createPskConfig(mSsid, mPassword);
+ assertNotNull("password is empty", password);
+ config = WifiConfigurationHelper.createPskConfig(ssid, password);
config.allowedAuthAlgorithms.set(AuthAlgorithm.OPEN);
config.allowedProtocols.set(Protocol.RSN);
config.allowedPairwiseCiphers.set(PairwiseCipher.CCMP);
config.allowedGroupCiphers.set(GroupCipher.CCMP);
break;
default:
- fail("Not a valid security type: " + mSecurityType);
+ fail("Not a valid security type: " + securityType);
break;
}
- logv("network config: %s", config.toString());
- connectToWifi(config);
- // verify that connection actually works
- assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
+ return config;
}
}
diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
index 5958c3a..30eb939 100644
--- a/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
+++ b/core/tests/inputmethodtests/src/android/os/InputMethodTest.java
@@ -16,8 +16,6 @@
package android.os;
-import com.android.internal.inputmethod.InputMethodUtils;
-
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ResolveInfo;
@@ -28,14 +26,25 @@
import android.view.inputmethod.InputMethodSubtype;
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder;
+import com.android.internal.inputmethod.InputMethodUtils;
+
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
public class InputMethodTest extends InstrumentationTestCase {
private static final boolean IS_AUX = true;
private static final boolean IS_DEFAULT = true;
private static final boolean IS_AUTO = true;
+ private static final boolean IS_ASCII_CAPABLE = true;
+ private static final boolean IS_SYSTEM_READY = true;
private static final ArrayList<InputMethodSubtype> NO_SUBTYPE = null;
+ private static final Locale LOCALE_EN_US = new Locale("en", "US");
+ private static final Locale LOCALE_EN_GB = new Locale("en", "GB");
+ private static final Locale LOCALE_EN_IN = new Locale("en", "IN");
+ private static final Locale LOCALE_HI = new Locale("hi");
@SmallTest
public void testDefaultEnabledImesWithDefaultVoiceIme() throws Exception {
@@ -45,22 +54,79 @@
imis.add(createNonDefaultAutoDummyVoiceIme0());
imis.add(createNonDefaultAutoDummyVoiceIme1());
imis.add(createNonDefaultDummyVoiceIme2());
- imis.add(createDefaultDummyEnUSKeyboardIme());
+ imis.add(createDefaultDummyLatinKeyboardIme());
imis.add(createNonDefaultDummyJaJPKeyboardIme());
imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
- final ArrayList<InputMethodInfo> enabledImis = InputMethodUtils.getDefaultEnabledImes(
- context, true, imis);
- assertEquals(2, enabledImis.size());
- for (int i = 0; i < enabledImis.size(); ++i) {
- final InputMethodInfo imi = enabledImis.get(0);
- // "DummyDefaultAutoVoiceIme" and "DummyDefaultEnKeyboardIme"
- if (imi.getPackageName().equals("DummyDefaultAutoVoiceIme")
- || imi.getPackageName().equals("DummyDefaultEnKeyboardIme")) {
- continue;
- } else {
- fail("Invalid enabled subtype.");
- }
- }
+ imis.add(createDefaultDummyHinglishKeyboardIme());
+
+ // locale: en_US, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnUs =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_EN_US);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleEnUs));
+
+ // locale: en_US, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnUs =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_EN_US);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleEnUs));
+
+ // locale: en_GB, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnGB =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_EN_GB);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleEnGB));
+
+ // locale: en_GB, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnGB =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_EN_GB);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleEnGB));
+
+ // locale: en_IN, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnIN =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_EN_IN);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleEnIN));
+
+ // locale: en_IN, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnIN =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_EN_IN);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleEnIN));
+
+ // locale: hi, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleHi =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_HI);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleHi));
+
+ // locale: hi, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleHi =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_HI);
+ assertEquals(toSet("DummyDefaultAutoVoiceIme", "DummyDefaultEnKeyboardIme",
+ "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleHi));
}
@SmallTest
@@ -70,24 +136,74 @@
imis.add(createNonDefaultAutoDummyVoiceIme0());
imis.add(createNonDefaultAutoDummyVoiceIme1());
imis.add(createNonDefaultDummyVoiceIme2());
- imis.add(createDefaultDummyEnUSKeyboardIme());
+ imis.add(createDefaultDummyLatinKeyboardIme());
imis.add(createNonDefaultDummyJaJPKeyboardIme());
imis.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
- final ArrayList<InputMethodInfo> enabledImis = InputMethodUtils.getDefaultEnabledImes(
- context, true, imis);
- assertEquals(3, enabledImis.size());
- for (int i = 0; i < enabledImis.size(); ++i) {
- final InputMethodInfo imi = enabledImis.get(0);
- // "DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1" and
- // "DummyDefaultEnKeyboardIme"
- if (imi.getPackageName().equals("DummyNonDefaultAutoVoiceIme0")
- || imi.getPackageName().equals("DummyNonDefaultAutoVoiceIme1")
- || imi.getPackageName().equals("DummyDefaultEnKeyboardIme")) {
- continue;
- } else {
- fail("Invalid enabled subtype.");
- }
- }
+ imis.add(createDefaultDummyHinglishKeyboardIme());
+
+ // locale: en_US, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnUs =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_EN_US);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleEnUs));
+
+ // locale: en_US, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnUs =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_EN_US);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleEnUs));
+
+ // locale: en_GB, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnGB =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_EN_GB);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleEnGB));
+
+ // locale: en_GB, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnGB =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_EN_GB);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleEnGB));
+
+ // locale: en_IN, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleEnIN =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_EN_IN);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleEnIN));
+
+ // locale: en_IN, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleEnIN =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_EN_IN);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleEnIN));
+
+ // locale: hi, system: not ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemNotReadyLocaleHi =
+ callGetDefaultEnabledImesUnderWithLocale(context, !IS_SYSTEM_READY, imis,
+ LOCALE_HI);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemNotReadyLocaleHi));
+
+ // locale: hi, system: ready
+ final ArrayList<InputMethodInfo> enabledImisForSystemReadyLocaleHi =
+ callGetDefaultEnabledImesUnderWithLocale(context, IS_SYSTEM_READY, imis,
+ LOCALE_HI);
+ assertEquals(toSet("DummyNonDefaultAutoVoiceIme0", "DummyNonDefaultAutoVoiceIme1",
+ "DummyDefaultEnKeyboardIme", "DummyDefaultHinglishKeyboardIme"),
+ getPackageNames(enabledImisForSystemReadyLocaleHi));
}
@SmallTest
@@ -96,7 +212,7 @@
originalList.add(createNonDefaultAutoDummyVoiceIme0());
originalList.add(createNonDefaultAutoDummyVoiceIme1());
originalList.add(createNonDefaultDummyVoiceIme2());
- originalList.add(createDefaultDummyEnUSKeyboardIme());
+ originalList.add(createDefaultDummyLatinKeyboardIme());
originalList.add(createNonDefaultDummyJaJPKeyboardIme());
originalList.add(createNonDefaultDummyJaJPKeyboardImeWithoutSubtypes());
@@ -128,6 +244,32 @@
}
}
+ private static ArrayList<InputMethodInfo> callGetDefaultEnabledImesUnderWithLocale(
+ final Context context, final boolean isSystemReady,
+ final ArrayList<InputMethodInfo> imis, final Locale locale) {
+ final Locale initialLocale = context.getResources().getConfiguration().locale;
+ try {
+ context.getResources().getConfiguration().setLocale(locale);
+ return InputMethodUtils.getDefaultEnabledImes(context, isSystemReady, imis);
+ } finally {
+ context.getResources().getConfiguration().setLocale(initialLocale);
+ }
+ }
+
+ @SafeVarargs
+ private static <T> HashSet<T> toSet(final T... xs) {
+ return new HashSet<T>(Arrays.asList(xs));
+ }
+
+ private HashSet<String> getPackageNames(final ArrayList<InputMethodInfo> imis) {
+ final HashSet<String> packageNames = new HashSet<>();
+ for (final InputMethodInfo imi : imis) {
+ final String actualPackageName = imi.getPackageName();
+ packageNames.add(actualPackageName);
+ }
+ return packageNames;
+ }
+
private static void verifyEquality(InputMethodInfo expected, InputMethodInfo actual) {
assertEquals(expected, actual);
assertEquals(expected.getSubtypeCount(), actual.getSubtypeCount());
@@ -159,7 +301,8 @@
}
private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode,
- boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype) {
+ boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype,
+ boolean isAsciiCapable) {
return new InputMethodSubtypeBuilder()
.setSubtypeNameResId(0)
.setSubtypeIconResId(0)
@@ -168,50 +311,68 @@
.setSubtypeExtraValue("")
.setIsAuxiliary(isAuxiliary)
.setOverridesImplicitlyEnabledSubtype(overridesImplicitlyEnabledSubtype)
+ .setIsAsciiCapable(isAsciiCapable)
.build();
}
private static InputMethodInfo createDefaultAutoDummyVoiceIme() {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
- subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO));
- subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO));
+ subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO,
+ !IS_ASCII_CAPABLE));
+ subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO,
+ !IS_ASCII_CAPABLE));
return createDummyInputMethodInfo("DummyDefaultAutoVoiceIme", "dummy.voice0",
"DummyVoice0", IS_AUX, IS_DEFAULT, subtypes);
}
private static InputMethodInfo createNonDefaultAutoDummyVoiceIme0() {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
- subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO));
- subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO));
+ subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO,
+ !IS_ASCII_CAPABLE));
+ subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO,
+ !IS_ASCII_CAPABLE));
return createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme0", "dummy.voice1",
"DummyVoice1", IS_AUX, !IS_DEFAULT, subtypes);
}
private static InputMethodInfo createNonDefaultAutoDummyVoiceIme1() {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
- subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO));
- subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO));
+ subtypes.add(createDummyInputMethodSubtype("auto", "voice", IS_AUX, IS_AUTO,
+ !IS_ASCII_CAPABLE));
+ subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO,
+ !IS_ASCII_CAPABLE));
return createDummyInputMethodInfo("DummyNonDefaultAutoVoiceIme1", "dummy.voice2",
"DummyVoice2", IS_AUX, !IS_DEFAULT, subtypes);
}
private static InputMethodInfo createNonDefaultDummyVoiceIme2() {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
- subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO));
+ subtypes.add(createDummyInputMethodSubtype("en_US", "voice", IS_AUX, !IS_AUTO,
+ !IS_ASCII_CAPABLE));
return createDummyInputMethodInfo("DummyNonDefaultVoiceIme2", "dummy.voice3",
"DummyVoice3", IS_AUX, !IS_DEFAULT, subtypes);
}
- private static InputMethodInfo createDefaultDummyEnUSKeyboardIme() {
+ private static InputMethodInfo createDefaultDummyLatinKeyboardIme() {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
- subtypes.add(createDummyInputMethodSubtype("en_US", "keyboard", !IS_AUX, !IS_AUTO));
+ subtypes.add(createDummyInputMethodSubtype("en_US", "keyboard", !IS_AUX, !IS_AUTO,
+ IS_ASCII_CAPABLE));
+ subtypes.add(createDummyInputMethodSubtype("en_GB", "keyboard", !IS_AUX, !IS_AUTO,
+ IS_ASCII_CAPABLE));
+ subtypes.add(createDummyInputMethodSubtype("en_IN", "keyboard", !IS_AUX, !IS_AUTO,
+ IS_ASCII_CAPABLE));
+ subtypes.add(createDummyInputMethodSubtype("hi", "keyboard", !IS_AUX, !IS_AUTO,
+ !IS_ASCII_CAPABLE)); // not AsciiCapable!
+ subtypes.add(createDummyInputMethodSubtype("hi_ZZ", "keyboard", !IS_AUX, !IS_AUTO,
+ IS_ASCII_CAPABLE));
return createDummyInputMethodInfo("DummyDefaultEnKeyboardIme", "dummy.keyboard0",
"DummyKeyboard0", !IS_AUX, IS_DEFAULT, subtypes);
}
private static InputMethodInfo createNonDefaultDummyJaJPKeyboardIme() {
final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
- subtypes.add(createDummyInputMethodSubtype("ja_JP", "keyboard", !IS_AUX, !IS_AUTO));
+ subtypes.add(createDummyInputMethodSubtype("ja_JP", "keyboard", !IS_AUX, !IS_AUTO,
+ IS_ASCII_CAPABLE));
return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardIme", "dummy.keyboard1",
"DummyKeyboard1", !IS_AUX, !IS_DEFAULT, subtypes);
}
@@ -223,4 +384,14 @@
return createDummyInputMethodInfo("DummyNonDefaultJaJPKeyboardImeWithoutSubtypes",
"dummy.keyboard2", "DummyKeyboard2", !IS_AUX, !IS_DEFAULT, NO_SUBTYPE);
}
+
+ private static InputMethodInfo createDefaultDummyHinglishKeyboardIme() {
+ final ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+ subtypes.add(createDummyInputMethodSubtype("en_IN", "keyboard", !IS_AUX, !IS_AUTO,
+ IS_ASCII_CAPABLE));
+ subtypes.add(createDummyInputMethodSubtype("hi", "keyboard", !IS_AUX, !IS_AUTO,
+ !IS_ASCII_CAPABLE)); // not AsciiCapable!
+ return createDummyInputMethodInfo("DummyDefaultHinglishKeyboardIme", "dummy.keyboard2",
+ "DummyKeyboard2", !IS_AUX, IS_DEFAULT, subtypes);
+ }
}
diff --git a/docs/html/tools/building/index.jd b/docs/html/tools/building/index.jd
index c64942f..c1f3019 100644
--- a/docs/html/tools/building/index.jd
+++ b/docs/html/tools/building/index.jd
@@ -79,3 +79,14 @@
running on a device.</li>
</ul>
+<p class="note"><b>Note:</b> Apps are limited to a 64K method reference limit. If your app reaches
+this limit, the build process outputs the following error message:
+
+<pre>Unable to execute dex: method ID not in [0, 0xffff]: 65536.</pre>
+
+To avoid this, you can
+<a href="http://android-developers.blogspot.com.es/2011/07/custom-class-loading-in-dalvik.html">load
+secondary dex files at runtime</a> and use
+<a href="http://developer.android.com/tools/help/proguard.html">ProGuard</a> to strip out unnecessary
+class references (Proguard only works when building in release mode).
+</p>
\ No newline at end of file
diff --git a/docs/html/training/efficient-downloads/redundant_redundant.jd b/docs/html/training/efficient-downloads/redundant_redundant.jd
index 4bf9af9..674298a 100644
--- a/docs/html/training/efficient-downloads/redundant_redundant.jd
+++ b/docs/html/training/efficient-downloads/redundant_redundant.jd
@@ -30,8 +30,8 @@
<p>The most fundamental way to reduce your downloads is to download only what you need. In terms of data, that means implementing REST APIs that allow you to specify query criteria that limit the returned data by using parameters such as the time of your last update.</p>
<p>Similarly, when downloading images, it's good practice to reduce the size of the images server-side, rather than downloading full-sized images that are reduced on the client.</p>
-
-<h2 id="LocalCache">Cache Files Locally</h2>
+
+<h2 id="LocalCache">Cache Files Locally</h2>
<p>Another important technique is to avoid downloading duplicate data. You can do this by aggressive caching. Always cache static resources, including on-demand downloads such as full size images, for as long as reasonably possible. On-demand resources should be stored separately to enable you to regularly flush your on-demand cache to manage its size.</p>
@@ -60,11 +60,11 @@
<p>Alternatively, you can use the managed / secure application cache. Note that this internal cache may be flushed when the system is running low on available storage.</p>
-<pre>Context.getCache();</pre>
+<pre>Context.getCacheDir();</pre>
<p>Files stored in either cache location will be erased when the application is uninstalled.</p>
-<h2 id="ResponseCache">Use the HttpURLConnection Response Cache</h2>
+<h2 id="ResponseCache">Use the HttpURLConnection Response Cache</h2>
<p>Android 4.0 added a response cache to {@code HttpURLConnection}. You can enable HTTP response caching on supported devices using reflection as follows:</p>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 0927ffd..f45c0cb 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -250,11 +250,6 @@
public void insertInorderBarrier() {}
/**
- * @hide
- */
- public void initializeLight(float lightX, float lightY, float lightZ, float lightRadius) {}
-
- /**
* Return true if the device that the current layer draws into is opaque
* (i.e. does not support per-pixel alpha).
*
@@ -416,10 +411,10 @@
* @return value to pass to restoreToCount() to balance this save()
*/
public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint, @Saveflags int saveFlags) {
- return native_saveLayer(mNativeCanvasWrapper,
- bounds.left, bounds.top, bounds.right, bounds.bottom,
- paint != null ? paint.mNativePaint : 0,
- saveFlags);
+ if (bounds == null) {
+ bounds = new RectF(getClipBounds());
+ }
+ return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
}
/**
@@ -462,17 +457,17 @@
* @param saveFlags see _SAVE_FLAG constants
* @return value to pass to restoreToCount() to balance this call
*/
- public int saveLayerAlpha(@NonNull RectF bounds, int alpha, @Saveflags int saveFlags) {
- alpha = Math.min(255, Math.max(0, alpha));
- return native_saveLayerAlpha(mNativeCanvasWrapper,
- bounds.left, bounds.top, bounds.right, bounds.bottom,
- alpha, saveFlags);
+ public int saveLayerAlpha(@Nullable RectF bounds, int alpha, @Saveflags int saveFlags) {
+ if (bounds == null) {
+ bounds = new RectF(getClipBounds());
+ }
+ return saveLayerAlpha(bounds.left, bounds.top, bounds.right, bounds.bottom, alpha, saveFlags);
}
/**
* Convenience for saveLayerAlpha(bounds, alpha, {@link #ALL_SAVE_FLAG})
*/
- public int saveLayerAlpha(@NonNull RectF bounds, int alpha) {
+ public int saveLayerAlpha(@Nullable RectF bounds, int alpha) {
return saveLayerAlpha(bounds, alpha, ALL_SAVE_FLAG);
}
@@ -481,6 +476,7 @@
*/
public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
@Saveflags int saveFlags) {
+ alpha = Math.min(255, Math.max(0, alpha));
return native_saveLayerAlpha(mNativeCanvasWrapper, left, top, right, bottom,
alpha, saveFlags);
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index e5e2f18..49e8b9d 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -27,6 +27,7 @@
import android.graphics.Outline;
import android.graphics.PorterDuff;
import android.graphics.Rect;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
@@ -131,7 +132,9 @@
private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
- private final AnimatedVectorDrawableState mAnimatedVectorState;
+ private AnimatedVectorDrawableState mAnimatedVectorState;
+
+ private boolean mMutated;
public AnimatedVectorDrawable() {
mAnimatedVectorState = new AnimatedVectorDrawableState(
@@ -140,7 +143,6 @@
private AnimatedVectorDrawable(AnimatedVectorDrawableState state, Resources res,
Theme theme) {
- // TODO: Correctly handle the constant state for AVD.
mAnimatedVectorState = new AnimatedVectorDrawableState(state);
if (theme != null && canApplyTheme()) {
applyTheme(theme);
@@ -148,8 +150,17 @@
}
@Override
+ public Drawable mutate() {
+ if (!mMutated && super.mutate() == this) {
+ mAnimatedVectorState = new AnimatedVectorDrawableState(mAnimatedVectorState);
+ mMutated = true;
+ }
+ return this;
+ }
+
+ @Override
public ConstantState getConstantState() {
- return null;
+ return mAnimatedVectorState;
}
@Override
@@ -311,14 +322,31 @@
int mChangingConfigurations;
VectorDrawable mVectorDrawable;
ArrayList<Animator> mAnimators;
+ ArrayMap<Animator, String> mTargetNameMap;
public AnimatedVectorDrawableState(AnimatedVectorDrawableState copy) {
if (copy != null) {
mChangingConfigurations = copy.mChangingConfigurations;
- // TODO: Make sure the constant state are handled correctly.
- mVectorDrawable = new VectorDrawable();
- mVectorDrawable.setAllowCaching(false);
- mAnimators = new ArrayList<Animator>();
+ if (copy.mVectorDrawable != null) {
+ mVectorDrawable = (VectorDrawable) copy.mVectorDrawable.getConstantState().newDrawable();
+ mVectorDrawable.mutate();
+ mVectorDrawable.setAllowCaching(false);
+ mVectorDrawable.setBounds(copy.mVectorDrawable.getBounds());
+ }
+ if (copy.mAnimators != null) {
+ final int numAnimators = copy.mAnimators.size();
+ mAnimators = new ArrayList<Animator>(numAnimators);
+ mTargetNameMap = new ArrayMap<Animator, String>(numAnimators);
+ for (int i = 0; i < numAnimators; ++i) {
+ Animator anim = copy.mAnimators.get(i);
+ Animator animClone = anim.clone();
+ String targetName = copy.mTargetNameMap.get(anim);
+ Object targetObject = mVectorDrawable.getTargetByName(targetName);
+ animClone.setTarget(targetObject);
+ mAnimators.add(animClone);
+ mTargetNameMap.put(animClone, targetName);
+ }
+ }
}
}
@@ -346,7 +374,12 @@
private void setupAnimatorsForTarget(String name, Animator animator) {
Object target = mAnimatedVectorState.mVectorDrawable.getTargetByName(name);
animator.setTarget(target);
+ if (mAnimatedVectorState.mAnimators == null) {
+ mAnimatedVectorState.mAnimators = new ArrayList<Animator>();
+ mAnimatedVectorState.mTargetNameMap = new ArrayMap<Animator, String>();
+ }
mAnimatedVectorState.mAnimators.add(animator);
+ mAnimatedVectorState.mTargetNameMap.put(animator, name);
if (DBG_ANIMATION_VECTOR_DRAWABLE) {
Log.v(LOGTAG, "add animator for target " + name + " " + animator);
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 2c8611e..2916d6c 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1552,6 +1552,7 @@
mUseLevel = state.mUseLevel;
mUseLevelForShape = state.mUseLevelForShape;
mOpaqueOverBounds = state.mOpaqueOverBounds;
+ mOpaqueOverShape = state.mOpaqueOverShape;
mThemeAttrs = state.mThemeAttrs;
mAttrSize = state.mAttrSize;
mAttrGradient = state.mAttrGradient;
@@ -1637,6 +1638,11 @@
}
}
+ // An unfilled shape is not opaque over bounds or shape
+ if (mColors == null && mColorStateList == null) {
+ return;
+ }
+
// Colors are opaque, so opaqueOverShape=true,
mOpaqueOverShape = true;
// and opaqueOverBounds=true if shape fills bounds
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index b05fb61..b13669b 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -156,6 +156,13 @@
private boolean mOverrideBounds;
/**
+ * Whether the next draw MUST draw something to canvas. Used to work around
+ * a bug in hardware invalidation following a render thread-accelerated
+ * animation.
+ */
+ private boolean mNeedsDraw;
+
+ /**
* Constructor used for drawable inflation.
*/
RippleDrawable() {
@@ -204,6 +211,8 @@
}
cancelExitingRipples();
+
+ mNeedsDraw = true;
invalidateSelf();
}
@@ -548,6 +557,8 @@
}
cancelExitingRipples();
+
+ mNeedsDraw = true;
invalidateSelf();
}
@@ -642,11 +653,12 @@
canvas.restoreToCount(rippleLayer);
}
- // If we failed to draw anything, at least draw a color so that
- // invalidation works correctly.
- if (contentLayer < 0 && backgroundLayer < 0 && rippleLayer < 0) {
+ // If we failed to draw anything and we just canceled animations, at
+ // least draw a color so that hardware invalidation works correctly.
+ if (contentLayer < 0 && backgroundLayer < 0 && rippleLayer < 0 && mNeedsDraw) {
canvas.drawColor(Color.TRANSPARENT);
}
+ mNeedsDraw = false;
canvas.restoreToCount(saveCount);
}
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index a07ccc4..4407a3c 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -104,8 +104,6 @@
* <dt><code>android:translateY</code></dt>
* <dd>The amount of translation on the Y coordinate.
* This is defined in the viewport space.</dd>
- * <dt><code>android:alpha</code></dt>
- * <dd>The amount of transparency.</dd>
* </dl></dd>
* </dl>
*
@@ -124,6 +122,10 @@
* <dd>Defines the color to draw the path outline (none if not present).</dd>
* <dt><code>android:strokeWidth</code></dt>
* <dd>The width a path stroke.</dd>
+ * <dt><code>android:strokeAlpha</code></dt>
+ * <dd>The opacity of a path stroke.</dd>
+ * <dt><code>android:fillAlpha</code></dt>
+ * <dd>The opacity to fill the path with.</dd>
* <dt><code>android:trimPathStart</code></dt>
* <dd>The fraction of the path to trim from the start, in the range from 0 to 1.</dd>
* <dt><code>android:trimPathEnd</code></dt>
@@ -629,6 +631,15 @@
mThemeAttrs = copy.mThemeAttrs;
mChangingConfigurations = copy.mChangingConfigurations;
mVPathRenderer = new VPathRenderer(copy.mVPathRenderer);
+ if (copy.mVPathRenderer.mFillPaint != null) {
+ mVPathRenderer.mFillPaint = new Paint(copy.mVPathRenderer.mFillPaint);
+ }
+ if (copy.mVPathRenderer.mStrokePaint != null) {
+ mVPathRenderer.mStrokePaint = new Paint(copy.mVPathRenderer.mStrokePaint);
+ }
+ if (copy.mVPathRenderer.mColorFilter != null) {
+ mVPathRenderer.mColorFilter = copy.mVPathRenderer.mColorFilter;
+ }
mTint = copy.mTint;
mTintMode = copy.mTintMode;
mAutoMirrored = copy.mAutoMirrored;
@@ -700,8 +711,8 @@
*/
// Variables that only used temporarily inside the draw() call, so there
// is no need for deep copying.
- private final Path mPath = new Path();
- private final Path mRenderPath = new Path();
+ private final Path mPath;
+ private final Path mRenderPath;
private static final Matrix IDENTITY_MATRIX = new Matrix();
private final Matrix mFinalPathMatrix = new Matrix();
@@ -724,6 +735,8 @@
public VPathRenderer() {
mRootGroup = new VGroup();
+ mPath = new Path();
+ mRenderPath = new Path();
}
public void setRootAlpha(int alpha) {
@@ -736,6 +749,8 @@
public VPathRenderer(VPathRenderer copy) {
mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
+ mPath = new Path(copy.mPath);
+ mRenderPath = new Path(copy.mRenderPath);
mBaseWidth = copy.mBaseWidth;
mBaseHeight = copy.mBaseHeight;
mViewportWidth = copy.mViewportWidth;
@@ -812,7 +827,7 @@
}
private void drawGroupTree(VGroup currentGroup, Matrix currentMatrix,
- float currentAlpha, Canvas canvas, int w, int h) {
+ Canvas canvas, int w, int h) {
// Calculate current group's matrix by preConcat the parent's and
// and the current one on the top of the stack.
// Basically the Mfinal = Mviewport * M0 * M1 * M2;
@@ -821,30 +836,26 @@
currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);
- float stackedAlpha = currentAlpha * currentGroup.mGroupAlpha;
-
// Draw the group tree in the same order as the XML file.
for (int i = 0; i < currentGroup.mChildren.size(); i++) {
Object child = currentGroup.mChildren.get(i);
if (child instanceof VGroup) {
VGroup childGroup = (VGroup) child;
drawGroupTree(childGroup, currentGroup.mStackedMatrix,
- stackedAlpha, canvas, w, h);
+ canvas, w, h);
} else if (child instanceof VPath) {
VPath childPath = (VPath) child;
- drawPath(currentGroup, childPath, stackedAlpha, canvas, w, h);
+ drawPath(currentGroup, childPath, canvas, w, h);
}
}
}
public void draw(Canvas canvas, int w, int h) {
// Travese the tree in pre-order to draw.
- drawGroupTree(mRootGroup, IDENTITY_MATRIX, ((float) mRootAlpha) / 0xFF,
- canvas, w, h);
+ drawGroupTree(mRootGroup, IDENTITY_MATRIX, canvas, w, h);
}
- private void drawPath(VGroup vGroup, VPath vPath, float stackedAlpha,
- Canvas canvas, int w, int h) {
+ private void drawPath(VGroup vGroup, VPath vPath, Canvas canvas, int w, int h) {
final float scaleX = w / mViewportWidth;
final float scaleY = h / mViewportHeight;
final float minScale = Math.min(scaleX, scaleY);
@@ -892,7 +903,8 @@
mFillPaint.setStyle(Paint.Style.FILL);
mFillPaint.setAntiAlias(true);
}
- mFillPaint.setColor(applyAlpha(fullPath.mFillColor, stackedAlpha));
+ mFillPaint.setColor(applyAlpha(fullPath.mFillColor,
+ fullPath.mFillAlpha));
canvas.drawPath(mRenderPath, mFillPaint);
}
@@ -915,7 +927,8 @@
strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
- strokePaint.setColor(applyAlpha(fullPath.mStrokeColor, stackedAlpha));
+ strokePaint.setColor(applyAlpha(fullPath.mStrokeColor,
+ fullPath.mStrokeAlpha));
strokePaint.setStrokeWidth(fullPath.mStrokeWidth * minScale);
canvas.drawPath(mRenderPath, strokePaint);
}
@@ -939,7 +952,6 @@
private float mScaleY = 1;
private float mTranslateX = 0;
private float mTranslateY = 0;
- private float mGroupAlpha = 1;
// mLocalMatrix is updated based on the update of transformation information,
// either parsed from the XML or by animation.
@@ -956,7 +968,6 @@
mScaleY = copy.mScaleY;
mTranslateX = copy.mTranslateX;
mTranslateY = copy.mTranslateY;
- mGroupAlpha = copy.mGroupAlpha;
mThemeAttrs = copy.mThemeAttrs;
mGroupName = copy.mGroupName;
mChangingConfigurations = copy.mChangingConfigurations;
@@ -1025,7 +1036,6 @@
mScaleY = a.getFloat(R.styleable.VectorDrawableGroup_scaleY, mScaleY);
mTranslateX = a.getFloat(R.styleable.VectorDrawableGroup_translateX, mTranslateX);
mTranslateY = a.getFloat(R.styleable.VectorDrawableGroup_translateY, mTranslateY);
- mGroupAlpha = a.getFloat(R.styleable.VectorDrawableGroup_alpha, mGroupAlpha);
final String groupName = a.getString(R.styleable.VectorDrawableGroup_name);
if (groupName != null) {
@@ -1147,18 +1157,6 @@
updateLocalMatrix();
}
}
-
- @SuppressWarnings("unused")
- public float getAlpha() {
- return mGroupAlpha;
- }
-
- @SuppressWarnings("unused")
- public void setAlpha(float groupAlpha) {
- if (groupAlpha != mGroupAlpha) {
- mGroupAlpha = groupAlpha;
- }
- }
}
/**
@@ -1262,8 +1260,11 @@
int mStrokeColor = Color.TRANSPARENT;
float mStrokeWidth = 0;
+
int mFillColor = Color.TRANSPARENT;
+ float mStrokeAlpha = 1.0f;
int mFillRule;
+ float mFillAlpha = 1.0f;
float mTrimPathStart = 0;
float mTrimPathEnd = 1;
float mTrimPathOffset = 0;
@@ -1282,8 +1283,10 @@
mStrokeColor = copy.mStrokeColor;
mStrokeWidth = copy.mStrokeWidth;
+ mStrokeAlpha = copy.mStrokeAlpha;
mFillColor = copy.mFillColor;
mFillRule = copy.mFillRule;
+ mFillAlpha = copy.mFillAlpha;
mTrimPathStart = copy.mTrimPathStart;
mTrimPathEnd = copy.mTrimPathEnd;
mTrimPathOffset = copy.mTrimPathOffset;
@@ -1344,6 +1347,8 @@
mFillColor = a.getColor(R.styleable.VectorDrawablePath_fillColor,
mFillColor);
+ mFillAlpha = a.getFloat(R.styleable.VectorDrawablePath_fillAlpha,
+ mFillAlpha);
mStrokeLineCap = getStrokeLineCap(a.getInt(
R.styleable.VectorDrawablePath_strokeLineCap, -1), mStrokeLineCap);
mStrokeLineJoin = getStrokeLineJoin(a.getInt(
@@ -1352,6 +1357,8 @@
R.styleable.VectorDrawablePath_strokeMiterLimit, mStrokeMiterlimit);
mStrokeColor = a.getColor(R.styleable.VectorDrawablePath_strokeColor,
mStrokeColor);
+ mStrokeAlpha = a.getFloat(R.styleable.VectorDrawablePath_strokeAlpha,
+ mStrokeAlpha);
mStrokeWidth = a.getFloat(R.styleable.VectorDrawablePath_strokeWidth,
mStrokeWidth);
mTrimPathEnd = a.getFloat(R.styleable.VectorDrawablePath_trimPathEnd,
@@ -1396,6 +1403,16 @@
}
@SuppressWarnings("unused")
+ float getstrokeAlpha() {
+ return mStrokeAlpha;
+ }
+
+ @SuppressWarnings("unused")
+ void setstrokeAlpha(float strokeAlpha) {
+ mStrokeAlpha = strokeAlpha;
+ }
+
+ @SuppressWarnings("unused")
int getFill() {
return mFillColor;
}
@@ -1406,6 +1423,16 @@
}
@SuppressWarnings("unused")
+ float getfillAlpha() {
+ return mFillAlpha;
+ }
+
+ @SuppressWarnings("unused")
+ void setfillAlpha(float fillAlpha) {
+ mFillAlpha = fillAlpha;
+ }
+
+ @SuppressWarnings("unused")
float getTrimPathStart() {
return mTrimPathStart;
}
diff --git a/include/android_runtime/AndroidRuntime.h b/include/android_runtime/AndroidRuntime.h
index 51e47e6..f3cfd97 100644
--- a/include/android_runtime/AndroidRuntime.h
+++ b/include/android_runtime/AndroidRuntime.h
@@ -45,6 +45,7 @@
};
void setArgv0(const char* argv0);
+ void addOption(const char* optionString, void* extra_info = NULL);
/**
* Register a set of methods in the specified class.
@@ -63,8 +64,6 @@
*/
static jclass findClass(JNIEnv* env, const char* className);
- int addVmArguments(int argc, const char* const argv[]);
-
void start(const char *classname, const Vector<String8>& options);
void exit(int code);
@@ -116,7 +115,6 @@
private:
static int startReg(JNIEnv* env);
- void addOption(const char* optionString, void* extra_info = NULL);
bool parseRuntimeOption(const char* property,
char* buffer,
const char* runtimeArg,
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index a93891a..20c94c5 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -31,6 +31,9 @@
// APIs used by CertInstaller
void installCaCertificate(in byte[] caCertificate);
+ // APIs used by DevicePolicyManager
+ boolean installKeyPair(in byte[] privateKey, in byte[] userCert, String alias);
+
// APIs used by Settings
boolean deleteCaCertificate(String alias);
boolean reset();
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 4873479..cb3a002 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -91,36 +91,13 @@
return getTransformedAlphaFromAlpha(getAlphaFromFactoredZ(factoredZ));
}
-inline int getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2,
- float divisor) {
- // When there is no distance difference, there is no need for extra vertices.
- if (vector1.lengthSquared() == 0 || vector2.lengthSquared() == 0) {
- return 0;
- }
- // The formula is :
- // extraNumber = floor(acos(dot(n1, n2)) / (M_PI / EXTRA_VERTEX_PER_PI))
- // The value ranges for each step are:
- // dot( ) --- [-1, 1]
- // acos( ) --- [0, M_PI]
- // floor(...) --- [0, EXTRA_VERTEX_PER_PI]
- float dotProduct = vector1.dot(vector2);
- // TODO: Use look up table for the dotProduct to extraVerticesNumber
- // computation, if needed.
- float angle = acosf(dotProduct);
- return (int) floor(angle / divisor);
-}
-
-inline void checkOverflow(int used, int total, const char* bufferName) {
- LOG_ALWAYS_FATAL_IF(used > total, "Error: %s overflow!!! used %d, total %d",
- bufferName, used, total);
-}
-
inline int getEdgeExtraAndUpdateSpike(Vector2* currentSpike,
const Vector3& secondVertex, const Vector3& centroid) {
Vector2 secondSpike = {secondVertex.x - centroid.x, secondVertex.y - centroid.y};
secondSpike.normalize();
- int result = getExtraVertexNumber(secondSpike, *currentSpike, EDGE_RADIANS_DIVISOR);
+ int result = ShadowTessellator::getExtraVertexNumber(secondSpike, *currentSpike,
+ EDGE_RADIANS_DIVISOR);
*currentSpike = secondSpike;
return result;
}
@@ -231,8 +208,8 @@
Vector2 currentNormal = getNormalFromVertices(casterVertices, i,
(i + 1) % casterVertexCount);
- int extraVerticesNumber = getExtraVertexNumber(currentNormal, previousNormal,
- CORNER_RADIANS_DIVISOR);
+ int extraVerticesNumber = ShadowTessellator::getExtraVertexNumber(currentNormal,
+ previousNormal, CORNER_RADIANS_DIVISOR);
float expansionDist = innerVertex.z * heightFactor * geomFactor;
const int cornerSlicesNumber = extraVerticesNumber + 1; // Minimal as 1.
@@ -349,9 +326,9 @@
shadowVertexBuffer.updateVertexCount(vertexBufferIndex);
shadowVertexBuffer.updateIndexCount(indexBufferIndex);
- checkOverflow(vertexBufferIndex, totalVertexCount, "Vertex Buffer");
- checkOverflow(indexBufferIndex, totalIndexCount, "Index Buffer");
- checkOverflow(umbraIndex, totalUmbraCount, "Umbra Buffer");
+ ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Vertex Buffer");
+ ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Index Buffer");
+ ShadowTessellator::checkOverflow(umbraIndex, totalUmbraCount, "Umbra Buffer");
#if DEBUG_SHADOW
for (int i = 0; i < vertexBufferIndex; i++) {
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index f853d1f..9b0025f 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -342,6 +342,7 @@
void Caches::deleteLayerDeferred(Layer* layer) {
Mutex::Autolock _l(mGarbageLock);
+ layer->state = Layer::kState_InGarbageList;
mLayerGarbage.push(layer);
}
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 91c4aee..b5089aa 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -30,7 +30,8 @@
namespace uirenderer {
Layer::Layer(Type layerType, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight)
- : caches(Caches::getInstance())
+ : state(kState_Uncached)
+ , caches(Caches::getInstance())
, renderState(renderState)
, texture(caches)
, type(layerType) {
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 36a4ed1..a8e1c26 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -59,6 +59,17 @@
kType_DisplayList,
};
+ // layer lifecycle, controlled from outside
+ enum State {
+ kState_Uncached = 0,
+ kState_InCache = 1,
+ kState_FailedToCache = 2,
+ kState_RemovedFromCache = 3,
+ kState_DeletedFromCache = 4,
+ kState_InGarbageList = 5,
+ };
+ State state; // public for logging/debugging purposes
+
Layer(Type type, RenderState& renderState, const uint32_t layerWidth, const uint32_t layerHeight);
~Layer();
diff --git a/libs/hwui/LayerCache.cpp b/libs/hwui/LayerCache.cpp
index d49daf6..833f64b 100644
--- a/libs/hwui/LayerCache.cpp
+++ b/libs/hwui/LayerCache.cpp
@@ -83,6 +83,7 @@
LAYER_LOGD("Destroying layer %dx%d, fbo %d", layer->getWidth(), layer->getHeight(),
layer->getFbo());
mSize -= layer->getWidth() * layer->getHeight() * 4;
+ layer->state = Layer::kState_DeletedFromCache;
Caches::getInstance().resourceCache.decrementRefcount(layer);
}
}
@@ -106,6 +107,7 @@
mCache.removeAt(index);
layer = entry.mLayer;
+ layer->state = Layer::kState_RemovedFromCache;
mSize -= layer->getWidth() * layer->getHeight() * 4;
LAYER_LOGD("Reusing layer %dx%d", layer->getWidth(), layer->getHeight());
@@ -166,8 +168,11 @@
mCache.add(entry);
mSize += size;
+ layer->state = Layer::kState_InCache;
return true;
}
+
+ layer->state = Layer::kState_FailedToCache;
return false;
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index dbd273d..31cc1c8 100755
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -54,10 +54,6 @@
namespace android {
namespace uirenderer {
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
static GLenum getFilter(const SkPaint* paint) {
if (!paint || paint->getFilterLevel() != SkPaint::kNone_FilterLevel) {
return GL_LINEAR;
@@ -3044,21 +3040,35 @@
}
void OpenGLRenderer::setupPaintFilter(int clearBits, int setBits) {
+ // TODO: don't bother with boolean, it's redundant with clear/set bits
mDrawModifiers.mHasDrawFilter = true;
mDrawModifiers.mPaintFilterClearBits = clearBits & SkPaint::kAllFlags;
mDrawModifiers.mPaintFilterSetBits = setBits & SkPaint::kAllFlags;
}
const SkPaint* OpenGLRenderer::filterPaint(const SkPaint* paint) {
+ // TODO: use CompatFlagsDrawFilter here, and combine logic with android/graphics/DrawFilter.cpp
+ // to avoid clobbering 0x02 paint flag
+
+ // Equivalent to the Java Paint's FILTER_BITMAP_FLAG.
+ static const uint32_t sFilterBitmapFlag = 0x02;
+
if (CC_LIKELY(!mDrawModifiers.mHasDrawFilter || !paint)) {
return paint;
}
- uint32_t flags = paint->getFlags();
+ const uint32_t clearBits = mDrawModifiers.mPaintFilterClearBits;
+ const uint32_t setBits = mDrawModifiers.mPaintFilterSetBits;
+ const uint32_t flags = (paint->getFlags() & ~clearBits) | setBits;
mFilteredPaint = *paint;
- mFilteredPaint.setFlags((flags & ~mDrawModifiers.mPaintFilterClearBits) |
- mDrawModifiers.mPaintFilterSetBits);
+ mFilteredPaint.setFlags(flags);
+
+ // check if paint filter trying to override bitmap filter
+ if ((clearBits | setBits) & sFilterBitmapFlag) {
+ mFilteredPaint.setFilterLevel(flags & sFilterBitmapFlag
+ ? SkPaint::kLow_FilterLevel : SkPaint::kNone_FilterLevel);
+ }
return &mFilteredPaint;
}
diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp
index ec8307f..54af528 100644
--- a/libs/hwui/RenderState.cpp
+++ b/libs/hwui/RenderState.cpp
@@ -39,13 +39,16 @@
void RenderState::onGLContextDestroyed() {
AutoMutex _lock(mLayerLock);
- if (CC_UNLIKELY(!mActiveLayers.empty())) {
+ size_t size = mActiveLayers.size();
+ if (CC_UNLIKELY(size != 0)) {
+ ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d",
+ mRegisteredContexts.size(), size, mActiveLayers.empty());
mCaches->dumpMemoryUsage();
for (std::set<renderthread::CanvasContext*>::iterator cit = mRegisteredContexts.begin();
cit != mRegisteredContexts.end(); cit++) {
renderthread::CanvasContext* context = *cit;
- ALOGD("Context: %p (root = %p)", context, context->mRootRenderNode.get());
- ALOGD(" Prefeteched layers: %zu", context->mPrefetechedLayers.size());
+ ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get());
+ ALOGE(" Prefeteched layers: %zu", context->mPrefetechedLayers.size());
for (std::set<RenderNode*>::iterator pit = context->mPrefetechedLayers.begin();
pit != context->mPrefetechedLayers.end(); pit++) {
(*pit)->debugDumpLayers(" ");
@@ -53,13 +56,17 @@
context->mRootRenderNode->debugDumpLayers(" ");
}
+
+ if (mActiveLayers.begin() == mActiveLayers.end()) {
+ ALOGE("set has become empty. wat.");
+ }
for (std::set<const Layer*>::iterator lit = mActiveLayers.begin();
lit != mActiveLayers.end(); lit++) {
const Layer* layer = *(lit);
- ALOGD("Layer %p, fbo %d, buildlayered %d",
- layer, layer->getFbo(), layer->wasBuildLayered);
+ ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d",
+ layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered);
}
- LOG_ALWAYS_FATAL("layers have survived gl context destruction");
+ LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size);
}
}
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 6cff815..c1ffa0a 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -252,5 +252,29 @@
}
}
+int ShadowTessellator::getExtraVertexNumber(const Vector2& vector1,
+ const Vector2& vector2, float divisor) {
+ // When there is no distance difference, there is no need for extra vertices.
+ if (vector1.lengthSquared() == 0 || vector2.lengthSquared() == 0) {
+ return 0;
+ }
+ // The formula is :
+ // extraNumber = floor(acos(dot(n1, n2)) / (M_PI / EXTRA_VERTEX_PER_PI))
+ // The value ranges for each step are:
+ // dot( ) --- [-1, 1]
+ // acos( ) --- [0, M_PI]
+ // floor(...) --- [0, EXTRA_VERTEX_PER_PI]
+ float dotProduct = vector1.dot(vector2);
+ // TODO: Use look up table for the dotProduct to extraVerticesNumber
+ // computation, if needed.
+ float angle = acosf(dotProduct);
+ return (int) floor(angle / divisor);
+}
+
+void ShadowTessellator::checkOverflow(int used, int total, const char* bufferName) {
+ LOG_ALWAYS_FATAL_IF(used > total, "Error: %s overflow!!! used %d, total %d",
+ bufferName, used, total);
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index 141dff6..8f19b5c 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -101,6 +101,10 @@
*/
static void reverseVertexArray(Vertex* polygon, int len);
+ static int getExtraVertexNumber(const Vector2& vector1, const Vector2& vector2,
+ float divisor);
+
+ static void checkOverflow(int used, int total, const char* bufferName);
}; // ShadowTessellator
}; // namespace uirenderer
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index 2178cc7..dbedf94 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -16,10 +16,34 @@
#define LOG_TAG "OpenGLRenderer"
-#define SHADOW_SHRINK_SCALE 0.1f
+// The highest z value can't be higher than (CASTER_Z_CAP_RATIO * light.z)
#define CASTER_Z_CAP_RATIO 0.95f
-#define FAKE_UMBRA_SIZE_RATIO 0.01f
-#define OCLLUDED_UMBRA_SHRINK_FACTOR 0.95f
+
+// When there is no umbra, then just fake the umbra using
+// centroid * (1 - FAKE_UMBRA_SIZE_RATIO) + outline * FAKE_UMBRA_SIZE_RATIO
+#define FAKE_UMBRA_SIZE_RATIO 0.05f
+
+// When the polygon is about 90 vertices, the penumbra + umbra can reach 270 rays.
+// That is consider pretty fine tessllated polygon so far.
+// This is just to prevent using too much some memory when edge slicing is not
+// needed any more.
+#define FINE_TESSELLATED_POLYGON_RAY_NUMBER 270
+/**
+ * Extra vertices for the corner for smoother corner.
+ * Only for outer loop.
+ * Note that we use such extra memory to avoid an extra loop.
+ */
+// For half circle, we could add EXTRA_VERTEX_PER_PI vertices.
+// Set to 1 if we don't want to have any.
+#define SPOT_EXTRA_CORNER_VERTEX_PER_PI 18
+
+// For the whole polygon, the sum of all the deltas b/t normals is 2 * M_PI,
+// therefore, the maximum number of extra vertices will be twice bigger.
+#define SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER (2 * SPOT_EXTRA_CORNER_VERTEX_PER_PI)
+
+// For each RADIANS_DIVISOR, we would allocate one more vertex b/t the normals.
+#define SPOT_CORNER_RADIANS_DIVISOR (M_PI / SPOT_EXTRA_CORNER_VERTEX_PER_PI)
+
#include <math.h>
#include <stdlib.h>
@@ -51,6 +75,24 @@
};
/**
+ * For each vertex, we need to keep track of its angle, whether it is penumbra or
+ * umbra, and its corresponding vertex index.
+ */
+struct SpotShadow::VertexAngleData {
+ // The angle to the vertex from the centroid.
+ float mAngle;
+ // True is the vertex comes from penumbra, otherwise it comes from umbra.
+ bool mIsPenumbra;
+ // The index of the vertex described by this data.
+ int mVertexIndex;
+ void set(float angle, bool isPenumbra, int index) {
+ mAngle = angle;
+ mIsPenumbra = isPenumbra;
+ mVertexIndex = index;
+ }
+};
+
+/**
* Calculate the angle between and x and a y coordinate.
* The atan2 range from -PI to PI.
*/
@@ -407,8 +449,8 @@
double endX = poly[i].x;
double endY = poly[i].y;
- if (((endY > testy) != (startY > testy)) &&
- (testx < (startX - endX) * (testy - endY)
+ if (((endY > testy) != (startY > testy))
+ && (testx < (startX - endX) * (testy - endY)
/ (startY - endY) + endX)) {
c = !c;
}
@@ -508,138 +550,14 @@
}
/**
-* Generate the shadow from a spot light.
-*
-* @param poly x,y,z vertexes of a convex polygon that occludes the light source
-* @param polyLength number of vertexes of the occluding polygon
-* @param lightCenter the center of the light
-* @param lightSize the radius of the light source
-* @param lightVertexCount the vertex counter for the light polygon
-* @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
-* empty strip if error.
-*
-*/
-
-void SpotShadow::createSpotShadow_old(bool isCasterOpaque, const Vector3* poly,
- int polyLength, const Vector3& lightCenter, float lightSize,
- int lightVertexCount, VertexBuffer& retStrips) {
- Vector3 light[lightVertexCount * 3];
- computeLightPolygon(lightVertexCount, lightCenter, lightSize, light);
- computeSpotShadow_old(isCasterOpaque, light, lightVertexCount, lightCenter, poly,
- polyLength, retStrips);
-}
-
-/**
- * Generate the shadow spot light of shape lightPoly and a object poly
+ * From light center, project one vertex to the z=0 surface and get the outline.
*
- * @param lightPoly x,y,z vertex of a convex polygon that is the light source
- * @param lightPolyLength number of vertexes of the light source polygon
- * @param poly x,y,z vertexes of a convex polygon that occludes the light source
- * @param polyLength number of vertexes of the occluding polygon
- * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
- * empty strip if error.
+ * @param outline The result which is the outline position.
+ * @param lightCenter The center of light.
+ * @param polyVertex The input polygon's vertex.
+ *
+ * @return float The ratio of (polygon.z / light.z - polygon.z)
*/
-void SpotShadow::computeSpotShadow_old(bool isCasterOpaque, const Vector3* lightPoly,
- int lightPolyLength, const Vector3& lightCenter, const Vector3* poly, int polyLength,
- VertexBuffer& shadowTriangleStrip) {
- // Point clouds for all the shadowed vertices
- Vector2 shadowRegion[lightPolyLength * polyLength];
- // Shadow polygon from one point light.
- Vector2 outline[polyLength];
- Vector2 umbraMem[polyLength * lightPolyLength];
- Vector2* umbra = umbraMem;
-
- int umbraLength = 0;
-
- // Validate input, receiver is always at z = 0 plane.
- bool inputPolyPositionValid = true;
- for (int i = 0; i < polyLength; i++) {
- if (poly[i].z >= lightPoly[0].z) {
- inputPolyPositionValid = false;
- ALOGW("polygon above the light");
- break;
- }
- }
-
- // If the caster's position is invalid, don't draw anything.
- if (!inputPolyPositionValid) {
- return;
- }
-
- // Calculate the umbra polygon based on intersections of all outlines
- int k = 0;
- for (int j = 0; j < lightPolyLength; j++) {
- int m = 0;
- for (int i = 0; i < polyLength; i++) {
- // After validating the input, deltaZ is guaranteed to be positive.
- float deltaZ = lightPoly[j].z - poly[i].z;
- float ratioZ = lightPoly[j].z / deltaZ;
- float x = lightPoly[j].x - ratioZ * (lightPoly[j].x - poly[i].x);
- float y = lightPoly[j].y - ratioZ * (lightPoly[j].y - poly[i].y);
-
- Vector2 newPoint = {x, y};
- shadowRegion[k] = newPoint;
- outline[m] = newPoint;
-
- k++;
- m++;
- }
-
- // For the first light polygon's vertex, use the outline as the umbra.
- // Later on, use the intersection of the outline and existing umbra.
- if (umbraLength == 0) {
- for (int i = 0; i < polyLength; i++) {
- umbra[i] = outline[i];
- }
- umbraLength = polyLength;
- } else {
- int col = ((j * 255) / lightPolyLength);
- umbraLength = intersection(outline, polyLength, umbra, umbraLength);
- if (umbraLength == 0) {
- break;
- }
- }
- }
-
- // Generate the penumbra area using the hull of all shadow regions.
- int shadowRegionLength = k;
- Vector2 penumbra[k];
- int penumbraLength = hull(shadowRegion, shadowRegionLength, penumbra);
-
- Vector2 fakeUmbra[polyLength];
- if (umbraLength < 3) {
- // If there is no real umbra, make a fake one.
- for (int i = 0; i < polyLength; i++) {
- float deltaZ = lightCenter.z - poly[i].z;
- float ratioZ = lightCenter.z / deltaZ;
- float x = lightCenter.x - ratioZ * (lightCenter.x - poly[i].x);
- float y = lightCenter.y - ratioZ * (lightCenter.y - poly[i].y);
-
- fakeUmbra[i].x = x;
- fakeUmbra[i].y = y;
- }
-
- // Shrink the centroid's shadow by 10%.
- // TODO: Study the magic number of 10%.
- Vector2 shadowCentroid =
- ShadowTessellator::centroid2d(fakeUmbra, polyLength);
- for (int i = 0; i < polyLength; i++) {
- fakeUmbra[i] = shadowCentroid * (1.0f - SHADOW_SHRINK_SCALE) +
- fakeUmbra[i] * SHADOW_SHRINK_SCALE;
- }
-#if DEBUG_SHADOW
- ALOGD("No real umbra make a fake one, centroid2d = %f , %f",
- shadowCentroid.x, shadowCentroid.y);
-#endif
- // Set the fake umbra, whose size is the same as the original polygon.
- umbra = fakeUmbra;
- umbraLength = polyLength;
- }
-
- generateTriangleStrip(isCasterOpaque, 1.0, penumbra, penumbraLength, umbra,
- umbraLength, poly, polyLength, shadowTriangleStrip);
-}
-
float SpotShadow::projectCasterToOutline(Vector2& outline,
const Vector3& lightCenter, const Vector3& polyVertex) {
float lightToPolyZ = lightCenter.z - polyVertex.z;
@@ -673,6 +591,12 @@
ALOGW("Relative Light Z is not positive. No spot shadow!");
return;
}
+ if (CC_UNLIKELY(polyLength < 3)) {
+#if DEBUG_SHADOW
+ ALOGW("Invalid polygon length. No spot shadow!");
+#endif
+ return;
+ }
OutlineData outlineData[polyLength];
Vector2 outlineCentroid;
// Calculate the projected outline for each polygon's vertices from the light center.
@@ -713,16 +637,20 @@
projectCasterToOutline(outlineCentroid, lightCenter, polyCentroid);
int penumbraIndex = 0;
- int penumbraLength = polyLength * 3;
- Vector2 penumbra[penumbraLength];
+ // Then each polygon's vertex produce at minmal 2 penumbra vertices.
+ // Since the size can be dynamic here, we keep track of the size and update
+ // the real size at the end.
+ int allocatedPenumbraLength = 2 * polyLength + SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER;
+ Vector2 penumbra[allocatedPenumbraLength];
+ int totalExtraCornerSliceNumber = 0;
Vector2 umbra[polyLength];
- float distOutline = 0;
- float ratioVI = 0;
+ // When centroid is covered by all circles from outline, then we consider
+ // the umbra is invalid, and we will tune down the shadow strength.
bool hasValidUmbra = true;
- // We need the maxRatioVI to decrease the spot shadow strength accordingly.
- float maxRaitoVI = 1.0;
+ // We need the minimal of RaitoVI to decrease the spot shadow strength accordingly.
+ float minRaitoVI = FLT_MAX;
for (int i = 0; i < polyLength; i++) {
// Generate all the penumbra's vertices only using the (outline vertex + normal * radius)
@@ -748,21 +676,35 @@
// | |
// (V3)-----------------------------------(V2)
int preNormalIndex = (i + polyLength - 1) % polyLength;
- penumbra[penumbraIndex++] = outlineData[i].position +
- outlineData[preNormalIndex].normal * outlineData[i].radius;
- int currentNormalIndex = i;
- // (TODO) Depending on how roundness we want for each corner, we can subdivide
+ const Vector2& previousNormal = outlineData[preNormalIndex].normal;
+ const Vector2& currentNormal = outlineData[i].normal;
+
+ // Depending on how roundness we want for each corner, we can subdivide
// further here and/or introduce some heuristic to decide how much the
// subdivision should be.
- Vector2 avgNormal =
- (outlineData[preNormalIndex].normal + outlineData[currentNormalIndex].normal) / 2;
+ int currentExtraSliceNumber = ShadowTessellator::getExtraVertexNumber(
+ previousNormal, currentNormal, SPOT_CORNER_RADIANS_DIVISOR);
- penumbra[penumbraIndex++] = outlineData[i].position +
- avgNormal * outlineData[i].radius;
+ int currentCornerSliceNumber = 1 + currentExtraSliceNumber;
+ totalExtraCornerSliceNumber += currentExtraSliceNumber;
+#if DEBUG_SHADOW
+ ALOGD("currentExtraSliceNumber should be %d", currentExtraSliceNumber);
+ ALOGD("currentCornerSliceNumber should be %d", currentCornerSliceNumber);
+ ALOGD("totalCornerSliceNumber is %d", totalExtraCornerSliceNumber);
+#endif
+ if (CC_UNLIKELY(totalExtraCornerSliceNumber > SPOT_MAX_EXTRA_CORNER_VERTEX_NUMBER)) {
+ currentCornerSliceNumber = 1;
+ }
+ for (int k = 0; k <= currentCornerSliceNumber; k++) {
+ Vector2 avgNormal =
+ (previousNormal * (currentCornerSliceNumber - k) + currentNormal * k) /
+ currentCornerSliceNumber;
+ avgNormal.normalize();
+ penumbra[penumbraIndex++] = outlineData[i].position +
+ avgNormal * outlineData[i].radius;
+ }
- penumbra[penumbraIndex++] = outlineData[i].position +
- outlineData[currentNormalIndex].normal * outlineData[i].radius;
// Compute the umbra by the intersection from the outline's centroid!
//
@@ -783,53 +725,70 @@
// Now, ratioVI = VI / VC, ratioIC = IC / VC
// Then the intersetion point can be computed as Ixy = Vxy * ratioIC + Cxy * ratioVI;
//
- // When one of the outline circle cover the the outline centroid, (like I is
+ // When all of the outline circles cover the the outline centroid, (like I is
// on the other side of C), there is no real umbra any more, so we just fake
// a small area around the centroid as the umbra, and tune down the spot
// shadow's umbra strength to simulate the effect the whole shadow will
// become lighter in this case.
// The ratio can be simulated by using the inverse of maximum of ratioVI for
// all (V).
- distOutline = (outlineData[i].position - outlineCentroid).length();
+ float distOutline = (outlineData[i].position - outlineCentroid).length();
if (CC_UNLIKELY(distOutline == 0)) {
// If the outline has 0 area, then there is no spot shadow anyway.
ALOGW("Outline has 0 area, no spot shadow!");
return;
}
- ratioVI = outlineData[i].radius / distOutline;
- if (ratioVI >= 1.0) {
- maxRaitoVI = ratioVI;
- hasValidUmbra = false;
+
+ float ratioVI = outlineData[i].radius / distOutline;
+ minRaitoVI = MathUtils::min(minRaitoVI, ratioVI);
+ if (ratioVI >= (1 - FAKE_UMBRA_SIZE_RATIO)) {
+ ratioVI = (1 - FAKE_UMBRA_SIZE_RATIO);
}
// When we know we don't have valid umbra, don't bother to compute the
// values below. But we can't skip the loop yet since we want to know the
// maximum ratio.
- if (hasValidUmbra) {
- float ratioIC = (distOutline - outlineData[i].radius) / distOutline;
- umbra[i] = outlineData[i].position * ratioIC + outlineCentroid * ratioVI;
- }
+ float ratioIC = 1 - ratioVI;
+ umbra[i] = outlineData[i].position * ratioIC + outlineCentroid * ratioVI;
}
+ hasValidUmbra = (minRaitoVI <= 1.0);
float shadowStrengthScale = 1.0;
if (!hasValidUmbra) {
+#if DEBUG_SHADOW
ALOGW("The object is too close to the light or too small, no real umbra!");
+#endif
for (int i = 0; i < polyLength; i++) {
umbra[i] = outlineData[i].position * FAKE_UMBRA_SIZE_RATIO +
- outlineCentroid * (1 - FAKE_UMBRA_SIZE_RATIO);
+ outlineCentroid * (1 - FAKE_UMBRA_SIZE_RATIO);
}
- shadowStrengthScale = 1.0 / maxRaitoVI;
+ shadowStrengthScale = 1.0 / minRaitoVI;
}
+ int penumbraLength = penumbraIndex;
+ int umbraLength = polyLength;
+
#if DEBUG_SHADOW
+ ALOGD("penumbraLength is %d , allocatedPenumbraLength %d", penumbraLength, allocatedPenumbraLength);
dumpPolygon(poly, polyLength, "input poly");
- dumpPolygon(outline, polyLength, "outline");
dumpPolygon(penumbra, penumbraLength, "penumbra");
- dumpPolygon(umbra, polyLength, "umbra");
+ dumpPolygon(umbra, umbraLength, "umbra");
ALOGD("hasValidUmbra is %d and shadowStrengthScale is %f", hasValidUmbra, shadowStrengthScale);
#endif
- generateTriangleStrip(isCasterOpaque, shadowStrengthScale, penumbra,
- penumbraLength, umbra, polyLength, poly, polyLength, shadowTriangleStrip);
+ // The penumbra and umbra needs to be in convex shape to keep consistency
+ // and quality.
+ // Since we are still shooting rays to penumbra, it needs to be convex.
+ // Umbra can be represented as a fan from the centroid, but visually umbra
+ // looks nicer when it is convex.
+ Vector2 finalUmbra[umbraLength];
+ Vector2 finalPenumbra[penumbraLength];
+ int finalUmbraLength = hull(umbra, umbraLength, finalUmbra);
+ int finalPenumbraLength = hull(penumbra, penumbraLength, finalPenumbra);
+
+ generateTriangleStrip(isCasterOpaque, shadowStrengthScale, finalPenumbra,
+ finalPenumbraLength, finalUmbra, finalUmbraLength, poly, polyLength,
+ shadowTriangleStrip, outlineCentroid);
+
}
/**
@@ -891,7 +850,7 @@
lastVertex = &poly[polyIndex];
}
- return true;
+ return true;
}
int SpotShadow::calculateOccludedUmbra(const Vector2* umbra, int umbraLength,
@@ -910,100 +869,6 @@
}
/**
- * Generate a triangle strip given two convex polygons
- *
- * @param penumbra The outer polygon x,y vertexes
- * @param penumbraLength The number of vertexes in the outer polygon
- * @param umbra The inner outer polygon x,y vertexes
- * @param umbraLength The number of vertexes in the inner polygon
- * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
- * empty strip if error.
-**/
-void SpotShadow::generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
- const Vector2* penumbra, int penumbraLength, const Vector2* umbra, int umbraLength,
- const Vector3* poly, int polyLength, VertexBuffer& shadowTriangleStrip) {
- const int rays = SHADOW_RAY_COUNT;
- const int size = 2 * rays;
- const float step = M_PI * 2 / rays;
- // Centroid of the umbra.
- Vector2 centroid = ShadowTessellator::centroid2d(umbra, umbraLength);
-#if DEBUG_SHADOW
- ALOGD("centroid2d = %f , %f", centroid.x, centroid.y);
-#endif
- // Intersection to the penumbra.
- float penumbraDistPerRay[rays];
- // Intersection to the umbra.
- float umbraDistPerRay[rays];
- // Intersection to the occluded umbra area.
- float occludedUmbraDistPerRay[rays];
-
- // convert CW polygons to ray distance encoding, aborting on conversion failure
- if (!convertPolyToRayDist(umbra, umbraLength, centroid, umbraDistPerRay)) return;
- if (!convertPolyToRayDist(penumbra, penumbraLength, centroid, penumbraDistPerRay)) return;
-
- bool hasOccludedUmbraArea = false;
- if (isCasterOpaque) {
- Vector2 occludedUmbra[polyLength + umbraLength];
- int occludedUmbraLength = calculateOccludedUmbra(umbra, umbraLength, poly, polyLength,
- occludedUmbra);
- // Make sure the centroid is inside the umbra, otherwise, fall back to the
- // approach as if there is no occluded umbra area.
- if (testPointInsidePolygon(centroid, occludedUmbra, occludedUmbraLength)) {
- hasOccludedUmbraArea = true;
- // Shrink the occluded umbra area to avoid pixel level artifacts.
- for (int i = 0; i < occludedUmbraLength; i ++) {
- occludedUmbra[i] = centroid + (occludedUmbra[i] - centroid) *
- OCLLUDED_UMBRA_SHRINK_FACTOR;
- }
- if (!convertPolyToRayDist(occludedUmbra, occludedUmbraLength, centroid,
- occludedUmbraDistPerRay)) {
- return;
- }
- }
- }
- AlphaVertex* shadowVertices =
- shadowTriangleStrip.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
-
- // NOTE: Shadow alpha values are transformed when stored in alphavertices,
- // so that they can be consumed directly by gFS_Main_ApplyVertexAlphaShadowInterp
- float transformedMaxAlpha = M_PI * shadowStrengthScale;
-
- // Calculate the vertices (x, y, alpha) in the shadow area.
- AlphaVertex centroidXYA;
- AlphaVertex::set(¢roidXYA, centroid.x, centroid.y, transformedMaxAlpha);
- for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
- float dx = cosf(step * rayIndex);
- float dy = sinf(step * rayIndex);
-
- // penumbra ring
- float penumbraDistance = penumbraDistPerRay[rayIndex];
- AlphaVertex::set(&shadowVertices[rayIndex],
- dx * penumbraDistance + centroid.x,
- dy * penumbraDistance + centroid.y, 0.0f);
-
- // umbra ring
- float umbraDistance = umbraDistPerRay[rayIndex];
- AlphaVertex::set(&shadowVertices[rays + rayIndex],
- dx * umbraDistance + centroid.x,
- dy * umbraDistance + centroid.y,
- transformedMaxAlpha);
-
- // occluded umbra ring
- if (hasOccludedUmbraArea) {
- float occludedUmbraDistance = occludedUmbraDistPerRay[rayIndex];
- AlphaVertex::set(&shadowVertices[2 * rays + rayIndex],
- dx * occludedUmbraDistance + centroid.x,
- dy * occludedUmbraDistance + centroid.y, transformedMaxAlpha);
- } else {
- // Put all vertices of the occluded umbra ring at the centroid.
- shadowVertices[2 * rays + rayIndex] = centroidXYA;
- }
- }
- shadowTriangleStrip.setMode(VertexBuffer::kTwoPolyRingShadow);
- shadowTriangleStrip.computeBounds<AlphaVertex>();
-}
-
-/**
* This is only for experimental purpose.
* After intersections are calculated, we could smooth the polygon if needed.
* So far, we don't think it is more appealing yet.
@@ -1024,15 +889,656 @@
}
}
+/**
+ * Generate a array of the angleData for either umbra or penumbra vertices.
+ *
+ * This array will be merged and used to guide where to shoot the rays, in clockwise order.
+ *
+ * @param angleDataList The result array of angle data.
+ *
+ * @return int The maximum angle's index in the array.
+ */
+int SpotShadow::setupAngleList(VertexAngleData* angleDataList,
+ int polyLength, const Vector2* polygon, const Vector2& centroid,
+ bool isPenumbra, const char* name) {
+ float maxAngle = FLT_MIN;
+ int maxAngleIndex = 0;
+ for (int i = 0; i < polyLength; i++) {
+ float currentAngle = angle(polygon[i], centroid);
+ if (currentAngle > maxAngle) {
+ maxAngle = currentAngle;
+ maxAngleIndex = i;
+ }
+ angleDataList[i].set(currentAngle, isPenumbra, i);
+#if DEBUG_SHADOW
+ ALOGD("%s AngleList i %d %f", name, i, currentAngle);
+#endif
+ }
+ return maxAngleIndex;
+}
+
+/**
+ * Make sure the polygons are indeed in clockwise order.
+ *
+ * Possible reasons to return false: 1. The input polygon is not setup properly. 2. The hull
+ * algorithm is not able to generate it properly.
+ *
+ * Anyway, since the algorithm depends on the clockwise, when these kind of unexpected error
+ * situation is found, we need to detect it and early return without corrupting the memory.
+ *
+ * @return bool True if the angle list is actually from big to small.
+ */
+bool SpotShadow::checkClockwise(int indexOfMaxAngle, int listLength, VertexAngleData* angleList,
+ const char* name) {
+ int currentIndex = indexOfMaxAngle;
+#if DEBUG_SHADOW
+ ALOGD("max index %d", currentIndex);
+#endif
+ for (int i = 0; i < listLength - 1; i++) {
+ // TODO: Cache the last angle.
+ float currentAngle = angleList[currentIndex].mAngle;
+ float nextAngle = angleList[(currentIndex + 1) % listLength].mAngle;
+ if (currentAngle < nextAngle) {
+#if DEBUG_SHADOW
+ ALOGE("%s, is not CW, at index %d", name, currentIndex);
+#endif
+ return false;
+ }
+ currentIndex = (currentIndex + 1) % listLength;
+ }
+ return true;
+}
+
+/**
+ * Check the polygon is clockwise.
+ *
+ * @return bool True is the polygon is clockwise.
+ */
+bool SpotShadow::checkPolyClockwise(int polyAngleLength, int maxPolyAngleIndex,
+ const float* polyAngleList) {
+ bool isPolyCW = true;
+ // Starting from maxPolyAngleIndex , check around to make sure angle decrease.
+ for (int i = 0; i < polyAngleLength - 1; i++) {
+ float currentAngle = polyAngleList[(i + maxPolyAngleIndex) % polyAngleLength];
+ float nextAngle = polyAngleList[(i + maxPolyAngleIndex + 1) % polyAngleLength];
+ if (currentAngle < nextAngle) {
+ isPolyCW = false;
+ }
+ }
+ return isPolyCW;
+}
+
+/**
+ * Given the sorted array of all the vertices angle data, calculate for each
+ * vertices, the offset value to array element which represent the start edge
+ * of the polygon we need to shoot the ray at.
+ *
+ * TODO: Calculate this for umbra and penumbra in one loop using one single array.
+ *
+ * @param distances The result of the array distance counter.
+ */
+void SpotShadow::calculateDistanceCounter(bool needsOffsetToUmbra, int angleLength,
+ const VertexAngleData* allVerticesAngleData, int* distances) {
+
+ bool firstVertexIsPenumbra = allVerticesAngleData[0].mIsPenumbra;
+ // If we want distance to inner, then we just set to 0 when we see inner.
+ bool needsSearch = needsOffsetToUmbra ? firstVertexIsPenumbra : !firstVertexIsPenumbra;
+ int distanceCounter = 0;
+ if (needsSearch) {
+ int foundIndex = -1;
+ for (int i = (angleLength - 1); i >= 0; i--) {
+ bool currentIsOuter = allVerticesAngleData[i].mIsPenumbra;
+ // If we need distance to inner, then we need to find a inner vertex.
+ if (currentIsOuter != firstVertexIsPenumbra) {
+ foundIndex = i;
+ break;
+ }
+ }
+ LOG_ALWAYS_FATAL_IF(foundIndex == -1, "Wrong index found, means either"
+ " umbra or penumbra's length is 0");
+ distanceCounter = angleLength - foundIndex;
+ }
+#if DEBUG_SHADOW
+ ALOGD("distances[0] is %d", distanceCounter);
+#endif
+
+ distances[0] = distanceCounter; // means never see a target poly
+
+ for (int i = 1; i < angleLength; i++) {
+ bool firstVertexIsPenumbra = allVerticesAngleData[i].mIsPenumbra;
+ // When we needs for distance for each outer vertex to inner, then we
+ // increase the distance when seeing outer vertices. Otherwise, we clear
+ // to 0.
+ bool needsIncrement = needsOffsetToUmbra ? firstVertexIsPenumbra : !firstVertexIsPenumbra;
+ // If counter is not -1, that means we have seen an other polygon's vertex.
+ if (needsIncrement && distanceCounter != -1) {
+ distanceCounter++;
+ } else {
+ distanceCounter = 0;
+ }
+ distances[i] = distanceCounter;
+ }
+}
+
+/**
+ * Given umbra and penumbra angle data list, merge them by sorting the angle
+ * from the biggest to smallest.
+ *
+ * @param allVerticesAngleData The result array of merged angle data.
+ */
+void SpotShadow::mergeAngleList(int maxUmbraAngleIndex, int maxPenumbraAngleIndex,
+ const VertexAngleData* umbraAngleList, int umbraLength,
+ const VertexAngleData* penumbraAngleList, int penumbraLength,
+ VertexAngleData* allVerticesAngleData) {
+
+ int totalRayNumber = umbraLength + penumbraLength;
+ int umbraIndex = maxUmbraAngleIndex;
+ int penumbraIndex = maxPenumbraAngleIndex;
+
+ float currentUmbraAngle = umbraAngleList[umbraIndex].mAngle;
+ float currentPenumbraAngle = penumbraAngleList[penumbraIndex].mAngle;
+
+ // TODO: Clean this up using a while loop with 2 iterators.
+ for (int i = 0; i < totalRayNumber; i++) {
+ if (currentUmbraAngle > currentPenumbraAngle) {
+ allVerticesAngleData[i] = umbraAngleList[umbraIndex];
+ umbraIndex = (umbraIndex + 1) % umbraLength;
+
+ // If umbraIndex round back, that means we are running out of
+ // umbra vertices to merge, so just copy all the penumbra leftover.
+ // Otherwise, we update the currentUmbraAngle.
+ if (umbraIndex != maxUmbraAngleIndex) {
+ currentUmbraAngle = umbraAngleList[umbraIndex].mAngle;
+ } else {
+ for (int j = i + 1; j < totalRayNumber; j++) {
+ allVerticesAngleData[j] = penumbraAngleList[penumbraIndex];
+ penumbraIndex = (penumbraIndex + 1) % penumbraLength;
+ }
+ break;
+ }
+ } else {
+ allVerticesAngleData[i] = penumbraAngleList[penumbraIndex];
+ penumbraIndex = (penumbraIndex + 1) % penumbraLength;
+ // If penumbraIndex round back, that means we are running out of
+ // penumbra vertices to merge, so just copy all the umbra leftover.
+ // Otherwise, we update the currentPenumbraAngle.
+ if (penumbraIndex != maxPenumbraAngleIndex) {
+ currentPenumbraAngle = penumbraAngleList[penumbraIndex].mAngle;
+ } else {
+ for (int j = i + 1; j < totalRayNumber; j++) {
+ allVerticesAngleData[j] = umbraAngleList[umbraIndex];
+ umbraIndex = (umbraIndex + 1) % umbraLength;
+ }
+ break;
+ }
+ }
+ }
+}
+
+#if DEBUG_SHADOW
+/**
+ * DEBUG ONLY: Verify all the offset compuation is correctly done by examining
+ * each vertex and its neighbor.
+ */
+static void verifyDistanceCounter(const VertexAngleData* allVerticesAngleData,
+ const int* distances, int angleLength, const char* name) {
+ int currentDistance = distances[0];
+ for (int i = 1; i < angleLength; i++) {
+ if (distances[i] != INT_MIN) {
+ if (!((currentDistance + 1) == distances[i]
+ || distances[i] == 0)) {
+ ALOGE("Wrong distance found at i %d name %s", i, name);
+ }
+ currentDistance = distances[i];
+ if (currentDistance != 0) {
+ bool currentOuter = allVerticesAngleData[i].mIsPenumbra;
+ for (int j = 1; j <= (currentDistance - 1); j++) {
+ bool neigborOuter =
+ allVerticesAngleData[(i + angleLength - j) % angleLength].mIsPenumbra;
+ if (neigborOuter != currentOuter) {
+ ALOGE("Wrong distance found at i %d name %s", i, name);
+ }
+ }
+ bool oppositeOuter =
+ allVerticesAngleData[(i + angleLength - currentDistance) % angleLength].mIsPenumbra;
+ if (oppositeOuter == currentOuter) {
+ ALOGE("Wrong distance found at i %d name %s", i, name);
+ }
+ }
+ }
+ }
+}
+
+/**
+ * DEBUG ONLY: Verify all the angle data compuated are is correctly done
+ */
+static void verifyAngleData(int totalRayNumber, const VertexAngleData* allVerticesAngleData,
+ const int* distancesToInner, const int* distancesToOuter,
+ const VertexAngleData* umbraAngleList, int maxUmbraAngleIndex, int umbraLength,
+ const VertexAngleData* penumbraAngleList, int maxPenumbraAngleIndex,
+ int penumbraLength) {
+ for (int i = 0; i < totalRayNumber; i++) {
+ ALOGD("currentAngleList i %d, angle %f, isInner %d, index %d distancesToInner"
+ " %d distancesToOuter %d", i, allVerticesAngleData[i].mAngle,
+ !allVerticesAngleData[i].mIsPenumbra,
+ allVerticesAngleData[i].mVertexIndex, distancesToInner[i], distancesToOuter[i]);
+ }
+
+ verifyDistanceCounter(allVerticesAngleData, distancesToInner, totalRayNumber, "distancesToInner");
+ verifyDistanceCounter(allVerticesAngleData, distancesToOuter, totalRayNumber, "distancesToOuter");
+
+ for (int i = 0; i < totalRayNumber; i++) {
+ if ((distancesToInner[i] * distancesToOuter[i]) != 0) {
+ ALOGE("distancesToInner wrong at index %d distancesToInner[i] %d,"
+ " distancesToOuter[i] %d", i, distancesToInner[i], distancesToOuter[i]);
+ }
+ }
+ int currentUmbraVertexIndex =
+ umbraAngleList[maxUmbraAngleIndex].mVertexIndex;
+ int currentPenumbraVertexIndex =
+ penumbraAngleList[maxPenumbraAngleIndex].mVertexIndex;
+ for (int i = 0; i < totalRayNumber; i++) {
+ if (allVerticesAngleData[i].mIsPenumbra == true) {
+ if (allVerticesAngleData[i].mVertexIndex != currentPenumbraVertexIndex) {
+ ALOGW("wrong penumbra indexing i %d allVerticesAngleData[i].mVertexIndex %d "
+ "currentpenumbraVertexIndex %d", i,
+ allVerticesAngleData[i].mVertexIndex, currentPenumbraVertexIndex);
+ }
+ currentPenumbraVertexIndex = (currentPenumbraVertexIndex + 1) % penumbraLength;
+ } else {
+ if (allVerticesAngleData[i].mVertexIndex != currentUmbraVertexIndex) {
+ ALOGW("wrong umbra indexing i %d allVerticesAngleData[i].mVertexIndex %d "
+ "currentUmbraVertexIndex %d", i,
+ allVerticesAngleData[i].mVertexIndex, currentUmbraVertexIndex);
+ }
+ currentUmbraVertexIndex = (currentUmbraVertexIndex + 1) % umbraLength;
+ }
+ }
+ for (int i = 0; i < totalRayNumber - 1; i++) {
+ float currentAngle = allVerticesAngleData[i].mAngle;
+ float nextAngle = allVerticesAngleData[(i + 1) % totalRayNumber].mAngle;
+ if (currentAngle < nextAngle) {
+ ALOGE("Unexpected angle values!, currentAngle nextAngle %f %f", currentAngle, nextAngle);
+ }
+ }
+}
+#endif
+
+/**
+ * In order to compute the occluded umbra, we need to setup the angle data list
+ * for the polygon data. Since we only store one poly vertex per polygon vertex,
+ * this array only needs to be a float array which are the angles for each vertex.
+ *
+ * @param polyAngleList The result list
+ *
+ * @return int The index for the maximum angle in this array.
+ */
+int SpotShadow::setupPolyAngleList(float* polyAngleList, int polyAngleLength,
+ const Vector2* poly2d, const Vector2& centroid) {
+ int maxPolyAngleIndex = -1;
+ float maxPolyAngle = -FLT_MAX;
+ for (int i = 0; i < polyAngleLength; i++) {
+ polyAngleList[i] = angle(poly2d[i], centroid);
+ if (polyAngleList[i] > maxPolyAngle) {
+ maxPolyAngle = polyAngleList[i];
+ maxPolyAngleIndex = i;
+ }
+ }
+ return maxPolyAngleIndex;
+}
+
+/**
+ * For umbra and penumbra, given the offset info and the current ray number,
+ * find the right edge index (the (starting vertex) for the ray to shoot at.
+ *
+ * @return int The index of the starting vertex of the edge.
+ */
+inline int SpotShadow::getEdgeStartIndex(const int* offsets, int rayIndex, int totalRayNumber,
+ const VertexAngleData* allVerticesAngleData) {
+ int tempOffset = offsets[rayIndex];
+ int targetRayIndex = (rayIndex - tempOffset + totalRayNumber) % totalRayNumber;
+ return allVerticesAngleData[targetRayIndex].mVertexIndex;
+}
+
+/**
+ * For the occluded umbra, given the array of angles, find the index of the
+ * starting vertex of the edge, for the ray to shoo at.
+ *
+ * TODO: Save the last result to shorten the search distance.
+ *
+ * @return int The index of the starting vertex of the edge.
+ */
+inline int SpotShadow::getPolyEdgeStartIndex(int maxPolyAngleIndex, int polyLength,
+ const float* polyAngleList, float rayAngle) {
+ int minPolyAngleIndex = (maxPolyAngleIndex + polyLength - 1) % polyLength;
+ int resultIndex = -1;
+ if (rayAngle > polyAngleList[maxPolyAngleIndex]
+ || rayAngle <= polyAngleList[minPolyAngleIndex]) {
+ resultIndex = minPolyAngleIndex;
+ } else {
+ for (int i = 0; i < polyLength - 1; i++) {
+ int currentIndex = (maxPolyAngleIndex + i) % polyLength;
+ int nextIndex = (maxPolyAngleIndex + i + 1) % polyLength;
+ if (rayAngle <= polyAngleList[currentIndex]
+ && rayAngle > polyAngleList[nextIndex]) {
+ resultIndex = currentIndex;
+ }
+ }
+ }
+ if (CC_UNLIKELY(resultIndex == -1)) {
+ // TODO: Add more error handling here.
+ ALOGE("Wrong index found, means no edge can't be found for rayAngle %f", rayAngle);
+ }
+ return resultIndex;
+}
+
+/**
+ * Convert the incoming polygons into arrays of vertices, for each ray.
+ * Ray only shoots when there is one vertex either on penumbra on umbra.
+ *
+ * Finally, it will generate vertices per ray for umbra, penumbra and optionally
+ * occludedUmbra.
+ *
+ * Return true (success) when all vertices are generated
+ */
+int SpotShadow::convertPolysToVerticesPerRay(
+ bool hasOccludedUmbraArea, const Vector2* poly2d, int polyLength,
+ const Vector2* umbra, int umbraLength, const Vector2* penumbra,
+ int penumbraLength, const Vector2& centroid,
+ Vector2* umbraVerticesPerRay, Vector2* penumbraVerticesPerRay,
+ Vector2* occludedUmbraVerticesPerRay) {
+ int totalRayNumber = umbraLength + penumbraLength;
+
+ // For incoming umbra / penumbra polygons, we will build an intermediate data
+ // structure to help us sort all the vertices according to the vertices.
+ // Using this data structure, we can tell where (the angle) to shoot the ray,
+ // whether we shoot at penumbra edge or umbra edge, and which edge to shoot at.
+ //
+ // We first parse each vertices and generate a table of VertexAngleData.
+ // Based on that, we create 2 arrays telling us which edge to shoot at.
+ VertexAngleData allVerticesAngleData[totalRayNumber];
+ VertexAngleData umbraAngleList[umbraLength];
+ VertexAngleData penumbraAngleList[penumbraLength];
+
+ int polyAngleLength = hasOccludedUmbraArea ? polyLength : 0;
+ float polyAngleList[polyAngleLength];
+
+ const int maxUmbraAngleIndex =
+ setupAngleList(umbraAngleList, umbraLength, umbra, centroid, false, "umbra");
+ const int maxPenumbraAngleIndex =
+ setupAngleList(penumbraAngleList, penumbraLength, penumbra, centroid, true, "penumbra");
+ const int maxPolyAngleIndex = setupPolyAngleList(polyAngleList, polyAngleLength, poly2d, centroid);
+
+ // Check all the polygons here are CW.
+ bool isPolyCW = checkPolyClockwise(polyAngleLength, maxPolyAngleIndex, polyAngleList);
+ bool isUmbraCW = checkClockwise(maxUmbraAngleIndex, umbraLength,
+ umbraAngleList, "umbra");
+ bool isPenumbraCW = checkClockwise(maxPenumbraAngleIndex, penumbraLength,
+ penumbraAngleList, "penumbra");
+
+ if (!isUmbraCW || !isPenumbraCW || !isPolyCW) {
+#if DEBUG_SHADOW
+ ALOGE("One polygon is not CW isUmbraCW %d isPenumbraCW %d isPolyCW %d",
+ isUmbraCW, isPenumbraCW, isPolyCW);
+#endif
+ return false;
+ }
+
+ mergeAngleList(maxUmbraAngleIndex, maxPenumbraAngleIndex,
+ umbraAngleList, umbraLength, penumbraAngleList, penumbraLength,
+ allVerticesAngleData);
+
+ // Calculate the offset to the left most Inner vertex for each outerVertex.
+ // Then the offset to the left most Outer vertex for each innerVertex.
+ int offsetToInner[totalRayNumber];
+ int offsetToOuter[totalRayNumber];
+ calculateDistanceCounter(true, totalRayNumber, allVerticesAngleData, offsetToInner);
+ calculateDistanceCounter(false, totalRayNumber, allVerticesAngleData, offsetToOuter);
+
+ // Generate both umbraVerticesPerRay and penumbraVerticesPerRay
+ for (int i = 0; i < totalRayNumber; i++) {
+ float rayAngle = allVerticesAngleData[i].mAngle;
+ bool isUmbraVertex = !allVerticesAngleData[i].mIsPenumbra;
+
+ float dx = cosf(rayAngle);
+ float dy = sinf(rayAngle);
+ float distanceToIntersectUmbra = -1;
+
+ if (isUmbraVertex) {
+ // We can just copy umbra easily, and calculate the distance for the
+ // occluded umbra computation.
+ int startUmbraIndex = allVerticesAngleData[i].mVertexIndex;
+ umbraVerticesPerRay[i] = umbra[startUmbraIndex];
+ if (hasOccludedUmbraArea) {
+ distanceToIntersectUmbra = (umbraVerticesPerRay[i] - centroid).length();
+ }
+
+ //shoot ray to penumbra only
+ int startPenumbraIndex = getEdgeStartIndex(offsetToOuter, i, totalRayNumber,
+ allVerticesAngleData);
+ float distanceToIntersectPenumbra = rayIntersectPoints(centroid, dx, dy,
+ penumbra[startPenumbraIndex],
+ penumbra[(startPenumbraIndex + 1) % penumbraLength]);
+ if (distanceToIntersectPenumbra < 0) {
+#if DEBUG_SHADOW
+ ALOGW("convertPolyToRayDist for penumbra failed rayAngle %f dx %f dy %f",
+ rayAngle, dx, dy);
+#endif
+ distanceToIntersectPenumbra = 0;
+ }
+ penumbraVerticesPerRay[i].x = centroid.x + dx * distanceToIntersectPenumbra;
+ penumbraVerticesPerRay[i].y = centroid.y + dy * distanceToIntersectPenumbra;
+ } else {
+ // We can just copy the penumbra
+ int startPenumbraIndex = allVerticesAngleData[i].mVertexIndex;
+ penumbraVerticesPerRay[i] = penumbra[startPenumbraIndex];
+
+ // And shoot ray to umbra only
+ int startUmbraIndex = getEdgeStartIndex(offsetToInner, i, totalRayNumber,
+ allVerticesAngleData);
+
+ distanceToIntersectUmbra = rayIntersectPoints(centroid, dx, dy,
+ umbra[startUmbraIndex], umbra[(startUmbraIndex + 1) % umbraLength]);
+ if (distanceToIntersectUmbra < 0) {
+#if DEBUG_SHADOW
+ ALOGW("convertPolyToRayDist for umbra failed rayAngle %f dx %f dy %f",
+ rayAngle, dx, dy);
+#endif
+ distanceToIntersectUmbra = 0;
+ }
+ umbraVerticesPerRay[i].x = centroid.x + dx * distanceToIntersectUmbra;
+ umbraVerticesPerRay[i].y = centroid.y + dy * distanceToIntersectUmbra;
+ }
+
+ if (hasOccludedUmbraArea) {
+ // Shoot the same ray to the poly2d, and get the distance.
+ int startPolyIndex = getPolyEdgeStartIndex(maxPolyAngleIndex, polyLength,
+ polyAngleList, rayAngle);
+
+ float distanceToIntersectPoly = rayIntersectPoints(centroid, dx, dy,
+ poly2d[startPolyIndex], poly2d[(startPolyIndex + 1) % polyLength]);
+ if (distanceToIntersectPoly < 0) {
+ distanceToIntersectPoly = 0;
+ }
+ distanceToIntersectPoly = MathUtils::min(distanceToIntersectUmbra, distanceToIntersectPoly);
+ occludedUmbraVerticesPerRay[i].x = centroid.x + dx * distanceToIntersectPoly;
+ occludedUmbraVerticesPerRay[i].y = centroid.y + dy * distanceToIntersectPoly;
+ }
+ }
+
+#if DEBUG_SHADOW
+ verifyAngleData(totalRayNumber, allVerticesAngleData, offsetToInner,
+ offsetToOuter, umbraAngleList, maxUmbraAngleIndex, umbraLength,
+ penumbraAngleList, maxPenumbraAngleIndex, penumbraLength);
+#endif
+ return true; // success
+
+}
+
+/**
+ * Generate a triangle strip given two convex polygon
+**/
+void SpotShadow::generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
+ Vector2* penumbra, int penumbraLength, Vector2* umbra, int umbraLength,
+ const Vector3* poly, int polyLength, VertexBuffer& shadowTriangleStrip,
+ const Vector2& centroid) {
+
+ bool hasOccludedUmbraArea = false;
+ Vector2 poly2d[polyLength];
+
+ if (isCasterOpaque) {
+ for (int i = 0; i < polyLength; i++) {
+ poly2d[i].x = poly[i].x;
+ poly2d[i].y = poly[i].y;
+ }
+ // Make sure the centroid is inside the umbra, otherwise, fall back to the
+ // approach as if there is no occluded umbra area.
+ if (testPointInsidePolygon(centroid, poly2d, polyLength)) {
+ hasOccludedUmbraArea = true;
+ }
+ }
+
+ int totalRayNum = umbraLength + penumbraLength;
+ Vector2 umbraVertices[totalRayNum];
+ Vector2 penumbraVertices[totalRayNum];
+ Vector2 occludedUmbraVertices[totalRayNum];
+ bool convertSuccess = convertPolysToVerticesPerRay(hasOccludedUmbraArea, poly2d,
+ polyLength, umbra, umbraLength, penumbra, penumbraLength,
+ centroid, umbraVertices, penumbraVertices, occludedUmbraVertices);
+ if (!convertSuccess) {
+ return;
+ }
+
+ // Minimal value is 1, for each vertex show up once.
+ // The bigger this value is , the smoother the look is, but more memory
+ // is consumed.
+ // When the ray number is high, that means the polygon has been fine
+ // tessellated, we don't need this extra slice, just keep it as 1.
+ int sliceNumberPerEdge = (totalRayNum > FINE_TESSELLATED_POLYGON_RAY_NUMBER) ? 1 : 2;
+
+ // For each polygon, we at most add (totalRayNum * sliceNumberPerEdge) vertices.
+ int slicedVertexCountPerPolygon = totalRayNum * sliceNumberPerEdge;
+ int totalVertexCount = slicedVertexCountPerPolygon * 2 + totalRayNum;
+ int totalIndexCount = 2 * (slicedVertexCountPerPolygon * 2 + 2);
+ AlphaVertex* shadowVertices =
+ shadowTriangleStrip.alloc<AlphaVertex>(totalVertexCount);
+ uint16_t* indexBuffer =
+ shadowTriangleStrip.allocIndices<uint16_t>(totalIndexCount);
+
+ int indexBufferIndex = 0;
+ int vertexBufferIndex = 0;
+
+ uint16_t slicedUmbraVertexIndex[totalRayNum * sliceNumberPerEdge];
+ // Should be something like 0 0 0 1 1 1 2 3 3 3...
+ int rayNumberPerSlicedUmbra[totalRayNum * sliceNumberPerEdge];
+ int realUmbraVertexCount = 0;
+ for (int i = 0; i < totalRayNum; i++) {
+ Vector2 currentPenumbra = penumbraVertices[i];
+ Vector2 currentUmbra = umbraVertices[i];
+
+ Vector2 nextPenumbra = penumbraVertices[(i + 1) % totalRayNum];
+ Vector2 nextUmbra = umbraVertices[(i + 1) % totalRayNum];
+ // NextUmbra/Penumbra will be done in the next loop!!
+ for (int weight = 0; weight < sliceNumberPerEdge; weight++) {
+ const Vector2& slicedPenumbra = (currentPenumbra * (sliceNumberPerEdge - weight)
+ + nextPenumbra * weight) / sliceNumberPerEdge;
+
+ const Vector2& slicedUmbra = (currentUmbra * (sliceNumberPerEdge - weight)
+ + nextUmbra * weight) / sliceNumberPerEdge;
+
+ // In the vertex buffer, we fill the Penumbra first, then umbra.
+ indexBuffer[indexBufferIndex++] = vertexBufferIndex;
+ AlphaVertex::set(&shadowVertices[vertexBufferIndex++], slicedPenumbra.x,
+ slicedPenumbra.y, 0.0f);
+
+ // When we add umbra vertex, we need to remember its current ray number.
+ // And its own vertexBufferIndex. This is for occluded umbra usage.
+ indexBuffer[indexBufferIndex++] = vertexBufferIndex;
+ rayNumberPerSlicedUmbra[realUmbraVertexCount] = i;
+ slicedUmbraVertexIndex[realUmbraVertexCount] = vertexBufferIndex;
+ realUmbraVertexCount++;
+ AlphaVertex::set(&shadowVertices[vertexBufferIndex++], slicedUmbra.x,
+ slicedUmbra.y, M_PI);
+ }
+ }
+
+ indexBuffer[indexBufferIndex++] = 0;
+ //RealUmbraVertexIndex[0] must be 1, so we connect back well at the
+ //beginning of occluded area.
+ indexBuffer[indexBufferIndex++] = 1;
+
+ float occludedUmbraAlpha = M_PI;
+ if (hasOccludedUmbraArea) {
+ // Now the occludedUmbra area;
+ int currentRayNumber = -1;
+ int firstOccludedUmbraIndex = -1;
+ for (int i = 0; i < realUmbraVertexCount; i++) {
+ indexBuffer[indexBufferIndex++] = slicedUmbraVertexIndex[i];
+
+ // If the occludedUmbra vertex has not been added yet, then add it.
+ // Otherwise, just use the previously added occludedUmbra vertices.
+ if (rayNumberPerSlicedUmbra[i] != currentRayNumber) {
+ currentRayNumber++;
+ indexBuffer[indexBufferIndex++] = vertexBufferIndex;
+ // We need to remember the begining of the occludedUmbra vertices
+ // to close this loop.
+ if (currentRayNumber == 0) {
+ firstOccludedUmbraIndex = vertexBufferIndex;
+ }
+ AlphaVertex::set(&shadowVertices[vertexBufferIndex++],
+ occludedUmbraVertices[currentRayNumber].x,
+ occludedUmbraVertices[currentRayNumber].y,
+ occludedUmbraAlpha);
+ } else {
+ indexBuffer[indexBufferIndex++] = (vertexBufferIndex - 1);
+ }
+ }
+ // Close the loop here!
+ indexBuffer[indexBufferIndex++] = slicedUmbraVertexIndex[0];
+ indexBuffer[indexBufferIndex++] = firstOccludedUmbraIndex;
+ } else {
+ int lastCentroidIndex = vertexBufferIndex;
+ AlphaVertex::set(&shadowVertices[vertexBufferIndex++], centroid.x,
+ centroid.y, occludedUmbraAlpha);
+ for (int i = 0; i < realUmbraVertexCount; i++) {
+ indexBuffer[indexBufferIndex++] = slicedUmbraVertexIndex[i];
+ indexBuffer[indexBufferIndex++] = lastCentroidIndex;
+ }
+ // Close the loop here!
+ indexBuffer[indexBufferIndex++] = slicedUmbraVertexIndex[0];
+ indexBuffer[indexBufferIndex++] = lastCentroidIndex;
+ }
+
+#if DEBUG_SHADOW
+ ALOGD("allocated IB %d allocated VB is %d", totalIndexCount, totalVertexCount);
+ ALOGD("IB index %d VB index is %d", indexBufferIndex, vertexBufferIndex);
+ for (int i = 0; i < vertexBufferIndex; i++) {
+ ALOGD("vertexBuffer i %d, (%f, %f %f)", i, shadowVertices[i].x, shadowVertices[i].y,
+ shadowVertices[i].alpha);
+ }
+ for (int i = 0; i < indexBufferIndex; i++) {
+ ALOGD("indexBuffer i %d, indexBuffer[i] %d", i, indexBuffer[i]);
+ }
+#endif
+
+ // At the end, update the real index and vertex buffer size.
+ shadowTriangleStrip.updateVertexCount(vertexBufferIndex);
+ shadowTriangleStrip.updateIndexCount(indexBufferIndex);
+ ShadowTessellator::checkOverflow(vertexBufferIndex, totalVertexCount, "Spot Vertex Buffer");
+ ShadowTessellator::checkOverflow(indexBufferIndex, totalIndexCount, "Spot Index Buffer");
+
+ shadowTriangleStrip.setMode(VertexBuffer::kIndices);
+ shadowTriangleStrip.computeBounds<AlphaVertex>();
+}
+
#if DEBUG_SHADOW
#define TEST_POINT_NUMBER 128
-
/**
* Calculate the bounds for generating random test points.
*/
void SpotShadow::updateBound(const Vector2 inVector, Vector2& lowerBound,
- Vector2& upperBound ) {
+ Vector2& upperBound) {
if (inVector.x < lowerBound.x) {
lowerBound.x = inVector.x;
}
@@ -1127,14 +1633,14 @@
if (!testPointInsidePolygon(testPoint, poly1, poly1Length)) {
dumpPoly = true;
ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
- " not in the poly1",
+ " not in the poly1",
testPoint.x, testPoint.y);
}
if (!testPointInsidePolygon(testPoint, poly2, poly2Length)) {
dumpPoly = true;
ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
- " not in the poly2",
+ " not in the poly2",
testPoint.x, testPoint.y);
}
}
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
index 355be8d..23fdca9 100644
--- a/libs/hwui/SpotShadow.h
+++ b/libs/hwui/SpotShadow.h
@@ -26,22 +26,51 @@
class SpotShadow {
public:
- static void createSpotShadow_old(bool isCasterOpaque, const Vector3* poly,
- int polyLength, const Vector3& lightCenter, float lightSize,
- int lightVertexCount, VertexBuffer& retStrips);
static void createSpotShadow(bool isCasterOpaque, const Vector3& lightCenter,
float lightSize, const Vector3* poly, int polyLength,
const Vector3& polyCentroid, VertexBuffer& retstrips);
private:
+ struct VertexAngleData;
+
static float projectCasterToOutline(Vector2& outline,
const Vector3& lightCenter, const Vector3& polyVertex);
static int calculateOccludedUmbra(const Vector2* umbra, int umbraLength,
const Vector3* poly, int polyLength, Vector2* occludedUmbra);
- static void computeSpotShadow_old(bool isCasterOpaque, const Vector3* lightPoly,
- int lightPolyLength, const Vector3& lightCenter, const Vector3* poly,
- int polyLength, VertexBuffer& shadowTriangleStrip);
+ static int setupAngleList(VertexAngleData* angleDataList,
+ int polyLength, const Vector2* polygon, const Vector2& centroid,
+ bool isPenumbra, const char* name);
+
+ static int convertPolysToVerticesPerRay(
+ bool hasOccludedUmbraArea, const Vector2* poly2d, int polyLength,
+ const Vector2* umbra, int umbraLength, const Vector2* penumbra,
+ int penumbraLength, const Vector2& centroid,
+ Vector2* umbraVerticesPerRay, Vector2* penumbraVerticesPerRay,
+ Vector2* occludedUmbraVerticesPerRay);
+
+ static bool checkClockwise(int maxIndex, int listLength,
+ VertexAngleData* angleList, const char* name);
+
+ static void calculateDistanceCounter(bool needsOffsetToUmbra, int angleLength,
+ const VertexAngleData* allVerticesAngleData, int* distances);
+
+ static void mergeAngleList(int maxUmbraAngleIndex, int maxPenumbraAngleIndex,
+ const VertexAngleData* umbraAngleList, int umbraLength,
+ const VertexAngleData* penumbraAngleList, int penumbraLength,
+ VertexAngleData* allVerticesAngleData);
+
+ static int setupPolyAngleList(float* polyAngleList, int polyAngleLength,
+ const Vector2* poly2d, const Vector2& centroid);
+
+ static bool checkPolyClockwise(int polyAngleLength, int maxPolyAngleIndex,
+ const float* polyAngleList);
+
+ static int getEdgeStartIndex(const int* offsets, int rayIndex, int totalRayNumber,
+ const VertexAngleData* allVerticesAngleData);
+
+ static int getPolyEdgeStartIndex(int maxPolyAngleIndex, int polyLength,
+ const float* polyAngleList, float rayAngle);
static void computeLightPolygon(int points, const Vector3& lightCenter,
float size, Vector3* ret);
@@ -67,11 +96,10 @@
double x3, double y3, double x4, double y4, Vector2& ret);
static void generateTriangleStrip(bool isCasterOpaque, float shadowStrengthScale,
- const Vector2* penumbra, int penumbraLength, const Vector2* umbra, int umbraLength,
- const Vector3* poly, int polyLength, VertexBuffer& retstrips);
+ Vector2* penumbra, int penumbraLength, Vector2* umbra, int umbraLength,
+ const Vector3* poly, int polyLength, VertexBuffer& retstrips, const Vector2& centroid);
#if DEBUG_SHADOW
- // Verification utility function.
static bool testConvex(const Vector2* polygon, int polygonLength,
const char* name);
static void testIntersection(const Vector2* poly1, int poly1Length,
diff --git a/libs/hwui/TessellationCache.cpp b/libs/hwui/TessellationCache.cpp
index 9e62f36..1e38f9e 100644
--- a/libs/hwui/TessellationCache.cpp
+++ b/libs/hwui/TessellationCache.cpp
@@ -216,7 +216,7 @@
// tessellate caster outline into a 2d polygon
Vector<Vertex> casterVertices2d;
- const float casterRefinementThresholdSquared = 20.0f; // TODO: experiment with this value
+ const float casterRefinementThresholdSquared = 4.0f;
PathTessellator::approximatePathOutlineVertices(*casterPerimeter,
casterRefinementThresholdSquared, casterVertices2d);
if (!ShadowTessellator::isClockwisePath(*casterPerimeter)) {
diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h
index 966fa4e..8c3a272 100644
--- a/libs/hwui/VertexBuffer.h
+++ b/libs/hwui/VertexBuffer.h
@@ -133,7 +133,7 @@
mIndexCount = MathUtils::min(newCount, mAllocatedIndexCount);
}
void updateVertexCount(unsigned int newCount) {
- newCount = MathUtils::min(newCount, mAllocatedVertexCount);
+ mVertexCount = MathUtils::min(newCount, mAllocatedVertexCount);
}
Mode getMode() const { return mMode; }
diff --git a/media/java/android/media/AudioDevice.java b/media/java/android/media/AudioDevice.java
index e078354..df4d60d 100644
--- a/media/java/android/media/AudioDevice.java
+++ b/media/java/android/media/AudioDevice.java
@@ -20,90 +20,91 @@
/**
* Class to provide information about the audio devices.
+ * @hide
*/
public class AudioDevice {
/**
* A device type associated with an unknown or uninitialized device.
*/
- public static final int DEVICE_TYPE_UNKNOWN = 0;
+ public static final int TYPE_UNKNOWN = 0;
/**
* A device type describing the attached earphone speaker.
*/
- public static final int DEVICE_TYPE_BUILTIN_EARPIECE = 1;
+ public static final int TYPE_BUILTIN_EARPIECE = 1;
/**
* A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
* in a device.
*/
- public static final int DEVICE_TYPE_BUILTIN_SPEAKER = 2;
+ public static final int TYPE_BUILTIN_SPEAKER = 2;
/**
* A device type describing a headset, which is the combination of a headphones and microphone.
*/
- public static final int DEVICE_TYPE_WIRED_HEADSET = 3;
+ public static final int TYPE_WIRED_HEADSET = 3;
/**
* A device type describing a pair of wired headphones .
*/
- public static final int DEVICE_TYPE_WIRED_HEADPHONES = 4;
+ public static final int TYPE_WIRED_HEADPHONES = 4;
/**
* A device type describing an analog line-level connection.
*/
- public static final int DEVICE_TYPE_LINE_ANALOG = 5;
+ public static final int TYPE_LINE_ANALOG = 5;
/**
* A device type describing a digital line connection (e.g. SPDIF).
*/
- public static final int DEVICE_TYPE_LINE_DIGITAL = 6;
+ public static final int TYPE_LINE_DIGITAL = 6;
/**
* A device type describing a Bluetooth device typically used for telephony .
*/
- public static final int DEVICE_TYPE_BLUETOOTH_SCO = 7;
+ public static final int TYPE_BLUETOOTH_SCO = 7;
/**
* A device type describing a Bluetooth device supporting the A2DP profile.
*/
- public static final int DEVICE_TYPE_BLUETOOTH_A2DP = 8;
+ public static final int TYPE_BLUETOOTH_A2DP = 8;
/**
* A device type describing an HDMI connection .
*/
- public static final int DEVICE_TYPE_HDMI = 9;
+ public static final int TYPE_HDMI = 9;
/**
* A device type describing the Audio Return Channel of an HDMI connection.
*/
- public static final int DEVICE_TYPE_HDMI_ARC = 10;
+ public static final int TYPE_HDMI_ARC = 10;
/**
* A device type describing a USB audio device.
*/
- public static final int DEVICE_TYPE_USB_DEVICE = 11;
+ public static final int TYPE_USB_DEVICE = 11;
/**
* A device type describing a USB audio device in accessory mode.
*/
- public static final int DEVICE_TYPE_USB_ACCESSORY = 12;
+ public static final int TYPE_USB_ACCESSORY = 12;
/**
* A device type describing the audio device associated with a dock.
*/
- public static final int DEVICE_TYPE_DOCK = 13;
+ public static final int TYPE_DOCK = 13;
/**
* A device type associated with the transmission of audio signals over FM.
*/
- public static final int DEVICE_TYPE_FM = 14;
+ public static final int TYPE_FM = 14;
/**
* A device type describing the microphone(s) built in a device.
*/
- public static final int DEVICE_TYPE_BUILTIN_MIC = 15;
+ public static final int TYPE_BUILTIN_MIC = 15;
/**
* A device type for accessing the audio content transmitted over FM.
*/
- public static final int DEVICE_TYPE_FM_TUNER = 16;
+ public static final int TYPE_FM_TUNER = 16;
/**
* A device type for accessing the audio content transmitted over the TV tuner system.
*/
- public static final int DEVICE_TYPE_TV_TUNER = 17;
+ public static final int TYPE_TV_TUNER = 17;
/**
* A device type describing the transmission of audio signals over the telephony network.
*/
- public static final int DEVICE_TYPE_TELEPHONY = 18;
+ public static final int TYPE_TELEPHONY = 18;
/**
* A device type describing the auxiliary line-level connectors.
*/
- public static final int DEVICE_TYPE_AUX_LINE = 19;
+ public static final int TYPE_AUX_LINE = 19;
AudioDevicePortConfig mConfig;
@@ -135,7 +136,7 @@
* @return
*/
public int getDeviceType() {
- return INT_TO_EXT_DEVICE_MAPPING.get(mConfig.port().type(), DEVICE_TYPE_UNKNOWN);
+ return INT_TO_EXT_DEVICE_MAPPING.get(mConfig.port().type(), TYPE_UNKNOWN);
}
/**
@@ -154,7 +155,7 @@
/** @hide */
public static int convertInternalDeviceToDeviceType(int intDevice) {
- return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, DEVICE_TYPE_UNKNOWN);
+ return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, TYPE_UNKNOWN);
}
private static final SparseIntArray INT_TO_EXT_DEVICE_MAPPING;
@@ -163,43 +164,43 @@
static {
INT_TO_EXT_DEVICE_MAPPING = new SparseIntArray();
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, DEVICE_TYPE_BUILTIN_EARPIECE);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER, DEVICE_TYPE_BUILTIN_SPEAKER);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADSET, DEVICE_TYPE_WIRED_HEADSET);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, DEVICE_TYPE_WIRED_HEADPHONES);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, DEVICE_TYPE_BLUETOOTH_SCO);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET, DEVICE_TYPE_BLUETOOTH_SCO);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT, DEVICE_TYPE_BLUETOOTH_SCO);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, DEVICE_TYPE_BLUETOOTH_A2DP);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, DEVICE_TYPE_BLUETOOTH_A2DP);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, DEVICE_TYPE_BLUETOOTH_A2DP);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI, DEVICE_TYPE_HDMI);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, DEVICE_TYPE_DOCK);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, DEVICE_TYPE_DOCK);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_ACCESSORY, DEVICE_TYPE_USB_ACCESSORY);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_DEVICE, DEVICE_TYPE_USB_DEVICE);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_TELEPHONY_TX, DEVICE_TYPE_TELEPHONY);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_LINE, DEVICE_TYPE_LINE_ANALOG);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_ARC, DEVICE_TYPE_HDMI_ARC);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPDIF, DEVICE_TYPE_LINE_DIGITAL);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_FM, DEVICE_TYPE_FM);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, DEVICE_TYPE_AUX_LINE);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, TYPE_BUILTIN_EARPIECE);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER, TYPE_BUILTIN_SPEAKER);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADSET, TYPE_WIRED_HEADSET);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, TYPE_WIRED_HEADPHONES);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, TYPE_BLUETOOTH_SCO);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT, TYPE_BLUETOOTH_SCO);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, TYPE_BLUETOOTH_A2DP);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, TYPE_BLUETOOTH_A2DP);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI, TYPE_HDMI);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, TYPE_DOCK);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, TYPE_DOCK);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_ACCESSORY, TYPE_USB_ACCESSORY);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_DEVICE, TYPE_USB_DEVICE);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_TELEPHONY_TX, TYPE_TELEPHONY);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_LINE, TYPE_LINE_ANALOG);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_ARC, TYPE_HDMI_ARC);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPDIF, TYPE_LINE_DIGITAL);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_FM, TYPE_FM);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, TYPE_AUX_LINE);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, DEVICE_TYPE_BUILTIN_MIC);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, DEVICE_TYPE_BLUETOOTH_SCO);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_WIRED_HEADSET, DEVICE_TYPE_WIRED_HEADSET);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI, DEVICE_TYPE_HDMI);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TELEPHONY_RX, DEVICE_TYPE_TELEPHONY);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BACK_MIC, DEVICE_TYPE_BUILTIN_MIC);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, DEVICE_TYPE_DOCK);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET, DEVICE_TYPE_DOCK);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_ACCESSORY, DEVICE_TYPE_USB_ACCESSORY);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_DEVICE, DEVICE_TYPE_USB_DEVICE);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_FM_TUNER, DEVICE_TYPE_FM_TUNER);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TV_TUNER, DEVICE_TYPE_TV_TUNER);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_LINE, DEVICE_TYPE_LINE_ANALOG);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_SPDIF, DEVICE_TYPE_LINE_DIGITAL);
- INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, DEVICE_TYPE_BLUETOOTH_A2DP);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_WIRED_HEADSET, TYPE_WIRED_HEADSET);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI, TYPE_HDMI);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TELEPHONY_RX, TYPE_TELEPHONY);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BACK_MIC, TYPE_BUILTIN_MIC);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, TYPE_DOCK);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET, TYPE_DOCK);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_ACCESSORY, TYPE_USB_ACCESSORY);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_DEVICE, TYPE_USB_DEVICE);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_FM_TUNER, TYPE_FM_TUNER);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TV_TUNER, TYPE_TV_TUNER);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_LINE, TYPE_LINE_ANALOG);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_SPDIF, TYPE_LINE_DIGITAL);
+ INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
// not covered here, legacy
//AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
@@ -207,25 +208,25 @@
// privileges mapping to output device
EXT_TO_INT_DEVICE_MAPPING = new SparseIntArray();
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_BUILTIN_EARPIECE, AudioSystem.DEVICE_OUT_EARPIECE);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_BUILTIN_SPEAKER, AudioSystem.DEVICE_OUT_SPEAKER);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_WIRED_HEADSET, AudioSystem.DEVICE_OUT_WIRED_HEADSET);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_WIRED_HEADPHONES, AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_LINE_ANALOG, AudioSystem.DEVICE_OUT_LINE);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_LINE_DIGITAL, AudioSystem.DEVICE_OUT_SPDIF);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_OUT_BLUETOOTH_SCO);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_HDMI, AudioSystem.DEVICE_OUT_HDMI);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_ARC);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_DOCK, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_FM, AudioSystem.DEVICE_OUT_FM);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_TELEPHONY, AudioSystem.DEVICE_OUT_TELEPHONY_TX);
- EXT_TO_INT_DEVICE_MAPPING.put(DEVICE_TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_EARPIECE, AudioSystem.DEVICE_OUT_EARPIECE);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_SPEAKER, AudioSystem.DEVICE_OUT_SPEAKER);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADSET, AudioSystem.DEVICE_OUT_WIRED_HEADSET);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADPHONES, AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_OUT_LINE);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_OUT_SPDIF);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_OUT_BLUETOOTH_SCO);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_OUT_HDMI);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_ARC);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM, AudioSystem.DEVICE_OUT_FM);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_OUT_TELEPHONY_TX);
+ EXT_TO_INT_DEVICE_MAPPING.put(TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE);
}
}
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index d93d81b..58ed4f8 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -320,15 +320,26 @@
/**
* Builder class for {@link AudioFormat} objects.
+ * Use this class to configure and create an AudioFormat instance. By setting format
+ * characteristics such as audio encoding, channel mask or sample rate, you indicate which
+ * of those are to vary from the default behavior on this device wherever this audio format
+ * is used.
+ * <p>{@link AudioFormat} is for instance used in
+ * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}. In this
+ * constructor, every format characteristic set on the <code>Builder</code> (e.g. with
+ * {@link #setSampleRate(int)}) will alter the default values used by an
+ * <code>AudioTrack</code>. In this case for audio playback with <code>AudioTrack</code>, the
+ * sample rate set in the <code>Builder</code> would override the platform output sample rate
+ * which would otherwise be selected by default.
*/
public static class Builder {
- private int mEncoding = ENCODING_PCM_16BIT;
+ private int mEncoding = ENCODING_INVALID;
private int mSampleRate = 0;
private int mChannelMask = CHANNEL_INVALID;
private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE;
/**
- * Constructs a new Builder with the defaults format values.
+ * Constructs a new Builder with none of the format characteristics set.
*/
public Builder() {
}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 6da3c0b..559c247 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
import android.app.PendingIntent;
import android.bluetooth.BluetoothDevice;
import android.content.ComponentName;
@@ -3158,6 +3159,21 @@
}
/**
+ * Returns true if Hdmi Cec system audio mode is supported.
+ *
+ * @hide
+ */
+ @SystemApi
+ public boolean isHdmiSystemAudioSupported() {
+ try {
+ return getService().isHdmiSystemAudioSupported();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error querying system audio mode", e);
+ return false;
+ }
+ }
+
+ /**
* Return codes for listAudioPorts(), createAudioPatch() ...
*/
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index cd4f31e..91a8468 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -5105,6 +5105,11 @@
return device;
}
+ @Override
+ public boolean isHdmiSystemAudioSupported() {
+ return mHdmiSystemAudioSupported;
+ }
+
//==========================================================================================
// Camera shutter sound policy.
// config_camera_sound_forced configuration option in config.xml defines if the camera shutter
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 6477055..75fc03c 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -201,6 +201,8 @@
int setHdmiSystemAudioSupported(boolean on);
- boolean registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb);
+ boolean isHdmiSystemAudioSupported();
+
+ boolean registerAudioPolicy(in AudioPolicyConfig policyConfig, IBinder cb);
oneway void unregisterAudioPolicyAsync(in IBinder cb);
}
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 1c7c9ea..b4fef36 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -1756,7 +1756,7 @@
if (cropRect != null) {
cropRect.offset(-xOffset, -yOffset);
}
- setCropRect(cropRect);
+ super.setCropRect(cropRect);
// save offsets and info
mXOffset = xOffset;
diff --git a/media/java/android/media/audiofx/Virtualizer.java b/media/java/android/media/audiofx/Virtualizer.java
index b314c02..be5adc8 100644
--- a/media/java/android/media/audiofx/Virtualizer.java
+++ b/media/java/android/media/audiofx/Virtualizer.java
@@ -16,11 +16,14 @@
package android.media.audiofx;
+import android.annotation.IntDef;
import android.media.AudioDevice;
import android.media.AudioFormat;
import android.media.audiofx.AudioEffect;
import android.util.Log;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.StringTokenizer;
@@ -248,14 +251,114 @@
}
/**
- * Checks if the combination of a channel mask and device type is supported by this virtualizer.
+ * A virtualization mode indicating virtualization processing is not active.
+ * See {@link #getVirtualizationMode()} as one of the possible return value.
+ */
+ public static final int VIRTUALIZATION_MODE_OFF = 0;
+
+ /**
+ * A virtualization mode used to indicate the virtualizer effect must stop forcing the
+ * processing to a particular mode in {@link #forceVirtualizationMode(int)}.
+ */
+ public static final int VIRTUALIZATION_MODE_AUTO = 1;
+ /**
+ * A virtualization mode typically used over headphones.
+ * Binaural virtualization describes an audio processing configuration for virtualization
+ * where the left and right channels are respectively reaching the left and right ear of the
+ * user, without also feeding the opposite ear (as is the case when listening over speakers).
+ * <p>Such a mode is therefore meant to be used when audio is playing over stereo wired
+ * headphones or headsets, but also stereo headphones through a wireless A2DP Bluetooth link.
+ * <p>See {@link #canVirtualize(int, int)} to verify this mode is supported by this Virtualizer.
+ */
+ public final static int VIRTUALIZATION_MODE_BINAURAL = 2;
+
+ /**
+ * A virtualization mode typically used over speakers.
+ * Transaural virtualization describes an audio processing configuration that differs from
+ * binaural (as described in {@link #VIRTUALIZATION_MODE_BINAURAL} in that cross-talk is
+ * present, i.e. audio played from the left channel also reaches the right ear of the user,
+ * and vice-versa.
+ * <p>When supported, such a mode is therefore meant to be used when audio is playing over the
+ * built-in stereo speakers of a device, if they are featured.
+ * <p>See {@link #canVirtualize(int, int)} to verify this mode is supported by this Virtualizer.
+ */
+ public final static int VIRTUALIZATION_MODE_TRANSAURAL = 3;
+
+ /** @hide */
+ @IntDef( {
+ VIRTUALIZATION_MODE_BINAURAL,
+ VIRTUALIZATION_MODE_TRANSAURAL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface VirtualizationMode {}
+
+ /** @hide */
+ @IntDef( {
+ VIRTUALIZATION_MODE_AUTO,
+ VIRTUALIZATION_MODE_BINAURAL,
+ VIRTUALIZATION_MODE_TRANSAURAL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ForceVirtualizationMode {}
+
+ private static int getDeviceForModeQuery(@VirtualizationMode int virtualizationMode)
+ throws IllegalArgumentException {
+ switch (virtualizationMode) {
+ case VIRTUALIZATION_MODE_BINAURAL:
+ return AudioDevice.TYPE_WIRED_HEADPHONES;
+ case VIRTUALIZATION_MODE_TRANSAURAL:
+ return AudioDevice.TYPE_BUILTIN_SPEAKER;
+ default:
+ throw (new IllegalArgumentException(
+ "Virtualizer: illegal virtualization mode " + virtualizationMode));
+ }
+ }
+
+ private static int getDeviceForModeForce(@ForceVirtualizationMode int virtualizationMode)
+ throws IllegalArgumentException {
+ if (virtualizationMode == VIRTUALIZATION_MODE_AUTO) {
+ return AudioDevice.TYPE_UNKNOWN;
+ } else {
+ return getDeviceForModeQuery(virtualizationMode);
+ }
+ }
+
+ private static int deviceToMode(int deviceType) {
+ switch (deviceType) {
+ case AudioDevice.TYPE_WIRED_HEADSET:
+ case AudioDevice.TYPE_WIRED_HEADPHONES:
+ case AudioDevice.TYPE_BLUETOOTH_SCO:
+ case AudioDevice.TYPE_BUILTIN_EARPIECE:
+ return VIRTUALIZATION_MODE_BINAURAL;
+ case AudioDevice.TYPE_BUILTIN_SPEAKER:
+ case AudioDevice.TYPE_LINE_ANALOG:
+ case AudioDevice.TYPE_LINE_DIGITAL:
+ case AudioDevice.TYPE_BLUETOOTH_A2DP:
+ case AudioDevice.TYPE_HDMI:
+ case AudioDevice.TYPE_HDMI_ARC:
+ case AudioDevice.TYPE_USB_DEVICE:
+ case AudioDevice.TYPE_USB_ACCESSORY:
+ case AudioDevice.TYPE_DOCK:
+ case AudioDevice.TYPE_FM:
+ case AudioDevice.TYPE_AUX_LINE:
+ return VIRTUALIZATION_MODE_TRANSAURAL;
+ case AudioDevice.TYPE_UNKNOWN:
+ default:
+ return VIRTUALIZATION_MODE_OFF;
+ }
+ }
+
+ /**
+ * Checks if the combination of a channel mask and virtualization mode is supported by this
+ * virtualizer.
* Some virtualizer implementations may only support binaural processing (i.e. only support
- * headphone output), some may support transaural processing (i.e. for speaker output) for the
+ * headphone output, see {@link #VIRTUALIZATION_MODE_BINAURAL}), some may support transaural
+ * processing (i.e. for speaker output, see {@link #VIRTUALIZATION_MODE_TRANSAURAL}) for the
* built-in speakers. Use this method to query the virtualizer implementation capabilities.
* @param inputChannelMask the channel mask of the content to virtualize.
- * @param deviceType the device type for which virtualization processing is to be performed.
- * Valid values are the device types defined in {@link AudioDevice}.
- * @return true if the combination of channel mask and output device type is supported, false
+ * @param virtualizationMode the mode for which virtualization processing is to be performed,
+ * one of {@link #VIRTUALIZATION_MODE_BINAURAL}, {@link #VIRTUALIZATION_MODE_TRANSAURAL}.
+ * @return true if the combination of channel mask and virtualization mode is supported, false
* otherwise.
* <br>An indication that a certain channel mask is not supported doesn't necessarily mean
* you cannot play content with that channel mask, it more likely implies the content will
@@ -268,22 +371,22 @@
* @throws IllegalArgumentException
* @throws UnsupportedOperationException
*/
- public boolean canVirtualize(int inputChannelMask, int deviceType)
+ public boolean canVirtualize(int inputChannelMask, @VirtualizationMode int virtualizationMode)
throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
- return getAnglesInt(inputChannelMask, deviceType, null);
+ return getAnglesInt(inputChannelMask, getDeviceForModeQuery(virtualizationMode), null);
}
/**
* Queries the virtual speaker angles (azimuth and elevation) for a combination of a channel
- * mask and device type.
- * If the virtualization configuration (mask and device) is supported (see
+ * mask and virtualization mode.
+ * If the virtualization configuration (mask and mode) is supported (see
* {@link #canVirtualize(int, int)}, the array angles will contain upon return the
* definition of each virtual speaker and its azimuth and elevation angles relative to the
* listener.
* <br>Note that in some virtualizer implementations, the angles may be strength-dependent.
* @param inputChannelMask the channel mask of the content to virtualize.
- * @param deviceType the device type for which virtualization processing is to be performed.
- * Valid values are the device types defined in {@link AudioDevice}.
+ * @param virtualizationMode the mode for which virtualization processing is to be performed,
+ * one of {@link #VIRTUALIZATION_MODE_BINAURAL}, {@link #VIRTUALIZATION_MODE_TRANSAURAL}.
* @param angles a non-null array whose length is 3 times the number of channels in the channel
* mask.
* If the method indicates the configuration is supported, the array will contain upon return
@@ -297,37 +400,39 @@
* <li>the element at index <code>3*i+2</code> contains its corresponding elevation angle
* where +90 is directly above the listener, 0 is the horizontal plane, and -90 is
* directly below the listener.</li>
- * @return true if the combination of channel mask and output device type is supported, false
+ * @return true if the combination of channel mask and virtualization mode is supported, false
* otherwise.
* @throws IllegalStateException
* @throws IllegalArgumentException
* @throws UnsupportedOperationException
*/
- public boolean getSpeakerAngles(int inputChannelMask, int deviceType, int[] angles)
+ public boolean getSpeakerAngles(int inputChannelMask,
+ @VirtualizationMode int virtualizationMode, int[] angles)
throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
if (angles == null) {
throw (new IllegalArgumentException(
"Virtualizer: illegal null channel / angle array"));
}
- return getAnglesInt(inputChannelMask, deviceType, angles);
+ return getAnglesInt(inputChannelMask, getDeviceForModeQuery(virtualizationMode), angles);
}
/**
- * Forces the virtualizer effect to use the processing mode used for the given device type.
+ * Forces the virtualizer effect to use the given processing mode.
* The effect must be enabled for the forced mode to be applied.
- * @param deviceType one of the device types defined in {@link AudioDevice}.
- * Use {@link AudioDevice#DEVICE_TYPE_UNKNOWN} to return to the non-forced mode.
- * @return true if the processing mode for the device type is supported, and it is successfully
- * set, or forcing was successfully disabled with {@link AudioDevice#DEVICE_TYPE_UNKNOWN},
- * false otherwise.
+ * @param virtualizationMode one of {@link #VIRTUALIZATION_MODE_BINAURAL},
+ * {@link #VIRTUALIZATION_MODE_TRANSAURAL} to force a particular processing mode, or
+ * {@value #VIRTUALIZATION_MODE_AUTO} to stop forcing a mode.
+ * @return true if the processing mode is supported, and it is successfully set, or
+ * forcing was successfully disabled, false otherwise.
* @throws IllegalStateException
* @throws IllegalArgumentException
* @throws UnsupportedOperationException
*/
- public boolean forceVirtualizationMode(int deviceType)
+ public boolean forceVirtualizationMode(@ForceVirtualizationMode int virtualizationMode)
throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
// convert Java device type to internal representation
+ int deviceType = getDeviceForModeForce(virtualizationMode);
int internalDevice = AudioDevice.convertDeviceTypeToInternalDevice(deviceType);
int status = setParameter(PARAM_FORCE_VIRTUALIZATION_MODE, internalDevice);
@@ -335,8 +440,8 @@
if (status >= 0) {
return true;
} else if (status == AudioEffect.ERROR_BAD_VALUE) {
- // a BAD_VALUE return from setParameter indicates the mode can't be forced to that
- // of this device, don't throw an exception, just return false
+ // a BAD_VALUE return from setParameter indicates the mode can't be forced
+ // don't throw an exception, just return false
return false;
} else {
// something wrong may have happened
@@ -349,31 +454,25 @@
}
/**
- * Return the device type which reflects the virtualization mode being used, if any.
- * @return a device type (as defined in {@link AudioDevice}) which reflects the virtualization
- * mode being used.
- * If virtualization is not active, the device type will be
- * {@link AudioDevice#DEVICE_TYPE_UNKNOWN}. Virtualization may not be active either because
- * the effect is not enabled or because the current output device is not compatible with
- * this virtualization implementation.
- * <p>Note that the return value may differ from a device type successfully set with
- * {@link #forceVirtualizationMode(int)} as the implementation
- * may use a single mode for multiple devices. An example of this is with
- * {@link AudioDevice#DEVICE_TYPE_WIRED_HEADSET} that would typically be handled
- * like {@link AudioDevice#DEVICE_TYPE_WIRED_HEADPHONES} from a virtualization
- * standpoint.
+ * Return the virtualization mode being used, if any.
+ * @return the virtualization mode being used.
+ * If virtualization is not active, the virtualization mode will be
+ * {@link #VIRTUALIZATION_MODE_OFF}. Otherwise the value will be
+ * {@link #VIRTUALIZATION_MODE_BINAURAL} or {@link #VIRTUALIZATION_MODE_TRANSAURAL}.
+ * Virtualization may not be active either because the effect is not enabled or
+ * because the current output device is not compatible with this virtualization
+ * implementation.
* @throws IllegalStateException
- * @throws IllegalArgumentException
* @throws UnsupportedOperationException
*/
public int getVirtualizationMode()
- throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+ throws IllegalStateException, UnsupportedOperationException {
int[] value = new int[1];
int status = getParameter(PARAM_VIRTUALIZATION_MODE, value);
if (status >= 0) {
- return AudioDevice.convertInternalDeviceToDeviceType(value[0]);
+ return deviceToMode(AudioDevice.convertInternalDeviceToDeviceType(value[0]));
} else if (status == AudioEffect.ERROR_BAD_VALUE) {
- return AudioDevice.DEVICE_TYPE_UNKNOWN;
+ return VIRTUALIZATION_MODE_OFF;
} else {
// something wrong may have happened
checkStatus(status);
@@ -381,7 +480,7 @@
// unexpected virtualizer behavior
Log.e(TAG, "unexpected status code " + status
+ " after getParameter(PARAM_VIRTUALIZATION_MODE)");
- return AudioDevice.DEVICE_TYPE_UNKNOWN;
+ return VIRTUALIZATION_MODE_OFF;
}
/**
diff --git a/media/java/android/media/projection/IMediaProjection.aidl b/media/java/android/media/projection/IMediaProjection.aidl
index 3d25aa6..19fc052 100644
--- a/media/java/android/media/projection/IMediaProjection.aidl
+++ b/media/java/android/media/projection/IMediaProjection.aidl
@@ -26,6 +26,6 @@
boolean canProjectVideo();
boolean canProjectSecureVideo();
int applyVirtualDisplayFlags(int flags);
- void addCallback(IMediaProjectionCallback callback);
- void removeCallback(IMediaProjectionCallback callback);
+ void registerCallback(IMediaProjectionCallback callback);
+ void unregisterCallback(IMediaProjectionCallback callback);
}
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 3a74d93..e6dadf9 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -40,7 +40,7 @@
*
* <p>
* A screen capture session can be started through {@link
- * MediaProjectionManager#getScreenCaptureIntent}. This grants the ability to
+ * MediaProjectionManager#createScreenCaptureIntent}. This grants the ability to
* capture screen contents, but not system audio.
* </p>
*/
@@ -70,9 +70,9 @@
* @param handler The handler on which the callback should be invoked, or
* null if the callback should be invoked on the calling thread's looper.
*
- * @see #removeCallback
+ * @see #unregisterCallback
*/
- public void addCallback(Callback callback, Handler handler) {
+ public void registerCallback(Callback callback, Handler handler) {
if (callback == null) {
throw new IllegalArgumentException("callback should not be null");
}
@@ -83,9 +83,9 @@
*
* @param callback The callback to unregister.
*
- * @see #addCallback
+ * @see #registerCallback
*/
- public void removeCallback(Callback callback) {
+ public void unregisterCallback(Callback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback should not be null");
}
diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java
index 50d66c6..a1cfc35 100644
--- a/media/java/android/media/projection/MediaProjectionManager.java
+++ b/media/java/android/media/projection/MediaProjectionManager.java
@@ -75,7 +75,7 @@
* the user whether to allow screen capture. The result of this
* activity should be passed to getMediaProjection.
*/
- public Intent getScreenCaptureIntent() {
+ public Intent createScreenCaptureIntent() {
Intent i = new Intent();
i.setClassName("com.android.systemui",
"com.android.systemui.media.MediaProjectionPermissionActivity");
diff --git a/media/java/android/media/tv/ITvInputManagerCallback.aidl b/media/java/android/media/tv/ITvInputManagerCallback.aidl
index 50a7636..6792680 100644
--- a/media/java/android/media/tv/ITvInputManagerCallback.aidl
+++ b/media/java/android/media/tv/ITvInputManagerCallback.aidl
@@ -24,4 +24,5 @@
void onInputStateChanged(in String inputId, int state);
void onInputAdded(in String inputId);
void onInputRemoved(in String inputId);
+ void onInputUpdated(in String inputId);
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index d2deb66..78714d2 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -477,6 +477,18 @@
*/
public void onInputRemoved(String inputId) {
}
+
+ /**
+ * This is called when a TV input is updated. The update of TV input happens when it is
+ * reinstalled or the media on which the newer version of TV input exists is
+ * available/unavailable.
+ *
+ * @param inputId The id of the TV input.
+ * @hide
+ */
+ @SystemApi
+ public void onInputUpdated(String inputId) {
+ }
}
private static final class TvInputCallbackRecord {
@@ -518,6 +530,15 @@
}
});
}
+
+ public void postInputUpdated(final String inputId) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mCallback.onInputUpdated(inputId);
+ }
+ });
+ }
}
/**
@@ -707,9 +728,20 @@
}
}
}
+
+ @Override
+ public void onInputUpdated(String inputId) {
+ synchronized (mLock) {
+ for (TvInputCallbackRecord record : mCallbackRecords) {
+ record.postInputUpdated(inputId);
+ }
+ }
+ }
};
try {
- mService.registerCallback(mManagerCallback, mUserId);
+ if (mService != null) {
+ mService.registerCallback(mManagerCallback, mUserId);
+ }
} catch (RemoteException e) {
Log.e(TAG, "mService.registerCallback failed: " + e);
}
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 4171e6d..213e34c 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -312,7 +312,9 @@
// is newly assigned for every createSession request and compared with
// MySessionCreateCallback.this.
mSessionCallback = new MySessionCallback(inputId, channelUri, params);
- mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+ if (mTvInputManager != null) {
+ mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+ }
}
}
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index be37aa8..c9cefbd 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -705,11 +705,12 @@
}
static jobjectArray
-android_media_AudioEffect_native_queryEffects(JNIEnv *env, jclass clazz)
+android_media_AudioEffect_native_queryEffects(JNIEnv *env, jclass clazz __unused)
{
effect_descriptor_t desc;
char str[EFFECT_STRING_LEN_MAX];
- uint32_t numEffects = 0;
+ uint32_t totalEffectsCount = 0;
+ uint32_t returnedEffectsCount = 0;
uint32_t i = 0;
jstring jdescType;
jstring jdescUuid;
@@ -717,19 +718,20 @@
jstring jdescName;
jstring jdescImplementor;
jobject jdesc;
+ jobjectArray ret;
- if (AudioEffect::queryNumberEffects(&numEffects) != NO_ERROR) {
+ if (AudioEffect::queryNumberEffects(&totalEffectsCount) != NO_ERROR) {
return NULL;
}
- jobjectArray ret = env->NewObjectArray(numEffects, fields.clazzDesc, NULL);
- if (ret == NULL) {
- return ret;
+ jobjectArray temp = env->NewObjectArray(totalEffectsCount, fields.clazzDesc, NULL);
+ if (temp == NULL) {
+ return temp;
}
- ALOGV("queryEffects() numEffects: %d", numEffects);
+ ALOGV("queryEffects() totalEffectsCount: %d", totalEffectsCount);
- for (i = 0; i < numEffects; i++) {
+ for (i = 0; i < totalEffectsCount; i++) {
if (AudioEffect::queryEffect(i, &desc) != NO_ERROR) {
goto queryEffects_failure;
}
@@ -770,15 +772,26 @@
goto queryEffects_failure;
}
- env->SetObjectArrayElement(ret, i, jdesc);
+ env->SetObjectArrayElement(temp, returnedEffectsCount++, jdesc);
}
+ if (returnedEffectsCount == 0) {
+ goto queryEffects_failure;
+ }
+ ret = env->NewObjectArray(returnedEffectsCount, fields.clazzDesc, NULL);
+ if (ret == NULL) {
+ goto queryEffects_failure;
+ }
+ for (i = 0; i < returnedEffectsCount; i++) {
+ env->SetObjectArrayElement(ret, i, env->GetObjectArrayElement(temp, i));
+ }
+ env->DeleteLocalRef(temp);
return ret;
queryEffects_failure:
- if (ret != NULL) {
- env->DeleteLocalRef(ret);
+ if (temp != NULL) {
+ env->DeleteLocalRef(temp);
}
return NULL;
@@ -787,7 +800,8 @@
static jobjectArray
-android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz, jint audioSession)
+android_media_AudioEffect_native_queryPreProcessings(JNIEnv *env, jclass clazz __unused,
+ jint audioSession)
{
// kDefaultNumEffects is a "reasonable" value ensuring that only one query will be enough on
// most devices to get all active audio pre processing on a given session.
@@ -895,7 +909,7 @@
return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}
-jint JNI_OnLoad(JavaVM* vm, void* reserved)
+jint JNI_OnLoad(JavaVM* vm, void* reserved __unused)
{
JNIEnv* env = NULL;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index f81690a..d72db1d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -116,9 +116,6 @@
* Gather roots from storage providers belonging to given package name.
*/
public void updatePackageAsync(String packageName) {
- // Need at least first load, since we're going to be using previously
- // cached values for non-matching packages.
- waitForFirstLoad();
new UpdateTask(packageName).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@@ -183,6 +180,12 @@
protected Void doInBackground(Void... params) {
final long start = SystemClock.elapsedRealtime();
+ if (mFilterPackage != null) {
+ // Need at least first load, since we're going to be using
+ // previously cached values for non-matching packages.
+ waitForFirstLoad();
+ }
+
mTaskRoots.put(mRecentsRoot.authority, mRecentsRoot);
final ContentResolver resolver = mContext.getContentResolver();
diff --git a/packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png
deleted file mode 100644
index cfd5db3..0000000
--- a/packages/Keyguard/res/drawable-hdpi/kg_bouncer_bg_white.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png
deleted file mode 100644
index e3cb6db..0000000
--- a/packages/Keyguard/res/drawable-mdpi/kg_bouncer_bg_white.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png b/packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
deleted file mode 100644
index b9e30e2..0000000
--- a/packages/Keyguard/res/drawable-xhdpi/kg_bouncer_bg_white.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
index 8c8ec7a..0c85dab 100644
--- a/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_face_unlock_view.xml
@@ -36,7 +36,6 @@
<FrameLayout
android:id="@+id/keyguard_bouncer_frame"
- android:background="@drawable/kg_bouncer_bg_white"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
diff --git a/packages/Keyguard/res/layout/keyguard_password_view.xml b/packages/Keyguard/res/layout/keyguard_password_view.xml
index 9e886f2..b7d5d30 100644
--- a/packages/Keyguard/res/layout/keyguard_password_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_password_view.xml
@@ -42,7 +42,6 @@
<!-- Password entry field -->
<FrameLayout
android:id="@+id/keyguard_bouncer_frame"
- android:background="@drawable/kg_bouncer_bg_white"
android:layout_height="wrap_content"
android:layout_width="280dp"
android:layout_gravity="center_horizontal"
diff --git a/packages/Keyguard/res/layout/keyguard_pattern_view.xml b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
index a126465..bd585b5 100644
--- a/packages/Keyguard/res/layout/keyguard_pattern_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
@@ -49,7 +49,6 @@
<FrameLayout
android:id="@+id/keyguard_bouncer_frame"
- android:background="@drawable/kg_bouncer_bg_white"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
diff --git a/packages/Keyguard/res/layout/keyguard_selector_view.xml b/packages/Keyguard/res/layout/keyguard_selector_view.xml
index d3064ed..5330363 100644
--- a/packages/Keyguard/res/layout/keyguard_selector_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_selector_view.xml
@@ -48,8 +48,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
- android:layout_marginRight="16dp"
- android:background="@drawable/kg_bouncer_bg_white"/>
+ android:layout_marginRight="16dp"/>
<include layout="@layout/keyguard_glow_pad_container" />
diff --git a/packages/PrintSpooler/res/layout/preview_page.xml b/packages/PrintSpooler/res/layout/preview_page.xml
index df9848b..edce289 100644
--- a/packages/PrintSpooler/res/layout/preview_page.xml
+++ b/packages/PrintSpooler/res/layout/preview_page.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.printspooler.widget.PreviewPageFrame xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/preview_page"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -33,7 +33,8 @@
android:layout_width="fill_parent"
android:layout_height="@dimen/preview_page_footer_height"
android:background="@color/material_grey_500"
- android:orientation="horizontal">
+ android:orientation="horizontal"
+ android:duplicateParentState="true">
<TextView
android:id="@+id/page_number"
@@ -51,9 +52,10 @@
android:layout_marginRight="8dip"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
- android:background="@drawable/page_selector_background">
+ android:background="@drawable/page_selector_background"
+ android:duplicateParentState="true">
</ImageView>
</RelativeLayout>
-</LinearLayout>
+</com.android.printspooler.widget.PreviewPageFrame>
diff --git a/packages/PrintSpooler/res/layout/print_activity.xml b/packages/PrintSpooler/res/layout/print_activity.xml
index 30b96292..6b8aa47 100644
--- a/packages/PrintSpooler/res/layout/print_activity.xml
+++ b/packages/PrintSpooler/res/layout/print_activity.xml
@@ -98,7 +98,7 @@
android:id="@+id/print_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="16dip"
+ android:layout_marginStart="16dip"
android:elevation="@dimen/preview_controls_elevation"
android:background="@drawable/print_button">
</ImageButton>
diff --git a/packages/PrintSpooler/res/layout/print_activity_controls.xml b/packages/PrintSpooler/res/layout/print_activity_controls.xml
index c2a0da9..f0b8adf 100644
--- a/packages/PrintSpooler/res/layout/print_activity_controls.xml
+++ b/packages/PrintSpooler/res/layout/print_activity_controls.xml
@@ -55,7 +55,7 @@
android:text="@string/label_copies">
</TextView>
- <EditText
+ <com.android.printspooler.widget.CustomErrorEditText
android:id="@+id/copies_edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
@@ -63,7 +63,7 @@
android:singleLine="true"
android:ellipsize="end"
android:inputType="numberDecimal">
- </EditText>
+ </com.android.printspooler.widget.CustomErrorEditText>
</LinearLayout>
@@ -197,7 +197,7 @@
android:visibility="visible">
</TextView>
- <EditText
+ <com.android.printspooler.widget.CustomErrorEditText
android:id="@+id/page_range_edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
@@ -206,7 +206,7 @@
android:ellipsize="end"
android:visibility="visible"
android:inputType="textNoSuggestions">
- </EditText>
+ </com.android.printspooler.widget.CustomErrorEditText>
</LinearLayout>
diff --git a/packages/PrintSpooler/res/values/strings.xml b/packages/PrintSpooler/res/values/strings.xml
index 27e1d51..ab633ea 100644
--- a/packages/PrintSpooler/res/values/strings.xml
+++ b/packages/PrintSpooler/res/values/strings.xml
@@ -76,10 +76,36 @@
<!-- Title for the print dialog announced to the user for accessibility. Not shown in the UI. [CHAR LIMIT=none] -->
<string name="print_dialog">Print dialog</string>
- <!-- Template for the message that shows the current page out of the total number of pages -->
+ <!-- Template for the message that shows the current page out of the total number of pages [CHAR LIMIT=none] -->
<string name="current_page_template"><xliff:g id="current_page">%1$d</xliff:g>
/<xliff:g id="page_count">%2$d</xliff:g></string>
+ <!-- Description of the current page - spoken to the user [CHAR LIMIT=none] -->
+ <string name="page_description_template">Page <xliff:g id="current_page" example="1">%1$d</xliff:g>
+ of <xliff:g id="page_count" example="100">%2$d</xliff:g></string>
+
+ <!-- Template for the message to announce the print options summary - spoken to the user. [CHAR LIMIT=none] -->
+ <string name="summary_template">Summary, copies <xliff:g id="copies" example="1">%1$s</xliff:g>,
+ paper size <xliff:g id="paper_size" example="A4">%2$s</xliff:g></string>
+
+ <!-- Description for the handle to expand all print options - spoken to the user. [CHAR LIMIT=none] -->
+ <string name="expand_handle">Expand handle</string>
+
+ <!-- Description for the handle to collapse all print options - spoken to the user. [CHAR LIMIT=none] -->
+ <string name="collapse_handle">Collapse handle</string>
+
+ <!-- Description for the print button - spoken to the user. [CHAR LIMIT=none] -->
+ <string name="print_button">Print</string>
+
+ <!-- Description for the save to PDF button - spoken to the user. [CHAR LIMIT=none] -->
+ <string name="savetopdf_button">Save to PDF</string>
+
+ <!-- Message to announce print options are expanded - spoken to the user. [CHAR LIMIT=none] -->
+ <string name="print_options_expanded">Print options expanded</string>
+
+ <!-- Message to announce print options are collapsed - spoken to the user. [CHAR LIMIT=none] -->
+ <string name="print_options_collapsed">Print options collapsed</string>
+
<!-- Select printer activity -->
<!-- Title for the share action bar menu item. [CHAR LIMIT=20] -->
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
index 06723c3..8537d6c 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerProvider.java
@@ -20,7 +20,9 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.os.Debug;
import android.os.IBinder;
+import android.util.Log;
public class PrintSpoolerProvider implements ServiceConnection {
private final Context mContext;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index 1e7a011..239f006 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -74,7 +74,7 @@
private final Looper mLooper;
private final IPrintDocumentAdapter mPrintDocumentAdapter;
- private final DocumentObserver mDocumentObserver;
+ private final RemoteAdapterDeathObserver mAdapterDeathObserver;
private final UpdateResultCallbacks mUpdateCallbacks;
@@ -135,7 +135,7 @@
private final DeathRecipient mDeathRecipient = new DeathRecipient() {
@Override
public void binderDied() {
- finish();
+ mAdapterDeathObserver.onDied();
}
};
@@ -144,8 +144,8 @@
private AsyncCommand mCurrentCommand;
private AsyncCommand mNextCommand;
- public interface DocumentObserver {
- public void onDestroy();
+ public interface RemoteAdapterDeathObserver {
+ public void onDied();
}
public interface UpdateResultCallbacks {
@@ -155,12 +155,12 @@
}
public RemotePrintDocument(Context context, IPrintDocumentAdapter adapter,
- MutexFileProvider fileProvider, DocumentObserver destroyListener,
+ MutexFileProvider fileProvider, RemoteAdapterDeathObserver deathObserver,
UpdateResultCallbacks callbacks) {
mPrintDocumentAdapter = adapter;
mLooper = context.getMainLooper();
mContext = context;
- mDocumentObserver = destroyListener;
+ mAdapterDeathObserver = deathObserver;
mDocumentInfo = new RemotePrintDocumentInfo();
mDocumentInfo.fileProvider = fileProvider;
mUpdateCallbacks = callbacks;
@@ -180,7 +180,7 @@
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error calling start()", re);
mState = STATE_FAILED;
- mDocumentObserver.onDestroy();
+ mAdapterDeathObserver.onDied();
}
}
@@ -269,7 +269,7 @@
} catch (RemoteException re) {
Log.e(LOG_TAG, "Error calling finish()", re);
mState = STATE_FAILED;
- mDocumentObserver.onDestroy();
+ mAdapterDeathObserver.onDied();
}
}
@@ -302,7 +302,6 @@
mState = STATE_DESTROYED;
disconnectFromRemoteDocument();
- mDocumentObserver.onDestroy();
}
public boolean isUpdating() {
@@ -1124,7 +1123,7 @@
new Handler(document.mLooper).post(new Runnable() {
@Override
public void run() {
- document.mDocumentObserver.onDestroy();
+ document.mAdapterDeathObserver.onDied();
}
});
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
index ce0b9b6..22a74d6 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java
@@ -41,6 +41,7 @@
import com.android.printspooler.model.PageContentRepository.PageContentProvider;
import com.android.printspooler.util.PageRangeUtils;
import com.android.printspooler.widget.PageContentView;
+import com.android.printspooler.widget.PreviewPageFrame;
import dalvik.system.CloseGuard;
import java.util.ArrayList;
@@ -94,12 +95,6 @@
private int mDocumentPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
private int mSelectedPageCount;
- private float mSelectedPageElevation;
- private float mSelectedPageAlpha;
-
- private float mUnselectedPageElevation;
- private float mUnselectedPageAlpha;
-
private int mPreviewPageMargin;
private int mPreviewPageMinWidth;
private int mPreviewListPadding;
@@ -134,16 +129,6 @@
Context.LAYOUT_INFLATER_SERVICE);
mPageContentRepository = new PageContentRepository(context, this);
- mSelectedPageElevation = mContext.getResources().getDimension(
- R.dimen.selected_page_elevation);
- mSelectedPageAlpha = mContext.getResources().getFraction(
- R.fraction.page_selected_alpha, 1, 1);
-
- mUnselectedPageElevation = mContext.getResources().getDimension(
- R.dimen.unselected_page_elevation);
- mUnselectedPageAlpha = mContext.getResources().getFraction(
- R.fraction.page_unselected_alpha, 1, 1);
-
mPreviewPageMargin = mContext.getResources().getDimensionPixelSize(
R.dimen.preview_page_margin);
@@ -296,7 +281,7 @@
MyViewHolder myHolder = (MyViewHolder) holder;
- View page = holder.itemView;
+ PreviewPageFrame page = (PreviewPageFrame) holder.itemView;
page.setOnClickListener(mPageClickListener);
page.setTag(holder);
@@ -340,20 +325,15 @@
}
content.init(provider, mEmptyState, mMediaSize, mMinMargins);
- View pageSelector = page.findViewById(R.id.page_selector);
- pageSelector.setTag(myHolder);
- pageSelector.setOnClickListener(mPageClickListener);
-
if (mConfirmedPagesInDocument.indexOfKey(pageInDocument) >= 0) {
- pageSelector.setSelected(true);
- page.setTranslationZ(mSelectedPageElevation);
- page.setAlpha(mSelectedPageAlpha);
+ page.setSelected(true, false);
} else {
- pageSelector.setSelected(false);
- page.setTranslationZ(mUnselectedPageElevation);
- page.setAlpha(mUnselectedPageAlpha);
+ page.setSelected(false, false);
}
+ page.setContentDescription(mContext.getString(R.string.page_description_template,
+ pageInDocument + 1, mDocumentPageCount));
+
TextView pageNumberView = (TextView) page.findViewById(R.id.page_number);
String text = mContext.getString(R.string.current_page_template,
pageInDocument + 1, mDocumentPageCount);
@@ -442,7 +422,8 @@
* mPreviewPageMargin);
final int verticalPadding;
- if (mPageContentHeight + mFooterHeight + mPreviewListPadding > availableHeight) {
+ if (mPageContentHeight + mFooterHeight + mPreviewListPadding
+ + 2 * mPreviewPageMargin > availableHeight) {
verticalPadding = Math.max(0,
(availableHeight - mPageContentHeight - mFooterHeight) / 2
- mPreviewPageMargin);
@@ -792,24 +773,20 @@
private final class PageClickListener implements OnClickListener {
@Override
- public void onClick(View page) {
+ public void onClick(View view) {
+ PreviewPageFrame page = (PreviewPageFrame) view;
MyViewHolder holder = (MyViewHolder) page.getTag();
final int pageInAdapter = holder.mPageInAdapter;
final int pageInDocument = computePageIndexInDocument(pageInAdapter);
- View pageSelector = page.findViewById(R.id.page_selector);
if (mConfirmedPagesInDocument.indexOfKey(pageInDocument) < 0) {
mConfirmedPagesInDocument.put(pageInDocument, null);
- pageSelector.setSelected(true);
- page.animate().translationZ(mSelectedPageElevation)
- .alpha(mSelectedPageAlpha);
+ page.setSelected(true, true);
} else {
if (mConfirmedPagesInDocument.size() <= 1) {
return;
}
mConfirmedPagesInDocument.remove(pageInDocument);
- pageSelector.setSelected(false);
- page.animate().translationZ(mUnselectedPageElevation)
- .alpha(mUnselectedPageAlpha);
+ page.setSelected(false, true);
}
}
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index c517f2d..dc2d5b1 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -61,6 +61,7 @@
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
@@ -191,6 +192,7 @@
private PrintContentView mOptionsContent;
+ private View mSummaryContainer;
private TextView mSummaryCopies;
private TextView mSummaryPaperSize;
@@ -219,8 +221,6 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setState(STATE_CONFIGURING);
-
Bundle extras = getIntent().getExtras();
mPrintJob = extras.getParcelable(PrintManager.EXTRA_PRINT_JOB);
@@ -284,11 +284,14 @@
mFileProvider);
mPrintedDocument = new RemotePrintDocument(PrintActivity.this,
IPrintDocumentAdapter.Stub.asInterface(documentAdapter),
- mFileProvider, new RemotePrintDocument.DocumentObserver() {
+ mFileProvider, new RemotePrintDocument.RemoteAdapterDeathObserver() {
@Override
- public void onDestroy() {
+ public void onDied() {
+ if (isFinishing()) {
+ return;
+ }
setState(STATE_PRINT_CANCELED);
- finish();
+ doFinish();
}
}, PrintActivity.this);
mProgressMessageController = new ProgressMessageController(
@@ -311,13 +314,17 @@
@Override
public void onPause() {
+ PrintSpoolerService spooler = mSpoolerProvider.getSpooler();
+
if (mState == STATE_INITIALIZING) {
+ if (isFinishing()) {
+ spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, null);
+ }
super.onPause();
return;
}
if (isFinishing()) {
- PrintSpoolerService spooler = mSpoolerProvider.getSpooler();
spooler.updatePrintJobUserConfigurableOptionsNoPersistence(mPrintJob);
switch (mState) {
@@ -338,13 +345,6 @@
spooler.setPrintJobState(mPrintJob.getId(), PrintJobInfo.STATE_CANCELED, null);
} break;
}
-
- mProgressMessageController.cancel();
- mPrinterRegistry.setTrackedPrinter(null);
- mPrintPreviewController.destroy();
- mSpoolerProvider.destroy();
- mPrintedDocument.finish();
- mPrintedDocument.destroy();
}
mPrinterAvailabilityDetector.cancel();
@@ -364,7 +364,13 @@
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (mState == STATE_INITIALIZING) {
- return super.onKeyUp(keyCode, event);
+ doFinish();
+ return true;
+ }
+
+ if (mState == STATE_PRINT_CANCELED ||mState == STATE_PRINT_CONFIRMED
+ || mState == STATE_PRINT_COMPLETED) {
+ return true;
}
if (keyCode == KeyEvent.KEYCODE_BACK
@@ -421,7 +427,7 @@
} break;
case STATE_PRINT_CANCELED: {
- finish();
+ doFinish();
} break;
}
}
@@ -458,7 +464,7 @@
} break;
case STATE_PRINT_CANCELED: {
- finish();
+ doFinish();
} break;
default: {
@@ -591,7 +597,7 @@
mDestinationSpinner.post(new Runnable() {
@Override
public void run() {
- finish();
+ doFinish();
}
});
}
@@ -953,7 +959,7 @@
if (mPrintedDocument.isUpdating()) {
mPrintedDocument.cancel();
}
- finish();
+ doFinish();
}
private void confirmPrint() {
@@ -983,6 +989,7 @@
private void bindUi() {
// Summary
+ mSummaryContainer = findViewById(R.id.summary_content);
mSummaryCopies = (TextView) findViewById(R.id.copies_count_summary);
mSummaryPaperSize = (TextView) findViewById(R.id.paper_size_summary);
@@ -1081,15 +1088,7 @@
void updateOptionsUi() {
// Always update the summary.
- if (!TextUtils.isEmpty(mCopiesEditText.getText())) {
- mSummaryCopies.setText(mCopiesEditText.getText());
- }
-
- final int selectedMediaIndex = mMediaSizeSpinner.getSelectedItemPosition();
- if (selectedMediaIndex >= 0) {
- SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(selectedMediaIndex);
- mSummaryPaperSize.setText(mediaItem.label);
- }
+ updateSummary();
if (mState == STATE_PRINT_CONFIRMED
|| mState == STATE_PRINT_COMPLETED
@@ -1330,8 +1329,10 @@
// Print
if (mDestinationSpinnerAdapter.getPdfPrinter() != mCurrentPrinter) {
mPrintButton.setImageResource(com.android.internal.R.drawable.ic_print);
+ mPrintButton.setContentDescription(getString(R.string.print_button));
} else {
mPrintButton.setImageResource(R.drawable.ic_menu_savetopdf);
+ mPrintButton.setContentDescription(getString(R.string.savetopdf_button));
}
if ((mRangeOptionsSpinner.getSelectedItemPosition() == 1
&& (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
@@ -1357,6 +1358,28 @@
}
}
+ private void updateSummary() {
+ CharSequence copiesText = null;
+ CharSequence mediaSizeText = null;
+
+ if (!TextUtils.isEmpty(mCopiesEditText.getText())) {
+ copiesText = mCopiesEditText.getText();
+ mSummaryCopies.setText(copiesText);
+ }
+
+ final int selectedMediaIndex = mMediaSizeSpinner.getSelectedItemPosition();
+ if (selectedMediaIndex >= 0) {
+ SpinnerItem<MediaSize> mediaItem = mMediaSizeSpinnerAdapter.getItem(selectedMediaIndex);
+ mediaSizeText = mediaItem.label;
+ mSummaryPaperSize.setText(mediaSizeText);
+ }
+
+ if (!TextUtils.isEmpty(copiesText) && !TextUtils.isEmpty(mediaSizeText)) {
+ String summaryText = getString(R.string.summary_template, copiesText, mediaSizeText);
+ mSummaryContainer.setContentDescription(summaryText);
+ }
+ }
+
private void updatePageRangeOptions(int pageCount) {
ArrayAdapter<SpinnerItem<Integer>> rangeOptionsSpinnerAdapter =
(ArrayAdapter) mRangeOptionsSpinner.getAdapter();
@@ -1513,11 +1536,23 @@
if (writeToUri != null) {
mPrintedDocument.writeContent(getContentResolver(), writeToUri);
}
- finish();
+ doFinish();
}
}).shred();
}
+ private void doFinish() {
+ if (mState != STATE_INITIALIZING) {
+ mProgressMessageController.cancel();
+ mPrinterRegistry.setTrackedPrinter(null);
+ mPrintPreviewController.destroy();
+ mSpoolerProvider.destroy();
+ mPrintedDocument.finish();
+ mPrintedDocument.destroy();
+ }
+ finish();
+ }
+
private final class SpinnerItem<T> {
final T value;
final CharSequence label;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
index a3d7f01..7f48217 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrinterRegistry.java
@@ -26,6 +26,7 @@
import android.print.PrinterId;
import android.print.PrinterInfo;
import com.android.internal.os.SomeArgs;
+import com.android.printspooler.model.PrintSpoolerService;
import java.util.ArrayList;
import java.util.List;
@@ -68,23 +69,40 @@
}
public void addHistoricalPrinter(PrinterInfo printer) {
- getPrinterProvider().addHistoricalPrinter(printer);
+ FusedPrintersProvider provider = getPrinterProvider();
+ if (provider != null) {
+ getPrinterProvider().addHistoricalPrinter(printer);
+ }
}
public void forgetFavoritePrinter(PrinterId printerId) {
- getPrinterProvider().forgetFavoritePrinter(printerId);
+ FusedPrintersProvider provider = getPrinterProvider();
+ if (provider != null) {
+ provider.forgetFavoritePrinter(printerId);
+ }
}
public boolean isFavoritePrinter(PrinterId printerId) {
- return getPrinterProvider().isFavoritePrinter(printerId);
+ FusedPrintersProvider provider = getPrinterProvider();
+ if (provider != null) {
+ return provider.isFavoritePrinter(printerId);
+ }
+ return false;
}
public void setTrackedPrinter(PrinterId printerId) {
- getPrinterProvider().setTrackedPrinter(printerId);
+ FusedPrintersProvider provider = getPrinterProvider();
+ if (provider != null) {
+ provider.setTrackedPrinter(printerId);
+ }
}
public boolean areHistoricalPrintersLoaded() {
- return getPrinterProvider().areHistoricalPrintersLoaded();
+ FusedPrintersProvider provider = getPrinterProvider();
+ if (provider != null) {
+ return getPrinterProvider().areHistoricalPrintersLoaded();
+ }
+ return false;
}
private FusedPrintersProvider getPrinterProvider() {
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java b/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java
new file mode 100644
index 0000000..b2aa008
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/CustomErrorEditText.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 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.printspooler.widget;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.EditText;
+
+/**
+ * EditText that shows an error without a popup.
+ */
+public final class CustomErrorEditText extends EditText {
+ private CharSequence mError;
+
+ public CustomErrorEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public CharSequence getError() {
+ return mError;
+ }
+
+ @Override
+ public void setError(CharSequence error, Drawable icon) {
+ setCompoundDrawables(null, null, icon, null);
+ mError = error;
+ }
+}
\ No newline at end of file
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
index e2ae758..c22c0e2 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
@@ -35,6 +35,7 @@
*/
public class PageContentView extends View
implements PageContentRepository.OnPageContentAvailableCallback {
+
private PageContentProvider mProvider;
private MediaSize mMediaSize;
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PreviewPageFrame.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PreviewPageFrame.java
new file mode 100644
index 0000000..feb0316
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PreviewPageFrame.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2014 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.printspooler.widget;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.CompoundButton;
+import android.widget.LinearLayout;
+import com.android.printspooler.R;
+
+/**
+ * This class represents the frame of page in the print preview list
+ * that contains the page and a footer.
+ */
+public final class PreviewPageFrame extends LinearLayout {
+ private final float mSelectedElevation;
+ private final float mNotSelectedElevation;
+
+ private final float mSelectedPageAlpha;
+ private final float mNotSelectedAlpha;
+
+ public PreviewPageFrame(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mSelectedElevation = mContext.getResources().getDimension(
+ R.dimen.selected_page_elevation);
+ mNotSelectedElevation = mContext.getResources().getDimension(
+ R.dimen.unselected_page_elevation);
+ mSelectedPageAlpha = mContext.getResources().getFraction(
+ R.fraction.page_selected_alpha, 1, 1);
+ mNotSelectedAlpha = mContext.getResources().getFraction(
+ R.fraction.page_unselected_alpha, 1, 1);
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+ event.setClassName(CompoundButton.class.getName());
+ event.setChecked(isSelected());
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setClassName(CompoundButton.class.getName());
+ info.setSelected(false);
+ info.setCheckable(true);
+ info.setChecked(isSelected());
+ }
+
+ public void setSelected(boolean selected, boolean animate) {
+ if (isSelected() == selected) {
+ return;
+ }
+ setSelected(selected);
+ if (selected) {
+ if (animate) {
+ animate().translationZ(mSelectedElevation)
+ .alpha(mSelectedPageAlpha);
+ } else {
+ setTranslationZ(mSelectedElevation);
+ setAlpha(mSelectedPageAlpha);
+ }
+ } else {
+ if (animate) {
+ animate().translationZ(mNotSelectedElevation)
+ .alpha(mNotSelectedAlpha);
+ } else {
+ setTranslationZ(mNotSelectedElevation);
+ setAlpha(mNotSelectedAlpha);
+ }
+ }
+ }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java
index c84b06a..bfcd334 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintContentView.java
@@ -283,8 +283,13 @@
mDynamicContent.layout(left, dynContentTop, right, dynContentBottom);
MarginLayoutParams params = (MarginLayoutParams) mPrintButton.getLayoutParams();
- final int rightMargin = params.rightMargin;
- final int printButtonLeft = right - mPrintButton.getMeasuredWidth() - rightMargin;
+
+ final int printButtonLeft;
+ if (getLayoutDirection() == View.LAYOUT_DIRECTION_LTR) {
+ printButtonLeft = right - mPrintButton.getMeasuredWidth() - params.getMarginStart();
+ } else {
+ printButtonLeft = left + params.getMarginStart();
+ }
final int printButtonTop = dynContentBottom - mPrintButton.getMeasuredHeight() / 2;
final int printButtonRight = printButtonLeft + mPrintButton.getMeasuredWidth();
final int printButtonBottom = printButtonTop + mPrintButton.getMeasuredHeight();
@@ -336,6 +341,9 @@
if (mOptionsStateChangeListener != null) {
mOptionsStateChangeListener.onOptionsOpened();
}
+ mExpandCollapseHandle.setContentDescription(
+ mContext.getString(R.string.collapse_handle));
+ announceForAccessibility(mContext.getString(R.string.print_options_expanded));
mSummaryContent.setVisibility(View.GONE);
mEmbeddedContentScrim.setOnClickListener(this);
mExpandCollapseIcon.setBackgroundResource(R.drawable.ic_expand_less);
@@ -347,6 +355,9 @@
if (mOptionsStateChangeListener != null) {
mOptionsStateChangeListener.onOptionsClosed();
}
+ mExpandCollapseHandle.setContentDescription(
+ mContext.getString(R.string.expand_handle));
+ announceForAccessibility(mContext.getString(R.string.print_options_collapsed));
if (mMoreOptionsButton.getVisibility() != View.GONE) {
mMoreOptionsButton.setVisibility(View.INVISIBLE);
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java
index 71f4aa7..7a80a8b 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PrintOptionsLayout.java
@@ -89,7 +89,7 @@
columnWidth - childParams.getMarginStart() - childParams.getMarginEnd(),
MeasureSpec.EXACTLY);
} else {
- childWidthMeasureSpec = getChildMeasureSpec(heightMeasureSpec,
+ childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec,
getPaddingStart() + getPaddingEnd() + width, childParams.width);
}
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 215d0f1..a3a3f03 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ligging deur GPS gestel"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Liggingversoeke aktief"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Instellings"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Die skerm sal outomaties draai."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skerm is in landskapsoriëntasie gesluit."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skerm is in portretoriëntasie gesluit."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Alles"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laai tans (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tot vol)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Wissel gebruiker"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Wissel gebruiker, huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Wys profiel"</string>
<string name="user_add_user" msgid="5110251524486079492">"Voeg gebruiker by"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nuwe gebruiker"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 23f9136..f3ea089 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"በ GPS የተዘጋጀ ሥፍራ"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"የአካባቢ ጥያቄዎች ነቅተዋል"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"ቅንብሮች"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ማያ ገጽ በራስ ሰር ይዞራል።"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ማያ ገጽ በወርድ ገፅ አቀማመጥ ተቆልፏል።"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ማያ ገጽ በቁም ገፅ አቀማመጥ ተቆልፏል።"</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"ሁሉም"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ሃይል በመሙላት ላይ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> እስከሚሞላ ድረስ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ተጠቃሚ ቀይር"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"መገለጫ አሳይ"</string>
<string name="user_add_user" msgid="5110251524486079492">"ተጠቃሚ አክል"</string>
<string name="user_new_user_name" msgid="426540612051178753">"አዲስ ተጠቃሚ"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 6416006..9bfb035 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"تم تعيين الموقع بواسطة GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"طلبات الموقع نشطة"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"الإعدادات"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"سيتم تدوير الشاشة تلقائيًا."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"تم تأمين الشاشة في الاتجاه الأفقي."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"تم تأمين الشاشة في الاتجاه العمودي."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"الكل"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"جارٍ الشحن (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> حتى الامتلاء)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"تبديل المستخدم"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"تبديل المستخدم، المستخدم الحالي <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"عرض الملف الشخصي"</string>
<string name="user_add_user" msgid="5110251524486079492">"إضافة مستخدم"</string>
<string name="user_new_user_name" msgid="426540612051178753">"مستخدم جديد"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index ee27bb2..e2f2905 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Местоположението е зададено от GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Активни заявки за местоположение"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Настройки"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранът ще се завърта автоматично."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Екранът е заключен в хоризонтална ориентация."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Екранът е заключен във вертикална ориентация."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Всички"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарежда се (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до пълно зареждане)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Превключване между потребителите"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Показване на потребителския профил"</string>
<string name="user_add_user" msgid="5110251524486079492">"Добавяне на потребител"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Нов потребител"</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 812b19c..8e87c94 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS এর দ্বারা সেট করা অবস্থান"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"অবস্থান অনুরোধ সক্রিয় রয়েছে"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"সমস্ত বিজ্ঞপ্তি সাফ করুন৷"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"সেটিংস"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"স্ক্রীন স্বয়ংক্রিয়ভাবে ঘুরে যাবে৷"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ভূদৃশ্য সজ্জাতে স্ক্রীন লক করা আছে৷"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"প্রতিকৃতি সজ্জাতে স্ক্রীন লক করা আছে৷"</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"সমস্ত"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"চার্জ হচ্ছে (পূর্ণ হতে <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> সময় বাকি)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ব্যবহারকারী পাল্টে দিন"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ব্যবহারকারী পাল্টান, বর্তমান ব্যবহারকারী <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"প্রোফাইল দেখান"</string>
<string name="user_add_user" msgid="5110251524486079492">"ব্যবহারকারী জুড়ুন"</string>
<string name="user_new_user_name" msgid="426540612051178753">"নতুন ব্যবহারকারী"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index ee20ce9..1399cd7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"S\'ha establert la ubicació per GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Configuració"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla està bloquejada en orientació horitzontal."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla està bloquejada en orientació vertical."</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Totes"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregant (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> per completar la càrrega)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Canvia d\'usuari"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Canvia l\'usuari. Usuari actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostra el perfil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Afegeix un usuari"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Usuari nou"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 89911ad..00ee3e1 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -44,7 +44,7 @@
<string name="battery_saver_start_action" msgid="5576697451677486320">"Zapnout úsporu baterie"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"Nastavení"</string>
<string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
- <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Režim V letadle"</string>
+ <string name="status_bar_settings_airplane" msgid="4879879698500955300">"Režim Letadlo"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"Autom. otočení obrazovky"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ZTLUM."</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"AUTOM."</string>
@@ -144,8 +144,8 @@
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"Edge"</string>
<string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"Žádná SIM karta."</string>
- <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Tethering přes Bluetooth."</string>
- <string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim V letadle."</string>
+ <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"Sdílené připojení přes Bluetooth."</string>
+ <string name="accessibility_airplane_mode" msgid="834748999790763092">"Režim Letadlo."</string>
<!-- String.format failed for translation -->
<!-- no translation found for accessibility_battery_level (7451474187113371965) -->
<skip />
@@ -174,10 +174,10 @@
<string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Připojení Wi-Fi je zapnuto."</string>
<string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Mobil: <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Baterie: <xliff:g id="STATE">%s</xliff:g>."</string>
- <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Režim V letadle je vypnutý."</string>
- <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Režim V letadle je zapnutý."</string>
- <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Režim V letadle je vypnutý."</string>
- <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Režim V letadle je zapnutý."</string>
+ <string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Režim Letadlo je vypnutý."</string>
+ <string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Režim Letadlo je zapnutý."</string>
+ <string name="accessibility_quick_settings_airplane_changed_off" msgid="66846307818850664">"Režim Letadlo je vypnutý."</string>
+ <string name="accessibility_quick_settings_airplane_changed_on" msgid="8983005603505087728">"Režim Letadlo je zapnutý."</string>
<string name="accessibility_quick_settings_bluetooth_off" msgid="2133631372372064339">"Rozhraní Bluetooth je vypnuto."</string>
<string name="accessibility_quick_settings_bluetooth_on" msgid="7681999166216621838">"Rozhraní Bluetooth je zapnuto."</string>
<string name="accessibility_quick_settings_bluetooth_connecting" msgid="6953242966685343855">"Probíhá připojování rozhraní Bluetooth."</string>
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavena pomocí systému GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktivní žádosti o polohu"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazat všechna oznámení."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Nastavení"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka se automaticky otočí."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Obrazovka je uzamčena v orientaci na šířku."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Obrazovka je uzamčena v orientaci na výšku."</string>
@@ -224,7 +227,7 @@
<string name="dessert_case" msgid="1295161776223959221">"Pult se sladkostmi"</string>
<string name="start_dreams" msgid="7219575858348719790">"Spořič obrazovky"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
- <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Režim V letadle"</string>
+ <string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Režim Letadlo"</string>
<string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Nabíjení, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Nabito"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Vše"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíjení (plně nabito za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Přepnout uživatele"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Přepnout uživatele, aktuální uživatel: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Zobrazit profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Přidat uživatele"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nový uživatel"</string>
@@ -324,7 +328,7 @@
<item quantity="other" msgid="6924190729213550991">"Na %d min"</item>
</plurals>
<plurals name="zen_mode_duration_hours">
- <item quantity="one" msgid="3480040795582254384">"Na jednu hodinu"</item>
+ <item quantity="one" msgid="3480040795582254384">"Na 1 h"</item>
<item quantity="other" msgid="5408537517529822157">"Na %d h"</item>
</plurals>
<string name="battery_saver_notification_title" msgid="237918726750955859">"Režim Úspora baterie je zapnutý."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index a4b36ed..50866d7 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Placeringen er angivet ved hjælp af GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktive placeringsanmodninger"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle underretninger."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Indstillinger"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skærmen er nu låst i liggende retning."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skærmen er nu låst i stående retning."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Opladning (fuldt opladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Skift bruger"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Vis profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Tilføj bruger"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Ny bruger"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 4675c8f..b9e39e1 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Standort durch GPS festgelegt"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Einstellungen"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Bildschirm bleibt im Querformat."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Bildschirm bleibt im Hochformat."</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Wird aufgeladen (voll in <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Nutzer wechseln"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Nutzer wechseln. Aktueller Nutzer: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Profil öffnen"</string>
<string name="user_add_user" msgid="5110251524486079492">"Nutzer hinzufügen"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Neuer Nutzer"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 02f0ca0..56c41a2 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ρύθμιση τοποθεσίας με GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Τα αιτήματα τοποθεσίας έχουν ενεργοποιηθεί"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Ρυθμίσεις"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Θα γίνεται αυτόματη περιστροφή της οθόνης."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Η οθόνη έχει κλειδωθεί σε οριζόντιο προσανατολισμό."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Η οθόνη έχει κλειδωθεί σε κατακόρυφο προσανατολισμό."</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Όλα"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Φόρτιση (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> για πλήρη φόρτιση)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Εναλλαγή χρήστη"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Εναλλαγή χρήστη, τρέχων χρήστης <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Εμφάνιση προφίλ"</string>
<string name="user_add_user" msgid="5110251524486079492">"Προσθήκη χρήστη"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Νέος χρήστης"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index ffbdcb9..a4abdca 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -212,7 +212,8 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Settings"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Notification settings"</string>
+ <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> settings"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Screen is locked in landscape orientation."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Screen is locked in portrait orientation."</string>
@@ -304,6 +305,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"All"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Switch user, current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Show profile"</string>
<string name="user_add_user" msgid="5110251524486079492">"Add user"</string>
<string name="user_new_user_name" msgid="426540612051178753">"New user"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index ffbdcb9..a4abdca 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -212,7 +212,8 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Location set by GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Settings"</string>
+ <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Notification settings"</string>
+ <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> settings"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Screen is locked in landscape orientation."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Screen is locked in portrait orientation."</string>
@@ -304,6 +305,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"All"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charging (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> until full)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Switch user"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Switch user, current user <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Show profile"</string>
<string name="user_add_user" msgid="5110251524486079492">"Add user"</string>
<string name="user_new_user_name" msgid="426540612051178753">"New user"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 9b1f2af..8a71771 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"La ubicación se estableció por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Configuración"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla está bloqueada en modo horizontal."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla está bloqueada en modo vertical."</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Todo"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (faltan <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para completar)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar usuario"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostrar perfil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Agregar usuario"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Usuario nuevo"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 03fde10..c3feb3a 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Ubicación definida por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Ajustes"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"La pantalla está bloqueada en modo horizontal."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"La pantalla está bloqueada en modo vertical."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Todo"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hasta completar)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar de usuario"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambiar de usuario (usuario actual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostrar perfil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Añadir usuario"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nuevo usuario"</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 951757a..94e67fa 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-i määratud asukoht"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Asukoha taotlused on aktiivsed"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Kustuta kõik teatised."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Seaded"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekraani pööramine toimub automaatselt."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekraan on lukustatud horisontaalsuunas."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekraan on lukustatud vertikaalsuunas."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Kõik"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laadimine (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>, kuni seade on täis)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Kasutaja vahetamine"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Kasutaja vahetamine, praegune kasutaja: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Kuva profiil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Kasutaja lisamine"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Uus kasutaja"</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 5226b9c..7ff9297 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Kokapena GPS bidez ezarri da"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aplikazioen kokapen-eskaerak aktibo daude"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Garbitu jakinarazpen guztiak."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Ezarpenak"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Pantaila automatikoki biratuko da."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Pantaila horizontalki blokeatuta dago."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Pantaila bertikalki blokeatuta dago."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Guztiak"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kargatzen (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> guztiz kargatu arte)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Aldatu erabiltzailea"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Aldatu erabiltzailez. <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> da saioa hasita duena."</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Erakutsi profila"</string>
<string name="user_add_user" msgid="5110251524486079492">"Gehitu erabiltzailea"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Erabiltzaile berria"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 9f63781..4cc5882 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"مکان تنظیم شده توسط GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"درخواستهای موقعیت مکانی فعال است"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلانها"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"تنظیمات"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"صفحه به صورت خودکار میچرخد."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"صفحه اکنون در جهت افقی قفل است."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"صفحه اکنون در جهت عمودی قفل است."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"همه"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"در حال شارژ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> تا شارژ کامل)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"تغییر کاربر"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"تعویض کاربر، کاربر کنونی <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"نمایش نمایه"</string>
<string name="user_add_user" msgid="5110251524486079492">"افزودن کاربر"</string>
<string name="user_new_user_name" msgid="426540612051178753">"کاربر جدید"</string>
@@ -328,7 +332,7 @@
<string name="battery_saver_notification_title" msgid="237918726750955859">"ذخیره کننده باتری روشن است."</string>
<string name="battery_saver_notification_text" msgid="820318788126672692">"عملکرد و اطلاعات پسزمینه را کاهش میدهد"</string>
<string name="battery_saver_notification_action_text" msgid="109158658238110382">"خاموش کردن ذخیرهکننده باتری"</string>
- <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>٪٪"</string>
+ <string name="battery_level_template" msgid="1609636980292580020">"<xliff:g id="LEVEL">%d</xliff:g>%%"</string>
<string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string>
<string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> شروع به ضبط هر چیزی میکند که در صفحهنمایش شما نمایش داده میشود."</string>
<string name="media_projection_remember_text" msgid="3103510882172746752">"دوباره نشان داده نشود"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index e2dd843..0b29e49 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Sijainti määritetty GPS:n avulla"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Sijaintipyynnöt aktiiviset"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Asetukset"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ruutu kääntyy automaattisesti."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ruutu on lukittu vaakasuuntaan."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ruutu on lukittu pystysuuntaan."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Kaikki"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ladataan (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kunnes täynnä)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Vaihda käyttäjää"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Näytä profiili"</string>
<string name="user_add_user" msgid="5110251524486079492">"Lisää käyttäjä"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Uusi käyttäjä"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 71f042d..7147727 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Paramètres"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"L\'écran est verrouillé en mode paysage."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"L\'écran est verrouillé en mode portrait."</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Tous"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours... (chargée à 100 % dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Changer d\'utilisateur"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Afficher le profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Ajouter un utilisateur"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nouvel utilisateur"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index a85b209..1020c27 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Position définie par GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Paramètres"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"L\'écran est verrouillé en mode paysage."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"L\'écran est verrouillé en mode portrait."</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Toutes"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Charge en cours… (chargé à 100 %% dans <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Changer d\'utilisateur"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Changer d\'utilisateur (utilisateur actuel : <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Afficher le profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Ajouter un utilisateur"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nouvel utilisateur"</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index 3d7f2a1..ad48160 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Localización establecida polo GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de localización activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas as notificacións."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Configuración"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A pantalla xirará automaticamente."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A pantalla está bloqueada en orientación horizontal."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A pantalla está bloqueada en orientación vertical."</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Sempre"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Cargando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> para finalizar a carga)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar usuario"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostrar perfil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Engadir usuario"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Novo usuario"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 99c5153..a1df1e0 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा सेट किया गया स्थान"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोध सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"सेटिंग"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वचालित रूप से घूमेगी."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"स्क्रीन लैंडस्केप अभिविन्यास में लॉक है."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"स्क्रीन पोर्ट्रेट अभिविन्यास में लॉक है."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"सभी"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"चार्ज हो रहा है (पूर्ण होने में <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> शेष)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"उपयोगकर्ता स्विच करें"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"उपयोगकर्ता स्विच करें, वर्तमान उपयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"प्रोफ़ाइल दिखाएं"</string>
<string name="user_add_user" msgid="5110251524486079492">"उपयोगकर्ता जोड़ें"</string>
<string name="user_new_user_name" msgid="426540612051178753">"नया उपयोगकर्ता"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index a35fed5..247bcec 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokaciju utvrdio GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Zahtjevi za lokaciju aktivni su"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Postavke"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon će se automatski zakrenuti."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Zaslon je zaključan u pejzažnoj orijentaciji."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Zaslon je zaključan u portretnoj orijentaciji."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Sve"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Punjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napunjenosti)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Promjena korisnika"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Prikaz profila"</string>
<string name="user_add_user" msgid="5110251524486079492">"Dodavanje korisnika"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Novi korisnik"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 4507754..42dc82d 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"A GPS beállította a helyet"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktív helylekérések"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Minden értesítés törlése"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Beállítások"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A képernyő automatikusan forogni fog."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A képernyő zárolva van fekvő tájolásban."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A képernyő zárolva van álló tájolásban."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Összes"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Töltés (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> a teljes töltöttségig)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Felhasználóváltás"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Felhasználóváltás (a jelenlegi felhasználó: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Profil megjelenítése"</string>
<string name="user_add_user" msgid="5110251524486079492">"Felhasználó hozzáadása"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Új felhasználó"</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index af20b98..1a96a43 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Տեղադրությունը կարգավորվել է GPS-ի կողմից"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Տեղադրության հարցումներն ակտիվ են"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Կարգավորումներ"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Էկրանը ինքնուրույն կպտտվի:"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Էկրանը կողպված է հորիզոնական դիրքավորման մեջ:"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:"</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Բոլորը"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Լիցքավորում (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> մինչև լրիվ լիցքավորումը)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Անջատել օգտվողին"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Ցույց տալ դիտարկումը"</string>
<string name="user_add_user" msgid="5110251524486079492">"Ավելացնել օգտվող"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Նոր օգտվող"</string>
@@ -336,10 +341,10 @@
<string name="media_projection_action_text" msgid="8470872969457985954">"Մեկնարկել հիմա"</string>
<string name="empty_shade_text" msgid="708135716272867002">"Ծանուցումներ չկան"</string>
<string name="device_owned_footer" msgid="3802752663326030053">"Սարքը կարող է վերահսկվել"</string>
- <string name="profile_owned_footer" msgid="8021888108553696069">"Պրոֆիլը կարող է մշտադիտարկվել"</string>
+ <string name="profile_owned_footer" msgid="8021888108553696069">"Պրոֆիլը կարող է վերահսկվել"</string>
<string name="vpn_footer" msgid="2388611096129106812">"Ցանցը կարող է վերահսկվել"</string>
<string name="monitoring_title_device_owned" msgid="7121079311903859610">"Սարքի մշտադիտարկում"</string>
- <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Պրոֆիլի մշտադիտարկում"</string>
+ <string name="monitoring_title_profile_owned" msgid="6790109874733501487">"Պրոֆիլի վերահսկում"</string>
<string name="monitoring_title" msgid="169206259253048106">"Ցանցի մշտադիտարկում"</string>
<string name="disable_vpn" msgid="4435534311510272506">"Անջատել VPN-ը"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"Անջատել VPN-ը"</string>
@@ -348,15 +353,15 @@
<string name="monitoring_description_legacy_vpn" msgid="4740349017929725435">"Դուք միացած եք VPN-ին («<xliff:g id="APPLICATION">%1$s</xliff:g>»):\n\nՁեզ VPN ծառայություն մատուցողը կարող է վերահսկել ձեր սարքի և ցանցի գործունեությունը, այդ թվում` նամակները, ծրագրերը և վստահելի կայքերը:"</string>
<string name="monitoring_description_vpn_device_owned" msgid="696121105616356493">"Այս սարքը կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nՁեր ադմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում՝ նամակները, ծրագրերը և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ձեր ադմինիստրատորին:\n\n Բացի այդ, դուք «<xliff:g id="APPLICATION">%2$s</xliff:g>» ծրագրին թույլատրել եք ստեղծել VPN կապ: Այդ ծրագիրը նույնպես կարող է վերահսկել ձեր ցանցային գործունեությունը:"</string>
<string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"Այս սարքը կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nՁեր ադմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում՝ նամակները, ծրագրերը և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ձեր ադմինիստրատորին:\n\nԲացի այդ, դուք միացած եք VPN-ին («<xliff:g id="APPLICATION">%2$s</xliff:g>»): Ձեզ VPN ծառայություն մատուցողը նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
- <string name="monitoring_description_profile_owned" msgid="2370062794285691713">"Այս պրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nՁեր ադմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում՝ նամակները, ծրագրերը և վստահելի կայքերը:\n\nԼրացուցիչ տեղեկությունների համար դիմեք ձեր ադմինիստրատորին:"</string>
- <string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"Սարքի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nՊրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nՁեր ադմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը՝ նամակները, ծրագրերը և վստահելի կայքերը:\n\nՀավելյալ տեղեկությունների համար դիմեք ադմինիստրատորին:"</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"Այս պրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում՝ նամակները, ծրագրերը և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:\n\nԴուք նաև «<xliff:g id="APPLICATION">%2$s</xliff:g>» ծրագրին թույլատրել եք ստեղծել VPN: Այն նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
- <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"Այս պրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը՝ նամակները, ծրագրերը և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ձեր ադմինիստրատորին:\n\nԴուք նաև միացած եք VPN-ին («<xliff:g id="APPLICATION">%2$s</xliff:g>»): VPN ծառայություն մատուցողը նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
- <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"Սարքի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nՊրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը՝ նամակները, ծրագրերը և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:\n\nԴուք նաև «<xliff:g id="APPLICATION">%3$s</xliff:g>»-ին թույլատրել եք ստեղծել VPN: Այն նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
- <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"Սարքի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nՊրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը՝ նամակները, ծրագրերը և վստահելի կայքերը: Այլ տեղեկությունների համար դիմեք ադմինիստրատորին:\n\nԴուք նաև միացած եք VPN-ին («<xliff:g id="APPLICATION">%3$s</xliff:g>»): VPN ծառայություն մատուցողը նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
+ <string name="monitoring_description_profile_owned" msgid="2370062794285691713">"Այս պրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում՝ նամակները, հավելվածները և վստահելի կայքերը:\n\nԼրացուցիչ տեղեկությունների համար դիմեք ձեր ադմինիստրատորին:"</string>
+ <string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"Սարքի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nՊրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր սարքի և ցանցի գործունեությունը՝ նամակները, հավելվածները և վստահելի կայքերը:\n\nՀավելյալ տեղեկությունների համար դիմեք ադմինիստրատորին:"</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"Այս պրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը, այդ թվում՝ նամակները, հավելվածները և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:\n\nԴուք նաև «<xliff:g id="APPLICATION">%2$s</xliff:g>» հավելվածին թույլատրել եք ստեղծել VPN: Այն նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
+ <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"Այս պրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը՝ նամակները, հավելվածները և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ձեր ադմինիստրատորին:\n\nԴուք նաև միացած եք VPN-ին («<xliff:g id="APPLICATION">%2$s</xliff:g>»): VPN ծառայություն մատուցողը նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
+ <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"Սարքի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nՊրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը՝ նամակները, հավելվածները և վստահելի կայքերը: Լրացուցիչ տեղեկությունների համար դիմեք ադմինիստրատորին:\n\nԴուք նաև «<xliff:g id="APPLICATION">%3$s</xliff:g>»-ին թույլատրել եք ստեղծել VPN: Այն նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
+ <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"Սարքի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nՊրոֆիլի կառավարիչն է՝\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nԱդմինիստրատորը կարող է վերահսկել ձեր ցանցային գործունեությունը՝ նամակները, հավելվածները և վստահելի կայքերը: Այլ տեղեկությունների համար դիմեք ադմինիստրատորին:\n\nԴուք նաև միացած եք VPN-ին («<xliff:g id="APPLICATION">%3$s</xliff:g>»): VPN ծառայություն մատուցողը նույնպես կարող է վերահսկել ցանցային գործունեությունը:"</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Սարքը կմնա արգելափակված՝ մինչև ձեռքով չբացեք"</string>
- <string name="hidden_notifications_title" msgid="7139628534207443290">"Ստանալ ծանուցումներն ավելի արագ"</string>
- <string name="hidden_notifications_text" msgid="2326409389088668981">"Տեսեք դրանք՝ մինչև ապակողպելը"</string>
+ <string name="hidden_notifications_title" msgid="7139628534207443290">"Ավելի արագ ստացեք ծանուցումները"</string>
+ <string name="hidden_notifications_text" msgid="2326409389088668981">"Տեսեք դրանք մինչև ապակողպելը"</string>
<string name="hidden_notifications_cancel" msgid="3690709735122344913">"Ոչ, շնորհակալություն"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"Կարգավորել"</string>
<string name="muted_by" msgid="6147073845094180001">"Համրեցվել է <xliff:g id="THIRD_PARTY">%1$s</xliff:g>-ի կողմից"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 6c3502b..910b500 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi yang disetel oleh GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Setelan"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Layar dikunci dalam orientasi lanskap."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Layar dikunci dalam orientasi potret."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Semua"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengisi daya (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hingga penuh)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Beralih pengguna"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Ganti pengguna, pengguna saat ini <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Tampilkan profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Tambahkan pengguna"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Pengguna baru"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index f98be45..73931db 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Staðsetning valin með GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Staðsetningarbeiðnir virkar"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Hreinsa allar tilkynningar."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Stillingar"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjárinn snýst sjálfkrafa."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skjárinn er læstur í langsniði."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skjárinn er læstur í skammsniði."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Allar"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Í hleðslu (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> fram að fullri hleðslu)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Skipta um notanda"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Skipta um notanda; núverandi notandi <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Sýna snið"</string>
<string name="user_add_user" msgid="5110251524486079492">"Bæta notanda við"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nýr notandi"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 39dc3ee..f1f3c97 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posizione stabilita dal GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Richieste di accesso alla posizione attive"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Impostazioni"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Lo schermo ruoterà automaticamente."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Lo schermo è bloccato in orientamento orizzontale."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Lo schermo è bloccato in orientamento verticale."</string>
@@ -268,7 +271,7 @@
<string name="quick_settings_tethering_label" msgid="7153452060448575549">"Tethering"</string>
<string name="quick_settings_hotspot_label" msgid="6046917934974004879">"Hotspot"</string>
<string name="quick_settings_notifications_label" msgid="4818156442169154523">"Notifiche"</string>
- <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Flashlight"</string>
+ <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"Torcia"</string>
<string name="quick_settings_cellular_detail_title" msgid="8575062783675171695">"Rete dati"</string>
<string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"Utilizzo dati"</string>
<string name="quick_settings_cellular_detail_remaining_data" msgid="722715415543541249">"Dati rimanenti"</string>
@@ -300,18 +303,19 @@
<string name="keyguard_unlock" msgid="8043466894212841998">"Scorri verso l\'alto per sbloccare"</string>
<string name="phone_hint" msgid="3101468054914424646">"Scorri verso destra per accedere al telefono"</string>
<string name="camera_hint" msgid="5241441720959174226">"Scorri verso sinistra per accedere alla fotocamera"</string>
- <string name="zen_mode_forever" msgid="4316804956488785559">"In modo indefinito"</string>
- <string name="interruption_level_none" msgid="3831278883136066646">"Nessuno"</string>
+ <string name="zen_mode_forever" msgid="4316804956488785559">"Sempre"</string>
+ <string name="interruption_level_none" msgid="3831278883136066646">"Nessuna"</string>
<string name="interruption_level_priority" msgid="6517366750688942030">"Priorità"</string>
- <string name="interruption_level_all" msgid="1330581184930945764">"Tutti"</string>
+ <string name="interruption_level_all" msgid="1330581184930945764">"Tutte"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"In carica (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> al termine)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambio utente"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambia utente, utente corrente <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostra profilo"</string>
<string name="user_add_user" msgid="5110251524486079492">"Aggiungi utente"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nuovo utente"</string>
<string name="guest_nickname" msgid="8059989128963789678">"Ospite"</string>
<string name="guest_new_guest" msgid="600537543078847803">"Aggiungi ospite"</string>
- <string name="guest_exit_guest" msgid="7187359342030096885">"Rimuovi invitato"</string>
+ <string name="guest_exit_guest" msgid="7187359342030096885">"Rimuovi ospite"</string>
<string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Rimuovere l\'ospite?"</string>
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Tutte le app e i dati di questa sessione verranno eliminati."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Rimuovi"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 74d1bcf..5582418 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"מיקום מוגדר על ידי GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"בקשות מיקום פעילות"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"הגדרות"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"המסך נעול כעת לרוחב."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"המסך נעול כעת לאורך."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"הכל"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"טוען (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> עד לסיום)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"החלפת משתמש"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"החלף משתמש. המשתמש הנוכחי הוא <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"הצג פרופיל"</string>
<string name="user_add_user" msgid="5110251524486079492">"הוסף משתמש"</string>
<string name="user_new_user_name" msgid="426540612051178753">"משתמש חדש"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index f1aa72c..0493b28 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPSにより現在地が設定されました"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"現在地リクエストがアクティブ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"設定"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"画面は自動的に回転します。"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"画面は横向きにロックされています。"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"画面は縦向きにロックされています。"</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"すべて"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中(フル充電まで<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ユーザーを切り替える"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"プロフィールを表示"</string>
<string name="user_add_user" msgid="5110251524486079492">"ユーザーを追加"</string>
<string name="user_new_user_name" msgid="426540612051178753">"新しいユーザー"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index e7b272b..e73c13e 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS-ით დადგენილი მდებარეობა"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"მდებარეობის მოთხოვნები აქტიურია"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ყველა შეტყობინების წაშლა"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"პარამეტრები"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ეკრანი შეტრიალდება ავტომატურად."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ეკრანი დაბლოკილია თარაზულ ორიენტაციაში"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ეკრანი დაბლოკილია პორტრეტის ორიენტაციაში."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"ყველა"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>-ის შეცვლა დასრულებამდე)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"მომხმარებლის გადართვა"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"პროფილის ჩვენება"</string>
<string name="user_add_user" msgid="5110251524486079492">"მომხმარებლის დამატება"</string>
<string name="user_new_user_name" msgid="426540612051178753">"ახალი მომხმარებელი"</string>
@@ -350,10 +355,10 @@
<string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"ამ მოწყობილობის მმართველი არის:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტების, აპების და უსაფრთხო საიტების. დამატებითი ინფორმაციისათვის, დაუკავშირდით თქვენს ადმინისტრატორს.\n\nასევე, თქვენ დაკავშირებული ხართ VPN-თან („<xliff:g id="APPLICATION">%2$s</xliff:g>“). თქვენს VPN სერვისის პროვაიდერს ასევე შეუძლია თქვენი ქსელის აქტივობის მონიტორინგი."</string>
<string name="monitoring_description_profile_owned" msgid="2370062794285691713">"ამ პროფილის მმართველია:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი მოწყობილობისა და ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტის, აპების და უსაფრთხო საიტების.\n\nდამატებითი ინფორმაციისათვის, დაუკავშირდით ადმინისტრატორს."</string>
<string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"ამ მოწყობილობის მმართველია:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nთქვენი პროფილის მმართველია:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი მოწყობილობისა და ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტის, აპების და უსაფრთხო საიტების.\n\nდამატებითი ინფორმაციისათვის, დაუკავშირდით ადმინისტრატორს."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"ამ პროფილის მმართველია:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი მოწყობილობისა და ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტის, აპების და უსაფრთხო საიტების. დამატებითი ინფორმაციისათვის, დაუკავშირდით ადმინისტრატორს.\n\nასევე, თქვენ მიანიჭეთ „<xliff:g id="APPLICATION">%2$s</xliff:g>“-ს VPN კავშირის დაყენება. ამ აპს ასევე შეუძლია ქსელის მონიტორინგი."</string>
- <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"ამ პროფილის მმართველია:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტების, აპების და უსაფრთხო საიტების. დამატებითი ინფორმაციისათვის, დაუკავშირდით თქვენს ადმინისტრატორს.\n\nასევე, თქვენ დაკავშირებული ხართ VPN-თან („<xliff:g id="APPLICATION">%2$s</xliff:g>“). თქვენს VPN სერვისის მომწოდებელს ასევე შეუძლია თქვენი ქსელის აქტივობის მონიტორინგი."</string>
- <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"ამ მოწყობილობის მმართველია:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nთქვენი პროფილის მმართველია:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი მოწყობილობისა და ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტის, აპების და უსაფრთხო საიტების. დამატებითი ინფორმაციისათვის, დაუკავშირდით ადმინისტრატორს.\n\nასევე, თქვენ მიანიჭეთ „<xliff:g id="APPLICATION">%3$s</xliff:g>“-ს VPN კავშირის დაყენება. ამ აპს ასევე შეუძლია ქსელის მონიტორინგი."</string>
- <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"ამ მოწყობილობის მმართველია:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nთქვენი პროფილის მმართველია:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი მოწყობილობისა და ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტის, აპების და უსაფრთხო საიტების. დამატებითი ინფორმაციისათვის, დაუკავშირდით ადმინისტრატორს.\n\nასევე, თქვენ დაკავშირებული ხართ VPN-თან („<xliff:g id="APPLICATION">%3$s</xliff:g>“). თქვენს VPN სერვისის მომწოდებელს ასევე შეუძლია თქვენი ქსელის აქტივობის მონიტორინგი."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"ამ პროფილის მმართველია:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nთქვენს ადმინისტრატორს შეუძლია თქვენი მოწყობილობისა და ქსელის აქტივობის მონიტორინგი, მათ შორის ელფოსტის, აპების და უსაფრთხო საიტების. დამატებითი ინფორმაციისათვის, დაუკავშირდით ადმინისტრატორს.\n\nასევე, თქვენ მიანიჭეთ „<xliff:g id="APPLICATION">%2$s</xliff:g>“-ს VPN კავშირის დაყენება. ამ აპს ასევე შეუძლია ქსელის მონიტორ."</string>
+ <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"ამ პროფილის მმართველია:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\nთქვენს ადმინ.-ს შეუძლია თქვენი ქსელის აქტივობის მონიტორ., მათ შორის ელფოსტების, აპების და უსაფრთხო საიტების. დამატ. ინფორმ.-თვის, დაუკავშირდით თქვენს ადმინ.-ს.\n\nასევე, თქვ. დაკავშ.-ლი ხართ VPN-თან („<xliff:g id="APPLICATION">%2$s</xliff:g>“). თქვენს VPN სერვისის მომწოდებელს ასევე შეუძლია თქვ. ქსელის აქტივობის მონიტორ."</string>
+ <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"ამ მოწყობილობის მმართველია:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nთქვ. პროფილის მმართველია:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nთქვენს ადმინ.-ს შეუძლია თქვ. მოწყ.-ისა და ქსელის აქტივობის მონიტ., მათ შორის ელფოსტის, აპების და უსაფრთხო საიტების. დამატებითი ინფორმ.-თვის, დაუკავშირდით ადმინ.-ს.\n\nასევე, თქვენ მიანიჭეთ „<xliff:g id="APPLICATION">%3$s</xliff:g>“-ს VPN კავშირის დაყენება. ამ აპს ასევე შეუძლია ქსელის მონიტ."</string>
+ <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"ამ მოწყ.-ის მმართ.-ია:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\nთქვ. პროფ-ის მმართ-ია:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\nთქვ. ადმინ.-ს შეუძლია თქვ. მოწყ.-ისა და ქსელის აქტივ.-ის მონიტ., მ. შ. ელფოსტის, აპების და უსაფრთხო საიტების. დამატებ. ინფორმ.-თვის, დაუკავშირდით ადმინ.-ს.\n\nასევე, თქვ. დაკავშირ. ხართ VPN-თან („<xliff:g id="APPLICATION">%3$s</xliff:g>“). თქვ. VPN სრვს-ის მომწ.-ს ასევე შეუძლია თქვ. ქსელის აქტ.-ის მონიტორ.."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"მოწყობილობის დარჩება ჩაკეტილი, სანამ ხელით არ გახსნით"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"შეტყობინებების უფრო სწრაფად მიღება"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"იხილეთ განბლოკვამდე"</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index e7e7119..561596bf 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Аймақ GPS арқылы орнатылған"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Аймақ өтініштері қосылған"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Барлық хабарларды жойыңыз."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Параметрлер"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматты түрде бұрылады."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Экран ландшафт бағытында бекітілген."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Экран портрет бағытында бекітілген."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Барлығы"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарядталуда (толғанша <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Пайдаланушыны ауыстыру"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Профильді көрсету"</string>
<string name="user_add_user" msgid="5110251524486079492">"Пайдаланушы қосу"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Жаңа пайдаланушы"</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 61d4289..8555163 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ទីតាំងកំណត់ដោយ GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"សំណើទីតាំងសកម្ម"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"សម្អាតការជូនដំណឹងទាំងអស់។"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"ការកំណត់"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"នឹងបង្វិលអេក្រង់ស្វ័យប្រវត្តិ។"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"អេក្រង់ជាប់សោក្នុងទិសផ្ដេក។"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"បានចាក់សោអេក្រង់ក្នុងទិសបញ្ឈរ។"</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"ទាំងអស់"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"កំពុងបញ្ចូលថ្ម (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ទើបពេញ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ប្ដូរអ្នកប្រើ"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ប្ដូរអ្នកប្រើ អ្នកប្រើបច្ចុប្បន្ន <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"បង្ហាញប្រវត្តិរូប"</string>
<string name="user_add_user" msgid="5110251524486079492">"បន្ថែមអ្នកប្រើ"</string>
<string name="user_new_user_name" msgid="426540612051178753">"អ្នកប្រើថ្មី"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index f7b21c7..b2d7063 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ಸ್ಥಾನವನ್ನು GPS ಮೂಲಕ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ಸ್ಥಾನ ವಿನಂತಿಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ಪರದೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಿರುಗುತ್ತದೆ."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ಪರದೆಯನ್ನು ಲ್ಯಾಂಡ್ಸ್ಕೇಪ್ ಓರಿಯಂಟೇಶನ್ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ಪರದೆಯನ್ನು ಪೋಟ್ರೇಟ್ ಓರಿಯಂಟೇಶನ್ನಲ್ಲಿ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"ಎಲ್ಲ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ ( ಪೂರ್ತಿ ಆಗುವವರೆಗೆ <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ಬಳಕೆದಾರರನ್ನು ಬದಲಿಸಿ, ಪ್ರಸ್ತುತ ಬಳಕೆದಾರ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ಪ್ರೊಫೈಲ್ ತೋರಿಸು"</string>
<string name="user_add_user" msgid="5110251524486079492">"ಬಳಕೆದಾರರನ್ನು ಸೇರಿಸಿ"</string>
<string name="user_new_user_name" msgid="426540612051178753">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index e73cbde..aa8c465 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS에서 위치 설정"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"위치 요청 있음"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"설정"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"화면이 자동으로 회전됩니다."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"화면이 가로 방향으로 잠겨 있습니다."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"화면이 세로 방향으로 잠겨 있습니다."</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"모두 수신"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"충전 중(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> 후 충전 완료)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"사용자 전환"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"사용자 전환, 현재 사용자 <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"프로필 표시"</string>
<string name="user_add_user" msgid="5110251524486079492">"사용자 추가"</string>
<string name="user_new_user_name" msgid="426540612051178753">"새 사용자"</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index a96c88a..ccd706e 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -238,7 +238,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS боюнча аныкталган жайгашуу"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Жайгаштыруу талаптары иштелүүдө"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Бардык эскертмелерди тазалоо."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Жөндөөлөр"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматтык түрдө бурулат."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Экран туурасынан турган бойдон бекитилген."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Экран тикесинен турган бойдон бекитилген."</string>
@@ -330,6 +333,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Бардыгы"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Кубатталууда (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> толгонго чейин)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Колдонуучуну которуу"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Профилди көрсөтүү"</string>
<string name="user_add_user" msgid="5110251524486079492">"Колдонуучу кошуу"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Жаңы колдонуучу"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 468f717..224b11f 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ສະຖານທີ່ກຳນົດໂດຍ GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ການຮ້ອງຂໍສະຖານທີ່ທີ່ເຮັດວຽກຢູ່"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ລຶບການແຈ້ງເຕືອນທັງໝົດ."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"ການຕັ້ງຄ່າ"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ໜ້າຈໍຈະໝຸນໂດຍອັດຕະໂນມັດ."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ໜ້າຈໍຖືກລັອກໃນລວງນອນ."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ໜ້າຈໍຖືກລັອກຢູ່ໃນໂໝດແນວຕັ້ງ."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"ທັງໝົດ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ກຳລັງສາກໄຟ (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ກວ່າຈະເຕັມ)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ສະລັບຜູ່ໃຊ້"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ສະແດງໂປຣໄຟລ໌"</string>
<string name="user_add_user" msgid="5110251524486079492">"ເພີ່ມຜູ່ໃຊ້"</string>
<string name="user_new_user_name" msgid="426540612051178753">"ຜູ່ໃຊ້ໃໝ່"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 866c8dd..f571a4c 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS nustatyta vieta"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Vietovės užklausos aktyvios"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Nustatymai"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekranas bus sukamas automatiškai."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Užrakintas ekranas yra horizontalios orientacijos."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Užrakintas ekranas yra vertikalios orientacijos."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Visi"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Kraunama (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> iki visiško įkrovimo)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Perjungti naudotoją"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Perjungti naudotoją, dabartinis naudotojas <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Rodyti profilį"</string>
<string name="user_add_user" msgid="5110251524486079492">"Naudotojo pridėjimas"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Naujas naudotojas"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 0e166b7..f309d24 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS iestatītā atrašanās vieta"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktīvi atrašanās vietu pieprasījumi"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Iestatījumi"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrāns tiks pagriezts automātiski."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekrāns tagad ir bloķēts ainavas orientācijā."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekrāns tagad ir bloķēts portreta orientācijā."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Visi"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Notiek uzlāde (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> līdz pilnīgai uzlādei)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Mainīt lietotāju"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Pārslēgt lietotāju; pašreizējais lietotājs: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Parādīt profilu"</string>
<string name="user_add_user" msgid="5110251524486079492">"Lietotāja pievienošana"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Jauns lietotājs"</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index b6b5396..90be4ad 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Локацијата е поставена со ГПС"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Активни барања за локација"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Исчисти ги сите известувања."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Поставки"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранот ќе ротира автоматски."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Екранот е заклучен во ориентација на пејзаж."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Екранот е заклучен во ориентација на портрет."</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Сѐ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Се полни (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> додека не се наполни)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Промени го корисникот"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Промени го корисникот, тековен корисник <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Прикажи го профилот"</string>
<string name="user_add_user" msgid="5110251524486079492">"Додај корисник"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Нов корисник"</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 293b028..742c943 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ലൊക്കേഷൻ സജ്ജീകരിച്ചത് GPS ആണ്"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ലൊക്കേഷൻ അഭ്യർത്ഥനകൾ സജീവമാണ്"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"എല്ലാ വിവരങ്ങളും മായ്ക്കുക."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"ക്രമീകരണങ്ങൾ"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"സ്ക്രീൻ യാന്ത്രികമായി തിരിയും."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"സ്ക്രീൻ ലാൻഡ്സ്കേപ്പ് ഓറിയന്റേഷനിൽ ലോക്കുചെയ്തു."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"സ്ക്രീൻ പോർട്രെയ്റ്റ് ഓറിയന്റേഷനിൽ ലോക്കുചെയ്തു."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"എല്ലാം"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ചാർജ്ജുചെയ്യുന്നു (പൂർണ്ണമാകുന്നതിന്, <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"ഉപയോക്താവ് മാറുക"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"ഉപയോക്താവിനെ മാറ്റുക, <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> എന്നയാളാണ് നിലവിലുള്ള ഉപയോക്താവ്"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"പ്രൊഫൈൽ കാണിക്കുക"</string>
<string name="user_add_user" msgid="5110251524486079492">"ഉപയോക്താവിനെ ചേര്ക്കുക"</string>
<string name="user_new_user_name" msgid="426540612051178753">"പുതിയ ഉപയോക്താവ്"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index c5cf310..40e5dcd 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS байршил"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Байршлын хүсэлтүүд идэвхтэй"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Бүх мэдэгдлийг цэвэрлэх."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Тохиргоо"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Дэлгэц автоматаар эргэнэ."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Дэлгэц хэвтээ чиглэлд түгжигдсэн."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Дэлгэц босоо чиглэлээр түгжигдсэн."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Бүгд"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Цэнэглэж байна (дүүргэхэд <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Хэрэглэгчийг сэлгэх"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Хэрэглэгчийг сэлгэх, одоогийн хэрэглэгч <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Профайлыг харуулах"</string>
<string name="user_add_user" msgid="5110251524486079492">"Хэрэглэгч нэмэх"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Шинэ хэрэглэгч"</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index f6c6f8a..4e31db0 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारे स्थान सेट केले"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान विनंत्या सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सर्व सूचना साफ करा."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"सेटिंग्ज"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वयंचलितपणे फिरेल."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"भूदृश्य अभिमुखतेमध्ये स्क्रीन लॉक केली आहे."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"पोर्ट्रेट अभिमुखतेमध्ये स्क्रीन लॉक केली आहे."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"सर्व"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण होईपर्यंत) चार्ज होत आहे"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"वापरकर्ता स्विच करा"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"वापरकर्ता स्विच करा, वर्तमान वापरकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"प्रोफाईल दर्शवा"</string>
<string name="user_add_user" msgid="5110251524486079492">"वापरकर्ता जोडा"</string>
<string name="user_new_user_name" msgid="426540612051178753">"नवीन वापरकर्ता"</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 0c0efb3..fb6e04d 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasi ditetapkan oleh GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Tetapan"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrin akan berputar secara automatik."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrin dikunci dalam orientasi landskap."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrin dikunci dalam orientasi potret."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Semua"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Mengecas (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> sehingga penuh)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Tukar pengguna"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Tunjuk profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Tambah pengguna"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Pengguna baharu"</string>
@@ -357,7 +362,7 @@
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Peranti akan kekal terkunci sehingga anda membuka kunci secara manual"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Dapatkan pemberitahuan lebih cepat"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Lihat sebelum anda membuka kunci"</string>
- <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Tidak, terima kasih"</string>
+ <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Tidak"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"Sediakan"</string>
<string name="muted_by" msgid="6147073845094180001">"Diredam oleh <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 5ac9d27..c22db95 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -210,7 +210,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPSမှတည်နေရာကိုအတည်ပြုသည်"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"တည်နေရာပြ တောင်းဆိုချက်များ အသက်ဝင်ရန်"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"သတိပေးချက်အားလုံးအား ဖယ်ရှားခြင်း။"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"ဆက်တင်များ"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ဖန်သားပြင်ပေါ်မှာ ပြသမှုက အလိုအလျောက် လှည့်သွားပါမည်"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ဖန်သားပြင် အနေအထားက အလျားလိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ဖန်သားပြင် အနေအထားက ဒေါင်လိုက်အဖြစ် ပုံသေ လုပ်ထားပါသည်"</string>
@@ -302,6 +305,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"အားလုံး"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"(<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> အပြည့် အထိ) အားသွင်းနေ"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"အသုံးပြုသူကို ပြောင်းလဲရန်"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"အသုံးပြုသူကို ပြောင်းရန်၊ လက်ရှိ အသုံးပြုသူ <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ပရိုဖိုင်ကို ပြရန်"</string>
<string name="user_add_user" msgid="5110251524486079492">"သုံးသူ ထပ်ထည့်ရန်"</string>
<string name="user_new_user_name" msgid="426540612051178753">"အသုံးပြုသူ အသစ်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 440fef3..dbbd216 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Posisjon angitt av GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktive stedsforespørsler"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Innstillinger"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjermen roterer automatisk."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skjermen er låst i liggende retning."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skjermen er låst i stående retning."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Lader (fulladet om <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Bytt bruker"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Bytt bruker, gjeldende bruker er <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Vis profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Legg til brukere"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Ny bruker"</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index df555a6..248df04 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS द्वारा स्थान सेट गरिएको"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोधहरू सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सबै सूचनाहरू हटाउनुहोस्।"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"सेटिङ्हरू"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रिन स्वतः घुम्ने छ।"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"स्क्रिनलाई ल्यान्डस्केप अवस्थामा बन्द गरिएको छ।"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"स्क्रिन पोर्टेट अभिमूखमा लक गरिएको छ।"</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"सबै"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"चार्ज हुँदै (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> पूर्ण भएसम्म)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"प्रयोगकर्ता फेर्नुहोस्"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"प्रयोगकर्ता, हालको प्रयोगकर्ता <xliff:g id="CURRENT_USER_NAME">%s</xliff:g> मा स्विच गर्नुहोस्"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"प्रोफाइल देखाउनुहोस्"</string>
<string name="user_add_user" msgid="5110251524486079492">"प्रयोगकर्ता थप्नुहोस्"</string>
<string name="user_new_user_name" msgid="426540612051178753">"नयाँ प्रयोगकर्ता"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4d5307c..6802420 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locatie bepaald met GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Locatieverzoeken actief"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Instellingen"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Scherm wordt automatisch geroteerd."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Het scherm is nu vergrendeld in liggende stand."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Het scherm is nu vergrendeld in staande stand."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Alle"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Opladen (vol over <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Gebruiker wijzigen"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Schakelen tussen gebruikers, huidige gebruiker <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Profiel weergeven"</string>
<string name="user_add_user" msgid="5110251524486079492">"Gebruiker toevoegen"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nieuwe gebruiker"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 51fe321..0d482ab 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokalizacja z GPSa"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Prośby o lokalizację są aktywne"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Ustawienia"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran zostanie obrócony automatycznie."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran jest zablokowany w orientacji poziomej."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran jest zablokowany w orientacji pionowej."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Wszystkie"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Ładuje się (pełne naładowanie za <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Przełącz użytkownika"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Przełącz użytkownika. Bieżący użytkownik: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Pokaż profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Dodaj użytkownika"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nowy użytkownik"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 88ce23a..a37c832 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Localização definida por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Pedidos de localização ativos"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Definições"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"O ecrã será rodado automaticamente."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"O ecrã está bloqueado na orientação horizontal."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"O ecrã está bloqueado na orientação vertical."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"A carregar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até à carga máxima)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Mudar utilizador"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Mudar de utilizador; o utilizador atual é <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostrar perfil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Adicionar utilizador"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Novo utilizador"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 4180640..da43300 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Local definido por GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Configurações"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A tela está bloqueada na orientação paisagem."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A tela está bloqueada na orientação retrato."</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Tudo"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Carregando (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> até concluir)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Trocar usuário"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Mostrar perfil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Adicionar usuário"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Novo usuário"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 8995c15..d4bebb3 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Locaţie setată prin GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitări locație active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeţi toate notificările."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Setări"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ecranul este blocat în orientarea de tip peisaj."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ecranul este blocat în orientarea de tip portret."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Toate"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Se încarcă (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> până la finalizare)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Comutați între utilizatori"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Afișați profilul"</string>
<string name="user_add_user" msgid="5110251524486079492">"Adăugați un utilizator"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Utilizator nou"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 84cfff4..337319a 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Координаты по GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Есть активные запросы на определение местоположения"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Настройки"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран будет поворачиваться автоматически."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Выбрана только альбомная ориентация экрана."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Выбрана только книжная ориентация экрана."</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Все"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Зарядка батареи (осталось <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Сменить пользователя."</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Показать профиль."</string>
<string name="user_add_user" msgid="5110251524486079492">"Добавить пользователя"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Новый пользователь"</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index 321ecb9..6b41dbe 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS මඟින් ස්ථානය සකසා ඇත"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"පිහිටීම් ඉල්ලීම් සක්රියයි"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"සියලු දැනුම්දීම් හිස් කරන්න."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"සැකසීම්"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"තිරය ස්වයංක්රීයව කරකැවේ."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"තිරය තිරස් දිශානතියෙහි අගුළු දමා ඇත."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"තිරය සිරස් දිශානතිය තුළ අගුළු වැටී ඇත."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"සියලු"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ආරෝපණය වෙමින් (සම්පුර්ණ වන තෙක් <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"පරිශීලක මාරුව"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"පැතිකඩ පෙන්වන්න"</string>
<string name="user_add_user" msgid="5110251524486079492">"පරිශීලකයෙක් එක් කරන්න"</string>
<string name="user_new_user_name" msgid="426540612051178753">"නව පරිශීලකයා"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index da1bb4c..2ebfe42 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Poloha nastavená pomocou GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Žiadosti o polohu sú aktívne"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Nastavenia"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka sa automaticky otočí."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Obrazovka je uzamknutá v orientácii na šírku."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Obrazovka je uzamknutá v orientácii na výšku."</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Všetky"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nabíja sa (úplné nabitie o <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Prepnutie používateľa"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Zobraziť profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Pridať používateľa"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nový používateľ"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 5b0442a..06a4b35 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokacija nastavljena z GPS-om"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktivne zahteve za lokacijo"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Nastavitve"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Zaslon je zaklenjen v ležeči usmerjenosti."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Zaslon je zaklenjen v pokončni usmerjenosti."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Vse"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Polnjenje (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> do napolnjenosti)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Preklop med uporabniki"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Preklop med uporabniki, trenutni uporabnik <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Prikaz profila"</string>
<string name="user_add_user" msgid="5110251524486079492">"Dodajanje uporabnika"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Nov uporabnik"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 4552926..4d509d5 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Локацију је подесио GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Има активних захтева за локацију"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Подешавања"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран ће се аутоматски ротирати."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Екран је закључан у хоризонталном положају."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Екран је закључан у вертикалном положају."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Све"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Пуњење (пун је за <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Замени корисника"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Прикажи профил"</string>
<string name="user_add_user" msgid="5110251524486079492">"Додај корисника"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Нови корисник"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index f99c4ef..48a8445 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Platsen har identifierats av GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Det finns aktiva platsbegäranden"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Inställningar"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Bildskärmens riktning är nu låst i liggande format."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Bildskärmens riktning är nu låst i stående format."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Alla"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Laddar (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> tills batteriet är fulladdat)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Byt användare"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Byt användare. Aktuell användare: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Visa profil"</string>
<string name="user_add_user" msgid="5110251524486079492">"Lägg till användare"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Ny användare"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index c0b1b12..a76edc1 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -210,7 +210,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Mahali pamewekwa na GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Maombi ya eneo yanatumika"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Mipangilio"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrini imefungwa sasa katika uelekezo wa mandhari."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrini imefungwa katika uelekeo wa picha."</string>
@@ -302,6 +305,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Zote"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Inachaji (Imebakisha <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ijae)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Badili mtumiaji"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Onyesha wasifu"</string>
<string name="user_add_user" msgid="5110251524486079492">"Ongeza mtumiaji"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Mtumiaji mpya"</string>
@@ -355,7 +360,7 @@
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Kifaa kitaendelea kuwa katika hali ya kufungwa hadi utakapokifungua mwenyewe"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"Pata arifa kwa haraka"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"Zitazame kabla hujafungua"</string>
- <string name="hidden_notifications_cancel" msgid="3690709735122344913">"La, asante"</string>
+ <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Hapana, asante"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"Sanidi"</string>
<string name="muted_by" msgid="6147073845094180001">"Sauti imezimwa na <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index 52700cc..0d92c1b 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS அமைத்த இருப்பிடம்"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"இருப்பிடக் கோரிக்கைகள் இயக்கப்பட்டன"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"எல்லா அறிவிப்புகளையும் அழி."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"அமைப்பு"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"திரை தானாகச் சுழலும்."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"நிலத்தோற்ற திசையமைப்பில் திரைப் பூட்டப்பட்டுள்ளது."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"உருவப்பட திசையமைப்பில் திசை பூட்டப்பட்டுள்ளது."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"எல்லாம்"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"சார்ஜாகிறது (முழு சார்ஜிற்கு <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ஆகும்)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"பயனரை மாற்று"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"பயனரை மாற்று, தற்போதைய பயனர் <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"சுயவிவரத்தைக் காட்டு"</string>
<string name="user_add_user" msgid="5110251524486079492">"பயனரைச் சேர்"</string>
<string name="user_new_user_name" msgid="426540612051178753">"புதியவர்"</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 3740172..f498ba0 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"స్థానం GPS ద్వారా సెట్ చేయబడింది"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"స్థాన అభ్యర్థనలు సక్రియంగా ఉన్నాయి"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"అన్ని నోటిఫికేషన్లను క్లియర్ చేయండి."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"సెట్టింగ్లు"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"స్క్రీన్ స్వయంచాలకంగా తిప్పబడుతుంది."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"స్క్రీన్ ల్యాండ్స్కేప్ దృగ్విన్యాసంలో లాక్ చేయబడుతుంది."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"స్క్రీన్ పోర్ట్రెయిట్ దృగ్విన్యాసంలో లాక్ చేయబడుతుంది."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"అన్నిటికీ"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"ఛార్జ్ అవుతోంది (పూర్తిగా నిండటానికి <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"వినియోగదారుని మార్చు"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"వినియోగదారుని మార్చు, ప్రస్తుత వినియోగదారు <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"ప్రొఫైల్ని చూపు"</string>
<string name="user_add_user" msgid="5110251524486079492">"వినియోగదారుని జోడించండి"</string>
<string name="user_new_user_name" msgid="426540612051178753">"కొత్త వినియోగదారు"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 59579bc..d1c2ecd 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"ตำแหน่งที่กำหนดโดย GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"คำขอตำแหน่งที่มีการใช้งาน"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"การตั้งค่า"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"หน้าจอจะหมุนโดยอัตโนมัติ"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"ขณะนี้หน้าจอถูกล็อกให้วางในแนวนอน"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"ขณะนี้หน้าจอถูกล็อกให้วางในแนวตั้ง"</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"ทั้งหมด"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"กำลังชาร์จ (อีก <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> เต็ม)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"สลับผู้ใช้"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"แสดงโปรไฟล์"</string>
<string name="user_add_user" msgid="5110251524486079492">"เพิ่มผู้ใช้"</string>
<string name="user_new_user_name" msgid="426540612051178753">"ผู้ใช้ใหม่"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index a421a84..aa2992f 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Lokasyong itinatakda ng GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktibo ang mga kahilingan ng lokasyon"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Mga Setting"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Awtomatikong iikot ang screen."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Naka-lock ang screen sa pahigang oryentasyon."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Naka-lock ang screen sa patayong oryentasyon."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Lahat"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Nagtsa-charge (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> hanggang mapuno)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Magpalit ng user"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Ipakita ang profile"</string>
<string name="user_add_user" msgid="5110251524486079492">"Magdagdag ng user"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Bagong user"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 0c0149c..0dc8c61 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Konum GPS ile belirlendi"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Konum bilgisi istekleri etkin"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Ayarlar"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran otomatik olarak dönecektir."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran yatay yönde kilitlendi."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran dikey yönde kilitlendi."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Tümü"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Şarj oluyor (tamamen dolmasına <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> kaldı)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Kullanıcı değiştirme"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Profili göster"</string>
<string name="user_add_user" msgid="5110251524486079492">"Kullanıcı ekle"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Yeni kullanıcı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 162a280..6e371a4 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Місцезнаходження встановлено за допомогою GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Запити про місцезнаходження активні"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Налаштування"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран обертатиметься автоматично."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Екран заблоковано в альбомній орієнтації."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Екран заблоковано в книжковій орієнтації."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Усі"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Заряджання (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> до повного зарядження)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Змінити користувача"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Змінити користувача, поточний користувач – <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Показати профіль"</string>
<string name="user_add_user" msgid="5110251524486079492">"Додати користувача"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Новий користувач"</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 708607c..ec3096b 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"مقام متعین کیا گیا بذریعہ GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"مقام کی درخواستیں فعال ہیں"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"سبھی اطلاعات صاف کریں۔"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"ترتیبات"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"اسکرین خود بخود گردش کرے گی۔"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"اسکرین لینڈ اسکیپ سمت بندی میں مقفل ہے۔"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"اسکرین پورٹریٹ سمت بندی میں مقفل ہے۔"</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"سبھی"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"چارج ہو رہا ہے (مکمل ہونے تک <xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> باقی ہیں)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"صارف سوئچ کریں"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"صارف کو سوئچ کریں، موجودہ صارف <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"پروفائل دکھائیں"</string>
<string name="user_add_user" msgid="5110251524486079492">"صارف کو شامل کریں"</string>
<string name="user_new_user_name" msgid="426540612051178753">"نیا صارف"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index 7776269..c0dd8b7 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS yordamida manzilni o‘rnatish"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Joylashuv so‘rovlari yoniq"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Barcha eslatmalarni tozalash."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Sozlamalar"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik ravishda aylanadi."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Ekran eniga holatida qulflandi."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Ekran bo‘yiga holatida qulflandi."</string>
@@ -304,6 +307,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Barchasi"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Quvvat olmoqda (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>da to‘ladi)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Foydalanuvchini almashtirish"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Profilni ko‘rsatish"</string>
<string name="user_add_user" msgid="5110251524486079492">"Foydalanuvchi qo‘shish"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Yangi foydalanuvchi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 80fdc46..2488556 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Vị trí đặt bởi GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Yêu cầu về thông tin vị trí đang hoạt động"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Cài đặt"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Màn hình hiện bị khóa theo hướng ngang."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Màn hình hiện bị khóa theo hướng dọc."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Tất cả"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Đang sạc (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> cho đến khi đầy)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Chuyển đổi người dùng"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Chuyển người dùng, người dùng hiện tại <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Hiển thị hồ sơ"</string>
<string name="user_add_user" msgid="5110251524486079492">"Thêm người dùng"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Người dùng mới"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 06cebb3..4ca0e8f 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"已通过GPS确定位置"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"应用发出了有效位置信息请求"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"设置"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"屏幕锁定为横向模式。"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"屏幕锁定为纵向模式。"</string>
@@ -306,6 +309,8 @@
<string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"正在充电(还需<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>充满)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"切换用户"</string>
+ <!-- no translation found for accessibility_multi_user_switch_switcher_with_current (8434880595284601601) -->
+ <skip />
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"显示个人资料"</string>
<string name="user_add_user" msgid="5110251524486079492">"添加用户"</string>
<string name="user_new_user_name" msgid="426540612051178753">"新用户"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 9b0bde1..3a53017 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"位置要求啟動中"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"設定"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"螢幕會自動旋轉。"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"螢幕已鎖定為橫向模式。"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"螢幕已鎖定為垂直模式。"</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後完成充電)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"切換使用者"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"切換使用者,目前使用者是<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"顯示個人檔案"</string>
<string name="user_add_user" msgid="5110251524486079492">"新增使用者"</string>
<string name="user_new_user_name" msgid="426540612051178753">"新使用者"</string>
@@ -357,7 +361,7 @@
<string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"這部裝置的管理機構:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的個人檔案的管理機構:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網絡活動,包括電郵、應用程式及安全網站。如需瞭解詳情,請聯絡您的管理員。\n\n同時,由於您已授權「<xliff:g id="APPLICATION">%3$s</xliff:g>」設定 VPN 連線,因此這個應用程式也能監控您的網絡活動。"</string>
<string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"這部裝置的管理機構:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的個人檔案的管理機構:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網絡活動,包括電郵、應用程式及安全網站。如需瞭解詳情,請聯絡您的管理員。\n\n同時,由於您的裝置已與 VPN (「<xliff:g id="APPLICATION">%3$s</xliff:g>」) 連線,因此您的 VPN 服務供應商也能監控您的網絡活動。"</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"裝置將保持上鎖,直到您手動解鎖"</string>
- <string name="hidden_notifications_title" msgid="7139628534207443290">"快速取得通知"</string>
+ <string name="hidden_notifications_title" msgid="7139628534207443290">"更快取得通知"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"解鎖前顯示"</string>
<string name="hidden_notifications_cancel" msgid="3690709735122344913">"不用了,謝謝"</string>
<string name="hidden_notifications_setup" msgid="41079514801976810">"設定"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index d57845b..8840b2c 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -214,7 +214,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"GPS 已定位"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"有位置資訊要求"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"設定"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"螢幕會自動旋轉。"</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"螢幕已鎖定為橫向模式。"</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"螢幕已鎖定為垂直模式。"</string>
@@ -306,6 +309,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"全部"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"充電中 (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g>後充飽)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"切換使用者"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"切換使用者,目前使用者是<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"顯示設定檔"</string>
<string name="user_add_user" msgid="5110251524486079492">"新增使用者"</string>
<string name="user_new_user_name" msgid="426540612051178753">"新使用者"</string>
@@ -350,12 +354,12 @@
<string name="monitoring_description_legacy_vpn" msgid="4740349017929725435">"您已連線至 VPN (「<xliff:g id="APPLICATION">%1$s</xliff:g>」)。\n\n您的 VPN 服務供應商可以監控您的裝置和網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。"</string>
<string name="monitoring_description_vpn_device_owned" msgid="696121105616356493">"這個裝置由下列網域管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>。\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請與您的管理員聯絡。\n\n同時,由於您已授權「<xliff:g id="APPLICATION">%2$s</xliff:g>」設定 VPN 連線,因此這個應用程式也能監控您的網路活動。"</string>
<string name="monitoring_description_legacy_vpn_device_owned" msgid="649791650224064248">"這個裝置由下列網域管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>。\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請與您的管理員聯絡。\n\n同時,由於您的裝置已連線至 VPN (「<xliff:g id="APPLICATION">%2$s</xliff:g>」),因此您的 VPN 服務供應商也能監控您的網路活動。"</string>
- <string name="monitoring_description_profile_owned" msgid="2370062794285691713">"這個設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n您的管理員可以監控您的裝置和網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。\n\n如需詳細資訊,請與您的管理員聯絡。"</string>
- <string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"這個裝置由下列機構管理:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。\n\n如需詳細資訊,請與您的管理員聯絡。"</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"這個設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請與您的管理員聯絡。\n\n同時,由於您已授權「<xliff:g id="APPLICATION">%2$s</xliff:g>」設定 VPN 連線,因此這個應用程式也能監控您的網路活動。"</string>
- <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"這個設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請與您的管理員聯絡。\n\n同時,由於您的裝置已連線至 VPN (「<xliff:g id="APPLICATION">%2$s</xliff:g>」),因此您的 VPN 服務供應商也能監控您的網路活動。"</string>
- <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"這個裝置由下列機構管理:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請與您的管理員聯絡。\n\n同時,由於您已授權「<xliff:g id="APPLICATION">%3$s</xliff:g>」設定 VPN 連線,因此這個應用程式也能監控您的網路活動。"</string>
- <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"這個裝置由下列機構管理:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的設定檔由以下機構管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請與您的管理員聯絡。\n\n同時,由於您的裝置已連線至 VPN (「<xliff:g id="APPLICATION">%3$s</xliff:g>」),因此您的 VPN 服務供應商也能監控您的網路活動。"</string>
+ <string name="monitoring_description_profile_owned" msgid="2370062794285691713">"這個設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n您的管理員可以監控您的裝置和網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。\n\n如需詳細資訊,請洽您的管理員。"</string>
+ <string name="monitoring_description_device_and_profile_owned" msgid="8685301493845456293">"這個裝置由下列機構管理:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。\n\n如需詳細資訊,請洽您的管理員。"</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="847491346263295767">"這個設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請洽您的管理員。\n\n同時,由於您已授權「<xliff:g id="APPLICATION">%2$s</xliff:g>」設定 VPN 連線,因此這個應用程式也能監控您的網路活動。"</string>
+ <string name="monitoring_description_legacy_vpn_profile_owned" msgid="4095516964132237051">"這個設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION">%1$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請洽您的管理員。\n\n同時,由於您的裝置已連線至 VPN (「<xliff:g id="APPLICATION">%2$s</xliff:g>」),因此您的 VPN 服務供應商也能監控您的網路活動。"</string>
+ <string name="monitoring_description_vpn_device_and_profile_owned" msgid="9193588924767232909">"這個裝置由下列機構管理:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的設定檔由下列機構管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請洽您的管理員。\n\n同時,由於您已授權「<xliff:g id="APPLICATION">%3$s</xliff:g>」設定 VPN 連線,因此這個應用程式也能監控您的網路活動。"</string>
+ <string name="monitoring_description_legacy_vpn_device_and_profile_owned" msgid="6935475023447698473">"這個裝置由下列機構管理:\n<xliff:g id="ORGANIZATION_0">%1$s</xliff:g>\n您的設定檔由以下機構管理:\n<xliff:g id="ORGANIZATION_1">%2$s</xliff:g>\n\n您的管理員可以監控您的網路活動,包括收發電子郵件、使用應用程式和瀏覽安全網站。如需詳細資訊,請洽您的管理員。\n\n同時,由於您的裝置已連線至 VPN (「<xliff:g id="APPLICATION">%3$s</xliff:g>」),因此您的 VPN 服務供應商也能監控您的網路活動。"</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"在您手動解鎖前,裝置將保持鎖定狀態"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"更快取得通知"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"解鎖前顯示"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index edf51a1..abb6841 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -212,7 +212,10 @@
<string name="gps_notification_found_text" msgid="4619274244146446464">"Indawo ihlelwe i-GPS"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"Izicelo zendawo ziyasebenza"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
- <string name="status_bar_notification_inspect_item_title" msgid="5386295743469882227">"Izilungiselelo"</string>
+ <!-- no translation found for status_bar_notification_inspect_item_title (5668348142410115323) -->
+ <skip />
+ <!-- no translation found for status_bar_notification_app_settings_title (5525260160341558869) -->
+ <skip />
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Isikrini sikhiyelwe ngomumo we-landscape."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Isikrini sikhiyelwe ngomumo we-portrait."</string>
@@ -304,6 +307,7 @@
<string name="interruption_level_all" msgid="1330581184930945764">"Konke"</string>
<string name="keyguard_indication_charging_time" msgid="1757251776872835768">"Iyashaja (<xliff:g id="CHARGING_TIME_LEFT">%s</xliff:g> ize igcwale)"</string>
<string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Shintsha umsebenzisi"</string>
+ <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Shintsha umsebenzisi, umsebenzisi wamanje ngu-<xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
<string name="accessibility_multi_user_switch_quick_contact" msgid="3020367729287990475">"Bonisa iphrofayela"</string>
<string name="user_add_user" msgid="5110251524486079492">"Engeza umsebenzisi"</string>
<string name="user_new_user_name" msgid="426540612051178753">"Umsebenzisi omusha"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 5a1c318..f899572 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -191,11 +191,21 @@
<!-- Doze: maximum brightness to use when pulsing -->
<integer name="doze_pulse_brightness">40</integer>
- <!-- Doze: number of pulses when doing multiple pulses in quick succession -->
- <integer name="doze_multipulse_count">3</integer>
+ <!-- Doze: period of time between pulses (start of pulse) when following the notification light
+ Format: <under_ms>:<period_ms>,...,<default_ms> -->
+ <string name="doze_pulse_period_function">60000:10000,300000:30000,1800000:60000,0</string>
- <!-- Doze: interval between pulses when following the notification light -->
- <integer name="doze_notification_pulse_interval">30000</integer>
+ <!-- Doze: pulse parameter - how long does it take to fade in? -->
+ <integer name="doze_pulse_duration_in">1000</integer>
+
+ <!-- Doze: pulse parameter - once faded in, how long does it stay visible? -->
+ <integer name="doze_pulse_duration_visible">3000</integer>
+
+ <!-- Doze: pulse parameter - how long does it take to fade out? -->
+ <integer name="doze_pulse_duration_out">1000</integer>
+
+ <!-- Doze: pulse parameter - how long to wait before pulsing (if not starting immediately) -->
+ <integer name="doze_pulse_delay">1000</integer>
<!-- Doze: alpha to apply to small icons when dozing -->
<integer name="doze_small_icon_alpha">222</integer><!-- 87% of 0xff -->
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index d17e263..1183582 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -42,6 +42,7 @@
import com.android.systemui.R;
import com.android.systemui.SystemUIApplication;
+import com.android.systemui.statusbar.phone.DozeParameters;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -54,11 +55,11 @@
private static final String ACTION_BASE = "com.android.systemui.doze";
private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
private static final String NOTIFICATION_PULSE_ACTION = ACTION_BASE + ".notification_pulse";
- private static final String EXTRA_PULSES = "pulses";
private final String mTag = String.format(TAG + ".%08x", hashCode());
private final Context mContext = this;
private final Handler mHandler = new Handler();
+ private final DozeParameters mDozeParameters = new DozeParameters(mContext);
private Host mHost;
private SensorManager mSensors;
@@ -74,9 +75,8 @@
private int mDisplayStateWhenOn;
private boolean mNotificationLightOn;
private PendingIntent mNotificationPulseIntent;
- private int mMultipulseCount;
- private int mNotificationPulseInterval;
private boolean mPowerSaveActive;
+ private long mNotificationPulseTime;
public DozeService() {
if (DEBUG) Log.d(mTag, "new DozeService()");
@@ -94,9 +94,9 @@
pw.print(" mMaxBrightness: "); pw.println(mMaxBrightness);
pw.print(" mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
pw.print(" mNotificationLightOn: "); pw.println(mNotificationLightOn);
- pw.print(" mMultipulseCount: "); pw.println(mMultipulseCount);
- pw.print(" mNotificationPulseInterval: "); pw.println(mNotificationPulseInterval);
pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive);
+ pw.print(" mNotificationPulseTime: "); pw.println(mNotificationPulseTime);
+ mDozeParameters.dump(pw);
}
@Override
@@ -127,11 +127,7 @@
BRIGHTNESS_OFF, BRIGHTNESS_ON);
mNotificationPulseIntent = PendingIntent.getBroadcast(mContext, 0,
new Intent(NOTIFICATION_PULSE_ACTION).setPackage(getPackageName()),
- PendingIntent.FLAG_CANCEL_CURRENT);
- mMultipulseCount = SystemProperties.getInt("doze.multipulses",
- res.getInteger(R.integer.doze_multipulse_count));
- mNotificationPulseInterval = SystemProperties.getInt("doze.notification.pulse",
- res.getInteger(R.integer.doze_notification_pulse_interval));
+ PendingIntent.FLAG_UPDATE_CURRENT);
mDisplayStateWhenOn = mDisplayStateSupported ? Display.STATE_DOZE : Display.STATE_ON;
setDozeScreenState(mDisplayStateWhenOn);
}
@@ -159,6 +155,7 @@
public void stayAwake(long millis) {
if (mDreaming && millis > 0) {
+ if (DEBUG) Log.d(mTag, "stayAwake millis=" + millis);
mWakeLock.acquire(millis);
setDozeScreenState(mDisplayStateWhenOn);
setDozeScreenBrightness(mMaxBrightness);
@@ -218,21 +215,9 @@
}
}
- private void requestMultipulse() {
- requestPulse(mMultipulseCount);
- }
-
- private void requestPulse() {
- requestPulse(1);
- }
-
- private void requestPulse(int pulses) {
- requestPulse(pulses, true /*delayed*/);
- }
-
- private void requestPulse(int pulses, boolean delayed) {
+ private void requestPulse(boolean delayed) {
if (mHost != null) {
- mHost.requestPulse(pulses, delayed, this);
+ mHost.requestPulse(delayed, this);
}
}
@@ -281,9 +266,14 @@
private void rescheduleNotificationPulse() {
mAlarmManager.cancel(mNotificationPulseIntent);
if (mNotificationLightOn) {
- final long time = System.currentTimeMillis() + mNotificationPulseInterval;
- if (DEBUG) Log.d(TAG, "Scheduling pulse for " + new Date(time));
- mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent);
+ final long now = System.currentTimeMillis();
+ final long age = now - mNotificationPulseTime;
+ final long period = mDozeParameters.getPulsePeriod(age);
+ final long time = now + period;
+ if (period > 0) {
+ if (DEBUG) Log.d(TAG, "Scheduling pulse in " + period + " for " + new Date(time));
+ mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, time, mNotificationPulseIntent);
+ }
}
}
@@ -314,11 +304,11 @@
public void onReceive(Context context, Intent intent) {
if (PULSE_ACTION.equals(intent.getAction())) {
if (DEBUG) Log.d(mTag, "Received pulse intent");
- requestPulse(intent.getIntExtra(EXTRA_PULSES, mMultipulseCount));
+ requestPulse(false /*delayed*/);
}
if (NOTIFICATION_PULSE_ACTION.equals(intent.getAction())) {
if (DEBUG) Log.d(mTag, "Received notification pulse intent");
- requestPulse();
+ requestPulse(true /*delayed*/);
rescheduleNotificationPulse();
}
}
@@ -334,7 +324,8 @@
@Override
public void onBuzzBeepBlinked() {
if (DEBUG) Log.d(mTag, "onBuzzBeepBlinked");
- requestMultipulse();
+ mNotificationPulseTime = System.currentTimeMillis();
+ requestPulse(true /*delayed*/);
}
@Override
@@ -342,6 +333,10 @@
if (DEBUG) Log.d(mTag, "onNotificationLight on=" + on);
if (mNotificationLightOn == on) return;
mNotificationLightOn = on;
+ if (mNotificationLightOn) {
+ mNotificationPulseTime = System.currentTimeMillis();
+ requestPulse(true /*delayed*/);
+ }
rescheduleNotificationPulse();
}
@@ -358,7 +353,7 @@
void addCallback(Callback callback);
void removeCallback(Callback callback);
void requestDoze(DozeService dozeService);
- void requestPulse(int pulses, boolean delayed, DozeService dozeService);
+ void requestPulse(boolean delayed, DozeService dozeService);
void dozingStopped(DozeService dozeService);
boolean isPowerSaveActive();
@@ -409,7 +404,7 @@
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
}
}
- requestPulse(1, false /*delayed*/);
+ requestPulse(false /*delayed*/);
setListening(true); // reregister, this sensor only fires once
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 907a13f..ce3739c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -92,6 +92,7 @@
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
+import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
import com.android.systemui.statusbar.policy.PreviewInflater;
@@ -288,6 +289,10 @@
// close the shade if it was open
if (handled) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from mOnClickHandler after keyguard"
+ + "dismiss");
+ }
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
visibilityChanged(false);
}
@@ -334,6 +339,9 @@
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
if (BANNER_ACTION_SETUP.equals(action)) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Animating collapse because of BANNER_ACTION_SETUP");
+ }
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -759,6 +767,10 @@
}
}
});
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from startNotificationGutsIntent after keyguard"
+ + "dismiss");
+ }
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
return true;
}
@@ -857,6 +869,10 @@
// Assume we are a status_bar_notification_row
final NotificationGuts guts = (NotificationGuts) v.findViewById(
R.id.notification_guts);
+ if (guts == null) {
+ // This view has no guts. Examples are the more card or the dismiss all view
+ return false;
+ }
// Already showing?
if (guts.getVisibility() == View.VISIBLE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 2ad6859..9196dc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -406,7 +406,6 @@
target.animate().cancel();
source.animate()
.alpha(0f)
- .withLayer()
.setStartDelay(delay)
.setDuration(duration)
.withEndAction(new Runnable() {
@@ -417,7 +416,6 @@
});
target.animate()
.alpha(1f)
- .withLayer()
.setStartDelay(delay)
.setDuration(duration);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index e31eb7c..502490f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -243,6 +243,14 @@
}
}
+ @Override
+ public boolean hasOverlappingRendering() {
+
+ // This is not really true, but good enough when fading from the contracted to the expanded
+ // layout, and saves us some layers.
+ return false;
+ }
+
private static Paint createInvertPaint() {
final Paint p = new Paint();
final float[] invert = {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
new file mode 100644
index 0000000..e14ef12
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2014 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 android.content.Context;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.MathUtils;
+
+import com.android.systemui.R;
+
+import java.io.PrintWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DozeParameters {
+ private static final String TAG = "DozeParameters";
+
+ private static final int MAX_DURATION = 10 * 1000;
+
+ private final Context mContext;
+
+ private StepFunction mPulsePeriodFunction;
+
+ public DozeParameters(Context context) {
+ mContext = context;
+ }
+
+ public void dump(PrintWriter pw) {
+ pw.println(" DozeParameters:");
+ pw.print(" getPulseDuration(): "); pw.println(getPulseDuration());
+ pw.print(" getPulseInDuration(): "); pw.println(getPulseInDuration());
+ pw.print(" getPulseInVisibleDuration(): "); pw.println(getPulseVisibleDuration());
+ pw.print(" getPulseOutDuration(): "); pw.println(getPulseOutDuration());
+ pw.print(" getPulseStartDelay(): "); pw.println(getPulseStartDelay());
+ pw.print(" getPulsePeriodFunction(): "); pw.println(getPulsePeriodFunction());
+ }
+
+ public int getPulseDuration() {
+ return getPulseInDuration() + getPulseVisibleDuration() + getPulseOutDuration();
+ }
+
+ public int getPulseInDuration() {
+ return getInt("doze.pulse.duration.in", R.integer.doze_pulse_duration_in);
+ }
+
+ public int getPulseVisibleDuration() {
+ return getInt("doze.pulse.duration.visible", R.integer.doze_pulse_duration_visible);
+ }
+
+ public int getPulseOutDuration() {
+ return getInt("doze.pulse.duration.out", R.integer.doze_pulse_duration_out);
+ }
+
+ public int getPulseStartDelay() {
+ return getInt("doze.pulse.delay", R.integer.doze_pulse_delay);
+ }
+
+ public long getPulsePeriod(long age) {
+ final String spec = getPulsePeriodFunction();
+ if (mPulsePeriodFunction == null || !mPulsePeriodFunction.mSpec.equals(spec)) {
+ mPulsePeriodFunction = StepFunction.parse(spec);
+ }
+ return mPulsePeriodFunction != null ? mPulsePeriodFunction.evaluate(age) : 0;
+ }
+
+ private String getPulsePeriodFunction() {
+ return getString("doze.pulse.period.function", R.string.doze_pulse_period_function);
+ }
+
+ private int getInt(String propName, int resId) {
+ int value = SystemProperties.getInt(propName, mContext.getResources().getInteger(resId));
+ return MathUtils.constrain(value, 0, MAX_DURATION);
+ }
+
+ private String getString(String propName, int resId) {
+ return SystemProperties.get(propName, mContext.getString(resId));
+ }
+
+ private static class StepFunction {
+ private static final Pattern PATTERN = Pattern.compile("(\\d+?)(:(\\d+?))?", 0);
+
+ private String mSpec;
+ private long[] mSteps;
+ private long[] mValues;
+ private long mDefault;
+
+ public static StepFunction parse(String spec) {
+ if (TextUtils.isEmpty(spec)) return null;
+ try {
+ final StepFunction rt = new StepFunction();
+ rt.mSpec = spec;
+ final String[] tokens = spec.split(",");
+ rt.mSteps = new long[tokens.length - 1];
+ rt.mValues = new long[tokens.length - 1];
+ for (int i = 0; i < tokens.length - 1; i++) {
+ final Matcher m = PATTERN.matcher(tokens[i]);
+ if (!m.matches()) throw new IllegalArgumentException("Bad token: " + tokens[i]);
+ rt.mSteps[i] = Long.parseLong(m.group(1));
+ rt.mValues[i] = Long.parseLong(m.group(3));
+ }
+ rt.mDefault = Long.parseLong(tokens[tokens.length - 1]);
+ return rt;
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Error parsing spec: " + spec, e);
+ return null;
+ }
+ }
+
+ public long evaluate(long x) {
+ for (int i = 0; i < mSteps.length; i++) {
+ if (x < mSteps[i]) return mValues[i];
+ }
+ return mDefault;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index e84ca52..23f027b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -128,6 +128,9 @@
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (action == ACTION_CLICK) {
if (host == mLockIcon) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from lock icon accessibility click");
+ }
mPhoneStatusBar.animateCollapsePanels(
CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index fc737be..70b6952 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,14 +17,10 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
-import android.os.SystemClock;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardViewBase;
@@ -33,7 +29,7 @@
import com.android.systemui.keyguard.KeyguardViewMediator;
import static com.android.keyguard.KeyguardHostView.OnDismissAction;
-import static com.android.keyguard.KeyguardSecurityModel.*;
+import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
/**
* A class which manages the bouncer on the lockscreen.
@@ -62,6 +58,10 @@
public void show() {
ensureView();
if (mRoot.getVisibility() == View.VISIBLE) {
+
+ // show() updates the current security method. This is needed in case we are already
+ // showing and the current security method changed.
+ mKeyguardView.show();
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 9585e17..c04ca83 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -276,6 +276,7 @@
// Calculate quick setting heights.
mQsMinExpansionHeight = mKeyguardShowing ? 0 : mHeader.getCollapsedHeight() + mQsPeekHeight;
mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight();
+ positionClockAndNotifications();
if (mQsExpanded) {
if (mQsFullyExpanded) {
mQsExpansionHeight = mQsMaxExpansionHeight;
@@ -283,7 +284,6 @@
}
} else {
setQsExpansion(mQsMinExpansionHeight + mLastOverscroll);
- positionClockAndNotifications();
mNotificationStackScroller.setStackHeight(getExpandedHeight());
updateHeader();
}
@@ -631,9 +631,10 @@
}
private boolean isInQsArea(float x, float y) {
- return mStatusBarState != StatusBarState.SHADE
- || y <= mNotificationStackScroller.getBottomMostNotificationBottom()
- || y <= mQsContainer.getY() + mQsContainer.getHeight();
+ return mStatusBarState != StatusBarState.SHADE ||
+ (x >= mScrollView.getLeft() && x <= mScrollView.getRight()) &&
+ (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
+ || y <= mQsContainer.getY() + mQsContainer.getHeight());
}
private void handleQsDown(MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index f74d2f4..ccafbd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -140,6 +140,9 @@
mPanelHolder.setSelectedPanel(mTouchingPanel);
for (PanelView pv : mPanels) {
if (pv != panel) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing because opening another panel");
+ }
pv.collapse(false /* delayed */);
}
}
@@ -191,9 +194,15 @@
boolean waiting = false;
for (PanelView pv : mPanels) {
if (animate && !pv.isFullyCollapsed()) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Animating collapse, delayed");
+ }
pv.collapse(true /* delayed */);
waiting = true;
} else {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing without animation");
+ }
pv.resetViews();
pv.setExpandedFraction(0); // just in case
pv.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 2f21781..c3b263d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -134,6 +134,9 @@
}
private void runPeekAnimation() {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Starting peek animation");
+ }
mPeekHeight = getPeekHeight();
if (DEBUG) logf("peek to height=%.1f", mPeekHeight);
if (mHeightAnimator != null) {
@@ -154,9 +157,15 @@
public void onAnimationEnd(Animator animation) {
mPeekAnimator = null;
if (mCollapseAfterPeek && !mCancelled) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Peek animation finished, posting collapse");
+ }
postOnAnimation(new Runnable() {
@Override
public void run() {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Peek animation finished, collapsing");
+ }
collapse(false /* delayed */);
}
});
@@ -330,6 +339,9 @@
}
boolean expand = flingExpands(vel, vectorVel);
onTrackingStopped(expand);
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Flinging: expand=" + expand);
+ }
fling(vel, expand);
mUpdateFlingOnLayout = expand && mPanelClosedOnDown && !mHasLayoutedSinceDown;
if (mUpdateFlingOnLayout) {
@@ -510,6 +522,9 @@
notifyExpandingFinished();
return;
}
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Executing fling: expand=" + expand + " vel=" + vel);
+ }
mOverExpandedBeforeFling = getOverExpansionAmount() > 0f;
ValueAnimator animator = createHeightAnimator(target);
if (expand) {
@@ -691,18 +706,29 @@
mClosing = true;
notifyExpandingStarted();
if (delayed) {
- postDelayed(new Runnable() {
- @Override
- public void run() {
- fling(0, false /* expand */);
- }
- }, 120);
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Posting collapse runnable, will be run in 120ms");
+ }
+ postDelayed(mFlingCollapseRunnable, 120);
} else {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Animating collapsing now");
+ }
fling(0, false /* expand */);
}
}
}
+ private final Runnable mFlingCollapseRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Executing collapse runnable, animating collapsing now");
+ }
+ fling(0, false /* expand */);
+ }
+ };
+
public void expand() {
if (DEBUG) logf("expand: " + this);
if (isFullyCollapsed()) {
@@ -727,8 +753,15 @@
}
public void instantExpand() {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Before instant expanding"
+ + " mTracking=" + mTracking
+ + " mExpanding=" + mExpanding);
+ }
mInstantExpanding = true;
+ mUpdateFlingOnLayout = false;
abortAnimations();
+ cancelPeek();
if (mTracking) {
onTrackingStopped(true /* expands */); // The panel is expanded after this call.
}
@@ -745,6 +778,11 @@
public void onGlobalLayout() {
if (mStatusBar.getStatusBarWindow().getHeight()
!= mStatusBar.getStatusBarHeight()) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Now instant expanding after layout"
+ + " mTracking=" + mTracking
+ + " mExpanding=" + mExpanding);
+ }
getViewTreeObserver().removeOnGlobalLayoutListener(this);
setExpandedFraction(1f);
mInstantExpanding = false;
@@ -761,6 +799,8 @@
if (mHeightAnimator != null) {
mHeightAnimator.cancel();
}
+ removeCallbacks(mPostCollapseRunnable);
+ removeCallbacks(mFlingCollapseRunnable);
}
protected void startUnlockHintAnimation() {
@@ -889,6 +929,9 @@
private final Runnable mPostCollapseRunnable = new Runnable() {
@Override
public void run() {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing after middle clicked");
+ }
collapse(false /* delayed */);
}
};
@@ -901,6 +944,9 @@
mStatusBar.goToKeyguard();
return true;
case StatusBarState.SHADE:
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Middle clicked in shade state, posting collapsing runnable");
+ }
// This gets called in the middle of the touch handling, where the state is still
// that we are tracking the panel. Collapse the panel after this is done.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 5d4c831..fd60ac4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -177,6 +177,7 @@
public static final boolean DEBUG_GESTURES = false;
public static final boolean DEBUG_MEDIA = false;
public static final boolean DEBUG_MEDIA_FAKE_ARTWORK = false;
+ public static final boolean DEBUG_EMPTY_KEYGUARD = true;
public static final boolean DEBUG_WINDOW_STATE = false;
@@ -2238,6 +2239,11 @@
mStatusBarWindowManager.setStatusBarFocusable(false);
mStatusBarWindow.cancelExpandHelper();
+ if (DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from animateCollapsePanels:"
+ + " force=" + force
+ + " mState=" + mState);
+ }
mStatusBarView.collapseAllPanels(true);
}
}
@@ -2325,6 +2331,9 @@
}
public void animateCollapseQuickSettings() {
+ if (DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from animateCollapseQuickSettings");
+ }
mStatusBarView.collapseAllPanels(true);
}
@@ -2337,6 +2346,9 @@
}
// Ensure the panel is fully collapsed (just in case; bug 6765842, 7260868)
+ if (DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from makeExpandedInvisible");
+ }
mStatusBarView.collapseAllPanels(/*animate=*/ false);
// reset things to their proper state
@@ -2430,6 +2442,9 @@
mStatusBarWindowState = state;
if (DEBUG_WINDOW_STATE) Log.d(TAG, "Status bar " + windowStateToString(state));
if (!showing) {
+ if (DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from setWindowState");
+ }
mStatusBarView.collapseAllPanels(false);
}
}
@@ -2987,6 +3002,10 @@
}
});
if (dismissShade) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel startActivityDismissKeyguard after keyguard"
+ + "dismiss");
+ }
animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
}
return true;
@@ -3654,6 +3673,9 @@
public boolean onSpacePressed() {
if (mScreenOn != null && mScreenOn
&& (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED)) {
+ if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD) {
+ Log.i(TAG, "Collapsing panel from onSpacePressed");
+ }
animateCollapsePanels(0 /* flags */, true /* force */);
return true;
}
@@ -3949,7 +3971,8 @@
}
public void wakeUpIfDozing(long time) {
- if (mDozeServiceHost != null && mDozeServiceHost.isDozing()) {
+ if (mDozeServiceHost != null && mDozeServiceHost.isDozing()
+ && mScrimController.isPulsing()) {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
pm.wakeUp(time);
}
@@ -4045,10 +4068,10 @@
}
@Override
- public void requestPulse(int pulses, boolean delayed, DozeService dozeService) {
+ public void requestPulse(boolean delayed, DozeService dozeService) {
if (dozeService == null) return;
dozeService.stayAwake(PROCESSING_TIME);
- mHandler.obtainMessage(H.REQUEST_PULSE, pulses, delayed ? 1 : 0, dozeService)
+ mHandler.obtainMessage(H.REQUEST_PULSE, delayed ? 1 : 0, 0, dozeService)
.sendToTarget();
}
@@ -4073,9 +4096,9 @@
mCurrentDozeService.startDozing();
}
- private void handleRequestPulse(int pulses, boolean delayed, DozeService dozeService) {
+ private void handleRequestPulse(boolean delayed, DozeService dozeService) {
if (!dozeService.equals(mCurrentDozeService)) return;
- final long stayAwake = mScrimController.pulse(pulses, delayed);
+ final long stayAwake = mScrimController.pulse(delayed);
mCurrentDozeService.stayAwake(stayAwake);
}
@@ -4099,7 +4122,7 @@
if (msg.what == REQUEST_DOZE) {
handleRequestDoze((DozeService) msg.obj);
} else if (msg.what == REQUEST_PULSE) {
- handleRequestPulse(msg.arg1, msg.arg2 != 0, (DozeService) msg.obj);
+ handleRequestPulse(msg.arg1 != 0, (DozeService) msg.obj);
} else if (msg.what == DOZING_STOPPED) {
handleDozingStopped((DozeService) msg.obj);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index be48df7..57e5755 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -19,6 +19,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
@@ -36,7 +37,7 @@
*/
public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
private static final String TAG = "ScrimController";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
public static final long ANIMATION_DURATION = 220;
@@ -46,17 +47,10 @@
private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
private static final int TAG_KEY_ANIM = R.id.scrim;
- private static final long PULSE_IN_ANIMATION_DURATION = 1000;
- private static final long PULSE_VISIBLE_DURATION = 3000;
- private static final long PULSE_OUT_ANIMATION_DURATION = 1000;
- private static final long PULSE_INVISIBLE_DURATION = 1000;
- private static final long PULSE_DURATION = PULSE_IN_ANIMATION_DURATION
- + PULSE_VISIBLE_DURATION + PULSE_OUT_ANIMATION_DURATION + PULSE_INVISIBLE_DURATION;
- private static final long PRE_PULSE_DELAY = 1000;
-
private final View mScrimBehind;
private final View mScrimInFront;
private final UnlockMethodCache mUnlockMethodCache;
+ private final DozeParameters mDozeParameters;
private boolean mKeyguardShowing;
private float mFraction;
@@ -72,16 +66,18 @@
private Runnable mOnAnimationFinished;
private boolean mAnimationStarted;
private boolean mDozing;
- private int mPulsesRemaining;
+ private long mPulseEndTime;
private final Interpolator mInterpolator = new DecelerateInterpolator();
private final Interpolator mLinearOutSlowInInterpolator;
public ScrimController(View scrimBehind, View scrimInFront) {
mScrimBehind = scrimBehind;
mScrimInFront = scrimInFront;
- mUnlockMethodCache = UnlockMethodCache.getInstance(scrimBehind.getContext());
- mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(scrimBehind.getContext(),
+ final Context context = scrimBehind.getContext();
+ mUnlockMethodCache = UnlockMethodCache.getInstance(context);
+ mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
android.R.interpolator.linear_out_slow_in);
+ mDozeParameters = new DozeParameters(context);
}
public void setKeyguardShowing(boolean showing) {
@@ -137,19 +133,28 @@
scheduleUpdate();
}
- /** When dozing, fade screen contents in and out a few times using the front scrim. */
- public long pulse(int pulses, boolean delayed) {
+ /** When dozing, fade screen contents in and out using the front scrim. */
+ public long pulse(boolean delayed) {
if (!mDozing) return 0;
- mPulsesRemaining = Math.max(pulses, mPulsesRemaining);
- final long delay = delayed ? PRE_PULSE_DELAY : 0;
+ final long now = System.currentTimeMillis();
+ if (DEBUG) Log.d(TAG, "pulse delayed=" + delayed + " mPulseEndTime=" + mPulseEndTime
+ + " now=" + now);
+ if (mPulseEndTime != 0 && mPulseEndTime > now) return mPulseEndTime - now;
+ final long delay = delayed ? mDozeParameters.getPulseStartDelay() : 0;
mScrimInFront.postDelayed(mPulseIn, delay);
- return delay + mPulsesRemaining * PULSE_DURATION;
+ mPulseEndTime = now + delay + mDozeParameters.getPulseDuration();
+ return mPulseEndTime - now;
+ }
+
+ public boolean isPulsing() {
+ return mDozing && mPulseEndTime != 0;
}
private void cancelPulsing() {
- mPulsesRemaining = 0;
+ if (DEBUG) Log.d(TAG, "Cancel pulsing");
mScrimInFront.removeCallbacks(mPulseIn);
mScrimInFront.removeCallbacks(mPulseOut);
+ mPulseEndTime = 0;
}
private void scheduleUpdate() {
@@ -302,11 +307,9 @@
private final Runnable mPulseIn = new Runnable() {
@Override
public void run() {
- if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing
- + " mPulsesRemaining=" + mPulsesRemaining);
- if (!mDozing || mPulsesRemaining == 0) return;
- mPulsesRemaining--;
- mDurationOverride = PULSE_IN_ANIMATION_DURATION;
+ if (DEBUG) Log.d(TAG, "Pulse in, mDozing=" + mDozing);
+ if (!mDozing) return;
+ mDurationOverride = mDozeParameters.getPulseInDuration();
mAnimationDelay = 0;
mAnimateChange = true;
mOnAnimationFinished = mPulseInFinished;
@@ -319,7 +322,7 @@
public void run() {
if (DEBUG) Log.d(TAG, "Pulse in finished, mDozing=" + mDozing);
if (!mDozing) return;
- mScrimInFront.postDelayed(mPulseOut, PULSE_VISIBLE_DURATION);
+ mScrimInFront.postDelayed(mPulseOut, mDozeParameters.getPulseVisibleDuration());
}
};
@@ -328,7 +331,7 @@
public void run() {
if (DEBUG) Log.d(TAG, "Pulse out, mDozing=" + mDozing);
if (!mDozing) return;
- mDurationOverride = PULSE_OUT_ANIMATION_DURATION;
+ mDurationOverride = mDozeParameters.getPulseOutDuration();
mAnimationDelay = 0;
mAnimateChange = true;
mOnAnimationFinished = mPulseOutFinished;
@@ -339,10 +342,8 @@
private final Runnable mPulseOutFinished = new Runnable() {
@Override
public void run() {
- if (DEBUG) Log.d(TAG, "Pulse out finished, mPulsesRemaining=" + mPulsesRemaining);
- if (mPulsesRemaining > 0) {
- mScrimInFront.postDelayed(mPulseIn, PULSE_INVISIBLE_DURATION);
- }
+ if (DEBUG) Log.d(TAG, "Pulse out finished");
+ mPulseEndTime = 0;
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index a5217ab..42cfd39 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -100,6 +100,11 @@
if (!down) {
return mService.onSpacePressed();
}
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ if (down) {
+ mService.wakeUpIfDozing(event.getEventTime());
+ }
}
if (mService.interceptMediaKey(event)) {
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 5088089..4d248c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -337,7 +337,9 @@
@Override
public DataUsageInfo getDataUsageInfo() {
final DataUsageInfo info = mMobileDataController.getDataUsageInfo();
- info.carrier = mNetworkName;
+ if (info != null) {
+ info.carrier = mNetworkName;
+ }
return info;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index ece82a1..a69390e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -166,7 +166,7 @@
boolean hasDelays = mAnimationFilter.hasDelays;
boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
alphaChanging || heightChanging || topInsetChanging;
- boolean noAnimation = wasAdded && !mAnimationFilter.hasGoToFullShadeEvent;
+ boolean noAnimation = wasAdded;
long delay = 0;
long duration = mCurrentLength;
if (hasDelays && isDelayRelevant || wasAdded) {
@@ -184,7 +184,7 @@
// start translationY animation
if (yTranslationChanging) {
- if (noAnimation) {
+ if (noAnimation && !mAnimationFilter.hasGoToFullShadeEvent) {
child.setTranslationY(viewState.yTranslation);
} else {
startYTranslationAnimation(child, viewState, duration, delay);
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index cce30c7..f802e1e 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -124,6 +124,7 @@
private static final int CUSTOM_TITLE_COMPATIBLE_FEATURES = DEFAULT_FEATURES |
(1 << FEATURE_CUSTOM_TITLE) |
(1 << FEATURE_CONTENT_TRANSITIONS) |
+ (1 << FEATURE_ACTIVITY_TRANSITIONS) |
(1 << FEATURE_ACTION_MODE_OVERLAY);
private static final Transition USE_DEFAULT_TRANSITION = new TransitionSet();
@@ -3207,6 +3208,9 @@
if (a.getBoolean(R.styleable.Window_windowContentTransitions, false)) {
requestFeature(FEATURE_CONTENT_TRANSITIONS);
}
+ if (a.getBoolean(R.styleable.Window_windowActivityTransitions, false)) {
+ requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
+ }
final WindowManager windowService = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE);
@@ -3516,7 +3520,7 @@
// Only inflate or create a new TransitionManager if the caller hasn't
// already set a custom one.
- if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
+ if (hasFeature(FEATURE_ACTIVITY_TRANSITIONS)) {
if (mTransitionManager == null) {
final int transitionRes = getWindowStyle().getResourceId(
R.styleable.Window_windowContentTransitionManager,
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 16bb00b..5874f63 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -439,6 +439,7 @@
WindowState mTopFullscreenOpaqueWindowState;
HashSet<IApplicationToken> mAppsToBeHidden = new HashSet<IApplicationToken>();
+ HashSet<IApplicationToken> mAppsThatDismissKeyguard = new HashSet<IApplicationToken>();
boolean mTopIsFullscreen;
boolean mForceStatusBar;
boolean mForceStatusBarFromKeyguard;
@@ -1758,6 +1759,11 @@
}
}
+ @Override
+ public WindowState getWinShowWhenLockedLw() {
+ return mWinShowWhenLocked;
+ }
+
/** {@inheritDoc} */
@Override
public View addStartingWindow(IBinder appToken, String packageName, int theme,
@@ -1826,8 +1832,6 @@
params.packageName = packageName;
params.windowAnimations = win.getWindowStyle().getResourceId(
com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
- params.privateFlags |=
- WindowManager.LayoutParams.PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED;
params.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
if (!compatInfo.supportsScreen()) {
@@ -3753,6 +3757,7 @@
public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
mTopFullscreenOpaqueWindowState = null;
mAppsToBeHidden.clear();
+ mAppsThatDismissKeyguard.clear();
mForceStatusBar = false;
mForceStatusBarFromKeyguard = false;
mForcingShowNavBar = false;
@@ -3793,7 +3798,7 @@
mShowingLockscreen = true;
}
boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
- && attrs.type <= LAST_APPLICATION_WINDOW;
+ && attrs.type < FIRST_SYSTEM_WINDOW;
if (attrs.type == TYPE_DREAM) {
// If the lockscreen was showing when the dream started then wait
// for the dream to draw before hiding the lockscreen.
@@ -3808,38 +3813,44 @@
final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
final boolean secureKeyguard = isKeyguardSecure();
if (appWindow) {
- if (showWhenLocked || (dismissKeyguard && !secureKeyguard)) {
+ final IApplicationToken appToken = win.getAppToken();
+ if (showWhenLocked) {
// Remove any previous windows with the same appToken.
- mAppsToBeHidden.remove(win.getAppToken());
- if (mAppsToBeHidden.isEmpty() && showWhenLocked &&
- isKeyguardSecureIncludingHidden()) {
+ mAppsToBeHidden.remove(appToken);
+ mAppsThatDismissKeyguard.remove(appToken);
+ if (mAppsToBeHidden.isEmpty() && isKeyguardSecureIncludingHidden()) {
mWinShowWhenLocked = win;
mHideLockScreen = true;
mForceStatusBarFromKeyguard = false;
}
+ } else if (dismissKeyguard) {
+ if (secureKeyguard) {
+ mAppsToBeHidden.add(appToken);
+ } else {
+ mAppsToBeHidden.remove(appToken);
+ }
+ mAppsThatDismissKeyguard.add(appToken);
} else {
- mAppsToBeHidden.add(win.getAppToken());
+ mAppsToBeHidden.add(appToken);
}
if (attrs.x == 0 && attrs.y == 0
&& attrs.width == WindowManager.LayoutParams.MATCH_PARENT
&& attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
mTopFullscreenOpaqueWindowState = win;
- if (mAppsToBeHidden.isEmpty()) {
- if (showWhenLocked) {
- if (DEBUG_LAYOUT) Slog.v(TAG,
- "Setting mHideLockScreen to true by win " + win);
- mHideLockScreen = true;
- mForceStatusBarFromKeyguard = false;
- }
- if (dismissKeyguard && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
- if (DEBUG_LAYOUT) Slog.v(TAG,
- "Setting mDismissKeyguard true by win " + win);
- mDismissKeyguard = mWinDismissingKeyguard == win ?
- DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
- mWinDismissingKeyguard = win;
- mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard;
- }
+ if (!mAppsThatDismissKeyguard.isEmpty() &&
+ mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ "Setting mDismissKeyguard true by win " + win);
+ mDismissKeyguard = mWinDismissingKeyguard == win ?
+ DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
+ mWinDismissingKeyguard = win;
+ mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard;
+ } else if (mAppsToBeHidden.isEmpty() && showWhenLocked) {
+ if (DEBUG_LAYOUT) Slog.v(TAG,
+ "Setting mHideLockScreen to true by win " + win);
+ mHideLockScreen = true;
+ mForceStatusBarFromKeyguard = false;
}
if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
mAllowLockscreenWhenOn = true;
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index e9419ad..b04cc19 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -1535,7 +1535,7 @@
for (int i=0; i<triggerList.size(); i++) {
Alarm alarm = triggerList.get(i);
try {
- if (localLOGV) Slog.v(TAG, "sending alarm " + alarm);
+ Slog.v(TAG, "sending alarm " + alarm);
alarm.operation.send(getContext(), 0,
mBackgroundIntent.putExtra(
Intent.EXTRA_ALARM_COUNT, alarm.count),
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 3062a92..75090db 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -4746,6 +4746,11 @@
private void updateNetworkScore(NetworkAgentInfo nai, int score) {
if (DBG) log("updateNetworkScore for " + nai.name() + " to " + score);
+ if (score < 0) {
+ loge("updateNetworkScore for " + nai.name() + " got a negative score (" + score +
+ "). Bumping score to min of 0");
+ score = 0;
+ }
nai.currentScore = score;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a9a4732..2885b83 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -180,6 +180,7 @@
import android.os.SystemProperties;
import android.os.UpdateLock;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.text.format.DateUtils;
import android.text.format.Time;
@@ -888,6 +889,8 @@
boolean mProcessesReady = false;
boolean mSystemReady = false;
boolean mBooting = false;
+ boolean mCallFinishBooting = false;
+ boolean mBootAnimationComplete = false;
boolean mWaitingUpdate = false;
boolean mDidUpdate = false;
boolean mOnBattery = false;
@@ -1075,13 +1078,16 @@
/**
* Runtime CPU use collection thread. This object's lock is used to
- * protect all related state.
+ * perform synchronization with the thread (notifying it to run).
*/
final Thread mProcessCpuThread;
/**
- * Used to collect process stats when showing not responding dialog.
- * Protected by mProcessCpuThread.
+ * Used to collect per-process CPU use for ANRs, battery stats, etc.
+ * Must acquire this object's lock when accessing it.
+ * NOTE: this lock will be held while doing long operations (trawling
+ * through all processes in /proc), so it should never be acquired by
+ * any critical paths such as when holding the main activity manager lock.
*/
final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
MONITOR_THREAD_CPU_USAGE);
@@ -1595,7 +1601,7 @@
infoMap.put(mi.pid, mi);
}
updateCpuStatsNow();
- synchronized (mProcessCpuThread) {
+ synchronized (mProcessCpuTracker) {
final int N = mProcessCpuTracker.countStats();
for (int i=0; i<N; i++) {
ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
@@ -1894,7 +1900,7 @@
if (memInfo != null) {
updateCpuStatsNow();
long nativeTotalPss = 0;
- synchronized (mProcessCpuThread) {
+ synchronized (mProcessCpuTracker) {
final int N = mProcessCpuTracker.countStats();
for (int j=0; j<N; j++) {
ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
@@ -1912,7 +1918,7 @@
}
}
memInfo.readMemInfo();
- synchronized (this) {
+ synchronized (ActivityManagerService.this) {
if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
+ (SystemClock.uptimeMillis()-start) + "ms");
mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
@@ -2183,7 +2189,7 @@
return;
}
- synchronized (mActivityManagerService.mProcessCpuThread) {
+ synchronized (mActivityManagerService.mProcessCpuTracker) {
pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
SystemClock.uptimeMillis()));
@@ -2379,7 +2385,7 @@
}
void updateCpuStatsNow() {
- synchronized (mProcessCpuThread) {
+ synchronized (mProcessCpuTracker) {
mProcessCpuMutexFree.set(false);
final long now = SystemClock.uptimeMillis();
boolean haveNewCpuStats = false;
@@ -3364,6 +3370,16 @@
}
}
+ void enforceShellRestriction(String restriction, int userHandle) {
+ if (Binder.getCallingUid() == Process.SHELL_UID) {
+ if (userHandle < 0
+ || mUserManager.hasUserRestriction(restriction, userHandle)) {
+ throw new SecurityException("Shell does not have permission to access user "
+ + userHandle);
+ }
+ }
+ }
+
@Override
public int getFrontActivityScreenCompatMode() {
enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
@@ -5074,7 +5090,7 @@
String cpuInfo = null;
if (MONITOR_CPU_USAGE) {
updateCpuStatsNow();
- synchronized (mProcessCpuThread) {
+ synchronized (mProcessCpuTracker) {
cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
}
info.append(processCpuTracker.printCurrentLoad());
@@ -6195,6 +6211,14 @@
}
final void finishBooting() {
+ synchronized (this) {
+ if (!mBootAnimationComplete) {
+ mCallFinishBooting = true;
+ return;
+ }
+ mCallFinishBooting = false;
+ }
+
// Register receivers to handle package update events
mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
@@ -6253,6 +6277,18 @@
}
}
+ @Override
+ public void bootAnimationComplete() {
+ final boolean callFinishBooting;
+ synchronized (this) {
+ callFinishBooting = mCallFinishBooting;
+ mBootAnimationComplete = true;
+ }
+ if (callFinishBooting) {
+ finishBooting();
+ }
+ }
+
final void ensureBootCompleted() {
boolean booting;
boolean enableScreen;
@@ -7446,12 +7482,33 @@
// Does the caller have this permission on the URI?
if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
- // Right now, if you are not the original owner of the permission,
- // you are not allowed to revoke it.
- //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
- throw new SecurityException("Uid " + callingUid
- + " does not have permission to uri " + grantUri);
- //}
+ // Have they don't have direct access to the URI, then revoke any URI
+ // permissions that have been granted to them.
+ final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
+ if (perms != null) {
+ boolean persistChanged = false;
+ for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
+ final UriPermission perm = it.next();
+ if (perm.uri.sourceUserId == grantUri.sourceUserId
+ && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
+ if (DEBUG_URI_PERMISSION)
+ Slog.v(TAG,
+ "Revoking " + perm.targetUid + " permission to " + perm.uri);
+ persistChanged |= perm.revokeModes(
+ modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
+ if (perm.modeFlags == 0) {
+ it.remove();
+ }
+ }
+ }
+ if (perms.isEmpty()) {
+ mGrantedUriPermissions.remove(callingUid);
+ }
+ if (persistChanged) {
+ schedulePersistUriGrants();
+ }
+ }
+ return;
}
boolean persistChanged = false;
@@ -9665,14 +9722,9 @@
long ident = 0;
boolean clearedIdentity = false;
userId = unsafeConvertIncomingUser(userId);
- if (UserHandle.getUserId(callingUid) != userId) {
- if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
- callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
- || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
- callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
- clearedIdentity = true;
- ident = Binder.clearCallingIdentity();
- }
+ if (canClearIdentity(callingPid, callingUid, userId)) {
+ clearedIdentity = true;
+ ident = Binder.clearCallingIdentity();
}
ContentProviderHolder holder = null;
try {
@@ -9700,6 +9752,19 @@
return null;
}
+ private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
+ if (UserHandle.getUserId(callingUid) == userId) {
+ return true;
+ }
+ if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
+ callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
+ || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
+ callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+ return false;
+ }
+
// =========================================================
// GLOBAL MANAGEMENT
// =========================================================
@@ -13700,7 +13765,7 @@
findPid = Integer.parseInt(args[opti]);
} catch (NumberFormatException e) {
}
- synchronized (mProcessCpuThread) {
+ synchronized (mProcessCpuTracker) {
final int N = mProcessCpuTracker.countStats();
for (int i=0; i<N; i++) {
ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
@@ -13862,7 +13927,7 @@
// If we are showing aggregations, also look for native processes to
// include so that our aggregations are more accurate.
updateCpuStatsNow();
- synchronized (mProcessCpuThread) {
+ synchronized (mProcessCpuTracker) {
final int N = mProcessCpuTracker.countStats();
for (int i=0; i<N; i++) {
ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
@@ -14548,6 +14613,14 @@
throw new IllegalArgumentException(
"Call does not support special user #" + targetUserId);
}
+ // Check shell permission
+ if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
+ if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
+ targetUserId)) {
+ throw new SecurityException("Shell does not have permission to access user "
+ + targetUserId + "\n " + Debug.getCallers(3));
+ }
+ }
return targetUserId;
}
@@ -14572,13 +14645,10 @@
}
} else if ("system".equals(componentProcessName)) {
result = true;
- } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
- && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
- // Phone app is allowed to export singleuser providers.
- result = true;
- } else {
- // App with pre-defined UID, check if it's a persistent app
- result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
+ } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
+ // Phone app and persistent apps are allowed to export singleuser providers.
+ result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
+ || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
}
if (DEBUG_MU) {
Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
@@ -14606,6 +14676,7 @@
Intent service, String resolvedType,
IServiceConnection connection, int flags, int userId) {
enforceNotIsolatedCaller("bindService");
+
// Refuse possible leaked file descriptors
if (service != null && service.hasFileDescriptors() == true) {
throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -15040,12 +15111,18 @@
}
private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
- int[] users) {
+ int callingUid, int[] users) {
List<ResolveInfo> receivers = null;
try {
HashSet<ComponentName> singleUserReceivers = null;
boolean scannedFirstReceivers = false;
for (int user : users) {
+ // Skip users that have Shell restrictions
+ if (callingUid == Process.SHELL_UID
+ && getUserManagerLocked().hasUserRestriction(
+ UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
+ continue;
+ }
List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
.queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
if (user != 0 && newReceivers != null) {
@@ -15134,7 +15211,6 @@
// Make sure that the user who is receiving this broadcast is started.
// If not, we will just skip it.
-
if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
& Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
@@ -15399,11 +15475,30 @@
// Need to resolve the intent to interested receivers...
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
- receivers = collectReceiverComponents(intent, resolvedType, users);
+ receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
}
if (intent.getComponent() == null) {
- registeredReceivers = mReceiverResolver.queryIntent(intent,
- resolvedType, false, userId);
+ if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
+ // Query one target user at a time, excluding shell-restricted users
+ UserManagerService ums = getUserManagerLocked();
+ for (int i = 0; i < users.length; i++) {
+ if (ums.hasUserRestriction(
+ UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
+ continue;
+ }
+ List<BroadcastFilter> registeredReceiversForUser =
+ mReceiverResolver.queryIntent(intent,
+ resolvedType, false, users[i]);
+ if (registeredReceivers == null) {
+ registeredReceivers = registeredReceiversForUser;
+ } else if (registeredReceiversForUser != null) {
+ registeredReceivers.addAll(registeredReceiversForUser);
+ }
+ }
+ } else {
+ registeredReceivers = mReceiverResolver.queryIntent(intent,
+ resolvedType, false, userId);
+ }
}
final boolean replacePending =
@@ -15565,7 +15660,7 @@
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
-
+
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
@@ -17973,6 +18068,7 @@
@Override
public boolean switchUser(final int userId) {
+ enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
String userName;
synchronized (this) {
UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
@@ -18414,6 +18510,7 @@
if (userId <= 0) {
throw new IllegalArgumentException("Can't stop primary user " + userId);
}
+ enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
synchronized (this) {
return stopUserLocked(userId, callback);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index bcf3b17..d71f94e 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1042,11 +1042,8 @@
if (prev.app != null && prev.cpuTimeAtResume > 0
&& mService.mBatteryStatsService.isOnBattery()) {
- long diff;
- synchronized (mService.mProcessCpuThread) {
- diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
- - prev.cpuTimeAtResume;
- }
+ long diff = mService.mProcessCpuTracker.getCpuTimeForPid(prev.app.pid)
+ - prev.cpuTimeAtResume;
if (diff > 0) {
BatteryStatsImpl bsi = mService.mBatteryStatsService.getActiveStatistics();
synchronized (bsi) {
@@ -1097,9 +1094,7 @@
// TODO: To be more accurate, the mark should be before the onCreate,
// not after the onResume. But for subsequent starts, onResume is fine.
if (next.app != null) {
- synchronized (mService.mProcessCpuThread) {
- next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid);
- }
+ next.cpuTimeAtResume = mService.mProcessCpuTracker.getCpuTimeForPid(next.app.pid);
} else {
next.cpuTimeAtResume = 0; // Couldn't get the cpu time of process
}
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 3cc406b..b21af48 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -347,6 +347,10 @@
private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) {
if (DEBUG) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds=" + persistentTaskIds +
" files=" + files);
+ if (files == null) {
+ Slog.e(TAG, "File error accessing recents directory (too many files open?).");
+ return;
+ }
for (int fileNdx = 0; fileNdx < files.length; ++fileNdx) {
File file = files[fileNdx];
String filename = file.getName();
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index f6beb9a..9292d45 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -16,6 +16,7 @@
package com.android.server.content;
+import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountAndUser;
import android.accounts.AccountManager;
@@ -478,7 +479,7 @@
mContext.registerReceiverAsUser(mAccountsUpdatedReceiver,
UserHandle.ALL,
new IntentFilter(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION),
- null, null);
+ Manifest.permission.ACCOUNT_MANAGER, null);
}
// Pick a random second in a day to seed all periodic syncs
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index f6399a3..a6a9a89 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -69,7 +69,7 @@
try {
if (projection != null) {
- projection.addCallback(new MediaProjectionCallback(appToken));
+ projection.registerCallback(new MediaProjectionCallback(appToken));
}
appToken.linkToDeath(device, 0);
} catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 5cd7c01..3d0fd3f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -43,7 +43,7 @@
import android.hardware.hdmi.IHdmiDeviceEventListener;
import android.hardware.hdmi.IHdmiHotplugEventListener;
import android.hardware.hdmi.IHdmiInputChangeListener;
-import android.hardware.hdmi.IHdmiMhlScratchpadCommandListener;
+import android.hardware.hdmi.IHdmiMhlVendorCommandListener;
import android.hardware.hdmi.IHdmiRecordListener;
import android.hardware.hdmi.IHdmiSystemAudioModeChangeListener;
import android.hardware.hdmi.IHdmiVendorCommandListener;
@@ -247,10 +247,10 @@
@GuardedBy("mLock")
private boolean mMhlInputChangeEnabled;
- // List of records for MHL Scratchpad command listener to handle the caller killed in action.
+ // List of records for MHL Vendor command listener to handle the caller killed in action.
@GuardedBy("mLock")
- private final ArrayList<HdmiMhlScratchpadCommandListenerRecord>
- mScratchpadCommandListenerRecords = new ArrayList<>();
+ private final ArrayList<HdmiMhlVendorCommandListenerRecord>
+ mMhlVendorCommandListenerRecords = new ArrayList<>();
@GuardedBy("mLock")
private List<HdmiDeviceInfo> mMhlDevices;
@@ -928,16 +928,16 @@
return mMhlDevices;
}
- private class HdmiMhlScratchpadCommandListenerRecord implements IBinder.DeathRecipient {
- private final IHdmiMhlScratchpadCommandListener mListener;
+ private class HdmiMhlVendorCommandListenerRecord implements IBinder.DeathRecipient {
+ private final IHdmiMhlVendorCommandListener mListener;
- public HdmiMhlScratchpadCommandListenerRecord(IHdmiMhlScratchpadCommandListener listener) {
+ public HdmiMhlVendorCommandListenerRecord(IHdmiMhlVendorCommandListener listener) {
mListener = listener;
}
@Override
public void binderDied() {
- mScratchpadCommandListenerRecords.remove(this);
+ mMhlVendorCommandListenerRecords.remove(this);
}
}
@@ -1403,7 +1403,7 @@
}
@Override
- public void sendScratchpadCommand(final int portId, final int offset, final int length,
+ public void sendMhlVendorCommand(final int portId, final int offset, final int length,
final byte[] data) {
enforceAccessPermission();
runOnServiceThread(new Runnable() {
@@ -1418,16 +1418,16 @@
Slog.w(TAG, "Invalid port id:" + portId);
return;
}
- mMhlController.sendScratchpadCommand(portId, offset, length, data);
+ mMhlController.sendVendorCommand(portId, offset, length, data);
}
});
}
@Override
- public void addHdmiMhlScratchpadCommandListener(
- IHdmiMhlScratchpadCommandListener listener) {
+ public void addHdmiMhlVendorCommandListener(
+ IHdmiMhlVendorCommandListener listener) {
enforceAccessPermission();
- HdmiControlService.this.addHdmiMhlScratchpadCommandListener(listener);
+ HdmiControlService.this.addHdmiMhlVendorCommandListener(listener);
}
@Override
@@ -1880,9 +1880,9 @@
}
}
- private void addHdmiMhlScratchpadCommandListener(IHdmiMhlScratchpadCommandListener listener) {
- HdmiMhlScratchpadCommandListenerRecord record =
- new HdmiMhlScratchpadCommandListenerRecord(listener);
+ private void addHdmiMhlVendorCommandListener(IHdmiMhlVendorCommandListener listener) {
+ HdmiMhlVendorCommandListenerRecord record =
+ new HdmiMhlVendorCommandListenerRecord(listener);
try {
listener.asBinder().linkToDeath(record, 0);
} catch (RemoteException e) {
@@ -1891,18 +1891,17 @@
}
synchronized (mLock) {
- mScratchpadCommandListenerRecords.add(record);
+ mMhlVendorCommandListenerRecords.add(record);
}
}
- void invokeScratchpadCommandListeners(int portId, int offest, int length, byte[] data) {
+ void invokeMhlVendorCommandListeners(int portId, int offest, int length, byte[] data) {
synchronized (mLock) {
- for (HdmiMhlScratchpadCommandListenerRecord record :
- mScratchpadCommandListenerRecords) {
+ for (HdmiMhlVendorCommandListenerRecord record : mMhlVendorCommandListenerRecords) {
try {
record.mListener.onReceived(portId, offest, length, data);
} catch (RemoteException e) {
- Slog.e(TAG, "Failed to notify scratchpad command", e);
+ Slog.e(TAG, "Failed to notify MHL vendor command", e);
}
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
index c27cf18..afe6e3c 100644
--- a/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
+++ b/services/core/java/com/android/server/hdmi/HdmiMhlControllerStub.java
@@ -106,7 +106,7 @@
}
- void sendScratchpadCommand(int portId, int offset, int length, byte[] data) {
+ void sendVendorCommand(int portId, int offset, int length, byte[] data) {
}
void setOption(int flag, int value) {
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 344c57b..d0447bc 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -153,7 +153,8 @@
}
mRunningJob = job;
- mParams = new JobParameters(job.getJobId(), job.getExtras(), this);
+ mParams = new JobParameters(this, job.getJobId(), job.getExtras(),
+ !job.isConstraintsSatisfied());
mExecutionStartTimeElapsed = SystemClock.elapsedRealtime();
mVerb = VERB_BINDING;
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index f562721..e3c55b6 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -195,16 +195,23 @@
}
/**
- * @return Whether or not this job is ready to run, based on its requirements.
+ * @return Whether or not this job is ready to run, based on its requirements. This is true if
+ * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
*/
public synchronized boolean isReady() {
+ return isConstraintsSatisfied()
+ || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
+ }
+
+ /**
+ * @return Whether the constraints set on this job are satisfied.
+ */
+ public synchronized boolean isConstraintsSatisfied() {
return (!hasChargingConstraint() || chargingConstraintSatisfied.get())
&& (!hasTimingDelayConstraint() || timeDelayConstraintSatisfied.get())
&& (!hasConnectivityConstraint() || connectivityConstraintSatisfied.get())
&& (!hasUnmeteredConstraint() || unmeteredConstraintSatisfied.get())
- && (!hasIdleConstraint() || idleConstraintSatisfied.get())
- // Also ready if the deadline has expired - special case.
- || (hasDeadlineConstraint() && deadlineConstraintSatisfied.get());
+ && (!hasIdleConstraint() || idleConstraintSatisfied.get());
}
public boolean matches(int uid, int jobId) {
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 8ec9b254..8a1f3ad 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -389,7 +389,7 @@
throw new IllegalStateException(
"Cannot start already started MediaProjection");
}
- addCallback(callback);
+ registerCallback(callback);
try {
mToken = callback.asBinder();
mDeathEater = new IBinder.DeathRecipient() {
@@ -424,7 +424,7 @@
}
@Override
- public void addCallback(IMediaProjectionCallback callback) {
+ public void registerCallback(IMediaProjectionCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback must not be null");
}
@@ -432,7 +432,7 @@
}
@Override
- public void removeCallback(IMediaProjectionCallback callback) {
+ public void unregisterCallback(IMediaProjectionCallback callback) {
if (callback == null) {
throw new IllegalArgumentException("callback must not be null");
}
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 9e5fa41..cf19416 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -433,14 +433,12 @@
// listen for configured wifi networks to be removed
final IntentFilter wifiConfigFilter = new IntentFilter(CONFIGURED_NETWORKS_CHANGED_ACTION);
- mContext.registerReceiver(
- mWifiConfigReceiver, wifiConfigFilter, CONNECTIVITY_INTERNAL, mHandler);
+ mContext.registerReceiver(mWifiConfigReceiver, wifiConfigFilter, null, mHandler);
// listen for wifi state changes to catch metered hint
final IntentFilter wifiStateFilter = new IntentFilter(
WifiManager.NETWORK_STATE_CHANGED_ACTION);
- mContext.registerReceiver(
- mWifiStateReceiver, wifiStateFilter, CONNECTIVITY_INTERNAL, mHandler);
+ mContext.registerReceiver(mWifiStateReceiver, wifiStateFilter, null, mHandler);
}
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index f995dee..b5aa4d8 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -318,7 +318,7 @@
// watch for tethering changes
final IntentFilter tetherFilter = new IntentFilter(ACTION_TETHER_STATE_CHANGED);
- mContext.registerReceiver(mTetherReceiver, tetherFilter, CONNECTIVITY_INTERNAL, mHandler);
+ mContext.registerReceiver(mTetherReceiver, tetherFilter, null, mHandler);
// listen for periodic polling events
final IntentFilter pollFilter = new IntentFilter(ACTION_NETWORK_STATS_POLL);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 496c136..ed678d2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -446,7 +446,7 @@
private int createSessionInternal(SessionParams params, String installerPackageName, int userId)
throws IOException {
final int callingUid = Binder.getCallingUid();
- mPm.enforceCrossUserPermission(callingUid, userId, true, "createSession");
+ mPm.enforceCrossUserPermission(callingUid, userId, true, false, "createSession");
if (mPm.isUserRestricted(UserHandle.getUserId(callingUid),
UserManager.DISALLOW_INSTALL_APPS)) {
@@ -654,7 +654,7 @@
@Override
public List<SessionInfo> getAllSessions(int userId) {
- mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getAllSessions");
+ mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getAllSessions");
final List<SessionInfo> result = new ArrayList<>();
synchronized (mSessions) {
@@ -670,7 +670,7 @@
@Override
public List<SessionInfo> getMySessions(String installerPackageName, int userId) {
- mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getMySessions");
+ mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getMySessions");
mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName);
final List<SessionInfo> result = new ArrayList<>();
@@ -688,7 +688,7 @@
@Override
public void uninstall(String packageName, int flags, IntentSender statusReceiver, int userId) {
- mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstall");
+ mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "uninstall");
final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
statusReceiver, packageName);
@@ -717,7 +717,7 @@
@Override
public void registerCallback(IPackageInstallerCallback callback, int userId) {
- mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "registerCallback");
+ mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "registerCallback");
mCallbacks.register(callback, userId);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d821fc1..3e5d514 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -138,6 +138,7 @@
import android.os.Environment;
import android.os.Environment.UserEnvironment;
import android.os.storage.StorageManager;
+import android.os.Debug;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
@@ -1845,7 +1846,7 @@
@Override
public boolean isPackageAvailable(String packageName, int userId) {
if (!sUserManager.exists(userId)) return false;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
if (p != null) {
@@ -1864,7 +1865,7 @@
@Override
public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -1909,7 +1910,7 @@
@Override
public int getPackageUid(String packageName, int userId) {
if (!sUserManager.exists(userId)) return -1;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
// reader
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -2059,7 +2060,7 @@
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
// writer
synchronized (mPackages) {
PackageParser.Package p = mPackages.get(packageName);
@@ -2150,7 +2151,7 @@
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
@@ -2189,7 +2190,7 @@
@Override
public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
synchronized (mPackages) {
PackageParser.Activity a = mReceivers.mActivities.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2207,7 +2208,7 @@
@Override
public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
synchronized (mPackages) {
PackageParser.Service s = mServices.mServices.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2225,7 +2226,7 @@
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
synchronized (mPackages) {
PackageParser.Provider p = mProviders.mProviders.get(component);
if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2329,13 +2330,17 @@
/**
* Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
* or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
+ * @param checkShell TODO(yamasani):
* @param message the message to log on security exception
*/
void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
- String message) {
+ boolean checkShell, String message) {
if (userId < 0) {
throw new IllegalArgumentException("Invalid userId " + userId);
}
+ if (checkShell) {
+ enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
+ }
if (userId == UserHandle.getUserId(callingUid)) return;
if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
if (requireFullPermission) {
@@ -2353,6 +2358,19 @@
}
}
+ void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
+ if (callingUid == Process.SHELL_UID) {
+ if (userHandle >= 0
+ && sUserManager.hasUserRestriction(restriction, userHandle)) {
+ throw new SecurityException("Shell does not have permission to access user "
+ + userHandle);
+ } else if (userHandle < 0) {
+ Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
+ + Debug.getCallers(3));
+ }
+ }
+ }
+
private BasePermission findPermissionTreeLP(String permName) {
for(BasePermission bp : mSettings.mPermissionTrees.values()) {
if (permName.startsWith(bp.name) &&
@@ -2876,7 +2894,7 @@
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return chooseBestActivity(intent, resolvedType, flags, query, userId);
}
@@ -3183,24 +3201,6 @@
if (matches.get(i).getTargetUserId() == targetUserId) return true;
}
}
- ArrayList<String> packageNames = null;
- SparseArray<ArrayList<String>> fromSource =
- mSettings.mCrossProfilePackageInfo.get(sourceUserId);
- if (fromSource != null) {
- packageNames = fromSource.get(targetUserId);
- if (packageNames != null) {
- // We need the package name, so we try to resolve with the loosest flags possible
- List<ResolveInfo> resolveInfos = mActivities.queryIntent(intent, resolvedType,
- PackageManager.GET_UNINSTALLED_PACKAGES, targetUserId);
- int count = resolveInfos.size();
- for (int i = 0; i < count; i++) {
- ResolveInfo resolveInfo = resolveInfos.get(i);
- if (packageNames.contains(resolveInfo.activityInfo.packageName)) {
- return true;
- }
- }
- }
- }
return false;
}
@@ -3217,7 +3217,7 @@
public List<ResolveInfo> queryIntentActivities(Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
ComponentName comp = intent.getComponent();
if (comp == null) {
if (intent.getSelector() != null) {
@@ -3241,20 +3241,10 @@
synchronized (mPackages) {
final String pkgName = intent.getPackage();
if (pkgName == null) {
- ResolveInfo resolveInfo = null;
-
- // Check if the intent needs to be forwarded to another user for this package
- ArrayList<ResolveInfo> crossProfileResult =
- queryIntentActivitiesCrossProfilePackage(
- intent, resolvedType, flags, userId);
- if (!crossProfileResult.isEmpty()) {
- // Skip the current profile
- return crossProfileResult;
- }
List<CrossProfileIntentFilter> matchingFilters =
getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
// Check for results that need to skip the current profile.
- resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
+ ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
resolvedType, flags, userId);
if (resolveInfo != null) {
List<ResolveInfo> result = new ArrayList<ResolveInfo>(1);
@@ -3276,13 +3266,6 @@
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
- ArrayList<ResolveInfo> crossProfileResult =
- queryIntentActivitiesCrossProfilePackage(
- intent, resolvedType, flags, userId, pkg, pkgName);
- if (!crossProfileResult.isEmpty()) {
- // Skip the current profile
- return crossProfileResult;
- }
return mActivities.queryIntentForPackage(intent, resolvedType, flags,
pkg.activities, userId);
}
@@ -3311,56 +3294,6 @@
return null;
}
- private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage(
- Intent intent, String resolvedType, int flags, int userId) {
- ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>();
- SparseArray<ArrayList<String>> sourceForwardingInfo =
- mSettings.mCrossProfilePackageInfo.get(userId);
- if (sourceForwardingInfo != null) {
- int NI = sourceForwardingInfo.size();
- for (int i = 0; i < NI; i++) {
- int targetUserId = sourceForwardingInfo.keyAt(i);
- ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i);
- List<ResolveInfo> resolveInfos = mActivities.queryIntent(
- intent, resolvedType, flags, targetUserId);
- int NJ = resolveInfos.size();
- for (int j = 0; j < NJ; j++) {
- ResolveInfo resolveInfo = resolveInfos.get(j);
- if (packageNames.contains(resolveInfo.activityInfo.packageName)) {
- matchingResolveInfos.add(createForwardingResolveInfo(
- resolveInfo.filter, userId, targetUserId));
- }
- }
- }
- }
- return matchingResolveInfos;
- }
-
- private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage(
- Intent intent, String resolvedType, int flags, int userId, PackageParser.Package pkg,
- String packageName) {
- ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>();
- SparseArray<ArrayList<String>> sourceForwardingInfo =
- mSettings.mCrossProfilePackageInfo.get(userId);
- if (sourceForwardingInfo != null) {
- int NI = sourceForwardingInfo.size();
- for (int i = 0; i < NI; i++) {
- int targetUserId = sourceForwardingInfo.keyAt(i);
- if (sourceForwardingInfo.valueAt(i).contains(packageName)) {
- List<ResolveInfo> resolveInfos = mActivities.queryIntentForPackage(
- intent, resolvedType, flags, pkg.activities, targetUserId);
- int NJ = resolveInfos.size();
- for (int j = 0; j < NJ; j++) {
- ResolveInfo resolveInfo = resolveInfos.get(j);
- matchingResolveInfos.add(createForwardingResolveInfo(
- resolveInfo.filter, userId, targetUserId));
- }
- }
- }
- }
- return matchingResolveInfos;
- }
-
// Return matching ResolveInfo if any for skip current profile intent filters.
private ResolveInfo queryCrossProfileIntents(
List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
@@ -3431,7 +3364,7 @@
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
- "query intent activity options");
+ false, "query intent activity options");
final String resultsAction = intent.getAction();
List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
@@ -3727,7 +3660,7 @@
public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
- enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
// writer
synchronized (mPackages) {
@@ -7745,7 +7678,7 @@
final File originFile = new File(originPath);
final int uid = Binder.getCallingUid();
- if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
+ if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
try {
if (observer != null) {
observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
@@ -7833,11 +7766,8 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
- if (UserHandle.getUserId(uid) != userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
- "setApplicationHiddenSetting for user " + userId);
- }
+ enforceCrossUserPermission(uid, userId, true, true,
+ "setApplicationHiddenSetting for user " + userId);
if (hidden && isPackageDeviceAdmin(packageName, userId)) {
Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
@@ -7896,7 +7826,7 @@
public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
- "getApplicationHidden for user " + userId);
+ false, "getApplicationHidden for user " + userId);
PackageSetting pkgSetting;
long callingId = Binder.clearCallingIdentity();
try {
@@ -7922,7 +7852,8 @@
null);
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
- enforceCrossUserPermission(uid, userId, true, "installExistingPackage for user " + userId);
+ enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
+ + userId);
if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
}
@@ -11046,7 +10977,7 @@
final IPackageDataObserver observer, final int userId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.CLEAR_APP_USER_DATA, null);
- enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
+ enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(new Runnable() {
public void run() {
@@ -11346,7 +11277,7 @@
String opname) {
// writer
int callingUid = Binder.getCallingUid();
- enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
+ enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
if (filter.countActions() == 0) {
Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
return;
@@ -11391,7 +11322,7 @@
}
final int callingUid = Binder.getCallingUid();
- enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity");
+ enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -11532,6 +11463,7 @@
@Override
public void resetPreferredActivities(int userId) {
+ /* TODO: Actually use userId. Why is it being passed in? */
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
// writer
@@ -11646,6 +11578,7 @@
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
int callingUid = Binder.getCallingUid();
enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
+ enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
if (intentFilter.countActions() == 0) {
Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
return;
@@ -11659,30 +11592,13 @@
}
@Override
- public void addCrossProfileIntentsForPackage(String packageName,
- int sourceUserId, int targetUserId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
- mSettings.addCrossProfilePackage(packageName, sourceUserId, targetUserId);
- mSettings.writePackageRestrictionsLPr(sourceUserId);
- }
-
- @Override
- public void removeCrossProfileIntentsForPackage(String packageName,
- int sourceUserId, int targetUserId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
- mSettings.removeCrossProfilePackage(packageName, sourceUserId, targetUserId);
- mSettings.writePackageRestrictionsLPr(sourceUserId);
- }
-
- @Override
public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage,
int ownerUserId) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
int callingUid = Binder.getCallingUid();
enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
+ enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
int callingUserId = UserHandle.getUserId(callingUid);
synchronized (mPackages) {
CrossProfileIntentResolver resolver =
@@ -11777,7 +11693,7 @@
final int uid = Binder.getCallingUid();
final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
- enforceCrossUserPermission(uid, userId, false, "set enabled");
+ enforceCrossUserPermission(uid, userId, false, true, "set enabled");
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
boolean sendNow = false;
boolean isApp = (className == null);
@@ -11911,7 +11827,7 @@
final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
- enforceCrossUserPermission(uid, userId, true, "stop package");
+ enforceCrossUserPermission(uid, userId, true, true, "stop package");
// writer
synchronized (mPackages) {
if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
@@ -11933,7 +11849,7 @@
public int getApplicationEnabledSetting(String packageName, int userId) {
if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
- enforceCrossUserPermission(uid, userId, false, "get enabled");
+ enforceCrossUserPermission(uid, userId, false, false, "get enabled");
// reader
synchronized (mPackages) {
return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
@@ -11944,7 +11860,7 @@
public int getComponentEnabledSetting(ComponentName componentName, int userId) {
if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
int uid = Binder.getCallingUid();
- enforceCrossUserPermission(uid, userId, false, "get component enabled");
+ enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
// reader
synchronized (mPackages) {
return mSettings.getComponentEnabledSettingLPr(componentName, userId);
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index c1caeac..0dadee7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -138,10 +138,6 @@
"persistent-preferred-activities";
static final String TAG_CROSS_PROFILE_INTENT_FILTERS =
"crossProfile-intent-filters";
- private static final String TAG_CROSS_PROFILE_PACKAGE_INFO = "cross-profile-package-info";
- private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID = "target-user-id";
- private static final String CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME = "package-name";
- private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME = "value";
private static final String ATTR_NAME = "name";
private static final String ATTR_USER = "user";
@@ -249,23 +245,15 @@
*/
private final ArrayList<PendingPackage> mPendingPackages = new ArrayList<PendingPackage>();
- private final Context mContext;
-
private final File mSystemDir;
public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
- // A mapping of (sourceUserId, targetUserId, packageNames) for forwarding the intents of a
- // package.
- final SparseArray<SparseArray<ArrayList<String>>>
- mCrossProfilePackageInfo = new SparseArray<SparseArray<ArrayList<String>>>();
-
Settings(Context context) {
this(context, Environment.getDataDirectory());
}
Settings(Context context, File dataDir) {
- mContext = context;
mSystemDir = new File(dataDir, "system");
mSystemDir.mkdirs();
FileUtils.setPermissions(mSystemDir.toString(),
@@ -282,47 +270,6 @@
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
- public void addCrossProfilePackage(
- String packageName, int sourceUserId, int targetUserId) {
- synchronized(mCrossProfilePackageInfo) {
- SparseArray<ArrayList<String>> sourceForwardingInfo =
- mCrossProfilePackageInfo.get(sourceUserId);
- if (sourceForwardingInfo == null) {
- sourceForwardingInfo = new SparseArray<ArrayList<String>>();
- mCrossProfilePackageInfo.put(sourceUserId, sourceForwardingInfo);
- }
- ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId);
- if (packageNames == null) {
- packageNames = new ArrayList<String>();
- sourceForwardingInfo.put(targetUserId, packageNames);
- }
- if (!packageNames.contains(packageName)) {
- packageNames.add(packageName);
- }
- }
- }
-
- public void removeCrossProfilePackage(
- String packageName, int sourceUserId, int targetUserId) {
- synchronized(mCrossProfilePackageInfo) {
- SparseArray<ArrayList<String>> sourceForwardingInfo =
- mCrossProfilePackageInfo.get(sourceUserId);
- if (sourceForwardingInfo == null) {
- return;
- }
- ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId);
- if (packageNames != null && packageNames.contains(packageName)) {
- packageNames.remove(packageName);
- if (packageNames.isEmpty()) {
- sourceForwardingInfo.remove(targetUserId);
- if (sourceForwardingInfo.size() == 0) {
- mCrossProfilePackageInfo.remove(sourceUserId);
- }
- }
- }
- }
- }
-
PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
String legacyNativeLibraryPathString, String primaryCpuAbi, String secondaryCpuAbi,
@@ -517,6 +464,7 @@
int vc, int pkgFlags, UserHandle installUser, boolean add,
boolean allowInstall) {
PackageSetting p = mPackages.get(name);
+ UserManagerService userManager = UserManagerService.getInstance();
if (p != null) {
p.primaryCpuAbiString = primaryCpuAbiString;
p.secondaryCpuAbiString = secondaryCpuAbiString;
@@ -594,6 +542,7 @@
Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
}
List<UserInfo> users = getAllUsers();
+ final int installUserId = installUser != null ? installUser.getIdentifier() : 0;
if (users != null && allowInstall) {
for (UserInfo user : users) {
// By default we consider this app to be installed
@@ -603,8 +552,9 @@
// asked to install for all users, or this is the
// user we are installing for.
final boolean installed = installUser == null
- || installUser.getIdentifier() == UserHandle.USER_ALL
- || installUser.getIdentifier() == user.id;
+ || (installUserId == UserHandle.USER_ALL
+ && !isAdbInstallDisallowed(userManager, user.id))
+ || installUserId == user.id;
p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,
installed,
true, // stopped,
@@ -670,7 +620,8 @@
List<UserInfo> users = getAllUsers();
if (users != null) {
for (UserInfo user : users) {
- if (installUser.getIdentifier() == UserHandle.USER_ALL
+ if ((installUser.getIdentifier() == UserHandle.USER_ALL
+ && !isAdbInstallDisallowed(userManager, user.id))
|| installUser.getIdentifier() == user.id) {
boolean installed = p.getInstalled(user.id);
if (!installed) {
@@ -685,6 +636,11 @@
return p;
}
+ boolean isAdbInstallDisallowed(UserManagerService userManager, int userId) {
+ return userManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
+ userId);
+ }
+
void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
p.pkg = pkg;
// pkg.mSetEnabled = p.getEnabled(userId);
@@ -1068,68 +1024,6 @@
}
}
- private void readCrossProfilePackageInfoLPw(XmlPullParser parser, int userId)
- throws XmlPullParserException, IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- String tagName = parser.getName();
- if (tagName.equals(TAG_ITEM)) {
- String targetUserIdString = parser.getAttributeValue(null,
- CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID);
- if (targetUserIdString == null) {
- String msg = "Missing element under " + TAG +": "
- + CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID + " at " +
- parser.getPositionDescription();
- PackageManagerService.reportSettingsProblem(Log.WARN, msg);
- continue;
- }
- int targetUserId = Integer.parseInt(targetUserIdString);
- readCrossProfilePackageInfoForTargetLPw(parser, userId, targetUserId);
- } else {
- String msg = "Unknown element under " + TAG_CROSS_PROFILE_PACKAGE_INFO + ": " +
- parser.getName();
- PackageManagerService.reportSettingsProblem(Log.WARN, msg);
- XmlUtils.skipCurrentTag(parser);
- }
- }
- }
-
- private void readCrossProfilePackageInfoForTargetLPw(
- XmlPullParser parser, int sourceUserId, int targetUserId)
- throws XmlPullParserException, IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- String tagName = parser.getName();
- if (tagName.equals(CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME)) {
- String packageName = parser.getAttributeValue(
- null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME);
- if (packageName == null) {
- String msg = "Missing element under " + TAG +": "
- + CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME + " at " +
- parser.getPositionDescription();
- PackageManagerService.reportSettingsProblem(Log.WARN, msg);
- continue;
- }
- addCrossProfilePackage(packageName, sourceUserId, targetUserId);
- } else {
- String msg = "Unknown element under " + TAG_ITEM + ": " +
- parser.getName();
- PackageManagerService.reportSettingsProblem(Log.WARN, msg);
- XmlUtils.skipCurrentTag(parser);
- }
- }
- }
-
void readPackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, "Reading package restrictions for user=" + userId);
@@ -1271,8 +1165,6 @@
readPersistentPreferredActivitiesLPw(parser, userId);
} else if (tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) {
readCrossProfileIntentFiltersLPw(parser, userId);
- } else if (tagName.equals(TAG_CROSS_PROFILE_PACKAGE_INFO)){
- readCrossProfilePackageInfoLPw(parser, userId);
} else {
Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
+ parser.getName());
@@ -1364,32 +1256,6 @@
serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS);
}
- void writeCrossProfilePackageInfoLPr(XmlSerializer serializer, int userId)
- throws IllegalArgumentException, IllegalStateException, IOException {
- SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(userId);
- if (sourceForwardingInfo == null) {
- return;
- }
- serializer.startTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO);
- int NI = sourceForwardingInfo.size();
- for (int i = 0; i < NI; i++) {
- int targetUserId = sourceForwardingInfo.keyAt(i);
- ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i);
- serializer.startTag(null, TAG_ITEM);
- serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID,
- Integer.toString(targetUserId));
- int NJ = packageNames.size();
- for (int j = 0; j < NJ; j++) {
- serializer.startTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME);
- serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME,
- packageNames.get(j));
- serializer.endTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME);
- }
- serializer.endTag(null, TAG_ITEM);
- }
- serializer.endTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO);
- }
-
void writePackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, "Writing package restrictions for user=" + userId);
@@ -1494,8 +1360,6 @@
writeCrossProfileIntentFiltersLPr(serializer, userId);
- writeCrossProfilePackageInfoLPr(serializer, userId);
-
serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
serializer.endDocument();
@@ -3180,7 +3044,6 @@
file = getUserPackagesStateBackupFile(userId);
file.delete();
removeCrossProfileIntentFiltersLPw(userId);
- removeCrossProfilePackagesLPw(userId);
}
void removeCrossProfileIntentFiltersLPw(int userId) {
@@ -3211,27 +3074,6 @@
}
}
- public void removeCrossProfilePackagesLPw(int userId) {
- synchronized(mCrossProfilePackageInfo) {
- // userId is the source user
- if (mCrossProfilePackageInfo.get(userId) != null) {
- mCrossProfilePackageInfo.remove(userId);
- writePackageRestrictionsLPr(userId);
- }
- // userId is the target user
- int count = mCrossProfilePackageInfo.size();
- for (int i = 0; i < count; i++) {
- int sourceUserId = mCrossProfilePackageInfo.keyAt(i);
- SparseArray<ArrayList<String>> sourceForwardingInfo =
- mCrossProfilePackageInfo.valueAt(i);
- if (sourceForwardingInfo.get(userId) != null) {
- sourceForwardingInfo.remove(userId);
- writePackageRestrictionsLPr(sourceUserId);
- }
- }
- }
- }
-
// This should be called (at least) whenever an application is removed
private void setFirstAvailableUid(int uid) {
if (uid > mFirstAvailableUid) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index d032d29..26e0db3 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -33,6 +33,7 @@
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Bundle;
+import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
@@ -480,6 +481,14 @@
}
@Override
+ public boolean hasUserRestriction(String restrictionKey, int userId) {
+ synchronized (mPackagesLock) {
+ Bundle restrictions = mUserRestrictions.get(userId);
+ return restrictions != null ? restrictions.getBoolean(restrictionKey) : false;
+ }
+ }
+
+ @Override
public Bundle getUserRestrictions(int userId) {
// checkManageUsersPermission("getUserRestrictions");
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 5f97a00..0a4b3bc 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -91,8 +91,6 @@
private static final int MSG_SANDMAN = 2;
// Message: Sent when the screen on blocker is released.
private static final int MSG_SCREEN_ON_BLOCKER_RELEASED = 3;
- // Message: Sent to poll whether the boot animation has terminated.
- private static final int MSG_CHECK_IF_BOOT_ANIMATION_FINISHED = 4;
// Dirty bit: mWakeLocks changed
private static final int DIRTY_WAKE_LOCKS = 1 << 0;
@@ -154,12 +152,6 @@
// provider populates the actual default value (R.integer.def_screen_off_timeout).
private static final int DEFAULT_SCREEN_OFF_TIMEOUT = 15 * 1000;
- // The name of the boot animation service in init.rc.
- private static final String BOOT_ANIMATION_SERVICE = "bootanim";
-
- // Poll interval in milliseconds for watching boot animation finished.
- private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
-
// Power hints defined in hardware/libhardware/include/hardware/power.h.
private static final int POWER_HINT_INTERACTION = 2;
private static final int POWER_HINT_LOW_POWER = 5;
@@ -478,14 +470,15 @@
@Override
public void onBootPhase(int phase) {
- if (phase == PHASE_BOOT_COMPLETED) {
- // This is our early signal that the system thinks it has finished booting.
- // However, the boot animation may still be running for a few more seconds
- // since it is ultimately in charge of when it terminates.
- // Defer transitioning into the boot completed state until the animation exits.
- // We do this so that the screen does not start to dim prematurely before
- // the user has actually had a chance to interact with the device.
- startWatchingForBootAnimationFinished();
+ synchronized (mLock) {
+ if (phase == PHASE_BOOT_COMPLETED) {
+ final long now = SystemClock.uptimeMillis();
+ mBootCompleted = true;
+ mDirty |= DIRTY_BOOT_COMPLETED;
+ userActivityNoUpdateLocked(
+ now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
+ updatePowerStateLocked();
+ }
}
}
@@ -821,7 +814,7 @@
+ " [" + wakeLock.mTag + "], flags=0x" + Integer.toHexString(flags));
}
- if ((flags & PowerManager.WAIT_FOR_DISTANT_PROXIMITY) != 0) {
+ if ((flags & PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY) != 0) {
mRequestWaitForNegativeProximity = true;
}
@@ -2076,38 +2069,6 @@
updatePowerStateLocked();
}
- private void startWatchingForBootAnimationFinished() {
- mHandler.sendEmptyMessage(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED);
- }
-
- private void checkIfBootAnimationFinished() {
- if (DEBUG) {
- Slog.d(TAG, "Check if boot animation finished...");
- }
-
- if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
- mHandler.sendEmptyMessageDelayed(MSG_CHECK_IF_BOOT_ANIMATION_FINISHED,
- BOOT_ANIMATION_POLL_INTERVAL);
- return;
- }
-
- synchronized (mLock) {
- if (!mBootCompleted) {
- Slog.i(TAG, "Boot animation finished.");
- handleBootCompletedLocked();
- }
- }
- }
-
- private void handleBootCompletedLocked() {
- final long now = SystemClock.uptimeMillis();
- mBootCompleted = true;
- mDirty |= DIRTY_BOOT_COMPLETED;
- userActivityNoUpdateLocked(
- now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
- updatePowerStateLocked();
- }
-
private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
final String reason, boolean wait) {
if (mHandler == null || !mSystemReady) {
@@ -2528,9 +2489,6 @@
case MSG_SCREEN_ON_BLOCKER_RELEASED:
handleScreenOnBlockerReleased();
break;
- case MSG_CHECK_IF_BOOT_ANIMATION_FINISHED:
- checkIfBootAnimationFinished();
- break;
}
}
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 3380f71..adae84fd 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -85,6 +85,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -139,7 +140,7 @@
registerBroadcastReceivers();
} else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
synchronized (mLock) {
- buildTvInputListLocked(mCurrentUserId);
+ buildTvInputListLocked(mCurrentUserId, null);
buildTvContentRatingSystemListLocked(mCurrentUserId);
}
}
@@ -148,19 +149,64 @@
private void registerBroadcastReceivers() {
PackageMonitor monitor = new PackageMonitor() {
+ private void buildTvInputList(String[] packages) {
+ synchronized (mLock) {
+ buildTvInputListLocked(getChangingUserId(), packages);
+ buildTvContentRatingSystemListLocked(getChangingUserId());
+ }
+ }
+
+ @Override
+ public void onPackageUpdateFinished(String packageName, int uid) {
+ if (DEBUG) Slog.d(TAG, "onPackageUpdateFinished(packageName=" + packageName + ")");
+ // This callback is invoked when the TV input is reinstalled.
+ // In this case, isReplacing() always returns true.
+ buildTvInputList(new String[] { packageName });
+ }
+
+ @Override
+ public void onPackagesAvailable(String[] packages) {
+ if (DEBUG) {
+ Slog.d(TAG, "onPackagesAvailable(packages=" + Arrays.toString(packages) + ")");
+ }
+ // This callback is invoked when the media on which some packages exist become
+ // available.
+ if (isReplacing()) {
+ buildTvInputList(packages);
+ }
+ }
+
+ @Override
+ public void onPackagesUnavailable(String[] packages) {
+ // This callback is invoked when the media on which some packages exist become
+ // unavailable.
+ if (DEBUG) {
+ Slog.d(TAG, "onPackagesUnavailable(packages=" + Arrays.toString(packages)
+ + ")");
+ }
+ if (isReplacing()) {
+ buildTvInputList(packages);
+ }
+ }
+
@Override
public void onSomePackagesChanged() {
+ // TODO: Use finer-grained methods(e.g. onPackageAdded, onPackageRemoved) to manage
+ // the TV inputs.
if (DEBUG) Slog.d(TAG, "onSomePackagesChanged()");
- synchronized (mLock) {
- buildTvInputListLocked(mCurrentUserId);
- buildTvContentRatingSystemListLocked(mCurrentUserId);
+ if (isReplacing()) {
+ if (DEBUG) Slog.d(TAG, "Skipped building TV input list due to replacing");
+ // When the package is updated, buildTvInputListLocked is called in other
+ // methods instead.
+ return;
}
+ buildTvInputList(null);
}
@Override
public void onPackageRemoved(String packageName, int uid) {
synchronized (mLock) {
- UserState userState = getUserStateLocked(mCurrentUserId);
+ UserState userState = getUserStateLocked(getChangingUserId());
if (!userState.packageSet.contains(packageName)) {
// Not a TV input package.
return;
@@ -218,13 +264,11 @@
component.getPackageName()) == PackageManager.PERMISSION_GRANTED;
}
- private void buildTvInputListLocked(int userId) {
+ private void buildTvInputListLocked(int userId, String[] updatedPackages) {
UserState userState = getUserStateLocked(userId);
userState.packageSet.clear();
- if (DEBUG) {
- Slog.d(TAG, "buildTvInputList");
- }
+ if (DEBUG) Slog.d(TAG, "buildTvInputList");
PackageManager pm = mContext.getPackageManager();
List<ResolveInfo> services = pm.queryIntentServices(
new Intent(TvInputService.SERVICE_INTERFACE),
@@ -278,6 +322,15 @@
for (String inputId : inputMap.keySet()) {
if (!userState.inputMap.containsKey(inputId)) {
notifyInputAddedLocked(userState, inputId);
+ } else if (updatedPackages != null) {
+ // Notify the package updates
+ TvInputState inputState = inputMap.get(inputId);
+ for (String updatedPackage : updatedPackages) {
+ if (inputState.info.getComponent().getPackageName().equals(updatedPackage)) {
+ notifyInputUpdatedLocked(userState, inputId);
+ break;
+ }
+ }
}
}
@@ -337,7 +390,7 @@
userState = new UserState(mContext, userId);
}
mUserStates.put(userId, userState);
- buildTvInputListLocked(userId);
+ buildTvInputListLocked(userId, null);
buildTvContentRatingSystemListLocked(userId);
}
}
@@ -649,6 +702,19 @@
}
}
+ private void notifyInputUpdatedLocked(UserState userState, String inputId) {
+ if (DEBUG) {
+ Slog.d(TAG, "notifyInputUpdatedLocked(inputId=" + inputId + ")");
+ }
+ for (ITvInputManagerCallback callback : userState.callbackSet) {
+ try {
+ callback.onInputUpdated(inputId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "failed to report updated input to callback", e);
+ }
+ }
+ }
+
private void notifyInputStateChangedLocked(UserState userState, String inputId,
int state, ITvInputManagerCallback targetCallback) {
if (DEBUG) {
@@ -1813,7 +1879,7 @@
private void addTvInputLocked(TvInputInfo inputInfo) {
ServiceState serviceState = getServiceStateLocked(mComponent, mUserId);
serviceState.inputList.add(inputInfo);
- buildTvInputListLocked(mUserId);
+ buildTvInputListLocked(mUserId, null);
}
@Override
@@ -1851,7 +1917,7 @@
}
}
if (removed) {
- buildTvInputListLocked(mUserId);
+ buildTvInputListLocked(mUserId, null);
mTvInputHardwareManager.removeTvInput(inputId);
} else {
Slog.e(TAG, "failed to remove input " + inputId);
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index e1ade63..a8245e7 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -843,7 +843,7 @@
}
File file = new File(dir, WALLPAPER);
ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
- MODE_CREATE|MODE_READ_WRITE);
+ MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE);
if (!SELinux.restorecon(file)) {
return null;
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 8d30e39..da5cfda 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -252,6 +252,10 @@
final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() &&
(imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0;
+ final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw();
+ final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ?
+ null : winShowWhenLocked.mAppToken;
+
for (int i = windows.size() - 1; i >= 0; i--) {
WindowState win = windows.get(i);
WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -316,8 +320,8 @@
+ " hidden=" + win.mRootToken.hidden
+ " anim=" + win.mWinAnimator.mAnimation);
} else if (mPolicy.canBeForceHidden(win, win.mAttrs)) {
- final boolean hideWhenLocked = (flags & FLAG_SHOW_WHEN_LOCKED) == 0 &&
- !(win.mIsImWindow && showImeOverKeyguard);
+ final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) ||
+ (appShowWhenLocked != null && appShowWhenLocked == win.mAppToken));
final boolean changed;
if (((mForceHiding == KEYGUARD_ANIMATING_IN)
&& (!winAnimator.isAnimating() || hideWhenLocked))
@@ -574,6 +578,15 @@
mBulkUpdateParams |= SET_UPDATE_ROTATION;
screenRotationAnimation.kill();
displayAnimator.mScreenRotationAnimation = null;
+
+ //TODO (multidisplay): Accessibility supported only for the default display.
+ if (mService.mAccessibilityController != null
+ && displayId == Display.DEFAULT_DISPLAY) {
+ // We just finished rotation animation which means we did not
+ // anounce the rotation and waited for it to end, announce now.
+ mService.mAccessibilityController.onRotationChangedLocked(
+ mService.getDefaultDisplayContentLocked(), mService.mRotation);
+ }
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d0bee62..9033f30 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -21,6 +21,7 @@
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
import android.app.AppOpsManager;
import android.os.Build;
+import android.os.SystemService;
import android.util.ArraySet;
import android.util.TimeUtils;
import android.view.IWindowId;
@@ -272,6 +273,12 @@
// Default input dispatching timeout in nanoseconds.
static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L;
+ // Poll interval in milliseconds for watching boot animation finished.
+ private static final int BOOT_ANIMATION_POLL_INTERVAL = 200;
+
+ // The name of the boot animation service in init.rc.
+ private static final String BOOT_ANIMATION_SERVICE = "bootanim";
+
/** Minimum value for attachStack and resizeStack weight value */
public static final float STACK_WEIGHT_MIN = 0.2f;
@@ -458,6 +465,7 @@
boolean mSystemBooted = false;
boolean mForceDisplayEnabled = false;
boolean mShowingBootMessages = false;
+ boolean mBootAnimationStopped = false;
String mLastANRState;
@@ -5607,17 +5615,70 @@
performEnableScreen();
}
+ private boolean checkWaitingForWindowsLocked() {
+
+ boolean haveBootMsg = false;
+ boolean haveApp = false;
+ // if the wallpaper service is disabled on the device, we're never going to have
+ // wallpaper, don't bother waiting for it
+ boolean haveWallpaper = false;
+ boolean wallpaperEnabled = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_enableWallpaperService)
+ && !mOnlyCore;
+ boolean haveKeyguard = true;
+ // TODO(multidisplay): Expand to all displays?
+ final WindowList windows = getDefaultWindowListLocked();
+ final int N = windows.size();
+ for (int i=0; i<N; i++) {
+ WindowState w = windows.get(i);
+ if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
+ return true;
+ }
+ if (w.isDrawnLw()) {
+ if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
+ haveBootMsg = true;
+ } else if (w.mAttrs.type == TYPE_APPLICATION) {
+ haveApp = true;
+ } else if (w.mAttrs.type == TYPE_WALLPAPER) {
+ haveWallpaper = true;
+ } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
+ haveKeyguard = mPolicy.isKeyguardDrawnLw();
+ }
+ }
+ }
+
+ if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
+ Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
+ + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
+ + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
+ + " haveKeyguard=" + haveKeyguard);
+ }
+
+ // If we are turning on the screen to show the boot message,
+ // don't do it until the boot message is actually displayed.
+ if (!mSystemBooted && !haveBootMsg) {
+ return true;
+ }
+
+ // If we are turning on the screen after the boot is completed
+ // normally, don't do so until we have the application and
+ // wallpaper.
+ if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
+ (wallpaperEnabled && !haveWallpaper))) {
+ return true;
+ }
+
+ return false;
+ }
+
public void performEnableScreen() {
synchronized(mWindowMap) {
- if (DEBUG_BOOT) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
- + " mForceDisplayEnabled=" + mForceDisplayEnabled
- + " mShowingBootMessages=" + mShowingBootMessages
- + " mSystemBooted=" + mSystemBooted
- + " mOnlyCore=" + mOnlyCore, here);
- }
+ if (DEBUG_BOOT) Slog.i(TAG, "performEnableScreen: mDisplayEnabled=" + mDisplayEnabled
+ + " mForceDisplayEnabled=" + mForceDisplayEnabled
+ + " mShowingBootMessages=" + mShowingBootMessages
+ + " mSystemBooted=" + mSystemBooted
+ + " mOnlyCore=" + mOnlyCore,
+ new RuntimeException("here").fillInStackTrace());
if (mDisplayEnabled) {
return;
}
@@ -5625,94 +5686,64 @@
return;
}
- if (!mForceDisplayEnabled) {
- // Don't enable the screen until all existing windows
- // have been drawn.
- boolean haveBootMsg = false;
- boolean haveApp = false;
- // if the wallpaper service is disabled on the device, we're never going to have
- // wallpaper, don't bother waiting for it
- boolean haveWallpaper = false;
- boolean wallpaperEnabled = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_enableWallpaperService)
- && !mOnlyCore;
- boolean haveKeyguard = true;
- // TODO(multidisplay): Expand to all displays?
- final WindowList windows = getDefaultWindowListLocked();
- final int N = windows.size();
- for (int i=0; i<N; i++) {
- WindowState w = windows.get(i);
- if (w.isVisibleLw() && !w.mObscured && !w.isDrawnLw()) {
- return;
+ // Don't enable the screen until all existing windows have been drawn.
+ if (!mForceDisplayEnabled && checkWaitingForWindowsLocked()) {
+ return;
+ }
+
+ if (!mBootAnimationStopped) {
+ // Do this one time.
+ try {
+ IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
+ if (surfaceFlinger != null) {
+ //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
+ data, null, 0);
+ data.recycle();
}
- if (w.isDrawnLw()) {
- if (w.mAttrs.type == TYPE_BOOT_PROGRESS) {
- haveBootMsg = true;
- } else if (w.mAttrs.type == TYPE_APPLICATION) {
- haveApp = true;
- } else if (w.mAttrs.type == TYPE_WALLPAPER) {
- haveWallpaper = true;
- } else if (w.mAttrs.type == TYPE_STATUS_BAR) {
- haveKeyguard = mPolicy.isKeyguardDrawnLw();
- }
- }
+ } catch (RemoteException ex) {
+ Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
}
+ mBootAnimationStopped = true;
+ }
- if (DEBUG_SCREEN_ON || DEBUG_BOOT) {
- Slog.i(TAG, "******** booted=" + mSystemBooted + " msg=" + mShowingBootMessages
- + " haveBoot=" + haveBootMsg + " haveApp=" + haveApp
- + " haveWall=" + haveWallpaper + " wallEnabled=" + wallpaperEnabled
- + " haveKeyguard=" + haveKeyguard);
- }
-
- // If we are turning on the screen to show the boot message,
- // don't do it until the boot message is actually displayed.
- if (!mSystemBooted && !haveBootMsg) {
- return;
- }
-
- // If we are turning on the screen after the boot is completed
- // normally, don't do so until we have the application and
- // wallpaper.
- if (mSystemBooted && ((!haveApp && !haveKeyguard) ||
- (wallpaperEnabled && !haveWallpaper))) {
- return;
- }
+ if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
+ if (DEBUG_BOOT) Slog.i(TAG, "performEnableScreen: Waiting for anim complete");
+ return;
}
mDisplayEnabled = true;
if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
- if (false) {
- StringWriter sw = new StringWriter();
- PrintWriter pw = new FastPrintWriter(sw, false, 1024);
- this.dump(null, pw, null);
- pw.flush();
- Slog.i(TAG, sw.toString());
- }
- try {
- IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
- if (surfaceFlinger != null) {
- //Slog.i(TAG, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken("android.ui.ISurfaceComposer");
- surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
- data, null, 0);
- data.recycle();
- }
- } catch (RemoteException ex) {
- Slog.e(TAG, "Boot completed: SurfaceFlinger is dead!");
- }
// Enable input dispatch.
mInputMonitor.setEventDispatchingLw(mEventDispatchingEnabled);
}
+ try {
+ mActivityManager.bootAnimationComplete();
+ } catch (RemoteException e) {
+ }
+
mPolicy.enableScreenAfterBoot();
// Make sure the last requested orientation has been applied.
updateRotationUnchecked(false, false);
}
+ private boolean checkBootAnimationCompleteLocked() {
+ if (SystemService.isRunning(BOOT_ANIMATION_SERVICE)) {
+ mH.removeMessages(H.CHECK_IF_BOOT_ANIMATION_FINISHED);
+ mH.sendEmptyMessageDelayed(H.CHECK_IF_BOOT_ANIMATION_FINISHED,
+ BOOT_ANIMATION_POLL_INTERVAL);
+ if (DEBUG_BOOT) Slog.i(TAG, "checkBootAnimationComplete: Waiting for anim complete");
+ return false;
+ }
+ if (DEBUG_BOOT) Slog.i(TAG, "checkBootAnimationComplete: Animation complete!");
+ return true;
+ }
+
public void showBootMessage(final CharSequence msg, final boolean always) {
boolean first = false;
synchronized(mWindowMap) {
@@ -6411,9 +6442,12 @@
}
//TODO (multidisplay): Magnification is supported only for the default display.
- if (mAccessibilityController != null
+ // Announce rotation only if we will not animate as we already have the
+ // windows in final state. Otherwise, we make this call at the rotation end.
+ if (screenRotationAnimation == null && mAccessibilityController != null
&& displayContent.getDisplayId() == Display.DEFAULT_DISPLAY) {
- mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(), rotation);
+ mAccessibilityController.onRotationChangedLocked(getDefaultDisplayContentLocked(),
+ rotation);
}
return true;
@@ -7457,6 +7491,8 @@
public static final int SHOW_CIRCULAR_DISPLAY_MASK = 35;
public static final int SHOW_EMULATOR_DISPLAY_OVERLAY = 36;
+ public static final int CHECK_IF_BOOT_ANIMATION_FINISHED = 37;
+
@Override
public void handleMessage(Message msg) {
if (DEBUG_WINDOW_TRACE) {
@@ -7941,6 +7977,17 @@
}
}
break;
+ case CHECK_IF_BOOT_ANIMATION_FINISHED: {
+ final boolean bootAnimationComplete;
+ synchronized (mWindowMap) {
+ if (DEBUG_BOOT) Slog.i(TAG, "CHECK_IF_BOOT_ANIMATION_FINISHED:");
+ bootAnimationComplete = checkBootAnimationCompleteLocked();
+ }
+ if (bootAnimationComplete) {
+ performEnableScreen();
+ }
+ }
+ break;
}
if (DEBUG_WINDOW_TRACE) {
Slog.v(TAG, "handleMessage: exit");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 09584f4..8e82e2a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -44,13 +44,13 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.media.IAudioService;
import android.net.ConnectivityManager;
-import android.net.Uri;
-import android.database.ContentObserver;
-import android.hardware.usb.UsbManager;
import android.net.ProxyInfo;
+import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -69,6 +69,7 @@
import android.os.UserManager;
import android.provider.Settings;
import android.security.Credentials;
+import android.security.IKeyChainService;
import android.security.KeyChain;
import android.security.KeyChain.KeyChainConnection;
import android.util.Log;
@@ -110,6 +111,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
+import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
@@ -166,12 +168,17 @@
}
private static final Set<String> SECURE_SETTINGS_WHITELIST;
+ private static final Set<String> SECURE_SETTINGS_DEVICEOWNER_WHITELIST;
private static final Set<String> GLOBAL_SETTINGS_WHITELIST;
static {
SECURE_SETTINGS_WHITELIST = new HashSet();
SECURE_SETTINGS_WHITELIST.add(Settings.Secure.DEFAULT_INPUT_METHOD);
SECURE_SETTINGS_WHITELIST.add(Settings.Secure.SKIP_FIRST_USE_HINTS);
+ SECURE_SETTINGS_DEVICEOWNER_WHITELIST = new HashSet();
+ SECURE_SETTINGS_DEVICEOWNER_WHITELIST.addAll(SECURE_SETTINGS_WHITELIST);
+ SECURE_SETTINGS_DEVICEOWNER_WHITELIST.add(Settings.Secure.LOCATION_MODE);
+
GLOBAL_SETTINGS_WHITELIST = new HashSet();
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.ADB_ENABLED);
GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.AUTO_TIME);
@@ -2824,6 +2831,35 @@
}
}
+ @Override
+ public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) {
+ if (who == null) {
+ throw new NullPointerException("ComponentName is null");
+ }
+ synchronized (this) {
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ }
+ final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
+ final long id = Binder.clearCallingIdentity();
+ try {
+ final KeyChainConnection keyChainConnection = KeyChain.bindAsUser(mContext, userHandle);
+ try {
+ IKeyChainService keyChain = keyChainConnection.getService();
+ return keyChain.installKeyPair(privKey, cert, alias);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Installing certificate", e);
+ } finally {
+ keyChainConnection.close();
+ }
+ } catch (InterruptedException e) {
+ Log.w(LOG_TAG, "Interrupted while installing certificate", e);
+ Thread.currentThread().interrupt();
+ } finally {
+ Binder.restoreCallingIdentity(id);
+ }
+ return false;
+ }
+
void wipeDataLocked(int flags) {
// If the SD card is encrypted and non-removable, we have to force a wipe.
boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
@@ -4608,7 +4644,8 @@
@Override
public void setUserRestriction(ComponentName who, String key, boolean enabled) {
- final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
+ final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
+ final int userHandle = user.getIdentifier();
synchronized (this) {
if (who == null) {
throw new NullPointerException("ComponentName is null");
@@ -4619,7 +4656,7 @@
if (!isDeviceOwner && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
throw new SecurityException("Profile owners cannot set user restriction " + key);
}
- boolean alreadyRestricted = mUserManager.hasUserRestriction(key, userHandle);
+ boolean alreadyRestricted = mUserManager.hasUserRestriction(key, user);
IAudioService iAudioService = null;
if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)
@@ -4645,7 +4682,7 @@
if (UserManager.DISALLOW_CONFIG_WIFI.equals(key)) {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0,
- userHandle.getIdentifier());
+ userHandle);
} else if (UserManager.DISALLOW_USB_FILE_TRANSFER.equals(key)) {
UsbManager manager =
(UsbManager) mContext.getSystemService(Context.USB_SERVICE);
@@ -4653,27 +4690,30 @@
} else if (UserManager.DISALLOW_SHARE_LOCATION.equals(key)) {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF,
- userHandle.getIdentifier());
+ userHandle);
Settings.Secure.putStringForUser(mContext.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "",
- userHandle.getIdentifier());
+ userHandle);
} else if (UserManager.DISALLOW_DEBUGGING_FEATURES.equals(key)) {
- Settings.Global.putStringForUser(mContext.getContentResolver(),
- Settings.Global.ADB_ENABLED, "0", userHandle.getIdentifier());
+ // Only disable adb if changing for primary user, since it is global
+ if (userHandle == UserHandle.USER_OWNER) {
+ Settings.Global.putStringForUser(mContext.getContentResolver(),
+ Settings.Global.ADB_ENABLED, "0", userHandle);
+ }
} else if (UserManager.ENSURE_VERIFY_APPS.equals(key)) {
Settings.Global.putStringForUser(mContext.getContentResolver(),
Settings.Global.PACKAGE_VERIFIER_ENABLE, "1",
- userHandle.getIdentifier());
+ userHandle);
Settings.Global.putStringForUser(mContext.getContentResolver(),
Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1",
- userHandle.getIdentifier());
+ userHandle);
} else if (UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES.equals(key)) {
Settings.Secure.putIntForUser(mContext.getContentResolver(),
Settings.Secure.INSTALL_NON_MARKET_APPS, 0,
- userHandle.getIdentifier());
+ userHandle);
}
}
- mUserManager.setUserRestriction(key, enabled, userHandle);
+ mUserManager.setUserRestriction(key, enabled, user);
} finally {
restoreCallingIdentity(id);
}
@@ -5109,11 +5149,17 @@
if (who == null) {
throw new NullPointerException("ComponentName is null");
}
- getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
+ ActiveAdmin activeAdmin =
+ getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
- if (!SECURE_SETTINGS_WHITELIST.contains(setting)) {
+ if (isDeviceOwner(activeAdmin.info.getPackageName())) {
+ if (!SECURE_SETTINGS_DEVICEOWNER_WHITELIST.contains(setting)) {
+ throw new SecurityException(String.format(
+ "Permission denial: Device owners cannot update %1$s", setting));
+ }
+ } else if (!SECURE_SETTINGS_WHITELIST.contains(setting)) {
throw new SecurityException(String.format(
- "Permission denial: profile/device owners cannot update %1$s", setting));
+ "Permission denial: Profile owners cannot update %1$s", setting));
}
long id = Binder.clearCallingIdentity();
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index 62a7ec0..972c929 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -61,7 +61,7 @@
/**
* Initialize any directories required and index what stats are available.
*/
- void init() {
+ public void init(long currentTimeMillis) {
synchronized (mLock) {
for (File f : mIntervalDirs) {
f.mkdirs();
@@ -72,27 +72,53 @@
}
checkVersionLocked();
+ indexFilesLocked();
- final FilenameFilter backupFileFilter = new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return !name.endsWith(".bak");
+ // Delete files that are in the future.
+ for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) {
+ final int startIndex = files.closestIndexOnOrAfter(currentTimeMillis);
+ if (startIndex < 0) {
+ continue;
}
- };
- // Index the available usage stat files on disk.
- for (int i = 0; i < mSortedStatFiles.length; i++) {
+ final int fileCount = files.size();
+ for (int i = startIndex; i < fileCount; i++) {
+ files.valueAt(i).delete();
+ }
+
+ // Remove in a separate loop because any accesses (valueAt)
+ // will cause a gc in the SparseArray and mess up the order.
+ for (int i = startIndex; i < fileCount; i++) {
+ files.removeAt(i);
+ }
+ }
+ }
+ }
+
+ private void indexFilesLocked() {
+ final FilenameFilter backupFileFilter = new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return !name.endsWith(".bak");
+ }
+ };
+
+ // Index the available usage stat files on disk.
+ for (int i = 0; i < mSortedStatFiles.length; i++) {
+ if (mSortedStatFiles[i] == null) {
mSortedStatFiles[i] = new TimeSparseArray<>();
- File[] files = mIntervalDirs[i].listFiles(backupFileFilter);
- if (files != null) {
- if (DEBUG) {
- Slog.d(TAG, "Found " + files.length + " stat files for interval " + i);
- }
+ } else {
+ mSortedStatFiles[i].clear();
+ }
+ File[] files = mIntervalDirs[i].listFiles(backupFileFilter);
+ if (files != null) {
+ if (DEBUG) {
+ Slog.d(TAG, "Found " + files.length + " stat files for interval " + i);
+ }
- for (File f : files) {
- final AtomicFile af = new AtomicFile(f);
- mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af);
- }
+ for (File f : files) {
+ final AtomicFile af = new AtomicFile(f);
+ mSortedStatFiles[i].put(UsageStatsXml.parseBeginTime(af), af);
}
}
}
@@ -135,6 +161,38 @@
}
}
+ public void onTimeChanged(long timeDiffMillis) {
+ synchronized (mLock) {
+ for (TimeSparseArray<AtomicFile> files : mSortedStatFiles) {
+ final int fileCount = files.size();
+ for (int i = 0; i < fileCount; i++) {
+ final AtomicFile file = files.valueAt(i);
+ final long newTime = files.keyAt(i) + timeDiffMillis;
+ if (newTime < 0) {
+ Slog.i(TAG, "Deleting file " + file.getBaseFile().getAbsolutePath()
+ + " for it is in the future now.");
+ file.delete();
+ } else {
+ try {
+ file.openRead().close();
+ } catch (IOException e) {
+ // Ignore, this is just to make sure there are no backups.
+ }
+ final File newFile = new File(file.getBaseFile().getParentFile(),
+ Long.toString(newTime));
+ Slog.i(TAG, "Moving file " + file.getBaseFile().getAbsolutePath() + " to "
+ + newFile.getAbsolutePath());
+ file.getBaseFile().renameTo(newFile);
+ }
+ }
+ files.clear();
+ }
+
+ // Now re-index the new files.
+ indexFilesLocked();
+ }
+ }
+
/**
* Get the latest stats that exist for this interval type.
*/
@@ -296,25 +354,24 @@
/**
* Remove any usage stat files that are too old.
*/
- public void prune() {
+ public void prune(final long currentTimeMillis) {
synchronized (mLock) {
- long timeNow = System.currentTimeMillis();
- mCal.setTimeInMillis(timeNow);
+ mCal.setTimeInMillis(currentTimeMillis);
mCal.addYears(-3);
pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_YEARLY],
mCal.getTimeInMillis());
- mCal.setTimeInMillis(timeNow);
+ mCal.setTimeInMillis(currentTimeMillis);
mCal.addMonths(-6);
pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_MONTHLY],
mCal.getTimeInMillis());
- mCal.setTimeInMillis(timeNow);
+ mCal.setTimeInMillis(currentTimeMillis);
mCal.addWeeks(-4);
pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_WEEKLY],
mCal.getTimeInMillis());
- mCal.setTimeInMillis(timeNow);
+ mCal.setTimeInMillis(currentTimeMillis);
mCal.addDays(-7);
pruneFilesOlderThan(mIntervalDirs[UsageStatsManager.INTERVAL_DAILY],
mCal.getTimeInMillis());
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 2dcdcc4..2ed9745 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -33,6 +33,7 @@
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.os.Binder;
+import android.os.Debug;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
@@ -64,6 +65,7 @@
private static final long TEN_SECONDS = 10 * 1000;
private static final long TWENTY_MINUTES = 20 * 60 * 1000;
private static final long FLUSH_INTERVAL = DEBUG ? TEN_SECONDS : TWENTY_MINUTES;
+ private static final long TIME_CHANGE_THRESHOLD_MILLIS = 2 * 1000; // Two seconds.
// Handler message types.
static final int MSG_REPORT_EVENT = 0;
@@ -170,18 +172,47 @@
}
}
- private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId) {
+ private UserUsageStatsService getUserDataAndInitializeIfNeededLocked(int userId,
+ long currentTimeMillis) {
UserUsageStatsService service = mUserState.get(userId);
if (service == null) {
service = new UserUsageStatsService(userId,
new File(mUsageStatsDir, Integer.toString(userId)), this);
- service.init();
+ service.init(currentTimeMillis);
mUserState.put(userId, service);
}
return service;
}
/**
+ * This should be the only way to get the time from the system.
+ */
+ private long checkAndGetTimeLocked() {
+ final long actualSystemTime = System.currentTimeMillis();
+ final long actualRealtime = SystemClock.elapsedRealtime();
+ final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
+ if (Math.abs(actualSystemTime - expectedSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
+ // The time has changed.
+ final int userCount = mUserState.size();
+ for (int i = 0; i < userCount; i++) {
+ final UserUsageStatsService service = mUserState.valueAt(i);
+ service.onTimeChanged(expectedSystemTime, actualSystemTime);
+ }
+ mRealTimeSnapshot = actualRealtime;
+ mSystemTimeSnapshot = actualSystemTime;
+ }
+ return actualSystemTime;
+ }
+
+ /**
+ * Assuming the event's timestamp is measured in milliseconds since boot,
+ * convert it to a system wall time.
+ */
+ private void convertToSystemTimeLocked(UsageEvents.Event event) {
+ event.mTimeStamp = Math.max(0, event.mTimeStamp - mRealTimeSnapshot) + mSystemTimeSnapshot;
+ }
+
+ /**
* Called by the Binder stub
*/
void shutdown() {
@@ -196,7 +227,11 @@
*/
void reportEvent(UsageEvents.Event event, int userId) {
synchronized (mLock) {
- final UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+ final long timeNow = checkAndGetTimeLocked();
+ convertToSystemTimeLocked(event);
+
+ final UserUsageStatsService service =
+ getUserDataAndInitializeIfNeededLocked(userId, timeNow);
service.reportEvent(event);
}
}
@@ -225,12 +260,14 @@
* Called by the Binder stub.
*/
List<UsageStats> queryUsageStats(int userId, int bucketType, long beginTime, long endTime) {
- if (!validRange(beginTime, endTime)) {
- return null;
- }
-
synchronized (mLock) {
- UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+ final long timeNow = checkAndGetTimeLocked();
+ if (!validRange(timeNow, beginTime, endTime)) {
+ return null;
+ }
+
+ final UserUsageStatsService service =
+ getUserDataAndInitializeIfNeededLocked(userId, timeNow);
return service.queryUsageStats(bucketType, beginTime, endTime);
}
}
@@ -240,12 +277,14 @@
*/
List<ConfigurationStats> queryConfigurationStats(int userId, int bucketType, long beginTime,
long endTime) {
- if (!validRange(beginTime, endTime)) {
- return null;
- }
-
synchronized (mLock) {
- UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+ final long timeNow = checkAndGetTimeLocked();
+ if (!validRange(timeNow, beginTime, endTime)) {
+ return null;
+ }
+
+ final UserUsageStatsService service =
+ getUserDataAndInitializeIfNeededLocked(userId, timeNow);
return service.queryConfigurationStats(bucketType, beginTime, endTime);
}
}
@@ -254,19 +293,20 @@
* Called by the Binder stub.
*/
UsageEvents queryEvents(int userId, long beginTime, long endTime) {
- if (!validRange(beginTime, endTime)) {
- return null;
- }
-
synchronized (mLock) {
- UserUsageStatsService service = getUserDataAndInitializeIfNeededLocked(userId);
+ final long timeNow = checkAndGetTimeLocked();
+ if (!validRange(timeNow, beginTime, endTime)) {
+ return null;
+ }
+
+ final UserUsageStatsService service =
+ getUserDataAndInitializeIfNeededLocked(userId, timeNow);
return service.queryEvents(beginTime, endTime);
}
}
- private static boolean validRange(long beginTime, long endTime) {
- final long timeNow = System.currentTimeMillis();
- return beginTime <= timeNow && beginTime < endTime;
+ private static boolean validRange(long currentTime, long beginTime, long endTime) {
+ return beginTime <= currentTime && beginTime < endTime;
}
private void flushToDiskLocked() {
@@ -386,14 +426,6 @@
*/
private class LocalService extends UsageStatsManagerInternal {
- /**
- * The system may have its time change, so at least make sure the events
- * are monotonic in order.
- */
- private long computeMonotonicSystemTime(long realTime) {
- return (realTime - mRealTimeSnapshot) + mSystemTimeSnapshot;
- }
-
@Override
public void reportEvent(ComponentName component, int userId, int eventType) {
if (component == null) {
@@ -404,7 +436,10 @@
UsageEvents.Event event = new UsageEvents.Event();
event.mPackage = component.getPackageName();
event.mClass = component.getClassName();
- event.mTimeStamp = computeMonotonicSystemTime(SystemClock.elapsedRealtime());
+
+ // This will later be converted to system time.
+ event.mTimeStamp = SystemClock.elapsedRealtime();
+
event.mEventType = eventType;
mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
}
@@ -418,7 +453,10 @@
UsageEvents.Event event = new UsageEvents.Event();
event.mPackage = "android";
- event.mTimeStamp = computeMonotonicSystemTime(SystemClock.elapsedRealtime());
+
+ // This will later be converted to system time.
+ event.mTimeStamp = SystemClock.elapsedRealtime();
+
event.mEventType = UsageEvents.Event.CONFIGURATION_CHANGE;
event.mConfiguration = new Configuration(config);
mHandler.obtainMessage(MSG_REPORT_EVENT, userId, 0, event).sendToTarget();
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index 2769666..4916ec2 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -22,6 +22,7 @@
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.res.Configuration;
+import android.os.SystemClock;
import android.util.ArraySet;
import android.util.Slog;
@@ -62,10 +63,9 @@
mLogPrefix = "User[" + Integer.toString(userId) + "] ";
}
- void init() {
- mDatabase.init();
+ void init(final long currentTimeMillis) {
+ mDatabase.init(currentTimeMillis);
- final long timeNow = System.currentTimeMillis();
int nullCount = 0;
for (int i = 0; i < mCurrentStats.length; i++) {
mCurrentStats[i] = mDatabase.getLatestUsageStats(i);
@@ -73,11 +73,6 @@
// Find out how many intervals we don't have data for.
// Ideally it should be all or none.
nullCount++;
- } else if (mCurrentStats[i].beginTime > timeNow) {
- Slog.e(TAG, mLogPrefix + "Interval " + i + " has stat in the future " +
- mCurrentStats[i].beginTime);
- mCurrentStats[i] = null;
- nullCount++;
}
}
@@ -92,7 +87,7 @@
// By calling loadActiveStats, we will
// generate new stats for each bucket.
- loadActiveStats();
+ loadActiveStats(currentTimeMillis, false);
} else {
// Set up the expiry date to be one day from the latest daily stat.
// This may actually be today and we will rollover on the first event
@@ -123,6 +118,12 @@
}
}
+ void onTimeChanged(long oldTime, long newTime) {
+ persistActiveStats();
+ mDatabase.onTimeChanged(newTime - oldTime);
+ loadActiveStats(newTime, true);
+ }
+
void reportEvent(UsageEvents.Event event) {
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
@@ -132,7 +133,7 @@
if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
// Need to rollover
- rolloverStats();
+ rolloverStats(event.mTimeStamp);
}
final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];
@@ -330,8 +331,8 @@
}
}
- private void rolloverStats() {
- final long startTime = System.currentTimeMillis();
+ private void rolloverStats(final long currentTimeMillis) {
+ final long startTime = SystemClock.elapsedRealtime();
Slog.i(TAG, mLogPrefix + "Rolling over usage stats");
// Finish any ongoing events with an END_OF_DAY event. Make a note of which components
@@ -348,7 +349,7 @@
continuePreviousDay.add(pkgStats.mPackageName);
stat.update(pkgStats.mPackageName, mDailyExpiryDate.getTimeInMillis() - 1,
UsageEvents.Event.END_OF_DAY);
- mStatsChanged = true;
+ notifyStatsChanged();
}
}
@@ -356,8 +357,8 @@
}
persistActiveStats();
- mDatabase.prune();
- loadActiveStats();
+ mDatabase.prune(currentTimeMillis);
+ loadActiveStats(currentTimeMillis, false);
final int continueCount = continuePreviousDay.size();
for (int i = 0; i < continueCount; i++) {
@@ -366,12 +367,12 @@
for (IntervalStats stat : mCurrentStats) {
stat.update(name, beginTime, UsageEvents.Event.CONTINUE_PREVIOUS_DAY);
stat.updateConfigurationStats(previousConfig, beginTime);
- mStatsChanged = true;
+ notifyStatsChanged();
}
}
persistActiveStats();
- final long totalTime = System.currentTimeMillis() - startTime;
+ final long totalTime = SystemClock.elapsedRealtime() - startTime;
Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime
+ " milliseconds");
}
@@ -383,15 +384,16 @@
}
}
- private void loadActiveStats() {
- final long timeNow = System.currentTimeMillis();
-
+ /**
+ * @param force To force all in-memory stats to be reloaded.
+ */
+ private void loadActiveStats(final long currentTimeMillis, boolean force) {
final UnixCalendar tempCal = mDailyExpiryDate;
for (int intervalType = 0; intervalType < mCurrentStats.length; intervalType++) {
- tempCal.setTimeInMillis(timeNow);
+ tempCal.setTimeInMillis(currentTimeMillis);
UnixCalendar.truncateTo(tempCal, intervalType);
- if (mCurrentStats[intervalType] != null &&
+ if (!force && mCurrentStats[intervalType] != null &&
mCurrentStats[intervalType].beginTime == tempCal.getTimeInMillis()) {
// These are the same, no need to load them (in memory stats are always newer
// than persisted stats).
@@ -399,11 +401,7 @@
}
final long lastBeginTime = mDatabase.getLatestUsageStatsBeginTime(intervalType);
- if (lastBeginTime > timeNow) {
- Slog.e(TAG, mLogPrefix + "Latest usage stats for interval " +
- intervalType + " begins in the future");
- mCurrentStats[intervalType] = null;
- } else if (lastBeginTime >= tempCal.getTimeInMillis()) {
+ if (lastBeginTime >= tempCal.getTimeInMillis()) {
if (DEBUG) {
Slog.d(TAG, mLogPrefix + "Loading existing stats @ " +
sDateFormat.format(lastBeginTime) + "(" + lastBeginTime +
@@ -423,11 +421,11 @@
}
mCurrentStats[intervalType] = new IntervalStats();
mCurrentStats[intervalType].beginTime = tempCal.getTimeInMillis();
- mCurrentStats[intervalType].endTime = timeNow;
+ mCurrentStats[intervalType].endTime = currentTimeMillis;
}
}
mStatsChanged = false;
- mDailyExpiryDate.setTimeInMillis(timeNow);
+ mDailyExpiryDate.setTimeInMillis(currentTimeMillis);
mDailyExpiryDate.addDays(1);
mDailyExpiryDate.truncateToDay();
Slog.i(TAG, mLogPrefix + "Rollover scheduled @ " +
diff --git a/telecomm/java/android/telecomm/Call.java b/telecomm/java/android/telecomm/Call.java
index c3aa2a0..7ada9b1 100644
--- a/telecomm/java/android/telecomm/Call.java
+++ b/telecomm/java/android/telecomm/Call.java
@@ -108,7 +108,7 @@
/**
* @return The presentation requirements for the handle. See
- * {@link PropertyPresentation} for valid values.
+ * {@link TelecommManager} for valid values.
*/
public int getHandlePresentation() {
return mHandlePresentation;
@@ -123,7 +123,7 @@
/**
* @return The presentation requirements for the caller display name. See
- * {@link PropertyPresentation} for valid values.
+ * {@link TelecommManager} for valid values.
*/
public int getCallerDisplayNamePresentation() {
return mCallerDisplayNamePresentation;
@@ -482,13 +482,6 @@
}
/**
- * Notifies this {@code Call} that the phone account user interface element was touched.
- */
- public void phoneAccountClicked() {
- mInCallAdapter.phoneAccountClicked(mTelecommCallId);
- }
-
- /**
* Notifies this {@code Call} that an account has been selected and to proceed with placing
* an outgoing call.
*/
diff --git a/telecomm/java/android/telecomm/Conference.java b/telecomm/java/android/telecomm/Conference.java
index f9c3ac3..a4f9c2c 100644
--- a/telecomm/java/android/telecomm/Conference.java
+++ b/telecomm/java/android/telecomm/Conference.java
@@ -50,22 +50,47 @@
private int mCapabilities;
private String mDisconnectMessage;
+ /**
+ * Constructs a new Conference with a mandatory {@link PhoneAccountHandle}
+ *
+ * @param phoneAccount The {@code PhoneAccountHandle} associated with the conference.
+ */
public Conference(PhoneAccountHandle phoneAccount) {
mPhoneAccount = phoneAccount;
}
+ /**
+ * Returns the {@link PhoneAccountHandle} the conference call is being placed through.
+ *
+ * @return A {@code PhoneAccountHandle} object representing the PhoneAccount of the conference.
+ */
public final PhoneAccountHandle getPhoneAccountHandle() {
return mPhoneAccount;
}
+ /**
+ * Returns the list of connections currently associated with the conference call.
+ *
+ * @return A list of {@code Connection} objects which represent the children of the conference.
+ */
public final List<Connection> getConnections() {
return mUnmodifiableChildConnections;
}
+ /**
+ * Gets the state of the conference call. See {@link Connection} for valid values.
+ *
+ * @return A constant representing the state the conference call is currently in.
+ */
public final int getState() {
return mState;
}
+ /**
+ * Returns the capabilities of a conference. See {@link PhoneCapabilities} for valid values.
+ *
+ * @return A bitmask of the {@code PhoneCapabilities} of the conference call.
+ */
public final int getCapabilities() {
return mCapabilities;
}
@@ -135,7 +160,9 @@
}
/**
- * Sets the capabilities of a conference.
+ * Sets the capabilities of a conference. See {@link PhoneCapabilities} for valid values.
+ *
+ * @param capabilities A bitmask of the {@code PhoneCapabilities} of the conference call.
*/
public final void setCapabilities(int capabilities) {
if (capabilities != mCapabilities) {
@@ -170,7 +197,6 @@
* Removes the specified connection as a child of this conference.
*
* @param connection The connection to remove.
- * @return True if the connection was successfully removed.
*/
public final void removeConnection(Connection connection) {
Log.d(this, "removing %s from %s", connection, mChildConnections);
diff --git a/telecomm/java/android/telecomm/Connection.java b/telecomm/java/android/telecomm/Connection.java
index 03db1c3..2f25dcf 100644
--- a/telecomm/java/android/telecomm/Connection.java
+++ b/telecomm/java/android/telecomm/Connection.java
@@ -68,13 +68,13 @@
/** @hide */
public abstract static class Listener {
public void onStateChanged(Connection c, int state) {}
- public void onHandleChanged(Connection c, Uri newHandle, int presentation) {}
+ public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
public void onCallerDisplayNameChanged(
Connection c, String callerDisplayName, int presentation) {}
public void onVideoStateChanged(Connection c, int videoState) {}
public void onDisconnected(Connection c, int cause, String message) {}
public void onPostDialWait(Connection c, String remaining) {}
- public void onRequestingRingback(Connection c, boolean ringback) {}
+ public void onRingbackRequested(Connection c, boolean ringback) {}
public void onDestroyed(Connection c) {}
public void onCallCapabilitiesChanged(Connection c, int callCapabilities) {}
public void onVideoProviderChanged(
@@ -464,11 +464,11 @@
private int mState = STATE_NEW;
private AudioState mAudioState;
- private Uri mHandle;
- private int mHandlePresentation;
+ private Uri mAddress;
+ private int mAddressPresentation;
private String mCallerDisplayName;
private int mCallerDisplayNamePresentation;
- private boolean mRequestingRingback = false;
+ private boolean mRingbackRequested = false;
private int mCallCapabilities;
private VideoProvider mVideoProvider;
private boolean mAudioModeIsVoip;
@@ -485,17 +485,18 @@
public Connection() {}
/**
- * @return The handle (e.g., phone number) to which this Connection is currently communicating.
+ * @return The address (e.g., phone number) to which this Connection is currently communicating.
*/
- public final Uri getHandle() {
- return mHandle;
+ public final Uri getAddress() {
+ return mAddress;
}
/**
- * @return The {@link PropertyPresentation} which controls how the handle is shown.
+ * @return The presentation requirements for the address.
+ * See {@link TelecommManager} for valid values.
*/
- public final int getHandlePresentation() {
- return mHandlePresentation;
+ public final int getAddressPresentation() {
+ return mAddressPresentation;
}
/**
@@ -506,8 +507,8 @@
}
/**
- * @return The {@link PropertyPresentation} which controls how the caller display name is
- * shown.
+ * @return The presentation requirements for the handle.
+ * See {@link TelecommManager} for valid values.
*/
public final int getCallerDisplayNamePresentation() {
return mCallerDisplayNamePresentation;
@@ -555,8 +556,8 @@
* Returns whether this connection is requesting that the system play a ringback tone
* on its behalf.
*/
- public final boolean isRequestingRingback() {
- return mRequestingRingback;
+ public final boolean isRingbackRequested() {
+ return mRingbackRequested;
}
/**
@@ -624,7 +625,7 @@
final void setAudioState(AudioState state) {
Log.d(this, "setAudioState %s", state);
mAudioState = state;
- onSetAudioState(state);
+ onAudioStateChanged(state);
}
/**
@@ -661,18 +662,18 @@
}
/**
- * Sets the value of the {@link #getHandle()} property.
+ * Sets the value of the {@link #getAddress()} property.
*
- * @param handle The new handle.
- * @param presentation The {@link PropertyPresentation} which controls how the handle is
- * shown.
+ * @param address The new address.
+ * @param presentation The presentation requirements for the address.
+ * See {@link TelecommManager} for valid values.
*/
- public final void setHandle(Uri handle, int presentation) {
- Log.d(this, "setHandle %s", handle);
- mHandle = handle;
- mHandlePresentation = presentation;
+ public final void setAddress(Uri address, int presentation) {
+ Log.d(this, "setAddress %s", address);
+ mAddress = address;
+ mAddressPresentation = presentation;
for (Listener l : mListeners) {
- l.onHandleChanged(this, handle, presentation);
+ l.onAddressChanged(this, address, presentation);
}
}
@@ -680,8 +681,8 @@
* Sets the caller display name (CNAP).
*
* @param callerDisplayName The new display name.
- * @param presentation The {@link PropertyPresentation} which controls how the name is
- * shown.
+ * @param presentation The presentation requirements for the handle.
+ * See {@link TelecommManager} for valid values.
*/
public final void setCallerDisplayName(String callerDisplayName, int presentation) {
Log.d(this, "setCallerDisplayName %s", callerDisplayName);
@@ -715,7 +716,7 @@
* communicate).
*/
public final void setActive() {
- setRequestingRingback(false);
+ setRingbackRequested(false);
setState(STATE_ACTIVE);
}
@@ -803,11 +804,11 @@
*
* @param ringback Whether the ringback tone is to be played.
*/
- public final void setRequestingRingback(boolean ringback) {
- if (mRequestingRingback != ringback) {
- mRequestingRingback = ringback;
+ public final void setRingbackRequested(boolean ringback) {
+ if (mRingbackRequested != ringback) {
+ mRingbackRequested = ringback;
for (Listener l : mListeners) {
- l.onRequestingRingback(this, ringback);
+ l.onRingbackRequested(this, ringback);
}
}
}
@@ -945,7 +946,7 @@
*
* @param state The new call audio state.
*/
- public void onSetAudioState(AudioState state) {}
+ public void onAudioStateChanged(AudioState state) {}
/**
* Notifies this Connection of an internal state change. This method is called after the
@@ -953,7 +954,7 @@
*
* @param state The new state, one of the {@code STATE_*} constants.
*/
- public void onSetState(int state) {}
+ public void onStateChanged(int state) {}
/**
* Notifies this Connection of a request to play a DTMF tone.
@@ -1021,11 +1022,6 @@
public void onPostDialContinue(boolean proceed) {}
/**
- * Called when the phone account UI was clicked.
- */
- public void onPhoneAccountClicked() {}
-
- /**
* Merge this connection and the specified connection into a conference call. Once the
* connections are merged, the calls should be added to the an existing or new
* {@code Conference} instance. For new {@code Conference} instances, use
@@ -1068,7 +1064,7 @@
if (mState != state) {
Log.d(this, "setState: %s", stateToString(state));
mState = state;
- onSetState(state);
+ onStateChanged(state);
for (Listener l : mListeners) {
l.onStateChanged(this, state);
}
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 39365b6..036d397 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -69,7 +69,6 @@
private static final int MSG_CONFERENCE = 12;
private static final int MSG_SPLIT_FROM_CONFERENCE = 13;
private static final int MSG_ON_POST_DIAL_CONTINUE = 14;
- private static final int MSG_ON_PHONE_ACCOUNT_CLICKED = 15;
private static final int MSG_REMOVE_CONNECTION_SERVICE_ADAPTER = 16;
private static final int MSG_ANSWER_VIDEO = 17;
private static final int MSG_MERGE_CONFERENCE = 18;
@@ -200,11 +199,6 @@
args.argi1 = proceed ? 1 : 0;
mHandler.obtainMessage(MSG_ON_POST_DIAL_CONTINUE, args).sendToTarget();
}
-
- @Override
- public void onPhoneAccountClicked(String callId) {
- mHandler.obtainMessage(MSG_ON_PHONE_ACCOUNT_CLICKED, callId).sendToTarget();
- }
};
private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@@ -327,9 +321,6 @@
}
break;
}
- case MSG_ON_PHONE_ACCOUNT_CLICKED:
- onPhoneAccountHandleClicked((String) msg.obj);
- break;
default:
break;
}
@@ -423,9 +414,9 @@
}
@Override
- public void onHandleChanged(Connection c, Uri handle, int presentation) {
+ public void onAddressChanged(Connection c, Uri address, int presentation) {
String id = mIdByConnection.get(c);
- mAdapter.setHandle(id, handle, presentation);
+ mAdapter.setAddress(id, address, presentation);
}
@Override
@@ -448,10 +439,10 @@
}
@Override
- public void onRequestingRingback(Connection c, boolean ringback) {
+ public void onRingbackRequested(Connection c, boolean ringback) {
String id = mIdByConnection.get(c);
Log.d(this, "Adapter onRingback %b", ringback);
- mAdapter.setRequestingRingback(id, ringback);
+ mAdapter.setRingbackRequested(id, ringback);
}
@Override
@@ -471,7 +462,7 @@
@Override
public void onAudioModeIsVoipChanged(Connection c, boolean isVoip) {
String id = mIdByConnection.get(c);
- mAdapter.setAudioModeIsVoip(id, isVoip);
+ mAdapter.setIsVoipAudioMode(id, isVoip);
}
@Override
@@ -532,8 +523,8 @@
addConnection(callId, connection);
}
- Uri handle = connection.getHandle();
- String number = handle == null ? "null" : handle.getSchemeSpecificPart();
+ Uri address = connection.getAddress();
+ String number = address == null ? "null" : address.getSchemeSpecificPart();
Log.v(this, "createConnection, number: %s, state: %s, capabilities: %s",
Connection.toLogSafePhoneNumber(number),
Connection.stateToString(connection.getState()),
@@ -547,14 +538,14 @@
request.getAccountHandle(),
connection.getState(),
connection.getCallCapabilities(),
- connection.getHandle(),
- connection.getHandlePresentation(),
+ connection.getAddress(),
+ connection.getAddressPresentation(),
connection.getCallerDisplayName(),
connection.getCallerDisplayNamePresentation(),
connection.getVideoProvider() == null ?
null : connection.getVideoProvider().getInterface(),
connection.getVideoState(),
- connection.isRequestingRingback(),
+ connection.isRingbackRequested(),
connection.getAudioModeIsVoip(),
connection.getStatusHints(),
connection.getDisconnectCause(),
@@ -678,11 +669,6 @@
findConnectionForAction(callId, "stopDtmfTone").onPostDialContinue(proceed);
}
- private void onPhoneAccountHandleClicked(String callId) {
- Log.d(this, "onPhoneAccountClicked %s", callId);
- findConnectionForAction(callId, "onPhoneAccountClicked").onPhoneAccountClicked();
- }
-
private void onAdapterAttached() {
if (mAreAccountsInitialized) {
// No need to query again if we already did it.
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
index e3dc713..19f42d6 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapter.java
@@ -168,10 +168,10 @@
* @param callId The unique ID of the call whose ringback is being changed.
* @param ringback Whether Telecomm should start playing a ringback tone.
*/
- void setRequestingRingback(String callId, boolean ringback) {
+ void setRingbackRequested(String callId, boolean ringback) {
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
- adapter.setRequestingRingback(callId, ringback);
+ adapter.setRingbackRequested(callId, ringback);
} catch (RemoteException e) {
}
}
@@ -280,10 +280,10 @@
* @param callId The unique ID of the call to set with the given call video provider.
* @param isVoip True if the audio mode is VOIP.
*/
- void setAudioModeIsVoip(String callId, boolean isVoip) {
+ void setIsVoipAudioMode(String callId, boolean isVoip) {
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
- adapter.setAudioModeIsVoip(callId, isVoip);
+ adapter.setIsVoipAudioMode(callId, isVoip);
} catch (RemoteException e) {
}
}
@@ -298,10 +298,10 @@
}
}
- void setHandle(String callId, Uri handle, int presentation) {
+ void setAddress(String callId, Uri address, int presentation) {
for (IConnectionServiceAdapter adapter : mAdapters) {
try {
- adapter.setHandle(callId, handle, presentation);
+ adapter.setAddress(callId, address, presentation);
} catch (RemoteException e) {
}
}
diff --git a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
index 21e99db..2aac7fc 100644
--- a/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecomm/ConnectionServiceAdapterServant.java
@@ -44,7 +44,7 @@
private static final int MSG_SET_DIALING = 4;
private static final int MSG_SET_DISCONNECTED = 5;
private static final int MSG_SET_ON_HOLD = 6;
- private static final int MSG_SET_REQUESTING_RINGBACK = 7;
+ private static final int MSG_SET_RINGBACK_REQUESTED = 7;
private static final int MSG_SET_CALL_CAPABILITIES = 8;
private static final int MSG_SET_IS_CONFERENCED = 9;
private static final int MSG_ADD_CONFERENCE_CALL = 10;
@@ -53,9 +53,9 @@
private static final int MSG_QUERY_REMOTE_CALL_SERVICES = 13;
private static final int MSG_SET_VIDEO_STATE = 14;
private static final int MSG_SET_VIDEO_CALL_PROVIDER = 15;
- private static final int MSG_SET_AUDIO_MODE_IS_VOIP = 16;
+ private static final int MSG_SET_IS_VOIP_AUDIO_MODE = 16;
private static final int MSG_SET_STATUS_HINTS = 17;
- private static final int MSG_SET_HANDLE = 18;
+ private static final int MSG_SET_ADDRESS = 18;
private static final int MSG_SET_CALLER_DISPLAY_NAME = 19;
private static final int MSG_SET_CONFERENCEABLE_CONNECTIONS = 20;
@@ -107,8 +107,8 @@
case MSG_SET_ON_HOLD:
mDelegate.setOnHold((String) msg.obj);
break;
- case MSG_SET_REQUESTING_RINGBACK:
- mDelegate.setRequestingRingback((String) msg.obj, msg.arg1 == 1);
+ case MSG_SET_RINGBACK_REQUESTED:
+ mDelegate.setRingbackRequested((String) msg.obj, msg.arg1 == 1);
break;
case MSG_SET_CALL_CAPABILITIES:
mDelegate.setCallCapabilities((String) msg.obj, msg.arg1);
@@ -160,8 +160,8 @@
}
break;
}
- case MSG_SET_AUDIO_MODE_IS_VOIP:
- mDelegate.setAudioModeIsVoip((String) msg.obj, msg.arg1 == 1);
+ case MSG_SET_IS_VOIP_AUDIO_MODE:
+ mDelegate.setIsVoipAudioMode((String) msg.obj, msg.arg1 == 1);
break;
case MSG_SET_STATUS_HINTS: {
SomeArgs args = (SomeArgs) msg.obj;
@@ -172,10 +172,10 @@
}
break;
}
- case MSG_SET_HANDLE: {
+ case MSG_SET_ADDRESS: {
SomeArgs args = (SomeArgs) msg.obj;
try {
- mDelegate.setHandle((String) args.arg1, (Uri) args.arg2, args.argi1);
+ mDelegate.setAddress((String) args.arg1, (Uri) args.arg2, args.argi1);
} finally {
args.recycle();
}
@@ -249,8 +249,8 @@
}
@Override
- public void setRequestingRingback(String connectionId, boolean ringback) {
- mHandler.obtainMessage(MSG_SET_REQUESTING_RINGBACK, ringback ? 1 : 0, 0, connectionId)
+ public void setRingbackRequested(String connectionId, boolean ringback) {
+ mHandler.obtainMessage(MSG_SET_RINGBACK_REQUESTED, ringback ? 1 : 0, 0, connectionId)
.sendToTarget();
}
@@ -308,8 +308,8 @@
}
@Override
- public final void setAudioModeIsVoip(String connectionId, boolean isVoip) {
- mHandler.obtainMessage(MSG_SET_AUDIO_MODE_IS_VOIP, isVoip ? 1 : 0, 0,
+ public final void setIsVoipAudioMode(String connectionId, boolean isVoip) {
+ mHandler.obtainMessage(MSG_SET_IS_VOIP_AUDIO_MODE, isVoip ? 1 : 0, 0,
connectionId).sendToTarget();
}
@@ -322,12 +322,12 @@
}
@Override
- public final void setHandle(String connectionId, Uri handle, int presentation) {
+ public final void setAddress(String connectionId, Uri address, int presentation) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = connectionId;
- args.arg2 = handle;
+ args.arg2 = address;
args.argi1 = presentation;
- mHandler.obtainMessage(MSG_SET_HANDLE, args).sendToTarget();
+ mHandler.obtainMessage(MSG_SET_ADDRESS, args).sendToTarget();
}
@Override
diff --git a/telecomm/java/android/telecomm/GatewayInfo.java b/telecomm/java/android/telecomm/GatewayInfo.java
index b95e6b6..a720284 100644
--- a/telecomm/java/android/telecomm/GatewayInfo.java
+++ b/telecomm/java/android/telecomm/GatewayInfo.java
@@ -16,6 +16,7 @@
package android.telecomm;
+import android.annotation.SystemApi;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,14 +34,15 @@
public class GatewayInfo implements Parcelable {
private final String mGatewayProviderPackageName;
- private final Uri mGatewayHandle;
- private final Uri mOriginalHandle;
+ private final Uri mGatewayAddress;
+ private final Uri mOriginalAddress;
/** @hide */
- public GatewayInfo(String packageName, Uri gatewayUri, Uri originalHandle) {
+ @SystemApi
+ public GatewayInfo(String packageName, Uri gatewayUri, Uri originalAddress) {
mGatewayProviderPackageName = packageName;
- mGatewayHandle = gatewayUri;
- mOriginalHandle = originalHandle;
+ mGatewayAddress = gatewayUri;
+ mOriginalAddress = originalAddress;
}
/**
@@ -51,21 +53,21 @@
}
/**
- * Gateway provider handle to use when actually placing the call.
+ * Gateway provider address to use when actually placing the call.
*/
- public Uri getGatewayHandle() {
- return mGatewayHandle;
+ public Uri getGatewayAddress() {
+ return mGatewayAddress;
}
/**
- * The actual call handle that the user is trying to connect to via the gateway.
+ * The actual call address that the user is trying to connect to via the gateway.
*/
- public Uri getOriginalHandle() {
- return mOriginalHandle;
+ public Uri getOriginalAddress() {
+ return mOriginalAddress;
}
public boolean isEmpty() {
- return TextUtils.isEmpty(mGatewayProviderPackageName) || mGatewayHandle == null;
+ return TextUtils.isEmpty(mGatewayProviderPackageName) || mGatewayAddress == null;
}
/** Implement the Parcelable interface */
@@ -76,8 +78,8 @@
public GatewayInfo createFromParcel(Parcel source) {
String gatewayPackageName = source.readString();
Uri gatewayUri = Uri.CREATOR.createFromParcel(source);
- Uri originalHandle = Uri.CREATOR.createFromParcel(source);
- return new GatewayInfo(gatewayPackageName, gatewayUri, originalHandle);
+ Uri originalAddress = Uri.CREATOR.createFromParcel(source);
+ return new GatewayInfo(gatewayPackageName, gatewayUri, originalAddress);
}
@Override
@@ -100,7 +102,7 @@
@Override
public void writeToParcel(Parcel destination, int flags) {
destination.writeString(mGatewayProviderPackageName);
- mGatewayHandle.writeToParcel(destination, 0);
- mOriginalHandle.writeToParcel(destination, 0);
+ mGatewayAddress.writeToParcel(destination, 0);
+ mOriginalAddress.writeToParcel(destination, 0);
}
}
diff --git a/telecomm/java/android/telecomm/InCallAdapter.java b/telecomm/java/android/telecomm/InCallAdapter.java
index 96ea5a6..899f35e 100644
--- a/telecomm/java/android/telecomm/InCallAdapter.java
+++ b/telecomm/java/android/telecomm/InCallAdapter.java
@@ -189,18 +189,6 @@
}
/**
- * Instructs Telecomm that the phone account UI was clicked.
- *
- * @param callId The identifier of the call.
- */
- public void phoneAccountClicked(String callId) {
- try {
- mAdapter.phoneAccountClicked(callId);
- } catch (RemoteException e) {
- }
- }
-
- /**
* Instructs Telecomm to add a PhoneAccountHandle to the specified call
*
* @param callId The identifier of the call
diff --git a/telecomm/java/android/telecomm/ParcelableCall.java b/telecomm/java/android/telecomm/ParcelableCall.java
index a2aa192..f7fc125 100644
--- a/telecomm/java/android/telecomm/ParcelableCall.java
+++ b/telecomm/java/android/telecomm/ParcelableCall.java
@@ -153,7 +153,9 @@
return mHandle;
}
- /** The {@link PropertyPresentation} which controls how the handle is shown. */
+ /**
+ * The presentation requirements for the handle. See {@link TelecommManager} for valid values.
+ */
public int getHandlePresentation() {
return mHandlePresentation;
}
@@ -163,7 +165,10 @@
return mCallerDisplayName;
}
- /** The {@link PropertyPresentation} which controls how the caller display name is shown. */
+ /**
+ * The presentation requirements for the caller display name.
+ * See {@link TelecommManager} for valid values.
+ */
public int getCallerDisplayNamePresentation() {
return mCallerDisplayNamePresentation;
}
diff --git a/telecomm/java/android/telecomm/ParcelableConnection.java b/telecomm/java/android/telecomm/ParcelableConnection.java
index 2e21d37..cadcd85 100644
--- a/telecomm/java/android/telecomm/ParcelableConnection.java
+++ b/telecomm/java/android/telecomm/ParcelableConnection.java
@@ -35,14 +35,14 @@
private final PhoneAccountHandle mPhoneAccount;
private final int mState;
private final int mCapabilities;
- private final Uri mHandle;
- private final int mHandlePresentation;
+ private final Uri mAddress;
+ private final int mAddressPresentation;
private final String mCallerDisplayName;
private final int mCallerDisplayNamePresentation;
private final IVideoProvider mVideoProvider;
private final int mVideoState;
- private final boolean mRequestingRingback;
- private final boolean mAudioModeIsVoip;
+ private final boolean mRingbackRequested;
+ private final boolean mIsVoipAudioMode;
private final StatusHints mStatusHints;
private final int mDisconnectCause;
private final String mDisconnectMessage;
@@ -53,14 +53,14 @@
PhoneAccountHandle phoneAccount,
int state,
int capabilities,
- Uri handle,
- int handlePresentation,
+ Uri address,
+ int addressPresentation,
String callerDisplayName,
int callerDisplayNamePresentation,
IVideoProvider videoProvider,
int videoState,
- boolean requestingRingback,
- boolean audioModeIsVoip,
+ boolean ringbackRequested,
+ boolean isVoipAudioMode,
StatusHints statusHints,
int disconnectCause,
String disconnectMessage,
@@ -68,14 +68,14 @@
mPhoneAccount = phoneAccount;
mState = state;
mCapabilities = capabilities;
- mHandle = handle;
- mHandlePresentation = handlePresentation;
+ mAddress = address;
+ mAddressPresentation = addressPresentation;
mCallerDisplayName = callerDisplayName;
mCallerDisplayNamePresentation = callerDisplayNamePresentation;
mVideoProvider = videoProvider;
mVideoState = videoState;
- mRequestingRingback = requestingRingback;
- mAudioModeIsVoip = audioModeIsVoip;
+ mRingbackRequested = ringbackRequested;
+ mIsVoipAudioMode = isVoipAudioMode;
mStatusHints = statusHints;
mDisconnectCause = disconnectCause;
mDisconnectMessage = disconnectMessage;
@@ -96,11 +96,11 @@
}
public Uri getHandle() {
- return mHandle;
+ return mAddress;
}
public int getHandlePresentation() {
- return mHandlePresentation;
+ return mAddressPresentation;
}
public String getCallerDisplayName() {
@@ -119,12 +119,12 @@
return mVideoState;
}
- public boolean isRequestingRingback() {
- return mRequestingRingback;
+ public boolean isRingbackRequested() {
+ return mRingbackRequested;
}
- public boolean getAudioModeIsVoip() {
- return mAudioModeIsVoip;
+ public boolean getIsVoipAudioMode() {
+ return mIsVoipAudioMode;
}
public final StatusHints getStatusHints() {
@@ -164,14 +164,14 @@
PhoneAccountHandle phoneAccount = source.readParcelable(classLoader);
int state = source.readInt();
int capabilities = source.readInt();
- Uri handle = source.readParcelable(classLoader);
- int handlePresentation = source.readInt();
+ Uri address = source.readParcelable(classLoader);
+ int addressPresentation = source.readInt();
String callerDisplayName = source.readString();
int callerDisplayNamePresentation = source.readInt();
IVideoProvider videoCallProvider =
IVideoProvider.Stub.asInterface(source.readStrongBinder());
int videoState = source.readInt();
- boolean requestingRingback = source.readByte() == 1;
+ boolean ringbackRequested = source.readByte() == 1;
boolean audioModeIsVoip = source.readByte() == 1;
StatusHints statusHints = source.readParcelable(classLoader);
int disconnectCauseCode = source.readInt();
@@ -183,13 +183,13 @@
phoneAccount,
state,
capabilities,
- handle,
- handlePresentation,
+ address,
+ addressPresentation,
callerDisplayName,
callerDisplayNamePresentation,
videoCallProvider,
videoState,
- requestingRingback,
+ ringbackRequested,
audioModeIsVoip,
statusHints,
disconnectCauseCode,
@@ -215,15 +215,15 @@
destination.writeParcelable(mPhoneAccount, 0);
destination.writeInt(mState);
destination.writeInt(mCapabilities);
- destination.writeParcelable(mHandle, 0);
- destination.writeInt(mHandlePresentation);
+ destination.writeParcelable(mAddress, 0);
+ destination.writeInt(mAddressPresentation);
destination.writeString(mCallerDisplayName);
destination.writeInt(mCallerDisplayNamePresentation);
destination.writeStrongBinder(
mVideoProvider != null ? mVideoProvider.asBinder() : null);
destination.writeInt(mVideoState);
- destination.writeByte((byte) (mRequestingRingback ? 1 : 0));
- destination.writeByte((byte) (mAudioModeIsVoip ? 1 : 0));
+ destination.writeByte((byte) (mRingbackRequested ? 1 : 0));
+ destination.writeByte((byte) (mIsVoipAudioMode ? 1 : 0));
destination.writeParcelable(mStatusHints, 0);
destination.writeInt(mDisconnectCause);
destination.writeString(mDisconnectMessage);
diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java
index f709a86..b37c144 100644
--- a/telecomm/java/android/telecomm/PhoneAccount.java
+++ b/telecomm/java/android/telecomm/PhoneAccount.java
@@ -83,6 +83,25 @@
public static final int CAPABILITY_VIDEO_CALLING = 0x8;
/**
+ * Flag indicating that this {@code PhoneAccount} is capable of placing emergency calls.
+ * By default all PSTN {@code PhoneAccount}s are capable of placing emergency calls.
+ * <p>
+ * See {@link #getCapabilities}
+ */
+ public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 0x10;
+
+ /**
+ * Flag indicating that this {@code PhoneAccount} is always enabled and cannot be disabled by
+ * the user.
+ * This capability is reserved for important {@code PhoneAccount}s such as the emergency calling
+ * only {@code PhoneAccount}.
+ * <p>
+ * See {@link #getCapabilities}
+ * @hide
+ */
+ public static final int CAPABILITY_ALWAYS_ENABLED = 0x20;
+
+ /**
* URI scheme for telephone number URIs.
*/
public static final String SCHEME_TEL = "tel";
@@ -105,6 +124,7 @@
private final CharSequence mLabel;
private final CharSequence mShortDescription;
private final List<String> mSupportedUriSchemes;
+ private final boolean mIsEnabled;
public static class Builder {
private PhoneAccountHandle mAccountHandle;
@@ -115,12 +135,31 @@
private CharSequence mLabel;
private CharSequence mShortDescription;
private List<String> mSupportedUriSchemes = new ArrayList<String>();
+ private boolean mIsEnabled = false;
public Builder(PhoneAccountHandle accountHandle, CharSequence label) {
this.mAccountHandle = accountHandle;
this.mLabel = label;
}
+ /**
+ * Creates an instance of the {@link PhoneAccount.Builder} from an existing
+ * {@link PhoneAccount}.
+ *
+ * @param phoneAccount The {@link PhoneAccount} used to initialize the builder.
+ */
+ public Builder(PhoneAccount phoneAccount) {
+ mAccountHandle = phoneAccount.getAccountHandle();
+ mAddress = phoneAccount.getAddress();
+ mSubscriptionAddress = phoneAccount.getSubscriptionAddress();
+ mCapabilities = phoneAccount.getCapabilities();
+ mIconResId = phoneAccount.getIconResId();
+ mLabel = phoneAccount.getLabel();
+ mShortDescription = phoneAccount.getShortDescription();
+ mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes());
+ mIsEnabled = phoneAccount.isEnabled();
+ }
+
public Builder setAddress(Uri value) {
this.mAddress = value;
return this;
@@ -177,6 +216,24 @@
return this;
}
+ /**
+ * Specifies whether the {@link PhoneAccount} is enabled or not. {@link PhoneAccount}s are
+ * by default not enabled.
+ *
+ * @param value {@code True} if the {@link PhoneAccount} is enabled.
+ * @return The Builder.
+ * @hide
+ */
+ public Builder setEnabled(boolean value) {
+ this.mIsEnabled = value;
+ return this;
+ }
+
+ /**
+ * Creates an instance of a {@link PhoneAccount} based on the current builder settings.
+ *
+ * @return The {@link PhoneAccount}.
+ */
public PhoneAccount build() {
// If no supported URI schemes were defined, assume "tel" is supported.
if (mSupportedUriSchemes.isEmpty()) {
@@ -191,7 +248,8 @@
mIconResId,
mLabel,
mShortDescription,
- mSupportedUriSchemes);
+ mSupportedUriSchemes,
+ mIsEnabled);
}
}
@@ -203,7 +261,8 @@
int iconResId,
CharSequence label,
CharSequence shortDescription,
- List<String> supportedUriSchemes) {
+ List<String> supportedUriSchemes,
+ boolean enabled) {
mAccountHandle = account;
mAddress = address;
mSubscriptionAddress = subscriptionAddress;
@@ -212,6 +271,7 @@
mLabel = label;
mShortDescription = shortDescription;
mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
+ mIsEnabled = enabled;
}
public static Builder builder(
@@ -221,6 +281,14 @@
}
/**
+ * Returns a builder initialized with the current {@link PhoneAccount} instance.
+ *
+ * @return The builder.
+ * @hide
+ */
+ public Builder toBuilder() { return new Builder(this); }
+
+ /**
* The unique identifier of this {@code PhoneAccount}.
*
* @return A {@code PhoneAccountHandle}.
@@ -265,6 +333,17 @@
}
/**
+ * Determines if this {@code PhoneAccount} has a capabilities specified by the passed in
+ * bit mask.
+ *
+ * @param capability The capabilities to check.
+ * @return {@code True} if the phone account has the capability.
+ */
+ public boolean hasCapabilities(int capability) {
+ return (mCapabilities & capability) == capability;
+ }
+
+ /**
* A short label describing a {@code PhoneAccount}.
*
* @return A label for this {@code PhoneAccount}.
@@ -313,6 +392,15 @@
}
/**
+ * Determines whether this {@code PhoneAccount} is enabled.
+ *
+ * @return {@code True} if this {@code PhoneAccount} is enabled..
+ */
+ public boolean isEnabled() {
+ return mIsEnabled;
+ }
+
+ /**
* The icon resource ID for the icon of this {@code PhoneAccount}.
*
* @return A resource ID.
@@ -367,6 +455,7 @@
out.writeCharSequence(mLabel);
out.writeCharSequence(mShortDescription);
out.writeList(mSupportedUriSchemes);
+ out.writeInt(mIsEnabled ? 1 : 0);
}
public static final Creator<PhoneAccount> CREATOR
@@ -396,5 +485,6 @@
List<String> supportedUriSchemes = new ArrayList<>();
in.readList(supportedUriSchemes, classLoader);
mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes);
+ mIsEnabled = in.readInt() == 1;
}
}
diff --git a/telecomm/java/android/telecomm/PhoneCapabilities.java b/telecomm/java/android/telecomm/PhoneCapabilities.java
index 7a338b4..ec11376 100644
--- a/telecomm/java/android/telecomm/PhoneCapabilities.java
+++ b/telecomm/java/android/telecomm/PhoneCapabilities.java
@@ -78,8 +78,19 @@
*/
public static final int VoWIFI = 0x00000800;
- public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CONFERENCE | SWAP_CONFERENCE | ADD_CALL
- | RESPOND_VIA_TEXT | MUTE | MANAGE_CONFERENCE;
+ /**
+ * Call is able to be separated from its parent {@code Conference}, if any.
+ */
+ public static final int SEPARATE_FROM_CONFERENCE = 0x00001000;
+
+ /**
+ * Call is able to be individually disconnected when in a {@code Conference}.
+ */
+ public static final int DISCONNECT_FROM_CONFERENCE = 0x00002000;
+
+ public static final int ALL = HOLD | SUPPORT_HOLD | MERGE_CONFERENCE | SWAP_CONFERENCE
+ | ADD_CALL | RESPOND_VIA_TEXT | MUTE | MANAGE_CONFERENCE | SEPARATE_FROM_CONFERENCE
+ | DISCONNECT_FROM_CONFERENCE;
public static String toString(int capabilities) {
StringBuilder builder = new StringBuilder();
diff --git a/telecomm/java/android/telecomm/PropertyPresentation.java b/telecomm/java/android/telecomm/PropertyPresentation.java
deleted file mode 100644
index fe97b3d..0000000
--- a/telecomm/java/android/telecomm/PropertyPresentation.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2014, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telecomm;
-
-/**
- * Defines how properties such as phone numbers and names are displayed to the user.
- */
-public class PropertyPresentation {
- /** Property is displayed normally. */
- public static final int ALLOWED = 1;
-
- /** Property was blocked. */
- public static final int RESTRICTED = 2;
-
- /** Presentation was not specified or is unknown. */
- public static final int UNKNOWN = 3;
-
- /** Property should be displayed as a pay phone. */
- public static final int PAYPHONE = 4;
-}
diff --git a/telecomm/java/android/telecomm/RemoteConference.java b/telecomm/java/android/telecomm/RemoteConference.java
index b073827..dbff079 100644
--- a/telecomm/java/android/telecomm/RemoteConference.java
+++ b/telecomm/java/android/telecomm/RemoteConference.java
@@ -188,11 +188,11 @@
return mDisconnectMessage;
}
- public final void addCallback(Callback callback) {
+ public final void registerCallback(Callback callback) {
mCallbacks.add(callback);
}
- public final void removeCallback(Callback callback) {
+ public final void unregisterCallback(Callback callback) {
mCallbacks.remove(callback);
}
}
diff --git a/telecomm/java/android/telecomm/RemoteConnection.java b/telecomm/java/android/telecomm/RemoteConnection.java
index 8ad8d19..f3a6085 100644
--- a/telecomm/java/android/telecomm/RemoteConnection.java
+++ b/telecomm/java/android/telecomm/RemoteConnection.java
@@ -42,7 +42,7 @@
*/
public final class RemoteConnection {
- public static abstract class Listener {
+ public static abstract class Callback {
/**
* Invoked when the state of this {@code RemoteConnection} has changed. See
* {@link #getState()}.
@@ -53,25 +53,6 @@
public void onStateChanged(RemoteConnection connection, int state) {}
/**
- * Invoked when the parent of this {@code RemoteConnection} has changed. See
- * {@link #getParent()}.
- *
- * @param connection The {@code RemoteConnection} invoking this method.
- * @param parent The new parent of the {@code RemoteConnection}.
- */
- public void onParentChanged(RemoteConnection connection, RemoteConnection parent) {}
-
- /**
- * Invoked when the children of this {@code RemoteConnection} have changed. See
- * {@link #getChildren()}.
- *
- * @param connection The {@code RemoteConnection} invoking this method.
- * @param children The new children of the {@code RemoteConnection}.
- */
- public void onChildrenChanged(
- RemoteConnection connection, List<RemoteConnection> children) {}
-
- /**
* Invoked when this {@code RemoteConnection} is disconnected.
*
* @param connection The {@code RemoteConnection} invoking this method.
@@ -87,12 +68,12 @@
/**
* Invoked when this {@code RemoteConnection} is requesting ringback. See
- * {@link #isRequestingRingback()}.
+ * {@link #isRingbackRequested()}.
*
* @param connection The {@code RemoteConnection} invoking this method.
* @param ringback Whether the {@code RemoteConnection} is requesting ringback.
*/
- public void onRequestingRingback(RemoteConnection connection, boolean ringback) {}
+ public void onRingbackRequested(RemoteConnection connection, boolean ringback) {}
/**
* Indicates that the call capabilities of this {@code RemoteConnection} have changed.
@@ -116,12 +97,12 @@
/**
* Indicates that the VOIP audio status of this {@code RemoteConnection} has changed.
- * See {@link #getAudioModeIsVoip()}.
+ * See {@link #isVoipAudioMode()}.
*
* @param connection The {@code RemoteConnection} invoking this method.
* @param isVoip Whether the new audio state of the {@code RemoteConnection} is VOIP.
*/
- public void onAudioModeIsVoipChanged(RemoteConnection connection, boolean isVoip) {}
+ public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {}
/**
* Indicates that the status hints of this {@code RemoteConnection} have changed. See
@@ -133,15 +114,15 @@
public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {}
/**
- * Indicates that the handle (e.g., phone number) of this {@code RemoteConnection} has
- * changed. See {@link #getHandle()} and {@link #getHandlePresentation()}.
+ * Indicates that the address (e.g., phone number) of this {@code RemoteConnection} has
+ * changed. See {@link #getAddress()} and {@link #getAddressPresentation()}.
*
* @param connection The {@code RemoteConnection} invoking this method.
- * @param handle The new handle of the {@code RemoteConnection}.
- * @param presentation The {@link PropertyPresentation} which controls how the
- * handle is shown.
+ * @param address The new address of the {@code RemoteConnection}.
+ * @param presentation The presentation requirements for the address.
+ * See {@link TelecommManager} for valid values.
*/
- public void onHandleChanged(RemoteConnection connection, Uri handle, int presentation) {}
+ public void onAddressChanged(RemoteConnection connection, Uri address, int presentation) {}
/**
* Indicates that the caller display name of this {@code RemoteConnection} has changed.
@@ -149,8 +130,8 @@
*
* @param connection The {@code RemoteConnection} invoking this method.
* @param callerDisplayName The new caller display name of the {@code RemoteConnection}.
- * @param presentation The {@link PropertyPresentation} which controls how the
- * caller display name is shown.
+ * @param presentation The presentation requirements for the handle.
+ * See {@link TelecommManager} for valid values.
*/
public void onCallerDisplayNameChanged(
RemoteConnection connection, String callerDisplayName, int presentation) {}
@@ -396,8 +377,8 @@
* load factor before resizing, 1 means we only expect a single thread to
* access the map so make only a single shard
*/
- private final Set<Listener> mListeners = Collections.newSetFromMap(
- new ConcurrentHashMap<Listener, Boolean>(8, 0.9f, 1));
+ private final Set<Callback> mCallbacks = Collections.newSetFromMap(
+ new ConcurrentHashMap<Callback, Boolean>(8, 0.9f, 1));
private final List<RemoteConnection> mConferenceableConnections = new ArrayList<>();
private final List<RemoteConnection> mUnmodifiableconferenceableConnections =
Collections.unmodifiableList(mConferenceableConnections);
@@ -405,15 +386,15 @@
private int mState = Connection.STATE_NEW;
private int mDisconnectCauseCode = DisconnectCause.NOT_VALID;
private String mDisconnectCauseMessage;
- private boolean mRequestingRingback;
+ private boolean mRingbackRequested;
private boolean mConnected;
private int mCallCapabilities;
private int mVideoState;
private VideoProvider mVideoProvider;
- private boolean mAudioModeIsVoip;
+ private boolean mIsVoipAudioMode;
private StatusHints mStatusHints;
- private Uri mHandle;
- private int mHandlePresentation;
+ private Uri mAddress;
+ private int mAddressPresentation;
private String mCallerDisplayName;
private int mCallerDisplayNamePresentation;
private int mFailureCode;
@@ -450,42 +431,26 @@
}
/**
- * Adds a listener to this {@code RemoteConnection}.
+ * Adds a callback to this {@code RemoteConnection}.
*
- * @param listener A {@code Listener}.
+ * @param callback A {@code Callback}.
*/
- public void addListener(Listener listener) {
- mListeners.add(listener);
+ public void registerCallback(Callback callback) {
+ mCallbacks.add(callback);
}
/**
- * Removes a listener from this {@code RemoteConnection}.
+ * Removes a callback from this {@code RemoteConnection}.
*
- * @param listener A {@code Listener}.
+ * @param callback A {@code Callback}.
*/
- public void removeListener(Listener listener) {
- if (listener != null) {
- mListeners.remove(listener);
+ public void unregisterCallback(Callback callback) {
+ if (callback != null) {
+ mCallbacks.remove(callback);
}
}
/**
- * Obtains the parent of this {@code RemoteConnection} in a conference, if any.
- *
- * @return The parent {@code RemoteConnection}, or {@code null} if this {@code RemoteConnection}
- * is not a child of any conference {@code RemoteConnection}s.
- */
- public RemoteConnection getParent() { return null; }
-
- /**
- * Obtains the children of this conference {@code RemoteConnection}, if any.
- *
- * @return The children of this {@code RemoteConnection} if this {@code RemoteConnection} is
- * a conference, or an empty {@code List} otherwise.
- */
- public List<RemoteConnection> getChildren() { return new ArrayList<>(); }
-
- /**
* Obtains the state of this {@code RemoteConnection}.
*
* @return A state value, chosen from the {@code STATE_*} constants.
@@ -522,8 +487,8 @@
/**
* @return {@code true} if the {@code RemoteConnection}'s current audio mode is VOIP.
*/
- public boolean getAudioModeIsVoip() {
- return mAudioModeIsVoip;
+ public boolean isVoipAudioMode() {
+ return mIsVoipAudioMode;
}
/**
@@ -535,31 +500,31 @@
}
/**
- * @return The handle (e.g., phone number) to which the {@code RemoteConnection} is currently
+ * @return The address (e.g., phone number) to which the {@code RemoteConnection} is currently
* connected.
*/
- public Uri getHandle() {
- return mHandle;
+ public Uri getAddress() {
+ return mAddress;
}
/**
- * @return The presentation requirements for the handle. See
- * {@link PropertyPresentation} for valid values.
+ * @return The presentation requirements for the address. See {@link TelecommManager} for valid
+ * values.
*/
- public int getHandlePresentation() {
- return mHandlePresentation;
+ public int getAddressPresentation() {
+ return mAddressPresentation;
}
/**
* @return The display name for the caller.
*/
- public String getCallerDisplayName() {
+ public CharSequence getCallerDisplayName() {
return mCallerDisplayName;
}
/**
* @return The presentation requirements for the caller display name. See
- * {@link PropertyPresentation} for valid values.
+ * {@link TelecommManager} for valid values.
*/
public int getCallerDisplayNamePresentation() {
return mCallerDisplayNamePresentation;
@@ -601,7 +566,7 @@
* @return Whether the {@code RemoteConnection} is requesting that the framework play a
* ringback tone on its behalf.
*/
- public boolean isRequestingRingback() {
+ public boolean isRingbackRequested() {
return false;
}
@@ -738,8 +703,8 @@
* of time.
*
* If the DTMF string contains a {@link TelecommManager#DTMF_CHARACTER_WAIT} symbol, this
- * {@code RemoteConnection} will pause playing the tones and notify listeners via
- * {@link Listener#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
+ * {@code RemoteConnection} will pause playing the tones and notify callbackss via
+ * {@link Callback#onPostDialWait(RemoteConnection, String)}. At this point, the in-call app
* should display to the user an indication of this state and an affordance to continue
* the postdial sequence. When the user decides to continue the postdial sequence, the in-call
* app should invoke the {@link #postDialContinue(boolean)} method.
@@ -806,8 +771,8 @@
void setState(int state) {
if (mState != state) {
mState = state;
- for (Listener l: mListeners) {
- l.onStateChanged(this, state);
+ for (Callback c: mCallbacks) {
+ c.onStateChanged(this, state);
}
}
}
@@ -821,8 +786,8 @@
mDisconnectCauseCode = cause;
mDisconnectCauseMessage = message;
- for (Listener l : mListeners) {
- l.onDisconnected(this, cause, message);
+ for (Callback c : mCallbacks) {
+ c.onDisconnected(this, cause, message);
}
}
}
@@ -830,11 +795,11 @@
/**
* @hide
*/
- void setRequestingRingback(boolean ringback) {
- if (mRequestingRingback != ringback) {
- mRequestingRingback = ringback;
- for (Listener l : mListeners) {
- l.onRequestingRingback(this, ringback);
+ void setRingbackRequested(boolean ringback) {
+ if (mRingbackRequested != ringback) {
+ mRingbackRequested = ringback;
+ for (Callback c : mCallbacks) {
+ c.onRingbackRequested(this, ringback);
}
}
}
@@ -844,8 +809,8 @@
*/
void setCallCapabilities(int callCapabilities) {
mCallCapabilities = callCapabilities;
- for (Listener l : mListeners) {
- l.onCallCapabilitiesChanged(this, callCapabilities);
+ for (Callback c : mCallbacks) {
+ c.onCallCapabilitiesChanged(this, callCapabilities);
}
}
@@ -853,16 +818,16 @@
* @hide
*/
void setDestroyed() {
- if (!mListeners.isEmpty()) {
- // Make sure that the listeners are notified that the call is destroyed first.
+ if (!mCallbacks.isEmpty()) {
+ // Make sure that the callbacks are notified that the call is destroyed first.
if (mState != Connection.STATE_DISCONNECTED) {
setDisconnected(DisconnectCause.ERROR_UNSPECIFIED, "Connection destroyed.");
}
- for (Listener l : mListeners) {
- l.onDestroyed(this);
+ for (Callback c : mCallbacks) {
+ c.onDestroyed(this);
}
- mListeners.clear();
+ mCallbacks.clear();
mConnected = false;
}
@@ -872,8 +837,8 @@
* @hide
*/
void setPostDialWait(String remainingDigits) {
- for (Listener l : mListeners) {
- l.onPostDialWait(this, remainingDigits);
+ for (Callback c : mCallbacks) {
+ c.onPostDialWait(this, remainingDigits);
}
}
@@ -882,8 +847,8 @@
*/
void setVideoState(int videoState) {
mVideoState = videoState;
- for (Listener l : mListeners) {
- l.onVideoStateChanged(this, videoState);
+ for (Callback c : mCallbacks) {
+ c.onVideoStateChanged(this, videoState);
}
}
@@ -892,33 +857,33 @@
*/
void setVideoProvider(VideoProvider videoProvider) {
mVideoProvider = videoProvider;
- for (Listener l : mListeners) {
- l.onVideoProviderChanged(this, videoProvider);
+ for (Callback c : mCallbacks) {
+ c.onVideoProviderChanged(this, videoProvider);
}
}
/** @hide */
- void setAudioModeIsVoip(boolean isVoip) {
- mAudioModeIsVoip = isVoip;
- for (Listener l : mListeners) {
- l.onAudioModeIsVoipChanged(this, isVoip);
+ void setIsVoipAudioMode(boolean isVoip) {
+ mIsVoipAudioMode = isVoip;
+ for (Callback c : mCallbacks) {
+ c.onVoipAudioChanged(this, isVoip);
}
}
/** @hide */
void setStatusHints(StatusHints statusHints) {
mStatusHints = statusHints;
- for (Listener l : mListeners) {
- l.onStatusHintsChanged(this, statusHints);
+ for (Callback c : mCallbacks) {
+ c.onStatusHintsChanged(this, statusHints);
}
}
/** @hide */
- void setHandle(Uri handle, int presentation) {
- mHandle = handle;
- mHandlePresentation = presentation;
- for (Listener l : mListeners) {
- l.onHandleChanged(this, handle, presentation);
+ void setAddress(Uri address, int presentation) {
+ mAddress = address;
+ mAddressPresentation = presentation;
+ for (Callback c : mCallbacks) {
+ c.onAddressChanged(this, address, presentation);
}
}
@@ -926,8 +891,8 @@
void setCallerDisplayName(String callerDisplayName, int presentation) {
mCallerDisplayName = callerDisplayName;
mCallerDisplayNamePresentation = presentation;
- for (Listener l : mListeners) {
- l.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
+ for (Callback c : mCallbacks) {
+ c.onCallerDisplayNameChanged(this, callerDisplayName, presentation);
}
}
@@ -935,8 +900,8 @@
void setConferenceableConnections(List<RemoteConnection> conferenceableConnections) {
mConferenceableConnections.clear();
mConferenceableConnections.addAll(conferenceableConnections);
- for (Listener l : mListeners) {
- l.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections);
+ for (Callback c : mCallbacks) {
+ c.onConferenceableConnectionsChanged(this, mUnmodifiableconferenceableConnections);
}
}
@@ -944,8 +909,8 @@
void setConference(RemoteConference conference) {
if (mConference != conference) {
mConference = conference;
- for (Listener l : mListeners) {
- l.onConferenceChanged(this, conference);
+ for (Callback c : mCallbacks) {
+ c.onConferenceChanged(this, conference);
}
}
}
diff --git a/telecomm/java/android/telecomm/RemoteConnectionService.java b/telecomm/java/android/telecomm/RemoteConnectionService.java
index 348c36c..d4dd9af 100644
--- a/telecomm/java/android/telecomm/RemoteConnectionService.java
+++ b/telecomm/java/android/telecomm/RemoteConnectionService.java
@@ -60,13 +60,14 @@
if (connection != NULL_CONNECTION && mPendingConnections.contains(connection)) {
mPendingConnections.remove(connection);
// Unconditionally initialize the connection ...
- connection.setState(parcel.getState());
connection.setCallCapabilities(parcel.getCapabilities());
- connection.setHandle(
+ connection.setAddress(
parcel.getHandle(), parcel.getHandlePresentation());
connection.setCallerDisplayName(
parcel.getCallerDisplayName(),
parcel.getCallerDisplayNamePresentation());
+ // Set state after handle so that the client can identify the connection.
+ connection.setState(parcel.getState());
List<RemoteConnection> conferenceable = new ArrayList<>();
for (String confId : parcel.getConferenceableConnectionIds()) {
if (mConnectionById.containsKey(confId)) {
@@ -130,9 +131,9 @@
}
@Override
- public void setRequestingRingback(String callId, boolean ringing) {
- findConnectionForAction(callId, "setRequestingRingback")
- .setRequestingRingback(ringing);
+ public void setRingbackRequested(String callId, boolean ringing) {
+ findConnectionForAction(callId, "setRingbackRequested")
+ .setRingbackRequested(ringing);
}
@Override
@@ -191,7 +192,7 @@
conference.setState(parcel.getState());
conference.setCallCapabilities(parcel.getCapabilities());
mConferenceById.put(callId, conference);
- conference.addCallback(new RemoteConference.Callback() {
+ conference.registerCallback(new RemoteConference.Callback() {
@Override
public void onDestroyed(RemoteConference c) {
mConferenceById.remove(callId);
@@ -237,9 +238,9 @@
}
@Override
- public void setAudioModeIsVoip(String callId, boolean isVoip) {
- findConnectionForAction(callId, "setAudioModeIsVoip")
- .setAudioModeIsVoip(isVoip);
+ public void setIsVoipAudioMode(String callId, boolean isVoip) {
+ findConnectionForAction(callId, "setIsVoipAudioMode")
+ .setIsVoipAudioMode(isVoip);
}
@Override
@@ -249,9 +250,9 @@
}
@Override
- public void setHandle(String callId, Uri handle, int presentation) {
- findConnectionForAction(callId, "setHandle")
- .setHandle(handle, presentation);
+ public void setAddress(String callId, Uri address, int presentation) {
+ findConnectionForAction(callId, "setAddress")
+ .setAddress(address, presentation);
}
@Override
@@ -342,7 +343,7 @@
id,
newRequest,
isIncoming);
- connection.addListener(new RemoteConnection.Listener() {
+ connection.registerCallback(new RemoteConnection.Callback() {
@Override
public void onDestroyed(RemoteConnection connection) {
mConnectionById.remove(id);
diff --git a/telecomm/java/android/telecomm/Response.java b/telecomm/java/android/telecomm/Response.java
index f879756..ad78ebd 100644
--- a/telecomm/java/android/telecomm/Response.java
+++ b/telecomm/java/android/telecomm/Response.java
@@ -17,10 +17,7 @@
package android.telecomm;
/**
- * <strong>OBSOLETE</strong> Used to inform a client of asynchronously returned results.
- * <p>
- * <strong>TODO:</strong> Remove onCreateConferenceConnection() async method
- * then delete this interface.
+ * @hide
*/
public interface Response<IN, OUT> {
diff --git a/telecomm/java/android/telecomm/TelecommManager.java b/telecomm/java/android/telecomm/TelecommManager.java
index 5e9e6d0..e2c98cd 100644
--- a/telecomm/java/android/telecomm/TelecommManager.java
+++ b/telecomm/java/android/telecomm/TelecommManager.java
@@ -25,6 +25,7 @@
import com.android.internal.telecomm.ITelecommService;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/**
@@ -69,6 +70,24 @@
"android.telecomm.action.CHANGE_PHONE_ACCOUNTS";
/**
+ * The {@link android.content.Intent} action used to inform a
+ * {@link android.telecomm.ConnectionService} that one of its {@link PhoneAccount}s has been
+ * enabled. The {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
+ * which {@link PhoneAccount} has been enabled.
+ */
+ public static final String ACTION_PHONE_ACCOUNT_ENABLED =
+ "android.telecom.action.PHONE_ACCOUNT_ENABLED";
+
+ /**
+ * The {@link android.content.Intent} action used to inform a
+ * {@link android.telecomm.ConnectionService} that one of its {@link PhoneAccount}s has been
+ * disabled. The {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE} extra is used to indicate
+ * which {@link PhoneAccount} has been disabled.
+ */
+ public static final String ACTION_PHONE_ACCOUNT_DISABLED =
+ "android.telecom.action.PHONE_ACCOUNT_DISABLED";
+
+ /**
* Optional extra for {@link android.content.Intent#ACTION_CALL} containing a boolean that
* determines whether the speakerphone should be automatically turned on for an outgoing call.
*/
@@ -141,6 +160,30 @@
"android.telecomm.extra.CONNECTION_SERVICE";
/**
+ * An optional {@link android.content.Intent#ACTION_CALL} intent extra denoting the
+ * package name of the app specifying an alternative gateway for the call.
+ * The value is a string.
+ *
+ * (The following comment corresponds to the all GATEWAY_* extras)
+ * An app which sends the {@link android.content.Intent#ACTION_CALL} intent can specify an
+ * alternative address to dial which is different from the one specified and displayed to
+ * the user. This alternative address is referred to as the gateway address.
+ */
+ public static final String GATEWAY_PROVIDER_PACKAGE =
+ "android.telecomm.extra.GATEWAY_PROVIDER_PACKAGE";
+
+ /**
+ * An optional {@link android.content.Intent#ACTION_CALL} intent extra corresponding to the
+ * original address to dial for the call. This is used when an alternative gateway address is
+ * provided to recall the original address.
+ * The value is a {@link android.net.Uri}.
+ *
+ * (See {@link #GATEWAY_PROVIDER_PACKAGE} for details)
+ */
+ public static final String GATEWAY_ORIGINAL_ADDRESS =
+ "android.telecomm.extra.GATEWAY_ORIGINAL_ADDRESS";
+
+ /**
* The number which the party on the other side of the line will see (and use to return the
* call).
* <p>
@@ -238,6 +281,23 @@
public static final String EXTRA_TTY_PREFERRED_MODE =
"android.telecomm.intent.extra.TTY_PREFERRED";
+ /**
+ * The following 4 constants define how properties such as phone numbers and names are
+ * displayed to the user.
+ */
+
+ /** Property is displayed normally. */
+ public static final int PRESENTATION_ALLOWED = 1;
+
+ /** Property was blocked. */
+ public static final int PRESENTATION_RESTRICTED = 2;
+
+ /** Presentation was not specified or is unknown. */
+ public static final int PRESENTATION_UNKNOWN = 3;
+
+ /** Property should be displayed as a pay phone. */
+ public static final int PRESENTATION_PAYPHONE = 4;
+
private static final String TAG = "TelecommManager";
private static final String TELECOMM_SERVICE_NAME = "telecomm";
@@ -270,7 +330,7 @@
* <p>
* Apps must be prepared for this method to return {@code null}, indicating that there currently
* exists no user-chosen default {@code PhoneAccount}. In this case, apps wishing to initiate a
- * phone call must either create their {@link android.content .Intent#ACTION_CALL} or
+ * phone call must either create their {@link android.content.Intent#ACTION_CALL} or
* {@link android.content.Intent#ACTION_DIAL} {@code Intent} with no
* {@link TelecommManager#EXTRA_PHONE_ACCOUNT_HANDLE}, or present the user with an affordance to
* select one of the elements of {@link #getEnabledPhoneAccounts()}.
@@ -330,8 +390,8 @@
}
/**
- * Return a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
- * calls.
+ * Return a list of enabled {@link PhoneAccountHandle}s which can be used to make and receive
+ * phone calls.
*
* @see #EXTRA_PHONE_ACCOUNT_HANDLE
* @return A list of {@code PhoneAccountHandle} objects.
@@ -339,10 +399,10 @@
public List<PhoneAccountHandle> getEnabledPhoneAccounts() {
try {
if (isServiceConnected()) {
- return getTelecommService().getOutgoingPhoneAccounts();
+ return getTelecommService().getEnabledPhoneAccounts();
}
} catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelecommService#getOutgoingPhoneAccounts", e);
+ Log.e(TAG, "Error calling ITelecommService#getEnabledPhoneAccounts", e);
}
return new ArrayList<>();
}
@@ -408,8 +468,8 @@
}
/**
- * Returns a list of {@link PhoneAccountHandle}s which can be used to make and receive phone
- * calls which support the specified URI scheme.
+ * Returns a list of the enabled {@link PhoneAccountHandle}s which can be used to make and
+ * receive phone calls which support the specified URI scheme.
* <P>
* For example, invoking with {@code "tel"} will find all {@link PhoneAccountHandle}s which
* support telephone calls (e.g. URIs such as {@code tel:555-555-1212}). Invoking with
@@ -459,6 +519,78 @@
}
/**
+ * Returns a count of enabled and disabled {@link PhoneAccount}s.
+ *
+ * @return The count of enabled and disabled {@link PhoneAccount}s.
+ * @hide
+ */
+ @SystemApi
+ public int getAllPhoneAccountsCount() {
+ try {
+ if (isServiceConnected()) {
+ return getTelecommService().getAllPhoneAccountsCount();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecommService#getAllPhoneAccountsCount", e);
+ }
+ return 0;
+ }
+
+ /**
+ * Returns a list of all {@link PhoneAccount}s.
+ *
+ * @return All {@link PhoneAccount}s.
+ * @hide
+ */
+ @SystemApi
+ public List<PhoneAccount> getAllPhoneAccounts() {
+ try {
+ if (isServiceConnected()) {
+ return getTelecommService().getAllPhoneAccounts();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecommService#getAllPhoneAccounts", e);
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
+ * Returns a list of all {@link PhoneAccountHandle}s.
+ *
+ * @return All {@link PhoneAccountHandle}s.
+ * @hide
+ */
+ @SystemApi
+ public List<PhoneAccountHandle> getAllPhoneAccountHandles() {
+ try {
+ if (isServiceConnected()) {
+ return getTelecommService().getAllPhoneAccountHandles();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecommService#getAllPhoneAccountHandles", e);
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ /**
+ * Enables or disables a {@link PhoneAccount}.
+ *
+ * @param account The {@link PhoneAccountHandle} to enable or disable.
+ * @param isEnabled {@code True} if the phone account should be enabled.
+ * @hide
+ */
+ @SystemApi
+ public void setPhoneAccountEnabled(PhoneAccountHandle account, boolean isEnabled) {
+ try {
+ if (isServiceConnected()) {
+ getTelecommService().setPhoneAccountEnabled(account, isEnabled);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecommService#setPhoneAccountEnabled", e);
+ }
+ }
+
+ /**
* Register a {@link PhoneAccount} for use by the system.
*
* @param account The complete {@link PhoneAccount}.
@@ -489,15 +621,13 @@
}
/**
- * Remove all Accounts for a given package from the system.
- *
- * @param packageName A package name that may have registered Accounts.
+ * Remove all Accounts that belong to the calling package from the system.
*/
@SystemApi
- public void clearAccounts(String packageName) {
+ public void clearAccounts() {
try {
if (isServiceConnected()) {
- getTelecommService().clearAccounts(packageName);
+ getTelecommService().clearAccounts(mContext.getPackageName());
}
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecommService#clearAccounts", e);
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl
index a673733..3af4ed3 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionService.aidl
@@ -70,6 +70,4 @@
void swapConference(String conferenceCallId);
void onPostDialContinue(String callId, boolean proceed);
-
- void onPhoneAccountClicked(String callId);
}
diff --git a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
index 610178e..4b636d1 100644
--- a/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IConnectionServiceAdapter.aidl
@@ -49,7 +49,7 @@
void setOnHold(String callId);
- void setRequestingRingback(String callId, boolean ringing);
+ void setRingbackRequested(String callId, boolean ringing);
void setCallCapabilities(String callId, int callCapabilities);
@@ -67,11 +67,11 @@
void setVideoState(String callId, int videoState);
- void setAudioModeIsVoip(String callId, boolean isVoip);
+ void setIsVoipAudioMode(String callId, boolean isVoip);
void setStatusHints(String callId, in StatusHints statusHints);
- void setHandle(String callId, in Uri handle, int presentation);
+ void setAddress(String callId, in Uri address, int presentation);
void setCallerDisplayName(String callId, String callerDisplayName, int presentation);
diff --git a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
index 626bb91..808a410 100644
--- a/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl
@@ -46,8 +46,6 @@
void postDialContinue(String callId, boolean proceed);
- void phoneAccountClicked(String callId);
-
void phoneAccountSelected(String callId, in PhoneAccountHandle accountHandle);
void conference(String callId, String otherCallId);
diff --git a/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
index 6ab78c4..30f2801 100644
--- a/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
+++ b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
@@ -50,9 +50,9 @@
void setUserSelectedOutgoingPhoneAccount(in PhoneAccountHandle account);
/**
- * @see TelecommServiceImpl#getOutgoingPhoneAccounts
+ * @see TelecommServiceImpl#getEnabledPhoneAccounts
*/
- List<PhoneAccountHandle> getOutgoingPhoneAccounts();
+ List<PhoneAccountHandle> getEnabledPhoneAccounts();
/**
* @see TelecommManager#getPhoneAccountsSupportingScheme
@@ -65,6 +65,21 @@
PhoneAccount getPhoneAccount(in PhoneAccountHandle account);
/**
+ * @see TelecommManager#getAllPhoneAccountsCount
+ */
+ int getAllPhoneAccountsCount();
+
+ /**
+ * @see TelecommManager#getAllPhoneAccounts
+ */
+ List<PhoneAccount> getAllPhoneAccounts();
+
+ /**
+ * @see TelecommManager#getAllPhoneAccountHandles
+ */
+ List<PhoneAccountHandle> getAllPhoneAccountHandles();
+
+ /**
* @see TelecommServiceImpl#getSimCallManager
*/
PhoneAccountHandle getSimCallManager();
@@ -80,6 +95,11 @@
List<PhoneAccountHandle> getSimCallManagers();
/**
+ * @see TelecommServiceImpl#setPhoneAccountEnabled
+ */
+ void setPhoneAccountEnabled(in PhoneAccountHandle account, in boolean isEnabled);
+
+ /**
* @see TelecommServiceImpl#registerPhoneAccount
*/
void registerPhoneAccount(in PhoneAccount metadata);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index d0f355e..fe68263 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -930,13 +930,20 @@
/** @hide */
public static boolean isValidSlotId(int slotId) {
- return slotId > INVALID_SLOT_ID && slotId < TelephonyManager.getDefault().getSimCount();
+ // We are testing INVALID_SLOT_ID and slotId >= 0 independently because we should
+ // not assume that INVALID_SLOT_ID will always be a negative value. Any negative
+ // value is invalid.
+ return slotId != INVALID_SLOT_ID && slotId >= 0 &&
+ slotId < TelephonyManager.getDefault().getSimCount();
}
/** @hide */
public static boolean isValidPhoneId(int phoneId) {
- return phoneId > INVALID_PHONE_ID
- && phoneId < TelephonyManager.getDefault().getPhoneCount();
+ // We are testing INVALID_PHONE_ID and phoneId >= 0 independently because we should
+ // not assume that INVALID_PHONE_ID will always be a negative value. Any negative
+ // value is invalid.
+ return phoneId != INVALID_PHONE_ID && phoneId >= 0 &&
+ phoneId < TelephonyManager.getDefault().getPhoneCount();
}
/** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d53be4f..9f94040 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1738,10 +1738,10 @@
}
/**
- * Set the phone number string and its alphatag for line 1 for display
- * purpose only, for example, displayed in Phone Status. It won't change
- * the actual MSISDN/MDN. This setting won't be persisted during power cycle
- * and it should be set again after reboot.
+ * Set the line 1 phone number string and its alphatag for the current ICCID
+ * for display purpose only, for example, displayed in Phone Status. It won't
+ * change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
+ * value.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
@@ -1755,10 +1755,10 @@
}
/**
- * Set the phone number string and its alphatag for line 1 for display
- * purpose only, for example, displayed in Phone Status. It won't change
- * the actual MSISDN/MDN. This setting won't be persisted during power cycle
- * and it should be set again after reboot.
+ * Set the line 1 phone number string and its alphatag for the current ICCID
+ * for display purpose only, for example, displayed in Phone Status. It won't
+ * change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
+ * value.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
@@ -3359,8 +3359,8 @@
}
/**
- * Set whether Android should display a simplified Mobile Network Settings UI.
- * The setting won't be persisted during power cycle.
+ * Set whether Android should display a simplified Mobile Network Settings UI
+ * for the current ICCID.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
@@ -3374,8 +3374,8 @@
}
/**
- * Set whether Android should display a simplified Mobile Network Settings UI.
- * The setting won't be persisted during power cycle.
+ * Set whether Android should display a simplified Mobile Network Settings UI
+ * for the current ICCID.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
@@ -3394,7 +3394,8 @@
}
/**
- * Get whether a simplified Mobile Network Settings UI is enabled.
+ * Get whether a simplified Mobile Network Settings UI is enabled for the
+ * current ICCID.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
@@ -3407,7 +3408,8 @@
}
/**
- * Get whether a simplified Mobile Network Settings UI is enabled.
+ * Get whether a simplified Mobile Network Settings UI is enabled for the
+ * current ICCID.
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index fa9cad4..0868f41 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -709,8 +709,8 @@
List<String> getCarrierPackageNamesForIntent(in Intent intent);
/**
- * Set whether Android should display a simplified Mobile Network Settings UI.
- * The setting won't be persisted during power cycle.
+ * Set whether Android should display a simplified Mobile Network Settings UI
+ * for the current ICCID.
*
* @param subId for which the simplified UI should be enabled or disabled.
* @param enable true means enabling the simplified UI.
@@ -718,7 +718,8 @@
void enableSimplifiedNetworkSettingsForSubscriber(long subId, boolean enable);
/**
- * Get whether a simplified Mobile Network Settings UI is enabled.
+ * Get whether a simplified Mobile Network Settings UI is enabled for the
+ * current ICCID.
*
* @param subId for which the simplified UI should be enabled or disabled.
* @return true if the simplified UI is enabled.
@@ -726,10 +727,10 @@
boolean getSimplifiedNetworkSettingsEnabledForSubscriber(long subId);
/**
- * Set the phone number string and its alphatag for line 1 for display
- * purpose only, for example, displayed in Phone Status. It won't change
- * the actual MSISDN/MDN. This setting won't be persisted during power cycle
- * and it should be set again after reboot.
+ * Set the line 1 phone number string and its alphatag for the current ICCID
+ * for display purpose only, for example, displayed in Phone Status. It won't
+ * change the actual MSISDN/MDN. To unset alphatag or number, pass in a null
+ * value.
*
* @param subId the subscriber that the alphatag and dialing number belongs to.
* @param alphaTag alpha-tagging of the dailing nubmer
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index 5a4e0eb..afe1d5d 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -790,24 +790,6 @@
/**
* @hide
*/
- @Override
- public void addCrossProfileIntentsForPackage(String packageName, int sourceUserId,
- int targetUserId) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * @hide
- */
- @Override
- public void removeCrossProfileIntentsForPackage(String packageName, int sourceUserId,
- int targetUserId) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * @hide
- */
public Drawable loadItemIcon(PackageItemInfo itemInfo, ApplicationInfo appInfo) {
throw new UnsupportedOperationException();
}
diff --git a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
index a68e04e..9df11fe 100644
--- a/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
+++ b/tests/JobSchedulerTestApp/src/com/android/demo/jobSchedulerApp/service/TestJobService.java
@@ -29,6 +29,7 @@
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
+import android.widget.Toast;
import com.android.demo.jobSchedulerApp.MainActivity;
@@ -84,12 +85,15 @@
currentId++;
jobParamsMap.put(currentId, params);
final int currId = this.currentId;
- Log.d(TAG, "putting :" + currId + " for " + params.toString());
- Log.d(TAG, " pulled: " + jobParamsMap.get(currId));
if (mActivity != null) {
mActivity.onReceivedStartJob(params);
}
+ Toast.makeText(
+ this, "On start job: '" + params.getJobId() + "' deadline exceeded: " +
+ params.isOverrideDeadlineExpired(),
+ Toast.LENGTH_LONG).show();
+
return true;
}
@@ -100,7 +104,7 @@
int ind = jobParamsMap.indexOfValue(params);
jobParamsMap.remove(ind);
mActivity.onReceivedStopJob();
- return true;
+ return false; // no reschedule
}
static int currentId = 0;
@@ -129,6 +133,7 @@
return false;
} else {
jobFinished(params, false);
+ jobParamsMap.removeAt(0);
return true;
}
}
diff --git a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
index 2ec620b..52527d9 100644
--- a/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/PowerTest.java
@@ -77,9 +77,9 @@
mProx.release();
}
},
- new Test("Disable proximity (WAIT_FOR_DISTANT_PROXIMITY") {
+ new Test("Disable proximity (RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY") {
public void run() {
- mProx.release(PowerManager.WAIT_FOR_DISTANT_PROXIMITY);
+ mProx.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
}
},
new Test("Enable proximity, wait 5 seconds then disable") {
@@ -93,13 +93,14 @@
}, 5000);
}
},
- new Test("Enable proximity, wait 5 seconds then disable (WAIT_FOR_DISTANT_PROXIMITY)") {
+ new Test("Enable proximity, wait 5 seconds then disable " +
+ "(RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY)") {
public void run() {
mProx.acquire();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- mProx.release(PowerManager.WAIT_FOR_DISTANT_PROXIMITY);
+ mProx.release(PowerManager.RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY);
}
}, 5000);
}
diff --git a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
index 31e7c38..d9a3b61 100644
--- a/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
+++ b/tests/UsageStatsTest/src/com/android/tests/usagestats/UsageLogActivity.java
@@ -86,7 +86,10 @@
}
mEvents.addFirst(event);
}
- notifyDataSetChanged();
+
+ if (lastTimeStamp != 0) {
+ notifyDataSetChanged();
+ }
return lastTimeStamp;
}
diff --git a/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml b/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml
index bbf1a17..f94ecba1 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_drawable05.xml
@@ -28,7 +28,8 @@
l-5.046875,0.0 0.0-1.0Z" />
<path
android:name="two"
- android:fillColor="#00ffff00"
+ android:fillColor="#ffff00"
+ android:fillAlpha="0"
android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0-5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
q 0.234375-0.453125 0.234375-0.875 0.0-0.703125-0.5-1.140625
diff --git a/tests/VectorDrawableTest/res/drawable/vector_icon_schedule.xml b/tests/VectorDrawableTest/res/drawable/vector_icon_schedule.xml
index 1aad743..3f79968 100644
--- a/tests/VectorDrawableTest/res/drawable/vector_icon_schedule.xml
+++ b/tests/VectorDrawableTest/res/drawable/vector_icon_schedule.xml
@@ -21,10 +21,12 @@
<group>
<path
- android:fillColor="#E6000000"
+ android:fillColor="#FF000000"
+ android:fillAlpha="0.9"
android:pathData="M11.994999,2.0C6.4679985,2.0 2.0,6.4780006 2.0,12.0s4.468,10.0 9.995,10.0S22.0,17.522 22.0,12.0S17.521,2.0 11.994999,2.0zM12.0,20.0c-4.42,0.0 -8.0,-3.582 -8.0,-8.0s3.58,-8.0 8.0,-8.0s8.0,3.582 8.0,8.0S16.419998,20.0 12.0,20.0z" />
<path
- android:fillColor="#E6000000"
+ android:fillColor="#FF000000"
+ android:fillAlpha="0.9"
android:pathData="M12.5,6.0l-1.5,0.0 0.0,7.0 5.3029995,3.1819992 0.75,-1.249999 -4.5529995,-2.7320004z" />
</group>
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 27e60f3..41d8502 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -2390,7 +2390,8 @@
char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
while (packageString != NULL) {
// Write the R.java file out with the correct package name
- err = writeResourceSymbols(bundle, assets, String8(packageString), true, false);
+ err = writeResourceSymbols(bundle, assets, String8(packageString), true,
+ bundle->getBuildSharedLibrary());
if (err < 0) {
goto bail;
}
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 5deeca2..afec5ed 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1926,110 +1926,75 @@
return String16();
}
-static void writeResourceLoadedCallback(FILE* fp, int indent) {
- IndentPrinter p(fp, 4);
- p.indent(indent);
- p.println("private static void rewriteIntArrayField(java.lang.reflect.Field field, int packageId) throws IllegalAccessException {");
- {
- p.indent();
- p.println("int requiredModifiers = java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.PUBLIC;");
- p.println("if ((field.getModifiers() & requiredModifiers) != requiredModifiers) {");
- {
- p.indent();
- p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not rewritable\");");
- p.indent(-1);
- }
- p.println("}");
- p.println("if (field.getType() != int[].class) {");
- {
- p.indent();
- p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not an int array\");");
- p.indent(-1);
- }
- p.println("}");
- p.println("int[] array = (int[]) field.get(null);");
- p.println("for (int i = 0; i < array.length; i++) {");
- {
- p.indent();
- p.println("array[i] = (array[i] & 0x00ffffff) | (packageId << 24);");
- p.indent(-1);
- }
- p.println("}");
- p.indent(-1);
+static status_t writeResourceLoadedCallbackForLayoutClasses(
+ FILE* fp, const sp<AaptAssets>& assets,
+ const sp<AaptSymbols>& symbols, int indent, bool includePrivate)
+{
+ String16 attr16("attr");
+ String16 package16(assets->getPackage());
+
+ const char* indentStr = getIndentSpace(indent);
+ bool hasErrors = false;
+
+ size_t i;
+ size_t N = symbols->getNestedSymbols().size();
+ for (i=0; i<N; i++) {
+ sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
+ String8 realClassName(symbols->getNestedSymbols().keyAt(i));
+ String8 nclassName(flattenSymbol(realClassName));
+
+ fprintf(fp,
+ "%sfor(int i = 0; i < styleable.%s.length; ++i) {\n"
+ "%sstyleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | (packageId << 24);\n"
+ "%s}\n",
+ indentStr, nclassName.string(),
+ getIndentSpace(indent+1), nclassName.string(), nclassName.string(),
+ indentStr);
}
- p.println("}");
- p.println();
- p.println("private static void rewriteIntField(java.lang.reflect.Field field, int packageId) throws IllegalAccessException {");
- {
- p.indent();
- p.println("int requiredModifiers = java.lang.reflect.Modifier.STATIC | java.lang.reflect.Modifier.PUBLIC;");
- p.println("int bannedModifiers = java.lang.reflect.Modifier.FINAL;");
- p.println("int mod = field.getModifiers();");
- p.println("if ((mod & requiredModifiers) != requiredModifiers || (mod & bannedModifiers) != 0) {");
- {
- p.indent();
- p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not rewritable\");");
- p.indent(-1);
+
+ return hasErrors ? UNKNOWN_ERROR : NO_ERROR;
+}
+
+static status_t writeResourceLoadedCallback(
+ FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
+ const sp<AaptSymbols>& symbols, const String8& className, int indent)
+{
+ size_t i;
+ status_t err = NO_ERROR;
+
+ size_t N = symbols->getSymbols().size();
+ for (i=0; i<N; i++) {
+ const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
+ if (sym.typeCode == AaptSymbolEntry::TYPE_UNKNOWN) {
+ continue;
}
- p.println("}");
- p.println("if (field.getType() != int.class && field.getType() != Integer.class) {");
- {
- p.indent();
- p.println("throw new IllegalArgumentException(\"Field \" + field.getName() + \" is not an int\");");
- p.indent(-1);
+ if (!assets->isJavaSymbol(sym, includePrivate)) {
+ continue;
}
- p.println("}");
- p.println("int resId = field.getInt(null);");
- p.println("field.setInt(null, (resId & 0x00ffffff) | (packageId << 24));");
- p.indent(-1);
+ String8 flat_name(flattenSymbol(sym.name));
+ fprintf(fp,
+ "%s%s.%s = (%s.%s & 0x00ffffff) | (packageId << 24);\n",
+ getIndentSpace(indent), className.string(), flat_name.string(),
+ className.string(), flat_name.string());
}
- p.println("}");
- p.println();
- p.println("public static void onResourcesLoaded(int assignedPackageId) throws Exception {");
- {
- p.indent();
- p.println("Class<?>[] declaredClasses = R.class.getDeclaredClasses();");
- p.println("for (Class<?> clazz : declaredClasses) {");
- {
- p.indent();
- p.println("if (clazz.getSimpleName().equals(\"styleable\")) {");
- {
- p.indent();
- p.println("for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {");
- {
- p.indent();
- p.println("if (field.getType() == int[].class) {");
- {
- p.indent();
- p.println("rewriteIntArrayField(field, assignedPackageId);");
- p.indent(-1);
- }
- p.println("}");
- p.indent(-1);
- }
- p.println("}");
- p.indent(-1);
- }
- p.println("} else {");
- {
- p.indent();
- p.println("for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {");
- {
- p.indent();
- p.println("rewriteIntField(field, assignedPackageId);");
- p.indent(-1);
- }
- p.println("}");
- p.indent(-1);
- }
- p.println("}");
- p.indent(-1);
+
+ N = symbols->getNestedSymbols().size();
+ for (i=0; i<N; i++) {
+ sp<AaptSymbols> nsymbols = symbols->getNestedSymbols().valueAt(i);
+ String8 nclassName(symbols->getNestedSymbols().keyAt(i));
+ if (nclassName == "styleable") {
+ err = writeResourceLoadedCallbackForLayoutClasses(
+ fp, assets, nsymbols, indent, includePrivate);
+ } else {
+ err = writeResourceLoadedCallback(fp, assets, includePrivate, nsymbols,
+ nclassName, indent);
}
- p.println("}");
- p.indent(-1);
+ if (err != NO_ERROR) {
+ return err;
+ }
}
- p.println("}");
- p.println();
+
+ return NO_ERROR;
}
static status_t writeLayoutClasses(
@@ -2485,7 +2450,10 @@
}
if (emitCallback) {
- writeResourceLoadedCallback(fp, indent);
+ fprintf(fp, "%spublic static void onResourcesLoaded(int packageId) {\n",
+ getIndentSpace(indent));
+ writeResourceLoadedCallback(fp, assets, includePrivate, symbols, className, indent + 1);
+ fprintf(fp, "%s}\n", getIndentSpace(indent));
}
indent--;
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index bd80cb8..bef5181 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -16,6 +16,8 @@
package android.graphics;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
@@ -50,10 +52,12 @@
*/
public class FontFamily_Delegate {
+ public static final int DEFAULT_FONT_WEIGHT = 400;
+ public static final int BOLD_FONT_WEIGHT_DELTA = 300;
+ public static final int BOLD_FONT_WEIGHT = 700;
+
// FONT_SUFFIX_ITALIC will always match FONT_SUFFIX_BOLDITALIC and hence it must be checked
// separately.
- private static final String FONT_SUFFIX_BOLDITALIC = "BoldItalic.ttf";
- private static final String FONT_SUFFIX_BOLD = "Bold.ttf";
private static final String FONT_SUFFIX_ITALIC = "Italic.ttf";
private static final String FN_ALL_FONTS_LIST = "fontsInSdk.txt";
@@ -61,9 +65,10 @@
* A class associating {@link Font} with its metadata.
*/
private static final class FontInfo {
+ @Nullable
Font mFont;
- /** Regular, Bold, Italic, or BoldItalic. */
- int mStyle;
+ int mWeight;
+ boolean mIsItalic;
}
// ---- delegate manager ----
@@ -79,16 +84,18 @@
// ---- delegate data ----
private List<FontInfo> mFonts = new ArrayList<FontInfo>();
+
/**
* The variant of the Font Family - compact or elegant.
+ * <p/>
* 0 is unspecified, 1 is compact and 2 is elegant. This needs to be kept in sync with values in
* android.graphics.FontFamily
*
* @see Paint#setElegantTextHeight(boolean)
*/
private FontVariant mVariant;
- // Path of fonts that haven't been created since sFontLoader hasn't been initialized.
- private List<String> mPath = new ArrayList<String>();
+ // List of runnables to process fonts after sFontLoader is initialized.
+ private List<Runnable> mPostInitRunnables = new ArrayList<Runnable>();
/** @see #isValid() */
private boolean mValid = false;
@@ -139,27 +146,30 @@
sPostInitDelegate.clear();
}
- public Font getFont(int style) {
- FontInfo plainFont = null;
+ @Nullable
+ public Font getFont(int desiredWeight, boolean isItalic) {
+ FontInfo desiredStyle = new FontInfo();
+ desiredStyle.mWeight = desiredWeight;
+ desiredStyle.mIsItalic = isItalic;
+ FontInfo bestFont = null;
+ int bestMatch = Integer.MAX_VALUE;
for (FontInfo font : mFonts) {
- if (font.mStyle == style) {
- return font.mFont;
- }
- if (font.mStyle == Font.PLAIN && plainFont == null) {
- plainFont = font;
+ int match = computeMatch(font, desiredStyle);
+ if (match < bestMatch) {
+ bestMatch = match;
+ bestFont = font;
}
}
-
- // No font with the mentioned style is found. Try to derive one.
- if (plainFont != null && style > 0 && style < 4) {
- FontInfo styledFont = new FontInfo();
- styledFont.mFont = plainFont.mFont.deriveFont(style);
- styledFont.mStyle = style;
- // Add the font to the list of fonts so that we don't have to derive it the next time.
- mFonts.add(styledFont);
- return styledFont.mFont;
+ if (bestFont == null) {
+ return null;
}
- return null;
+ if (bestMatch == 0) {
+ return bestFont.mFont;
+ }
+ // Derive the font as required and add it to the list of Fonts.
+ deriveFont(bestFont, desiredStyle);
+ addFont(desiredStyle);
+ return desiredStyle.mFont;
}
public FontVariant getVariant() {
@@ -168,27 +178,14 @@
/**
* Returns if the FontFamily should contain any fonts. If this returns true and
- * {@link #getFont(int)} returns an empty list, it means that an error occurred while loading
- * the fonts. However, some fonts are deliberately skipped, for example they are not bundled
- * with the SDK. In such a case, this method returns false.
+ * {@link #getFont(int, boolean)} returns an empty list, it means that an error occurred while
+ * loading the fonts. However, some fonts are deliberately skipped, for example they are not
+ * bundled with the SDK. In such a case, this method returns false.
*/
public boolean isValid() {
return mValid;
}
- /*package*/ static int getFontStyle(String path) {
- int style = Font.PLAIN;
- String fontName = path.substring(path.lastIndexOf('/'));
- if (fontName.endsWith(FONT_SUFFIX_BOLDITALIC)) {
- style = Font.BOLD | Font.ITALIC;
- } else if (fontName.endsWith(FONT_SUFFIX_BOLD)) {
- style = Font.BOLD;
- } else if (fontName.endsWith(FONT_SUFFIX_ITALIC)) {
- style = Font.ITALIC;
- }
- return style;
- }
-
/*package*/ static Font loadFont(String path) {
if (path.startsWith(SYSTEM_FONTS) ) {
String relativePath = path.substring(SYSTEM_FONTS.length());
@@ -242,11 +239,16 @@
}
@LayoutlibDelegate
- /*package*/ static boolean nAddFont(long nativeFamily, String path) {
- FontFamily_Delegate delegate = getDelegate(nativeFamily);
+ /*package*/ static boolean nAddFont(long nativeFamily, final String path) {
+ final FontFamily_Delegate delegate = getDelegate(nativeFamily);
if (delegate != null) {
if (sFontLocation == null) {
- delegate.mPath.add(path);
+ delegate.mPostInitRunnables.add(new Runnable() {
+ @Override
+ public void run() {
+ delegate.addFont(path);
+ }
+ });
return true;
}
return delegate.addFont(path);
@@ -255,6 +257,25 @@
}
@LayoutlibDelegate
+ /*package*/ static boolean nAddFontWeightStyle(long nativeFamily, final String path,
+ final int weight, final boolean isItalic) {
+ final FontFamily_Delegate delegate = getDelegate(nativeFamily);
+ if (delegate != null) {
+ if (sFontLocation == null) {
+ delegate.mPostInitRunnables.add(new Runnable() {
+ @Override
+ public void run() {
+ delegate.addFont(path, weight, isItalic);
+ }
+ });
+ return true;
+ }
+ return delegate.addFont(path, weight, isItalic);
+ }
+ return false;
+ }
+
+ @LayoutlibDelegate
/*package*/ static boolean nAddFontFromAsset(long nativeFamily, AssetManager mgr, String path) {
Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
"FontFamily.addFontFromAsset is not supported.", null, null);
@@ -265,15 +286,17 @@
// ---- private helper methods ----
private void init() {
- for (String path : mPath) {
- addFont(path);
+ for (Runnable postInitRunnable : mPostInitRunnables) {
+ postInitRunnable.run();
}
- mPath = null;
+ mPostInitRunnables = null;
}
- private boolean addFont(String path) {
- // If the font is not in the list of fonts bundled with the SDK, don't try to load it and
- // mark the FontFamily to be not valid.
+ private boolean addFont(@NonNull String path) {
+ return addFont(path, DEFAULT_FONT_WEIGHT, path.endsWith(FONT_SUFFIX_ITALIC));
+ }
+
+ private boolean addFont(@NonNull String path, int weight, boolean isItalic) {
if (path.startsWith(SYSTEM_FONTS) &&
!SDK_FONTS.contains(path.substring(SYSTEM_FONTS.length()))) {
return mValid = false;
@@ -286,9 +309,67 @@
}
FontInfo fontInfo = new FontInfo();
fontInfo.mFont = font;
- fontInfo.mStyle = getFontStyle(path);
- // TODO ensure that mFonts doesn't have the font with this style already.
+ fontInfo.mWeight = weight;
+ fontInfo.mIsItalic = isItalic;
+ addFont(fontInfo);
+ return true;
+ }
+
+ private boolean addFont(@NonNull FontInfo fontInfo) {
+ int weight = fontInfo.mWeight;
+ boolean isItalic = fontInfo.mIsItalic;
+ // The list is usually just two fonts big. So iterating over all isn't as bad as it looks.
+ // It's biggest for roboto where the size is 12.
+ for (FontInfo font : mFonts) {
+ if (font.mWeight == weight && font.mIsItalic == isItalic) {
+ return false;
+ }
+ }
mFonts.add(fontInfo);
return true;
}
+
+ /**
+ * Compute matching metric between two styles - 0 is an exact match.
+ */
+ private static int computeMatch(@NonNull FontInfo font1, @NonNull FontInfo font2) {
+ int score = Math.abs(font1.mWeight - font2.mWeight);
+ if (font1.mIsItalic != font2.mIsItalic) {
+ score += 200;
+ }
+ return score;
+ }
+
+ /**
+ * Try to derive a font from {@code srcFont} for the style in {@code outFont}.
+ * <p/>
+ * {@code outFont} is updated to reflect the style of the derived font.
+ * @param srcFont the source font
+ * @param outFont contains the desired font style. Updated to contain the derived font and
+ * its style
+ * @return outFont
+ */
+ @NonNull
+ private FontInfo deriveFont(@NonNull FontInfo srcFont, @NonNull FontInfo outFont) {
+ int desiredWeight = outFont.mWeight;
+ int srcWeight = srcFont.mWeight;
+ Font derivedFont = srcFont.mFont;
+ // Embolden the font if required.
+ if (desiredWeight >= BOLD_FONT_WEIGHT && desiredWeight - srcWeight > BOLD_FONT_WEIGHT_DELTA / 2) {
+ derivedFont = derivedFont.deriveFont(Font.BOLD);
+ srcWeight += BOLD_FONT_WEIGHT_DELTA;
+ }
+ // Italicize the font if required.
+ if (outFont.mIsItalic && !srcFont.mIsItalic) {
+ derivedFont = derivedFont.deriveFont(Font.ITALIC);
+ } else if (outFont.mIsItalic != srcFont.mIsItalic) {
+ // The desired font is plain, but the src font is italics. We can't convert it back. So
+ // we update the value to reflect the true style of the font we're deriving.
+ outFont.mIsItalic = srcFont.mIsItalic;
+ }
+ outFont.mFont = derivedFont;
+ outFont.mWeight = srcWeight;
+ // No need to update mIsItalics, as it's already been handled above.
+ return outFont;
+ }
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
index 832d0a3..14e9960 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Shader_Delegate.java
@@ -76,22 +76,19 @@
// ---- native methods ----
@LayoutlibDelegate
- /*package*/ static void nativeDestructor(long native_shader, long native_with_local_matrix) {
- // TODO: check what's native_with_local_matrix
+ /*package*/ static void nativeDestructor(long native_shader) {
sManager.removeJavaReferenceFor(native_shader);
}
@LayoutlibDelegate
- /*package*/ static long nativeSetLocalMatrix(long native_shader,
- long native_with_local_matrix, long matrix_instance) {
+ /*package*/ static void nativeSetLocalMatrix(long native_shader, long matrix_instance) {
// get the delegate from the native int.
Shader_Delegate shaderDelegate = sManager.getDelegate(native_shader);
if (shaderDelegate == null) {
- return 0;
+ return;
}
shaderDelegate.mLocalMatrix = Matrix_Delegate.getDelegate(matrix_instance);
- return 0;
}
// ---- Private delegate/helper methods ----
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 72fe61c..276e134 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -55,8 +55,9 @@
@NonNull
private final FontFamily_Delegate[] mFontFamilies; // the reference to FontFamily_Delegate.
- /** @see FontFamily_Delegate.FontInfo#mStyle */
+ /** @see Font#getStyle() */
private final int mStyle;
+ private final int mWeight;
private static long sDefaultTypeface;
@@ -84,11 +85,18 @@
@NonNull
public List<Font> getFonts(FontVariant variant) {
assert variant != FontVariant.NONE;
+
+ // Calculate the required weight based on style and weight of this typeface.
+ int weight = mWeight + ((mStyle & Font.BOLD) == 0 ? 0 : FontFamily_Delegate.BOLD_FONT_WEIGHT_DELTA);
+ if (weight > 900) {
+ weight = 900;
+ }
+ final boolean isItalic = (mStyle & Font.ITALIC) != 0;
List<Font> fonts = new ArrayList<Font>(mFontFamilies.length);
for (int i = 0; i < mFontFamilies.length; i++) {
FontFamily_Delegate ffd = mFontFamilies[i];
if (ffd != null && ffd.isValid()) {
- Font font = ffd.getFont(mStyle);
+ Font font = ffd.getFont(weight, isItalic);
if (font != null) {
FontVariant ffdVariant = ffd.getVariant();
if (ffdVariant == FontVariant.NONE) {
@@ -102,7 +110,7 @@
FontFamily_Delegate ffd2 = mFontFamilies[++i];
assert ffd2 != null;
FontVariant ffd2Variant = ffd2.getVariant();
- Font font2 = ffd2.getFont(mStyle);
+ Font font2 = ffd2.getFont(weight, isItalic);
assert ffd2Variant != FontVariant.NONE && ffd2Variant != ffdVariant
&& font2 != null;
// Add the font with the matching variant to the list.
@@ -135,7 +143,22 @@
return 0;
}
- return sManager.addNewDelegate(new Typeface_Delegate(delegate.mFontFamilies, style));
+ return sManager.addNewDelegate(new Typeface_Delegate(delegate.mFontFamilies, style,
+ delegate.mWeight));
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static long nativeCreateWeightAlias(long native_instance, int weight) {
+ Typeface_Delegate delegate = sManager.getDelegate(native_instance);
+ if (delegate == null) {
+ delegate = sManager.getDelegate(sDefaultTypeface);
+ }
+ if (delegate == null) {
+ return 0;
+ }
+ Typeface_Delegate weightAlias =
+ new Typeface_Delegate(delegate.mFontFamilies, delegate.mStyle, weight);
+ return sManager.addNewDelegate(weightAlias);
}
@LayoutlibDelegate
@@ -176,7 +199,12 @@
// ---- Private delegate/helper methods ----
private Typeface_Delegate(@NonNull FontFamily_Delegate[] fontFamilies, int style) {
+ this(fontFamilies, style, FontFamily_Delegate.DEFAULT_FONT_WEIGHT);
+ }
+
+ public Typeface_Delegate(@NonNull FontFamily_Delegate[] fontFamilies, int style, int weight) {
mFontFamilies = fontFamilies;
mStyle = style;
+ mWeight = weight;
}
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 21f200f..aeaff71 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -367,9 +367,9 @@
/**
* @hide
- * Uid of app owning the BSSID
+ * Uid used by autoJoin
*/
- public int bssidOwnerUid;
+ public String autoJoinBSSID;
/**
* @hide
@@ -467,8 +467,10 @@
public int rssi24; // strongest 2.4GHz RSSI
public int num5; // number of BSSIDs on 5GHz
public int num24; // number of BSSIDs on 2.4GHz
- public long age5; // timestamp of the strongest 5GHz BSSID (last time it was seen)
- public long age24; // timestamp of the strongest 2.4GHz BSSID (last time it was seen)
+ public long age5; // timestamp of the strongest 5GHz BSSID (last time it was seen)
+ public long age24; // timestamp of the strongest 2.4GHz BSSID (last time it was seen)
+ public String BSSID24;
+ public String BSSID5;
public Visibility() {
rssi5 = INVALID_RSSI;
@@ -482,6 +484,8 @@
age5 = source.age5;
num24 = source.num24;
num5 = source.num5;
+ BSSID5 = source.BSSID5;
+ BSSID24 = source.BSSID24;
}
@Override
@@ -492,6 +496,7 @@
sbuf.append(Integer.toString(rssi24));
sbuf.append(",");
sbuf.append(Integer.toString(num24));
+ if (BSSID24 != null) sbuf.append(",").append(BSSID24);
} else {
sbuf.append("*");
}
@@ -500,6 +505,7 @@
sbuf.append(Integer.toString(rssi5));
sbuf.append(",");
sbuf.append(Integer.toString(num5));
+ if (BSSID5 != null) sbuf.append(",").append(BSSID5);
}
sbuf.append("]");
return sbuf.toString();
@@ -549,11 +555,13 @@
if (result.level > status.rssi5) {
status.rssi5 = result.level;
status.age5 = result.seen;
+ status.BSSID5 = result.BSSID;
}
} else if (result.is24GHz()) {
if (result.level > status.rssi24) {
status.rssi24 = result.level;
status.age24 = result.seen;
+ status.BSSID24 = result.BSSID;
}
}
}
@@ -949,7 +957,7 @@
sbuf.append(mIpConfiguration.toString());
if (this.creatorUid != 0) sbuf.append("uid=" + Integer.toString(creatorUid));
-
+ if (this.autoJoinBSSID != null) sbuf.append("autoJoinBSSID=" + autoJoinBSSID);
if (this.blackListTimestamp != 0) {
long now_ms = System.currentTimeMillis();
long diff = now_ms - this.blackListTimestamp;
@@ -1284,7 +1292,6 @@
didSelfAdd = source.didSelfAdd;
lastConnectUid = source.lastConnectUid;
lastUpdateUid = source.lastUpdateUid;
- bssidOwnerUid = source.bssidOwnerUid;
creatorUid = source.creatorUid;
peerWifiConfiguration = source.peerWifiConfiguration;
blackListTimestamp = source.blackListTimestamp;
@@ -1302,6 +1309,7 @@
numTicksAtBadRSSI = source.numTicksAtBadRSSI;
numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI;
numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts;
+ autoJoinBSSID = source.autoJoinBSSID;
}
}
@@ -1318,6 +1326,7 @@
dest.writeInt(disableReason);
dest.writeString(SSID);
dest.writeString(BSSID);
+ dest.writeString(autoJoinBSSID);
dest.writeString(FQDN);
dest.writeString(naiRealm);
dest.writeString(preSharedKey);
@@ -1348,7 +1357,6 @@
dest.writeInt(creatorUid);
dest.writeInt(lastConnectUid);
dest.writeInt(lastUpdateUid);
- dest.writeInt(bssidOwnerUid);
dest.writeLong(blackListTimestamp);
dest.writeLong(lastConnectionFailure);
dest.writeInt(numConnectionFailures);
@@ -1375,6 +1383,7 @@
config.disableReason = in.readInt();
config.SSID = in.readString();
config.BSSID = in.readString();
+ config.autoJoinBSSID = in.readString();
config.FQDN = in.readString();
config.naiRealm = in.readString();
config.preSharedKey = in.readString();
@@ -1405,7 +1414,6 @@
config.creatorUid = in.readInt();
config.lastConnectUid = in.readInt();
config.lastUpdateUid = in.readInt();
- config.bssidOwnerUid = in.readInt();
config.blackListTimestamp = in.readLong();
config.lastConnectionFailure = in.readLong();
config.numConnectionFailures = in.readInt();