Merge "Add support for localizing order of day of week and date in status bar date view"
diff --git a/api/14.txt b/api/14.txt
index 895c44d..3d96c11 100644
--- a/api/14.txt
+++ b/api/14.txt
@@ -20979,45 +20979,17 @@
public class Surface implements android.os.Parcelable {
method public int describeContents();
- method public void freeze();
- method public void hide();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
method public void readFromParcel(android.os.Parcel);
- method public void setAlpha(float);
- method public void setFlags(int, int);
- method public void setFreezeTint(int);
- method public void setLayer(int);
- method public void setMatrix(float, float, float, float);
- method public static void setOrientation(int, int);
- method public void setPosition(int, int);
- method public void setSize(int, int);
- method public void setTransparentRegionHint(android.graphics.Region);
- method public void show();
- method public void unfreeze();
method public void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
- field public static final int FX_SURFACE_BLUR = 65536; // 0x10000
- field public static final int FX_SURFACE_DIM = 131072; // 0x20000
- field public static final int FX_SURFACE_MASK = 983040; // 0xf0000
- field public static final int FX_SURFACE_NORMAL = 0; // 0x0
- field public static final deprecated int GPU = 40; // 0x28
- field public static final deprecated int HARDWARE = 16; // 0x10
- field public static final int HIDDEN = 4; // 0x4
- field public static final int NON_PREMULTIPLIED = 256; // 0x100
- field public static final deprecated int PUSH_BUFFERS = 512; // 0x200
field public static final int ROTATION_0 = 0; // 0x0
field public static final int ROTATION_180 = 2; // 0x2
field public static final int ROTATION_270 = 3; // 0x3
field public static final int ROTATION_90 = 1; // 0x1
- field public static final int SECURE = 128; // 0x80
- field public static final deprecated int SURACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_BLUR_FREEZE = 16; // 0x10
- field public static final int SURFACE_DITHER = 4; // 0x4
- field public static final int SURFACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_HIDDEN = 1; // 0x1
}
public static class Surface.OutOfResourcesException extends java.lang.Exception {
diff --git a/api/current.txt b/api/current.txt
index 876d555..1180440 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1499,6 +1499,12 @@
field public static final int Animation_InputMethod = 16973910; // 0x1030056
field public static final int Animation_Toast = 16973828; // 0x1030004
field public static final int Animation_Translucent = 16973827; // 0x1030003
+ field public static final int DeviceDefault_ButtonBar = 16974287; // 0x10301cf
+ field public static final int DeviceDefault_ButtonBar_AlertDialog = 16974288; // 0x10301d0
+ field public static final int DeviceDefault_Light_ButtonBar = 16974290; // 0x10301d2
+ field public static final int DeviceDefault_Light_ButtonBar_AlertDialog = 16974291; // 0x10301d3
+ field public static final int DeviceDefault_Light_SegmentedButton = 16974292; // 0x10301d4
+ field public static final int DeviceDefault_SegmentedButton = 16974289; // 0x10301d1
field public static final int Holo_ButtonBar = 16974053; // 0x10300e5
field public static final int Holo_ButtonBar_AlertDialog = 16974055; // 0x10300e7
field public static final int Holo_Light_ButtonBar = 16974054; // 0x10300e6
@@ -1513,6 +1519,40 @@
field public static final int MediaButton_Previous = 16973880; // 0x1030038
field public static final int MediaButton_Rew = 16973884; // 0x103003c
field public static final int TextAppearance = 16973886; // 0x103003e
+ field public static final int TextAppearance_DeviceDefault = 16974253; // 0x10301ad
+ field public static final int TextAppearance_DeviceDefault_DialogWindowTitle = 16974264; // 0x10301b8
+ field public static final int TextAppearance_DeviceDefault_Inverse = 16974254; // 0x10301ae
+ field public static final int TextAppearance_DeviceDefault_Large = 16974255; // 0x10301af
+ field public static final int TextAppearance_DeviceDefault_Large_Inverse = 16974256; // 0x10301b0
+ field public static final int TextAppearance_DeviceDefault_Medium = 16974257; // 0x10301b1
+ field public static final int TextAppearance_DeviceDefault_Medium_Inverse = 16974258; // 0x10301b2
+ field public static final int TextAppearance_DeviceDefault_SearchResult_Subtitle = 16974262; // 0x10301b6
+ field public static final int TextAppearance_DeviceDefault_SearchResult_Title = 16974261; // 0x10301b5
+ field public static final int TextAppearance_DeviceDefault_Small = 16974259; // 0x10301b3
+ field public static final int TextAppearance_DeviceDefault_Small_Inverse = 16974260; // 0x10301b4
+ field public static final int TextAppearance_DeviceDefault_Widget = 16974265; // 0x10301b9
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Menu = 16974286; // 0x10301ce
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Subtitle = 16974279; // 0x10301c7
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Subtitle_Inverse = 16974283; // 0x10301cb
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Title = 16974278; // 0x10301c6
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionBar_Title_Inverse = 16974282; // 0x10301ca
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Subtitle = 16974281; // 0x10301c9
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Subtitle_Inverse = 16974285; // 0x10301cd
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Title = 16974280; // 0x10301c8
+ field public static final int TextAppearance_DeviceDefault_Widget_ActionMode_Title_Inverse = 16974284; // 0x10301cc
+ field public static final int TextAppearance_DeviceDefault_Widget_Button = 16974266; // 0x10301ba
+ field public static final int TextAppearance_DeviceDefault_Widget_DropDownHint = 16974271; // 0x10301bf
+ field public static final int TextAppearance_DeviceDefault_Widget_DropDownItem = 16974272; // 0x10301c0
+ field public static final int TextAppearance_DeviceDefault_Widget_EditText = 16974274; // 0x10301c2
+ field public static final int TextAppearance_DeviceDefault_Widget_IconMenu_Item = 16974267; // 0x10301bb
+ field public static final int TextAppearance_DeviceDefault_Widget_PopupMenu = 16974275; // 0x10301c3
+ field public static final int TextAppearance_DeviceDefault_Widget_PopupMenu_Large = 16974276; // 0x10301c4
+ field public static final int TextAppearance_DeviceDefault_Widget_PopupMenu_Small = 16974277; // 0x10301c5
+ field public static final int TextAppearance_DeviceDefault_Widget_TabWidget = 16974268; // 0x10301bc
+ field public static final int TextAppearance_DeviceDefault_Widget_TextView = 16974269; // 0x10301bd
+ field public static final int TextAppearance_DeviceDefault_Widget_TextView_PopupMenu = 16974270; // 0x10301be
+ field public static final int TextAppearance_DeviceDefault_Widget_TextView_SpinnerItem = 16974273; // 0x10301c1
+ field public static final int TextAppearance_DeviceDefault_WindowTitle = 16974263; // 0x10301b7
field public static final int TextAppearance_DialogWindowTitle = 16973889; // 0x1030041
field public static final int TextAppearance_Holo = 16974075; // 0x10300fb
field public static final int TextAppearance_Holo_DialogWindowTitle = 16974103; // 0x1030117
@@ -1578,6 +1618,30 @@
field public static final int Theme_Black = 16973832; // 0x1030008
field public static final int Theme_Black_NoTitleBar = 16973833; // 0x1030009
field public static final int Theme_Black_NoTitleBar_Fullscreen = 16973834; // 0x103000a
+ field public static final int Theme_DeviceDefault = 16974120; // 0x1030128
+ field public static final int Theme_DeviceDefault_Dialog = 16974126; // 0x103012e
+ field public static final int Theme_DeviceDefault_DialogWhenLarge = 16974134; // 0x1030136
+ field public static final int Theme_DeviceDefault_DialogWhenLarge_NoActionBar = 16974135; // 0x1030137
+ field public static final int Theme_DeviceDefault_Dialog_MinWidth = 16974127; // 0x103012f
+ field public static final int Theme_DeviceDefault_Dialog_NoActionBar = 16974128; // 0x1030130
+ field public static final int Theme_DeviceDefault_Dialog_NoActionBar_MinWidth = 16974129; // 0x1030131
+ field public static final int Theme_DeviceDefault_InputMethod = 16974142; // 0x103013e
+ field public static final int Theme_DeviceDefault_Light = 16974123; // 0x103012b
+ field public static final int Theme_DeviceDefault_Light_DarkActionBar = 16974143; // 0x103013f
+ field public static final int Theme_DeviceDefault_Light_Dialog = 16974130; // 0x1030132
+ field public static final int Theme_DeviceDefault_Light_DialogWhenLarge = 16974136; // 0x1030138
+ field public static final int Theme_DeviceDefault_Light_DialogWhenLarge_NoActionBar = 16974137; // 0x1030139
+ field public static final int Theme_DeviceDefault_Light_Dialog_MinWidth = 16974131; // 0x1030133
+ field public static final int Theme_DeviceDefault_Light_Dialog_NoActionBar = 16974132; // 0x1030134
+ field public static final int Theme_DeviceDefault_Light_Dialog_NoActionBar_MinWidth = 16974133; // 0x1030135
+ field public static final int Theme_DeviceDefault_Light_NoActionBar = 16974124; // 0x103012c
+ field public static final int Theme_DeviceDefault_Light_NoActionBar_Fullscreen = 16974125; // 0x103012d
+ field public static final int Theme_DeviceDefault_Light_Panel = 16974139; // 0x103013b
+ field public static final int Theme_DeviceDefault_NoActionBar = 16974121; // 0x1030129
+ field public static final int Theme_DeviceDefault_NoActionBar_Fullscreen = 16974122; // 0x103012a
+ field public static final int Theme_DeviceDefault_Panel = 16974138; // 0x103013a
+ field public static final int Theme_DeviceDefault_Wallpaper = 16974140; // 0x103013c
+ field public static final int Theme_DeviceDefault_Wallpaper_NoTitleBar = 16974141; // 0x103013d
field public static final int Theme_Dialog = 16973835; // 0x103000b
field public static final int Theme_Holo = 16973931; // 0x103006b
field public static final int Theme_Holo_Dialog = 16973935; // 0x103006f
@@ -1642,6 +1706,115 @@
field public static final int Widget_CompoundButton_RadioButton = 16973850; // 0x103001a
field public static final int Widget_CompoundButton_Star = 16973851; // 0x103001b
field public static final int Widget_DatePicker = 16974062; // 0x10300ee
+ field public static final int Widget_DeviceDefault = 16974144; // 0x1030140
+ field public static final int Widget_DeviceDefault_ActionBar = 16974187; // 0x103016b
+ field public static final int Widget_DeviceDefault_ActionBar_Solid = 16974195; // 0x1030173
+ field public static final int Widget_DeviceDefault_ActionBar_TabBar = 16974194; // 0x1030172
+ field public static final int Widget_DeviceDefault_ActionBar_TabText = 16974193; // 0x1030171
+ field public static final int Widget_DeviceDefault_ActionBar_TabView = 16974192; // 0x1030170
+ field public static final int Widget_DeviceDefault_ActionButton = 16974182; // 0x1030166
+ field public static final int Widget_DeviceDefault_ActionButton_CloseMode = 16974186; // 0x103016a
+ field public static final int Widget_DeviceDefault_ActionButton_Overflow = 16974183; // 0x1030167
+ field public static final int Widget_DeviceDefault_ActionButton_TextButton = 16974184; // 0x1030168
+ field public static final int Widget_DeviceDefault_ActionMode = 16974185; // 0x1030169
+ field public static final int Widget_DeviceDefault_AutoCompleteTextView = 16974151; // 0x1030147
+ field public static final int Widget_DeviceDefault_Button = 16974145; // 0x1030141
+ field public static final int Widget_DeviceDefault_Button_Borderless = 16974188; // 0x103016c
+ field public static final int Widget_DeviceDefault_Button_Borderless_Small = 16974149; // 0x1030145
+ field public static final int Widget_DeviceDefault_Button_Inset = 16974147; // 0x1030143
+ field public static final int Widget_DeviceDefault_Button_Small = 16974146; // 0x1030142
+ field public static final int Widget_DeviceDefault_Button_Toggle = 16974148; // 0x1030144
+ field public static final int Widget_DeviceDefault_CalendarView = 16974190; // 0x103016e
+ field public static final int Widget_DeviceDefault_CompoundButton_CheckBox = 16974152; // 0x1030148
+ field public static final int Widget_DeviceDefault_CompoundButton_RadioButton = 16974169; // 0x1030159
+ field public static final int Widget_DeviceDefault_CompoundButton_Star = 16974173; // 0x103015d
+ field public static final int Widget_DeviceDefault_DatePicker = 16974191; // 0x103016f
+ field public static final int Widget_DeviceDefault_DropDownItem = 16974177; // 0x1030161
+ field public static final int Widget_DeviceDefault_DropDownItem_Spinner = 16974178; // 0x1030162
+ field public static final int Widget_DeviceDefault_EditText = 16974154; // 0x103014a
+ field public static final int Widget_DeviceDefault_ExpandableListView = 16974155; // 0x103014b
+ field public static final int Widget_DeviceDefault_GridView = 16974156; // 0x103014c
+ field public static final int Widget_DeviceDefault_HorizontalScrollView = 16974171; // 0x103015b
+ field public static final int Widget_DeviceDefault_ImageButton = 16974157; // 0x103014d
+ field public static final int Widget_DeviceDefault_Light = 16974196; // 0x1030174
+ field public static final int Widget_DeviceDefault_Light_ActionBar = 16974243; // 0x10301a3
+ field public static final int Widget_DeviceDefault_Light_ActionBar_Solid = 16974247; // 0x10301a7
+ field public static final int Widget_DeviceDefault_Light_ActionBar_Solid_Inverse = 16974248; // 0x10301a8
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabBar = 16974246; // 0x10301a6
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabBar_Inverse = 16974249; // 0x10301a9
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabText = 16974245; // 0x10301a5
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabText_Inverse = 16974251; // 0x10301ab
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabView = 16974244; // 0x10301a4
+ field public static final int Widget_DeviceDefault_Light_ActionBar_TabView_Inverse = 16974250; // 0x10301aa
+ field public static final int Widget_DeviceDefault_Light_ActionButton = 16974239; // 0x103019f
+ field public static final int Widget_DeviceDefault_Light_ActionButton_CloseMode = 16974242; // 0x10301a2
+ field public static final int Widget_DeviceDefault_Light_ActionButton_Overflow = 16974240; // 0x10301a0
+ field public static final int Widget_DeviceDefault_Light_ActionMode = 16974241; // 0x10301a1
+ field public static final int Widget_DeviceDefault_Light_ActionMode_Inverse = 16974252; // 0x10301ac
+ field public static final int Widget_DeviceDefault_Light_AutoCompleteTextView = 16974203; // 0x103017b
+ field public static final int Widget_DeviceDefault_Light_Button = 16974197; // 0x1030175
+ field public static final int Widget_DeviceDefault_Light_Button_Borderless_Small = 16974201; // 0x1030179
+ field public static final int Widget_DeviceDefault_Light_Button_Inset = 16974199; // 0x1030177
+ field public static final int Widget_DeviceDefault_Light_Button_Small = 16974198; // 0x1030176
+ field public static final int Widget_DeviceDefault_Light_Button_Toggle = 16974200; // 0x1030178
+ field public static final int Widget_DeviceDefault_Light_CalendarView = 16974238; // 0x103019e
+ field public static final int Widget_DeviceDefault_Light_CompoundButton_CheckBox = 16974204; // 0x103017c
+ field public static final int Widget_DeviceDefault_Light_CompoundButton_RadioButton = 16974224; // 0x1030190
+ field public static final int Widget_DeviceDefault_Light_CompoundButton_Star = 16974228; // 0x1030194
+ field public static final int Widget_DeviceDefault_Light_DropDownItem = 16974232; // 0x1030198
+ field public static final int Widget_DeviceDefault_Light_DropDownItem_Spinner = 16974233; // 0x1030199
+ field public static final int Widget_DeviceDefault_Light_EditText = 16974206; // 0x103017e
+ field public static final int Widget_DeviceDefault_Light_ExpandableListView = 16974207; // 0x103017f
+ field public static final int Widget_DeviceDefault_Light_GridView = 16974208; // 0x1030180
+ field public static final int Widget_DeviceDefault_Light_HorizontalScrollView = 16974226; // 0x1030192
+ field public static final int Widget_DeviceDefault_Light_ImageButton = 16974209; // 0x1030181
+ field public static final int Widget_DeviceDefault_Light_ListPopupWindow = 16974235; // 0x103019b
+ field public static final int Widget_DeviceDefault_Light_ListView = 16974210; // 0x1030182
+ field public static final int Widget_DeviceDefault_Light_ListView_DropDown = 16974205; // 0x103017d
+ field public static final int Widget_DeviceDefault_Light_PopupMenu = 16974236; // 0x103019c
+ field public static final int Widget_DeviceDefault_Light_PopupWindow = 16974211; // 0x1030183
+ field public static final int Widget_DeviceDefault_Light_ProgressBar = 16974212; // 0x1030184
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Horizontal = 16974213; // 0x1030185
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Inverse = 16974217; // 0x1030189
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Large = 16974216; // 0x1030188
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Large_Inverse = 16974219; // 0x103018b
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Small = 16974214; // 0x1030186
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Small_Inverse = 16974218; // 0x103018a
+ field public static final int Widget_DeviceDefault_Light_ProgressBar_Small_Title = 16974215; // 0x1030187
+ field public static final int Widget_DeviceDefault_Light_RatingBar = 16974221; // 0x103018d
+ field public static final int Widget_DeviceDefault_Light_RatingBar_Indicator = 16974222; // 0x103018e
+ field public static final int Widget_DeviceDefault_Light_RatingBar_Small = 16974223; // 0x103018f
+ field public static final int Widget_DeviceDefault_Light_ScrollView = 16974225; // 0x1030191
+ field public static final int Widget_DeviceDefault_Light_SeekBar = 16974220; // 0x103018c
+ field public static final int Widget_DeviceDefault_Light_Spinner = 16974227; // 0x1030193
+ field public static final int Widget_DeviceDefault_Light_Tab = 16974237; // 0x103019d
+ field public static final int Widget_DeviceDefault_Light_TabWidget = 16974229; // 0x1030195
+ field public static final int Widget_DeviceDefault_Light_TextView = 16974202; // 0x103017a
+ field public static final int Widget_DeviceDefault_Light_TextView_SpinnerItem = 16974234; // 0x103019a
+ field public static final int Widget_DeviceDefault_Light_WebTextView = 16974230; // 0x1030196
+ field public static final int Widget_DeviceDefault_Light_WebView = 16974231; // 0x1030197
+ field public static final int Widget_DeviceDefault_ListPopupWindow = 16974180; // 0x1030164
+ field public static final int Widget_DeviceDefault_ListView = 16974158; // 0x103014e
+ field public static final int Widget_DeviceDefault_ListView_DropDown = 16974153; // 0x1030149
+ field public static final int Widget_DeviceDefault_PopupMenu = 16974181; // 0x1030165
+ field public static final int Widget_DeviceDefault_PopupWindow = 16974159; // 0x103014f
+ field public static final int Widget_DeviceDefault_ProgressBar = 16974160; // 0x1030150
+ field public static final int Widget_DeviceDefault_ProgressBar_Horizontal = 16974161; // 0x1030151
+ field public static final int Widget_DeviceDefault_ProgressBar_Large = 16974164; // 0x1030154
+ field public static final int Widget_DeviceDefault_ProgressBar_Small = 16974162; // 0x1030152
+ field public static final int Widget_DeviceDefault_ProgressBar_Small_Title = 16974163; // 0x1030153
+ field public static final int Widget_DeviceDefault_RatingBar = 16974166; // 0x1030156
+ field public static final int Widget_DeviceDefault_RatingBar_Indicator = 16974167; // 0x1030157
+ field public static final int Widget_DeviceDefault_RatingBar_Small = 16974168; // 0x1030158
+ field public static final int Widget_DeviceDefault_ScrollView = 16974170; // 0x103015a
+ field public static final int Widget_DeviceDefault_SeekBar = 16974165; // 0x1030155
+ field public static final int Widget_DeviceDefault_Spinner = 16974172; // 0x103015c
+ field public static final int Widget_DeviceDefault_Tab = 16974189; // 0x103016d
+ field public static final int Widget_DeviceDefault_TabWidget = 16974174; // 0x103015e
+ field public static final int Widget_DeviceDefault_TextView = 16974150; // 0x1030146
+ field public static final int Widget_DeviceDefault_TextView_SpinnerItem = 16974179; // 0x1030163
+ field public static final int Widget_DeviceDefault_WebTextView = 16974175; // 0x103015f
+ field public static final int Widget_DeviceDefault_WebView = 16974176; // 0x1030160
field public static final int Widget_DropDownItem = 16973867; // 0x103002b
field public static final int Widget_DropDownItem_Spinner = 16973868; // 0x103002c
field public static final int Widget_EditText = 16973859; // 0x1030023
@@ -8454,6 +8627,7 @@
ctor public SurfaceTexture(int, boolean);
method public long getTimestamp();
method public void getTransformMatrix(float[]);
+ method public void release();
method public void setOnFrameAvailableListener(android.graphics.SurfaceTexture.OnFrameAvailableListener);
method public void updateTexImage();
}
@@ -11116,6 +11290,7 @@
public class ConnectivityManager {
method public android.net.NetworkInfo getActiveNetworkInfo();
+ method public android.net.NetworkQuotaInfo getActiveNetworkQuotaInfo();
method public android.net.NetworkInfo[] getAllNetworkInfo();
method public boolean getBackgroundDataSetting();
method public android.net.NetworkInfo getNetworkInfo(int);
@@ -11130,7 +11305,7 @@
field public static final int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
field public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
field public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover";
- field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
+ field public static final deprecated java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
field public static final java.lang.String EXTRA_REASON = "reason";
@@ -11275,6 +11450,16 @@
enum_constant public static final android.net.NetworkInfo.State UNKNOWN;
}
+ public class NetworkQuotaInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getEstimatedBytes();
+ method public long getHardLimitBytes();
+ method public long getSoftLimitBytes();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final long NO_LIMIT = -1L; // 0xffffffffffffffffL
+ }
+
public class ParseException extends java.lang.RuntimeException {
field public java.lang.String response;
}
@@ -22068,45 +22253,18 @@
public class Surface implements android.os.Parcelable {
method public int describeContents();
- method public void freeze();
- method public void hide();
method public boolean isValid();
method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException;
method public void readFromParcel(android.os.Parcel);
- method public void setAlpha(float);
- method public void setFlags(int, int);
- method public void setFreezeTint(int);
- method public void setLayer(int);
- method public void setMatrix(float, float, float, float);
- method public static void setOrientation(int, int);
- method public void setPosition(int, int);
- method public void setSize(int, int);
- method public void setTransparentRegionHint(android.graphics.Region);
- method public void show();
- method public void unfreeze();
+ method public void release();
method public void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator CREATOR;
- field public static final int FX_SURFACE_BLUR = 65536; // 0x10000
- field public static final int FX_SURFACE_DIM = 131072; // 0x20000
- field public static final int FX_SURFACE_MASK = 983040; // 0xf0000
- field public static final int FX_SURFACE_NORMAL = 0; // 0x0
- field public static final deprecated int GPU = 40; // 0x28
- field public static final deprecated int HARDWARE = 16; // 0x10
- field public static final int HIDDEN = 4; // 0x4
- field public static final int NON_PREMULTIPLIED = 256; // 0x100
- field public static final deprecated int PUSH_BUFFERS = 512; // 0x200
field public static final int ROTATION_0 = 0; // 0x0
field public static final int ROTATION_180 = 2; // 0x2
field public static final int ROTATION_270 = 3; // 0x3
field public static final int ROTATION_90 = 1; // 0x1
- field public static final int SECURE = 128; // 0x80
- field public static final deprecated int SURACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_BLUR_FREEZE = 16; // 0x10
- field public static final int SURFACE_DITHER = 4; // 0x4
- field public static final int SURFACE_FROZEN = 2; // 0x2
- field public static final int SURFACE_HIDDEN = 1; // 0x1
}
public static class Surface.OutOfResourcesException extends java.lang.Exception {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ca6f085..28bc424 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1163,7 +1163,10 @@
* <p> If this API returns true, it means the callback will be called.
* The callback will be called with the current state of Bluetooth.
* If the state is not what was requested, an internal error would be the
- * reason.
+ * reason. If Bluetooth is already on and if this function is called to turn
+ * it on, the api will return true and a callback will be called.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
*
* @param on True for on, false for off.
* @param callback The callback to notify changes to the state.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b6c64cb..22fdc98 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -598,7 +598,12 @@
assmgr = new AssetManager();
assmgr.setConfiguration(0, 0, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Build.VERSION.RESOURCES_SDK_INT);
+
int cookie = assmgr.addAssetPath(packageFilePath);
+ if (cookie == 0) {
+ return null;
+ }
+
parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
} catch (Exception e) {
if (assmgr != null) assmgr.close();
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a564d97..eb9cd21 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -16,10 +16,11 @@
package android.net;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.os.Binder;
-import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import java.net.InetAddress;
@@ -67,11 +68,19 @@
* is set to {@code true} if there are no connected networks at all.
*/
public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
+
/**
* The lookup key for a {@link NetworkInfo} object. Retrieve with
* {@link android.content.Intent#getParcelableExtra(String)}.
+ *
+ * @deprecated Since {@link NetworkInfo} can vary based on UID, applications
+ * should always obtain network information through
+ * {@link #getActiveNetworkInfo()} or
+ * {@link #getAllNetworkInfo()}.
*/
+ @Deprecated
public static final String EXTRA_NETWORK_INFO = "networkInfo";
+
/**
* The lookup key for a boolean that indicates whether a connect event
* is for a network to which the connectivity manager was failing over
@@ -515,6 +524,19 @@
}
/**
+ * Return quota status for the current active network, or {@code null} if no
+ * network is active. Quota status can change rapidly, so these values
+ * shouldn't be cached.
+ */
+ public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
+ try {
+ return mService.getActiveNetworkQuotaInfo();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Gets the value of the setting for enabling Mobile data.
*
* @return Whether mobile data is enabled.
@@ -546,10 +568,7 @@
* {@hide}
*/
public ConnectivityManager(IConnectivityManager service) {
- if (service == null) {
- throw new IllegalArgumentException("missing IConnectivityManager");
- }
- mService = service;
+ mService = checkNotNull(service, "missing IConnectivityManager");
}
/**
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b1d99a4..f391200 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -18,6 +18,7 @@
import android.net.LinkProperties;
import android.net.NetworkInfo;
+import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.ProxyProperties;
import android.os.IBinder;
@@ -47,6 +48,8 @@
NetworkState[] getAllNetworkState();
+ NetworkQuotaInfo getActiveNetworkQuotaInfo();
+
boolean setRadios(boolean onOff);
boolean setRadio(int networkType, boolean turnOn);
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 3e07b0a..633c38e0 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -18,6 +18,8 @@
import android.net.INetworkPolicyListener;
import android.net.NetworkPolicy;
+import android.net.NetworkQuotaInfo;
+import android.net.NetworkState;
import android.net.NetworkTemplate;
/**
@@ -27,6 +29,7 @@
*/
interface INetworkPolicyManager {
+ /** Control UID policies. */
void setUidPolicy(int uid, int policy);
int getUidPolicy(int uid);
@@ -35,12 +38,17 @@
void registerListener(INetworkPolicyListener listener);
void unregisterListener(INetworkPolicyListener listener);
+ /** Control network policies atomically. */
void setNetworkPolicies(in NetworkPolicy[] policies);
NetworkPolicy[] getNetworkPolicies();
+ /** Snooze limit on policy matching given template. */
void snoozePolicy(in NetworkTemplate template);
+ /** Control if background data is restricted system-wide. */
void setRestrictBackground(boolean restrictBackground);
boolean getRestrictBackground();
+ NetworkQuotaInfo getNetworkQuotaInfo(in NetworkState state);
+
}
diff --git a/core/java/android/net/NetworkQuotaInfo.aidl b/core/java/android/net/NetworkQuotaInfo.aidl
new file mode 100644
index 0000000..98a02c4
--- /dev/null
+++ b/core/java/android/net/NetworkQuotaInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011 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.net;
+
+parcelable NetworkQuotaInfo;
diff --git a/core/java/android/net/NetworkQuotaInfo.java b/core/java/android/net/NetworkQuotaInfo.java
new file mode 100644
index 0000000..b85f925
--- /dev/null
+++ b/core/java/android/net/NetworkQuotaInfo.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 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.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about quota status on a specific network.
+ */
+public class NetworkQuotaInfo implements Parcelable {
+ private final long mEstimatedBytes;
+ private final long mSoftLimitBytes;
+ private final long mHardLimitBytes;
+
+ public static final long NO_LIMIT = -1;
+
+ /** {@hide} */
+ public NetworkQuotaInfo(long estimatedBytes, long softLimitBytes, long hardLimitBytes) {
+ mEstimatedBytes = estimatedBytes;
+ mSoftLimitBytes = softLimitBytes;
+ mHardLimitBytes = hardLimitBytes;
+ }
+
+ /** {@hide} */
+ public NetworkQuotaInfo(Parcel in) {
+ mEstimatedBytes = in.readLong();
+ mSoftLimitBytes = in.readLong();
+ mHardLimitBytes = in.readLong();
+ }
+
+ public long getEstimatedBytes() {
+ return mEstimatedBytes;
+ }
+
+ public long getSoftLimitBytes() {
+ return mSoftLimitBytes;
+ }
+
+ public long getHardLimitBytes() {
+ return mHardLimitBytes;
+ }
+
+ /** {@inheritDoc} */
+ public int describeContents() {
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeLong(mEstimatedBytes);
+ out.writeLong(mSoftLimitBytes);
+ out.writeLong(mHardLimitBytes);
+ }
+
+ public static final Creator<NetworkQuotaInfo> CREATOR = new Creator<NetworkQuotaInfo>() {
+ public NetworkQuotaInfo createFromParcel(Parcel in) {
+ return new NetworkQuotaInfo(in);
+ }
+
+ public NetworkQuotaInfo[] newArray(int size) {
+ return new NetworkQuotaInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/net/NetworkStatsHistory.java b/core/java/android/net/NetworkStatsHistory.java
index 4ffabb1..7a4b811 100644
--- a/core/java/android/net/NetworkStatsHistory.java
+++ b/core/java/android/net/NetworkStatsHistory.java
@@ -405,11 +405,10 @@
final long curEnd = randomLong(r, curStart, end);
entry.rxBytes = randomLong(r, 0, rx);
entry.txBytes = randomLong(r, 0, tx);
-
- recordData(curStart, curEnd, entry);
-
rx -= entry.rxBytes;
tx -= entry.txBytes;
+
+ recordData(curStart, curEnd, entry);
}
}
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
index cb18ade..031375e 100644
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ b/core/java/android/server/BluetoothAdapterStateMachine.java
@@ -39,7 +39,7 @@
* (BluetootOn)<----------------------<-
* | ^ -------------------->- |
* | | | |
- * TURN_OFF | | BECAME_PAIRABLE m1 | | USER_TURN_ON
+ * TURN_OFF | | BECAME_PAIRABLE m1 | | USER_TURN_ON
* AIRPLANE_MODE_ON | | | |
* V | | |
* (Switching) (PerProcessState)
@@ -47,7 +47,7 @@
* BECAME_NON_PAIRABLE& | | TURN_ON(_CONTINUE) | |
* ALL_DEVICES_DISCONNECTED | | m2 | |
* V |------------------------< | BECAME_PAIRABLE
- * (HotOff)---------------------------- PER_PROCESS_TURN_ON
+ * (HotOff)-------------------------->- PER_PROCESS_TURN_ON
* / ^
* / | SERVICE_RECORD_LOADED
* | |
@@ -59,7 +59,7 @@
* (PowerOff) <----- initial state
*
* Legend:
- * m1 = USER_TURN_OFF
+ * m1 = TURN_HOT
* m2 = Transition to HotOff when number of process wanting BT on is 0.
* BECAME_NON_PAIRABLE will make the transition.
*/
@@ -73,6 +73,9 @@
static final int USER_TURN_ON = 1;
// We get this message when user tries to turn off BT
static final int USER_TURN_OFF = 2;
+ // Per process enable / disable messages
+ static final int PER_PROCESS_TURN_ON = 3;
+ static final int PER_PROCESS_TURN_OFF = 4;
// Message(what) to report a event that the state machine need to respond to
//
@@ -102,9 +105,8 @@
private static final int TURN_ON_CONTINUE = 102;
// Unload firmware, turning off Bluetooth module power
private static final int TURN_COLD = 103;
- // Per process enable / disable messages
- static final int PER_PROCESS_TURN_ON = 104;
- static final int PER_PROCESS_TURN_OFF = 105;
+ // Device disconnecting timeout happens
+ private static final int DEVICES_DISCONNECT_TIMEOUT = 104;
private Context mContext;
private BluetoothService mBluetoothService;
@@ -120,6 +122,9 @@
// this is the BluetoothAdapter state that reported externally
private int mPublicState;
+ // timeout value waiting for all the devices to be disconnected
+ private static final int DEVICES_DISCONNECT_TIMEOUT_TIME = 3000;
+
BluetoothAdapterStateMachine(Context context, BluetoothService bluetoothService,
BluetoothAdapter bluetoothAdapter) {
super(TAG);
@@ -214,8 +219,9 @@
case PER_PROCESS_TURN_OFF:
perProcessCallback(false, (IBluetoothStateChangeCallback) message.obj);
break;
- case AIRPLANE_MODE_ON:
- case USER_TURN_OFF: // ignore
+ case USER_TURN_OFF:
+ Log.w(TAG, "PowerOff received: " + message.what);
+ case AIRPLANE_MODE_ON: // ignore
break;
default:
return NOT_HANDLED;
@@ -301,7 +307,8 @@
case PER_PROCESS_TURN_OFF:
deferMessage(message);
break;
- case USER_TURN_OFF: // ignore
+ case USER_TURN_OFF:
+ Log.w(TAG, "WarmUp received: " + message.what);
break;
default:
return NOT_HANDLED;
@@ -344,7 +351,6 @@
mBluetoothService.shutoffBluetooth();
mEventLoop.stop();
transitionTo(mPowerOff);
- // ASSERT no support of config_bluetooth_adapter_quick_switch
broadcastState(BluetoothAdapter.STATE_OFF);
break;
case AIRPLANE_MODE_OFF:
@@ -354,8 +360,6 @@
broadcastState(BluetoothAdapter.STATE_TURNING_ON);
}
break;
- case USER_TURN_OFF: // ignore
- break;
case PER_PROCESS_TURN_ON:
transitionTo(mPerProcessState);
@@ -368,6 +372,8 @@
case PER_PROCESS_TURN_OFF:
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
break;
+ case USER_TURN_OFF: // ignore
+ break;
default:
return NOT_HANDLED;
}
@@ -399,16 +405,28 @@
case BECAME_NON_PAIRABLE:
if (mBluetoothService.getAdapterConnectionState() ==
BluetoothAdapter.STATE_DISCONNECTED) {
+ removeMessages(DEVICES_DISCONNECT_TIMEOUT);
transitionTo(mHotOff);
finishSwitchingOff();
}
break;
case ALL_DEVICES_DISCONNECTED:
+ removeMessages(DEVICES_DISCONNECT_TIMEOUT);
if (mBluetoothService.getScanMode() == BluetoothAdapter.SCAN_MODE_NONE) {
transitionTo(mHotOff);
finishSwitchingOff();
}
break;
+ case DEVICES_DISCONNECT_TIMEOUT:
+ sendMessage(ALL_DEVICES_DISCONNECTED);
+ // reset the hardware for error recovery
+ Log.e(TAG, "Devices failed to disconnect, reseting...");
+ deferMessage(obtainMessage(TURN_COLD));
+ if (mContext.getResources().getBoolean
+ (com.android.internal.R.bool.config_bluetooth_adapter_quick_switch)) {
+ deferMessage(obtainMessage(TURN_HOT));
+ }
+ break;
case USER_TURN_ON:
case AIRPLANE_MODE_OFF:
case AIRPLANE_MODE_ON:
@@ -457,7 +475,7 @@
}
if (!mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
transitionTo(mPerProcessState);
- deferMessage(obtainMessage(USER_TURN_OFF));
+ deferMessage(obtainMessage(TURN_HOT));
break;
}
//$FALL-THROUGH$ to AIRPLANE_MODE_ON
@@ -466,6 +484,7 @@
broadcastState(BluetoothAdapter.STATE_TURNING_OFF);
mBluetoothService.switchConnectable(false);
mBluetoothService.disconnectDevices();
+ sendMessageDelayed(DEVICES_DISCONNECT_TIMEOUT, DEVICES_DISCONNECT_TIMEOUT_TIME);
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
if (message.what == AIRPLANE_MODE_ON) {
@@ -474,8 +493,9 @@
deferMessage(obtainMessage(AIRPLANE_MODE_ON));
}
break;
- case AIRPLANE_MODE_OFF: // ignore
- case USER_TURN_ON: // ignore
+ case AIRPLANE_MODE_OFF:
+ case USER_TURN_ON:
+ Log.w(TAG, "BluetoothOn received: " + message.what);
break;
case PER_PROCESS_TURN_ON:
perProcessCallback(true, (IBluetoothStateChangeCallback)message.obj);
@@ -526,19 +546,34 @@
// run bluetooth now that it's turned on
mBluetoothService.runBluetooth();
break;
- case USER_TURN_OFF:
+ case TURN_HOT:
broadcastState(BluetoothAdapter.STATE_TURNING_OFF);
if (mBluetoothService.getAdapterConnectionState() !=
BluetoothAdapter.STATE_DISCONNECTED) {
mBluetoothService.disconnectDevices();
+ sendMessageDelayed(DEVICES_DISCONNECT_TIMEOUT,
+ DEVICES_DISCONNECT_TIMEOUT_TIME);
break;
}
//$FALL-THROUGH$ all devices are already disconnected
case ALL_DEVICES_DISCONNECTED:
+ removeMessages(DEVICES_DISCONNECT_TIMEOUT);
mBluetoothService.finishDisable();
broadcastState(BluetoothAdapter.STATE_OFF);
break;
- case PER_PROCESS_TURN_OFF:
+ case DEVICES_DISCONNECT_TIMEOUT:
+ mBluetoothService.finishDisable();
+ broadcastState(BluetoothAdapter.STATE_OFF);
+ Log.e(TAG, "Devices fail to disconnect, reseting...");
+ transitionTo(mHotOff);
+ deferMessage(obtainMessage(TURN_COLD));
+ for (IBluetoothStateChangeCallback c:
+ mBluetoothService.getApplicationStateChangeCallbacks()) {
+ perProcessCallback(false, c);
+ deferMessage(obtainMessage(PER_PROCESS_TURN_ON, c));
+ }
+ break;
+ case PER_PROCESS_TURN_OFF:
perProcessCallback(false, (IBluetoothStateChangeCallback)message.obj);
if (mBluetoothService.isApplicationStateChangeTrackerEmpty()) {
mBluetoothService.switchConnectable(false);
@@ -557,6 +592,9 @@
// we turn all the way to PowerOff with AIRPLANE_MODE_ON
deferMessage(obtainMessage(AIRPLANE_MODE_ON));
break;
+ case USER_TURN_OFF:
+ Log.w(TAG, "PerProcessState received: " + message.what);
+ break;
default:
return NOT_HANDLED;
}
diff --git a/core/java/android/server/BluetoothPanProfileHandler.java b/core/java/android/server/BluetoothPanProfileHandler.java
index 0d63e19..37cfdc4 100644
--- a/core/java/android/server/BluetoothPanProfileHandler.java
+++ b/core/java/android/server/BluetoothPanProfileHandler.java
@@ -145,13 +145,14 @@
return false;
}
- handlePanDeviceStateChange(device, BluetoothPan.STATE_CONNECTING,
+ // Send interface as null as it is not known
+ handlePanDeviceStateChange(device, null, BluetoothPan.STATE_CONNECTING,
BluetoothPan.LOCAL_PANU_ROLE);
if (mBluetoothService.connectPanDeviceNative(objectPath, "nap")) {
debugLog("connecting to PAN");
return true;
} else {
- handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTED,
+ handlePanDeviceStateChange(device, null, BluetoothPan.STATE_DISCONNECTED,
BluetoothPan.LOCAL_PANU_ROLE);
errorLog("could not connect to PAN");
return false;
@@ -168,16 +169,16 @@
panDevice.mLocalRole == BluetoothPan.LOCAL_NAP_ROLE) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
- handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTING,
- panDevice.mLocalRole);
+ handlePanDeviceStateChange(device, panDevice.mIface,
+ BluetoothPan.STATE_DISCONNECTING, panDevice.mLocalRole);
if (!mBluetoothService.disconnectPanServerDeviceNative(objectPath,
device.getAddress(),
- panDevice.mIfaceAddr)) {
+ panDevice.mIface)) {
errorLog("could not disconnect Pan Server Device "+device.getAddress());
// Restore prev state
- handlePanDeviceStateChange(device, state,
+ handlePanDeviceStateChange(device, panDevice.mIface, state,
panDevice.mLocalRole);
return false;
@@ -230,19 +231,19 @@
return false;
}
- handlePanDeviceStateChange(device, BluetoothPan.STATE_DISCONNECTING,
+ handlePanDeviceStateChange(device, panDevice.mIface, BluetoothPan.STATE_DISCONNECTING,
panDevice.mLocalRole);
if (panDevice.mLocalRole == BluetoothPan.LOCAL_NAP_ROLE) {
if (!mBluetoothService.disconnectPanServerDeviceNative(objectPath, device.getAddress(),
panDevice.mIface)) {
// Restore prev state, this shouldn't happen
- handlePanDeviceStateChange(device, state, panDevice.mLocalRole);
+ handlePanDeviceStateChange(device, panDevice.mIface, state, panDevice.mLocalRole);
return false;
}
} else {
if (!mBluetoothService.disconnectPanDeviceNative(objectPath)) {
// Restore prev state, this shouldn't happen
- handlePanDeviceStateChange(device, state, panDevice.mLocalRole);
+ handlePanDeviceStateChange(device, panDevice.mIface, state, panDevice.mLocalRole);
return false;
}
}
@@ -291,6 +292,7 @@
panDevice.mState = state;
panDevice.mIfaceAddr = ifaceAddr;
panDevice.mLocalRole = role;
+ panDevice.mIface = iface;
}
Intent intent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
@@ -304,11 +306,6 @@
mBluetoothService.sendConnectionStateChange(device, state, prevState);
}
- void handlePanDeviceStateChange(BluetoothDevice device,
- int state, int role) {
- handlePanDeviceStateChange(device, null, state, role);
- }
-
private class BluetoothPanDevice {
private int mState;
private String mIfaceAddr;
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 28546dc..3029c9d 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -1565,6 +1565,8 @@
@Override
public boolean changeApplicationBluetoothState(boolean on,
IBluetoothStateChangeCallback callback, IBinder binder) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+
int pid = Binder.getCallingPid();
//mStateChangeTracker is a synchronized map
if (!mStateChangeTracker.containsKey(pid)) {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 66d2641..f2b6b1f 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -635,16 +635,8 @@
destroySurface();
// Create an EGL surface we can render into.
- mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, holder, null);
-
- if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
- int error = sEgl.eglGetError();
- if (error == EGL_BAD_NATIVE_WINDOW) {
- Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
- return null;
- }
- throw new RuntimeException("createWindowSurface failed "
- + getEGLErrorString(error));
+ if (!createSurface(holder)) {
+ return null;
}
/*
@@ -713,18 +705,34 @@
// Cancels any existing buffer to ensure we'll get a buffer
// of the right size before we call eglSwapBuffers
sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+
+ if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
+ sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+ mEglSurface = null;
+ setEnabled(false);
+ }
+
+ if (holder.getSurface().isValid()) {
+ if (!createSurface(holder)) {
+ return;
+ }
+ setEnabled(true);
+ }
+ }
+
+ private boolean createSurface(SurfaceHolder holder) {
mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, holder, null);
if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
int error = sEgl.eglGetError();
if (error == EGL_BAD_NATIVE_WINDOW) {
Log.e(LOG_TAG, "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
- return;
+ return false;
}
throw new RuntimeException("createWindowSurface failed "
+ getEGLErrorString(error));
}
+ return true;
}
@Override
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 836867b..7a96a50 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -29,30 +29,84 @@
private static final String LOG_TAG = "Surface";
private static final boolean DEBUG_RELEASE = false;
+ /* orientations for setOrientation() */
+ public static final int ROTATION_0 = 0;
+ public static final int ROTATION_90 = 1;
+ public static final int ROTATION_180 = 2;
+ public static final int ROTATION_270 = 3;
+
+ /**
+ * Does this object hold a valid surface? Returns true if it holds
+ * a physical surface, so lockCanvas() will succeed. Otherwise
+ * returns false.
+ */
+ public native boolean isValid();
+
+ /** Release the local reference to the server-side surface.
+ * Always call release() when you're done with a Surface. This will
+ * make the surface invalid.
+ */
+ public native void release();
+
+ /** draw into a surface */
+ public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException {
+ /*
+ * the dirty rectangle may be expanded to the surface's size, if for
+ * instance it has been resized or if the bits were lost, since the last
+ * call.
+ */
+ return lockCanvasNative(dirty);
+ }
+
+ /** unlock the surface and asks a page flip */
+ public native void unlockCanvasAndPost(Canvas canvas);
+
+ /**
+ * unlock the surface. the screen won't be updated until
+ * post() or postAll() is called
+ */
+ public native void unlockCanvas(Canvas canvas);
+
+ @Override
+ public String toString() {
+ return "Surface(name=" + mName + ", identity=" + getIdentity() + ")";
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public native void readFromParcel(Parcel source);
+ public native void writeToParcel(Parcel dest, int flags);
+
+ /**
+ * Exception thrown when a surface couldn't be created or resized
+ */
+ public static class OutOfResourcesException extends Exception {
+ public OutOfResourcesException() {
+ }
+ public OutOfResourcesException(String name) {
+ super(name);
+ }
+ }
+
+ /*
+ * -----------------------------------------------------------------------
+ * No user serviceable parts beyond this point
+ * -----------------------------------------------------------------------
+ */
+
/* flags used in constructor (keep in sync with ISurfaceComposer.h) */
- /** Surface is created hidden */
+ /** Surface is created hidden @hide */
public static final int HIDDEN = 0x00000004;
- /** The surface is to be used by hardware accelerators or DMA engines
- * @deprecated this is ignored, this value is set automatically when needed.
- */
- @Deprecated
- public static final int HARDWARE = 0x00000010;
-
- /** Implies "HARDWARE", the surface is to be used by the GPU;
- * additionally the backbuffer is never preserved for these
- * surfaces.
- * @deprecated this is ignored, this value is set automatically when needed.
- */
- @Deprecated
- public static final int GPU = 0x00000028;
-
/** The surface contains secure content, special measures will
* be taken to disallow the surface's content to be copied from
* another process. In particular, screenshots and VNC servers will
* be disabled, but other measures can take place, for instance the
- * surface might not be hardware accelerated. */
+ * surface might not be hardware accelerated.
+ * @hide*/
public static final int SECURE = 0x00000080;
/** Creates a surface where color components are interpreted as
@@ -75,20 +129,11 @@
*
* In some rare situations, a non pre-multiplied surface is preferable.
*
+ * @hide
*/
public static final int NON_PREMULTIPLIED = 0x00000100;
/**
- * Creates a surface without a rendering buffer. Instead, the content
- * of the surface must be pushed by an external entity. This type
- * of surface can be used for efficient camera preview or movie
- * playback.
- *
- * @deprecated not support by the system anymore
- */
- @Deprecated
- public static final int PUSH_BUFFERS = 0x00000200;
- /**
* Indicates that the surface must be considered opaque, even if its
* pixel format is set to translucent. This can be useful if an
* application needs full RGBA 8888 support for instance but will
@@ -109,7 +154,7 @@
// 0x1000 is reserved for an independent DRM protected flag in framework
- /** Creates a normal surface. This is the default. */
+ /** Creates a normal surface. This is the default. @hide */
public static final int FX_SURFACE_NORMAL = 0x00000000;
/** Creates a Blur surface. Everything behind this surface is blurred
@@ -117,6 +162,7 @@
* is not settable or guaranteed.
* It is an error to lock a Blur surface, since it doesn't have
* a backing store.
+ * @hide
*/
public static final int FX_SURFACE_BLUR = 0x00010000;
@@ -124,55 +170,35 @@
* by the amount specified in {@link #setAlpha}.
* It is an error to lock a Dim surface, since it doesn't have
* a backing store.
+ * @hide
*/
public static final int FX_SURFACE_DIM = 0x00020000;
- /** Mask used for FX values above */
+ /** Mask used for FX values above @hide */
public static final int FX_SURFACE_MASK = 0x000F0000;
/* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
- /** Hide the surface. Equivalent to calling hide(). */
+ /** Hide the surface. Equivalent to calling hide(). @hide */
public static final int SURFACE_HIDDEN = 0x01;
- /** Freeze the surface. Equivalent to calling freeze(). */
+ /** Freeze the surface. Equivalent to calling freeze(). @hide */
public static final int SURFACE_FROZEN = 0x02;
- /**
- * @deprecated Use {@link #SURFACE_FROZEN} instead.
- */
- @Deprecated
- public static final int SURACE_FROZEN = 0x02;
-
- /** Enable dithering when compositing this surface */
+ /** Enable dithering when compositing this surface @hide */
public static final int SURFACE_DITHER = 0x04;
-
- public static final int SURFACE_BLUR_FREEZE= 0x10;
-
- /* orientations for setOrientation() */
- public static final int ROTATION_0 = 0;
- public static final int ROTATION_90 = 1;
- public static final int ROTATION_180 = 2;
- public static final int ROTATION_270 = 3;
- /**
- * Disable the orientation animation
- * {@hide}
- */
+ /** Disable the orientation animation @hide */
public static final int FLAGS_ORIENTATION_ANIMATION_DISABLE = 0x000000001;
// The mSurfaceControl will only be present for Surfaces used by the window
// server or system processes. When this class is parceled we defer to the
- // mSurfaceControl to do the parceling. Otherwise we parcel the mNativeSurface.
- @SuppressWarnings("unused")
+ // mSurfaceControl to do the parceling. Otherwise we parcel the
+ // mNativeSurface.
private int mSurfaceControl;
- @SuppressWarnings("unused")
private int mSaveCount;
- @SuppressWarnings("unused")
private Canvas mCanvas;
- @SuppressWarnings("unused")
private int mNativeSurface;
- @SuppressWarnings("unused")
private int mSurfaceGenerationId;
private String mName;
@@ -184,19 +210,8 @@
// non compatibility mode.
private Matrix mCompatibleMatrix;
- @SuppressWarnings("unused")
private Exception mCreationStack;
- /**
- * Exception thrown when a surface couldn't be created or resized
- */
- public static class OutOfResourcesException extends Exception {
- public OutOfResourcesException() {
- }
- public OutOfResourcesException(String name) {
- super(name);
- }
- }
/*
* We use a class initializer to allow the native code to cache some
@@ -219,10 +234,7 @@
initFromSurfaceTexture(surfaceTexture);
}
- /**
- * create a surface
- * {@hide}
- */
+ /** create a surface @hide */
public Surface(SurfaceSession s,
int pid, int display, int w, int h, int format, int flags)
throws OutOfResourcesException {
@@ -233,10 +245,7 @@
init(s,pid,null,display,w,h,format,flags);
}
- /**
- * create a surface with a name
- * {@hide}
- */
+ /** create a surface with a name @hide */
public Surface(SurfaceSession s,
int pid, String name, int display, int w, int h, int format, int flags)
throws OutOfResourcesException {
@@ -251,7 +260,7 @@
/**
* Create an empty surface, which will later be filled in by
* readFromParcel().
- * {@hide}
+ * @hide
*/
public Surface() {
if (DEBUG_RELEASE) {
@@ -260,16 +269,35 @@
mCanvas = new CompatibleCanvas();
}
+ private Surface(Parcel source) throws OutOfResourcesException {
+ init(source);
+ }
+
/**
- * A Canvas class that can handle the compatibility mode. This does two things differently.
+ * Copy another surface to this one. This surface now holds a reference
+ * to the same data as the original surface, and is -not- the owner.
+ * @hide
+ */
+ public native void copyFrom(Surface o);
+
+ /** @hide */
+ public int getGenerationId() {
+ return mSurfaceGenerationId;
+ }
+
+ /**
+ * A Canvas class that can handle the compatibility mode. This does two
+ * things differently.
* <ul>
- * <li> Returns the width and height of the target metrics, rather than native.
- * For example, the canvas returns 320x480 even if an app is running in WVGA high density.
- * <li> Scales the matrix in setMatrix by the application scale, except if the matrix looks
- * like obtained from getMatrix. This is a hack to handle the case that an application
- * uses getMatrix to keep the original matrix, set matrix of its own, then set the original
- * matrix back. There is no perfect solution that works for all cases, and there are a lot of
- * cases that this model does not work, but we hope this works for many apps.
+ * <li>Returns the width and height of the target metrics, rather than
+ * native. For example, the canvas returns 320x480 even if an app is running
+ * in WVGA high density.
+ * <li>Scales the matrix in setMatrix by the application scale, except if
+ * the matrix looks like obtained from getMatrix. This is a hack to handle
+ * the case that an application uses getMatrix to keep the original matrix,
+ * set matrix of its own, then set the original matrix back. There is no
+ * perfect solution that works for all cases, and there are a lot of cases
+ * that this model does not work, but we hope this works for many apps.
* </ul>
*/
private class CompatibleCanvas extends Canvas {
@@ -318,7 +346,8 @@
}
/**
- * Sets the translator used to scale canvas's width/height in compatibility mode.
+ * Sets the translator used to scale canvas's width/height in compatibility
+ * mode.
*/
void setCompatibilityTranslator(Translator translator) {
if (translator != null) {
@@ -328,73 +357,29 @@
}
}
- /**
- * Copy another surface to this one. This surface now holds a reference
- * to the same data as the original surface, and is -not- the owner.
- * {@hide}
- */
- public native void copyFrom(Surface o);
-
- /**
- * Does this object hold a valid surface? Returns true if it holds
- * a physical surface, so lockCanvas() will succeed. Otherwise
- * returns false.
- */
- public native boolean isValid();
-
- /**
- * @hide
- */
- public int getGenerationId() {
- return mSurfaceGenerationId;
- }
-
/** Free all server-side state associated with this surface and
- * release this object's reference. {@hide} */
+ * release this object's reference. @hide */
public native void destroy();
- /** Release the local reference to the server-side surface. @hide */
- public native void release();
+ private native Canvas lockCanvasNative(Rect dirty);
- /** draw into a surface */
- public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException
- {
- /* the dirty rectangle may be expanded to the surface's size, if
- * for instance it has been resized or if the bits were lost, since
- * the last call.
- */
- return lockCanvasNative(dirty);
- }
-
- private native Canvas lockCanvasNative(Rect dirty);
-
- /** unlock the surface and asks a page flip */
- public native void unlockCanvasAndPost(Canvas canvas);
-
- /**
- * unlock the surface. the screen won't be updated until
- * post() or postAll() is called
+ /*
+ * set display parameters & screenshots
*/
- public native void unlockCanvas(Canvas canvas);
- /** start/end a transaction {@hide} */
- public static native void openTransaction();
- /** {@hide} */
- public static native void closeTransaction();
-
/**
* Freezes the specified display, No updating of the screen will occur
* until unfreezeDisplay() is called. Everything else works as usual though,
* in particular transactions.
* @param display
- * {@hide}
+ * @hide
*/
public static native void freezeDisplay(int display);
/**
* resume updating the specified display.
* @param display
- * {@hide}
+ * @hide
*/
public static native void unfreezeDisplay(int display);
@@ -403,7 +388,7 @@
* @param display
* @param orientation
* @param flags
- * {@hide}
+ * @hide
*/
public static native void setOrientation(int display, int orientation, int flags);
@@ -411,6 +396,7 @@
* set the orientation of the given display.
* @param display
* @param orientation
+ * @hide
*/
public static void setOrientation(int display, int orientation) {
setOrientation(display, orientation, 0);
@@ -441,44 +427,43 @@
*/
public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer);
- /**
+
+ /*
* set surface parameters.
* needs to be inside open/closeTransaction block
*/
+
+ /** start a transaction @hide */
+ public static native void openTransaction();
+ /** end a transaction @hide */
+ public static native void closeTransaction();
+ /** @hide */
public native void setLayer(int zorder);
+ /** @hide */
public native void setPosition(int x, int y);
+ /** @hide */
public native void setSize(int w, int h);
-
+ /** @hide */
public native void hide();
+ /** @hide */
public native void show();
+ /** @hide */
public native void setTransparentRegionHint(Region region);
+ /** @hide */
public native void setAlpha(float alpha);
- public native void setMatrix(float dsdx, float dtdx,
- float dsdy, float dtdy);
-
+ /** @hide */
+ public native void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
+ /** @hide */
public native void freeze();
+ /** @hide */
public native void unfreeze();
-
+ /** @hide */
public native void setFreezeTint(int tint);
-
+ /** @hide */
public native void setFlags(int flags, int mask);
- @Override
- public String toString() {
- return "Surface(name=" + mName + ", identity=" + getIdentity() + ")";
- }
- private Surface(Parcel source) throws OutOfResourcesException {
- init(source);
- }
-
- public int describeContents() {
- return 0;
- }
-
- public native void readFromParcel(Parcel source);
- public native void writeToParcel(Parcel dest, int flags);
-
+
public static final Parcelable.Creator<Surface> CREATOR
= new Parcelable.Creator<Surface>()
{
@@ -496,7 +481,6 @@
}
};
- /* no user serviceable parts here ... */
@Override
protected void finalize() throws Throwable {
try {
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 96d6f09..76aa21f 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -204,6 +204,7 @@
}
mLayer.destroy();
+ mSurface.release();
mSurface = null;
mLayer = null;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 911bf2f..ec4c5a29 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1253,6 +1253,11 @@
mScroller.abortAnimation();
}
disposeResizeBuffer();
+ // Our surface is gone
+ if (mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled()) {
+ mAttachInfo.mHardwareRenderer.destroy(true);
+ }
} else if (surfaceGenerationId != mSurface.getGenerationId() &&
mSurfaceHolder == null && mAttachInfo.mHardwareRenderer != null) {
fullRedrawNeeded = true;
@@ -1273,7 +1278,7 @@
}
} catch (RemoteException e) {
}
-
+
if (DEBUG_ORIENTATION) Log.v(
TAG, "Relayout returned: frame=" + frame + ", surface=" + mSurface);
diff --git a/core/java/android/webkit/DeviceMotionService.java b/core/java/android/webkit/DeviceMotionService.java
index 7d7a0f0..b4d5759 100755
--- a/core/java/android/webkit/DeviceMotionService.java
+++ b/core/java/android/webkit/DeviceMotionService.java
@@ -99,6 +99,7 @@
mUpdateRunnable = new Runnable() {
@Override
public void run() {
+ assert mIsRunning;
mManager.onMotionChange(new Double(mLastAcceleration[0]),
new Double(mLastAcceleration[1]), new Double(mLastAcceleration[2]),
INTERVAL_MILLIS);
@@ -157,6 +158,11 @@
assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
assert(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER);
+ // We may get callbacks after the call to getSensorManager().unregisterListener() returns.
+ if (!mIsRunning) {
+ return;
+ }
+
boolean firstData = mLastAcceleration == null;
mLastAcceleration = event.values;
if (firstData) {
diff --git a/core/java/android/webkit/DeviceOrientationService.java b/core/java/android/webkit/DeviceOrientationService.java
index f3c0576..47c8ab7 100755
--- a/core/java/android/webkit/DeviceOrientationService.java
+++ b/core/java/android/webkit/DeviceOrientationService.java
@@ -188,6 +188,7 @@
assert(event.values.length == 3);
assert WebViewCore.THREAD_NAME.equals(Thread.currentThread().getName());
+ // We may get callbacks after the call to getSensorManager().unregisterListener() returns.
if (!mIsRunning) {
return;
}
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index f354c6e..d977029 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -250,6 +250,7 @@
* {@inheritDoc}
*/
public GridLayout(Context context) {
+ //noinspection NullableProblems
this(context, null);
}
@@ -519,14 +520,6 @@
return result;
}
- private static int sum(int[] a) {
- int result = 0;
- for (int i = 0, N = a.length; i < N; i++) {
- result += a[i];
- }
- return result;
- }
-
@SuppressWarnings("unchecked")
private static <T> T[] append(T[] a, T[] b) {
T[] result = (T[]) Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
@@ -553,6 +546,7 @@
}
}
+ /** @noinspection UnusedParameters*/
private int getDefaultMargin(View c, boolean horizontal, boolean leading) {
if (c.getClass() == Space.class) {
return 0;
@@ -576,7 +570,7 @@
return getDefaultMargin(c, isAtEdge, horizontal, leading);
}
- private int getMargin(View view, boolean horizontal, boolean leading) {
+ private int getMargin1(View view, boolean horizontal, boolean leading) {
LayoutParams lp = getLayoutParams(view);
int margin = horizontal ?
(leading ? lp.leftMargin : lp.rightMargin) :
@@ -584,6 +578,19 @@
return margin == UNDEFINED ? getDefaultMarginValue(view, lp, horizontal, leading) : margin;
}
+ private int getMargin(View view, boolean horizontal, boolean leading) {
+ if (mAlignmentMode == ALIGN_MARGINS) {
+ return getMargin1(view, horizontal, leading);
+ } else {
+ Axis axis = horizontal ? mHorizontalAxis : mVerticalAxis;
+ int[] margins = leading ? axis.getLeadingMargins() : axis.getTrailingMargins();
+ LayoutParams lp = getLayoutParams(view);
+ Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
+ int index = leading ? spec.span.min : spec.span.max;
+ return margins[index];
+ }
+ }
+
private int getTotalMargin(View child, boolean horizontal) {
return getMargin(child, horizontal, true) + getMargin(child, horizontal, false);
}
@@ -733,15 +740,6 @@
graphics.drawLine(dx + x1, dy + y1, dx + x2, dy + y2, paint);
}
- private void drawRectangle(Canvas graphics, int x1, int y1, int x2, int y2, Paint paint) {
- x2 = x2 - 1;
- y2 = y2 - 1;
- graphics.drawLine(x1, y1, x1, y2, paint);
- graphics.drawLine(x1, y1, x2, y1, paint);
- graphics.drawLine(x1, y2, x2, y2, paint);
- graphics.drawLine(x2, y1, x2, y2, paint);
- }
-
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
@@ -751,6 +749,7 @@
int width = getWidth() - getPaddingLeft() - getPaddingRight();
Paint paint = new Paint();
+ paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.argb(50, 255, 255, 255));
int[] xs = mHorizontalAxis.locations;
@@ -773,22 +772,18 @@
paint.setColor(Color.BLUE);
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- drawRectangle(canvas,
- c.getLeft(),
- c.getTop(),
- c.getRight(),
- c.getBottom(), paint);
+ canvas.drawRect(c.getLeft(), c.getTop(), c.getRight(), c.getBottom(), paint);
}
// Draw margins
paint.setColor(Color.MAGENTA);
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
- drawRectangle(canvas,
- c.getLeft() - getMargin(c, true, true),
- c.getTop() - getMargin(c, false, true),
- c.getRight() + getMargin(c, true, false),
- c.getBottom() + getMargin(c, false, false), paint);
+ canvas.drawRect(
+ c.getLeft() - getMargin1(c, true, true),
+ c.getTop() - getMargin1(c, false, true),
+ c.getRight() + getMargin1(c, true, false),
+ c.getBottom() + getMargin1(c, false, false), paint);
}
}
}
@@ -875,11 +870,7 @@
if (isGone(c)) {
return 0;
}
- int result = getMeasurement(c, horizontal);
- if (mAlignmentMode == ALIGN_MARGINS) {
- return result + getTotalMargin(c, horizontal);
- }
- return result;
+ return getMeasurement(c, horizontal) + getTotalMargin(c, horizontal);
}
@Override
@@ -920,6 +911,9 @@
mHorizontalAxis.layout(targetWidth - paddingLeft - paddingRight);
mVerticalAxis.layout(targetHeight - paddingTop - paddingBottom);
+ int[] hLocations = mHorizontalAxis.getLocations();
+ int[] vLocations = mVerticalAxis.getLocations();
+
for (int i = 0, N = getChildCount(); i < N; i++) {
View c = getChildAt(i);
if (isGone(c)) continue;
@@ -930,11 +924,11 @@
Interval colSpan = columnSpec.span;
Interval rowSpan = rowSpec.span;
- int x1 = mHorizontalAxis.getLocationIncludingMargin(true, colSpan.min);
- int y1 = mVerticalAxis.getLocationIncludingMargin(true, rowSpan.min);
+ int x1 = hLocations[colSpan.min];
+ int y1 = vLocations[rowSpan.min];
- int x2 = mHorizontalAxis.getLocationIncludingMargin(false, colSpan.max);
- int y2 = mVerticalAxis.getLocationIncludingMargin(false, rowSpan.max);
+ int x2 = hLocations[colSpan.max];
+ int y2 = vLocations[rowSpan.max];
int cellWidth = x2 - x1;
int cellHeight = y2 - y1;
@@ -951,36 +945,29 @@
Bounds rowBounds = mVerticalAxis.getGroupBounds().getValue(i);
// Gravity offsets: the location of the alignment group relative to its cell group.
+ //noinspection NullableProblems
int c2ax = protect(hAlign.getAlignmentValue(null, cellWidth - colBounds.size(true)));
+ //noinspection NullableProblems
int c2ay = protect(vAlign.getAlignmentValue(null, cellHeight - rowBounds.size(true)));
- if (mAlignmentMode == ALIGN_MARGINS) {
- int leftMargin = getMargin(c, true, true);
- int topMargin = getMargin(c, false, true);
- int rightMargin = getMargin(c, true, false);
- int bottomMargin = getMargin(c, false, false);
+ int leftMargin = getMargin(c, true, true);
+ int topMargin = getMargin(c, false, true);
+ int rightMargin = getMargin(c, true, false);
+ int bottomMargin = getMargin(c, false, false);
- // Same calculation as getMeasurementIncludingMargin()
- int mWidth = leftMargin + pWidth + rightMargin;
- int mHeight = topMargin + pHeight + bottomMargin;
+ // Same calculation as getMeasurementIncludingMargin()
+ int mWidth = leftMargin + pWidth + rightMargin;
+ int mHeight = topMargin + pHeight + bottomMargin;
- // Alignment offsets: the location of the view relative to its alignment group.
- int a2vx = colBounds.getOffset(c, hAlign, mWidth);
- int a2vy = rowBounds.getOffset(c, vAlign, mHeight);
+ // Alignment offsets: the location of the view relative to its alignment group.
+ int a2vx = colBounds.getOffset(c, hAlign, mWidth);
+ int a2vy = rowBounds.getOffset(c, vAlign, mHeight);
- dx = c2ax + a2vx + leftMargin;
- dy = c2ay + a2vy + topMargin;
+ dx = c2ax + a2vx + leftMargin;
+ dy = c2ay + a2vy + topMargin;
- cellWidth -= leftMargin + rightMargin;
- cellHeight -= topMargin + bottomMargin;
- } else {
- // Alignment offsets: the location of the view relative to its alignment group.
- int a2vx = colBounds.getOffset(c, hAlign, pWidth);
- int a2vy = rowBounds.getOffset(c, vAlign, pHeight);
-
- dx = c2ax + a2vx;
- dy = c2ay + a2vy;
- }
+ cellWidth -= leftMargin + rightMargin;
+ cellHeight -= topMargin + bottomMargin;
int type = PRF;
int width = hAlign.getSizeInCell(c, pWidth, cellWidth, type);
@@ -1366,10 +1353,9 @@
String axis = horizontal ? "horizontal" : "vertical";
int N = getCount() + 1; // The number of vertices is the number of columns/rows + 1.
- boolean changed = false;
// We take one extra pass over traditional Bellman-Ford (and omit their final step)
for (int i = 0; i < N; i++) {
- changed = false;
+ boolean changed = false;
for (int j = 0, length = arcs.length; j < length; j++) {
changed |= relax(locations, arcs[j]);
}
@@ -1420,7 +1406,7 @@
Spec spec = horizontal ? lp.columnSpec : lp.rowSpec;
Interval span = spec.span;
int index = leading ? span.min : span.max;
- margins[index] = max(margins[index], getMargin(c, horizontal, leading));
+ margins[index] = max(margins[index], getMargin1(c, horizontal, leading));
}
}
@@ -1446,34 +1432,8 @@
return trailingMargins;
}
- private void addMargins() {
- int[] leadingMargins = getLeadingMargins();
- int[] trailingMargins = getTrailingMargins();
-
- int delta = 0;
- for (int i = 0, N = getCount(); i < N; i++) {
- int margins = leadingMargins[i] + trailingMargins[i + 1];
- delta += margins;
- locations[i + 1] += delta;
- }
- }
-
- private int getLocationIncludingMargin(boolean leading, int index) {
- int location = locations[index];
- int margin;
- if (mAlignmentMode != ALIGN_MARGINS) {
- margin = (leading ? leadingMargins : trailingMargins)[index];
- } else {
- margin = 0;
- }
- return leading ? (location + margin) : (location - margin);
- }
-
private void computeLocations(int[] a) {
solve1(getArcs(), a);
- if (mAlignmentMode != ALIGN_MARGINS) {
- addMargins();
- }
}
private int[] getLocations() {
@@ -1495,12 +1455,6 @@
}
private void setParentConstraints(int min, int max) {
- if (mAlignmentMode != ALIGN_MARGINS) {
- int margins = sum(getLeadingMargins()) + sum(getTrailingMargins());
- min -= margins;
- max -= margins;
- }
-
parentMin.value = min;
parentMax.value = -max;
locationsValid = false;
@@ -1905,10 +1859,6 @@
this.values = compact(values, index);
}
- private K getKey(int i) {
- return keys[index[i]];
- }
-
private V getValue(int i) {
return values[index[i]];
}
@@ -1958,8 +1908,6 @@
of the values for each View.
*/
private static class Bounds {
- private static final Bounds GONE = new Bounds();
-
public int before;
public int after;
public int flexibility; // we're flexible iff all included specs are flexible
@@ -1995,8 +1943,8 @@
protected final void include(View c, Spec spec, GridLayout gridLayout, Axis axis) {
this.flexibility &= spec.getFlexibility();
int size = gridLayout.getMeasurementIncludingMargin(c, axis.horizontal);
- // todo test this works correctly when the returned value is UNDEFINED
Alignment alignment = gridLayout.getAlignment(spec.alignment, axis.horizontal);
+ // todo test this works correctly when the returned value is UNDEFINED
int before = alignment.getAlignmentValue(c, size);
include(before, size - before);
}
@@ -2079,6 +2027,7 @@
if (max != interval.max) {
return false;
}
+ //noinspection RedundantIfStatement
if (min != interval.min) {
return false;
}
@@ -2113,57 +2062,33 @@
* For column groups, this specifies the horizontal alignment.
*/
public static class Spec {
- private static final int UNDEFINED_FLEXIBILITY = UNDEFINED;
-
final Interval span;
-
final Alignment alignment;
- /**
- * The <em>flexibility</em> property tells GridLayout how to derive minimum and maximum size
- * values for a component. Specifications are made with respect to a child's
- * 'measured size'. A child's measured size is, in turn, controlled by its
- * height and width layout parameters which either specify a size or, in
- * the case of {@link LayoutParams#WRAP_CONTENT WRAP_CONTENT}, defer to
- * the computed size of the component.
- * <p>
- * A cell group is flexible only if <em>all</em> of its components are flexible.
- * <p>
- * By default, flexibility is {@link #INFLEXIBLE} only when alignment/gravity is undefined.
- */
- final int flexibility;
-
- private Spec(Interval span, Alignment alignment, int flexibility) {
+ private Spec(Interval span, Alignment alignment) {
this.span = span;
this.alignment = alignment;
- this.flexibility = flexibility;
}
/* Copying constructor */
private Spec(Spec that) {
- this(that.span, that.alignment, that.flexibility);
+ this(that.span, that.alignment);
}
private Spec(int start, int size, Alignment alignment) {
- this(new Interval(start, start + size), alignment, UNDEFINED);
+ this(new Interval(start, start + size), alignment);
}
private Spec copyWriteSpan(Interval span) {
- return new Spec(span, alignment, flexibility);
+ return new Spec(span, alignment);
}
private Spec copyWriteAlignment(Alignment alignment) {
- return new Spec(span, alignment, flexibility);
- }
-
- private static int defaultFlexibility(Alignment alignment) {
- return (alignment == UNDEFINED_ALIGNMENT) ? INFLEXIBLE : CAN_STRETCH;
+ return new Spec(span, alignment);
}
int getFlexibility() {
- return (flexibility != UNDEFINED_FLEXIBILITY) ?
- flexibility :
- defaultFlexibility(alignment);
+ return (alignment == UNDEFINED_ALIGNMENT) ? INFLEXIBLE : CAN_STRETCH;
}
/**
@@ -2190,6 +2115,7 @@
if (!alignment.equals(spec.alignment)) {
return false;
}
+ //noinspection RedundantIfStatement
if (!span.equals(spec.span)) {
return false;
}
@@ -2447,15 +2373,5 @@
private static final int INFLEXIBLE = 0;
- /**
- * Indicates that a view's size should be greater than or equal to the size specified by
- * its layout parameters.
- *
- * @deprecated Please use {@link #spec(int, int, Alignment)} instead,
- * all spec's that define alignment (gravity) are assumed to able to stretch.
- *
- * @hide
- */
- @Deprecated
- public static final int CAN_STRETCH = 2;
+ private static final int CAN_STRETCH = 2;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 65ee745..968d612 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -343,6 +343,9 @@
private Drawable mSelectHandleRight;
private Drawable mSelectHandleCenter;
+ // Global listener that detects changes in the global position of the TextView
+ private PositionListener mPositionListener;
+
private float mLastDownPositionX, mLastDownPositionY;
private Callback mCustomSelectionActionModeCallback;
@@ -394,7 +397,7 @@
*/
boolean onEditorAction(TextView v, int actionId, KeyEvent event);
}
-
+
public TextView(Context context) {
this(context, null);
}
@@ -2081,7 +2084,7 @@
TextAppearance_textStyle, -1);
setTypefaceByIndex(typefaceIndex, styleIndex);
-
+
if (appearance.getBoolean(com.android.internal.R.styleable.TextAppearance_textAllCaps,
false)) {
setTransformationMethod(new AllCapsTransformationMethod(getContext()));
@@ -3019,7 +3022,7 @@
* To style your strings, attach android.text.style.* objects to a
* {@link android.text.SpannableString SpannableString}, or see the
* <a href="{@docRoot}guide/topics/resources/available-resources.html#stringresources">
- * Available Resource Types</a> documentation for an example of setting
+ * Available Resource Types</a> documentation for an example of setting
* formatted text in the XML resource file.
*
* @attr ref android.R.styleable#TextView_text
@@ -8757,32 +8760,247 @@
return ((minOffset >= selectionStart) && (maxOffset < selectionEnd));
}
+ private PositionListener getPositionListener() {
+ if (mPositionListener == null) {
+ mPositionListener = new PositionListener();
+ }
+ return mPositionListener;
+ }
+
+ private interface TextViewPositionListener {
+ public void updatePosition(int parentPositionX, int parentPositionY, boolean modified);
+ }
+
+ private class PositionListener implements ViewTreeObserver.OnPreDrawListener {
+ // 3 handles, 2 ActionPopup (suggestionsPopup first hides the others)
+ private final int MAXIMUM_NUMBER_OF_LISTENERS = 5;
+ private TextViewPositionListener[] mPositionListeners =
+ new TextViewPositionListener[MAXIMUM_NUMBER_OF_LISTENERS];
+ private boolean mCanMove[] = new boolean[MAXIMUM_NUMBER_OF_LISTENERS];
+ private boolean mPositionHasChanged = true;
+ // Absolute position of the TextView with respect to its parent window
+ private int mPositionX, mPositionY;
+ private int mNumberOfListeners;
+
+ public void addSubscriber(TextViewPositionListener positionListener, boolean canMove) {
+ if (mNumberOfListeners == 0) {
+ updatePosition();
+ ViewTreeObserver vto = TextView.this.getViewTreeObserver();
+ vto.addOnPreDrawListener(this);
+ }
+
+ int emptySlotIndex = -1;
+ for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
+ TextViewPositionListener listener = mPositionListeners[i];
+ if (listener == positionListener) {
+ return;
+ } else if (emptySlotIndex < 0 && listener == null) {
+ emptySlotIndex = i;
+ }
+ }
+
+ mPositionListeners[emptySlotIndex] = positionListener;
+ mCanMove[emptySlotIndex] = canMove;
+ mNumberOfListeners++;
+ }
+
+ public void removeSubscriber(TextViewPositionListener positionListener) {
+ for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
+ if (mPositionListeners[i] == positionListener) {
+ mPositionListeners[i] = null;
+ mNumberOfListeners--;
+ break;
+ }
+ }
+
+ if (mNumberOfListeners == 0) {
+ ViewTreeObserver vto = TextView.this.getViewTreeObserver();
+ vto.removeOnPreDrawListener(this);
+ }
+ }
+
+ public int getPositionX() {
+ return mPositionX;
+ }
+
+ public int getPositionY() {
+ return mPositionY;
+ }
+
+ @Override
+ public boolean onPreDraw() {
+ updatePosition();
+
+ for (int i = 0; i < MAXIMUM_NUMBER_OF_LISTENERS; i++) {
+ if (mPositionHasChanged || mCanMove[i]) {
+ TextViewPositionListener positionListener = mPositionListeners[i];
+ if (positionListener != null) {
+ positionListener.updatePosition(mPositionX, mPositionY,
+ mPositionHasChanged);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private void updatePosition() {
+ TextView.this.getLocationInWindow(mTempCoords);
+
+ mPositionHasChanged = mTempCoords[0] != mPositionX || mTempCoords[1] != mPositionY;
+
+ mPositionX = mTempCoords[0];
+ mPositionY = mTempCoords[1];
+ }
+
+ public boolean isVisible(int positionX, int positionY) {
+ final TextView textView = TextView.this;
+
+ if (mTempRect == null) mTempRect = new Rect();
+ final Rect clip = mTempRect;
+ clip.left = getCompoundPaddingLeft();
+ clip.top = getExtendedPaddingTop();
+ clip.right = textView.getWidth() - getCompoundPaddingRight();
+ clip.bottom = textView.getHeight() - getExtendedPaddingBottom();
+
+ final ViewParent parent = textView.getParent();
+ if (parent == null || !parent.getChildVisibleRect(textView, clip, null)) {
+ return false;
+ }
+
+ int posX = mPositionX + positionX;
+ int posY = mPositionY + positionY;
+
+ // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal.
+ return posX >= clip.left - 1 && posX <= clip.right + 1 &&
+ posY >= clip.top && posY <= clip.bottom;
+ }
+
+ public boolean isOffsetVisible(int offset) {
+ final int line = mLayout.getLineForOffset(offset);
+ final int lineBottom = mLayout.getLineBottom(line);
+ final int primaryHorizontal = (int) mLayout.getPrimaryHorizontal(offset);
+ return isVisible(primaryHorizontal, lineBottom);
+ }
+ }
+
+ private abstract class PinnedPopupWindow implements TextViewPositionListener {
+ protected PopupWindow mPopupWindow;
+ protected LinearLayout mContentView;
+ int mPositionX, mPositionY;
+
+ protected abstract void createPopupWindow();
+ protected abstract void initContentView();
+ protected abstract int getTextOffset();
+ protected abstract int getVerticalLocalPosition(int line);
+ protected abstract int clipVertically(int positionY);
+
+ public PinnedPopupWindow() {
+ createPopupWindow();
+
+ mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
+ mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mContentView = new LinearLayout(TextView.this.getContext());
+ LayoutParams wrapContent = new LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+ mContentView.setLayoutParams(wrapContent);
+
+ initContentView();
+ mPopupWindow.setContentView(mContentView);
+ }
+
+ public void show() {
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ mContentView.measure(
+ View.MeasureSpec.makeMeasureSpec(displayMetrics.widthPixels,
+ View.MeasureSpec.AT_MOST),
+ View.MeasureSpec.makeMeasureSpec(displayMetrics.heightPixels,
+ View.MeasureSpec.AT_MOST));
+
+ TextView.this.getPositionListener().addSubscriber(this, false);
+
+ computeLocalPosition();
+
+ final PositionListener positionListener = TextView.this.getPositionListener();
+ updatePosition(positionListener.getPositionX(), positionListener.getPositionY());
+ }
+
+ private void computeLocalPosition() {
+ final int offset = getTextOffset();
+
+ final int width = mContentView.getMeasuredWidth();
+ mPositionX = (int) (mLayout.getPrimaryHorizontal(offset) - width / 2.0f);
+ mPositionX += viewportToContentHorizontalOffset();
+
+ final int line = mLayout.getLineForOffset(offset);
+ mPositionY = getVerticalLocalPosition(line);
+ mPositionY += viewportToContentVerticalOffset();
+ }
+
+ private void updatePosition(int parentPositionX, int parentPositionY) {
+ int positionX = parentPositionX + mPositionX;
+ int positionY = parentPositionY + mPositionY;
+
+ positionY = clipVertically(positionY);
+
+ // Horizontal clipping
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ final int width = mContentView.getMeasuredWidth();
+ positionX = Math.min(displayMetrics.widthPixels - width, positionX);
+ positionX = Math.max(0, positionX);
+
+ if (isShowing()) {
+ mPopupWindow.update(positionX, positionY, -1, -1);
+ } else {
+ mPopupWindow.showAtLocation(TextView.this, Gravity.NO_GRAVITY,
+ positionX, positionY);
+ }
+ }
+
+ public void hide() {
+ mPopupWindow.dismiss();
+ TextView.this.getPositionListener().removeSubscriber(this);
+ }
+
+ @Override
+ public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
+ if (isShowing() && getPositionListener().isOffsetVisible(getTextOffset())) {
+ updatePosition(parentPositionX, parentPositionY);
+ } else {
+ hide();
+ }
+ }
+
+ public boolean isShowing() {
+ return mPopupWindow.isShowing();
+ }
+ }
+
private static class SuggestionRangeSpan extends UnderlineSpan {
// TODO themable, would be nice to make it a child class of TextAppearanceSpan, but
// there is no way to have underline and TextAppearanceSpan.
}
- private class SuggestionsPopupWindow implements OnClickListener {
+ private class SuggestionsPopupWindow extends PinnedPopupWindow implements OnClickListener {
private static final int MAX_NUMBER_SUGGESTIONS = 5;
private static final int NO_SUGGESTIONS = -1;
- private final PopupWindow mPopupWindow;
- private LinearLayout mSuggestionsContainer;
private WordIterator mSuggestionWordIterator;
private TextAppearanceSpan[] mHighlightSpans = new TextAppearanceSpan[0];
- public SuggestionsPopupWindow() {
+ @Override
+ protected void createPopupWindow() {
mPopupWindow = new PopupWindow(TextView.this.mContext, null,
- com.android.internal.R.attr.textSuggestionsWindowStyle);
- mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+ com.android.internal.R.attr.textSuggestionsWindowStyle);
mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
mPopupWindow.setOutsideTouchable(true);
- mPopupWindow.setClippingEnabled(true);
+ mPopupWindow.setClippingEnabled(false);
+ }
- mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
- mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
-
- mSuggestionsContainer = new LinearLayout(TextView.this.mContext);
- mSuggestionsContainer.setOrientation(LinearLayout.VERTICAL);
+ @Override
+ protected void initContentView() {
+ mContentView.setOrientation(LinearLayout.VERTICAL);
LayoutInflater inflater = (LayoutInflater) TextView.this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -8795,7 +9013,7 @@
// Inflate the suggestion items once and for all.
for (int i = 0; i < MAX_NUMBER_SUGGESTIONS; i++) {
View childView = inflater.inflate(mTextEditSuggestionItemLayout,
- mSuggestionsContainer, false);
+ mContentView, false);
if (! (childView instanceof TextView)) {
throw new IllegalArgumentException(
@@ -8803,11 +9021,9 @@
}
childView.setTag(new SuggestionInfo());
- mSuggestionsContainer.addView(childView);
+ mContentView.addView(childView);
childView.setOnClickListener(this);
}
-
- mPopupWindow.setContentView(mSuggestionsContainer);
}
private class SuggestionInfo {
@@ -8827,30 +9043,61 @@
SuggestionSpan[] suggestionSpans = spannable.getSpans(pos, pos, SuggestionSpan.class);
// Cache the span length for performance reason.
- final HashMap<SuggestionSpan, Integer> spanLengthMap =
- new HashMap<SuggestionSpan, Integer>();
+ final HashMap<SuggestionSpan, Integer> spansLengths =
+ new HashMap<SuggestionSpan, Integer>();
for (SuggestionSpan suggestionSpan : suggestionSpans) {
int start = spannable.getSpanStart(suggestionSpan);
int end = spannable.getSpanEnd(suggestionSpan);
- spanLengthMap.put(suggestionSpan, end - start);
+ spansLengths.put(suggestionSpan, Integer.valueOf(end - start));
}
// The suggestions are sorted according to the lenght of the text that they cover
// (shorter first)
Arrays.sort(suggestionSpans, new Comparator<SuggestionSpan>() {
public int compare(SuggestionSpan span1, SuggestionSpan span2) {
- return spanLengthMap.get(span1) - spanLengthMap.get(span2);
+ return spansLengths.get(span1).intValue() - spansLengths.get(span2).intValue();
}
});
return suggestionSpans;
}
+ @Override
public void show() {
if (!(mText instanceof Editable)) return;
+ updateSuggestions();
- Spannable spannable = (Spannable) TextView.this.mText;
+ super.show();
+ }
+
+ @Override
+ protected int getTextOffset() {
+ return getSelectionStart();
+ }
+
+ @Override
+ protected int getVerticalLocalPosition(int line) {
+ return mLayout.getLineBottom(line);
+ }
+
+ @Override
+ protected int clipVertically(int positionY) {
+ final int height = mContentView.getMeasuredHeight();
+ final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
+ return Math.min(positionY, displayMetrics.heightPixels - height);
+ }
+
+ @Override
+ public void hide() {
+ super.hide();
+ if ((mText instanceof Editable) && mSuggestionRangeSpan != null) {
+ ((Editable) mText).removeSpan(mSuggestionRangeSpan);
+ }
+ }
+
+ private void updateSuggestions() {
+ Spannable spannable = (Spannable)TextView.this.mText;
SuggestionSpan[] suggestionSpans = getSuggestionSpans();
final int nbSpans = suggestionSpans.length;
@@ -8869,7 +9116,7 @@
String[] suggestions = suggestionSpan.getSuggestions();
int nbSuggestions = suggestions.length;
for (int suggestionIndex = 0; suggestionIndex < nbSuggestions; suggestionIndex++) {
- TextView textView = (TextView) mSuggestionsContainer.getChildAt(
+ TextView textView = (TextView) mContentView.getChildAt(
totalNbSuggestions);
textView.setText(suggestions[suggestionIndex]);
SuggestionInfo suggestionInfo = (SuggestionInfo) textView.getTag();
@@ -8889,7 +9136,7 @@
if (totalNbSuggestions == 0) {
// TODO Replace by final text, use a dedicated layout, add a fade out timer...
- TextView textView = (TextView) mSuggestionsContainer.getChildAt(0);
+ TextView textView = (TextView) mContentView.getChildAt(0);
textView.setText("No suggestions available");
SuggestionInfo suggestionInfo = (SuggestionInfo) textView.getTag();
suggestionInfo.spanStart = NO_SUGGESTIONS;
@@ -8900,26 +9147,17 @@
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
for (int i = 0; i < totalNbSuggestions; i++) {
- final TextView textView = (TextView) mSuggestionsContainer.getChildAt(i);
+ final TextView textView = (TextView) mContentView.getChildAt(i);
highlightTextDifferences(textView, spanUnionStart, spanUnionEnd);
}
}
for (int i = 0; i < totalNbSuggestions; i++) {
- mSuggestionsContainer.getChildAt(i).setVisibility(VISIBLE);
+ mContentView.getChildAt(i).setVisibility(VISIBLE);
}
for (int i = totalNbSuggestions; i < MAX_NUMBER_SUGGESTIONS; i++) {
- mSuggestionsContainer.getChildAt(i).setVisibility(GONE);
+ mContentView.getChildAt(i).setVisibility(GONE);
}
-
- final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
- final int screenWidth = displayMetrics.widthPixels;
- final int screenHeight = displayMetrics.heightPixels;
- mSuggestionsContainer.measure(
- View.MeasureSpec.makeMeasureSpec(screenWidth, View.MeasureSpec.AT_MOST),
- View.MeasureSpec.makeMeasureSpec(screenHeight, View.MeasureSpec.AT_MOST));
-
- positionAtCursor();
}
private long[] getWordLimits(CharSequence text) {
@@ -9071,17 +9309,6 @@
textView.setText(ssb);
}
- public void hide() {
- if ((mText instanceof Editable) && mSuggestionRangeSpan != null) {
- ((Editable) mText).removeSpan(mSuggestionRangeSpan);
- }
- mPopupWindow.dismiss();
- }
-
- public boolean isShowing() {
- return mPopupWindow.isShowing();
- }
-
@Override
public void onClick(View view) {
if (view instanceof TextView) {
@@ -9141,44 +9368,6 @@
}
hide();
}
-
- void positionAtCursor() {
- View contentView = mPopupWindow.getContentView();
- int width = contentView.getMeasuredWidth();
- int height = contentView.getMeasuredHeight();
- final int offset = TextView.this.getSelectionStart();
- final int line = mLayout.getLineForOffset(offset);
- final int lineBottom = mLayout.getLineBottom(line);
- float primaryHorizontal = mLayout.getPrimaryHorizontal(offset);
-
- final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (primaryHorizontal - width / 2.0f);
- bounds.top = lineBottom;
-
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
-
- convertFromViewportToContentCoordinates(bounds);
-
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
- coords[0] += bounds.left;
- coords[1] += bounds.top;
-
- final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics();
- final int screenHeight = displayMetrics.heightPixels;
-
- // Vertical clipping
- if (coords[1] + height > screenHeight) {
- coords[1] = screenHeight - height;
- }
-
- // Horizontal clipping
- coords[0] = Math.min(displayMetrics.widthPixels - width, coords[0]);
- coords[0] = Math.max(0, coords[0]);
-
- mPopupWindow.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
- }
}
void showSuggestions() {
@@ -9359,7 +9548,7 @@
boolean allowText = getContext().getResources().getBoolean(
com.android.internal.R.bool.config_allowActionMenuItemTextWithIcon);
- mode.setTitle(allowText ?
+ mode.setTitle(allowText ?
mContext.getString(com.android.internal.R.string.textSelectionCABTitle) : null);
mode.setSubtitle(null);
@@ -9452,29 +9641,23 @@
}
}
- private class ActionPopupWindow implements OnClickListener {
- private static final int TEXT_EDIT_ACTION_POPUP_TEXT =
+ private class ActionPopupWindow extends PinnedPopupWindow implements OnClickListener {
+ private static final int POPUP_TEXT_LAYOUT =
com.android.internal.R.layout.text_edit_action_popup_text;
- private final PopupWindow mPopupWindow;
private TextView mPasteTextView;
private TextView mReplaceTextView;
- private LinearLayout mContentView;
// Whether or not the Paste action should be available when the action popup is displayed
private boolean mWithPaste;
- public ActionPopupWindow() {
+ @Override
+ protected void createPopupWindow() {
mPopupWindow = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
mPopupWindow.setClippingEnabled(true);
- mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL);
+ }
- mPopupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
- mPopupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
-
- mContentView = new LinearLayout(TextView.this.getContext());
- LayoutParams wrapContent = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- mContentView.setLayoutParams(wrapContent);
+ @Override
+ protected void initContentView() {
mContentView.setOrientation(LinearLayout.HORIZONTAL);
mContentView.setBackgroundResource(
com.android.internal.R.drawable.text_edit_side_paste_window);
@@ -9482,36 +9665,26 @@
LayoutInflater inflater = (LayoutInflater)TextView.this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mPasteTextView = (TextView) inflater.inflate(TEXT_EDIT_ACTION_POPUP_TEXT, null);
+ LayoutParams wrapContent = new LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+ mPasteTextView = (TextView) inflater.inflate(POPUP_TEXT_LAYOUT, null);
mPasteTextView.setLayoutParams(wrapContent);
mContentView.addView(mPasteTextView);
mPasteTextView.setText(com.android.internal.R.string.paste);
mPasteTextView.setOnClickListener(this);
- mReplaceTextView = (TextView) inflater.inflate(TEXT_EDIT_ACTION_POPUP_TEXT, null);
+ mReplaceTextView = (TextView) inflater.inflate(POPUP_TEXT_LAYOUT, null);
mReplaceTextView.setLayoutParams(wrapContent);
mContentView.addView(mReplaceTextView);
mReplaceTextView.setText(com.android.internal.R.string.replace);
mReplaceTextView.setOnClickListener(this);
-
- mPopupWindow.setContentView(mContentView);
}
+ @Override
public void show() {
mPasteTextView.setVisibility(mWithPaste && canPaste() ? View.VISIBLE : View.GONE);
-
- final int size = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- mContentView.measure(size, size);
-
- positionAtCursor();
- }
-
- public void hide() {
- mPopupWindow.dismiss();
- }
-
- public boolean isShowing() {
- return mPopupWindow.isShowing();
+ super.show();
}
@Override
@@ -9524,48 +9697,30 @@
}
}
- void positionAtCursor() {
- int width = mContentView.getMeasuredWidth();
- int height = mContentView.getMeasuredHeight();
- final int selectionStart = TextView.this.getSelectionStart();
- final int selectionEnd = TextView.this.getSelectionEnd();
- final int offset = (selectionStart + selectionEnd) / 2;
- final int line = mLayout.getLineForOffset(offset);
- final int lineTop = mLayout.getLineTop(line);
- float primaryHorizontal = mLayout.getPrimaryHorizontal(offset);
+ @Override
+ protected int getTextOffset() {
+ return (getSelectionStart() + getSelectionEnd()) / 2;
+ }
- final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (primaryHorizontal - width / 2.0f);
- bounds.top = lineTop - height;
+ @Override
+ protected int getVerticalLocalPosition(int line) {
+ return mLayout.getLineTop(line) - mContentView.getMeasuredHeight();
+ }
- bounds.right = bounds.left + width;
- bounds.bottom = bounds.top + height;
-
- convertFromViewportToContentCoordinates(bounds);
-
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
- coords[0] += bounds.left;
- coords[1] += bounds.top;
-
- // Vertical clipping, move under edited line and to the side of insertion cursor
- if (coords[1] < 0) {
- coords[1] += height;
- final int lineBottom = mLayout.getLineBottom(line);
- final int lineHeight = lineBottom - lineTop;
- coords[1] += lineHeight;
+ @Override
+ protected int clipVertically(int positionY) {
+ if (positionY < 0) {
+ final int offset = getTextOffset();
+ final int line = mLayout.getLineForOffset(offset);
+ positionY += mLayout.getLineBottom(line) - mLayout.getLineTop(line);
+ positionY += mContentView.getMeasuredHeight();
// Assumes insertion and selection handles share the same height
final Drawable handle = mContext.getResources().getDrawable(mTextSelectHandleRes);
- coords[1] += handle.getIntrinsicHeight();
+ positionY += handle.getIntrinsicHeight();
}
- // Horizontal clipping
- coords[0] = Math.max(0, coords[0]);
- final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
- coords[0] = Math.min(screenWidth - width, coords[0]);
-
- mPopupWindow.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
+ return positionY;
}
public void setShowWithPaste(boolean withPaste) {
@@ -9573,7 +9728,7 @@
}
}
- private abstract class HandleView extends View implements ViewTreeObserver.OnPreDrawListener {
+ private abstract class HandleView extends View implements TextViewPositionListener {
protected Drawable mDrawable;
private final PopupWindow mContainer;
// Position with respect to the parent TextView
@@ -9581,21 +9736,19 @@
private boolean mIsDragging;
// Offset from touch position to mPosition
private float mTouchToWindowOffsetX, mTouchToWindowOffsetY;
- protected float mHotspotX;
+ protected int mHotspotX;
// Offsets the hotspot point up, so that cursor is not hidden by the finger when moving up
private float mTouchOffsetY;
// Where the touch position should be on the handle to ensure a maximum cursor visibility
private float mIdealVerticalOffset;
// Parent's (TextView) previous position in window
private int mLastParentX, mLastParentY;
- // PopupWindow container absolute position with respect to the enclosing window
- private int mContainerPositionX, mContainerPositionY;
- // Visible or not (scrolled off screen), whether or not this handle should be visible
- private boolean mIsActive = false;
- // Used to detect that setFrame was called
- private boolean mNeedsUpdate = true;
// Transient action popup window for Paste and Replace actions
protected ActionPopupWindow mActionPopupWindow;
+ // Previous text character offset
+ private int mPreviousOffset = -1;
+ // Previous text character offset
+ private boolean mPositionHasChanged = true;
// Used to delay the appearance of the action popup window
private Runnable mActionPopupShower;
@@ -9615,15 +9768,6 @@
mIdealVerticalOffset = 0.7f * handleHeight;
}
- @Override
- protected boolean setFrame(int left, int top, int right, int bottom) {
- boolean changed = super.setFrame(left, top, right, bottom);
- // onPreDraw is called for PhoneWindow before the layout of this view is
- // performed. Make sure to update position, even if container didn't move.
- if (changed) mNeedsUpdate = true;
- return changed;
- }
-
protected abstract void initDrawable();
// Touch-up filter: number of previous positions remembered
@@ -9641,12 +9785,6 @@
}
private void addPositionToTouchUpFilter(int offset) {
- if (mNumberPreviousOffsets > 0 &&
- mPreviousOffsets[mPreviousOffsetIndex] == offset) {
- // Make sure only actual changes of position are recorded.
- return;
- }
-
mPreviousOffsetIndex = (mPreviousOffsetIndex + 1) % HISTORY_SIZE;
mPreviousOffsets[mPreviousOffsetIndex] = offset;
mPreviousOffsetsTimes[mPreviousOffsetIndex] = SystemClock.uptimeMillis();
@@ -9665,28 +9803,28 @@
if (i > 0 && i < iMax &&
(now - mPreviousOffsetsTimes[index]) > TOUCH_UP_FILTER_DELAY_BEFORE) {
- updateOffset(mPreviousOffsets[index]);
+ positionAtCursorOffset(mPreviousOffsets[index]);
}
}
+ public boolean offsetHasBeenChanged() {
+ return mNumberPreviousOffsets > 1;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
}
public void show() {
- if (isShowing()) {
- mContainer.update(mContainerPositionX, mContainerPositionY, -1, -1);
- } else {
- mContainer.showAtLocation(TextView.this, 0,
- mContainerPositionX, mContainerPositionY);
+ if (isShowing()) return;
- if (!mIsActive) {
- ViewTreeObserver vto = TextView.this.getViewTreeObserver();
- vto.addOnPreDrawListener(this);
- mIsActive = true;
- }
- }
+ getPositionListener().addSubscriber(this, true);
+
+ // Make sure the offset is always considered new, even when focusing at same position
+ mPreviousOffset = -1;
+ positionAtCursorOffset(getCurrentCursorOffset());
+
hideActionPopupWindow();
}
@@ -9699,9 +9837,7 @@
public void hide() {
dismiss();
- ViewTreeObserver vto = TextView.this.getViewTreeObserver();
- vto.removeOnPreDrawListener(this);
- mIsActive = false;
+ TextView.this.getPositionListener().removeSubscriber(this);
}
void showActionPopupWindow(int delay, boolean withPaste) {
@@ -9734,7 +9870,7 @@
return mContainer.isShowing();
}
- private boolean isPositionVisible() {
+ private boolean isVisible() {
// Always show a dragging handle.
if (mIsDragging) {
return true;
@@ -9744,103 +9880,71 @@
return false;
}
- final int extendedPaddingTop = getExtendedPaddingTop();
- final int extendedPaddingBottom = getExtendedPaddingBottom();
- final int compoundPaddingLeft = getCompoundPaddingLeft();
- final int compoundPaddingRight = getCompoundPaddingRight();
-
- final TextView textView = TextView.this;
-
- if (mTempRect == null) mTempRect = new Rect();
- final Rect clip = mTempRect;
- clip.left = compoundPaddingLeft;
- clip.top = extendedPaddingTop;
- clip.right = textView.getWidth() - compoundPaddingRight;
- clip.bottom = textView.getHeight() - extendedPaddingBottom;
-
- final ViewParent parent = textView.getParent();
- if (parent == null || !parent.getChildVisibleRect(textView, clip, null)) {
- return false;
- }
-
- final int[] coords = mTempCoords;
- textView.getLocationInWindow(coords);
- final int posX = coords[0] + mPositionX + (int) mHotspotX;
- final int posY = coords[1] + mPositionY;
-
- // Offset by 1 to take into account 0.5 and int rounding around getPrimaryHorizontal.
- return posX >= clip.left - 1 && posX <= clip.right + 1 &&
- posY >= clip.top && posY <= clip.bottom;
+ return getPositionListener().isVisible(mPositionX + mHotspotX, mPositionY);
}
public abstract int getCurrentCursorOffset();
- public abstract void updateOffset(int offset);
+ public abstract void updateSelection(int offset);
public abstract void updatePosition(float x, float y);
protected void positionAtCursorOffset(int offset) {
- // A HandleView relies on the layout, which may be nulled by external methods.
+ // A HandleView relies on the layout, which may be nulled by external methods
if (mLayout == null) {
// Will update controllers' state, hiding them and stopping selection mode if needed
prepareCursorControllers();
return;
}
- addPositionToTouchUpFilter(offset);
- final int line = mLayout.getLineForOffset(offset);
- final int lineBottom = mLayout.getLineBottom(line);
+ if (offset != mPreviousOffset) {
+ updateSelection(offset);
+ addPositionToTouchUpFilter(offset);
+ final int line = mLayout.getLineForOffset(offset);
- mPositionX = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX);
- mPositionY = lineBottom;
+ mPositionX = (int) (mLayout.getPrimaryHorizontal(offset) - 0.5f - mHotspotX);
+ mPositionY = mLayout.getLineBottom(line);
- // Take TextView's padding into account.
- mPositionX += viewportToContentHorizontalOffset();
- mPositionY += viewportToContentVerticalOffset();
+ // Take TextView's padding into account.
+ mPositionX += viewportToContentHorizontalOffset();
+ mPositionY += viewportToContentVerticalOffset();
+
+ mPreviousOffset = offset;
+ mPositionHasChanged = true;
+ }
}
- private void checkForContainerPositionChange() {
- positionAtCursorOffset(getCurrentCursorOffset());
-
- final int previousContainerPositionX = mContainerPositionX;
- final int previousContainerPositionY = mContainerPositionY;
-
- TextView.this.getLocationInWindow(mTempCoords);
- mContainerPositionX = mTempCoords[0] + mPositionX;
- mContainerPositionY = mTempCoords[1] + mPositionY;
-
- mNeedsUpdate |= previousContainerPositionX != mContainerPositionX;
- mNeedsUpdate |= previousContainerPositionY != mContainerPositionY;
- }
-
- public boolean onPreDraw() {
- checkForContainerPositionChange();
- if (mNeedsUpdate) {
+ public void updatePosition(int parentPositionX, int parentPositionY, boolean modified) {
+ if (modified || mPositionHasChanged) {
if (mIsDragging) {
- if (mTempCoords[0] != mLastParentX || mTempCoords[1] != mLastParentY) {
- mTouchToWindowOffsetX += mTempCoords[0] - mLastParentX;
- mTouchToWindowOffsetY += mTempCoords[1] - mLastParentY;
- mLastParentX = mTempCoords[0];
- mLastParentY = mTempCoords[1];
+ // Update touchToWindow offset in case of parent scrolling while dragging
+ if (parentPositionX != mLastParentX || parentPositionY != mLastParentY) {
+ mTouchToWindowOffsetX += parentPositionX - mLastParentX;
+ mTouchToWindowOffsetY += parentPositionY - mLastParentY;
+ mLastParentX = parentPositionX;
+ mLastParentY = parentPositionY;
}
onHandleMoved();
}
- if (isPositionVisible()) {
- mContainer.update(mContainerPositionX, mContainerPositionY, -1, -1);
-
- if (mIsActive && !isShowing()) {
- show();
+ if (isVisible()) {
+ final int positionX = parentPositionX + mPositionX;
+ final int positionY = parentPositionY + mPositionY;
+ if (isShowing()) {
+ mContainer.update(positionX, positionY, -1, -1);
+ } else {
+ mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY,
+ positionX, positionY);
}
} else {
if (isShowing()) {
dismiss();
}
}
- mNeedsUpdate = false;
+
+ mPositionHasChanged = false;
}
- return true;
}
@Override
@@ -9857,10 +9961,9 @@
mTouchToWindowOffsetX = ev.getRawX() - mPositionX;
mTouchToWindowOffsetY = ev.getRawY() - mPositionY;
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
- mLastParentX = coords[0];
- mLastParentY = coords[1];
+ final PositionListener positionListener = getPositionListener();
+ mLastParentX = positionListener.getPositionX();
+ mLastParentY = positionListener.getPositionY();
mIsDragging = true;
break;
}
@@ -9963,7 +10066,7 @@
mTextSelectHandleRes);
}
mDrawable = mSelectHandleCenter;
- mHotspotX = mDrawable.getIntrinsicWidth() / 2.0f;
+ mHotspotX = mDrawable.getIntrinsicWidth() / 2;
}
@Override
@@ -9977,15 +10080,17 @@
break;
case MotionEvent.ACTION_UP:
- final float deltaX = mDownPositionX - ev.getRawX();
- final float deltaY = mDownPositionY - ev.getRawY();
- final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
- if (distanceSquared < mSquaredTouchSlopDistance) {
- if (mActionPopupWindow != null && mActionPopupWindow.isShowing()) {
- // Tapping on the handle dismisses the displayed action popup
- mActionPopupWindow.hide();
- } else {
- show(0);
+ if (!offsetHasBeenChanged()) {
+ final float deltaX = mDownPositionX - ev.getRawX();
+ final float deltaY = mDownPositionY - ev.getRawY();
+ final float distanceSquared = deltaX * deltaX + deltaY * deltaY;
+ if (distanceSquared < mSquaredTouchSlopDistance) {
+ if (mActionPopupWindow != null && mActionPopupWindow.isShowing()) {
+ // Tapping on the handle dismisses the displayed action popup
+ mActionPopupWindow.hide();
+ } else {
+ show(0);
+ }
}
}
hideAfterDelay();
@@ -10008,13 +10113,13 @@
}
@Override
- public void updateOffset(int offset) {
+ public void updateSelection(int offset) {
Selection.setSelection((Spannable) mText, offset);
}
@Override
public void updatePosition(float x, float y) {
- updateOffset(getOffsetForPosition(x, y));
+ positionAtCursorOffset(getOffsetForPosition(x, y));
}
@Override
@@ -10038,7 +10143,7 @@
mTextSelectHandleLeftRes);
}
mDrawable = mSelectHandleLeft;
- mHotspotX = mDrawable.getIntrinsicWidth() * 3.0f / 4.0f;
+ mHotspotX = (mDrawable.getIntrinsicWidth() * 3) / 4;
}
@Override
@@ -10047,7 +10152,7 @@
}
@Override
- public void updateOffset(int offset) {
+ public void updateSelection(int offset) {
Selection.setSelection((Spannable) mText, offset, getSelectionEnd());
}
@@ -10063,7 +10168,7 @@
// Handles can not cross and selection is at least one character
if (offset >= selectionEnd) offset = selectionEnd - 1;
- Selection.setSelection((Spannable) mText, offset, selectionEnd);
+ positionAtCursorOffset(offset);
}
public ActionPopupWindow getActionPopupWindow() {
@@ -10079,7 +10184,7 @@
mTextSelectHandleRightRes);
}
mDrawable = mSelectHandleRight;
- mHotspotX = mDrawable.getIntrinsicWidth() / 4.0f;
+ mHotspotX = mDrawable.getIntrinsicWidth() / 4;
}
@Override
@@ -10088,7 +10193,7 @@
}
@Override
- public void updateOffset(int offset) {
+ public void updateSelection(int offset) {
Selection.setSelection((Spannable) mText, getSelectionStart(), offset);
}
@@ -10104,7 +10209,7 @@
// Handles can not cross and selection is at least one character
if (offset <= selectionStart) offset = selectionStart + 1;
- Selection.setSelection((Spannable) mText, selectionStart, offset);
+ positionAtCursorOffset(offset);
}
public void setActionPopupWindow(ActionPopupWindow actionPopupWindow) {
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 1531946..6d65782 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.internal.content;
import android.os.Build;
@@ -17,6 +33,12 @@
private static native long nativeSumNativeBinaries(String file, String cpuAbi, String cpuAbi2);
+ /**
+ * Sums the size of native binaries in an APK.
+ *
+ * @param apkFile APK file to scan for native libraries
+ * @return size of all native binary files in bytes
+ */
public static long sumNativeBinariesLI(File apkFile) {
final String cpuAbi = Build.CPU_ABI;
final String cpuAbi2 = Build.CPU_ABI2;
@@ -26,6 +48,14 @@
private native static int nativeCopyNativeBinaries(String filePath, String sharedLibraryPath,
String cpuAbi, String cpuAbi2);
+ /**
+ * Copies native binaries to a shared library directory.
+ *
+ * @param apkFile APK file to scan for native libraries
+ * @param sharedLibraryDir directory for libraries to be copied to
+ * @return {@link PackageManager#INSTALL_SUCCEEDED} if successful or another
+ * error code from that class if not
+ */
public static int copyNativeBinariesIfNeededLI(File apkFile, File sharedLibraryDir) {
final String cpuAbi = Build.CPU_ABI;
final String cpuAbi2 = Build.CPU_ABI2;
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index ec64552..266728b 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -39,6 +39,8 @@
public static final int RECOMMEND_FAILED_INVALID_LOCATION = -3;
public static final int RECOMMEND_FAILED_ALREADY_EXISTS = -4;
public static final int RECOMMEND_MEDIA_UNAVAILABLE = -5;
+ public static final int RECOMMEND_FAILED_INVALID_URI = -6;
+
private static final boolean localLOGV = true;
private static final String TAG = "PackageHelper";
// App installation location settings values
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 7839a08..5e70e4c 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -150,6 +150,11 @@
private CopyOnWriteArrayList<WeakReference<MenuPresenter>> mPresenters =
new CopyOnWriteArrayList<WeakReference<MenuPresenter>>();
+
+ /**
+ * Currently expanded menu item; must be collapsed when we clear.
+ */
+ private MenuItemImpl mExpandedItem;
/**
* Called by menu to notify of close and selection changes.
@@ -512,6 +517,9 @@
}
public void clear() {
+ if (mExpandedItem != null) {
+ collapseItemActionView(mExpandedItem);
+ }
mItems.clear();
onItemsChanged(true);
@@ -1223,11 +1231,14 @@
}
startDispatchingItemsChanged();
+ if (expanded) {
+ mExpandedItem = item;
+ }
return expanded;
}
public boolean collapseItemActionView(MenuItemImpl item) {
- if (mPresenters.isEmpty()) return false;
+ if (mPresenters.isEmpty() || mExpandedItem != item) return false;
boolean collapsed = false;
@@ -1242,6 +1253,9 @@
}
startDispatchingItemsChanged();
+ if (collapsed) {
+ mExpandedItem = null;
+ }
return collapsed;
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 446c842..4878b0f 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -1265,9 +1265,8 @@
@Override
public void initForMenu(Context context, MenuBuilder menu) {
// Clear the expanded action view when menus change.
- mExpandedActionView = null;
- if (mCurrentExpandedItem != null) {
- mCurrentExpandedItem.collapseActionView();
+ if (mMenu != null && mCurrentExpandedItem != null) {
+ mMenu.collapseItemActionView(mCurrentExpandedItem);
}
mMenu = menu;
}
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 2de0932..ffcd1a0 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -233,6 +233,12 @@
return surfaceTexture->getTimestamp();
}
+static void SurfaceTexture_release(JNIEnv* env, jobject thiz)
+{
+ sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
+ surfaceTexture->abandon();
+}
+
// ----------------------------------------------------------------------------
static JNINativeMethod gSurfaceTextureMethods[] = {
@@ -243,6 +249,7 @@
{"nativeUpdateTexImage", "()V", (void*)SurfaceTexture_updateTexImage },
{"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
{"nativeGetTimestamp", "()J", (void*)SurfaceTexture_getTimestamp },
+ {"nativeRelease", "()V", (void*)SurfaceTexture_release },
};
int register_android_graphics_SurfaceTexture(JNIEnv* env)
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index 830f70e..5118351 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -51,15 +51,17 @@
namespace android {
-typedef void (*iterFunc)(JNIEnv*, void*, ZipFileRO*, ZipEntryRO, const char*);
-
// These match PackageManager.java install codes
typedef enum {
- INSTALL_SUCCEEDED = 0,
+ INSTALL_SUCCEEDED = 1,
INSTALL_FAILED_INVALID_APK = -2,
INSTALL_FAILED_INSUFFICIENT_STORAGE = -4,
+ INSTALL_FAILED_CONTAINER_ERROR = -18,
+ INSTALL_FAILED_INTERNAL_ERROR = -110,
} install_status_t;
+typedef install_status_t (*iterFunc)(JNIEnv*, void*, ZipFileRO*, ZipEntryRO, const char*);
+
// Equivalent to isFilenameSafe
static bool
isFilenameSafe(const char* filename)
@@ -140,17 +142,19 @@
return false;
}
-static void
+static install_status_t
sumFiles(JNIEnv* env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
{
size_t* total = (size_t*) arg;
size_t uncompLen;
if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, NULL, NULL)) {
- return;
+ return INSTALL_FAILED_INVALID_APK;
}
*total += uncompLen;
+
+ return INSTALL_SUCCEEDED;
}
/*
@@ -158,7 +162,7 @@
*
* This function assumes the library and path names passed in are considered safe.
*/
-static void
+static install_status_t
copyFileIfChanged(JNIEnv *env, void* arg, ZipFileRO* zipFile, ZipEntryRO zipEntry, const char* fileName)
{
jstring* javaNativeLibPath = (jstring*) arg;
@@ -170,7 +174,8 @@
time_t modTime;
if (!zipFile->getEntryInfo(zipEntry, NULL, &uncompLen, NULL, NULL, &when, &crc)) {
- return;
+ LOGD("Couldn't read zip entry info\n");
+ return INSTALL_FAILED_INVALID_APK;
} else {
struct tm t;
ZipFileRO::zipTimeToTimespec(when, &t);
@@ -182,50 +187,50 @@
char localFileName[nativeLibPath.size() + fileNameLen + 2];
if (strlcpy(localFileName, nativeLibPath.c_str(), sizeof(localFileName)) != nativeLibPath.size()) {
- LOGD("Couldn't allocate local file name for library: %s", strerror(errno));
- return;
+ LOGD("Couldn't allocate local file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
*(localFileName + nativeLibPath.size()) = '/';
if (strlcpy(localFileName + nativeLibPath.size() + 1, fileName, sizeof(localFileName)
- nativeLibPath.size() - 1) != fileNameLen) {
- LOGD("Couldn't allocate local file name for library: %s", strerror(errno));
- return;
+ LOGD("Couldn't allocate local file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
// Only copy out the native file if it's different.
struct stat st;
if (!isFileDifferent(localFileName, uncompLen, modTime, crc, &st)) {
- return;
+ return INSTALL_SUCCEEDED;
}
char localTmpFileName[nativeLibPath.size() + TMP_FILE_PATTERN_LEN + 2];
if (strlcpy(localTmpFileName, nativeLibPath.c_str(), sizeof(localTmpFileName))
!= nativeLibPath.size()) {
- LOGD("Couldn't allocate local file name for library: %s", strerror(errno));
- return;
+ LOGD("Couldn't allocate local file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
*(localFileName + nativeLibPath.size()) = '/';
if (strlcpy(localTmpFileName + nativeLibPath.size(), TMP_FILE_PATTERN,
TMP_FILE_PATTERN_LEN - nativeLibPath.size()) != TMP_FILE_PATTERN_LEN) {
- LOGI("Couldn't allocate temporary file name for library: %s", strerror(errno));
- return;
+ LOGI("Couldn't allocate temporary file name for library");
+ return INSTALL_FAILED_INTERNAL_ERROR;
}
int fd = mkstemp(localTmpFileName);
if (fd < 0) {
LOGI("Couldn't open temporary file name: %s: %s\n", localTmpFileName, strerror(errno));
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
if (!zipFile->uncompressEntry(zipEntry, fd)) {
- LOGI("Failed uncompressing %s to %s: %s", fileName, localTmpFileName, strerror(errno));
+ LOGI("Failed uncompressing %s to %s\n", fileName, localTmpFileName);
close(fd);
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
close(fd);
@@ -238,7 +243,7 @@
if (utimes(localTmpFileName, times) < 0) {
LOGI("Couldn't change modification time on %s: %s\n", localTmpFileName, strerror(errno));
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
// Set the mode to 755
@@ -246,17 +251,19 @@
if (chmod(localTmpFileName, mode) < 0) {
LOGI("Couldn't change permissions on %s: %s\n", localTmpFileName, strerror(errno));
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
// Finally, rename it to the final name.
if (rename(localTmpFileName, localFileName) < 0) {
LOGI("Couldn't rename %s to %s: %s\n", localTmpFileName, localFileName, strerror(errno));
unlink(localTmpFileName);
- return;
+ return INSTALL_FAILED_CONTAINER_ERROR;
}
LOGV("Successfully moved %s to %s\n", localTmpFileName, localFileName);
+
+ return INSTALL_SUCCEEDED;
}
static install_status_t
@@ -301,10 +308,7 @@
}
const char* lastSlash = strrchr(fileName, '/');
- if (lastSlash == NULL) {
- LOG_ASSERT("last slash was null somehow for %s\n", fileName);
- continue;
- }
+ LOG_ASSERT(lastSlash != NULL, "last slash was null somehow for %s\n", fileName);
// Check to make sure the CPU ABI of this file is one we support.
const char* cpuAbiOffset = fileName + APK_LIB_LEN;
@@ -325,12 +329,17 @@
}
// If this is a .so file, check to see if we need to copy it.
- if (!strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
- && !strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)
- && isFilenameSafe(lastSlash + 1)) {
- callFunc(env, callArg, &zipFile, entry, lastSlash + 1);
- } else if (!strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
- callFunc(env, callArg, &zipFile, entry, lastSlash + 1);
+ if ((!strncmp(fileName + fileNameLen - LIB_SUFFIX_LEN, LIB_SUFFIX, LIB_SUFFIX_LEN)
+ && !strncmp(lastSlash, LIB_PREFIX, LIB_PREFIX_LEN)
+ && isFilenameSafe(lastSlash + 1))
+ || !strncmp(lastSlash + 1, GDBSERVER, GDBSERVER_LEN)) {
+
+ install_status_t ret = callFunc(env, callArg, &zipFile, entry, lastSlash + 1);
+
+ if (ret != INSTALL_SUCCEEDED) {
+ LOGV("Failure for entry %s", lastSlash + 1);
+ return ret;
+ }
}
}
@@ -341,7 +350,7 @@
com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
jstring javaFilePath, jstring javaNativeLibPath, jstring javaCpuAbi, jstring javaCpuAbi2)
{
- return iterateOverNativeFiles(env, javaFilePath, javaCpuAbi, javaCpuAbi2,
+ return (jint) iterateOverNativeFiles(env, javaFilePath, javaCpuAbi, javaCpuAbi2,
copyFileIfChanged, &javaNativeLibPath);
}
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
index 9e3e0bb..871a131 100644
--- a/core/res/res/values-large/themes.xml
+++ b/core/res/res/values-large/themes.xml
@@ -16,6 +16,21 @@
** limitations under the License.
*/
-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
<resources>
<style name="Theme.Holo.DialogWhenLarge"
parent="@android:style/Theme.Holo.Dialog.MinWidth">
diff --git a/core/res/res/values-large/themes_device_defaults.xml b/core/res/res/values-large/themes_device_defaults.xml
new file mode 100644
index 0000000..52fff5c
--- /dev/null
+++ b/core/res/res/values-large/themes_device_defaults.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+This file contains the themes that are the Device Defaults.
+If you want to edit themes to skin your device, do it here.
+We recommend that you do not edit themes.xml and instead edit
+this file.
+
+Editing this file instead of themes.xml will greatly simplify
+merges for future platform versions and CTS compliance will be
+easier.
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <style name="Theme.DeviceDefault.DialogWhenLarge"
+ parent="@android:style/Theme.DeviceDefault.Dialog.MinWidth">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar"
+ parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.MinWidth">
+ <item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge"
+ parent="@android:style/Theme.DeviceDefault.Light.Dialog.MinWidth">
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"
+ parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth">
+ </style>
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2dfe453..f85dd85 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1803,6 +1803,183 @@
<public type="style" name="Widget.Holo.Light.ActionBar.TabText.Inverse" />
<public type="style" name="Widget.Holo.Light.ActionMode.Inverse" />
+ <public type="style" name="Theme.DeviceDefault" />
+ <public type="style" name="Theme.DeviceDefault.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.NoActionBar.Fullscreen" />
+ <public type="style" name="Theme.DeviceDefault.Light" />
+ <public type="style" name="Theme.DeviceDefault.Light.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" />
+ <public type="style" name="Theme.DeviceDefault.Dialog" />
+ <public type="style" name="Theme.DeviceDefault.Dialog.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.Dialog.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" />
+ <public type="style" name="Theme.DeviceDefault.DialogWhenLarge" />
+ <public type="style" name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Light.DialogWhenLarge" />
+ <public type="style" name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" />
+ <public type="style" name="Theme.DeviceDefault.Panel" />
+ <public type="style" name="Theme.DeviceDefault.Light.Panel" />
+ <public type="style" name="Theme.DeviceDefault.Wallpaper" />
+ <public type="style" name="Theme.DeviceDefault.Wallpaper.NoTitleBar" />
+ <public type="style" name="Theme.DeviceDefault.InputMethod" />
+ <public type="style" name="Theme.DeviceDefault.Light.DarkActionBar" />
+
+ <public type="style" name="Widget.DeviceDefault" />
+ <public type="style" name="Widget.DeviceDefault.Button" />
+ <public type="style" name="Widget.DeviceDefault.Button.Small" />
+ <public type="style" name="Widget.DeviceDefault.Button.Inset" />
+ <public type="style" name="Widget.DeviceDefault.Button.Toggle" />
+ <public type="style" name="Widget.DeviceDefault.Button.Borderless.Small" />
+ <public type="style" name="Widget.DeviceDefault.TextView" />
+ <public type="style" name="Widget.DeviceDefault.AutoCompleteTextView" />
+ <public type="style" name="Widget.DeviceDefault.CompoundButton.CheckBox" />
+ <public type="style" name="Widget.DeviceDefault.ListView.DropDown" />
+ <public type="style" name="Widget.DeviceDefault.EditText" />
+ <public type="style" name="Widget.DeviceDefault.ExpandableListView" />
+ <public type="style" name="Widget.DeviceDefault.GridView" />
+ <public type="style" name="Widget.DeviceDefault.ImageButton" />
+ <public type="style" name="Widget.DeviceDefault.ListView" />
+ <public type="style" name="Widget.DeviceDefault.PopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Horizontal" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Small.Title" />
+ <public type="style" name="Widget.DeviceDefault.ProgressBar.Large" />
+ <public type="style" name="Widget.DeviceDefault.SeekBar" />
+ <public type="style" name="Widget.DeviceDefault.RatingBar" />
+ <public type="style" name="Widget.DeviceDefault.RatingBar.Indicator" />
+ <public type="style" name="Widget.DeviceDefault.RatingBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.CompoundButton.RadioButton" />
+ <public type="style" name="Widget.DeviceDefault.ScrollView" />
+ <public type="style" name="Widget.DeviceDefault.HorizontalScrollView" />
+ <public type="style" name="Widget.DeviceDefault.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.CompoundButton.Star" />
+ <public type="style" name="Widget.DeviceDefault.TabWidget" />
+ <public type="style" name="Widget.DeviceDefault.WebTextView" />
+ <public type="style" name="Widget.DeviceDefault.WebView" />
+ <public type="style" name="Widget.DeviceDefault.DropDownItem" />
+ <public type="style" name="Widget.DeviceDefault.DropDownItem.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.TextView.SpinnerItem" />
+ <public type="style" name="Widget.DeviceDefault.ListPopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.PopupMenu" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton.Overflow" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton.TextButton" />
+ <public type="style" name="Widget.DeviceDefault.ActionMode" />
+ <public type="style" name="Widget.DeviceDefault.ActionButton.CloseMode" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar" />
+ <public type="style" name="Widget.DeviceDefault.Button.Borderless" />
+ <public type="style" name="Widget.DeviceDefault.Tab" />
+ <public type="style" name="Widget.DeviceDefault.CalendarView" />
+ <public type="style" name="Widget.DeviceDefault.DatePicker" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.TabView" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.TabText" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.TabBar" />
+ <public type="style" name="Widget.DeviceDefault.ActionBar.Solid" />
+ <public type="style" name="Widget.DeviceDefault.Light" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Inset" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Toggle" />
+ <public type="style" name="Widget.DeviceDefault.Light.Button.Borderless.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.TextView" />
+ <public type="style" name="Widget.DeviceDefault.Light.AutoCompleteTextView" />
+ <public type="style" name="Widget.DeviceDefault.Light.CompoundButton.CheckBox" />
+ <public type="style" name="Widget.DeviceDefault.Light.ListView.DropDown" />
+ <public type="style" name="Widget.DeviceDefault.Light.EditText" />
+ <public type="style" name="Widget.DeviceDefault.Light.ExpandableListView" />
+ <public type="style" name="Widget.DeviceDefault.Light.GridView" />
+ <public type="style" name="Widget.DeviceDefault.Light.ImageButton" />
+ <public type="style" name="Widget.DeviceDefault.Light.ListView" />
+ <public type="style" name="Widget.DeviceDefault.Light.PopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Horizontal" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Small.Title" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Large" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Small.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.SeekBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.RatingBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.RatingBar.Indicator" />
+ <public type="style" name="Widget.DeviceDefault.Light.RatingBar.Small" />
+ <public type="style" name="Widget.DeviceDefault.Light.CompoundButton.RadioButton" />
+ <public type="style" name="Widget.DeviceDefault.Light.ScrollView" />
+ <public type="style" name="Widget.DeviceDefault.Light.HorizontalScrollView" />
+ <public type="style" name="Widget.DeviceDefault.Light.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.Light.CompoundButton.Star" />
+ <public type="style" name="Widget.DeviceDefault.Light.TabWidget" />
+ <public type="style" name="Widget.DeviceDefault.Light.WebTextView" />
+ <public type="style" name="Widget.DeviceDefault.Light.WebView" />
+ <public type="style" name="Widget.DeviceDefault.Light.DropDownItem" />
+ <public type="style" name="Widget.DeviceDefault.Light.DropDownItem.Spinner" />
+ <public type="style" name="Widget.DeviceDefault.Light.TextView.SpinnerItem" />
+ <public type="style" name="Widget.DeviceDefault.Light.ListPopupWindow" />
+ <public type="style" name="Widget.DeviceDefault.Light.PopupMenu" />
+ <public type="style" name="Widget.DeviceDefault.Light.Tab" />
+ <public type="style" name="Widget.DeviceDefault.Light.CalendarView" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionButton" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionButton.Overflow" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionMode" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionButton.CloseMode" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabView" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabText" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabBar" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.Solid" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.Solid.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabBar.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabView.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionBar.TabText.Inverse" />
+ <public type="style" name="Widget.DeviceDefault.Light.ActionMode.Inverse" />
+
+ <public type="style" name="TextAppearance.DeviceDefault" />
+ <public type="style" name="TextAppearance.DeviceDefault.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Large" />
+ <public type="style" name="TextAppearance.DeviceDefault.Large.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Medium" />
+ <public type="style" name="TextAppearance.DeviceDefault.Medium.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Small" />
+ <public type="style" name="TextAppearance.DeviceDefault.Small.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.SearchResult.Title" />
+ <public type="style" name="TextAppearance.DeviceDefault.SearchResult.Subtitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.WindowTitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.DialogWindowTitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.Button" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.IconMenu.Item" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TabWidget" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TextView" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TextView.PopupMenu" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.DropDownHint" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.DropDownItem" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.TextView.SpinnerItem" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.EditText" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.PopupMenu" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Title.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" />
+ <public type="style" name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" />
+
+ <public type="style" name="DeviceDefault.ButtonBar" />
+ <public type="style" name="DeviceDefault.ButtonBar.AlertDialog" />
+ <public type="style" name="DeviceDefault.SegmentedButton" />
+ <public type="style" name="DeviceDefault.Light.ButtonBar" />
+ <public type="style" name="DeviceDefault.Light.ButtonBar.AlertDialog" />
+ <public type="style" name="DeviceDefault.Light.SegmentedButton" />
+
<public type="integer" name="status_bar_notification_info_maxnum" />
<public type="string" name="status_bar_notification_info_overflow" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 5aa47b7..21f1cef 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -14,6 +14,20 @@
limitations under the License.
-->
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see styles_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
<resources>
<!-- Global Theme Styles -->
<eat-comment />
@@ -95,19 +109,6 @@
<item name="windowExitAnimation">@anim/dialog_exit</item>
</style>
- <!-- Standard animations for hiding and showing the status bar. -->
- <style name="Animation.StatusBar">
- <item name="windowEnterAnimation">@anim/status_bar_enter</item>
- <item name="windowExitAnimation">@anim/status_bar_exit</item>
- </style>
-
- <!-- {@hide} -->
- <style name="Animation.StatusBar.IntruderAlert"
- parent="@android:style/Animation.StatusBar">
- <item name="android:windowEnterAnimation">@anim/priority_alert_enter</item>
- <item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
- </style>
-
<!-- Standard animations for a translucent window or activity. This
style is <em>not<em> used by default for the translucent theme
(since translucent activities are a special case that have no
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
new file mode 100644
index 0000000..7f1891e
--- /dev/null
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -0,0 +1,741 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+This file contains the themes that are the Device Defaults.
+If you want to edit styles to skin your device, do it here.
+We recommend that you do not edit styles.xml and instead edit
+this file.
+
+Editing this file instead of styles.xml will greatly simplify
+merges for future platform versions and CTS compliance will be
+easier.
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <!-- Widget Styles -->
+ <style name="Widget.DeviceDefault" parent="Widget.Holo" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button" parent="Widget.Holo.Button" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Small" parent="Widget.Holo.Button.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Inset" parent="Widget.Holo.Button.Inset" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Toggle" parent="Widget.Holo.Button.Toggle" >
+
+ </style>
+ <style name="Widget.DeviceDefault.TextView" parent="Widget.Holo.TextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.AutoCompleteTextView" parent="Widget.Holo.AutoCompleteTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.CheckBox" parent="Widget.Holo.CompoundButton.CheckBox" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ListView.DropDown" parent="Widget.Holo.ListView.DropDown" >
+
+ </style>
+ <style name="Widget.DeviceDefault.EditText" parent="Widget.Holo.EditText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ExpandableListView" parent="Widget.Holo.ExpandableListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.GridView" parent="Widget.Holo.GridView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageButton" parent="Widget.Holo.ImageButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ListView" parent="Widget.Holo.ListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.PopupWindow" parent="Widget.Holo.PopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar" parent="Widget.Holo.ProgressBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Horizontal" parent="Widget.Holo.ProgressBar.Horizontal" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Small" parent="Widget.Holo.ProgressBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Small.Title" parent="Widget.Holo.ProgressBar.Small.Title" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Large" parent="Widget.Holo.ProgressBar.Large" >
+
+ </style>
+ <style name="Widget.DeviceDefault.SeekBar" parent="Widget.Holo.SeekBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.RatingBar" parent="Widget.Holo.RatingBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.RatingBar.Indicator" parent="Widget.Holo.RatingBar.Indicator" >
+
+ </style>
+ <style name="Widget.DeviceDefault.RatingBar.Small" parent="Widget.Holo.RatingBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.RadioButton" parent="Widget.Holo.CompoundButton.RadioButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ScrollView" parent="Widget.Holo.ScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.HorizontalScrollView" parent="Widget.Holo.HorizontalScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Spinner" parent="Widget.Holo.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.Star" parent="Widget.Holo.CompoundButton.Star" >
+
+ </style>
+ <style name="Widget.DeviceDefault.TabWidget" parent="Widget.Holo.TabWidget" >
+
+ </style>
+ <style name="Widget.DeviceDefault.WebTextView" parent="Widget.Holo.WebTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.WebView" parent="Widget.Holo.WebView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.DropDownItem" parent="Widget.Holo.DropDownItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.DropDownItem.Spinner" parent="Widget.Holo.DropDownItem.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.TextView.SpinnerItem" parent="Widget.Holo.TextView.SpinnerItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ListPopupWindow" parent="Widget.Holo.ListPopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.PopupMenu" parent="Widget.Holo.PopupMenu" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton" parent="Widget.Holo.ActionButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton.Overflow" parent="Widget.Holo.ActionButton.Overflow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton.TextButton" parent="Widget.Holo.ActionButton.TextButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionMode" parent="Widget.Holo.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionButton.CloseMode" parent="Widget.Holo.ActionButton.CloseMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar" parent="Widget.Holo.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Borderless" parent="Widget.Holo.Button.Borderless" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Tab" parent="Widget.Holo.Tab" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CalendarView" parent="Widget.Holo.CalendarView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.DatePicker" parent="Widget.Holo.DatePicker" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.TabView" parent="Widget.Holo.ActionBar.TabView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.TabText" parent="Widget.Holo.ActionBar.TabText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.TabBar" parent="Widget.Holo.ActionBar.TabBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.ActionBar.Solid" parent="Widget.Holo.ActionBar.Solid" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Button.Borderless.Small" parent="Widget.Holo.Button.Borderless.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.AbsListView" parent="Widget.Holo.AbsListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Spinner.DropDown.ActionBar" parent="Widget.Holo.Spinner.DropDown.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.PopupWindow.ActionMode" parent="Widget.Holo.PopupWindow.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.CompoundButton.Switch" parent="Widget.Holo.CompoundButton.Switch">
+
+ </style>
+ <style name="Widget.DeviceDefault.EditText.NumberPickerInputText" parent="Widget.Holo.EditText.NumberPickerInputText">
+
+ </style>
+ <style name="Widget.DeviceDefault.ExpandableListView.White" parent="Widget.Holo.ExpandableListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.Gallery" parent="Widget.Holo.Gallery">
+
+ </style>
+ <style name="Widget.DeviceDefault.GestureOverlayView" parent="Widget.Holo.GestureOverlayView">
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageButton.NumberPickerDownButton" parent="Widget.Holo.ImageButton.NumberPickerDownButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.ImageWell" parent="Widget.Holo.ImageWell">
+
+ </style>
+ <style name="Widget.DeviceDefault.KeyboardView" parent="Widget.Holo.KeyboardView">
+
+ </style>
+ <style name="Widget.DeviceDefault.ListView.White" parent="Widget.Holo.ListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.NumberPicker" parent="Widget.Holo.NumberPicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.PreferenceFrameLayout" parent="Widget.Holo.PreferenceFrameLayout">
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Inverse" parent="Widget.Holo.ProgressBar.Inverse">
+
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Large.Inverse" parent="Widget.Holo.ProgressBar.Large.Inverse">
+
+ </style>
+ <style name="Widget.DeviceDefault.ProgressBar.Small.Inverse" parent="Widget.Holo.ProgressBar.Small.Inverse">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadge.WindowLarge" parent="Widget.Holo.QuickContactBadge.WindowLarge">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadge.WindowMedium" parent="Widget.Holo.QuickContactBadge.WindowMedium">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadge.WindowSmall" parent="Widget.Holo.QuickContactBadge.WindowSmall">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge" parent="Widget.Holo.QuickContactBadgeSmall.WindowLarge">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium" parent="Widget.Holo.QuickContactBadgeSmall.WindowMedium">
+
+ </style>
+ <style name="Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall" parent="Widget.Holo.QuickContactBadgeSmall.WindowSmall">
+
+ </style>
+ <style name="Widget.DeviceDefault.Spinner.DropDown" parent="Widget.Holo.Spinner.DropDown">
+
+ </style>
+ <style name="Widget.DeviceDefault.StackView" parent="Widget.Holo.StackView">
+
+ </style>
+ <style name="Widget.DeviceDefault.TextSelectHandle" parent="Widget.Holo.TextSelectHandle">
+
+ </style>
+ <style name="Widget.DeviceDefault.TextSuggestionsPopupWindow" parent="Widget.Holo.TextSuggestionsPopupWindow">
+
+ </style>
+ <style name="Widget.DeviceDefault.TextView.ListSeparator" parent="Widget.Holo.TextView.ListSeparator">
+
+ </style>
+ <style name="Widget.DeviceDefault.TimePicker" parent="Widget.Holo.TimePicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light" parent="Widget.Holo.Light" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button" parent="Widget.Holo.Light.Button" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Small" parent="Widget.Holo.Light.Button.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Inset" parent="Widget.Holo.Light.Button.Inset" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Toggle" parent="Widget.Holo.Light.Button.Toggle" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextView" parent="Widget.Holo.Light.TextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.AutoCompleteTextView" parent="Widget.Holo.Light.AutoCompleteTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CompoundButton.CheckBox" parent="Widget.Holo.Light.CompoundButton.CheckBox" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListView.DropDown" parent="Widget.Holo.Light.ListView.DropDown" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.EditText" parent="Widget.Holo.Light.EditText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ExpandableListView" parent="Widget.Holo.Light.ExpandableListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.GridView" parent="Widget.Holo.Light.GridView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageButton" parent="Widget.Holo.Light.ImageButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListView" parent="Widget.Holo.Light.ListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.PopupWindow" parent="Widget.Holo.Light.PopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar" parent="Widget.Holo.Light.ProgressBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Horizontal" parent="Widget.Holo.Light.ProgressBar.Horizontal" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Small" parent="Widget.Holo.Light.ProgressBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Title" parent="Widget.Holo.Light.ProgressBar.Small.Title" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Large" parent="Widget.Holo.Light.ProgressBar.Large" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Inverse" parent="Widget.Holo.Light.ProgressBar.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Small.Inverse" parent="Widget.Holo.Light.ProgressBar.Small.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ProgressBar.Large.Inverse" parent="Widget.Holo.Light.ProgressBar.Large.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.SeekBar" parent="Widget.Holo.Light.SeekBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.RatingBar" parent="Widget.Holo.Light.RatingBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.RatingBar.Indicator" parent="Widget.Holo.Light.RatingBar.Indicator" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.RatingBar.Small" parent="Widget.Holo.Light.RatingBar.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CompoundButton.RadioButton" parent="Widget.Holo.Light.CompoundButton.RadioButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ScrollView" parent="Widget.Holo.Light.ScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.HorizontalScrollView" parent="Widget.Holo.Light.HorizontalScrollView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Spinner" parent="Widget.Holo.Light.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CompoundButton.Star" parent="Widget.Holo.Light.CompoundButton.Star" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TabWidget" parent="Widget.Holo.Light.TabWidget" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.WebTextView" parent="Widget.Holo.Light.WebTextView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.WebView" parent="Widget.Holo.Light.WebView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.DropDownItem" parent="Widget.Holo.Light.DropDownItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.DropDownItem.Spinner" parent="Widget.Holo.Light.DropDownItem.Spinner" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextView.SpinnerItem" parent="Widget.Holo.Light.TextView.SpinnerItem" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListPopupWindow" parent="Widget.Holo.Light.ListPopupWindow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.PopupMenu" parent="Widget.Holo.Light.PopupMenu" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Tab" parent="Widget.Holo.Light.Tab" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.CalendarView" parent="Widget.Holo.Light.CalendarView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Borderless.Small" parent="Widget.Holo.Light.Button.Borderless.Small" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionButton" parent="Widget.Holo.Light.ActionButton" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionButton.Overflow" parent="Widget.Holo.Light.ActionButton.Overflow" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionMode" parent="Widget.Holo.Light.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionButton.CloseMode" parent="Widget.Holo.Light.ActionButton.CloseMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar" parent="Widget.Holo.Light.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabView" parent="Widget.Holo.Light.ActionBar.TabView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabText" parent="Widget.Holo.Light.ActionBar.TabText" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabBar" parent="Widget.Holo.Light.ActionBar.TabBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Holo.Light.ActionBar.Solid" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.Solid.Inverse" parent="Widget.Holo.Light.ActionBar.Solid.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabBar.Inverse" parent="Widget.Holo.Light.ActionBar.TabBar.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabView.Inverse" parent="Widget.Holo.Light.ActionBar.TabView.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionBar.TabText.Inverse" parent="Widget.Holo.Light.ActionBar.TabText.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ActionMode.Inverse" parent="Widget.Holo.Light.ActionMode.Inverse" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.AbsListView" parent="Widget.Holo.Light.AbsListView" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Spinner.DropDown.ActionBar" parent="Widget.Holo.Light.Spinner.DropDown.ActionBar" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.PopupWindow.ActionMode" parent="Widget.Holo.Light.PopupWindow.ActionMode" >
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Button.Borderless" parent="Widget.Holo.Light.Button.Borderless">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.DatePicker" parent="Widget.Holo.Light.DatePicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.EditText.NumberPickerInputText" parent="Widget.Holo.Light.EditText.NumberPickerInputText">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ExpandableListView.White" parent="Widget.Holo.Light.ExpandableListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Gallery" parent="Widget.Holo.Light.Gallery">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.GestureOverlayView" parent="Widget.Holo.Light.GestureOverlayView">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton" parent="Widget.Holo.Light.ImageButton.NumberPickerDownButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.Light.ImageButton.NumberPickerUpButton">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ImageWell" parent="Widget.Holo.Light.ImageWell">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.ListView.White" parent="Widget.Holo.Light.ListView.White">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.NumberPicker" parent="Widget.Holo.Light.NumberPicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.Spinner.DropDown" parent="Widget.Holo.Light.Spinner.DropDown">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextView.ListSeparator" parent="Widget.Holo.Light.TextView.ListSeparator">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TimePicker" parent="Widget.Holo.Light.TimePicker">
+
+ </style>
+ <style name="Widget.DeviceDefault.Light.TextSuggestionsPopupWindow" parent="Widget.Holo.Light.TextSuggestionsPopupWindow">
+
+ </style>
+
+
+ <!-- Text Appearance Styles -->
+ <style name="TextAppearance.DeviceDefault" parent="TextAppearance.Holo" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Inverse" parent="TextAppearance.Holo.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Large" parent="TextAppearance.Holo.Large" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Large.Inverse" parent="TextAppearance.Holo.Large.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Medium" parent="TextAppearance.Holo.Medium" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Medium.Inverse" parent="TextAppearance.Holo.Medium.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Small" parent="TextAppearance.Holo.Small" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Small.Inverse" parent="TextAppearance.Holo.Small.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.SearchResult.Title" parent="TextAppearance.Holo.SearchResult.Title" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.SearchResult.Subtitle" parent="TextAppearance.Holo.SearchResult.Subtitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget" parent="TextAppearance.Holo.Widget" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.Button" parent="TextAppearance.Holo.Widget.Button" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.IconMenu.Item" parent="TextAppearance.Holo.Widget.IconMenu.Item" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TabWidget" parent="TextAppearance.Holo.Widget.TabWidget" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TextView" parent="TextAppearance.Holo.Widget.TextView" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TextView.PopupMenu" parent="TextAppearance.Holo.Widget.TextView.PopupMenu" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.DropDownHint" parent="TextAppearance.Holo.Widget.DropDownHint" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.DropDownItem" parent="TextAppearance.Holo.Widget.DropDownItem" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.TextView.SpinnerItem" parent="TextAppearance.Holo.Widget.TextView.SpinnerItem" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.EditText" parent="TextAppearance.Holo.Widget.EditText" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.PopupMenu" parent="TextAppearance.Holo.Widget.PopupMenu" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" parent="TextAppearance.Holo.Widget.PopupMenu.Large" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" parent="TextAppearance.Holo.Widget.PopupMenu.Small" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Holo.Widget.ActionBar.Title" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" parent="TextAppearance.Holo.Widget.ActionBar.Subtitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" parent="TextAppearance.Holo.Widget.ActionMode.Title" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" parent="TextAppearance.Holo.Widget.ActionMode.Subtitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.WindowTitle" parent="TextAppearance.Holo.WindowTitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.DialogWindowTitle" parent="TextAppearance.Holo.DialogWindowTitle" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Holo.Widget.ActionBar.Title.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Holo.Widget.ActionMode.Title.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Holo.Widget.ActionMode.Subtitle.Inverse" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" parent="TextAppearance.Holo.Widget.ActionBar.Menu" >
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light" parent="TextAppearance.Holo.Light">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Inverse" parent="TextAppearance.Holo.Light.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Large" parent="TextAppearance.Holo.Light.Large">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Large.Inverse" parent="TextAppearance.Holo.Light.Large.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Medium" parent="TextAppearance.Holo.Light.Medium">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Medium.Inverse" parent="TextAppearance.Holo.Light.Medium.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.SearchResult.Subtitle" parent="TextAppearance.Holo.Light.SearchResult.Subtitle">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.SearchResult.Title" parent="TextAppearance.Holo.Light.SearchResult.Title">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Small" parent="TextAppearance.Holo.Light.Small">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Small.Inverse" parent="TextAppearance.Holo.Light.Small.Inverse">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Widget.Button" parent="TextAppearance.Holo.Light.Widget.Button">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Large" parent="TextAppearance.Holo.Light.Widget.PopupMenu.Large">
+
+ </style>
+ <style name="TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Small" parent="TextAppearance.Holo.Light.Widget.PopupMenu.Small">
+
+ </style>
+
+
+ <!-- Preference Styles -->
+ <style name="Preference.DeviceDefault" parent="Preference.Holo">
+
+ </style>
+ <style name="Preference.DeviceDefault.Category" parent="Preference.Holo.Category">
+
+ </style>
+ <style name="Preference.DeviceDefault.CheckBoxPreference" parent="Preference.Holo.CheckBoxPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.DialogPreference" parent="Preference.Holo.DialogPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.DialogPreference.EditTextPreference" parent="Preference.Holo.DialogPreference.EditTextPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.DialogPreference.YesNoPreference" parent="Preference.Holo.DialogPreference.YesNoPreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.Information" parent="Preference.Holo.Information">
+
+ </style>
+ <style name="Preference.DeviceDefault.PreferenceScreen" parent="Preference.Holo.PreferenceScreen">
+
+ </style>
+ <style name="Preference.DeviceDefault.RingtonePreference" parent="Preference.Holo.RingtonePreference">
+
+ </style>
+ <style name="Preference.DeviceDefault.SwitchPreference" parent="Preference.Holo.SwitchPreference">
+
+ </style>
+
+
+ <!-- AlertDialog Styles -->
+ <style name="AlertDialog.DeviceDefault" parent="AlertDialog.Holo">
+
+ </style>
+ <style name="AlertDialog.DeviceDefault.Light" parent="AlertDialog.DeviceDefault.Light" >
+
+ </style>
+
+
+ <!-- Animation Styles -->
+ <style name="Animation.DeviceDefault.Activity" parent="Animation.Holo.Activity">
+
+ </style>
+ <style name="Animation.DeviceDefault.Dialog" parent="Animation.Holo.Dialog">
+
+ </style>
+
+
+ <!-- DialogWindowTitle Styles -->
+ <style name="DialogWindowTitle.DeviceDefault" parent="DialogWindowTitle.Holo">
+
+ </style>
+ <style name="DialogWindowTitle.DeviceDefault.Light" parent="DialogWindowTitle.Holo.Light">
+
+ </style>
+
+
+ <!-- WindowTitle Styles -->
+ <style name="WindowTitle.DeviceDefault" parent="WindowTitle.Holo">
+
+ </style>
+ <style name="WindowTitleBackground.DeviceDefault" parent="WindowTitleBackground.Holo">
+
+ </style>
+
+
+ <!-- Other Styles -->
+ <style name="DeviceDefault.ButtonBar" parent="Holo.ButtonBar" >
+
+ </style>
+ <style name="DeviceDefault.ButtonBar.AlertDialog" parent="Holo.ButtonBar.AlertDialog" >
+
+ </style>
+ <style name="DeviceDefault.SegmentedButton" parent="Holo.SegmentedButton" >
+
+ </style>
+ <style name="DeviceDefault.Light.ButtonBar" parent="Holo.Light.ButtonBar" >
+
+ </style>
+ <style name="DeviceDefault.Light.ButtonBar.AlertDialog" parent="Holo.Light.ButtonBar.AlertDialog" >
+
+ </style>
+ <style name="DeviceDefault.Light.SegmentedButton" parent="Holo.Light.SegmentedButton" >
+
+ </style>
+</resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 2b1b693..615a37d 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -14,6 +14,20 @@
limitations under the License.
-->
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+
+The Holo themes must not be modified in order to pass CTS.
+Many related themes and styles depend on other values defined in this file.
+If you would like to provide custom themes and styles for your device,
+please see themes_device_defaults.xml.
+
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
<resources>
<!-- The default system theme. This is the theme used for activities
that have not explicitly set their own theme.
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
new file mode 100644
index 0000000..bf6329d
--- /dev/null
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -0,0 +1,423 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!--
+===============================================================
+ PLEASE READ
+===============================================================
+This file contains the themes that are the Device Defaults.
+If you want to edit themes to skin your device, do it here.
+We recommend that you do not edit themes.xml and instead edit
+this file.
+
+Editing this file instead of themes.xml will greatly simplify
+merges for future platform versions and CTS compliance will be
+easier.
+===============================================================
+ PLEASE READ
+===============================================================
+ -->
+<resources>
+ <style name="Theme.DeviceDefault" parent="Theme.Holo" >
+ <!-- Text styles -->
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Inverse</item>
+
+ <item name="textAppearanceLarge">@android:style/TextAppearance.DeviceDefault.Large</item>
+ <item name="textAppearanceMedium">@android:style/TextAppearance.DeviceDefault.Medium</item>
+ <item name="textAppearanceSmall">@android:style/TextAppearance.DeviceDefault.Small</item>
+ <item name="textAppearanceLargeInverse">@android:style/TextAppearance.DeviceDefault.Large.Inverse</item>
+ <item name="textAppearanceMediumInverse">@android:style/TextAppearance.DeviceDefault.Medium.Inverse</item>
+ <item name="textAppearanceSmallInverse">@android:style/TextAppearance.DeviceDefault.Small.Inverse</item>
+ <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Title</item>
+ <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle</item>
+
+ <item name="textAppearanceButton">@android:style/TextAppearance.DeviceDefault.Widget.Button</item>
+
+ <item name="textAppearanceLargePopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Large</item>
+ <item name="textAppearanceSmallPopupMenu">@android:style/TextAppearance.DeviceDefault.Widget.PopupMenu.Small</item>
+
+ <!-- Button styles -->
+ <item name="buttonStyle">@android:style/Widget.DeviceDefault.Button</item>
+
+ <item name="buttonStyleSmall">@android:style/Widget.DeviceDefault.Button.Small</item>
+ <item name="buttonStyleInset">@android:style/Widget.DeviceDefault.Button.Inset</item>
+
+ <item name="buttonStyleToggle">@android:style/Widget.DeviceDefault.Button.Toggle</item>
+ <item name="switchStyle">@android:style/Widget.DeviceDefault.CompoundButton.Switch</item>
+
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Button.Borderless</item>
+
+ <item name="listSeparatorTextViewStyle">@android:style/Widget.DeviceDefault.TextView.ListSeparator</item>
+
+ <!-- Window attributes -->
+ <item name="windowTitleStyle">@android:style/WindowTitle.DeviceDefault</item>
+ <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground.DeviceDefault</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
+
+ <!-- Dialog attributes -->
+ <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault</item>
+ <item name="dialogTheme">@android:style/Theme.DeviceDefault.Dialog</item>
+ <item name="alertDialogTheme">@android:style/Theme.DeviceDefault.Dialog.Alert</item>
+
+ <!-- Text selection handle attributes -->
+ <item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item>
+ <item name="textSuggestionsWindowStyle">@android:style/Widget.DeviceDefault.TextSuggestionsPopupWindow</item>
+
+ <!-- Widget styles -->
+ <item name="absListViewStyle">@android:style/Widget.DeviceDefault.AbsListView</item>
+ <item name="autoCompleteTextViewStyle">@android:style/Widget.DeviceDefault.AutoCompleteTextView</item>
+ <item name="checkboxStyle">@android:style/Widget.DeviceDefault.CompoundButton.CheckBox</item>
+ <item name="dropDownListViewStyle">@android:style/Widget.DeviceDefault.ListView.DropDown</item>
+ <item name="editTextStyle">@android:style/Widget.DeviceDefault.EditText</item>
+ <item name="expandableListViewStyle">@android:style/Widget.DeviceDefault.ExpandableListView</item>
+ <item name="expandableListViewWhiteStyle">@android:style/Widget.DeviceDefault.ExpandableListView.White</item>
+ <item name="galleryStyle">@android:style/Widget.DeviceDefault.Gallery</item>
+ <item name="gestureOverlayViewStyle">@android:style/Widget.DeviceDefault.GestureOverlayView</item>
+ <item name="gridViewStyle">@android:style/Widget.DeviceDefault.GridView</item>
+ <item name="imageButtonStyle">@android:style/Widget.DeviceDefault.ImageButton</item>
+ <item name="imageWellStyle">@android:style/Widget.DeviceDefault.ImageWell</item>
+ <item name="listViewStyle">@android:style/Widget.DeviceDefault.ListView</item>
+ <item name="listViewWhiteStyle">@android:style/Widget.DeviceDefault.ListView.White</item>
+ <item name="popupWindowStyle">@android:style/Widget.DeviceDefault.PopupWindow</item>
+ <item name="progressBarStyle">@android:style/Widget.DeviceDefault.ProgressBar</item>
+ <item name="progressBarStyleHorizontal">@android:style/Widget.DeviceDefault.ProgressBar.Horizontal</item>
+ <item name="progressBarStyleSmall">@android:style/Widget.DeviceDefault.ProgressBar.Small</item>
+ <item name="progressBarStyleSmallTitle">@android:style/Widget.DeviceDefault.ProgressBar.Small.Title</item>
+ <item name="progressBarStyleLarge">@android:style/Widget.DeviceDefault.ProgressBar.Large</item>
+ <item name="progressBarStyleInverse">@android:style/Widget.DeviceDefault.ProgressBar.Inverse</item>
+ <item name="progressBarStyleSmallInverse">@android:style/Widget.DeviceDefault.ProgressBar.Small.Inverse</item>
+ <item name="progressBarStyleLargeInverse">@android:style/Widget.DeviceDefault.ProgressBar.Large.Inverse</item>
+ <item name="seekBarStyle">@android:style/Widget.DeviceDefault.SeekBar</item>
+ <item name="ratingBarStyle">@android:style/Widget.DeviceDefault.RatingBar</item>
+ <item name="ratingBarStyleIndicator">@android:style/Widget.DeviceDefault.RatingBar.Indicator</item>
+ <item name="ratingBarStyleSmall">@android:style/Widget.DeviceDefault.RatingBar.Small</item>
+ <item name="radioButtonStyle">@android:style/Widget.DeviceDefault.CompoundButton.RadioButton</item>
+ <item name="scrollViewStyle">@android:style/Widget.DeviceDefault.ScrollView</item>
+ <item name="horizontalScrollViewStyle">@android:style/Widget.DeviceDefault.HorizontalScrollView</item>
+ <item name="dropDownSpinnerStyle">@android:style/Widget.DeviceDefault.Spinner.DropDown</item>
+ <item name="starStyle">@android:style/Widget.DeviceDefault.CompoundButton.Star</item>
+ <item name="tabWidgetStyle">@android:style/Widget.DeviceDefault.TabWidget</item>
+ <item name="textViewStyle">@android:style/Widget.DeviceDefault.TextView</item>
+ <item name="webTextViewStyle">@android:style/Widget.DeviceDefault.WebTextView</item>
+ <item name="webViewStyle">@android:style/Widget.DeviceDefault.WebView</item>
+ <item name="dropDownItemStyle">@android:style/Widget.DeviceDefault.DropDownItem</item>
+ <item name="spinnerDropDownItemStyle">@android:style/Widget.DeviceDefault.DropDownItem.Spinner</item>
+ <item name="spinnerItemStyle">@android:style/Widget.DeviceDefault.TextView.SpinnerItem</item>
+ <item name="dropDownHintAppearance">@android:style/TextAppearance.DeviceDefault.Widget.DropDownHint</item>
+ <item name="keyboardViewStyle">@android:style/Widget.DeviceDefault.KeyboardView</item>
+ <item name="quickContactBadgeStyleWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowSmall</item>
+ <item name="quickContactBadgeStyleWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowMedium</item>
+ <item name="quickContactBadgeStyleWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowLarge</item>
+ <item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall</item>
+ <item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium</item>
+ <item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge</item>
+ <item name="listPopupWindowStyle">@android:style/Widget.DeviceDefault.ListPopupWindow</item>
+ <item name="popupMenuStyle">@android:style/Widget.DeviceDefault.PopupMenu</item>
+ <item name="stackViewStyle">@android:style/Widget.DeviceDefault.StackView</item>
+
+ <!-- Preference styles -->
+ <item name="preferenceScreenStyle">@android:style/Preference.DeviceDefault.PreferenceScreen</item>
+ <item name="preferenceCategoryStyle">@android:style/Preference.DeviceDefault.Category</item>
+ <item name="preferenceStyle">@android:style/Preference.DeviceDefault</item>
+ <item name="preferenceInformationStyle">@android:style/Preference.DeviceDefault.Information</item>
+ <item name="checkBoxPreferenceStyle">@android:style/Preference.DeviceDefault.CheckBoxPreference</item>
+ <item name="switchPreferenceStyle">@android:style/Preference.DeviceDefault.SwitchPreference</item>
+ <item name="yesNoPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.YesNoPreference</item>
+ <item name="dialogPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference</item>
+ <item name="editTextPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.EditTextPreference</item>
+ <item name="ringtonePreferenceStyle">@android:style/Preference.DeviceDefault.RingtonePreference</item>
+
+ <!-- Action bar styles -->
+ <item name="actionDropDownStyle">@android:style/Widget.DeviceDefault.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.DeviceDefault.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.DeviceDefault.ActionButton.Overflow</item>
+ <item name="actionBarTabStyle">@style/Widget.DeviceDefault.ActionBar.TabView</item>
+ <item name="actionBarTabBarStyle">@style/Widget.DeviceDefault.ActionBar.TabBar</item>
+ <item name="actionBarTabTextStyle">@style/Widget.DeviceDefault.ActionBar.TabText</item>
+ <item name="actionModeStyle">@style/Widget.DeviceDefault.ActionMode</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.DeviceDefault.ActionButton.CloseMode</item>
+ <item name="actionBarStyle">@android:style/Widget.DeviceDefault.ActionBar</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.DeviceDefault.PopupWindow.ActionMode</item>
+
+ <item name="buttonBarStyle">@android:style/DeviceDefault.ButtonBar</item>
+ <item name="segmentedButtonStyle">@android:style/DeviceDefault.SegmentedButton</item>
+
+ <item name="searchDialogTheme">@style/Theme.DeviceDefault.SearchBar</item>
+
+ <!-- PreferenceFrameLayout attributes -->
+ <item name="preferenceFrameLayoutStyle">@android:style/Widget.DeviceDefault.PreferenceFrameLayout</item>
+
+ <!-- NumberPicker styles-->
+ <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerUpButton</item>
+ <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.ImageButton.NumberPickerDownButton</item>
+ <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.DeviceDefault.NumberPicker</item>
+
+ <!-- CalendarView style-->
+ <item name="calendarViewStyle">@style/Widget.DeviceDefault.CalendarView</item>
+
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.DeviceDefault.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.DeviceDefault.DatePicker</item>
+ </style>
+ <style name="Theme.DeviceDefault.NoActionBar" parent="Theme.Holo.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.NoActionBar.Fullscreen" parent="Theme.Holo.NoActionBar.Fullscreen" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light" parent="Theme.Holo.Light" >
+ <!-- Text styles -->
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Light</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Light.Inverse</item>
+
+ <item name="textAppearanceLarge">@android:style/TextAppearance.DeviceDefault.Light.Large</item>
+ <item name="textAppearanceMedium">@android:style/TextAppearance.DeviceDefault.Light.Medium</item>
+ <item name="textAppearanceSmall">@android:style/TextAppearance.DeviceDefault.Light.Small</item>
+ <item name="textAppearanceLargeInverse">@android:style/TextAppearance.DeviceDefault.Light.Large.Inverse</item>
+ <item name="textAppearanceMediumInverse">@android:style/TextAppearance.DeviceDefault.Light.Medium.Inverse</item>
+ <item name="textAppearanceSmallInverse">@android:style/TextAppearance.DeviceDefault.Light.Small.Inverse</item>
+ <item name="textAppearanceSearchResultTitle">@android:style/TextAppearance.DeviceDefault.Light.SearchResult.Title</item>
+ <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.DeviceDefault.Light.SearchResult.Subtitle</item>
+
+ <item name="textAppearanceButton">@android:style/TextAppearance.DeviceDefault.Light.Widget.Button</item>
+
+ <item name="textAppearanceLargePopupMenu">@android:style/TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Large</item>
+ <item name="textAppearanceSmallPopupMenu">@android:style/TextAppearance.DeviceDefault.Light.Widget.PopupMenu.Small</item>
+
+ <!-- Button styles -->
+ <item name="buttonStyle">@android:style/Widget.DeviceDefault.Light.Button</item>
+
+ <item name="buttonStyleSmall">@android:style/Widget.DeviceDefault.Light.Button.Small</item>
+ <item name="buttonStyleInset">@android:style/Widget.DeviceDefault.Light.Button.Inset</item>
+
+ <item name="buttonStyleToggle">@android:style/Widget.DeviceDefault.Light.Button.Toggle</item>
+
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Light.Button.Borderless</item>
+
+ <item name="listSeparatorTextViewStyle">@android:style/Widget.DeviceDefault.Light.TextView.ListSeparator</item>
+
+ <item name="windowTitleStyle">@android:style/WindowTitle.DeviceDefault</item>
+ <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground.DeviceDefault</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Activity</item>
+
+ <!-- Dialog attributes -->
+ <item name="alertDialogStyle">@android:style/AlertDialog.DeviceDefault.Light</item>
+ <item name="dialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog</item>
+ <item name="alertDialogTheme">@android:style/Theme.DeviceDefault.Light.Dialog.Alert</item>
+
+ <!-- Text selection handle attributes -->
+ <item name="textSelectHandleWindowStyle">@android:style/Widget.DeviceDefault.TextSelectHandle</item>
+ <item name="textSuggestionsWindowStyle">@android:style/Widget.DeviceDefault.Light.TextSuggestionsPopupWindow</item>
+
+ <!-- Widget styles -->
+ <item name="absListViewStyle">@android:style/Widget.DeviceDefault.Light.AbsListView</item>
+ <item name="autoCompleteTextViewStyle">@android:style/Widget.DeviceDefault.Light.AutoCompleteTextView</item>
+ <item name="checkboxStyle">@android:style/Widget.DeviceDefault.Light.CompoundButton.CheckBox</item>
+ <item name="dropDownListViewStyle">@android:style/Widget.DeviceDefault.ListView.DropDown</item>
+ <item name="editTextStyle">@android:style/Widget.DeviceDefault.Light.EditText</item>
+ <item name="expandableListViewStyle">@android:style/Widget.DeviceDefault.Light.ExpandableListView</item>
+ <item name="expandableListViewWhiteStyle">@android:style/Widget.DeviceDefault.Light.ExpandableListView.White</item>
+ <item name="galleryStyle">@android:style/Widget.DeviceDefault.Light.Gallery</item>
+ <item name="gestureOverlayViewStyle">@android:style/Widget.DeviceDefault.Light.GestureOverlayView</item>
+ <item name="gridViewStyle">@android:style/Widget.DeviceDefault.Light.GridView</item>
+ <item name="imageButtonStyle">@android:style/Widget.DeviceDefault.Light.ImageButton</item>
+ <item name="imageWellStyle">@android:style/Widget.DeviceDefault.Light.ImageWell</item>
+ <item name="listViewStyle">@android:style/Widget.DeviceDefault.Light.ListView</item>
+ <item name="listViewWhiteStyle">@android:style/Widget.DeviceDefault.Light.ListView.White</item>
+ <item name="popupWindowStyle">@android:style/Widget.DeviceDefault.Light.PopupWindow</item>
+ <item name="progressBarStyle">@android:style/Widget.DeviceDefault.Light.ProgressBar</item>
+ <item name="progressBarStyleHorizontal">@android:style/Widget.DeviceDefault.Light.ProgressBar.Horizontal</item>
+ <item name="progressBarStyleSmall">@android:style/Widget.DeviceDefault.Light.ProgressBar.Small</item>
+ <item name="progressBarStyleSmallTitle">@android:style/Widget.DeviceDefault.Light.ProgressBar.Small.Title</item>
+ <item name="progressBarStyleLarge">@android:style/Widget.DeviceDefault.Light.ProgressBar.Large</item>
+ <item name="progressBarStyleInverse">@android:style/Widget.DeviceDefault.Light.ProgressBar.Inverse</item>
+ <item name="progressBarStyleSmallInverse">@android:style/Widget.DeviceDefault.Light.ProgressBar.Small.Inverse</item>
+ <item name="progressBarStyleLargeInverse">@android:style/Widget.DeviceDefault.Light.ProgressBar.Large.Inverse</item>
+ <item name="seekBarStyle">@android:style/Widget.DeviceDefault.Light.SeekBar</item>
+ <item name="ratingBarStyle">@android:style/Widget.DeviceDefault.Light.RatingBar</item>
+ <item name="ratingBarStyleIndicator">@android:style/Widget.DeviceDefault.Light.RatingBar.Indicator</item>
+ <item name="ratingBarStyleSmall">@android:style/Widget.DeviceDefault.Light.RatingBar.Small</item>
+ <item name="radioButtonStyle">@android:style/Widget.DeviceDefault.Light.CompoundButton.RadioButton</item>
+ <item name="scrollViewStyle">@android:style/Widget.DeviceDefault.Light.ScrollView</item>
+ <item name="horizontalScrollViewStyle">@android:style/Widget.DeviceDefault.Light.HorizontalScrollView</item>
+ <item name="dropDownSpinnerStyle">@android:style/Widget.DeviceDefault.Light.Spinner.DropDown</item>
+ <item name="starStyle">@android:style/Widget.DeviceDefault.Light.CompoundButton.Star</item>
+ <item name="tabWidgetStyle">@android:style/Widget.DeviceDefault.Light.TabWidget</item>
+ <item name="textViewStyle">@android:style/Widget.DeviceDefault.Light.TextView</item>
+ <item name="webTextViewStyle">@android:style/Widget.DeviceDefault.Light.WebTextView</item>
+ <item name="webViewStyle">@android:style/Widget.DeviceDefault.Light.WebView</item>
+ <item name="dropDownItemStyle">@android:style/Widget.DeviceDefault.Light.DropDownItem</item>
+ <item name="spinnerDropDownItemStyle">@android:style/Widget.DeviceDefault.Light.DropDownItem.Spinner</item>
+ <item name="spinnerItemStyle">@android:style/Widget.DeviceDefault.TextView.SpinnerItem</item>
+ <item name="dropDownHintAppearance">@android:style/TextAppearance.DeviceDefault.Widget.DropDownHint</item>
+ <item name="keyboardViewStyle">@android:style/Widget.DeviceDefault.KeyboardView</item>
+ <item name="quickContactBadgeStyleWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowSmall</item>
+ <item name="quickContactBadgeStyleWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowMedium</item>
+ <item name="quickContactBadgeStyleWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadge.WindowLarge</item>
+ <item name="quickContactBadgeStyleSmallWindowSmall">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowSmall</item>
+ <item name="quickContactBadgeStyleSmallWindowMedium">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowMedium</item>
+ <item name="quickContactBadgeStyleSmallWindowLarge">@android:style/Widget.DeviceDefault.QuickContactBadgeSmall.WindowLarge</item>
+ <item name="listPopupWindowStyle">@android:style/Widget.DeviceDefault.Light.ListPopupWindow</item>
+ <item name="popupMenuStyle">@android:style/Widget.DeviceDefault.Light.PopupMenu</item>
+ <item name="stackViewStyle">@android:style/Widget.DeviceDefault.StackView</item>
+
+ <!-- Preference styles -->
+ <item name="preferenceScreenStyle">@android:style/Preference.DeviceDefault.PreferenceScreen</item>
+ <item name="preferenceCategoryStyle">@android:style/Preference.DeviceDefault.Category</item>
+ <item name="preferenceStyle">@android:style/Preference.DeviceDefault</item>
+ <item name="preferenceInformationStyle">@android:style/Preference.DeviceDefault.Information</item>
+ <item name="checkBoxPreferenceStyle">@android:style/Preference.DeviceDefault.CheckBoxPreference</item>
+ <item name="switchPreferenceStyle">@android:style/Preference.DeviceDefault.SwitchPreference</item>
+ <item name="yesNoPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.YesNoPreference</item>
+ <item name="dialogPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference</item>
+ <item name="editTextPreferenceStyle">@android:style/Preference.DeviceDefault.DialogPreference.EditTextPreference</item>
+ <item name="ringtonePreferenceStyle">@android:style/Preference.DeviceDefault.RingtonePreference</item>
+
+ <!-- Action bar styles -->
+ <item name="actionDropDownStyle">@android:style/Widget.DeviceDefault.Light.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.DeviceDefault.Light.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.DeviceDefault.Light.ActionButton.Overflow</item>
+ <item name="actionBarTabStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabView</item>
+ <item name="actionBarTabBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabBar</item>
+ <item name="actionBarTabTextStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabText</item>
+ <item name="actionModeStyle">@style/Widget.DeviceDefault.Light.ActionMode</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.DeviceDefault.Light.ActionButton.CloseMode</item>
+ <item name="actionBarStyle">@android:style/Widget.DeviceDefault.Light.ActionBar</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.DeviceDefault.Light.PopupWindow.ActionMode</item>
+
+ <item name="buttonBarStyle">@android:style/DeviceDefault.Light.ButtonBar</item>
+ <item name="segmentedButtonStyle">@android:style/DeviceDefault.Light.SegmentedButton</item>
+
+ <item name="searchDialogTheme">@style/Theme.DeviceDefault.Light.SearchBar</item>
+
+ <!-- NumberPicker attributes and styles-->
+ <item name="numberPickerUpButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerUpButton</item>
+ <item name="numberPickerDownButtonStyle">@style/Widget.DeviceDefault.Light.ImageButton.NumberPickerDownButton</item>
+ <item name="numberPickerInputTextStyle">@style/Widget.DeviceDefault.Light.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.DeviceDefault.Light.NumberPicker</item>
+
+ <!-- CalendarView style-->
+ <item name="calendarViewStyle">@style/Widget.DeviceDefault.Light.CalendarView</item>
+
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.DeviceDefault.Light.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.DeviceDefault.Light.DatePicker</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.NoActionBar" parent="Theme.Holo.Light.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.NoActionBar.Fullscreen" parent="Theme.Holo.Light.NoActionBar.Fullscreen" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Dialog" parent="Theme.Holo.Dialog" >
+ <item name="android:windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Dialog</item>
+
+ <item name="android:buttonBarStyle">@android:style/DeviceDefault.ButtonBar.AlertDialog</item>
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Button.Borderless.Small</item>
+
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Inverse</item>
+ </style>
+ <style name="Theme.DeviceDefault.Dialog.MinWidth" parent="Theme.Holo.Dialog.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Dialog.NoActionBar" parent="Theme.Holo.Dialog.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Dialog.NoActionBar.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog" parent="Theme.Holo.Light.Dialog" >
+ <item name="android:windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault.Light</item>
+ <item name="android:windowAnimationStyle">@android:style/Animation.DeviceDefault.Dialog</item>
+
+ <item name="android:buttonBarStyle">@android:style/DeviceDefault.Light.ButtonBar.AlertDialog</item>
+ <item name="borderlessButtonStyle">@android:style/Widget.DeviceDefault.Light.Button.Borderless.Small</item>
+
+ <item name="textAppearance">@android:style/TextAppearance.DeviceDefault.Light</item>
+ <item name="textAppearanceInverse">@android:style/TextAppearance.DeviceDefault.Light.Inverse</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.MinWidth" parent="Theme.Holo.Light.Dialog.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar" parent="Theme.Holo.Light.Dialog.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Light.Dialog.NoActionBar.MinWidth" >
+
+ </style>
+ <style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Holo.DialogWhenLarge" >
+
+ </style>
+ <style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar" parent="Theme.Holo.DialogWhenLarge.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge" parent="Theme.Holo.Light.DialogWhenLarge" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar" parent="Theme.Holo.Light.DialogWhenLarge.NoActionBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Panel" parent="Theme.Holo.Panel" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.Panel" parent="Theme.Holo.Light.Panel" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Wallpaper" parent="Theme.Holo.Wallpaper" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Wallpaper.NoTitleBar" parent="Theme.Holo.Wallpaper.NoTitleBar" >
+
+ </style>
+ <style name="Theme.DeviceDefault.InputMethod" parent="Theme.Holo.InputMethod" >
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.DarkActionBar" parent="Theme.Holo.Light.DarkActionBar" >
+ <item name="android:actionBarStyle">@android:style/Widget.DeviceDefault.Light.ActionBar.Solid.Inverse</item>
+
+ <item name="actionDropDownStyle">@android:style/Widget.DeviceDefault.Spinner.DropDown.ActionBar</item>
+ <item name="actionButtonStyle">@android:style/Widget.DeviceDefault.ActionButton</item>
+ <item name="actionOverflowButtonStyle">@android:style/Widget.DeviceDefault.ActionButton.Overflow</item>
+ <item name="actionBarTabStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabView.Inverse</item>
+ <item name="actionBarTabBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabBar.Inverse</item>
+ <item name="actionBarTabTextStyle">@style/Widget.DeviceDefault.Light.ActionBar.TabText.Inverse</item>
+ <item name="actionModeStyle">@style/Widget.DeviceDefault.Light.ActionMode.Inverse</item>
+ <item name="actionModeCloseButtonStyle">@style/Widget.DeviceDefault.ActionButton.CloseMode</item>
+ <item name="actionModePopupWindowStyle">@android:style/Widget.DeviceDefault.PopupWindow.ActionMode</item>
+
+ </style>
+
+ <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Holo.Dialog.Alert">
+ <item name="windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault</item>
+ </style>
+ <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.DeviceDefault.Light.Dialog.Alert">
+ <item name="windowTitleStyle">@android:style/DialogWindowTitle.DeviceDefault.Light</item>
+ </style>
+ <style name="Theme.DeviceDefault.SearchBar" parent="Theme.DeviceDefault.SearchBar">
+
+ </style>
+ <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.DeviceDefault.Light.SearchBar">
+
+ </style>
+</resources>
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 5d28ef7..6c87c3b 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -3114,6 +3114,13 @@
PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
}
+ @LargeTest
+ public void testInstallNonexistentFile() {
+ int retCode = PackageManager.INSTALL_FAILED_INVALID_URI;
+ File invalidFile = new File("/nonexistent-file.apk");
+ invokeInstallPackageFail(Uri.fromFile(invalidFile), 0, retCode);
+ }
+
/*---------- Recommended install location tests ----*/
/*
* TODO's
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 1647ff3..d62fd67 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -187,6 +187,25 @@
return nativeGetTimestamp();
}
+ /**
+ * release() frees all the buffers and puts the SurfaceTexture into the
+ * 'abandoned' state. Once put in this state the SurfaceTexture can never
+ * leave it. When in the 'abandoned' state, all methods of the
+ * ISurfaceTexture interface will fail with the NO_INIT error.
+ *
+ * Note that while calling this method causes all the buffers to be freed
+ * from the perspective of the the SurfaceTexture, if there are additional
+ * references on the buffers (e.g. if a buffer is referenced by a client or
+ * by OpenGL ES as a texture) then those buffer will remain allocated.
+ *
+ * Always call this method when you are done with SurfaceTexture. Failing
+ * to do so may delay resource deallocation for a significant amount of
+ * time.
+ */
+ public void release() {
+ nativeRelease();
+ }
+
protected void finalize() throws Throwable {
try {
nativeFinalize();
@@ -232,6 +251,7 @@
private native void nativeSetDefaultBufferSize(int width, int height);
private native void nativeUpdateTexImage();
private native int nativeGetQueuedCount();
+ private native void nativeRelease();
/*
* We use a class initializer to allow the native code to cache some
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 4f51f03..1a036ee 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -910,6 +910,7 @@
Mutex::Autolock lock(mMutex);
freeAllBuffers();
mAbandoned = true;
+ mCurrentTextureBuf.clear();
mDequeueCondition.signal();
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 3e786c3..cd55b0e 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -187,7 +187,7 @@
AudioSystem.STREAM_RING, // STREAM_RING
AudioSystem.STREAM_MUSIC, // STREAM_MUSIC
AudioSystem.STREAM_ALARM, // STREAM_ALARM
- AudioSystem.STREAM_NOTIFICATION, // STREAM_NOTIFICATION
+ AudioSystem.STREAM_RING, // STREAM_NOTIFICATION
AudioSystem.STREAM_BLUETOOTH_SCO, // STREAM_BLUETOOTH_SCO
AudioSystem.STREAM_SYSTEM, // STREAM_SYSTEM_ENFORCED
AudioSystem.STREAM_VOICE_CALL, // STREAM_DTMF
@@ -242,9 +242,6 @@
*/
private int mVibrateSetting;
- /** @see System#NOTIFICATIONS_USE_RING_VOLUME */
- private int mNotificationsUseRingVolume;
-
// Broadcast receiver for device connections intent broadcasts
private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
@@ -456,16 +453,6 @@
System.MUTE_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
- if (mVoiceCapable) {
- mNotificationsUseRingVolume = System.getInt(cr,
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1);
- } else {
- mNotificationsUseRingVolume = 1;
- }
-
- if (mNotificationsUseRingVolume == 1) {
- STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
- }
// Each stream will read its own persisted settings
// Broadcast the sticky intent
@@ -2202,8 +2189,6 @@
super(new Handler());
mContentResolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
- mContentResolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME), false, this);
}
@Override
@@ -2227,29 +2212,6 @@
mRingerModeAffectedStreams = ringerModeAffectedStreams;
setRingerModeInt(getRingerMode(), false);
}
-
- int notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
- Settings.System.NOTIFICATIONS_USE_RING_VOLUME,
- 1);
- if (mVoiceCapable) {
- if (notificationsUseRingVolume != mNotificationsUseRingVolume) {
- mNotificationsUseRingVolume = notificationsUseRingVolume;
- if (mNotificationsUseRingVolume == 1) {
- STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_RING;
- mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
- System.VOLUME_SETTINGS[AudioSystem.STREAM_RING]);
- } else {
- STREAM_VOLUME_ALIAS[AudioSystem.STREAM_NOTIFICATION] = AudioSystem.STREAM_NOTIFICATION;
- mStreamStates[AudioSystem.STREAM_NOTIFICATION].setVolumeIndexSettingName(
- System.VOLUME_SETTINGS[AudioSystem.STREAM_NOTIFICATION]);
- // Persist notification volume volume as it was not persisted while aliased to ring volume
- // and persist with no delay as there might be registered observers of the persisted
- // notification volume.
- sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, AudioSystem.STREAM_NOTIFICATION,
- SENDMSG_REPLACE, 1, 1, mStreamStates[AudioSystem.STREAM_NOTIFICATION], 0);
- }
- }
- }
}
}
}
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 4203b6e..a5a6b64 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -92,7 +92,7 @@
size_t frameSize = 0;
uint8_t syncword[2];
- if (source->readAt(0, &syncword, 2) != 2) {
+ if (source->readAt(offset, &syncword, 2) != 2) {
return 0;
}
if ((syncword[0] != 0xff) || ((syncword[1] & 0xf6) != 0xf0)) {
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
index 3668b8c..7dfa53e 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
@@ -18,10 +18,20 @@
*/
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="16dp" >
+
+ <ScrollView
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:layout_width="match_parent">
+ <LinearLayout
+ android:orientation="vertical"
android:layout_height="wrap_content"
- android:padding="16dp" >
+ android:layout_width="match_parent">
<TextView android:id="@+id/confirm_text"
android:layout_width="match_parent"
@@ -63,13 +73,21 @@
android:layout_marginLeft="30dp"
android:layout_below="@id/enc_password"
android:layout_marginBottom="30dp" />
+ </LinearLayout>
+ </ScrollView>
+
+ <LinearLayout android:orientation="horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_gravity="bottom">
<Button android:id="@+id/button_allow"
android:filterTouchesWhenObscured="true"
android:text="@string/allow_backup_button_label"
android:layout_below="@id/package_name"
android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ android:layout_width="0dp"
+ android:layout_weight="1" />
<Button android:id="@+id/button_deny"
android:text="@string/deny_backup_button_label"
@@ -77,6 +95,9 @@
android:layout_toRightOf="@id/button_allow"
android:layout_alignTop="@id/button_allow"
android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ android:layout_width="0dp"
+ android:layout_weight="1" />
-</RelativeLayout>
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
index 38fcc496..4927cbb 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
@@ -18,65 +18,86 @@
*/
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:padding="16dp" >
-
- <TextView android:id="@+id/confirm_text"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="30dp"
- android:text="@string/restore_confirm_text" />
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="16dp" >
- <TextView android:id="@+id/password_desc"
- android:layout_below="@id/confirm_text"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="10dp"
- android:text="@string/current_password_text" />
+ <ScrollView
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:layout_width="match_parent">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent">
- <EditText android:id="@+id/password"
- android:layout_below="@id/password_desc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="30dp"
- android:password="true" />
+ <TextView android:id="@+id/confirm_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="30dp"
+ android:text="@string/restore_confirm_text" />
- <TextView android:id="@+id/enc_password_desc"
- android:layout_below="@id/password"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="10dp"
- android:text="@string/restore_enc_password_text" />
+ <TextView android:id="@+id/password_desc"
+ android:layout_below="@id/confirm_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:text="@string/current_password_text" />
- <EditText android:id="@+id/enc_password"
- android:layout_below="@id/enc_password_desc"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginBottom="30dp"
- android:password="true" />
+ <EditText android:id="@+id/password"
+ android:layout_below="@id/password_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="30dp"
+ android:password="true" />
- <TextView android:id="@+id/package_name"
- android:layout_width="match_parent"
- android:layout_height="20dp"
- android:layout_marginLeft="30dp"
- android:layout_below="@id/enc_password"
- android:layout_marginBottom="30dp" />
+ <TextView android:id="@+id/enc_password_desc"
+ android:layout_below="@id/password"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:text="@string/restore_enc_password_text" />
- <Button android:id="@+id/button_allow"
- android:filterTouchesWhenObscured="true"
- android:text="@string/allow_restore_button_label"
- android:layout_below="@id/package_name"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ <EditText android:id="@+id/enc_password"
+ android:layout_below="@id/enc_password_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="30dp"
+ android:password="true" />
- <Button android:id="@+id/button_deny"
- android:text="@string/deny_restore_button_label"
- android:layout_below="@id/package_name"
- android:layout_toRightOf="@id/button_allow"
- android:layout_alignTop="@id/button_allow"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content" />
+ <TextView android:id="@+id/package_name"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginLeft="30dp"
+ android:layout_below="@id/enc_password"
+ android:layout_marginBottom="10dp" />
+ </LinearLayout>
+ </ScrollView>
-</RelativeLayout>
+ <LinearLayout android:orientation="horizontal"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_gravity="bottom">
+
+ <Button android:id="@+id/button_allow"
+ android:filterTouchesWhenObscured="true"
+ android:text="@string/allow_restore_button_label"
+ android:layout_below="@id/package_name"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/button_deny"
+ android:text="@string/deny_restore_button_label"
+ android:layout_below="@id/package_name"
+ android:layout_toRightOf="@id/button_allow"
+ android:layout_alignTop="@id/button_allow"
+ android:layout_height="wrap_content"
+ android:layout_width="0dp"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 626cc86..eae6112 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -38,8 +38,7 @@
import android.os.StatFs;
import android.app.IntentService;
import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.Pair;
+import android.util.Slog;
import java.io.File;
import java.io.FileInputStream;
@@ -47,11 +46,6 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
import android.os.FileUtils;
import android.provider.Settings;
@@ -120,29 +114,39 @@
public PackageInfoLite getMinimalPackageInfo(final Uri fileUri, int flags, long threshold) {
PackageInfoLite ret = new PackageInfoLite();
if (fileUri == null) {
- Log.i(TAG, "Invalid package uri " + fileUri);
+ Slog.i(TAG, "Invalid package uri " + fileUri);
ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
return ret;
}
String scheme = fileUri.getScheme();
if (scheme != null && !scheme.equals("file")) {
- Log.w(TAG, "Falling back to installing on internal storage only");
+ Slog.w(TAG, "Falling back to installing on internal storage only");
ret.recommendedInstallLocation = PackageHelper.RECOMMEND_INSTALL_INTERNAL;
return ret;
}
String archiveFilePath = fileUri.getPath();
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
+
PackageParser.PackageLite pkg = PackageParser.parsePackageLite(archiveFilePath, 0);
if (pkg == null) {
- Log.w(TAG, "Failed to parse package");
- ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
+ Slog.w(TAG, "Failed to parse package");
+
+ final File apkFile = new File(archiveFilePath);
+ if (!apkFile.exists()) {
+ ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_URI;
+ } else {
+ ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
+ }
+
return ret;
}
ret.packageName = pkg.packageName;
ret.installLocation = pkg.installLocation;
+
ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation,
archiveFilePath, flags, threshold);
+
return ret;
}
@@ -150,20 +154,28 @@
public boolean checkInternalFreeStorage(Uri packageUri, long threshold)
throws RemoteException {
final File apkFile = new File(packageUri.getPath());
- return isUnderInternalThreshold(apkFile, threshold);
+ try {
+ return isUnderInternalThreshold(apkFile, threshold);
+ } catch (FileNotFoundException e) {
+ return true;
+ }
}
@Override
public boolean checkExternalFreeStorage(Uri packageUri) throws RemoteException {
final File apkFile = new File(packageUri.getPath());
- return isUnderExternalThreshold(apkFile);
+ try {
+ return isUnderExternalThreshold(apkFile);
+ } catch (FileNotFoundException e) {
+ return true;
+ }
}
public ObbInfo getObbInfo(String filename) {
try {
return ObbScanner.getObbInfo(filename);
} catch (IOException e) {
- Log.d(TAG, "Couldn't get OBB info for " + filename);
+ Slog.d(TAG, "Couldn't get OBB info for " + filename);
return null;
}
}
@@ -221,7 +233,7 @@
// Make sure the sdcard is mounted.
String status = Environment.getExternalStorageState();
if (!status.equals(Environment.MEDIA_MOUNTED)) {
- Log.w(TAG, "Make sure sdcard is mounted.");
+ Slog.w(TAG, "Make sure sdcard is mounted.");
return null;
}
@@ -229,75 +241,81 @@
String codePath = packageURI.getPath();
File codeFile = new File(codePath);
- // Native files we need to copy to the container.
- List<Pair<ZipEntry, String>> nativeFiles = new ArrayList<Pair<ZipEntry, String>>();
-
// Calculate size of container needed to hold base APK.
- final int sizeMb = calculateContainerSize(codeFile, nativeFiles);
+ int sizeMb;
+ try {
+ sizeMb = calculateContainerSize(codeFile);
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "File does not exist when trying to copy " + codeFile.getPath());
+ return null;
+ }
// Create new container
- String newCachePath = null;
+ final String newCachePath;
if ((newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid())) == null) {
- Log.e(TAG, "Failed to create container " + newCid);
- return null;
- }
- if (localLOGV)
- Log.i(TAG, "Created container for " + newCid + " at path : " + newCachePath);
- File resFile = new File(newCachePath, resFileName);
- if (!FileUtils.copyFile(new File(codePath), resFile)) {
- Log.e(TAG, "Failed to copy " + codePath + " to " + resFile);
- // Clean up container
- PackageHelper.destroySdDir(newCid);
+ Slog.e(TAG, "Failed to create container " + newCid);
return null;
}
- try {
- ZipFile zipFile = new ZipFile(codeFile);
+ if (localLOGV) {
+ Slog.i(TAG, "Created container for " + newCid + " at path : " + newCachePath);
+ }
- File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
- sharedLibraryDir.mkdir();
-
- final int N = nativeFiles.size();
- for (int i = 0; i < N; i++) {
- final Pair<ZipEntry, String> entry = nativeFiles.get(i);
-
- InputStream is = zipFile.getInputStream(entry.first);
- try {
- File destFile = new File(sharedLibraryDir, entry.second);
- if (!FileUtils.copyToFile(is, destFile)) {
- throw new IOException("Couldn't copy native binary "
- + entry.first.getName() + " to " + entry.second);
- }
- } finally {
- is.close();
- }
+ final File resFile = new File(newCachePath, resFileName);
+ if (FileUtils.copyFile(new File(codePath), resFile)) {
+ if (localLOGV) {
+ Slog.i(TAG, "Copied " + codePath + " to " + resFile);
}
- } catch (IOException e) {
- Log.e(TAG, "Couldn't copy native file to container", e);
+ } else {
+ Slog.e(TAG, "Failed to copy " + codePath + " to " + resFile);
+ // Clean up container
PackageHelper.destroySdDir(newCid);
return null;
}
- if (localLOGV) Log.i(TAG, "Copied " + codePath + " to " + resFile);
+ final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME);
+ if (sharedLibraryDir.mkdir()) {
+ int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir);
+ if (ret != PackageManager.INSTALL_SUCCEEDED) {
+ Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath());
+ PackageHelper.destroySdDir(newCid);
+ return null;
+ }
+ } else {
+ Slog.e(TAG, "Could not create native lib directory: " + sharedLibraryDir.getPath());
+ PackageHelper.destroySdDir(newCid);
+ return null;
+ }
+
if (!PackageHelper.finalizeSdDir(newCid)) {
- Log.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath);
+ Slog.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath);
// Clean up container
PackageHelper.destroySdDir(newCid);
+ return null;
}
- if (localLOGV) Log.i(TAG, "Finalized container " + newCid);
+
+ if (localLOGV) {
+ Slog.i(TAG, "Finalized container " + newCid);
+ }
+
if (PackageHelper.isContainerMounted(newCid)) {
- if (localLOGV) Log.i(TAG, "Unmounting " + newCid +
- " at path " + newCachePath);
+ if (localLOGV) {
+ Slog.i(TAG, "Unmounting " + newCid + " at path " + newCachePath);
+ }
+
// Force a gc to avoid being killed.
Runtime.getRuntime().gc();
PackageHelper.unMountSdDir(newCid);
} else {
- if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted");
+ if (localLOGV) {
+ Slog.i(TAG, "Container " + newCid + " not mounted");
+ }
}
+
return newCachePath;
}
- public static boolean copyToFile(InputStream inputStream, FileOutputStream out) {
+ private static boolean copyToFile(InputStream inputStream, FileOutputStream out) {
try {
byte[] buffer = new byte[4096];
int bytesRead;
@@ -306,12 +324,12 @@
}
return true;
} catch (IOException e) {
- Log.i(TAG, "Exception : " + e + " when copying file");
+ Slog.i(TAG, "Exception : " + e + " when copying file");
return false;
}
}
- public static boolean copyToFile(File srcFile, FileOutputStream out) {
+ private static boolean copyToFile(File srcFile, FileOutputStream out) {
InputStream inputStream = null;
try {
inputStream = new FileInputStream(srcFile);
@@ -323,7 +341,7 @@
}
}
- private boolean copyFile(Uri pPackageURI, FileOutputStream outStream) {
+ private boolean copyFile(Uri pPackageURI, FileOutputStream outStream) {
String scheme = pPackageURI.getScheme();
if (scheme == null || scheme.equals("file")) {
final File srcPackageFile = new File(pPackageURI.getPath());
@@ -331,7 +349,7 @@
// destination file in order to eliminate a window where the package directory
// scanner notices the new package file but it's not completely copied yet.
if (!copyToFile(srcPackageFile, outStream)) {
- Log.e(TAG, "Couldn't copy file: " + srcPackageFile);
+ Slog.e(TAG, "Couldn't copy file: " + srcPackageFile);
return false;
}
} else if (scheme.equals("content")) {
@@ -339,28 +357,31 @@
try {
fd = getContentResolver().openFileDescriptor(pPackageURI, "r");
} catch (FileNotFoundException e) {
- Log.e(TAG, "Couldn't open file descriptor from download service. Failed with exception " + e);
+ Slog.e(TAG,
+ "Couldn't open file descriptor from download service. Failed with exception "
+ + e);
return false;
}
if (fd == null) {
- Log.e(TAG, "Couldn't open file descriptor from download service (null).");
+ Slog.e(TAG, "Couldn't open file descriptor from download service (null).");
return false;
} else {
if (localLOGV) {
- Log.v(TAG, "Opened file descriptor from download service.");
+ Slog.i(TAG, "Opened file descriptor from download service.");
}
ParcelFileDescriptor.AutoCloseInputStream
dlStream = new ParcelFileDescriptor.AutoCloseInputStream(fd);
// We copy the source package file to a temp file and then rename it to the
// destination file in order to eliminate a window where the package directory
- // scanner notices the new package file but it's not completely copied yet.
+ // scanner notices the new package file but it's not completely
+ // cop
if (!copyToFile(dlStream, outStream)) {
- Log.e(TAG, "Couldn't copy " + pPackageURI + " to temp file.");
+ Slog.e(TAG, "Couldn't copy " + pPackageURI + " to temp file.");
return false;
}
}
} else {
- Log.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
+ Slog.e(TAG, "Package URI is not 'file:' or 'content:' - " + pPackageURI);
return false;
}
return true;
@@ -434,12 +455,20 @@
boolean fitsOnInternal = false;
if (checkBoth || prefer == PREFER_INTERNAL) {
- fitsOnInternal = isUnderInternalThreshold(apkFile, threshold);
+ try {
+ fitsOnInternal = isUnderInternalThreshold(apkFile, threshold);
+ } catch (FileNotFoundException e) {
+ return PackageHelper.RECOMMEND_FAILED_INVALID_URI;
+ }
}
boolean fitsOnSd = false;
if (!emulated && (checkBoth || prefer == PREFER_EXTERNAL)) {
- fitsOnSd = isUnderExternalThreshold(apkFile);
+ try {
+ fitsOnSd = isUnderExternalThreshold(apkFile);
+ } catch (FileNotFoundException e) {
+ return PackageHelper.RECOMMEND_FAILED_INVALID_URI;
+ }
}
if (prefer == PREFER_INTERNAL) {
@@ -473,8 +502,20 @@
}
}
- private boolean isUnderInternalThreshold(File apkFile, long threshold) {
+ /**
+ * Measure a file to see if it fits within the free space threshold.
+ *
+ * @param apkFile file to check
+ * @param threshold byte threshold to compare against
+ * @return true if file fits under threshold
+ * @throws FileNotFoundException when APK does not exist
+ */
+ private boolean isUnderInternalThreshold(File apkFile, long threshold)
+ throws FileNotFoundException {
final long size = apkFile.length();
+ if (size == 0 && !apkFile.exists()) {
+ throw new FileNotFoundException();
+ }
final StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath());
final long availInternalSize = (long) internalStats.getAvailableBlocks()
@@ -484,12 +525,19 @@
}
- private boolean isUnderExternalThreshold(File apkFile) {
+ /**
+ * Measure a file to see if it fits in the external free space.
+ *
+ * @param apkFile file to check
+ * @return true if file fits
+ * @throws IOException when file does not exist
+ */
+ private boolean isUnderExternalThreshold(File apkFile) throws FileNotFoundException {
if (Environment.isExternalStorageEmulated()) {
return false;
}
- final int sizeMb = calculateContainerSize(apkFile, null);
+ final int sizeMb = calculateContainerSize(apkFile);
final int availSdMb;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
@@ -508,10 +556,14 @@
*
* @param apkFile file from which to calculate size
* @return size in megabytes (2^20 bytes)
+ * @throws FileNotFoundException when file does not exist
*/
- private int calculateContainerSize(File apkFile, List<Pair<ZipEntry, String>> outFiles) {
+ private int calculateContainerSize(File apkFile) throws FileNotFoundException {
// Calculate size of container needed to hold base APK.
long sizeBytes = apkFile.length();
+ if (sizeBytes == 0 && !apkFile.exists()) {
+ throw new FileNotFoundException();
+ }
// Check all the native files that need to be copied and add that to the
// container size.
diff --git a/core/res/res/anim/priority_alert_enter.xml b/packages/SystemUI/res/anim/priority_alert_enter.xml
similarity index 100%
rename from core/res/res/anim/priority_alert_enter.xml
rename to packages/SystemUI/res/anim/priority_alert_enter.xml
diff --git a/core/res/res/anim/priority_alert_exit.xml b/packages/SystemUI/res/anim/priority_alert_exit.xml
similarity index 100%
rename from core/res/res/anim/priority_alert_exit.xml
rename to packages/SystemUI/res/anim/priority_alert_exit.xml
diff --git a/core/res/res/anim/status_bar_enter.xml b/packages/SystemUI/res/anim/status_bar_enter.xml
similarity index 87%
rename from core/res/res/anim/status_bar_enter.xml
rename to packages/SystemUI/res/anim/status_bar_enter.xml
index 1a1dc9b..f1c1301 100644
--- a/core/res/res/anim/status_bar_enter.xml
+++ b/packages/SystemUI/res/anim/status_bar_enter.xml
@@ -18,7 +18,8 @@
*/
-->
-<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/decelerate_quad">
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/decelerate_quad">
<translate android:fromYDelta="-75%" android:toYDelta="0"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
diff --git a/core/res/res/anim/status_bar_exit.xml b/packages/SystemUI/res/anim/status_bar_exit.xml
similarity index 88%
rename from core/res/res/anim/status_bar_exit.xml
rename to packages/SystemUI/res/anim/status_bar_exit.xml
index 1f71090..46462e2 100644
--- a/core/res/res/anim/status_bar_exit.xml
+++ b/packages/SystemUI/res/anim/status_bar_exit.xml
@@ -18,7 +18,8 @@
*/
-->
-<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/accelerate_quad">
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:interpolator="@android:interpolator/accelerate_quad">
<translate android:fromYDelta="0" android:toYDelta="-75%"
android:startOffset="100" android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 91a8855..ad236b7 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -52,4 +52,15 @@
<item name="android:windowExitAnimation">@*android:anim/shrink_fade_out_from_bottom</item>
</style>
+ <!-- Standard animations for hiding and showing the status bar. -->
+ <style name="Animation.StatusBar">
+ <item name="android:windowEnterAnimation">@anim/status_bar_enter</item>
+ <item name="android:windowExitAnimation">@anim/status_bar_exit</item>
+ </style>
+
+ <style name="Animation.StatusBar.IntruderAlert">
+ <item name="android:windowEnterAnimation">@anim/priority_alert_enter</item>
+ <item name="android:windowExitAnimation">@anim/priority_alert_exit</item>
+ </style>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index 918d5a3..61da1f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -119,7 +119,8 @@
PixelFormat.RGBX_8888);
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
- // TODO lp.windowAnimations = R.style.Animation_StatusBar;
+ lp.packageName = mContext.getPackageName();
+ lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(sb, lp);
if (SPEW) {
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 d25a827..7bb8277 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -505,7 +505,8 @@
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.y += height * 1.5; // FIXME
lp.setTitle("IntruderAlert");
- lp.windowAnimations = com.android.internal.R.style.Animation_StatusBar_IntruderAlert;
+ lp.packageName = mContext.getPackageName();
+ lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp);
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 9c19da2..14f7c11 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -552,6 +552,8 @@
if (!st.shownPanelView.hasFocus()) {
st.shownPanelView.requestFocus();
}
+ } else if (!st.isInExpandedMode) {
+ width = MATCH_PARENT;
}
st.isOpen = true;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ec45530..2355d5c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -51,6 +51,8 @@
#include <media/EffectsFactoryApi.h>
#include <audio_effects/effect_visualizer.h>
+#include <audio_effects/effect_ns.h>
+#include <audio_effects/effect_aec.h>
#include <cpustats/ThreadCpuUsage.h>
#include <powermanager/PowerManager.h>
@@ -148,7 +150,8 @@
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
- mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
+ mPrimaryHardwareDev(0), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1),
+ mBtNrec(false)
{
}
@@ -717,6 +720,31 @@
final_result = result ?: final_result;
}
mHardwareStatus = AUDIO_HW_IDLE;
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ AudioParameter param = AudioParameter(keyValuePairs);
+ String8 value;
+ if (param.get(String8(AUDIO_PARAMETER_KEY_BT_NREC), value) == NO_ERROR) {
+ Mutex::Autolock _l(mLock);
+ bool btNrec = (value == AUDIO_PARAMETER_VALUE_ON);
+ if (mBtNrec != btNrec) {
+ for (size_t i = 0; i < mRecordThreads.size(); i++) {
+ sp<RecordThread> thread = mRecordThreads.valueAt(i);
+ RecordThread::RecordTrack *track = thread->track();
+ if (track != NULL) {
+ audio_devices_t device = (audio_devices_t)(
+ thread->device() & AUDIO_DEVICE_IN_ALL);
+ bool suspend = audio_is_bluetooth_sco_device(device) && btNrec;
+ thread->setEffectSuspended(FX_IID_AEC,
+ suspend,
+ track->sessionId());
+ thread->setEffectSuspended(FX_IID_NS,
+ suspend,
+ track->sessionId());
+ }
+ }
+ mBtNrec = btNrec;
+ }
+ }
return final_result;
}
@@ -1130,6 +1158,140 @@
LOGW("power manager service died !!!");
}
+void AudioFlinger::ThreadBase::setEffectSuspended(
+ const effect_uuid_t *type, bool suspend, int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+ setEffectSuspended_l(type, suspend, sessionId);
+}
+
+void AudioFlinger::ThreadBase::setEffectSuspended_l(
+ const effect_uuid_t *type, bool suspend, int sessionId)
+{
+ sp<EffectChain> chain;
+ chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ if (type != NULL) {
+ chain->setEffectSuspended_l(type, suspend);
+ } else {
+ chain->setEffectSuspendedAll_l(suspend);
+ }
+ }
+
+ updateSuspendedSessions_l(type, suspend, sessionId);
+}
+
+void AudioFlinger::ThreadBase::checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain)
+{
+ int index = mSuspendedSessions.indexOfKey(chain->sessionId());
+ if (index < 0) {
+ return;
+ }
+
+ KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects =
+ mSuspendedSessions.editValueAt(index);
+
+ for (size_t i = 0; i < sessionEffects.size(); i++) {
+ sp <SuspendedSessionDesc> desc = sessionEffects.valueAt(i);
+ for (int j = 0; j < desc->mRefCount; j++) {
+ if (sessionEffects.keyAt(i) == EffectChain::kKeyForSuspendAll) {
+ chain->setEffectSuspendedAll_l(true);
+ } else {
+ LOGV("checkSuspendOnAddEffectChain_l() suspending effects %08x",
+ desc->mType.timeLow);
+ chain->setEffectSuspended_l(&desc->mType, true);
+ }
+ }
+ }
+}
+
+void AudioFlinger::ThreadBase::updateSuspendedSessionsOnRemoveEffectChain_l(
+ const sp<EffectChain>& chain)
+{
+ int index = mSuspendedSessions.indexOfKey(chain->sessionId());
+ if (index < 0) {
+ return;
+ }
+ LOGV("updateSuspendedSessionsOnRemoveEffectChain_l() removed suspended session %d",
+ chain->sessionId());
+ mSuspendedSessions.removeItemsAt(index);
+}
+
+void AudioFlinger::ThreadBase::updateSuspendedSessions_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId)
+{
+ int index = mSuspendedSessions.indexOfKey(sessionId);
+
+ KeyedVector <int, sp<SuspendedSessionDesc> > sessionEffects;
+
+ if (suspend) {
+ if (index >= 0) {
+ sessionEffects = mSuspendedSessions.editValueAt(index);
+ } else {
+ mSuspendedSessions.add(sessionId, sessionEffects);
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ sessionEffects = mSuspendedSessions.editValueAt(index);
+ }
+
+
+ int key = EffectChain::kKeyForSuspendAll;
+ if (type != NULL) {
+ key = type->timeLow;
+ }
+ index = sessionEffects.indexOfKey(key);
+
+ sp <SuspendedSessionDesc> desc;
+ if (suspend) {
+ if (index >= 0) {
+ desc = sessionEffects.valueAt(index);
+ } else {
+ desc = new SuspendedSessionDesc();
+ if (type != NULL) {
+ memcpy(&desc->mType, type, sizeof(effect_uuid_t));
+ }
+ sessionEffects.add(key, desc);
+ LOGV("updateSuspendedSessions_l() suspend adding effect %08x", key);
+ }
+ desc->mRefCount++;
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = sessionEffects.valueAt(index);
+ if (--desc->mRefCount == 0) {
+ LOGV("updateSuspendedSessions_l() restore removing effect %08x", key);
+ sessionEffects.removeItemsAt(index);
+ if (sessionEffects.isEmpty()) {
+ LOGV("updateSuspendedSessions_l() restore removing session %d",
+ sessionId);
+ mSuspendedSessions.removeItem(sessionId);
+ }
+ }
+ }
+ if (!sessionEffects.isEmpty()) {
+ mSuspendedSessions.replaceValueFor(sessionId, sessionEffects);
+ }
+}
+
+void AudioFlinger::ThreadBase::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled,
+ int sessionId)
+{
+ Mutex::Autolock _l(mLock);
+
+ // TODO: implement PlaybackThread or RecordThread specific behavior here
+
+ sp<EffectChain> chain = getEffectChain_l(sessionId);
+ if (chain != 0) {
+ chain->checkSuspendOnEffectEnabled(effect, enabled);
+ }
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
@@ -4143,7 +4305,11 @@
}
mTrack = track.get();
-
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ bool suspend = audio_is_bluetooth_sco_device(
+ (audio_devices_t)(mDevice & AUDIO_DEVICE_IN_ALL)) && mAudioFlinger->btNrec();
+ setEffectSuspended_l(FX_IID_AEC, suspend, sessionId);
+ setEffectSuspended_l(FX_IID_NS, suspend, sessionId);
}
lStatus = NO_ERROR;
@@ -4363,6 +4529,13 @@
status = BAD_VALUE;
} else {
mDevice &= (uint32_t)~(value & AUDIO_DEVICE_IN_ALL);
+ // disable AEC and NS if the device is a BT SCO headset supporting those pre processings
+ if (mTrack != NULL) {
+ bool suspend = audio_is_bluetooth_sco_device(
+ (audio_devices_t)value) && mAudioFlinger->btNrec();
+ setEffectSuspended_l(FX_IID_AEC, suspend, mTrack->sessionId());
+ setEffectSuspended_l(FX_IID_NS, suspend, mTrack->sessionId());
+ }
}
mDevice |= (uint32_t)value;
}
@@ -4490,6 +4663,12 @@
return result;
}
+AudioFlinger::RecordThread::RecordTrack* AudioFlinger::RecordThread::track()
+{
+ Mutex::Autolock _l(mLock);
+ return mTrack;
+}
+
// ----------------------------------------------------------------------------
int AudioFlinger::openOutput(uint32_t *pDevices,
@@ -4874,10 +5053,6 @@
}
-// this UUID must match the one defined in media/libeffects/EffectVisualizer.cpp
-static const effect_uuid_t VISUALIZATION_UUID_ =
- {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
-
sp<IEffect> AudioFlinger::createEffect(pid_t pid,
effect_descriptor_t *pDesc,
const sp<IEffectClient>& effectClient,
@@ -4915,14 +5090,6 @@
goto Exit;
}
- // check recording permission for visualizer
- if ((memcmp(&pDesc->type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0 ||
- memcmp(&pDesc->uuid, &VISUALIZATION_UUID_, sizeof(effect_uuid_t)) == 0) &&
- !recordingAllowed()) {
- lStatus = PERMISSION_DENIED;
- goto Exit;
- }
-
if (io == 0) {
if (sessionId == AUDIO_SESSION_OUTPUT_STAGE) {
// output must be specified by AudioPolicyManager when using session
@@ -5003,6 +5170,13 @@
goto Exit;
}
+ // check recording permission for visualizer
+ if ((memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) &&
+ !recordingAllowed()) {
+ lStatus = PERMISSION_DENIED;
+ goto Exit;
+ }
+
// return effect descriptor
memcpy(pDesc, &desc, sizeof(effect_descriptor_t));
@@ -5069,10 +5243,10 @@
return handle;
}
-status_t AudioFlinger::moveEffects(int session, int srcOutput, int dstOutput)
+status_t AudioFlinger::moveEffects(int sessionId, int srcOutput, int dstOutput)
{
LOGV("moveEffects() session %d, srcOutput %d, dstOutput %d",
- session, srcOutput, dstOutput);
+ sessionId, srcOutput, dstOutput);
Mutex::Autolock _l(mLock);
if (srcOutput == dstOutput) {
LOGW("moveEffects() same dst and src outputs %d", dstOutput);
@@ -5091,24 +5265,24 @@
Mutex::Autolock _dl(dstThread->mLock);
Mutex::Autolock _sl(srcThread->mLock);
- moveEffectChain_l(session, srcThread, dstThread, false);
+ moveEffectChain_l(sessionId, srcThread, dstThread, false);
return NO_ERROR;
}
// moveEffectChain_l mustbe called with both srcThread and dstThread mLocks held
-status_t AudioFlinger::moveEffectChain_l(int session,
+status_t AudioFlinger::moveEffectChain_l(int sessionId,
AudioFlinger::PlaybackThread *srcThread,
AudioFlinger::PlaybackThread *dstThread,
bool reRegister)
{
LOGV("moveEffectChain_l() session %d from thread %p to thread %p",
- session, srcThread, dstThread);
+ sessionId, srcThread, dstThread);
- sp<EffectChain> chain = srcThread->getEffectChain_l(session);
+ sp<EffectChain> chain = srcThread->getEffectChain_l(sessionId);
if (chain == 0) {
LOGW("moveEffectChain_l() effect chain for session %d not on source thread %p",
- session, srcThread);
+ sessionId, srcThread);
return INVALID_OPERATION;
}
@@ -5143,7 +5317,7 @@
AudioSystem::registerEffect(&effect->desc(),
dstOutput,
strategy,
- session,
+ sessionId,
effect->id());
}
effect = chain->getEffectFromId_l(0);
@@ -5385,6 +5559,7 @@
void AudioFlinger::ThreadBase::disconnectEffect(const sp<EffectModule>& effect,
const wp<EffectHandle>& handle) {
+
Mutex::Autolock _l(mLock);
LOGV("disconnectEffect() %p effect %p", this, effect.get());
// delete the effect module if removing last handle on it
@@ -5451,6 +5626,7 @@
if (mEffectChains[i]->sessionId() < session) break;
}
mEffectChains.insertAt(chain, i);
+ checkSuspendOnAddEffectChain_l(chain);
return NO_ERROR;
}
@@ -5463,6 +5639,7 @@
for (size_t i = 0; i < mEffectChains.size(); i++) {
if (chain == mEffectChains[i]) {
+ updateSuspendedSessionsOnRemoveEffectChain_l(chain);
mEffectChains.removeAt(i);
// detach all active tracks from the chain
for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) {
@@ -5540,6 +5717,8 @@
chain->setInBuffer(NULL);
chain->setOutBuffer(NULL);
+ checkSuspendOnAddEffectChain_l(chain);
+
mEffectChains.add(chain);
return NO_ERROR;
@@ -5552,6 +5731,7 @@
"removeEffectChain_l() %p invalid chain size %d on thread %p",
chain.get(), mEffectChains.size(), this);
if (mEffectChains.size() == 1) {
+ updateSuspendedSessionsOnRemoveEffectChain_l(chain);
mEffectChains.removeAt(0);
}
return 0;
@@ -5570,7 +5750,7 @@
int id,
int sessionId)
: mThread(wThread), mChain(chain), mId(id), mSessionId(sessionId), mEffectInterface(NULL),
- mStatus(NO_INIT), mState(IDLE)
+ mStatus(NO_INIT), mState(IDLE), mSuspended(false)
{
LOGV("Constructor %p", this);
int lStatus;
@@ -5634,14 +5814,17 @@
}
// if inserted in first place, move effect control from previous owner to this handle
if (i == 0) {
+ bool enabled = false;
if (h != 0) {
- h->setControl(false, true);
+ enabled = h->enabled();
+ h->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
}
- handle->setControl(true, false);
+ handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
status = NO_ERROR;
} else {
status = ALREADY_EXISTS;
}
+ LOGV("addHandle() %p added handle %p in position %d", this, handle.get(), i);
mHandles.insertAt(handle, i);
return status;
}
@@ -5657,13 +5840,21 @@
if (i == size) {
return size;
}
+ LOGV("removeHandle() %p removed handle %p in position %d", this, handle.unsafe_get(), i);
+
+ bool enabled = false;
+ EffectHandle *hdl = handle.unsafe_get();
+ if (hdl) {
+ LOGV("removeHandle() unsafe_get OK");
+ enabled = hdl->enabled();
+ }
mHandles.removeAt(i);
size = mHandles.size();
// if removed from first place, move effect control from this handle to next in line
if (i == 0 && size != 0) {
sp<EffectHandle> h = mHandles[0].promote();
if (h != 0) {
- h->setControl(true, true);
+ h->setControl(true /*hasControl*/, true /*signal*/ , enabled /*enabled*/);
}
}
@@ -5677,8 +5868,21 @@
return size;
}
+sp<AudioFlinger::EffectHandle> AudioFlinger::EffectModule::controlHandle()
+{
+ Mutex::Autolock _l(mLock);
+ sp<EffectHandle> handle;
+ if (mHandles.size() != 0) {
+ handle = mHandles[0].promote();
+ }
+ return handle;
+}
+
+
+
void AudioFlinger::EffectModule::disconnect(const wp<EffectHandle>& handle)
{
+ LOGV("disconnect() %p handle %p ", this, handle.unsafe_get());
// keep a strong reference on this EffectModule to avoid calling the
// destructor before we exit
sp<EffectModule> keep(this);
@@ -6139,6 +6343,17 @@
return status;
}
+void AudioFlinger::EffectModule::setSuspended(bool suspended)
+{
+ Mutex::Autolock _l(mLock);
+ mSuspended = suspended;
+}
+bool AudioFlinger::EffectModule::suspended()
+{
+ Mutex::Autolock _l(mLock);
+ return mSuspended;
+}
+
status_t AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
@@ -6235,7 +6450,8 @@
const sp<IEffectClient>& effectClient,
int32_t priority)
: BnEffect(),
- mEffect(effect), mEffectClient(effectClient), mClient(client), mPriority(priority), mHasControl(false)
+ mEffect(effect), mEffectClient(effectClient), mClient(client),
+ mPriority(priority), mHasControl(false), mEnabled(false)
{
LOGV("constructor %p", this);
@@ -6258,30 +6474,66 @@
{
LOGV("Destructor %p", this);
disconnect();
+ LOGV("Destructor DONE %p", this);
}
status_t AudioFlinger::EffectHandle::enable()
{
+ LOGV("enable %p", this);
if (!mHasControl) return INVALID_OPERATION;
if (mEffect == 0) return DEAD_OBJECT;
+ mEnabled = true;
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId());
+ }
+
+ // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
+ if (mEffect->suspended()) {
+ return NO_ERROR;
+ }
+
return mEffect->setEnabled(true);
}
status_t AudioFlinger::EffectHandle::disable()
{
+ LOGV("disable %p", this);
if (!mHasControl) return INVALID_OPERATION;
- if (mEffect == NULL) return DEAD_OBJECT;
+ if (mEffect == 0) return DEAD_OBJECT;
- return mEffect->setEnabled(false);
+ mEnabled = false;
+
+ if (mEffect->suspended()) {
+ return NO_ERROR;
+ }
+
+ status_t status = mEffect->setEnabled(false);
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+ }
+
+ return status;
}
void AudioFlinger::EffectHandle::disconnect()
{
+ LOGV("disconnect %p", this);
if (mEffect == 0) {
return;
}
+
mEffect->disconnect(this);
+
+ sp<ThreadBase> thread = mEffect->thread().promote();
+ if (thread != 0) {
+ thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId());
+ }
+
// release sp on module => module destructor can be called now
mEffect.clear();
if (mCblk) {
@@ -6373,11 +6625,13 @@
return mCblkMemory;
}
-void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal)
+void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
{
LOGV("setControl %p control %d", this, hasControl);
mHasControl = hasControl;
+ mEnabled = enabled;
+
if (signal && mEffectClient != 0) {
mEffectClient->controlStatusChanged(hasControl);
}
@@ -6448,7 +6702,7 @@
}
-// getEffectFromDesc_l() must be called with PlaybackThread::mLock held
+// getEffectFromDesc_l() must be called with ThreadBase::mLock held
sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(effect_descriptor_t *descriptor)
{
sp<EffectModule> effect;
@@ -6463,7 +6717,7 @@
return effect;
}
-// getEffectFromId_l() must be called with PlaybackThread::mLock held
+// getEffectFromId_l() must be called with ThreadBase::mLock held
sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
{
sp<EffectModule> effect;
@@ -6479,6 +6733,22 @@
return effect;
}
+// getEffectFromType_l() must be called with ThreadBase::mLock held
+sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
+ const effect_uuid_t *type)
+{
+ sp<EffectModule> effect;
+ size_t size = mEffects.size();
+
+ for (size_t i = 0; i < size; i++) {
+ if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
+ effect = mEffects[i];
+ break;
+ }
+ }
+ return effect;
+}
+
// Must be called with EffectChain::mLock locked
void AudioFlinger::EffectChain::process_l()
{
@@ -6773,6 +7043,166 @@
return NO_ERROR;
}
+// must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setEffectSuspended_l(
+ const effect_uuid_t *type, bool suspend)
+{
+ sp<SuspendedEffectDesc> desc;
+ // use effect type UUID timelow as key as there is no real risk of identical
+ // timeLow fields among effect type UUIDs.
+ int index = mSuspendedEffects.indexOfKey(type->timeLow);
+ if (suspend) {
+ if (index >= 0) {
+ desc = mSuspendedEffects.valueAt(index);
+ } else {
+ desc = new SuspendedEffectDesc();
+ memcpy(&desc->mType, type, sizeof(effect_uuid_t));
+ mSuspendedEffects.add(type->timeLow, desc);
+ LOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
+ }
+ if (desc->mRefCount++ == 0) {
+ sp<EffectModule> effect = getEffectIfEnabled(type);
+ if (effect != 0) {
+ desc->mEffect = effect;
+ effect->setSuspended(true);
+ effect->setEnabled(false);
+ }
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = mSuspendedEffects.valueAt(index);
+ if (desc->mRefCount <= 0) {
+ LOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
+ desc->mRefCount = 1;
+ }
+ if (--desc->mRefCount == 0) {
+ LOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
+ if (desc->mEffect != 0) {
+ sp<EffectModule> effect = desc->mEffect.promote();
+ if (effect != 0) {
+ effect->setSuspended(false);
+ sp<EffectHandle> handle = effect->controlHandle();
+ if (handle != 0) {
+ effect->setEnabled(handle->enabled());
+ }
+ }
+ desc->mEffect.clear();
+ }
+ mSuspendedEffects.removeItemsAt(index);
+ }
+ }
+}
+
+// must be called with ThreadBase::mLock held
+void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
+{
+ sp<SuspendedEffectDesc> desc;
+
+ int index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
+ if (suspend) {
+ if (index >= 0) {
+ desc = mSuspendedEffects.valueAt(index);
+ } else {
+ desc = new SuspendedEffectDesc();
+ mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
+ LOGV("setEffectSuspendedAll_l() add entry for 0");
+ }
+ if (desc->mRefCount++ == 0) {
+ Vector< sp<EffectModule> > effects = getSuspendEligibleEffects();
+ for (size_t i = 0; i < effects.size(); i++) {
+ setEffectSuspended_l(&effects[i]->desc().type, true);
+ }
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ desc = mSuspendedEffects.valueAt(index);
+ if (desc->mRefCount <= 0) {
+ LOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
+ desc->mRefCount = 1;
+ }
+ if (--desc->mRefCount == 0) {
+ Vector<const effect_uuid_t *> types;
+ for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
+ if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
+ continue;
+ }
+ types.add(&mSuspendedEffects.valueAt(i)->mType);
+ }
+ for (size_t i = 0; i < types.size(); i++) {
+ setEffectSuspended_l(types[i], false);
+ }
+ LOGV("setEffectSuspendedAll_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
+ mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
+ }
+ }
+}
+
+Vector< sp<AudioFlinger::EffectModule> > AudioFlinger::EffectChain::getSuspendEligibleEffects()
+{
+ Vector< sp<EffectModule> > effects;
+ for (size_t i = 0; i < mEffects.size(); i++) {
+ effect_descriptor_t desc = mEffects[i]->desc();
+ // auxiliary effects and vizualizer are never suspended on output mix
+ if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) && (
+ ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
+ (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0))) {
+ continue;
+ }
+ effects.add(mEffects[i]);
+ }
+ return effects;
+}
+
+sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
+ const effect_uuid_t *type)
+{
+ sp<EffectModule> effect;
+ effect = getEffectFromType_l(type);
+ if (effect != 0 && !effect->isEnabled()) {
+ effect.clear();
+ }
+ return effect;
+}
+
+void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled)
+{
+ int index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
+ if (enabled) {
+ if (index < 0) {
+ // if the effect is not suspend check if all effects are suspended
+ index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
+ if (index < 0) {
+ return;
+ }
+ setEffectSuspended_l(&effect->desc().type, enabled);
+ index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
+ }
+ LOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
+ effect->desc().type.timeLow);
+ sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
+ // if effect is requested to suspended but was not yet enabled, supend it now.
+ if (desc->mEffect == 0) {
+ desc->mEffect = effect;
+ effect->setEnabled(false);
+ effect->setSuspended(true);
+ }
+ } else {
+ if (index < 0) {
+ return;
+ }
+ LOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
+ effect->desc().type.timeLow);
+ sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
+ desc->mEffect.clear();
+ effect->setSuspended(false);
+ }
+}
+
#undef LOG_TAG
#define LOG_TAG "AudioFlinger"
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 7b6215f..791341a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -165,7 +165,7 @@
int *id,
int *enabled);
- virtual status_t moveEffects(int session, int srcOutput, int dstOutput);
+ virtual status_t moveEffects(int sessionId, int srcOutput, int dstOutput);
enum hardware_call_state {
AUDIO_HW_IDLE = 0,
@@ -206,6 +206,8 @@
uint32_t getMode() { return mMode; }
+ bool btNrec() { return mBtNrec; }
+
private:
AudioFlinger();
virtual ~AudioFlinger();
@@ -477,14 +479,45 @@
// strategy is only meaningful for PlaybackThread which implements this method
virtual uint32_t getStrategyForSession_l(int sessionId) { return 0; }
+ // suspend or restore effect according to the type of effect passed. a NULL
+ // type pointer means suspend all effects in the session
+ void setEffectSuspended(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+ // check if some effects must be suspended/restored when an effect is enabled
+ // or disabled
+ virtual void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+
mutable Mutex mLock;
protected:
+ // entry describing an effect being suspended in mSuspendedSessions keyed vector
+ class SuspendedSessionDesc : public RefBase {
+ public:
+ SuspendedSessionDesc() : mRefCount(0) {}
+
+ int mRefCount; // number of active suspend requests
+ effect_uuid_t mType; // effect type UUID
+ };
+
void acquireWakeLock();
void acquireWakeLock_l();
void releaseWakeLock();
void releaseWakeLock_l();
+ void setEffectSuspended_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId = AUDIO_SESSION_OUTPUT_MIX);
+ // updated mSuspendedSessions when an effect suspended or restored
+ void updateSuspendedSessions_l(const effect_uuid_t *type,
+ bool suspend,
+ int sessionId);
+ // check if some effects must be suspended when an effect chain is added
+ void checkSuspendOnAddEffectChain_l(const sp<EffectChain>& chain);
+ // updated mSuspendedSessions when an effect chain is removed
+ void updateSuspendedSessionsOnRemoveEffectChain_l(const sp<EffectChain>& chain);
friend class Track;
friend class TrackBase;
@@ -519,6 +552,9 @@
sp<IPowerManager> mPowerManager;
sp<IBinder> mWakeLockToken;
sp<PMDeathRecipient> mDeathRecipient;
+ // list of suspended effects per session and per type. The first vector is
+ // keyed by session ID, the second by type UUID timeLow field
+ KeyedVector< int, KeyedVector< int, sp<SuspendedSessionDesc> > > mSuspendedSessions;
};
// --- PlaybackThread ---
@@ -848,7 +884,7 @@
void audioConfigChanged_l(int event, int ioHandle, void *param2);
uint32_t nextUniqueId();
- status_t moveEffectChain_l(int session,
+ status_t moveEffectChain_l(int sessionId,
AudioFlinger::PlaybackThread *srcThread,
AudioFlinger::PlaybackThread *dstThread,
bool reRegister);
@@ -908,6 +944,7 @@
bool setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
void dump(char* buffer, size_t size);
+
private:
friend class AudioFlinger;
friend class RecordThread;
@@ -950,8 +987,6 @@
AudioStreamIn* getInput() { return mInput; }
virtual audio_stream_t* stream() { return &mInput->stream->common; }
-
- void setTrack(RecordTrack *recordTrack) { mTrack = recordTrack; }
virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
virtual bool checkForNewParameters_l();
@@ -963,6 +998,7 @@
virtual status_t addEffectChain_l(const sp<EffectChain>& chain);
virtual size_t removeEffectChain_l(const sp<EffectChain>& chain);
virtual uint32_t hasAudioSession(int sessionId);
+ RecordTrack* track();
private:
RecordThread();
@@ -1059,6 +1095,7 @@
int16_t *outBuffer() { return mConfig.outputCfg.buffer.s16; }
void setChain(const wp<EffectChain>& chain) { mChain = chain; }
void setThread(const wp<ThreadBase>& thread) { mThread = thread; }
+ wp<ThreadBase>& thread() { return mThread; }
status_t addHandle(sp<EffectHandle>& handle);
void disconnect(const wp<EffectHandle>& handle);
@@ -1071,6 +1108,10 @@
status_t setVolume(uint32_t *left, uint32_t *right, bool controller);
status_t setMode(uint32_t mode);
status_t stop();
+ void setSuspended(bool suspended);
+ bool suspended();
+
+ sp<EffectHandle> controlHandle();
status_t dump(int fd, const Vector<String16>& args);
@@ -1099,6 +1140,7 @@
uint32_t mMaxDisableWaitCnt; // maximum grace period before forcing an effect off after
// sending disable command.
uint32_t mDisableWaitCnt; // current process() calls count during disable period.
+ bool mSuspended; // effect is suspended: temporarily disabled by framework
};
// The EffectHandle class implements the IEffect interface. It provides resources
@@ -1131,13 +1173,17 @@
// Give or take control of effect module
- void setControl(bool hasControl, bool signal);
+ // - hasControl: true if control is given, false if removed
+ // - signal: true client app should be signaled of change, false otherwise
+ // - enabled: state of the effect when control is passed
+ void setControl(bool hasControl, bool signal, bool enabled);
void commandExecuted(uint32_t cmdCode,
uint32_t cmdSize,
void *pCmdData,
uint32_t replySize,
void *pReplyData);
void setEnabled(bool enabled);
+ bool enabled() { return mEnabled; }
// Getters
int id() { return mEffect->id(); }
@@ -1160,6 +1206,8 @@
uint8_t* mBuffer; // pointer to parameter area in shared memory
int mPriority; // client application priority to control the effect
bool mHasControl; // true if this handle is controlling the effect
+ bool mEnabled; // cached enable state: needed when the effect is
+ // restored after being suspended
};
// the EffectChain class represents a group of effects associated to one audio session.
@@ -1174,6 +1222,10 @@
EffectChain(const wp<ThreadBase>& wThread, int sessionId);
~EffectChain();
+ // special key used for an entry in mSuspendedEffects keyed vector
+ // corresponding to a suspend all request.
+ static const int kKeyForSuspendAll = 0;
+
void process_l();
void lock() {
@@ -1191,6 +1243,7 @@
sp<EffectModule> getEffectFromDesc_l(effect_descriptor_t *descriptor);
sp<EffectModule> getEffectFromId_l(int id);
+ sp<EffectModule> getEffectFromType_l(const effect_uuid_t *type);
bool setVolume_l(uint32_t *left, uint32_t *right);
void setDevice_l(uint32_t device);
void setMode_l(uint32_t mode);
@@ -1221,6 +1274,15 @@
void setStrategy(uint32_t strategy)
{ mStrategy = strategy; }
+ // suspend effect of the given type
+ void setEffectSuspended_l(const effect_uuid_t *type,
+ bool suspend);
+ // suspend all eligible effects
+ void setEffectSuspendedAll_l(bool suspend);
+ // check if effects should be suspend or restored when a given effect is enable or disabled
+ virtual void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
+ bool enabled);
+
status_t dump(int fd, const Vector<String16>& args);
protected:
@@ -1228,6 +1290,21 @@
EffectChain(const EffectChain&);
EffectChain& operator =(const EffectChain&);
+ class SuspendedEffectDesc : public RefBase {
+ public:
+ SuspendedEffectDesc() : mRefCount(0) {}
+
+ int mRefCount;
+ effect_uuid_t mType;
+ wp<EffectModule> mEffect;
+ };
+
+ // get a list of effect modules to suspend when an effect of the type
+ // passed is enabled.
+ Vector< sp<EffectModule> > getSuspendEligibleEffects();
+ // get an effect module if it is currently enable
+ sp<EffectModule> getEffectIfEnabled(const effect_uuid_t *type);
+
wp<ThreadBase> mThread; // parent mixer thread
Mutex mLock; // mutex protecting effect list
Vector<sp<EffectModule> > mEffects; // list of effect modules
@@ -1243,6 +1320,10 @@
uint32_t mNewLeftVolume; // new volume on left channel
uint32_t mNewRightVolume; // new volume on right channel
uint32_t mStrategy; // strategy for this effect chain
+ // mSuspendedEffects lists all effect currently suspended in the chain
+ // use effect type UUID timelow field as key. There is no real risk of identical
+ // timeLow fields among effect type UUIDs.
+ KeyedVector< int, sp<SuspendedEffectDesc> > mSuspendedEffects;
};
struct AudioStreamOut {
@@ -1283,7 +1364,8 @@
DefaultKeyedVector< pid_t, sp<NotificationClient> > mNotificationClients;
volatile int32_t mNextUniqueId;
- uint32_t mMode;
+ uint32_t mMode;
+ bool mBtNrec;
};
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 1bbe934..bf9e014 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -40,6 +40,7 @@
import android.net.NetworkConfig;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkStateTracker;
import android.net.NetworkUtils;
@@ -737,6 +738,30 @@
return result.toArray(new NetworkState[result.size()]);
}
+ private NetworkState getNetworkStateUnchecked(int networkType) {
+ if (isNetworkTypeValid(networkType)) {
+ final NetworkStateTracker tracker = mNetTrackers[networkType];
+ if (tracker != null) {
+ return new NetworkState(tracker.getNetworkInfo(), tracker.getLinkProperties(),
+ tracker.getLinkCapabilities());
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public NetworkQuotaInfo getActiveNetworkQuotaInfo() {
+ enforceAccessPermission();
+ final NetworkState state = getNetworkStateUnchecked(mActiveDefaultNetwork);
+ if (state != null) {
+ try {
+ return mPolicyManager.getNetworkQuotaInfo(state);
+ } catch (RemoteException e) {
+ }
+ }
+ return null;
+ }
+
public boolean setRadios(boolean turnOn) {
boolean result = true;
enforceChangePermission();
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 88d94c2..fed554c 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -19,6 +19,9 @@
import android.net.LocalSocketAddress;
import android.net.LocalSocket;
import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.util.Slog;
@@ -39,7 +42,7 @@
* daemon which uses the libsysutils FrameworkListener
* protocol.
*/
-final class NativeDaemonConnector implements Runnable {
+final class NativeDaemonConnector implements Runnable, Handler.Callback {
private static final boolean LOCAL_LOGD = false;
private BlockingQueue<String> mResponseQueue;
@@ -47,6 +50,7 @@
private String TAG = "NativeDaemonConnector";
private String mSocket;
private INativeDaemonConnectorCallbacks mCallbacks;
+ private Handler mCallbackHandler;
private final int BUFFER_SIZE = 4096;
@@ -76,7 +80,11 @@
mResponseQueue = new LinkedBlockingQueue<String>(responseQueueSize);
}
+ @Override
public void run() {
+ HandlerThread thread = new HandlerThread(TAG + ".CallbackHandler");
+ thread.start();
+ mCallbackHandler = new Handler(thread.getLooper(), this);
while (true) {
try {
@@ -88,6 +96,21 @@
}
}
+ @Override
+ public boolean handleMessage(Message msg) {
+ String event = (String) msg.obj;
+ try {
+ if (!mCallbacks.onEvent(msg.what, event, event.split(" "))) {
+ Slog.w(TAG, String.format(
+ "Unhandled event '%s'", event));
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, String.format(
+ "Error handling '%s'", event), e);
+ }
+ return true;
+ }
+
private void listenToSocket() throws IOException {
LocalSocket socket = null;
@@ -119,20 +142,13 @@
String event = new String(buffer, start, i - start);
if (LOCAL_LOGD) Slog.d(TAG, String.format("RCV <- {%s}", event));
- String[] tokens = event.split(" ");
+ String[] tokens = event.split(" ", 2);
try {
int code = Integer.parseInt(tokens[0]);
if (code >= ResponseCode.UnsolicitedInformational) {
- try {
- if (!mCallbacks.onEvent(code, event, tokens)) {
- Slog.w(TAG, String.format(
- "Unhandled event (%s)", event));
- }
- } catch (Exception ex) {
- Slog.e(TAG, String.format(
- "Error handling '%s'", event), ex);
- }
+ mCallbackHandler.sendMessage(
+ mCallbackHandler.obtainMessage(code, event));
} else {
try {
mResponseQueue.put(event);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 756cd00..a075255 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.net;
+import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.DUMP;
import static android.Manifest.permission.MANAGE_APP_TOKENS;
@@ -75,9 +76,11 @@
import android.net.INetworkStatsService;
import android.net.NetworkIdentity;
import android.net.NetworkPolicy;
+import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkStats;
import android.net.NetworkTemplate;
+import android.os.Binder;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
@@ -1054,6 +1057,7 @@
synchronized (mRulesLock) {
mRestrictBackground = restrictBackground;
updateRulesForRestrictBackgroundLocked();
+ writePolicyLocked();
}
}
@@ -1066,6 +1070,68 @@
}
}
+ private NetworkPolicy findPolicyForNetworkLocked(NetworkIdentity ident) {
+ for (NetworkPolicy policy : mNetworkPolicy.values()) {
+ if (policy.template.matches(ident)) {
+ return policy;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public NetworkQuotaInfo getNetworkQuotaInfo(NetworkState state) {
+ mContext.enforceCallingOrSelfPermission(ACCESS_NETWORK_STATE, TAG);
+
+ // only returns usage summary, so we don't require caller to have
+ // READ_NETWORK_USAGE_HISTORY.
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return getNetworkQuotaInfoUnchecked(state);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private NetworkQuotaInfo getNetworkQuotaInfoUnchecked(NetworkState state) {
+ final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state);
+
+ final NetworkPolicy policy;
+ synchronized (mRulesLock) {
+ policy = findPolicyForNetworkLocked(ident);
+ }
+
+ if (policy == null) {
+ // missing policy means we can't derive useful quota info
+ return null;
+ }
+
+ final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
+ : System.currentTimeMillis();
+
+ final long start = computeLastCycleBoundary(currentTime, policy);
+ final long end = currentTime;
+
+ // find total bytes used under policy
+ long totalBytes = 0;
+ try {
+ final NetworkStats stats = mNetworkStats.getSummaryForNetwork(
+ policy.template, start, end);
+ final NetworkStats.Entry entry = stats.getValues(0, null);
+ totalBytes = entry.rxBytes + entry.txBytes;
+ } catch (RemoteException e) {
+ Slog.w(TAG, "problem reading summary for template " + policy.template);
+ }
+
+ // report soft and hard limits under policy
+ final long softLimitBytes = policy.warningBytes != WARNING_DISABLED ? policy.warningBytes
+ : NetworkQuotaInfo.NO_LIMIT;
+ final long hardLimitBytes = policy.limitBytes != LIMIT_DISABLED ? policy.limitBytes
+ : NetworkQuotaInfo.NO_LIMIT;
+
+ return new NetworkQuotaInfo(totalBytes, softLimitBytes, hardLimitBytes);
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
mContext.enforceCallingOrSelfPermission(DUMP, TAG);
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 3d977d0..36371a57 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -5025,16 +5025,18 @@
}
int loc = pkgLite.recommendedInstallLocation;
- if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){
+ if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
- } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS){
+ } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
- } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE){
+ } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
} else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
ret = PackageManager.INSTALL_FAILED_INVALID_APK;
+ } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
+ ret = PackageManager.INSTALL_FAILED_INVALID_URI;
} else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
- ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
+ ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
} else {
// Override with defaults if needed.
loc = installLocationPolicy(pkgLite, flags);
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
index aad138c..9ea90f8 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/PlaybackGraphs.java
@@ -236,8 +236,10 @@
int yPos = LABELOFFSET;
canvas.drawText(label, xPos, yPos, whiteLabels);
for (int statIndex = 0; statIndex < Stats.length; statIndex++) {
- label = resources.getString(R.string.format_stat,
- mStats[metricIndex][statIndex]);
+ String statLabel = resources.getString(
+ Stats[statIndex].getLabelId()).substring(0,3);
+ label = statLabel + " " + resources.getString(
+ R.string.format_stat, mStats[metricIndex][statIndex]);
yPos = LABELOFFSET + (1 + statIndex) * PlaybackView.TILE_SCALE
/ 2;
canvas.drawText(label, xPos, yPos, whiteLabels);
diff --git a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
index a63a2f0..82a7e82 100644
--- a/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
+++ b/tests/TileBenchmark/src/com/test/tilebenchmark/ProfileActivity.java
@@ -223,7 +223,7 @@
mMovementSpinner = (Spinner) findViewById(R.id.movement);
mUrl = (EditText) findViewById(R.id.url);
mWeb = (ProfiledWebView) findViewById(R.id.web);
- mCallback = new ProfileCallback() {
+ setCallback(new ProfileCallback() {
@SuppressWarnings("unchecked")
@Override
public void profileCallback(RunData data) {
@@ -232,7 +232,7 @@
mCaptureButton.setChecked(false);
setTestingState(TestingState.STOP_TESTING);
}
- };
+ });
// Inspect button (opens PlaybackActivity)
mInspectButton.setOnClickListener(new OnClickListener() {